This repository has been archived on 2021-06-24. You can view files and clone it, but cannot push or open issues or pull requests.
ui/go/ui/manager.go

223 lines
6.0 KiB
Go
Raw Normal View History

package ui
2018-11-22 00:01:17 +00:00
import (
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/protocol/connections"
2018-11-28 22:14:02 +00:00
"cwtch.im/ui/go/constants"
"cwtch.im/ui/go/the"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
2019-02-04 23:00:12 +00:00
"runtime/debug"
"time"
2018-11-22 00:01:17 +00:00
)
func isGroup(id string) bool {
return len(id) == 32
}
func isPeer(id string) bool {
return len(id) == 56
}
func getOrDefault(id, key, defaultVal string) string {
var val string
var ok bool
if isGroup(id) {
val, ok = the.Peer.GetGroupAttribute(id, key)
} else {
val, ok = the.Peer.GetContactAttribute(id, key)
}
if ok {
return val
} else {
return defaultVal
}
}
func getWithSetDefault(id string, key, defaultVal string) string {
var val string
var ok bool
if isGroup(id) {
val, ok = the.Peer.GetGroupAttribute(id, key)
} else {
val, ok = the.Peer.GetContactAttribute(id, key)
}
if !ok {
val = defaultVal
if isGroup(id) {
the.Peer.SetGroupAttribute(id, key, defaultVal)
} else {
the.Peer.SetContactAttribute(id, key, defaultVal)
}
}
return val
}
// initLastReadTime checks and gets the Attributable's LastRead time or sets it to now
func initLastReadTime(id string) time.Time {
nowStr, _ := time.Now().MarshalText()
lastReadStr := getWithSetDefault(id, constants.LastRead, string(nowStr))
var lastRead time.Time
lastRead.UnmarshalText([]byte(lastReadStr))
return lastRead
}
func initProfilePicture(id string) string {
if isGroup(id) {
return getWithSetDefault(id, constants.Picture, RandomGroupImage(id))
} else {
return getWithSetDefault(id, constants.Picture, RandomProfileImage(id))
}
}
// getProfilePic supplies a profile pic to use. In groups we may not have a contact so it will generate one
func getProfilePic(id string) string {
if isGroup(id) {
if pic, exists := the.Peer.GetGroupAttribute(id, constants.Picture); !exists {
return RandomGroupImage(id)
} else {
return pic
}
} else {
if pic, exists := the.Peer.GetContactAttribute(id, constants.Picture); !exists {
return RandomProfileImage(id)
} else {
return pic
}
}
}
func updateLastReadTime(id string) {
lastRead, _ := time.Now().MarshalText()
if isGroup(id) {
the.Peer.SetGroupAttribute(id, constants.LastRead, string(lastRead))
} else {
the.Peer.SetContactAttribute(id, constants.LastRead, string(lastRead))
}
}
func countUnread(messages []model.Message, lastRead time.Time) int {
count := 0
for i := len(messages) - 1; i >= 0; i-- {
if messages[i].Timestamp.After(lastRead) || messages[i].Timestamp.Equal(lastRead) {
count++
} else {
break
}
}
return count
}
type Manager struct {
gcd *GrandCentralDispatcher
2018-11-22 00:01:17 +00:00
}
func NewManager(gcd *GrandCentralDispatcher) Manager {
return Manager{gcd}
2018-11-22 00:01:17 +00:00
}
func (this *Manager) AddProfile(handle string) {
peer := the.CwtchApp.GetPeer(handle)
if peer != nil {
nick := peer.GetProfile().Name
if nick == "" {
nick = handle
peer.SetAttribute(constants.Nick, nick)
}
pic, ok := peer.GetAttribute(constants.Picture)
if !ok {
pic = RandomProfileImage(handle)
peer.SetAttribute(constants.Picture, pic)
}
log.Infof("AddProfile %v %v %v\n", handle, nick, pic)
this.gcd.AddProfile(handle, nick, pic)
}
}
func (this *Manager) Acknowledge(mID string) {
this.gcd.Acknowledged(mID)
2019-07-31 18:59:43 +00:00
}
func getLastMessageTime(tl *model.Timeline) int {
if len(tl.Messages) == 0 {
return 0
}
return int(tl.Messages[len(tl.Messages)-1].Timestamp.Unix())
}
func (this *Manager) AddContact(Handle string) {
if isGroup(Handle) {
group := the.Peer.GetGroup(Handle)
if group != nil {
lastRead := initLastReadTime(group.GroupID)
unread := countUnread(group.Timeline.GetMessages(), lastRead)
picture := initProfilePicture(Handle)
nick, exists := group.GetAttribute(constants.Nick)
if !exists {
nick = Handle
}
this.gcd.AddContact(Handle, nick, picture, group.GroupServer, unread, int(connections.ConnectionStateToType[group.State]), false, false, getLastMessageTime(&group.Timeline))
2018-11-22 00:01:17 +00:00
}
return
} else if !isPeer(Handle) {
log.Errorf("sorry, unable to handle AddContact(%v)", Handle)
2019-02-04 23:00:12 +00:00
debug.PrintStack()
2018-11-22 00:01:17 +00:00
return
}
contact := the.Peer.GetContact(Handle)
if contact != nil {
lastRead := initLastReadTime(contact.Onion)
unread := countUnread(contact.Timeline.GetMessages(), lastRead)
picture := initProfilePicture(Handle)
nick, exists := contact.GetAttribute(constants.Nick)
if !exists {
nick = Handle
2019-02-05 21:09:38 +00:00
}
this.gcd.AddContact(Handle, nick, picture, "", unread, int(connections.ConnectionStateToType[contact.State]), contact.Blocked, false, getLastMessageTime(&contact.Timeline))
}
2018-11-22 00:01:17 +00:00
}
func (this *Manager) AddSendMessageError(peer string, signature string, err string) {
2019-04-10 20:53:45 +00:00
log.Debugf("Received Error Sending Message: %v", err)
// FIXME: Sometimes, for the first Peer message we send our error beats our message to the UI
time.Sleep(time.Second * 1)
this.gcd.GroupSendError(signature, err)
2019-02-20 21:45:42 +00:00
}
func (this *Manager) AddMessage(handle string, from string, message string, fromMe bool, messageID string, timestamp time.Time, Acknowledged bool) {
nick := getOrDefault(handle, constants.Nick, handle)
image := getProfilePic(handle)
2018-11-22 00:01:17 +00:00
2019-07-31 22:35:35 +00:00
// If we have this group loaded already
if this.gcd.CurrentOpenConversation() == handle {
updateLastReadTime(handle)
2019-07-31 22:35:35 +00:00
// If the message is not from the user then add it, otherwise, just acknowledge.
if !fromMe {
this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Format(constants.TIME_FORMAT), false, false)
2019-02-04 22:22:58 +00:00
} else {
if !Acknowledged {
this.gcd.AppendMessage(handle, from, nick, message, image, messageID, fromMe, timestamp.Format(constants.TIME_FORMAT), false, false)
} else {
this.gcd.Acknowledged(messageID)
}
2019-02-04 22:22:58 +00:00
}
2019-07-31 22:35:35 +00:00
}
this.gcd.IncContactUnreadCount(handle)
2018-11-22 00:01:17 +00:00
}
func (this *Manager) UpdateContactDisplayName(handle string, name string) {
this.gcd.UpdateContactDisplayName(handle, name)
}
2019-10-21 19:19:18 +00:00
func (this *Manager) UpdateContactStatus(handle string, status int, loading bool) {
this.gcd.UpdateContactStatus(handle, status, loading)
2018-11-28 20:34:49 +00:00
}
func (this *Manager) UpdateContactAttribute(handle, key, value string) {
this.gcd.UpdateContactAttribute(handle, key, value)
}