Skip to content

Commit

Permalink
feat(message)_: add PinnedBy to common.Message
Browse files Browse the repository at this point in the history
Needed for status-im/status-desktop#16896

Having `PinnedBy`  directly in the Message object makes it way simpler in the client to know if a message is pinned. This saves us from having to keep a cache of the pinned messages and comparing all new messages.
  • Loading branch information
jrainville committed Dec 18, 2024
1 parent d291204 commit f048766
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
5 changes: 5 additions & 0 deletions protocol/common/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ type Message struct {
ContactVerificationState ContactVerificationState `json:"contactVerificationState,omitempty"`

DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"`

// When a message is pinned, the pubkey of the user that pinned it is stored here
PinnedBy string `json:"pinnedBy,omitempty"`
}

func (m *Message) MarshalJSON() ([]byte, error) {
Expand Down Expand Up @@ -284,6 +287,7 @@ func (m *Message) MarshalJSON() ([]byte, error) {
DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"`
BridgeMessage *protobuf.BridgeMessage `json:"bridgeMessage,omitempty"`
PaymentRequests []*protobuf.PaymentRequest `json:"paymentRequests,omitempty"`
PinnedBy string `json:"pinnedBy,omitempty"`
}
item := MessageStructType{
ID: m.ID,
Expand Down Expand Up @@ -327,6 +331,7 @@ func (m *Message) MarshalJSON() ([]byte, error) {
ContactRequestState: m.ContactRequestState,
ContactVerificationState: m.ContactVerificationState,
PaymentRequests: m.PaymentRequests,
PinnedBy: m.PinnedBy,
}

if sticker := m.GetSticker(); sticker != nil {
Expand Down
15 changes: 11 additions & 4 deletions protocol/message_persistence.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ LEFT JOIN bridge_messages bm
ON m1.id = bm.user_messages_id
LEFT JOIN bridge_messages bm_response
ON m2.id = bm_response.user_messages_id
LEFT JOIN pin_messages pm
ON m1.id = pm.message_id AND pm.pinned = 1
`

var basicInsertDiscordMessageAuthorQuery = `INSERT OR REPLACE INTO discord_message_authors(id,name,discriminator,nickname,avatar_url, avatar_image_payload) VALUES (?,?,?,?,?,?)`
Expand Down Expand Up @@ -135,6 +137,7 @@ func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string {
m1.seen,
m1.outgoing_status,
m1.parsed_text,
pm.pinned_by,
m1.sticker_pack,
m1.sticker_hash,
m1.image_payload,
Expand Down Expand Up @@ -257,6 +260,7 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
var deletedForMe sql.NullBool
var contactRequestState sql.NullInt64
var contactVerificationState sql.NullInt64
var pinnedBy sql.NullString

sticker := &protobuf.StickerMessage{}
command := &common.CommandParameters{}
Expand Down Expand Up @@ -292,6 +296,7 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
&message.Seen,
&message.OutgoingStatus,
&message.ParsedText,
&pinnedBy,
&sticker.Pack,
&sticker.Hash,
&image.Payload,
Expand Down Expand Up @@ -405,6 +410,10 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
message.ContactVerificationState = common.ContactVerificationState(contactVerificationState.Int64)
}

if pinnedBy.Valid {
message.PinnedBy = pinnedBy.String
}

if quotedText.Valid {
if quotedDeleted.Bool || quotedDeletedForMe.Bool {
message.QuotedMessage = &common.QuotedMessage{
Expand Down Expand Up @@ -1199,7 +1208,6 @@ func (db sqlitePersistence) PinnedMessageByChatIDs(chatIDs []string, currCursor
SELECT
%s,
pm.clock_value as pinnedAt,
pm.pinned_by as pinnedBy,
%s
FROM
pin_messages pm
Expand Down Expand Up @@ -2940,18 +2948,17 @@ func getPinnedMessagesAndCursorsFromScanRows(db sqlitePersistence, rows *sql.Row
for rows.Next() {
var (
pinnedAt uint64
pinnedBy string
cursor string
)
message := common.NewMessage()
if err := db.tableUserMessagesScanAllFields(rows, message, &pinnedAt, &pinnedBy, &cursor); err != nil {
if err := db.tableUserMessagesScanAllFields(rows, message, &pinnedAt, &cursor); err != nil {
return nil, nil, err
}
if msg, ok := messageIdx[message.ID]; !ok {
pinnedMessage := &common.PinnedMessage{
Message: message,
PinnedAt: pinnedAt,
PinnedBy: pinnedBy,
PinnedBy: message.PinnedBy,
}
messageIdx[message.ID] = pinnedMessage
messages = append(messages, pinnedMessage)
Expand Down
19 changes: 19 additions & 0 deletions protocol/persistence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,25 @@ func TestPinMessageByChatID(t *testing.T) {
for i := 0; i < len(result)-1; i++ {
require.Equal(t, testPK, result[i].PinnedBy)
}

// The Message itself should have the pinnedBy field
p.PinnedMessageByChatID(chatID, cursor, pageSize)

pinnedMessageID := result[len(result)-1].Message.ID

m, err := p.MessagesByIDs([]string{pinnedMessageID})
require.NoError(t, err)
require.Len(t, m, 1)
require.Equal(t, "them", m[0].PinnedBy)

msgs, _, err := p.MessageByChatID(chatID, cursor, 10)
require.NoError(t, err)
require.Len(t, msgs, 10)
for _, msg := range msgs {
if msg.ID == pinnedMessageID {
require.Equal(t, "them", msg.PinnedBy)
}
}
}

func TestMessageReplies(t *testing.T) {
Expand Down

0 comments on commit f048766

Please sign in to comment.