From 58c6a6d38a5ebbd7bfc9c698227b931a2252e140 Mon Sep 17 00:00:00 2001 From: Kyren223 Date: Tue, 14 Jan 2025 19:09:18 +0200 Subject: Added the ability to delete messages in frequencies --- internal/client/ui/core/chat/chat.go | 26 +++++++++++--- internal/data/messages.sql.go | 19 ++++++++++ internal/server/api/api.go | 67 +++++++++++++++++++++++++++++++++++- internal/server/server.go | 2 ++ query/messages.sql | 4 +++ 5 files changed, 112 insertions(+), 6 deletions(-) diff --git a/internal/client/ui/core/chat/chat.go b/internal/client/ui/core/chat/chat.go index 8130910..bebb72f 100644 --- a/internal/client/ui/core/chat/chat.go +++ b/internal/client/ui/core/chat/chat.go @@ -67,8 +67,9 @@ type Model struct { receiverIndex int frequencyIndex int - offset int - index int + offset int + index int + selectedMessage *snowflake.ID messagesHeight int maxMessagesHeight int @@ -112,6 +113,7 @@ func (m *Model) Prerender() { // if m.messagesCache == nil || messagesHeight != m.messagesHeight { // // Re-render // } + m.selectedMessage = nil messages := m.renderMessages(messagesHeight) m.messagesCache = &messages m.messagesHeight = messagesHeight @@ -154,6 +156,8 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { return m, cmd } + var cmd tea.Cmd + switch msg := msg.(type) { case tea.KeyMsg: key := msg.String() @@ -175,16 +179,26 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { // Also for the first time a user scrolls there will be a visual // glitch that doesn't show the top message being selected m.Scroll(10000) // Large numbers can slow this!!!! - case "G": - fallthrough case "enter": + m.locked = true + m.vi.SetMode(viminput.InsertMode) + fallthrough + case "G": m.offset = SnapToBottom m.index = -1 + + case "x", "X", "d", "D": + if m.selectedMessage != nil { + log.Println("deleting message:", m.selectedMessage) + cmd = gateway.Send(&packet.DeleteMessage{ + Message: *m.selectedMessage, + }) + } } } m.Prerender() - return m, nil + return m, cmd } func (m *Model) Focus() { @@ -527,6 +541,8 @@ func (m *Model) renderMessageGroup(group []data.Message, remaining *int, height *remaining-- // For the header if selectedIndex != -1 { + m.selectedMessage = &group[selectedIndex].ID + if selectedIndex == len(group)-1 { buf = m.renderHeader(group[selectedIndex], true) } else { diff --git a/internal/data/messages.sql.go b/internal/data/messages.sql.go index 43edb7d..a3d8257 100644 --- a/internal/data/messages.sql.go +++ b/internal/data/messages.sql.go @@ -163,3 +163,22 @@ func (q *Queries) GetFrequencyMessages(ctx context.Context, frequencyID *snowfla } return items, nil } + +const getMessageById = `-- name: GetMessageById :one +SELECT id, sender_id, content, edited, frequency_id, receiver_id FROM messages +WHERE id = ? +` + +func (q *Queries) GetMessageById(ctx context.Context, id snowflake.ID) (Message, error) { + row := q.db.QueryRowContext(ctx, getMessageById, id) + var i Message + err := row.Scan( + &i.ID, + &i.SenderID, + &i.Content, + &i.Edited, + &i.FrequencyID, + &i.ReceiverID, + ) + return i, err +} diff --git a/internal/server/api/api.go b/internal/server/api/api.go index 4a3c24a..f0d1b1f 100644 --- a/internal/server/api/api.go +++ b/internal/server/api/api.go @@ -19,6 +19,7 @@ import ( var ( ErrInternalError = packet.Error{Error: "internal server error"} ErrPermissionDenied = packet.Error{Error: "permission denied"} + ErrNotImplemented = packet.Error{Error: "not implemented yet"} ) func SendMessage(ctx context.Context, sess *session.Session, request *packet.SendMessage) packet.Payload { @@ -147,7 +148,7 @@ func RequestMessages(ctx context.Context, sess *session.Session, request *packet } if request.ReceiverID != nil && request.FrequencyID == nil { - return &packet.Error{Error: "receiver message requests are not implemented yet!"} + return &ErrNotImplemented } return &packet.Error{Error: "either receiver id or frequency id must be specified"} @@ -826,3 +827,67 @@ func UpdateFrequency(ctx context.Context, sess *session.Session, request *packet Network: frequency.NetworkID, }) } + +func DeleteMessage(ctx context.Context, sess *session.Session, request *packet.DeleteMessage) packet.Payload { + queries := data.New(db) + + message, err := queries.GetMessageById(ctx, request.Message) + if err == sql.ErrNoRows { + return &packet.Error{Error: "message doesn't exist"} + } + if err != nil { + log.Println("database error 0:", err) + return &ErrInternalError + } + + if message.FrequencyID != nil { + frequency, err := queries.GetFrequencyById(ctx, *message.FrequencyID) + if err != nil { + log.Println("database error 1:", err) + return &ErrInternalError + } + + network, err := queries.GetNetworkById(ctx, frequency.NetworkID) + if err != nil { + log.Println("database error 2:", err) + return &ErrInternalError + } + + isSessAdmin, err := IsNetworkAdmin(ctx, queries, sess.ID(), frequency.NetworkID) + if err != nil { + log.Println("database error 3:", err) + return &ErrInternalError + } + + isSelf := message.SenderID == sess.ID() + isAdmin := isSessAdmin && message.SenderID != network.OwnerID + isOwner := network.OwnerID == sess.ID() + if !isSelf && !isOwner && !isAdmin { + return &ErrPermissionDenied + } + + err = queries.DeleteMessage(ctx, message.ID) + if err != nil { + log.Println("database error 4:", err) + return &ErrInternalError + } + + return NetworkPropagateWithFilter(ctx, sess, frequency.NetworkID, &packet.MessagesInfo{ + Messages: nil, + RemovedMessages: []snowflake.ID{message.ID}, + }, func(userId snowflake.ID) (pass bool) { + if frequency.Perms != packet.PermNoAccess { + return true + } + isAdmin, _ := IsNetworkAdmin(ctx, queries, userId, frequency.NetworkID) + return isAdmin + }) + } + + if message.ReceiverID != nil { + return &ErrNotImplemented + } + + assert.Never("unreachable") + return nil +} diff --git a/internal/server/server.go b/internal/server/server.go index 26ab7b7..95c22f6 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -361,6 +361,8 @@ func processRequest(ctx context.Context, sess *session.Session, request packet.P case *packet.SendMessage: response = timeout(20*time.Millisecond, api.SendMessage, ctx, sess, request) + case *packet.DeleteMessage: + response = timeout(5*time.Millisecond, api.DeleteMessage, ctx, sess, request) case *packet.RequestMessages: response = timeout(50*time.Millisecond, api.RequestMessages, ctx, sess, request) diff --git a/query/messages.sql b/query/messages.sql index f7be629..063b576 100644 --- a/query/messages.sql +++ b/query/messages.sql @@ -1,3 +1,7 @@ +-- name: GetMessageById :one +SELECT * FROM messages +WHERE id = ?; + -- name: GetFrequencyMessages :many SELECT * FROM messages WHERE frequency_id = ? -- cgit v1.3.1