diff --git a/go/characters/grouppoller.go b/go/characters/grouppoller.go index 1bc6a73..33e174b 100644 --- a/go/characters/grouppoller.go +++ b/go/characters/grouppoller.go @@ -3,6 +3,7 @@ package characters import ( "cwtch.im/ui/go/gobjects" "cwtch.im/ui/go/the" + "git.openprivacy.ca/openprivacy/libricochet-go/log" "time" ) @@ -14,8 +15,12 @@ func GroupPoller(getContact func(string) *gobjects.Contact, updateContact func(s groups := the.Peer.GetGroups() for i := range groups { group := the.Peer.GetGroup(groups[i]) - getContact(group.GroupID).Status = int(servers[group.GroupServer]) - updateContact(group.GroupID) + if group != nil { + 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/incominglistener.go b/go/characters/incominglistener.go new file mode 100644 index 0000000..1d39bbd --- /dev/null +++ b/go/characters/incominglistener.go @@ -0,0 +1,40 @@ +package characters + +import ( + "cwtch.im/cwtch/event" + "cwtch.im/ui/go/cwutil" + "cwtch.im/ui/go/gobjects" + "cwtch.im/ui/go/the" + "time" +) + +func IncomingListener(callback func(*gobjects.Message)) { + q := event.NewEventQueue(1000) + the.CwtchApp.EventBus().Subscribe(event.NewMessageFromPeer, q.EventChannel) + the.CwtchApp.EventBus().Subscribe(event.NewMessageFromGroup, q.EventChannel) + + 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]) + callback(&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, + }) + case event.NewMessageFromGroup://event.TimestampReceived, event.TimestampSent, event.Data, event.GroupID, event.RemotePeer + ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampReceived]) + callback(&gobjects.Message{ + Handle: e.Data[event.GroupID], + From: e.Data[event.RemotePeer], + Message: e.Data[event.Data], + Image: cwutil.RandomGroupImage(e.Data[event.GroupID]), + Timestamp: ts, + }) + } + } +} \ No newline at end of file diff --git a/go/characters/postmanpat.go b/go/characters/postmanpat.go index 18dae10..8c45d38 100644 --- a/go/characters/postmanpat.go +++ b/go/characters/postmanpat.go @@ -3,7 +3,6 @@ package characters import ( "cwtch.im/ui/go/gobjects" "cwtch.im/ui/go/the" - "git.openprivacy.ca/openprivacy/libricochet-go/channels" "git.openprivacy.ca/openprivacy/libricochet-go/log" ) @@ -26,14 +25,9 @@ func PostmanPat(messages chan gobjects.Letter) { func andHisBlackAndWhiteCat(incomingMessages chan gobjects.Letter) { for { m := <-incomingMessages - connection := the.Peer.PeerWithOnion(m.To) - connection.WaitTilAuthenticated() - connection.DoOnChannel("im.ricochet.chat", channels.Outbound, func(channel *channels.Channel) { - chatchannel, ok := channel.Handler.(*channels.ChatChannel) - if ok { - log.Debugln("Sending packet") - the.AcknowledgementIDs[chatchannel.SendMessage(m.Message)] = m.MID - } - }) + the.Peer.PeerWithOnion(m.To) + log.Debugf("sending message!") + id := the.Peer.SendMessageToPeer(m.To, m.Message) + the.AcknowledgementIDs[id] = m.MID } } diff --git a/go/characters/presencepoller.go b/go/characters/presencepoller.go index 87d4f08..87bfafa 100644 --- a/go/characters/presencepoller.go +++ b/go/characters/presencepoller.go @@ -1,6 +1,7 @@ package characters import ( + "cwtch.im/cwtch/event" "cwtch.im/ui/go/cwutil" "cwtch.im/ui/go/gobjects" "cwtch.im/ui/go/the" @@ -26,7 +27,7 @@ func PresencePoller(getContact func(string) *gobjects.Contact, addContact func(c c.Trusted, }) c.SetAttribute("name", c.Name) - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) } cxnState, found := the.Peer.GetPeers()[contacts[i]] diff --git a/go/cwtchthings/chatchannellistener.go b/go/cwtchthings/chatchannellistener.go deleted file mode 100644 index a0924c9..0000000 --- a/go/cwtchthings/chatchannellistener.go +++ /dev/null @@ -1,60 +0,0 @@ -package cwtchthings - -import ( - "cwtch.im/ui/go/cwutil" - "cwtch.im/ui/go/gobjects" - "cwtch.im/ui/go/the" - "git.openprivacy.ca/openprivacy/libricochet-go/application" - "git.openprivacy.ca/openprivacy/libricochet-go/channels" - "time" -) - -type ChatChannelListener struct { - rai *application.ApplicationInstance - ra *application.RicochetApplication - addMessage func(*gobjects.Message) - acknowledged func(uint) -} - -func (this *ChatChannelListener) Init(rai *application.ApplicationInstance, ra *application.RicochetApplication, addMessage func(*gobjects.Message), acknowledged func(uint)) { - this.rai = rai - this.ra = ra - this.addMessage = addMessage - this.acknowledged = acknowledged -} - -// We always want bidirectional chat channels -func (this *ChatChannelListener) OpenInbound() { - outboutChatChannel := this.rai.Connection.Channel("im.ricochet.chat", channels.Outbound) - if outboutChatChannel == nil { - this.rai.Connection.Do(func() error { - this.rai.Connection.RequestOpenChannel("im.ricochet.chat", - &channels.ChatChannel{ - Handler: this, - }) - return nil - }) - } -} - -func (this *ChatChannelListener) ChatMessage(messageID uint32, when time.Time, message string) bool { - this.addMessage(&gobjects.Message{ - this.rai.RemoteHostname, - this.rai.RemoteHostname, - "", - message, - cwutil.RandomProfileImage(this.rai.RemoteHostname), - false, - int(messageID), - when, - }) - go func() { // TODO: this is probably no longer necessary. check later - time.Sleep(time.Second) - the.CwtchApp.SaveProfile(the.Peer) - }() - return true -} - -func (this *ChatChannelListener) ChatMessageAck(messageID uint32, accepted bool) { - this.acknowledged(the.AcknowledgementIDs[messageID]) -} diff --git a/go/gothings/gcd.go b/go/gothings/gcd.go index d67f873..5f87c74 100644 --- a/go/gothings/gcd.go +++ b/go/gothings/gcd.go @@ -1,6 +1,7 @@ package gothings import ( + "cwtch.im/cwtch/event" "cwtch.im/ui/go/constants" "cwtch.im/ui/go/cwutil" @@ -68,7 +69,7 @@ func (this *GrandCentralDispatcher) sendMessage(message string, mID uint) { if len(this.CurrentOpenConversation()) == 32 { // SEND TO GROUP if !the.Peer.GetGroup(this.CurrentOpenConversation()).Accepted { the.Peer.GetGroup(this.CurrentOpenConversation()).Accepted = true - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) c := this.UIState.GetContact(this.CurrentOpenConversation()) c.Trusted = true this.UIState.UpdateContact(c.Handle) @@ -121,7 +122,7 @@ func (this *GrandCentralDispatcher) loadMessagesPane(handle string) { } var name string var exists bool - name, exists = the.Peer.GetProfile().GetCustomAttribute(tl[i].PeerID + "_name") + name, exists = the.Peer.GetProfile().GetAttribute(tl[i].PeerID + "_name") if !exists || name == "" { name = tl[i].PeerID[:16] + "..." } @@ -201,11 +202,19 @@ func (this *GrandCentralDispatcher) importString(str string) { } group := the.Peer.GetGroup(groupID) + + log.Debugf("group id: %s", groupID) + if group == nil { + log.Debugf("group IS nil. bad!") + } else { + log.Debugf("group is NOT nil. good!") + } + the.Peer.JoinServer(group.GroupServer) - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) this.UIState.AddContact(&gobjects.Contact{ - groupID[:12], groupID, + groupID[:12], cwutil.RandomGroupImage(groupID), group.GroupServer, 0, @@ -250,26 +259,23 @@ func (this *GrandCentralDispatcher) importString(str string) { return } - _, exists := the.Peer.GetProfile().GetCustomAttribute(name + "_onion") + _, exists := the.Peer.GetProfile().GetAttribute(name + "_onion") if exists { this.InvokePopup("can't re-use names :(") return } - _, exists = the.Peer.GetProfile().GetCustomAttribute(onion + "_name") + _, exists = the.Peer.GetProfile().GetAttribute(onion + "_name") if exists { this.InvokePopup("already have this contact") return //TODO: bring them to the duplicate } this.UIState.AddContact(&gobjects.Contact{ - onion, - name, - cwutil.RandomProfileImage(onion), - "", - 0, - 0, - true, + Handle: onion, + DisplayName: name, + Image: cwutil.RandomProfileImage(onion), + Trusted: true, }) } @@ -279,7 +285,7 @@ func (this *GrandCentralDispatcher) popup(str string) { func (this *GrandCentralDispatcher) updateNick(nick string) { the.Peer.GetProfile().Name = nick - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) } func (this *GrandCentralDispatcher) createGroup(server, groupName string) { @@ -290,18 +296,16 @@ func (this *GrandCentralDispatcher) createGroup(server, groupName string) { } this.UIState.AddContact(&gobjects.Contact{ - groupID, - groupName, - cwutil.RandomGroupImage(groupID), - server, - 0, - 0, - true, + Handle: groupID, + DisplayName: groupName, + Image: cwutil.RandomGroupImage(groupID), + Server: server, + Trusted: true, }) group := the.Peer.GetGroup(groupID) group.SetAttribute("nick", groupName) - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) the.Peer.JoinServer(server) group.NewMessage = make(chan model.Message) diff --git a/go/gothings/uistate.go b/go/gothings/uistate.go index d280bcc..dab29b6 100644 --- a/go/gothings/uistate.go +++ b/go/gothings/uistate.go @@ -1,6 +1,7 @@ package gothings import ( + "cwtch.im/cwtch/event" "cwtch.im/cwtch/model" "cwtch.im/ui/go/constants" "cwtch.im/ui/go/gobjects" @@ -45,7 +46,7 @@ func (this *InterfaceState) AddContact(c *gobjects.Contact) { if c.Trusted { the.Peer.GetProfile().TrustPeer(c.Handle) } - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) go the.Peer.PeerWithOnion(c.Handle) } @@ -54,7 +55,7 @@ func (this *InterfaceState) AddContact(c *gobjects.Contact) { this.parentGcd.AddContact(c.Handle, c.DisplayName, c.Image, c.Server, c.Badge, c.Status, c.Trusted) } - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) } func (this *InterfaceState) GetContact(handle string) *gobjects.Contact { @@ -98,7 +99,7 @@ func (this *InterfaceState) AddMessage(m *gobjects.Message) { c.Badge++ this.UpdateContact(c.Handle) } - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) } func (this *InterfaceState) GetMessages(handle string) []*gobjects.Message { diff --git a/go/the/globals.go b/go/the/globals.go index b6869e8..5cc8f69 100644 --- a/go/the/globals.go +++ b/go/the/globals.go @@ -8,4 +8,4 @@ import ( var CwtchApp app.Application var Peer libPeer.CwtchPeer var CwtchDir string -var AcknowledgementIDs map[uint32]uint +var AcknowledgementIDs map[string]uint diff --git a/main.go b/main.go index 98d6b54..c37e2bc 100644 --- a/main.go +++ b/main.go @@ -2,16 +2,14 @@ package main import ( libapp "cwtch.im/cwtch/app" + "cwtch.im/cwtch/event" "cwtch.im/cwtch/model" "cwtch.im/ui/go/characters" - "cwtch.im/ui/go/cwtchthings" "cwtch.im/ui/go/cwutil" "cwtch.im/ui/go/gobjects" "cwtch.im/ui/go/gothings" "cwtch.im/ui/go/the" "fmt" - "git.openprivacy.ca/openprivacy/libricochet-go/application" - "git.openprivacy.ca/openprivacy/libricochet-go/channels" "git.openprivacy.ca/openprivacy/libricochet-go/connectivity" "git.openprivacy.ca/openprivacy/libricochet-go/log" "github.com/therecipe/qt/core" @@ -29,10 +27,12 @@ func init() { } func main() { + log.SetLevel(log.LevelDebug) + // our globals gcd := gothings.NewGrandCentralDispatcher(nil) gcd.UIState = gothings.NewUIState(gcd) - the.AcknowledgementIDs = make(map[uint32]uint) + the.AcknowledgementIDs = make(map[string]uint) gcd.OutgoingMessages = make(chan gobjects.Letter, 1000) //TODO: put theme stuff somewhere better @@ -57,6 +57,7 @@ func main() { // these are long-lived pollers/listeners for incoming messages and status changes loadCwtchData(gcd) + go characters.IncomingListener(gcd.UIState.AddMessage) go characters.PostmanPat(gcd.OutgoingMessages) go characters.TorStatusPoller(gcd.TorStatus) go characters.PresencePoller(gcd.UIState.GetContact, gcd.UIState.AddContact, gcd.UIState.UpdateContact) @@ -126,26 +127,12 @@ func loadCwtchData(gcd *gothings.GrandCentralDispatcher) { log.Errorf("couldn't create one. is your cwtch folder writable?") os.Exit(1) } - the.CwtchApp.SaveProfile(the.Peer) + the.CwtchApp.EventBus().Publish(event.NewEvent(event.RequestProfileSave, map[event.Field]string{})) } else { the.Peer = the.CwtchApp.PrimaryIdentity() } gcd.UpdateMyProfile(the.Peer.GetProfile().Name, the.Peer.GetProfile().Onion, cwutil.RandomProfileImage(the.Peer.GetProfile().Onion)) - - aif := application.ApplicationInstanceFactory{} - aif.Init() - app := new(application.RicochetApplication) - aif.AddHandler("im.ricochet.chat", func(rai *application.ApplicationInstance) func() channels.Handler { - ccl := new(cwtchthings.ChatChannelListener) - ccl.Init(rai, app, gcd.UIState.AddMessage, gcd.Acknowledged) - return func() channels.Handler { - chat := new(channels.ChatChannel) - chat.Handler = ccl - return chat - } - }) - the.Peer.SetApplicationInstanceFactory(aif) the.CwtchApp.LaunchPeers() contacts := the.Peer.GetContacts() @@ -153,13 +140,10 @@ func loadCwtchData(gcd *gothings.GrandCentralDispatcher) { contact, _ := the.Peer.GetProfile().GetContact(contacts[i]) displayName, _ := contact.GetAttribute("name") gcd.UIState.AddContact(&gobjects.Contact{ - contacts[i], - displayName, - cwutil.RandomProfileImage(contacts[i]), - "", - 0, - 0, - contact.Trusted, + Handle: contacts[i], + DisplayName: displayName, + Image: cwutil.RandomProfileImage(contacts[i]), + Trusted: contact.Trusted, }) } @@ -168,20 +152,17 @@ func loadCwtchData(gcd *gothings.GrandCentralDispatcher) { log.Infof("adding saved group %v", groups[i]) group := the.Peer.GetGroup(groups[i]) group.NewMessage = make(chan model.Message) - go characters.CwtchListener(gcd.UIState.AddMessage, groups[i], group.NewMessage) the.Peer.JoinServer(group.GroupServer) nick, exists := group.GetAttribute("nick") if !exists { nick = group.GroupID[:12] } gcd.UIState.AddContact(&gobjects.Contact{ - group.GroupID, - nick, - cwutil.RandomGroupImage(group.GroupID), - group.GroupServer, - 0, - 0, - group.Accepted, + Handle: group.GroupID, + DisplayName: nick, + Image: cwutil.RandomGroupImage(group.GroupID), + Server: group.GroupServer, + Trusted: group.Accepted, }) } }