summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/client/ui/core/chat/chat.go26
-rw-r--r--internal/data/messages.sql.go19
-rw-r--r--internal/server/api/api.go67
-rw-r--r--internal/server/server.go2
4 files changed, 108 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)