diff --git a/go/characters/grouppoller.go b/go/characters/grouppoller.go index ad44a76..0bb3a96 100644 --- a/go/characters/grouppoller.go +++ b/go/characters/grouppoller.go @@ -16,9 +16,11 @@ func GroupPoller(getContact func(string) *gobjects.Contact, updateContact func(s for i := range groups { group := the.Peer.GetGroup(groups[i]) if group != nil && group.GroupID != "" { - log.Debugf("Found a Group: %v %v", group.GroupID, group.GroupServer) - getContact(group.GroupID).Status = int(servers[group.GroupServer]) - updateContact(group.GroupID) + deleted,_ := group.GetAttribute("deleted") + if deleted != "deleted" { + getContact(group.GroupID).Status = int(servers[group.GroupServer]) + updateContact(group.GroupID) + } } else { log.Errorf("grouppoller found a group that is nil :/") } diff --git a/go/characters/presencepoller.go b/go/characters/presencepoller.go index ddd2672..bc015b2 100644 --- a/go/characters/presencepoller.go +++ b/go/characters/presencepoller.go @@ -17,21 +17,25 @@ func PresencePoller(getContact func(string) *gobjects.Contact, addContact func(c if ct == nil { // new contact has attempted to connect with us, treat it as an invite toc := the.Peer.GetContact(contacts[i]) c, _ := the.Peer.GetProfile().GetContact(contacts[i]) - addContact(&gobjects.Contact{ - toc.Onion, - toc.Name, - cwutil.RandomProfileImage(toc.Onion), - "", - 0, - 0, - c.Trusted, - }) + deleted,_ := c.GetAttribute("deleted") - the.CwtchApp.EventBus().Publish(event.NewEvent(event.SetPeerAttribute, map[event.Field]string{ - event.RemotePeer: contacts[i], - event.Key: "name", - event.Data: c.Name, - })) + if deleted != "deleted" { + addContact(&gobjects.Contact{ + toc.Onion, + toc.Name, + cwutil.RandomProfileImage(toc.Onion), + "", + 0, + 0, + c.Trusted, + }) + + the.CwtchApp.EventBus().Publish(event.NewEvent(event.SetPeerAttribute, map[event.Field]string{ + event.RemotePeer: contacts[i], + event.Key: "name", + event.Data: c.Name, + })) + } } cxnState, found := the.Peer.GetPeers()[contacts[i]] diff --git a/go/gothings/gcd.go b/go/gothings/gcd.go index 6be3365..0e95add 100644 --- a/go/gothings/gcd.go +++ b/go/gothings/gcd.go @@ -28,6 +28,7 @@ type GrandCentralDispatcher struct { // contact list stuff _ func(handle, displayName, image, server string, badge, status int, trusted bool) `signal:"AddContact"` _ func(handle, displayName, image, server string, badge, status int, trusted bool) `signal:"UpdateContact"` + _ func(handle, key, value string) `signal:"UpdateContactAttribute"` // messages pane stuff _ func(handle, from, displayName, message, image string, mID uint, fromMe bool, ts string) `signal:"AppendMessage"` @@ -53,11 +54,13 @@ type GrandCentralDispatcher struct { _ func(str string) `signal:"popup,auto"` _ func(nick string) `signal:"updateNick,auto"` _ func(server, groupName string) `signal:"createGroup,auto"` + _ func(groupID string) `signal:"leaveGroup,auto"` _ func() `signal:"requestGroupSettings,auto"` _ func(groupID, nick string) `signal:"saveGroupSettings,auto"` _ func() `signal:"requestPeerSettings,auto"` _ func(onion, nick string) `signal:"savePeerSettings,auto"` _ func(onion, groupID string) `signal:"inviteToGroup,auto"` + _ func(onion, key, nick string) `signal:"setAttribute,auto"` } func (this *GrandCentralDispatcher) sendMessage(message string, mID uint) { @@ -120,8 +123,23 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) { this.SetCurrentOpenConversation(handle) c := this.UIState.GetContact(handle) - c.Badge = 0 - this.UIState.UpdateContact(handle) + if c == nil { + this.UIState.AddContact(&gobjects.Contact{ + handle, + handle, + cwutil.RandomProfileImage(handle), + "", + 0, + 0, + false, + }) + } else { + c.Badge = 0 + this.UIState.UpdateContact(handle) + } + + + if len(handle) == 32 { // LOAD GROUP log.Debugf("LOADING GROUP %s", handle) @@ -255,11 +273,11 @@ func (this *GrandCentralDispatcher) requestGroupSettings() { } } - this.SupplyGroupSettings(this.CurrentOpenConversation(), nick, group.GroupServer, invite, contactnames, contactaddrs) + this.SupplyGroupSettings(group.GroupID, nick, group.GroupServer, invite, contactnames, contactaddrs) } func (this *GrandCentralDispatcher) saveGroupSettings(groupID, nick string) { - group := the.Peer.GetGroup(this.CurrentOpenConversation()) + group := the.Peer.GetGroup(groupID) if group == nil { log.Errorf("couldn't find group %v", groupID) @@ -342,8 +360,12 @@ func (this *GrandCentralDispatcher) importString(str string) { checkc := the.Peer.GetContact(onion) if checkc != nil { - this.InvokePopup("already have this contact") - return //TODO: bring them to the duplicate + deleted,_ := checkc.GetAttribute("deleted") + if deleted != "deleted" { + this.InvokePopup("already have this contact") + return //TODO: bring them to the duplicate + } + this.SetAttribute(onion, "deleted", "") } this.UIState.AddContact(&gobjects.Contact{ @@ -397,4 +419,26 @@ func (this *GrandCentralDispatcher) inviteToGroup(onion, groupID string) { if err != nil { log.Errorf("inviting %v to %v: %v", onion, groupID, err) } +} + +func (this *GrandCentralDispatcher) leaveGroup(groupID string) { + the.CwtchApp.EventBus().Publish(event.NewEvent(event.SetGroupAttribute, map[event.Field]string{ + event.GroupID: groupID, + event.Key: "deleted", + event.Data: "deleted", + })) + this.UIState.UpdateContactAttribute(groupID, "deleted", "deleted") +} + +func (this *GrandCentralDispatcher) setAttribute(onion, key, value string) { + pp,_ := the.Peer.GetProfile().GetContact(onion) + if pp != nil { + pp.SetAttribute(key, value) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.SetPeerAttribute, map[event.Field]string{ + event.RemotePeer: onion, + event.Key: key, + event.Data: value, + })) + this.UIState.UpdateContactAttribute(onion, key, value) + } } \ No newline at end of file diff --git a/go/gothings/uistate.go b/go/gothings/uistate.go index 2751469..e9ed0de 100644 --- a/go/gothings/uistate.go +++ b/go/gothings/uistate.go @@ -49,28 +49,37 @@ func (this *InterfaceState) AddContact(c *gobjects.Contact) { func (this *InterfaceState) GetContact(handle string) *gobjects.Contact { if _, found := this.contacts[handle]; !found { if len(handle) == 32 { - this.AddContact(&gobjects.Contact{ - handle, - handle, - cwutil.RandomGroupImage(handle), - "", - 0, - 0, - false, - }) group := the.Peer.GetGroup(handle) - go the.Peer.JoinServer(group.GroupServer) + if group != nil { + this.AddContact(&gobjects.Contact{ + handle, + handle, + cwutil.RandomGroupImage(handle), + "", + 0, + 0, + false, + }) + + go the.Peer.JoinServer(group.GroupServer) + } else { + log.Errorf("Attempting to add non existent group to ui %v", handle) + } } else { - this.AddContact(&gobjects.Contact{ - handle, - handle, - cwutil.RandomProfileImage(handle), - "", - 0, - 0, - false, - }) - go the.Peer.PeerWithOnion(handle) + contact := the.Peer.GetContact(handle) + if contact != nil && handle != contact.Onion { + this.AddContact(&gobjects.Contact{ + handle, + handle, + cwutil.RandomProfileImage(handle), + "", + 0, + 0, + false, + }) + } else if contact == nil { + log.Errorf("Attempting to add non existent contact to ui %v", handle) + } } } @@ -78,20 +87,9 @@ func (this *InterfaceState) GetContact(handle string) *gobjects.Contact { } func (this *InterfaceState) AddMessage(m *gobjects.Message) { - _, found := this.contacts[m.Handle] - if !found { - this.AddContact(&gobjects.Contact{ - m.Handle, - m.Handle, - cwutil.RandomProfileImage(m.Handle), - "", - 0, - 0, - false, - }) - } + this.GetContact(m.From) - _, found = this.messages[m.Handle] + _, found := this.messages[m.Handle] if !found { this.messages[m.Handle] = make([]*gobjects.Message, 0) } @@ -110,8 +108,10 @@ func (this *InterfaceState) AddMessage(m *gobjects.Message) { this.parentGcd.AppendMessage(m.Handle, m.From, m.DisplayName, m.Message, m.Image, uint(m.MessageID), m.FromMe, m.Timestamp.Format(constants.TIME_FORMAT)) } else { c := this.GetContact(m.Handle) - c.Badge++ - this.UpdateContact(c.Handle) + if c != nil { + c.Badge++ + this.UpdateContact(c.Handle) + } } } @@ -131,3 +131,7 @@ func (this *InterfaceState) UpdateContact(handle string) { this.parentGcd.UpdateContact(c.Handle, c.DisplayName, c.Image, c.Server, c.Badge, c.Status, c.Trusted) } } + +func (this *InterfaceState) UpdateContactAttribute(handle, key, value string) { + this.parentGcd.UpdateContactAttribute(handle, key, value) +} diff --git a/main.go b/main.go index ac6abb7..913571b 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( libapp "cwtch.im/cwtch/app" - "cwtch.im/cwtch/model" "cwtch.im/ui/go/characters" "cwtch.im/ui/go/cwutil" "cwtch.im/ui/go/gobjects" @@ -142,29 +141,34 @@ func loadCwtchData(gcd *gothings.GrandCentralDispatcher, acn connectivity.ACN) { for i := range contacts { contact, _ := the.Peer.GetProfile().GetContact(contacts[i]) displayName, _ := contact.GetAttribute("nick") - gcd.UIState.AddContact(&gobjects.Contact{ - Handle: contacts[i], - DisplayName: displayName, - Image: cwutil.RandomProfileImage(contacts[i]), - Trusted: contact.Trusted, - }) + deleted, _ := contact.GetAttribute("deleted") + if deleted != "deleted" { + gcd.UIState.AddContact(&gobjects.Contact{ + Handle: contacts[i], + DisplayName: displayName, + Image: cwutil.RandomProfileImage(contacts[i]), + Trusted: contact.Trusted, + }) + } } groups := the.Peer.GetGroups() for i := range groups { group := the.Peer.GetGroup(groups[i]) - group.NewMessage = make(chan model.Message) - the.Peer.JoinServer(group.GroupServer) nick, exists := group.GetAttribute("nick") if !exists { nick = group.GroupID[:12] } - gcd.UIState.AddContact(&gobjects.Contact{ - Handle: group.GroupID, - DisplayName: nick, - Image: cwutil.RandomGroupImage(group.GroupID), - Server: group.GroupServer, - Trusted: group.Accepted, - }) + deleted,_ := group.GetAttribute("deleted") + if deleted != "deleted" { + the.Peer.JoinServer(group.GroupServer) + gcd.UIState.AddContact(&gobjects.Contact{ + Handle: group.GroupID, + DisplayName: nick, + Image: cwutil.RandomGroupImage(group.GroupID), + Server: group.GroupServer, + Trusted: group.Accepted, + }) + } } } diff --git a/qml/overlays/ChatOverlay.qml b/qml/overlays/ChatOverlay.qml index bf751d0..b4b980a 100644 --- a/qml/overlays/ChatOverlay.qml +++ b/qml/overlays/ChatOverlay.qml @@ -52,6 +52,9 @@ ColumnLayout { "_ts": ts, }) + // If the window is out of focus, alert the user (makes taskbar light up) + windowItem.alert(0) + if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) { sv.contentY = sv.contentHeight - sv.height } diff --git a/qml/panes/GroupSettingsPane.qml b/qml/panes/GroupSettingsPane.qml index ef2d5c4..b3440e6 100644 --- a/qml/panes/GroupSettingsPane.qml +++ b/qml/panes/GroupSettingsPane.qml @@ -11,6 +11,7 @@ import "../styles" import "../utils.js" as Utils ColumnLayout { // groupSettingsPane + id: gsp anchors.fill: parent property string groupID property variant addrbook @@ -104,13 +105,24 @@ ColumnLayout { // groupSettingsPane } } + SimpleButton { + icon: "regular/trash-alt" + text: "delete" + + onClicked: { + gcd.leaveGroup(groupID) + theStack.pane = theStack.emptyPane + } + } + }//end of column with padding Connections { target: gcd onSupplyGroupSettings: function(gid, name, server, invite, addrbooknames, addrbookaddrs) { - groupID = gid + console.log("Supplied " + gid + " " + name) + gsp.groupID = gid toolbar.text = name txtGroupName.text = name txtServer.text = server diff --git a/qml/panes/PeerSettingsPane.qml b/qml/panes/PeerSettingsPane.qml index 98a9b0e..33bd763 100644 --- a/qml/panes/PeerSettingsPane.qml +++ b/qml/panes/PeerSettingsPane.qml @@ -65,6 +65,16 @@ ColumnLayout { // peerSettingsPane } } + SimpleButton { + icon: "regular/trash-alt" + text: "delete" + + onClicked: { + gcd.setAttribute(txtOnion.text, "deleted", "deleted") + theStack.pane = theStack.emptyPane + } + } + }//end of column with padding diff --git a/qml/widgets/ContactList.qml b/qml/widgets/ContactList.qml index 00de5f0..b01b86d 100644 --- a/qml/widgets/ContactList.qml +++ b/qml/widgets/ContactList.qml @@ -48,8 +48,21 @@ ColumnLayout { "_badge": badge, "_status": status, "_trusted": trusted, + "_deleted": false }) } + + onUpdateContactAttribute: function(handle, key, value) { + if (key == "deleted" && value == "deleted") { + for(var i = 0; i