From 25da6ae0af4b41fe27a24b34afaccdd49a5fc55b Mon Sep 17 00:00:00 2001 From: decentral1se Date: Tue, 25 Jul 2023 11:42:54 +0200 Subject: [PATCH] wip: send/receive messages from contacts --- message.go | 2 ++ model.go | 47 ++++++++++++++++++++++++++++++++++++++++++----- profile.go | 42 +++++++++++++++++++++++++++++++++++++++--- render.go | 21 +++++++++++++++++++++ 4 files changed, 104 insertions(+), 8 deletions(-) diff --git a/message.go b/message.go index 0915dcb..36202eb 100644 --- a/message.go +++ b/message.go @@ -49,3 +49,5 @@ type acnOnMsg struct{} type clearMsg struct{} type profileInfoMsg struct{} + +type startProfileQueuePollMsg struct{ onion string } diff --git a/model.go b/model.go index 800d1a3..f0d7cb0 100644 --- a/model.go +++ b/model.go @@ -2,10 +2,13 @@ package main import ( "fmt" + "log" "path" "strings" "cwtch.im/cwtch/app" + "cwtch.im/cwtch/event" + cwtchModel "cwtch.im/cwtch/model" "git.openprivacy.ca/openprivacy/connectivity" "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/viewport" @@ -125,6 +128,35 @@ func (m model) sendStatus(lines ...string) { } } +func (m model) startProfileQueueCmd(onion string) tea.Cmd { + return func() tea.Msg { + profile := getProfile(m, onion) + peer := m.app.GetPeer(onion) + + log.Printf("PEER ONION: %s", peer.GetOnion()) + log.Printf("CONNECTION STATE: %v", peer.GetPeerState(onion)) + + for { + message := profile.queue.Next() + cid, _ := peer.FetchConversationInfo(message.Data[event.RemotePeer]) + + switch message.EventType { + case event.NewMessageFromPeer: + msg := unpackMessage(message.Data[event.Data]) + log.Printf("RECEIVED MESSAGE: %v\n", msg) + reply := string(packMessage(msg.Overlay, msg.Data)) + peer.SendMessage(cid.ID, reply) + + case event.ContactCreated: + log.Printf("AUTO APPROVING STRANGER: %v %v\n", cid, message.Data[event.RemotePeer]) + peer.AcceptConversation(cid.ID) + reply := string(packMessage(cwtchModel.OverlayChat, "Hello!")) + peer.SendMessage(cid.ID, reply) + } + } + } +} + func (m model) Init() tea.Cmd { return tea.Batch( textinput.Blink, @@ -265,8 +297,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.profiles = append(m.profiles, newProfile) - // TODO - // cmds = append(cmds, startProfileCmd(m, newProfile.onion)) + cmds = append(cmds, func() tea.Msg { + return startProfileCmd(&m, newProfile.onion) + }) m.menuBar = append(m.menuBar, strings.ToUpper(msg.name)) @@ -288,8 +321,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { for _, profile := range profiles { m.menuBar = append(m.menuBar, strings.ToUpper(profile.name)) - // TODO - // cmds = append(cmds, startProfileCmd(m, profile.onion)) + cmds = append(cmds, func() tea.Msg { + return startProfileCmd(&m, profile.onion) + }) } m.profiles = profiles @@ -312,6 +346,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { fmt.Sprintf("Profile onion: %s", profile.onion), )) + case startProfileQueuePollMsg: + cmds = append(cmds, m.startProfileQueueCmd(msg.onion)) + case sendStatusMsg: cmds = append(cmds, func() tea.Msg { for _, line := range msg.lines { @@ -350,7 +387,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.app = msg.app m.acn = msg.acn m.connState = connected - m.app.ActivateEngines(true, true, false) + m.app.ActivateEngines(true, true, true) case errMsg: cmds = append(cmds, m.sendStatusCmd(msg.Error())) diff --git a/profile.go b/profile.go index 6527578..aa20113 100644 --- a/profile.go +++ b/profile.go @@ -1,6 +1,7 @@ package main import ( + "cwtch.im/cwtch/event" "cwtch.im/cwtch/model/attr" "cwtch.im/cwtch/model/constants" "github.com/charmbracelet/bubbles/viewport" @@ -11,6 +12,8 @@ type profile struct { name string onion string statusViewport viewport.Model + queue event.Queue + eventBus event.Manager } type profiles []profile @@ -23,6 +26,24 @@ func (ps profiles) names() []string { return names } +func getProfile(m model, onion string) profile { + var profile profile + for _, p := range m.profiles { + if p.onion == onion { + profile = p + } + } + return profile +} + +func setProfile(m *model, profile profile) { + for idx, p := range m.profiles { + if p.onion == profile.onion { + m.profiles[idx] = profile + } + } +} + func unlockProfiles(m model, password string) profiles { var unlocked []profile @@ -41,7 +62,22 @@ func unlockProfiles(m model, password string) profiles { return unlocked } -func startProfileCmd(m model, onion string) tea.Msg { - // https://git.openprivacy.ca/sarah/cwtchbot/src/branch/main/bot.go - return nil +func startProfileCmd(m *model, onion string) tea.Msg { + profile := getProfile(*m, onion) + + profile.queue = event.NewQueue() + profile.eventBus = m.app.GetEventBus(onion) + + profile.eventBus.Subscribe(event.NewMessageFromPeer, profile.queue) + profile.eventBus.Subscribe(event.PeerAcknowledgement, profile.queue) + profile.eventBus.Subscribe(event.SendMessageToPeerError, profile.queue) + profile.eventBus.Subscribe(event.PeerStateChange, profile.queue) + profile.eventBus.Subscribe(event.NewGetValMessageFromPeer, profile.queue) + profile.eventBus.Subscribe(event.ContactCreated, profile.queue) + + setProfile(m, profile) + + m.app.ActivatePeerEngine(profile.onion) + + return startProfileQueuePollMsg{onion: onion} } diff --git a/render.go b/render.go index 61d388a..173b7d4 100644 --- a/render.go +++ b/render.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "strings" "time" @@ -89,3 +90,23 @@ func renderCmdHelp(m model) []string { return renderedCmdHelp } + +// https://git.openprivacy.ca/sarah/cwtchbot/src/branch/main/bot.go +type MessageWrapper struct { + Overlay int `json:"o"` + Data string `json:"d"` +} + +func packMessage(overlay int, message string) []byte { + mw := new(MessageWrapper) + mw.Overlay = overlay + mw.Data = message + data, _ := json.Marshal(mw) + return data +} + +func unpackMessage(message string) MessageWrapper { + mw := new(MessageWrapper) + json.Unmarshal([]byte(message), mw) + return *mw +}