mirror of
https://github.com/status-im/status-app.git
synced 2026-08-27 07:01:14 +00:00
fix(threads): clear unread badge when opening thread
Pass the active threadId through chat content mark-read handling so thread views call the thread-aware status-go mark-read path instead of the parent chat mark-all-read path. Carry threadId through the async message service read event and use it to route read acknowledgements to the matching thread controller. When a thread is marked read, clear the synthetic thread row badge while leaving the parent channel unread state untouched. This fixes unread thread badges staying visible after entering a thread.
This commit is contained in:
@@ -20,6 +20,7 @@ type
|
||||
events: UniqueUUIDEventEmitter
|
||||
sectionId: string
|
||||
chatId: string
|
||||
threadId: string
|
||||
belongsToCommunity: bool
|
||||
isUsersListAvailable: bool #users list is not available for 1:1 chat
|
||||
nodeConfigurationService: node_configuration_service.Service
|
||||
@@ -37,12 +38,13 @@ proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter
|
||||
belongsToCommunity: bool, isUsersListAvailable: bool, settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service, contactService: contact_service.Service,
|
||||
chatService: chat_service.Service, communityService: community_service.Service,
|
||||
messageService: message_service.Service): Controller =
|
||||
messageService: message_service.Service, threadId: string = ""): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.events = initUniqueUUIDEventEmitter(events)
|
||||
result.sectionId = sectionId
|
||||
result.chatId = chatId
|
||||
result.threadId = threadId
|
||||
result.belongsToCommunity = belongsToCommunity
|
||||
result.isUsersListAvailable = isUsersListAvailable
|
||||
result.settingsService = settingsService
|
||||
@@ -238,7 +240,7 @@ proc unblockChat*(self: Controller) =
|
||||
self.contactService.unblockContact(self.chatId)
|
||||
|
||||
proc markAllMessagesRead*(self: Controller) =
|
||||
self.messageService.markAllMessagesRead(self.chatId)
|
||||
self.messageService.markAllMessagesRead(self.chatId, self.threadId)
|
||||
|
||||
proc markMessageRead*(self: Controller, msgID: string) =
|
||||
self.messageService.markCertainMessagesRead(self.chatId, @[msgID])
|
||||
|
||||
@@ -150,6 +150,8 @@ proc init*(self: Controller) =
|
||||
let args = MessagesMarkedAsReadArgs(e)
|
||||
if self.chatId != args.chatId:
|
||||
return
|
||||
if self.threadId != args.threadId:
|
||||
return
|
||||
if args.allMessagesMarked:
|
||||
self.delegate.markAllMessagesRead()
|
||||
else:
|
||||
|
||||
@@ -54,7 +54,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitt
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity,
|
||||
isUsersListAvailable, settingsService, nodeConfigurationService, contactService, chatService, communityService,
|
||||
messageService)
|
||||
messageService, threadId = threadId)
|
||||
result.moduleLoaded = false
|
||||
|
||||
result.inputAreaModule = input_area_module.newModule(result, events, sectionId, chatId, belongsToCommunity,
|
||||
|
||||
@@ -124,8 +124,9 @@ proc init*(self: Controller) =
|
||||
if ((self.isCommunitySection and chat.communityId != self.sectionId) or
|
||||
(not self.isCommunitySection and chat.communityId != "")):
|
||||
return
|
||||
self.chatService.updateUnreadMessagesAndMentions(args.chatId, args.allMessagesMarked, args.messagesCount, args.messagesWithMentionsCount)
|
||||
self.delegate.onMarkAllMessagesRead(chat)
|
||||
if args.threadId.len == 0:
|
||||
self.chatService.updateUnreadMessagesAndMentions(args.chatId, args.allMessagesMarked, args.messagesCount, args.messagesWithMentionsCount)
|
||||
self.delegate.onMarkAllMessagesRead(chat, args.threadId)
|
||||
|
||||
self.events.on(message_service.SIGNAL_MESSAGE_MARKED_AS_UNREAD) do(e:Args):
|
||||
let args = message_service.MessageMarkMessageAsUnreadArgs(e)
|
||||
|
||||
@@ -102,7 +102,7 @@ method onNewMessagesReceived*(self: AccessInterface, sectionIdMsgBelongsTo: stri
|
||||
method changeMutedOnChat*(self: AccessInterface, chatId: string, muted: bool) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onMarkAllMessagesRead*(self: AccessInterface, chat: ChatDto) {.base.} =
|
||||
method onMarkAllMessagesRead*(self: AccessInterface, chat: ChatDto, threadId: string = "") {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onMarkMessageAsUnread*(self: AccessInterface, chat: ChatDto) {.base.} =
|
||||
|
||||
@@ -1249,7 +1249,14 @@ method onJoinedCommunity*(self: Module) =
|
||||
self.view.setWaitingOnNewCommunityOwnerToConfirmRequestToRejoin(false)
|
||||
self.view.setRequestToJoinState(RequestToJoinState.None)
|
||||
|
||||
method onMarkAllMessagesRead*(self: Module, chat: ChatDto) =
|
||||
method onMarkAllMessagesRead*(self: Module, chat: ChatDto, threadId: string = "") =
|
||||
if threadId.len > 0:
|
||||
self.view.chatsModel().updateNotificationsForItemById(threadId, hasUnreadMessages=false, notificationsCount=0)
|
||||
if self.chatContentModules.contains(threadId):
|
||||
self.chatContentModules[threadId].onNotificationsUpdated(hasUnreadMessages=false, notificationCount=0)
|
||||
self.updateParentBadgeNotifications()
|
||||
return
|
||||
|
||||
self.updateBadgeNotifications(chat, hasUnreadMessages=false, unviewedMentionsCount=0)
|
||||
|
||||
method onMarkMessageAsUnread*(self: Module, chat: ChatDto) =
|
||||
|
||||
@@ -357,18 +357,24 @@ proc asyncSearchMessagesInChatsAndCommunitiesTask(argEncoded: string) {.gcsafe,
|
||||
type
|
||||
AsyncMarkAllMessagesReadTaskArg = ref object of QObjectTaskArg
|
||||
chatId: string
|
||||
threadId: string
|
||||
|
||||
proc asyncMarkAllMessagesReadTask(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncMarkAllMessagesReadTaskArg](argEncoded)
|
||||
|
||||
try:
|
||||
let rpcResponse = status_go.markAllMessagesFromChatWithIdAsRead(arg.chatId)
|
||||
let rpcResponse =
|
||||
if arg.threadId.len > 0:
|
||||
status_go.markAllMessagesFromThreadWithIdAsRead(arg.chatId, arg.threadId)
|
||||
else:
|
||||
status_go.markAllMessagesFromChatWithIdAsRead(arg.chatId)
|
||||
|
||||
var activityCenterNotifications: JsonNode = newJObject()
|
||||
discard rpcResponse.result.getProp("activityCenterNotifications", activityCenterNotifications)
|
||||
|
||||
arg.finish(%*{
|
||||
"chatId": arg.chatId,
|
||||
"threadId": arg.threadId,
|
||||
"activityCenterNotifications": activityCenterNotifications,
|
||||
"error": rpcResponse.error,
|
||||
})
|
||||
@@ -376,6 +382,7 @@ proc asyncMarkAllMessagesReadTask(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
except Exception as e:
|
||||
arg.finish(%* {
|
||||
"chatId": arg.chatId,
|
||||
"threadId": arg.threadId,
|
||||
"error": e.msg,
|
||||
})
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ type
|
||||
|
||||
MessagesMarkedAsReadArgs* = ref object of Args
|
||||
chatId*: string
|
||||
threadId*: string
|
||||
allMessagesMarked*: bool
|
||||
messagesIds*: seq[string]
|
||||
messagesCount*: int
|
||||
@@ -1310,13 +1311,16 @@ QtObject:
|
||||
var chatId: string
|
||||
discard responseObj.getProp("chatId", chatId)
|
||||
|
||||
let data = MessagesMarkedAsReadArgs(chatId: chatId, allMessagesMarked: true)
|
||||
var threadId: string
|
||||
discard responseObj.getProp("threadId", threadId)
|
||||
|
||||
let data = MessagesMarkedAsReadArgs(chatId: chatId, threadId: threadId, allMessagesMarked: true)
|
||||
self.events.emit(SIGNAL_MESSAGES_MARKED_AS_READ, data)
|
||||
checkAndEmitACNotificationsFromResponse(self.events, responseObj{"activityCenterNotifications"})
|
||||
except Exception as e:
|
||||
error "error: ", procName="onMarkAllMessagesRead", errDesription = e.msg
|
||||
|
||||
proc markAllMessagesRead*(self: Service, chatId: string) =
|
||||
proc markAllMessagesRead*(self: Service, chatId: string, threadId: string = "") =
|
||||
if (chatId.len == 0):
|
||||
error "empty chat id", procName="markAllMessagesRead"
|
||||
return
|
||||
@@ -1325,7 +1329,8 @@ QtObject:
|
||||
tptr: asyncMarkAllMessagesReadTask,
|
||||
vptr: cast[uint](self.vptr),
|
||||
slot: "onMarkAllMessagesRead",
|
||||
chatId: chatId
|
||||
chatId: chatId,
|
||||
threadId: threadId
|
||||
)
|
||||
|
||||
self.threadpool.start(arg)
|
||||
|
||||
@@ -58,6 +58,10 @@ proc markAllMessagesFromChatWithIdAsRead*(chatId: string): RpcResponse[JsonNode]
|
||||
let payload = %* [chatId]
|
||||
result = callPrivateRPC("markAllRead".prefix, payload)
|
||||
|
||||
proc markAllMessagesFromThreadWithIdAsRead*(chatId: string, threadId: string): RpcResponse[JsonNode] =
|
||||
let payload = %* [chatId, threadId]
|
||||
result = callPrivateRPC("markThreadRead".prefix, payload)
|
||||
|
||||
proc markCertainMessagesFromChatWithIdAsRead*(chatId: string, messageIds: seq[string]):
|
||||
RpcResponse[JsonNode] =
|
||||
let payload = %* [chatId, messageIds]
|
||||
|
||||
+2
-2
@@ -17165,7 +17165,7 @@ avec un retour à la ligne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Fastest</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation type="unfinished">Le plus rapide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Shortest execution time</source>
|
||||
@@ -17173,7 +17173,7 @@ avec un retour à la ligne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Lowest fee</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation type="unfinished">Frais le plus bas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Lowest network cost</source>
|
||||
|
||||
Reference in New Issue
Block a user