diff --git a/go/characters/appEventListener.go b/go/characters/appEventListener.go index 827e8bcc..3ee2f498 100644 --- a/go/characters/appEventListener.go +++ b/go/characters/appEventListener.go @@ -75,9 +75,6 @@ func AppEventListener(gcd *gothings.GrandCentralDispatcher, subscribed chan bool go PresencePoller(&gcd.UIState) gcd.UpdateMyProfile(the.Peer.GetProfile().Name, the.Peer.GetProfile().Onion, cwutil.RandomProfileImage(the.Peer.GetProfile().Onion)) - if e.Data[event.Status] != "running" { - the.CwtchApp.LaunchPeers() - } contacts := the.Peer.GetContacts() for i := range contacts { @@ -117,6 +114,10 @@ func AppEventListener(gcd *gothings.GrandCentralDispatcher, subscribed chan bool } } + if e.Data[event.Status] != "running" { + the.CwtchApp.LaunchPeers() + } + // load ui preferences gcd.RequestSettings() locale, exists := the.Peer.GetProfile().GetAttribute("settings.locale") diff --git a/go/characters/incominglistener.go b/go/characters/incominglistener.go index f81078e8..4b1602dc 100644 --- a/go/characters/incominglistener.go +++ b/go/characters/incominglistener.go @@ -14,6 +14,7 @@ import ( func IncomingListener(uiState *gothings.InterfaceState, subscribed chan bool) { q := event.NewEventQueue(1000) the.EventBus.Subscribe(event.NewMessageFromPeer, q.EventChannel) + the.EventBus.Subscribe(event.PeerAcknowledgement, q.EventChannel) the.EventBus.Subscribe(event.NewMessageFromGroup, q.EventChannel) the.EventBus.Subscribe(event.NewGroupInvite, q.EventChannel) the.EventBus.Subscribe(event.SendMessageToGroupError, q.EventChannel) @@ -38,10 +39,18 @@ func IncomingListener(uiState *gothings.InterfaceState, subscribed chan bool) { if the.Peer.GetContact(e.Data[event.RemotePeer]) == nil { the.Peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], false) } - the.Peer.PeerWithOnion(e.Data[event.RemotePeer]) - if e.Data[event.Data] != "ack" { - the.Peer.SendMessageToPeer(e.Data[event.RemotePeer], "ack") + + 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 @@ -75,18 +84,27 @@ func IncomingListener(uiState *gothings.InterfaceState, subscribed chan bool) { uiState.AddSendMessageError(e.Data[event.RemotePeer], e.Data[event.Signature], e.Data[event.Error]) case event.PeerStateChange: cxnState := connections.ConnectionStateToType[e.Data[event.ConnectionState]] + + _, 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 contact, exists := the.Peer.GetProfile().Contacts[e.Data[event.RemotePeer]]; exists { uiContact := uiState.GetContact(contact.Onion) if uiContact != nil && uiContact.Status != int(cxnState) { uiContact.Status = int(cxnState) uiState.UpdateContact(contact.Onion) } - } else { - the.Peer.PeerWithOnion(contact.Onion) - c2 := uiState.GetContact(contact.Onion) - if c2 != nil && c2.Status != -2 { - c2.Status = -2 - uiState.UpdateContact(contact.Onion) + + // Stub reconnection-handler simply attempts reconnection + if cxnState == connections.DISCONNECTED { + the.Peer.PeerWithOnion(contact.Onion) } } case event.ServerStateChange: diff --git a/go/gobjects/message.go b/go/gobjects/message.go index 8001dcad..01284ffb 100644 --- a/go/gobjects/message.go +++ b/go/gobjects/message.go @@ -3,14 +3,14 @@ package gobjects import "time" type Message struct { - Handle string - From string - DisplayName string - Message string - Image string - FromMe bool - MessageID string - Timestamp time.Time + Handle string + From string + DisplayName string + Message string + Image string + FromMe bool + MessageID string + Timestamp time.Time Acknowledged bool - Error bool + Error bool } diff --git a/go/gothings/gcd.go b/go/gothings/gcd.go index 3ac7365f..29e38e1f 100644 --- a/go/gothings/gcd.go +++ b/go/gothings/gcd.go @@ -127,7 +127,6 @@ func (this *GrandCentralDispatcher) sendMessage(message string, mID string) { } to := this.CurrentOpenConversation() - the.Peer.PeerWithOnion(to) mID = the.Peer.SendMessageToPeer(to, message) this.UIState.AddMessage(&gobjects.Message{ @@ -146,7 +145,8 @@ func (this *GrandCentralDispatcher) sendMessage(message string, mID string) { ackID := new(the.AckId) ackID.ID = mID ackID.Ack = false - the.AcknowledgementIDs[to] = append(the.AcknowledgementIDs[to], ackID) + ackID.Peer = to + the.AcknowledgementIDs.Store(mID, ackID) } } @@ -237,6 +237,13 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { from = "me" } + ackI, ok := the.AcknowledgementIDs.Load(messages[i].MessageID) + acked := false + if ok { + ack := ackI.(*the.AckId) + acked = ack.Ack + } + this.AppendMessage( messages[i].Handle, from, @@ -246,14 +253,10 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { messages[i].MessageID, messages[i].FromMe, messages[i].Timestamp.Format(constants.TIME_FORMAT), - false, + acked, messages[i].Error, ) - for _, id := range the.AcknowledgementIDs[messages[i].Handle] { - if id.ID == messages[i].MessageID && id.Ack && !id.Error { - this.Acknowledged(id.ID) - } - } + } } diff --git a/go/gothings/uistate.go b/go/gothings/uistate.go index 5185f559..61581b8e 100644 --- a/go/gothings/uistate.go +++ b/go/gothings/uistate.go @@ -22,6 +22,10 @@ func NewUIState(gcd *GrandCentralDispatcher) (uis InterfaceState) { return } +func (this *InterfaceState) Acknowledge(mID string) { + this.parentGcd.Acknowledged(mID) +} + func (this *InterfaceState) AddContact(c *gobjects.Contact) { if len(c.Handle) == 32 { // ADD GROUP if _, found := this.contacts.Load(c.Handle); !found { @@ -64,8 +68,6 @@ func (this *InterfaceState) GetContact(handle string) *gobjects.Contact { group.Accepted, false, }) - - go the.Peer.JoinServer(group.GroupServer) } else { log.Errorf("Attempting to add non existent group to ui %v", handle) } @@ -101,12 +103,12 @@ func (this *InterfaceState) GetContact(handle string) *gobjects.Contact { } func (this *InterfaceState) AddSendMessageError(peer string, signature string, err string) { - acklist := the.AcknowledgementIDs[peer] - for _, ack := range acklist { - if ack.ID == signature { - ack.Error = true - } + ackI, ok := the.AcknowledgementIDs.Load(signature) + if ok { + ack := ackI.(*the.AckId) + ack.Error = true } + messages, _ := this.messages.Load(peer) messageList, _ := messages.([]*gobjects.Message) @@ -132,37 +134,23 @@ func (this *InterfaceState) AddMessage(m *gobjects.Message) { // Ack message sent to group this.parentGcd.Acknowledged(m.MessageID) - // Ack personal messages - // TODO: unify this with the above signature based approach - if m.Message == "ack" { - // If an ack, swallow the message and ack from the list. - acklist := the.AcknowledgementIDs[m.From] - for _, ack := range acklist { - if ack.Error == false { - ack.Ack = true - this.parentGcd.Acknowledged(ack.ID) - } + messages, _ := this.messages.Load(m.Handle) + messageList, _ := messages.([]*gobjects.Message) + this.messages.Store(m.Handle, append(messageList, m)) + + // If we have this group loaded already + if this.parentGcd.CurrentOpenConversation() == m.Handle { + // If the message is not from the user then add it, otherwise, just acknowledge. + if !m.FromMe || !m.Acknowledged { + this.parentGcd.AppendMessage(m.Handle, m.From, m.DisplayName, m.Message, m.Image, m.MessageID, m.FromMe, m.Timestamp.Format(constants.TIME_FORMAT), m.Acknowledged, m.Error) + } else { + this.parentGcd.Acknowledged(m.MessageID) } } else { - - messages, _ := this.messages.Load(m.Handle) - messageList, _ := messages.([]*gobjects.Message) - this.messages.Store(m.Handle, append(messageList, m)) - - // If we have this group loaded already - if this.parentGcd.CurrentOpenConversation() == m.Handle { - // If the message is not from the user then add it, otherwise, just acknowledge. - if !m.FromMe || !m.Acknowledged { - this.parentGcd.AppendMessage(m.Handle, m.From, m.DisplayName, m.Message, m.Image, m.MessageID, m.FromMe, m.Timestamp.Format(constants.TIME_FORMAT), m.Acknowledged, m.Error) - } else { - this.parentGcd.Acknowledged(m.MessageID) - } - } else { - c := this.GetContact(m.Handle) - if c != nil { - c.Badge++ - this.UpdateContact(c.Handle) - } + c := this.GetContact(m.Handle) + if c != nil { + c.Badge++ + this.UpdateContact(c.Handle) } } diff --git a/go/the/globals.go b/go/the/globals.go index fe634706..013a76cb 100644 --- a/go/the/globals.go +++ b/go/the/globals.go @@ -5,6 +5,7 @@ import ( "cwtch.im/cwtch/event" libPeer "cwtch.im/cwtch/peer" "git.openprivacy.ca/openprivacy/libricochet-go/connectivity" + "sync" ) // Terrible, to be replaced when proper profile/password management comes in ~ 0.2 @@ -21,8 +22,9 @@ var IPCBridge event.IPCBridge type AckId struct { ID string + Peer string Ack bool Error bool } -var AcknowledgementIDs map[string][]*AckId +var AcknowledgementIDs sync.Map diff --git a/main.go b/main.go index efb6c68f..919df035 100644 --- a/main.go +++ b/main.go @@ -113,7 +113,6 @@ func mainUi(flagLocal bool, flagClientUI bool) { gcd.SetBuildDate("now") } gcd.UIState = gothings.NewUIState(gcd) - the.AcknowledgementIDs = make(map[string][]*the.AckId) gcd.OutgoingMessages = make(chan gobjects.Letter, 1000) //TODO: put theme stuff somewhere better