From 752403fd523f287020dfcc6cdd3bf6d304365672 Mon Sep 17 00:00:00 2001 From: Kyren223 Date: Tue, 4 Feb 2025 19:32:04 +0200 Subject: Implemented notifications rework on the client --- internal/client/ui/core/chat/chat.go | 14 ++--- internal/client/ui/core/core.go | 26 +-------- internal/client/ui/core/state/state.go | 100 +++++++++++++++++---------------- 3 files changed, 63 insertions(+), 77 deletions(-) (limited to 'internal') diff --git a/internal/client/ui/core/chat/chat.go b/internal/client/ui/core/chat/chat.go index 10c7b99..7d4ec6a 100644 --- a/internal/client/ui/core/chat/chat.go +++ b/internal/client/ui/core/chat/chat.go @@ -218,13 +218,13 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { if m.base != SnapToBottom { m.keepLastRead = false } else if lastMsg != nil { - lastReadMsg := state.Data.LastReadMessage[frequency.ID] + lastReadMsg := state.State.LastReadMessages[frequency.ID] if m.keepLastRead && m.lastReadMsg != nil && lastReadMsg != nil && *lastReadMsg != *lastMsg && *lastReadMsg != *m.lastReadMsg { m.keepLastRead = false } - state.Data.LastReadMessage[frequency.ID] = lastMsg + state.State.LastReadMessages[frequency.ID] = lastMsg } m.hasReadAccess = frequency.Perms != packet.PermNoAccess || member.IsAdmin @@ -269,13 +269,13 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { if m.base != SnapToBottom { m.keepLastRead = false } else if lastMsg != nil { - lastReadMsg := state.Data.LastReadMessage[receiverId] + lastReadMsg := state.State.LastReadMessages[receiverId] if m.keepLastRead && m.lastReadMsg != nil && lastReadMsg != nil && *lastReadMsg != *lastMsg && *lastReadMsg != *m.lastReadMsg { m.keepLastRead = false } - state.Data.LastReadMessage[receiverId] = lastMsg + state.State.LastReadMessages[receiverId] = lastMsg } } @@ -750,7 +750,7 @@ func (m *Model) RestoreAfterSwitch() tea.Cmd { frequency := frequencies[m.frequencyIndex] log.Println("Restoring frequency:", frequency.ID) - m.lastReadMsg = state.Data.LastReadMessage[frequency.ID] + m.lastReadMsg = state.State.LastReadMessages[frequency.ID] lastMsg := state.GetLastMessage(frequency.ID) if m.lastReadMsg != nil && lastMsg != nil && *m.lastReadMsg != *lastMsg { m.keepLastRead = true @@ -773,7 +773,7 @@ func (m *Model) RestoreAfterSwitch() tea.Cmd { receiverId := state.Data.Peers[m.receiverIndex] log.Println("Restoring signal:", receiverId) - m.lastReadMsg = state.Data.LastReadMessage[receiverId] + m.lastReadMsg = state.State.LastReadMessages[receiverId] lastMsg := state.GetLastMessage(receiverId) if m.lastReadMsg != nil && lastMsg != nil && *m.lastReadMsg != *lastMsg { m.keepLastRead = true @@ -895,7 +895,7 @@ func (m *Model) renderMessages(screenHeight int) string { renderedGroups := []string{} group := []data.Message{} - lastReadId := state.Data.LastReadMessage[*id] + lastReadId := state.State.LastReadMessages[*id] if m.keepLastRead { lastReadId = m.lastReadMsg } diff --git a/internal/client/ui/core/core.go b/internal/client/ui/core/core.go index eb07593..70c871f 100644 --- a/internal/client/ui/core/core.go +++ b/internal/client/ui/core/core.go @@ -1,7 +1,6 @@ package core import ( - "context" "crypto/ed25519" "fmt" "log" @@ -189,9 +188,6 @@ func (m *Model) updateNotConnected(msg tea.Msg) tea.Cmd { switch msg := msg.(type) { case gateway.ConnectionEstablished: state.UserID = (*snowflake.ID)(&msg) - state.ReceivedData = false - state.ReceivedNetworks = false - state.AskedForNotifs = false m.connected = true m.timeout = initialTimeout @@ -260,26 +256,9 @@ func (m *Model) updateConnected(msg tea.Msg) tea.Cmd { m.memberList.SetWidth(sidebarWidth) m.chat.SetWidth(chatWidth) - if state.ReceivedData && state.ReceivedNetworks && !state.AskedForNotifs { - state.AskedForNotifs = true - state.AskForNotifs() - } - switch msg := msg.(type) { case ui.QuitMsg: - data := state.JsonUserData() - ch := gateway.SendAsync(&packet.SetUserData{ - Data: &data, - User: nil, - }) - - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) - select { - case <-ctx.Done(): - case <-ch: - } - cancel() - + state.SendFinalData() // blocks gateway.Disconnect() case gateway.ConnectionLost: @@ -702,6 +681,7 @@ func (m *Model) HasPopup() bool { } func calculateNotifications() { + // TODO: handle notifications for receiver id for networkId := range state.State.Networks { for _, frequency := range state.State.Frequencies[networkId] { if _, ok := state.State.Messages[frequency.ID]; !ok { @@ -719,7 +699,7 @@ func calculateNotifications() { } func getFrequencyNotification(networkId, frequencyId snowflake.ID) (_ int, _ bool) { - lastReadMsg := state.Data.LastReadMessage[frequencyId] + lastReadMsg := state.State.LastReadMessages[frequencyId] if lastReadMsg == nil { return 0, false } diff --git a/internal/client/ui/core/state/state.go b/internal/client/ui/core/state/state.go index 1115c13..c1dd4cd 100644 --- a/internal/client/ui/core/state/state.go +++ b/internal/client/ui/core/state/state.go @@ -1,9 +1,11 @@ package state import ( + "context" "crypto/ed25519" "encoding/json" "slices" + "time" "github.com/google/btree" "github.com/kyren223/eko/internal/client/gateway" @@ -20,8 +22,8 @@ type ChatState struct { } type state struct { - ChatState map[snowflake.ID]ChatState // key is frequency id or receiver id - LastFrequency map[snowflake.ID]snowflake.ID // key is network id + ChatState map[snowflake.ID]ChatState // key is frequency id or receiver id + LastFrequency map[snowflake.ID]snowflake.ID // key is network id Messages map[snowflake.ID]*btree.BTreeG[data.Message] // key is frequency id or receiver id Networks map[snowflake.ID]data.Network // key is network id @@ -30,41 +32,35 @@ type state struct { Users map[snowflake.ID]data.User // key is user id Trusteds map[snowflake.ID]ed25519.PublicKey // key is user id - Notifications map[snowflake.ID]int // key is frequency id or receiver id + LastReadMessages map[snowflake.ID]*snowflake.ID // key is frequency id or receiver id + Notifications map[snowflake.ID]int // key is frequency id or receiver id } var State state = state{ - ChatState: map[snowflake.ID]ChatState{}, - LastFrequency: map[snowflake.ID]snowflake.ID{}, - Messages: map[snowflake.ID]*btree.BTreeG[data.Message]{}, - Networks: map[snowflake.ID]data.Network{}, - Frequencies: map[snowflake.ID][]data.Frequency{}, - Members: map[snowflake.ID]map[snowflake.ID]data.Member{}, - Users: map[snowflake.ID]data.User{}, - Trusteds: map[snowflake.ID]ed25519.PublicKey{}, - Notifications: map[snowflake.ID]int{}, + ChatState: map[snowflake.ID]ChatState{}, + LastFrequency: map[snowflake.ID]snowflake.ID{}, + Messages: map[snowflake.ID]*btree.BTreeG[data.Message]{}, + Networks: map[snowflake.ID]data.Network{}, + Frequencies: map[snowflake.ID][]data.Frequency{}, + Members: map[snowflake.ID]map[snowflake.ID]data.Member{}, + Users: map[snowflake.ID]data.User{}, + Trusteds: map[snowflake.ID]ed25519.PublicKey{}, + Notifications: map[snowflake.ID]int{}, + LastReadMessages: map[snowflake.ID]*snowflake.ID{}, } type UserData struct { - LastReadMessage map[snowflake.ID]*snowflake.ID - Networks []snowflake.ID - Peers []snowflake.ID + Networks []snowflake.ID + Peers []snowflake.ID } var Data UserData = UserData{ - LastReadMessage: map[snowflake.ID]*snowflake.ID{}, - Networks: []snowflake.ID{}, - Peers: []snowflake.ID{}, + Networks: []snowflake.ID{}, + Peers: []snowflake.ID{}, } var UserID *snowflake.ID = nil -var ( - ReceivedData = false - ReceivedNetworks = false - AskedForNotifs = false -) - func UpdateNetworks(info *packet.NetworksInfo) { networks := State.Networks @@ -117,8 +113,6 @@ func UpdateNetworks(info *packet.NetworksInfo) { Data: &data, User: nil, }) - - ReceivedNetworks = true } func UpdateFrequencies(info *packet.FrequenciesInfo) { @@ -232,11 +226,6 @@ func FromJsonUserData(s string) { return } Data = data - if Data.LastReadMessage == nil { - Data.LastReadMessage = map[snowflake.ID]*snowflake.ID{} - } - - ReceivedData = true } func UpdateTrusteds(info *packet.TrustInfo) { @@ -280,29 +269,46 @@ func UpdateNotifications(info *packet.NotificationsInfo) { } } -func AskForNotifs() { - source := []snowflake.ID{} +func SendFinalData() { + data := JsonUserData() + ch1 := gateway.SendAsync(&packet.SetUserData{ + Data: &data, + User: nil, + }) + + sources := []snowflake.ID{} - source = append(source, Data.Peers...) - for networkId := range State.Networks { - for _, frequency := range State.Frequencies[networkId] { - source = append(source, frequency.ID) + sources = append(sources, Data.Peers...) + for _, frequencies := range State.Frequencies { + for _, frequency := range frequencies { + sources = append(sources, frequency.ID) } } - lastReadId := make([]snowflake.ID, 0, len(source)) - - for _, source := range source { - id := Data.LastReadMessage[source] - if id == nil { - lastReadId = append(lastReadId, 0) + lastReads := make([]int64, 0, len(sources)) + for _, source := range sources { + if lastRead := State.LastReadMessages[source]; lastRead != nil { + lastReads = append(lastReads, int64(*lastRead)) } else { - lastReadId = append(lastReadId, *id) + lastReads = append(lastReads, 0) } } - gateway.SendAsync(&packet.GetNotifications{ - Source: source, - LastReadId: lastReadId, + ch2 := gateway.SendAsync(&packet.SetLastReadMessages{ + Source: sources, + LastRead: lastReads, }) + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + select { + case <-ctx.Done(): + case <-ch1: + } + + select { + case <-ctx.Done(): + case <-ch2: + } } -- cgit v1.3.1