summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorKyren223 <Kyren223@proton.me>2025-02-05 19:41:34 +0200
committerKyren223 <Kyren223@proton.me>2025-02-05 19:41:34 +0200
commit0bf5515629f1cfe1557dba4f8d588ac64b77d408 (patch)
tree2bfc56b990c6edd6bab6ddf7b10964b0efb1dbcb /internal
parent8a8c4e9abc1006da92969e0234bb2d42f587c149 (diff)
When a user sends a message "signal" and the receiving user doesn't have
the signal already open, it will be added as the first signal
Diffstat (limited to 'internal')
-rw-r--r--internal/client/ui/core/chat/chat.go28
-rw-r--r--internal/client/ui/core/core.go14
-rw-r--r--internal/client/ui/core/signallist/signallist.go4
-rw-r--r--internal/client/ui/core/state/state.go58
-rw-r--r--internal/data/notifications.sql.go17
-rw-r--r--internal/server/api/api.go10
-rw-r--r--internal/server/api/helpers.go7
-rw-r--r--internal/server/server.go4
8 files changed, 111 insertions, 31 deletions
diff --git a/internal/client/ui/core/chat/chat.go b/internal/client/ui/core/chat/chat.go
index aba65a2..37fc1a8 100644
--- a/internal/client/ui/core/chat/chat.go
+++ b/internal/client/ui/core/chat/chat.go
@@ -277,6 +277,26 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
state.State.LastReadMessages[receiverId] = lastMsg
}
+
+ m.hasReadAccess = true
+ m.hasWriteAccess = true // TODO: implement blocking users
+
+ if m.locked {
+ m.vi.Placeholder = SendMessagePlaceholder
+ m.borderStyle = ViFocusedBorder
+ m.style = focusStyle
+ m.vi.SetInactive(false)
+ m.vi.Focus()
+ if m.editingMessage != nil {
+ m.borderStyle = ViEditBorder
+ m.style = editStyle
+ }
+ } else {
+ m.vi.Placeholder = SendMessagePlaceholder
+ m.borderStyle = ViBlurredBorder
+ m.style = blurStyle
+ m.vi.SetInactive(false)
+ }
}
if !m.focus {
@@ -734,8 +754,6 @@ func (m *Model) ResetBeforeSwitch() {
MaxHeight: m.maxMessagesHeight,
}
- state.SendUserDatUpdate()
-
} else if m.receiverIndex != -1 {
receiverId := state.Data.Signals[m.receiverIndex]
log.Println("Saving signal:", receiverId)
@@ -744,8 +762,6 @@ func (m *Model) ResetBeforeSwitch() {
Base: m.base,
MaxHeight: m.maxMessagesHeight,
}
-
- state.SendUserDatUpdate()
}
}
@@ -772,6 +788,8 @@ func (m *Model) RestoreAfterSwitch() tea.Cmd {
// Don't ask for messages if you already visited this frequency
return nil
}
+
+ log.Println("Requesting frequency messages")
return gateway.Send(&packet.RequestMessages{
ReceiverID: nil,
FrequencyID: &frequency.ID,
@@ -795,6 +813,8 @@ func (m *Model) RestoreAfterSwitch() tea.Cmd {
// Don't ask for messages if you already visited this frequency
return nil
}
+
+ log.Println("Requesting signal messages:", receiverId)
return gateway.Send(&packet.RequestMessages{
ReceiverID: &receiverId,
FrequencyID: nil,
diff --git a/internal/client/ui/core/core.go b/internal/client/ui/core/core.go
index b87600d..60225d8 100644
--- a/internal/client/ui/core/core.go
+++ b/internal/client/ui/core/core.go
@@ -5,6 +5,7 @@ import (
"fmt"
"log"
"math"
+ "slices"
"time"
"github.com/atotto/clipboard"
@@ -191,8 +192,6 @@ func (m *Model) updateNotConnected(msg tea.Msg) tea.Cmd {
m.connected = true
m.timeout = initialTimeout
- requestUserData := gateway.Send(&packet.GetUserData{})
-
var setName tea.Cmd
if m.name != "" {
setName = gateway.Send(&packet.SetUserData{
@@ -206,7 +205,7 @@ func (m *Model) updateNotConnected(msg tea.Msg) tea.Cmd {
m.name = ""
}
- return tea.Batch(m.timer.Stop(), requestUserData, setName)
+ return tea.Batch(m.timer.Stop(), setName)
case gateway.ConnectionFailed:
log.Println("failed to connect:", msg)
@@ -323,7 +322,14 @@ func (m *Model) updateConnected(msg tea.Msg) tea.Cmd {
state.UpdateTrusteds(msg)
case *packet.NotificationsInfo:
- state.UpdateNotifications(msg)
+ signals := state.UpdateNotifications(msg)
+ if m.networkList.Index() == networklist.SignalsIndex {
+ m.chat.SetReceiver(-1)
+ state.Data.Signals = slices.Insert(state.Data.Signals, 0, signals...)
+ return m.chat.SetReceiver(m.signalList.Index())
+ } else {
+ state.Data.Signals = slices.Insert(state.Data.Signals, 0, signals...)
+ }
case ui.BanReasonPopupMsg:
popup := banreason.New(msg.User, msg.Network)
diff --git a/internal/client/ui/core/signallist/signallist.go b/internal/client/ui/core/signallist/signallist.go
index e6fccb9..c9fad95 100644
--- a/internal/client/ui/core/signallist/signallist.go
+++ b/internal/client/ui/core/signallist/signallist.go
@@ -28,8 +28,8 @@ var (
MarginBottom(1).Padding(1, 2).Align(lipgloss.Center).
Border(lipgloss.ThickBorder(), false, false, true)
- margin = 2
- padding = 1
+ margin = 2
+ padding = 1
signalStyle = lipgloss.NewStyle().
Margin(0, margin).Padding(0, padding).Align(lipgloss.Left)
diff --git a/internal/client/ui/core/state/state.go b/internal/client/ui/core/state/state.go
index 658c218..8c6dfeb 100644
--- a/internal/client/ui/core/state/state.go
+++ b/internal/client/ui/core/state/state.go
@@ -4,6 +4,7 @@ import (
"context"
"crypto/ed25519"
"encoding/json"
+ "log"
"slices"
"time"
@@ -51,12 +52,12 @@ var State state = state{
type UserData struct {
Networks []snowflake.ID
- Signals []snowflake.ID
+ Signals []snowflake.ID
}
var Data UserData = UserData{
Networks: []snowflake.ID{},
- Signals: []snowflake.ID{},
+ Signals: []snowflake.ID{},
}
var UserID *snowflake.ID = nil
@@ -107,12 +108,6 @@ func UpdateNetworks(info *packet.NetworksInfo) {
_, ok := State.Networks[id]
return !ok
})
-
- data := JsonUserData()
- gateway.SendAsync(&packet.SetUserData{
- Data: &data,
- User: nil,
- })
}
func UpdateFrequencies(info *packet.FrequenciesInfo) {
@@ -225,7 +220,15 @@ func FromJsonUserData(s string) {
if err != nil {
return
}
- Data = data
+
+ // log.Println("Previous user data:", Data)
+ if data.Networks != nil {
+ Data.Networks = data.Networks
+ }
+ if data.Signals != nil {
+ Data.Signals = data.Signals
+ }
+ log.Println("Updated user data:", Data)
}
func UpdateTrusteds(info *packet.TrustInfo) {
@@ -250,26 +253,45 @@ func GetLastMessage(id snowflake.ID) *snowflake.ID {
return &msg.ID
}
-func SendUserDatUpdate() {
- data := JsonUserData()
- gateway.SendAsync(&packet.SetUserData{
- Data: &data,
- User: nil,
- })
+func IsFrequency(id snowflake.ID) bool {
+ // Note this is very expensive and inefficient
+ // A map is better but as most of the time frequencies are iterated
+ // over based on a network id, this would add overhead
+ // And this function is only used once in notifications
+
+ for _, frequencies := range State.Frequencies {
+ for _, frequency := range frequencies {
+ if id == frequency.ID {
+ return true
+ }
+ }
+ }
+ return false
}
-func UpdateNotifications(info *packet.NotificationsInfo) {
+func UpdateNotifications(info *packet.NotificationsInfo) []snowflake.ID {
+ signals := []snowflake.ID{}
+
for i := 0; i < len(info.Source); i++ {
+ source := info.Source[i]
lastRead := snowflake.ID(info.LastRead[i])
- State.LastReadMessages[info.Source[i]] = &lastRead
+ State.LastReadMessages[source] = &lastRead
ping := info.Pings[i]
if ping != nil {
- State.Notifications[info.Source[i]] = int(*ping)
+ // log.Println(source, *ping)
+ State.Notifications[source] = int(*ping)
+ if !IsFrequency(source) && !slices.Contains(Data.Signals, source) {
+ signals = append(signals, source)
+ // log.Println("Signals:", Data.Signals)
+ }
} else {
+ // log.Println(source, "deleted")
delete(State.Notifications, info.Source[i])
}
}
+
+ return signals
}
func SendFinalData() {
diff --git a/internal/data/notifications.sql.go b/internal/data/notifications.sql.go
index 5819438..393d90a 100644
--- a/internal/data/notifications.sql.go
+++ b/internal/data/notifications.sql.go
@@ -11,6 +11,23 @@ import (
"github.com/kyren223/eko/pkg/snowflake"
)
+const insertLastReadMessage = `-- name: InsertLastReadMessage :exec
+INSERT OR IGNORE INTO last_read_messages (
+ user_id, source_id, last_read
+) VALUES (?, ?, ?)
+`
+
+type InsertLastReadMessageParams struct {
+ UserID snowflake.ID
+ SourceID snowflake.ID
+ LastRead int64
+}
+
+func (q *Queries) InsertLastReadMessage(ctx context.Context, arg InsertLastReadMessageParams) error {
+ _, err := q.db.ExecContext(ctx, insertLastReadMessage, arg.UserID, arg.SourceID, arg.LastRead)
+ return err
+}
+
const setLastReadMessage = `-- name: SetLastReadMessage :exec
INSERT INTO last_read_messages (
user_id, source_id, last_read
diff --git a/internal/server/api/api.go b/internal/server/api/api.go
index 92679b8..e087268 100644
--- a/internal/server/api/api.go
+++ b/internal/server/api/api.go
@@ -156,6 +156,16 @@ func SendMessage(ctx context.Context, sess *session.Session, request *packet.Sen
return &ErrInternalError
}
+ err = queries.InsertLastReadMessage(ctx, data.InsertLastReadMessageParams{
+ UserID: *request.ReceiverID,
+ SourceID: sess.ID(),
+ LastRead: 0,
+ })
+ if err != nil {
+ log.Println("database error 7:", err)
+ return &ErrInternalError
+ }
+
return UserPropagate(ctx, sess, user.ID, &packet.MessagesInfo{
Messages: []data.Message{message},
RemovedMessages: nil,
diff --git a/internal/server/api/helpers.go b/internal/server/api/helpers.go
index 2daeb9f..4327a49 100644
--- a/internal/server/api/helpers.go
+++ b/internal/server/api/helpers.go
@@ -151,15 +151,16 @@ SELECT
e.source_id, e.last_read,
CASE
WHEN COUNT(m.id) = 0 THEN NULL
- ELSE SUM(CASE WHEN (m.ping = 0 OR (m.ping = 1 AND pf.is_admin = true) OR m.ping = ?) THEN 1 ELSE 0 END)
+ ELSE SUM(CASE WHEN (m.frequency_id IS NULL OR
+ m.ping = 0 OR (m.ping = 1 AND pf.is_admin = true) OR m.ping = ?) THEN 1 ELSE 0 END)
-- 0 is @everyone, 1 is @admins, otherwise it's user_id
END AS pings
FROM entries e
+LEFT JOIN permitted_frequencies pf ON e.source_id = pf.id
LEFT JOIN messages m ON m.id > e.last_read
- AND (m.frequency_id = e.source_id OR
+ AND ((m.frequency_id = e.source_id AND pf.id IS NOT NULL) OR
(m.receiver_id = e.source_id AND m.sender_id = ?) OR
(m.sender_id = e.source_id AND m.receiver_id = ?))
-JOIN permitted_frequencies pf ON e.source_id = pf.id
GROUP BY e.source_id, e.last_read;
`
diff --git a/internal/server/server.go b/internal/server/server.go
index 153f612..1477e7f 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -414,6 +414,7 @@ func (server *server) sendInitialPackets(ctx context.Context, sess *session.Sess
if payload == &api.ErrInternalError {
return false
}
+ log.Println(sess.Addr(), "sending", payload.Type(), "payload:", payload)
pkt := packet.NewPacket(packet.NewMsgPackEncoder(payload))
sess.Write(ctx, pkt)
@@ -421,6 +422,7 @@ func (server *server) sendInitialPackets(ctx context.Context, sess *session.Sess
if payload == &api.ErrInternalError {
return false
}
+ log.Println(sess.Addr(), "sending", payload.Type(), "payload:", payload)
pkt = packet.NewPacket(packet.NewMsgPackEncoder(payload))
sess.Write(ctx, pkt)
@@ -428,6 +430,7 @@ func (server *server) sendInitialPackets(ctx context.Context, sess *session.Sess
if err != nil {
return false
}
+ log.Println(sess.Addr(), "sending", payload.Type(), "payload:", payload)
pkt = packet.NewPacket(packet.NewMsgPackEncoder(payload))
sess.Write(ctx, pkt)
@@ -435,6 +438,7 @@ func (server *server) sendInitialPackets(ctx context.Context, sess *session.Sess
if payload == &api.ErrInternalError {
return false
}
+ log.Println(sess.Addr(), "sending", payload.Type(), "payload:", payload)
pkt = packet.NewPacket(packet.NewMsgPackEncoder(payload))
sess.Write(ctx, pkt)