feat(chat): implement marking specific messages as seen

iterates: #9069
This commit is contained in:
Patryk Osmaczko 2023-04-11 22:28:24 +02:00 committed by osmaczko
parent 2e68c97c8e
commit e822c37716
15 changed files with 119 additions and 14 deletions

View File

@ -224,6 +224,9 @@ proc unblockChat*(self: Controller) =
proc markAllMessagesRead*(self: Controller) =
self.messageService.markAllMessagesRead(self.chatId)
proc markMessageRead*(self: Controller, msgID: string) =
self.messageService.markCertainMessagesRead(self.chatId, @[msgID])
proc clearChatHistory*(self: Controller) =
self.chatService.clearChatHistory(self.chatId)

View File

@ -101,6 +101,9 @@ method unblockChat*(self: AccessInterface) {.base.} =
method markAllMessagesRead*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method markMessageRead*(self: AccessInterface, msgID: string) {.base.} =
raise newException(ValueError, "No implementation available")
method clearChatHistory*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -132,7 +132,10 @@ proc init*(self: Controller) =
let args = MessagesMarkedAsReadArgs(e)
if(self.chatId != args.chatId):
return
if(args.allMessagesMarked):
self.delegate.markAllMessagesRead()
else:
self.delegate.markMessagesAsRead(args.messagesIds)
self.events.on(SIGNAL_CONTACT_NICKNAME_CHANGED) do(e: Args):
var args = ContactArgs(e)

View File

@ -164,6 +164,9 @@ method resetAndScrollToNewMessagesMarker*(self: AccessInterface) =
method markAllMessagesRead*(self: AccessInterface) =
raise newException(ValueError, "No implementation available")
method markMessagesAsRead*(self: AccessInterface, messages: seq[string]) =
raise newException(ValueError, "No implementation available")
method updateCommunityDetails*(self: AccessInterface, community: CommunityDto) =
raise newException(ValueError, "No implementation available")

View File

@ -712,6 +712,9 @@ method removeNewMessagesMarker*(self: Module) =
method markAllMessagesRead*(self: Module) =
self.view.model().markAllAsSeen()
method markMessagesAsRead*(self: Module, messages: seq[string]) =
self.view.model().markAsSeen(messages)
method updateCommunityDetails*(self: Module, community: CommunityDto) =
self.view.setAmIChatAdmin(community.admin)
self.view.setIsPinMessageAllowedForMembers(community.adminSettings.pinMessageAllMembersEnabled)

View File

@ -274,6 +274,9 @@ method unblockChat*(self: Module) =
method markAllMessagesRead*(self: Module) =
self.controller.markAllMessagesRead()
method markMessageRead*(self: Module, msgID: string) =
self.controller.markMessageRead(msgID)
method clearChatHistory*(self: Module) =
self.controller.clearChatHistory()

View File

@ -86,6 +86,9 @@ QtObject:
proc markAllMessagesRead*(self: View) {.slot.} =
self.delegate.markAllMessagesRead()
proc markMessageRead*(self: View, msgID: string) {.slot.} =
self.delegate.markMessageRead(msgID)
proc clearChatHistory*(self: View) {.slot.} =
self.delegate.clearChatHistory()

View File

@ -147,14 +147,12 @@ proc init*(self: Controller) =
self.events.on(message_service.SIGNAL_MESSAGES_MARKED_AS_READ) do(e: Args):
let args = message_service.MessagesMarkedAsReadArgs(e)
# update chat entity in chat service
var chat = self.chatService.getChatById(args.chatId)
let chat = self.chatService.getChatById(args.chatId)
if ((self.isCommunitySection and chat.communityId != self.sectionId) or
(not self.isCommunitySection and chat.communityId != "")):
return
chat.unviewedMessagesCount = 0
chat.unviewedMentionsCount = 0
self.chatService.updateOrAddChat(chat)
self.delegate.onMarkAllMessagesRead(args.chatId)
self.chatService.updateUnreadMessagesAndMentions(args.chatId, args.allMessagesMarked, args.messagesCount, args.messagesWithMentionsCount)
self.delegate.updateUnreadMessagesAndMentions(args.chatId)
self.events.on(chat_service.SIGNAL_CHAT_LEFT) do(e: Args):
let args = chat_service.ChatArgs(e)

View File

@ -111,7 +111,7 @@ method onChatMuted*(self: AccessInterface, chatId: string) {.base.} =
method onChatUnmuted*(self: AccessInterface, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onMarkAllMessagesRead*(self: AccessInterface, chatId: string) {.base.} =
method updateUnreadMessagesAndMentions*(self: AccessInterface, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onContactAdded*(self: AccessInterface, publicKey: string) {.base.} =

View File

@ -827,9 +827,12 @@ method onJoinedCommunity*(self: Module) =
method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string) =
self.controller.requestToJoinCommunityAuthenticated(password)
method onMarkAllMessagesRead*(self: Module, chatId: string) =
self.updateBadgeNotifications(chatId, hasUnreadMessages=false, unviewedMentionsCount=0)
method updateUnreadMessagesAndMentions*(self: Module, chatId: string) =
let chatDetails = self.controller.getChatDetails(chatId)
self.updateBadgeNotifications(
chatId=chatId,
hasUnreadMessages=chatDetails.unviewedMessagesCount > 0,
unviewedMentionsCount=chatDetails.unviewedMentionsCount)
if chatDetails.categoryId != "":
let hasUnreadMessages = self.controller.chatsWithCategoryHaveUnreadMessages(chatDetails.communityId, chatDetails.categoryId)
self.view.chatsModel().setCategoryHasUnreadMessages(chatDetails.categoryId, hasUnreadMessages)

View File

@ -713,6 +713,21 @@ QtObject:
let index = self.createIndex(i, 0, nil)
self.dataChanged(index, index, @[ModelRole.Seen.int])
proc markAsSeen*(self: Model, messages: seq[string]) =
var messagesSet = toHashSet(messages)
for i in 0 ..< self.items.len:
let currentItemID = self.items[i].id
if messagesSet.contains(currentItemID):
self.items[i].seen = true
let index = self.createIndex(i, 0, nil)
self.dataChanged(index, index, @[ModelRole.Seen.int])
messagesSet.excl(currentItemID)
if messagesSet.len == 0:
return
proc updateAlbumIfExists*(self: Model, albumId: string, messageImage: string, messageId: string): bool =
for i in 0 ..< self.items.len:
let item = self.items[i]

View File

@ -725,3 +725,15 @@ QtObject:
result.add(member)
except Exception as e:
error "error while getting members", msg = e.msg, communityID, chatId
proc updateUnreadMessagesAndMentions*(self: Service, chatID: string, markAllAsRead: bool, markAsReadCount: int, markAsReadMentionsCount: int) =
var chat = self.getChatById(chatID)
if chat.id == "":
return
if markAllAsRead:
chat.unviewedMessagesCount = 0
chat.unviewedMentionsCount = 0
else:
chat.unviewedMessagesCount = max(0, chat.unviewedMessagesCount - markAsReadCount)
chat.unviewedMentionsCount = max(0, chat.unviewedMentionsCount - markAsReadMentionsCount)
self.updateOrAddChat(chat)

View File

@ -142,16 +142,21 @@ const asyncMarkCertainMessagesReadTask: Task = proc(argEncoded: string) {.gcsafe
let response = status_go.markCertainMessagesFromChatWithIdAsRead(arg.chatId, arg.messagesIds)
var numberOfAffectedMessages: int
discard response.result.getProp("count", numberOfAffectedMessages)
var count: int
discard response.result.getProp("count", count)
var countWithMentions: int
discard response.result.getProp("countWithMentions", countWithMentions)
var error = ""
if(numberOfAffectedMessages == 0):
if(count == 0):
error = "no message has updated"
let responseJson = %*{
"chatId": arg.chatId,
"messagesIds": arg.messagesIds,
"count": count,
"countWithMentions": countWithMentions,
"error": error
}
arg.finish(responseJson)

View File

@ -88,6 +88,8 @@ type
chatId*: string
allMessagesMarked*: bool
messagesIds*: seq[string]
messagesCount*: int
messagesWithMentionsCount*: int
MessageAddRemoveReactionArgs* = ref object of Args
chatId*: string
@ -640,7 +642,7 @@ QtObject:
var error: string
discard responseObj.getProp("error", error)
if(error.len > 0):
error "error: ", procName="onMarkCertainMessagesRead", errDescription=error
error "error: ", procName="onMarkAllMessagesRead", errDescription=error
return
var chatId: string
@ -681,7 +683,21 @@ QtObject:
for id in messagesIdsArr:
messagesIds.add(id.getStr)
let data = MessagesMarkedAsReadArgs(chatId: chatId, allMessagesMarked: false, messagesIds: messagesIds)
var count: int
discard responseObj.getProp("count", count)
if count < len(messagesIds):
warn "warning: ", procName="onMarkCertainMessagesRead", errDescription="not all messages has been marked as read"
var countWithMentions: int
discard responseObj.getProp("countWithMentions", countWithMentions)
let data = MessagesMarkedAsReadArgs(
chatId: chatId,
allMessagesMarked: false,
messagesIds: messagesIds,
messagesCount: count,
messagesWithMentionsCount: countWithMentions)
self.events.emit(SIGNAL_MESSAGES_MARKED_AS_READ, data)
proc markCertainMessagesRead*(self: Service, chatId: string, messagesIds: seq[string]) =

View File

@ -311,3 +311,38 @@ suite "simulations":
check(model.items[5].id == message1.id)
check(model.items[6].id == message0_fetchMoreMessages.id)
check(model.items[7].id == message0_chatIdentifier.id)
suite "mark as seen":
setup:
let model = newModel()
var msg1 = createTestMessageItem("0xa", 1)
msg1.seen=false
let msg2 = createTestMessageItem("0xb", 2)
msg2.seen=false
let msg3 = createTestMessageItem("0xc", 3)
msg3.seen=true
model.insertItemsBasedOnClock(@[msg1, msg2, msg3])
require(model.items.len == 3)
check(model.items[0].seen == true)
check(model.items[1].seen == false)
check(model.items[2].seen == false)
test "mark all as seen":
model.markAllAsSeen()
check(model.items[0].seen == true)
check(model.items[1].seen == true)
check(model.items[2].seen == true)
test "mark some as seen":
model.markAsSeen(@["0xa"])
check(model.items[0].seen == true)
check(model.items[1].seen == false)
check(model.items[2].seen == true)
model.markAsSeen(@["0xb"])
check(model.items[0].seen == true)
check(model.items[1].seen == true)
check(model.items[2].seen == true)