feat: Return seen/unseen messages count in MessnegerResponse (#4461)

This commit is contained in:
Mikhail Rogachev 2023-12-25 13:25:22 +07:00 committed by GitHub
parent 151185c436
commit 843bae5659
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 161 additions and 58 deletions

View File

@ -4146,7 +4146,7 @@ func (m *Messenger) DeleteMessagesByChatID(id string) error {
return m.persistence.DeleteMessagesByChatID(id)
}
func (m *Messenger) MarkMessageAsUnreadImpl(chatID string, messageID string) (uint64, uint64, error) {
func (m *Messenger) markMessageAsUnreadImpl(chatID string, messageID string) (uint64, uint64, error) {
count, countWithMentions, err := m.persistence.MarkMessageAsUnread(chatID, messageID)
if err != nil {
@ -4161,17 +4161,23 @@ func (m *Messenger) MarkMessageAsUnreadImpl(chatID string, messageID string) (ui
return count, countWithMentions, nil
}
func (m *Messenger) MarkMessageAsUnread(chatID string, messageID string) (uint64, uint64, []*ActivityCenterNotification, error) {
count, countWithMentions, err := m.MarkMessageAsUnreadImpl(chatID, messageID)
func (m *Messenger) MarkMessageAsUnread(chatID string, messageID string) (*MessengerResponse, error) {
count, countWithMentions, err := m.markMessageAsUnreadImpl(chatID, messageID)
if err != nil {
return 0, 0, nil, err
return nil, err
}
ids, err := m.persistence.GetMessageIdsWithGreaterTimestamp(chatID, messageID)
response := &MessengerResponse{}
response.AddSeenAndUnseenMessages(&SeenUnseenMessages{
ChatID: chatID,
Count: count,
CountWithMentions: countWithMentions,
Seen: false,
})
ids, err := m.persistence.GetMessageIdsWithGreaterTimestamp(chatID, messageID)
if err != nil {
return 0, 0, nil, err
return nil, err
}
hexBytesIds := []types.HexBytes{}
@ -4181,12 +4187,13 @@ func (m *Messenger) MarkMessageAsUnread(chatID string, messageID string) (uint64
updatedAt := m.GetCurrentTimeInMillis()
notifications, err := m.persistence.MarkActivityCenterNotificationsUnread(hexBytesIds, updatedAt)
if err != nil {
return 0, 0, nil, err
return nil, err
}
return count, countWithMentions, notifications, nil
response.AddActivityCenterNotifications(notifications)
return response, nil
}
// MarkMessagesSeen marks messages with `ids` as seen in the chat `chatID`.
@ -4205,6 +4212,7 @@ func (m *Messenger) markMessagesSeenImpl(chatID string, ids []string) (uint64, u
return count, countWithMentions, nil
}
// Deprecated: Use MarkMessagesRead instead
func (m *Messenger) MarkMessagesSeen(chatID string, ids []string) (uint64, uint64, []*ActivityCenterNotification, error) {
count, countWithMentions, err := m.markMessagesSeenImpl(chatID, ids)
if err != nil {
@ -4231,6 +4239,42 @@ func (m *Messenger) MarkMessagesSeen(chatID string, ids []string) (uint64, uint6
return count, countWithMentions, notifications, nil
}
func (m *Messenger) MarkMessagesRead(chatID string, ids []string) (*MessengerResponse, error) {
count, countWithMentions, err := m.markMessagesSeenImpl(chatID, ids)
if err != nil {
return nil, err
}
response := &MessengerResponse{}
response.AddSeenAndUnseenMessages(&SeenUnseenMessages{
ChatID: chatID,
Count: count,
CountWithMentions: countWithMentions,
Seen: true,
})
hexBytesIds := []types.HexBytes{}
for _, id := range ids {
hexBytesIds = append(hexBytesIds, types.FromHex(id))
}
// Mark notifications as read in the database
updatedAt := m.GetCurrentTimeInMillis()
err = m.persistence.MarkActivityCenterNotificationsRead(hexBytesIds, updatedAt)
if err != nil {
return nil, err
}
notifications, err := m.persistence.GetActivityCenterNotificationsByID(hexBytesIds)
if err != nil {
return nil, err
}
response.AddActivityCenterNotifications(notifications)
return response, nil
}
func (m *Messenger) syncChatMessagesRead(ctx context.Context, chatID string, clock uint64, rawMessageHandler RawMessageHandler) error {
if !m.hasPairedDevices() {
return nil

View File

@ -143,7 +143,7 @@ func (m *Messenger) MarkActivityCenterNotificationsRead(ctx context.Context, ids
response := &MessengerResponse{}
repliesAndMentions := make(map[string][]string)
// When marking as read Mention or Reply notification, the corresponding chat message should also be read.
// When marking as read Mention or Reply notification, the corresponding chat message should also be seen.
for _, notification := range notifications {
response.AddActivityCenterNotification(notification)
@ -155,10 +155,17 @@ func (m *Messenger) MarkActivityCenterNotificationsRead(ctx context.Context, ids
// Mark messages as seen
for chatID, messageIDs := range repliesAndMentions {
_, _, err := m.markMessagesSeenImpl(chatID, messageIDs)
count, countWithMentions, err := m.markMessagesSeenImpl(chatID, messageIDs)
if err != nil {
return nil, err
}
response.AddSeenAndUnseenMessages(&SeenUnseenMessages{
ChatID: chatID,
Count: count,
CountWithMentions: countWithMentions,
Seen: true,
})
}
state, err := m.persistence.GetActivityCenterState()
@ -182,12 +189,16 @@ func (m *Messenger) MarkActivityCenterNotificationsRead(ctx context.Context, ids
}
func (m *Messenger) MarkActivityCenterNotificationsUnread(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) {
response := &MessengerResponse{}
notifications, err := m.persistence.MarkActivityCenterNotificationsUnread(ids, updatedAt)
if err != nil {
return nil, err
}
response := &MessengerResponse{}
response.AddActivityCenterNotifications(notifications)
// Don't mark messages unseen in chat, that looks weird
state, err := m.persistence.GetActivityCenterState()
if err != nil {
return nil, err

View File

@ -417,12 +417,12 @@ func (s *MessengerActivityCenterMessageSuite) confirmMentionAndReplyNotification
func (s *MessengerActivityCenterMessageSuite) TestMarkMessagesSeenMarksNotificationsRead() {
alice, _, mentionMessage, replyMessage, _ := s.prepareCommunityChannelWithMentionAndReply()
_, _, notifications, err := alice.MarkMessagesSeen(replyMessage.ChatId, []string{mentionMessage.ID, replyMessage.ID})
response, err := alice.MarkMessagesRead(replyMessage.ChatId, []string{mentionMessage.ID, replyMessage.ID})
s.Require().NoError(err)
s.Require().Len(notifications, 2)
s.Require().True(notifications[0].Read)
s.Require().True(notifications[1].Read)
s.Require().Len(response.ActivityCenterNotifications(), 2)
s.Require().True(response.ActivityCenterNotifications()[0].Read)
s.Require().True(response.ActivityCenterNotifications()[1].Read)
s.confirmMentionAndReplyNotificationsRead(alice, mentionMessage, replyMessage, true)
}

View File

@ -35,6 +35,13 @@ type ClearedHistory struct {
ClearedAt uint64 `json:"clearedAt"`
}
type SeenUnseenMessages struct {
ChatID string `json:"chatId"`
Count uint64 `json:"count"`
CountWithMentions uint64 `json:"countWithMentions"`
Seen bool `json:"seen"`
}
type MessengerResponse struct {
Contacts []*Contact
Installations []*multidevice.Installation
@ -81,6 +88,7 @@ type MessengerResponse struct {
SocialLinksInfo *identity.SocialLinksInfo
ensUsernameDetails []*ensservice.UsernameDetail
updatedProfileShowcases map[string]*ProfileShowcase
seenAndUnseenMessages map[string]*SeenUnseenMessages
}
func (r *MessengerResponse) MarshalJSON() ([]byte, error) {
@ -126,6 +134,7 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) {
SocialLinksInfo *identity.SocialLinksInfo `json:"socialLinksInfo,omitempty"`
EnsUsernameDetails []*ensservice.UsernameDetail `json:"ensUsernameDetails,omitempty"`
UpdatedProfileShowcases []*ProfileShowcase `json:"updatedProfileShowcases,omitempty"`
SeenAndUnseenMessages []*SeenUnseenMessages `json:"seenAndUnseenMessages,omitempty"`
}{
Contacts: r.Contacts,
Installations: r.Installations,
@ -164,6 +173,7 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) {
SocialLinksInfo: r.SocialLinksInfo,
EnsUsernameDetails: r.EnsUsernameDetails(),
UpdatedProfileShowcases: r.GetUpdatedProfileShowcases(),
SeenAndUnseenMessages: r.GetSeenAndUnseenMessages(),
}
responseItem.TrustStatus = r.TrustStatus()
@ -292,6 +302,7 @@ func (r *MessengerResponse) IsEmpty() bool {
len(r.RequestsToJoinCommunity)+
len(r.savedAddresses)+
len(r.updatedProfileShowcases)+
len(r.seenAndUnseenMessages)+
len(r.ensUsernameDetails) == 0 &&
r.currentStatus == nil &&
r.activityCenterState == nil &&
@ -329,6 +340,7 @@ func (r *MessengerResponse) Merge(response *MessengerResponse) error {
r.AddRequestsToJoinCommunity(response.RequestsToJoinCommunity)
r.AddBookmarks(response.GetBookmarks())
r.AddProfileShowcases(response.GetUpdatedProfileShowcases())
r.AddSeveralSeenAndUnseenMessages(response.GetSeenAndUnseenMessages())
r.CommunityChanges = append(r.CommunityChanges, response.CommunityChanges...)
r.BackupHandled = response.BackupHandled
r.CustomizationColor = response.CustomizationColor
@ -812,3 +824,25 @@ func (r *MessengerResponse) GetUpdatedProfileShowcases() []*ProfileShowcase {
}
return showcases
}
func (r *MessengerResponse) AddSeveralSeenAndUnseenMessages(messages []*SeenUnseenMessages) {
for _, message := range messages {
r.AddSeenAndUnseenMessages(message)
}
}
func (r *MessengerResponse) AddSeenAndUnseenMessages(message *SeenUnseenMessages) {
if r.seenAndUnseenMessages == nil {
r.seenAndUnseenMessages = make(map[string]*SeenUnseenMessages)
}
r.seenAndUnseenMessages[message.ChatID] = message
}
func (r *MessengerResponse) GetSeenAndUnseenMessages() []*SeenUnseenMessages {
var messages []*SeenUnseenMessages
for _, message := range r.seenAndUnseenMessages {
messages = append(messages, message)
}
return messages
}

View File

@ -268,18 +268,25 @@ func (s *MessengerSuite) TestMarkMessagesSeen() {
err = s.m.SaveMessages([]*common.Message{inputMessage1, inputMessage2})
s.Require().NoError(err)
count, countWithMentions, notifications, err := s.m.MarkMessagesSeen(chat.ID, []string{inputMessage1.ID})
response, err := s.m.MarkMessagesRead(chat.ID, []string{inputMessage1.ID})
s.Require().NoError(err)
s.Require().Equal(uint64(1), count)
s.Require().Equal(uint64(1), countWithMentions)
s.Require().Len(notifications, 0)
s.Require().Len(response.GetSeenAndUnseenMessages(), 1)
s.Require().Equal(chat.ID, response.GetSeenAndUnseenMessages()[0].ChatID)
s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].Count)
s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].CountWithMentions)
s.Require().Equal(true, response.GetSeenAndUnseenMessages()[0].Seen)
s.Require().Len(response.ActivityCenterNotifications(), 0)
// Make sure that if it's not seen, it does not return a count of 1
count, countWithMentions, notifications, err = s.m.MarkMessagesSeen(chat.ID, []string{inputMessage1.ID})
response, err = s.m.MarkMessagesRead(chat.ID, []string{inputMessage1.ID})
s.Require().NoError(err)
s.Require().Equal(uint64(0), count)
s.Require().Equal(uint64(0), countWithMentions)
s.Require().Len(notifications, 0)
s.Require().Len(response.GetSeenAndUnseenMessages(), 1)
s.Require().Equal(chat.ID, response.GetSeenAndUnseenMessages()[0].ChatID)
s.Require().Equal(uint64(0), response.GetSeenAndUnseenMessages()[0].Count)
s.Require().Equal(uint64(0), response.GetSeenAndUnseenMessages()[0].CountWithMentions)
s.Require().Equal(true, response.GetSeenAndUnseenMessages()[0].Seen)
s.Require().Len(response.ActivityCenterNotifications(), 0)
chats := s.m.Chats()
for _, c := range chats {

View File

@ -69,11 +69,14 @@ func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageListContainsSingleMes
s.Require().False(actualChat.Highlight)
s.checkMessageSeen(inputMessage1.ID, true)
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage1.ID)
response, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage1.ID)
s.Require().NoError(err)
s.Require().Equal(uint64(1), count)
s.Require().Equal(uint64(1), countWithMentions)
s.Require().Len(notifications, 0)
s.Require().Len(response.GetSeenAndUnseenMessages(), 1)
s.Require().Equal(chat.ID, response.GetSeenAndUnseenMessages()[0].ChatID)
s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].Count)
s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].CountWithMentions)
s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen)
s.Require().Len(response.ActivityCenterNotifications(), 0)
chats = s.m.allChats
@ -134,7 +137,7 @@ func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageListContainsSeveralMe
s.checkMessageSeen(inputMessage2.ID, true)
s.checkMessageSeen(inputMessage3.ID, true)
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage2.ID)
response, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage2.ID)
s.Require().NoError(err)
// count is 2 because the messages are layout the following way :
@ -147,9 +150,11 @@ func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageListContainsSeveralMe
// And the inputMessage3 has greater timestamp than inputMessage2
// Similarly, the mentioned message is inputMessage1, therefore the
// countWithMentions is 0
s.Require().Equal(uint64(2), count)
s.Require().Equal(uint64(0), countWithMentions)
s.Require().Len(notifications, 0)
s.Require().Len(response.GetSeenAndUnseenMessages(), 1)
s.Require().Equal(chat.ID, response.GetSeenAndUnseenMessages()[0].ChatID)
s.Require().Equal(uint64(2), response.GetSeenAndUnseenMessages()[0].Count)
s.Require().Equal(uint64(0), response.GetSeenAndUnseenMessages()[0].CountWithMentions)
s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen)
chats = s.m.allChats
actualChat, ok = chats.Load(chat.ID)
@ -190,11 +195,13 @@ func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageIsAlreadyInUnreadStat
s.Require().True(actualChat.Highlight)
s.checkMessageSeen(inputMessage1.ID, false)
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage1.ID)
response, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage1.ID)
s.Require().NoError(err)
s.Require().Equal(uint64(1), count)
s.Require().Equal(uint64(0), countWithMentions)
s.Require().Len(notifications, 0)
s.Require().Len(response.GetSeenAndUnseenMessages(), 1)
s.Require().Equal(chat.ID, response.GetSeenAndUnseenMessages()[0].ChatID)
s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].Count)
s.Require().Equal(uint64(0), response.GetSeenAndUnseenMessages()[0].CountWithMentions)
s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen)
chats = s.m.allChats
actualChat, ok = chats.Load(chat.ID)
@ -249,13 +256,15 @@ func (s *MessengerSuite) TestMarkMessageAsUnreadInOneChatDoesNotImpactOtherChats
s.checkMessageSeen(inputMessage1.ID, true)
s.checkMessageSeen(inputMessage2.ID, true)
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(chat1.ID, inputMessage1.ID)
response, err := s.m.MarkMessageAsUnread(chat1.ID, inputMessage1.ID)
s.Require().NoError(err)
s.Require().Equal(uint(1), chat2.UnviewedMessagesCount)
s.Require().Equal(uint64(2), count)
s.Require().Equal(uint64(0), countWithMentions)
s.Require().Len(notifications, 0)
s.Require().Len(response.GetSeenAndUnseenMessages(), 1)
s.Require().Equal(chat1.ID, response.GetSeenAndUnseenMessages()[0].ChatID)
s.Require().Equal(uint64(2), response.GetSeenAndUnseenMessages()[0].Count)
s.Require().Equal(uint64(0), response.GetSeenAndUnseenMessages()[0].CountWithMentions)
s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen)
s.Require().Len(response.ActivityCenterNotifications(), 0)
chats := s.m.allChats
actualChat, ok := chats.Load(chat1.ID)
@ -325,11 +334,14 @@ func (s *MessengerSuite) TestMarkMessageWithNotificationAsUnreadInCommunityChatS
s.Require().Len(response.ActivityCenterNotifications(), 1)
s.Require().True(response.ActivityCenterNotifications()[0].Read)
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(communityChat.ID, inputMessage1.ID)
response, err = s.m.MarkMessageAsUnread(communityChat.ID, inputMessage1.ID)
s.Require().NoError(err)
s.Require().Equal(count, uint64(1))
s.Require().Equal(countWithMentions, uint64(1))
s.Require().Len(notifications, 1)
s.Require().False(notifications[0].Read)
s.Require().Len(response.GetSeenAndUnseenMessages(), 1)
s.Require().Equal(communityChat.ID, response.GetSeenAndUnseenMessages()[0].ChatID)
s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].Count)
s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].CountWithMentions)
s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen)
s.Require().Len(response.ActivityCenterNotifications(), 1)
s.Require().False(response.ActivityCenterNotifications()[0].Read)
}

View File

@ -797,6 +797,7 @@ func (api *PublicAPI) DeleteMessagesByChatID(id string) error {
return api.service.messenger.DeleteMessagesByChatID(id)
}
// Deprecated: Use MarkMessagesRead instead
func (api *PublicAPI) MarkMessagesSeen(chatID string, ids []string) (*MarkMessageSeenResponse, error) {
count, withMentions, notifications, err := api.service.messenger.MarkMessagesSeen(chatID, ids)
if err != nil {
@ -811,18 +812,12 @@ func (api *PublicAPI) MarkMessagesSeen(chatID string, ids []string) (*MarkMessag
return response, nil
}
func (api *PublicAPI) MarkMessageAsUnread(chatID string, messageID string) (*MarkMessageSeenResponse, error) {
count, withMentions, notifications, err := api.service.messenger.MarkMessageAsUnread(chatID, messageID)
if err != nil {
return nil, err
}
func (api *PublicAPI) MarkMessagesRead(chatID string, ids []string) (*protocol.MessengerResponse, error) {
return api.service.messenger.MarkMessagesRead(chatID, ids)
}
response := &MarkMessageSeenResponse{
Count: count,
CountWithMentions: withMentions,
ActivityCenterNotifications: notifications,
}
return response, nil
func (api *PublicAPI) MarkMessageAsUnread(chatID string, messageID string) (*protocol.MessengerResponse, error) {
return api.service.messenger.MarkMessageAsUnread(chatID, messageID)
}
func (api *PublicAPI) MarkAllRead(ctx context.Context, chatID string) (*protocol.MessengerResponse, error) {