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/characters/incominglistener.go

155 lines
5.4 KiB
Go

package characters
import (
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/protocol/connections"
"cwtch.im/ui/go/cwutil"
"cwtch.im/ui/go/gobjects"
"cwtch.im/ui/go/gothings"
"cwtch.im/ui/go/the"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"time"
)
func IncomingListener(uiState *gothings.InterfaceState, subscribed chan bool) {
q := event.NewQueue()
the.EventBus.Subscribe(event.NewMessageFromPeer, q)
the.EventBus.Subscribe(event.PeerAcknowledgement, q)
the.EventBus.Subscribe(event.NewMessageFromGroup, q)
the.EventBus.Subscribe(event.NewGroupInvite, q)
the.EventBus.Subscribe(event.SendMessageToGroupError, q)
the.EventBus.Subscribe(event.SendMessageToPeerError, q)
the.EventBus.Subscribe(event.ServerStateChange, q)
the.EventBus.Subscribe(event.PeerStateChange, q)
subscribed <- true
for {
e := q.Next()
switch e.EventType {
case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data
ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampReceived])
uiState.AddMessage(&gobjects.Message{
Handle: e.Data[event.RemotePeer],
From: e.Data[event.RemotePeer],
Message: e.Data[event.Data],
Image: cwutil.RandomProfileImage(e.Data[event.RemotePeer]),
Timestamp: ts,
})
if the.Peer.GetContact(e.Data[event.RemotePeer]) == nil {
the.Peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], false)
}
case event.PeerAcknowledgement:
ackI, ok := the.AcknowledgementIDs.Load(e.Data[event.EventID])
if ok {
ack := ackI.(*the.AckId)
if ack.Peer == e.Data[event.RemotePeer] {
ack.Ack = true
uiState.Acknowledge(e.Data[event.EventID])
continue
}
}
log.Debugf("Received Ack ID for unknown message or peer: %v", e)
case event.NewMessageFromGroup: //event.TimestampReceived, event.TimestampSent, event.Data, event.GroupID, event.RemotePeer
var name string
var exists bool
ctc := the.Peer.GetContact(e.Data[event.RemotePeer])
if ctc != nil {
name, exists = ctc.GetAttribute("nick")
if !exists || name == "" {
name = e.Data[event.RemotePeer]
}
} else {
name = e.Data[event.RemotePeer]
}
ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampSent])
uiState.AddMessage(&gobjects.Message{
MessageID: e.Data[event.Signature],
Handle: e.Data[event.GroupID],
From: e.Data[event.RemotePeer],
Message: e.Data[event.Data],
Image: cwutil.RandomProfileImage(e.Data[event.RemotePeer]),
FromMe: e.Data[event.RemotePeer] == the.Peer.GetProfile().Onion,
Timestamp: ts,
Acknowledged: true,
DisplayName: name,
})
case event.NewGroupInvite:
gid, err := the.Peer.GetProfile().ProcessInvite(e.Data[event.GroupInvite], e.Data[event.RemotePeer])
group := the.Peer.GetGroup(gid)
if err == nil && group != nil {
uiState.AddContact(&gobjects.Contact{
Handle: gid,
DisplayName: gid,
Image: cwutil.RandomGroupImage(gid),
Server: group.GroupServer,
Trusted: false,
Loading: false,
})
}
case event.SendMessageToGroupError:
uiState.AddSendMessageError(e.Data[event.GroupServer], e.Data[event.Signature], e.Data[event.Error])
case event.SendMessageToPeerError:
uiState.AddSendMessageError(e.Data[event.RemotePeer], e.Data[event.Signature], e.Data[event.Error])
case event.PeerStateChange:
cxnState := connections.ConnectionStateToType[e.Data[event.ConnectionState]]
// if it's not in the.Peer it's new. Only add once Authed
_, exists := the.Peer.GetProfile().Contacts[e.Data[event.RemotePeer]]
if !exists {
// Contact does not exist, we will add them but we won't know who they are until they are authenticated
// So if we get any other state from an unknown contact we do nothing
// (the next exists check will fail)
if cxnState == connections.AUTHENTICATED {
the.Peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], false)
}
}
// if it's in the.Peer its either existing and needs an update or not in the UI and needs to be added
if contact, exists := the.Peer.GetProfile().Contacts[e.Data[event.RemotePeer]]; exists {
contact.State = e.Data[event.ConnectionState]
uiContact := uiState.GetContact(contact.Onion)
if uiContact != nil {
if uiContact.Status != int(cxnState) {
uiContact.Status = int(cxnState)
uiState.UpdateContact(contact.Onion)
}
} else {
uiState.AddContact(&gobjects.Contact{
e.Data[event.RemotePeer],
e.Data[event.RemotePeer],
cwutil.RandomProfileImage(e.Data[event.RemotePeer]),
"",
0,
int(cxnState),
false,
false,
false,
})
}
}
case event.ServerStateChange:
serverOnion := e.Data[event.GroupServer]
state := connections.ConnectionStateToType[e.Data[event.ConnectionState]]
groups := the.Peer.GetGroups()
for _, groupID := range groups {
group := the.Peer.GetGroup(groupID)
group.State = e.Data[event.ConnectionState]
if group != nil && group.GroupServer == serverOnion {
uiState.GetContact(group.GroupID).Status = int(state)
if state == connections.AUTHENTICATED {
uiState.GetContact(group.GroupID).Loading = true
} else {
uiState.GetContact(group.GroupID).Loading = false
}
uiState.UpdateContact(group.GroupID)
} else {
log.Errorf("found group that is nil :/")
}
}
}
}
}