Add unviewed mentions count
This commit add a field to count the unviewed mentions in a given chat. The usage pattern is identical to `UnviewedMessagesCount`
This commit is contained in:
parent
70cbad6aba
commit
11de62749d
|
@ -60,6 +60,7 @@ type Chat struct {
|
|||
|
||||
// Denormalized fields
|
||||
UnviewedMessagesCount uint `json:"unviewedMessagesCount"`
|
||||
UnviewedMentionsCount uint `json:"unviewedMentionsCount"`
|
||||
LastMessage *common.Message `json:"lastMessage"`
|
||||
|
||||
// Group chat fields
|
||||
|
|
|
@ -148,18 +148,7 @@ func (m *MessageHandler) HandleMembershipUpdate(messageState *ReceivedMessageSta
|
|||
chat.updateChatFromGroupMembershipChanges(group)
|
||||
|
||||
if !chat.Active {
|
||||
notification := &ActivityCenterNotification{
|
||||
ID: types.FromHex(chat.ID),
|
||||
Name: chat.Name,
|
||||
LastMessage: chat.LastMessage,
|
||||
Type: ActivityCenterNotificationTypeNewPrivateGroupChat,
|
||||
Timestamp: messageState.CurrentMessageState.WhisperTimestamp,
|
||||
ChatID: chat.ID,
|
||||
}
|
||||
err := m.addActivityCenterNotification(messageState, notification)
|
||||
if err != nil {
|
||||
m.logger.Warn("failed to create activity center notification", zap.Error(err))
|
||||
}
|
||||
m.createMessageNotification(chat, messageState)
|
||||
}
|
||||
|
||||
systemMessages := buildSystemMessages(message.Events, translations)
|
||||
|
@ -190,6 +179,28 @@ func (m *MessageHandler) HandleMembershipUpdate(messageState *ReceivedMessageSta
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *MessageHandler) createMessageNotification(chat *Chat, messageState *ReceivedMessageState) {
|
||||
|
||||
var notificationType ActivityCenterType
|
||||
if chat.OneToOne() {
|
||||
notificationType = ActivityCenterNotificationTypeNewOneToOne
|
||||
} else {
|
||||
notificationType = ActivityCenterNotificationTypeNewPrivateGroupChat
|
||||
}
|
||||
notification := &ActivityCenterNotification{
|
||||
ID: types.FromHex(chat.ID),
|
||||
Name: chat.Name,
|
||||
LastMessage: chat.LastMessage,
|
||||
Type: notificationType,
|
||||
Timestamp: messageState.CurrentMessageState.WhisperTimestamp,
|
||||
ChatID: chat.ID,
|
||||
}
|
||||
err := m.addActivityCenterNotification(messageState, notification)
|
||||
if err != nil {
|
||||
m.logger.Warn("failed to create activity center notification", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MessageHandler) handleCommandMessage(state *ReceivedMessageState, message *common.Message) error {
|
||||
message.ID = state.CurrentMessageState.MessageID
|
||||
message.From = state.CurrentMessageState.Contact.ID
|
||||
|
@ -232,7 +243,7 @@ func (m *MessageHandler) handleCommandMessage(state *ReceivedMessageState, messa
|
|||
|
||||
// Increase unviewed count
|
||||
if !common.IsPubKeyEqual(message.SigPubKey, &m.identity.PublicKey) {
|
||||
chat.UnviewedMessagesCount++
|
||||
m.updateUnviewedCounts(chat, message.Mentioned)
|
||||
message.OutgoingStatus = ""
|
||||
} else {
|
||||
// Our own message, mark as sent
|
||||
|
@ -245,18 +256,7 @@ func (m *MessageHandler) handleCommandMessage(state *ReceivedMessageState, messa
|
|||
}
|
||||
|
||||
if !chat.Active {
|
||||
notification := &ActivityCenterNotification{
|
||||
ID: types.FromHex(chat.ID),
|
||||
Type: ActivityCenterNotificationTypeNewOneToOne,
|
||||
Name: chat.Name,
|
||||
LastMessage: chat.LastMessage,
|
||||
Timestamp: state.CurrentMessageState.WhisperTimestamp,
|
||||
ChatID: chat.ID,
|
||||
}
|
||||
err := m.addActivityCenterNotification(state, notification)
|
||||
if err != nil {
|
||||
m.logger.Warn("failed to save notification", zap.Error(err))
|
||||
}
|
||||
m.createMessageNotification(chat, state)
|
||||
}
|
||||
|
||||
// Add to response
|
||||
|
@ -625,7 +625,7 @@ func (m *MessageHandler) HandleChatMessage(state *ReceivedMessageState) error {
|
|||
|
||||
// Increase unviewed count
|
||||
if !common.IsPubKeyEqual(receivedMessage.SigPubKey, &m.identity.PublicKey) {
|
||||
chat.UnviewedMessagesCount++
|
||||
m.updateUnviewedCounts(chat, receivedMessage.Mentioned)
|
||||
} else {
|
||||
// Our own message, mark as sent
|
||||
receivedMessage.OutgoingStatus = common.OutgoingStatusSent
|
||||
|
@ -638,19 +638,9 @@ func (m *MessageHandler) HandleChatMessage(state *ReceivedMessageState) error {
|
|||
|
||||
// If the chat is not active, create a notification in the center
|
||||
if chat.OneToOne() && !chat.Active {
|
||||
notification := &ActivityCenterNotification{
|
||||
ID: types.FromHex(chat.ID),
|
||||
Name: chat.Name,
|
||||
LastMessage: chat.LastMessage,
|
||||
Type: ActivityCenterNotificationTypeNewOneToOne,
|
||||
Timestamp: state.CurrentMessageState.WhisperTimestamp,
|
||||
ChatID: chat.ID,
|
||||
}
|
||||
err := m.addActivityCenterNotification(state, notification)
|
||||
if err != nil {
|
||||
m.logger.Warn("failed to create notification", zap.Error(err))
|
||||
}
|
||||
m.createMessageNotification(chat, state)
|
||||
}
|
||||
|
||||
// Set in the modified maps chat
|
||||
state.Response.AddChat(chat)
|
||||
// TODO(samyoul) remove storing of an updated reference pointer?
|
||||
|
@ -1205,3 +1195,10 @@ func (m *MessageHandler) isMessageAllowedFrom(allContacts *contactMap, publicKey
|
|||
// Otherwise we check if we added it
|
||||
return contact.IsAdded(), nil
|
||||
}
|
||||
|
||||
func (m *MessageHandler) updateUnviewedCounts(chat *Chat, mentioned bool) {
|
||||
chat.UnviewedMessagesCount++
|
||||
if mentioned {
|
||||
chat.UnviewedMentionsCount++
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1059,7 +1059,7 @@ func (db sqlitePersistence) MarkAllRead(chatID string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = tx.Exec(`UPDATE chats SET unviewed_message_count = 0 WHERE id = ?`, chatID)
|
||||
_, err = tx.Exec(`UPDATE chats SET unviewed_mentions_count = 0, unviewed_message_count = 0 WHERE id = ?`, chatID)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1101,8 +1101,12 @@ func (db sqlitePersistence) MarkMessagesSeen(chatID string, ids []string) (uint6
|
|||
SET unviewed_message_count =
|
||||
(SELECT COUNT(1)
|
||||
FROM user_messages
|
||||
WHERE local_chat_id = ? AND seen = 0)
|
||||
WHERE id = ?`, chatID, chatID)
|
||||
WHERE local_chat_id = ? AND seen = 0),
|
||||
unviewed_mentions_count =
|
||||
(SELECT COUNT(1)
|
||||
FROM user_messages
|
||||
WHERE local_chat_id = ? AND seen = 0 AND mentioned)
|
||||
WHERE id = ?`, chatID, chatID, chatID)
|
||||
return count, err
|
||||
}
|
||||
|
||||
|
@ -1158,7 +1162,8 @@ func (db sqlitePersistence) BlockContact(contact *Contact) ([]*Chat, error) {
|
|||
_, err = tx.Exec(`
|
||||
UPDATE chats
|
||||
SET
|
||||
unviewed_message_count = (SELECT COUNT(1) FROM user_messages WHERE seen = 0 AND local_chat_id = chats.id)`)
|
||||
unviewed_message_count = (SELECT COUNT(1) FROM user_messages WHERE seen = 0 AND local_chat_id = chats.id),
|
||||
unviewed_mentions_count = (SELECT COUNT(1) FROM user_messages WHERE seen = 0 AND local_chat_id = chats.id AND mentioned)`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1427,6 +1432,7 @@ func (db sqlitePersistence) clearHistory(chat *Chat, currentClockValue uint64, t
|
|||
|
||||
chat.LastMessage = nil
|
||||
chat.UnviewedMessagesCount = 0
|
||||
chat.UnviewedMentionsCount = 0
|
||||
|
||||
err := db.deleteMessagesByChatID(chat.ID, tx)
|
||||
if err != nil {
|
||||
|
|
|
@ -3068,6 +3068,7 @@ func (m *Messenger) MarkAllRead(chatID string) error {
|
|||
}
|
||||
|
||||
chat.UnviewedMessagesCount = 0
|
||||
chat.UnviewedMentionsCount = 0
|
||||
// TODO(samyoul) remove storing of an updated reference pointer?
|
||||
m.allChats.Store(chat.ID, chat)
|
||||
return nil
|
||||
|
|
|
@ -334,13 +334,18 @@ func buildTestMessage(chat Chat) *common.Message {
|
|||
func (s *MessengerSuite) TestMarkMessagesSeen() {
|
||||
chat := CreatePublicChat("test-chat", s.m.transport)
|
||||
chat.UnviewedMessagesCount = 2
|
||||
chat.UnviewedMentionsCount = 3
|
||||
err := s.m.SaveChat(chat)
|
||||
s.Require().NoError(err)
|
||||
inputMessage1 := buildTestMessage(*chat)
|
||||
inputMessage1.ID = "1"
|
||||
inputMessage1.Seen = false
|
||||
inputMessage1.Text = "hey @" + common.PubkeyToHex(&s.m.identity.PublicKey)
|
||||
inputMessage1.Mentioned = true
|
||||
inputMessage2 := buildTestMessage(*chat)
|
||||
inputMessage2.ID = "2"
|
||||
inputMessage2.Text = "hey @" + common.PubkeyToHex(&s.m.identity.PublicKey)
|
||||
inputMessage2.Mentioned = true
|
||||
inputMessage2.Seen = false
|
||||
|
||||
err = s.m.SaveMessages([]*common.Message{inputMessage1, inputMessage2})
|
||||
|
@ -359,6 +364,7 @@ func (s *MessengerSuite) TestMarkMessagesSeen() {
|
|||
for _, c := range chats {
|
||||
if c.ID == chat.ID {
|
||||
s.Require().Equal(uint(1), c.UnviewedMessagesCount)
|
||||
s.Require().Equal(uint(1), c.UnviewedMentionsCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
// 1619094007_add_joined_chat_field.up.sql (101B)
|
||||
// 1619099821_add_last_synced_field.up.sql (226B)
|
||||
// 1621933219_add_mentioned.up.sql (70B)
|
||||
// 1622010048_add_unviewed_mentions_count.up.sql (114B)
|
||||
// README.md (554B)
|
||||
// doc.go (850B)
|
||||
|
||||
|
@ -721,6 +722,26 @@ func _1621933219_add_mentionedUpSql() (*asset, error) {
|
|||
return a, nil
|
||||
}
|
||||
|
||||
var __1622010048_add_unviewed_mentions_countUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\x48\xce\x48\x2c\x29\x56\x70\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xcd\x2b\xcb\x4c\x2d\x4f\x4d\x89\xcf\x4d\xcd\x2b\xc9\xcc\xcf\x2b\x8e\x4f\xce\x2f\xcd\x2b\x51\xf0\xf4\x0b\x51\x70\x71\x75\x73\x0c\xf5\x09\x51\x30\xb0\xe6\x0a\x0d\x70\x71\x0c\x81\x69\x0f\x76\x0d\xc1\xa9\xcf\x16\xa4\x1a\x10\x00\x00\xff\xff\x0f\xdf\x43\x35\x72\x00\x00\x00")
|
||||
|
||||
func _1622010048_add_unviewed_mentions_countUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__1622010048_add_unviewed_mentions_countUpSql,
|
||||
"1622010048_add_unviewed_mentions_count.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _1622010048_add_unviewed_mentions_countUpSql() (*asset, error) {
|
||||
bytes, err := _1622010048_add_unviewed_mentions_countUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1622010048_add_unviewed_mentions_count.up.sql", size: 114, mode: os.FileMode(0644), modTime: time.Unix(1622010095, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7c, 0x16, 0x85, 0xa6, 0x5b, 0xe1, 0x66, 0xb9, 0x84, 0xbe, 0x7f, 0xa, 0x77, 0x23, 0xb9, 0xef, 0x8e, 0x2, 0x8, 0xfc, 0x61, 0xb2, 0x43, 0xa9, 0x63, 0xae, 0xb4, 0xdf, 0x30, 0xb1, 0x61, 0x4b}}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _readmeMd = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x91\xc1\xce\xd3\x30\x10\x84\xef\x7e\x8a\x91\x7a\x01\xa9\x2a\x8f\xc0\x0d\x71\x82\x03\x48\x1c\xc9\x36\x9e\x36\x96\x1c\x6f\xf0\xae\x93\xe6\xed\x91\xa3\xc2\xdf\xff\x66\xed\xd8\x33\xdf\x78\x4f\xa7\x13\xbe\xea\x06\x57\x6c\x35\x39\x31\xa7\x7b\x15\x4f\x5a\xec\x73\x08\xbf\x08\x2d\x79\x7f\x4a\x43\x5b\x86\x17\xfd\x8c\x21\xea\x56\x5e\x47\x90\x4a\x14\x75\x48\xde\x64\x37\x2c\x6a\x96\xae\x99\x48\x05\xf6\x27\x77\x13\xad\x08\xae\x8a\x51\xe7\x25\xf3\xf1\xa9\x9f\xf9\x58\x58\x2c\xad\xbc\xe0\x8b\x56\xf0\x21\x5d\xeb\x4c\x95\xb3\xae\x84\x60\xd4\xdc\xe6\x82\x5d\x1b\x36\x6d\x39\x62\x92\xf5\xb8\x11\xdb\x92\xd3\x28\xce\xe0\x13\xe1\x72\xcd\x3c\x63\xd4\x65\x87\xae\xac\xe8\xc3\x28\x2e\x67\x44\x66\x3a\x21\x25\xa2\x72\xac\x14\x67\xbc\x84\x9f\x53\x32\x8c\x52\x70\x25\x56\xd6\xfd\x8d\x05\x37\xad\x30\x9d\x9f\xa6\x86\x0f\xcd\x58\x7f\xcf\x34\x93\x3b\xed\x90\x9f\xa4\x1f\xcf\x30\x85\x4d\x07\x58\xaf\x7f\x25\xc4\x9d\xf3\x72\x64\x84\xd0\x7f\xf9\x9b\x3a\x2d\x84\xef\x85\x48\x66\x8d\xd8\x88\x9b\x8c\x8c\x98\x5b\xf6\x74\x14\x4e\x33\x0d\xc9\xe0\x93\x38\xda\x12\xc5\x69\xbd\xe4\xf0\x2e\x7a\x78\x07\x1c\xfe\x13\x9f\x91\x29\x31\x95\x7b\x7f\x62\x59\x37\xb4\xe5\x5e\x25\xfe\x33\xee\xd5\x53\x71\xd6\xda\x3a\xd8\xcb\xde\x2e\xf8\xa1\x90\x55\x53\x0c\xc7\xaa\x0d\xe9\x76\x14\x29\x1c\x7b\x68\xdd\x2f\xe1\x6f\x00\x00\x00\xff\xff\x3c\x0a\xc2\xfe\x2a\x02\x00\x00")
|
||||
|
||||
func readmeMdBytes() ([]byte, error) {
|
||||
|
@ -914,6 +935,8 @@ var _bindata = map[string]func() (*asset, error){
|
|||
|
||||
"1621933219_add_mentioned.up.sql": _1621933219_add_mentionedUpSql,
|
||||
|
||||
"1622010048_add_unviewed_mentions_count.up.sql": _1622010048_add_unviewed_mentions_countUpSql,
|
||||
|
||||
"README.md": readmeMd,
|
||||
|
||||
"doc.go": docGo,
|
||||
|
@ -991,8 +1014,9 @@ var _bintree = &bintree{nil, map[string]*bintree{
|
|||
"1619094007_add_joined_chat_field.up.sql": &bintree{_1619094007_add_joined_chat_fieldUpSql, map[string]*bintree{}},
|
||||
"1619099821_add_last_synced_field.up.sql": &bintree{_1619099821_add_last_synced_fieldUpSql, map[string]*bintree{}},
|
||||
"1621933219_add_mentioned.up.sql": &bintree{_1621933219_add_mentionedUpSql, map[string]*bintree{}},
|
||||
"README.md": &bintree{readmeMd, map[string]*bintree{}},
|
||||
"doc.go": &bintree{docGo, map[string]*bintree{}},
|
||||
"1622010048_add_unviewed_mentions_count.up.sql": &bintree{_1622010048_add_unviewed_mentions_countUpSql, map[string]*bintree{}},
|
||||
"README.md": &bintree{readmeMd, map[string]*bintree{}},
|
||||
"doc.go": &bintree{docGo, map[string]*bintree{}},
|
||||
}}
|
||||
|
||||
// RestoreAsset restores an asset under the given directory.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE chats ADD COLUMN unviewed_mentions_count INT DEFAULT 0;
|
||||
UPDATE chats SET unviewed_mentions_count = 0;
|
|
@ -130,8 +130,8 @@ func (db sqlitePersistence) saveChat(tx *sql.Tx, chat Chat) error {
|
|||
}
|
||||
|
||||
// Insert record
|
||||
stmt, err := tx.Prepare(`INSERT INTO chats(id, name, color, active, type, timestamp, deleted_at_clock_value, unviewed_message_count, last_clock_value, last_message, members, membership_updates, muted, invitation_admin, profile, community_id, joined, synced_from, synced_to)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?,?,?,?,?,?)`)
|
||||
stmt, err := tx.Prepare(`INSERT INTO chats(id, name, color, active, type, timestamp, deleted_at_clock_value, unviewed_message_count, unviewed_mentions_count, last_clock_value, last_message, members, membership_updates, muted, invitation_admin, profile, community_id, joined, synced_from, synced_to)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?,?,?,?,?,?,?)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -146,6 +146,7 @@ func (db sqlitePersistence) saveChat(tx *sql.Tx, chat Chat) error {
|
|||
chat.Timestamp,
|
||||
chat.DeletedAtClockValue,
|
||||
chat.UnviewedMessagesCount,
|
||||
chat.UnviewedMentionsCount,
|
||||
chat.LastClockValue,
|
||||
encodedLastMessage,
|
||||
encodedMembers.Bytes(),
|
||||
|
@ -235,6 +236,7 @@ func (db sqlitePersistence) chats(tx *sql.Tx) (chats []*Chat, err error) {
|
|||
chats.timestamp,
|
||||
chats.deleted_at_clock_value,
|
||||
chats.unviewed_message_count,
|
||||
chats.unviewed_mentions_count,
|
||||
chats.last_clock_value,
|
||||
chats.last_message,
|
||||
chats.members,
|
||||
|
@ -278,6 +280,7 @@ func (db sqlitePersistence) chats(tx *sql.Tx) (chats []*Chat, err error) {
|
|||
&chat.Timestamp,
|
||||
&chat.DeletedAtClockValue,
|
||||
&chat.UnviewedMessagesCount,
|
||||
&chat.UnviewedMentionsCount,
|
||||
&chat.LastClockValue,
|
||||
&lastMessageBytes,
|
||||
&encodedMembers,
|
||||
|
@ -364,6 +367,7 @@ func (db sqlitePersistence) Chat(chatID string) (*Chat, error) {
|
|||
timestamp,
|
||||
deleted_at_clock_value,
|
||||
unviewed_message_count,
|
||||
unviewed_mentions_count,
|
||||
last_clock_value,
|
||||
last_message,
|
||||
members,
|
||||
|
@ -383,6 +387,7 @@ func (db sqlitePersistence) Chat(chatID string) (*Chat, error) {
|
|||
&chat.Timestamp,
|
||||
&chat.DeletedAtClockValue,
|
||||
&chat.UnviewedMessagesCount,
|
||||
&chat.UnviewedMentionsCount,
|
||||
&chat.LastClockValue,
|
||||
&lastMessageBytes,
|
||||
&encodedMembers,
|
||||
|
|
Loading…
Reference in New Issue