feat(ActivityCenter): Sync message & AC notification read state (#12815)

* feat(ActivityCenter): Use signal for delivery of AC notifications from other services

Close #9349

* feat(ActivityCenter): Sync messages read state with AC notifications
This commit is contained in:
Mikhail Rogachev 2023-11-27 16:22:58 +04:00 committed by GitHub
parent 0dbbea383d
commit 9a714cfec0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 81 additions and 39 deletions

View File

@ -171,8 +171,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
statusFoundation.fleetConfiguration)
result.networkService = network_service.newService(statusFoundation.events, result.settingsService)
result.contactsService = contacts_service.newService(
statusFoundation.events, statusFoundation.threadpool, result.networkService, result.settingsService,
result.activityCenterService
statusFoundation.events, statusFoundation.threadpool, result.networkService, result.settingsService
)
result.chatService = chat_service.newService(statusFoundation.events, statusFoundation.threadpool, result.contactsService)
result.tokenService = token_service.newService(

View File

@ -0,0 +1,8 @@
import json
import ../../app/core/eventemitter
const SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS* = "parseRawActivityCenterNotifications"
type RawActivityCenterNotificationsArgs* = ref object of Args
activityCenterNotifications*: JsonNode

View File

@ -11,6 +11,8 @@ import ../../../backend/backend
import ../../../backend/response_type
import ./dto/notification
import ../../common/activity_center
export notification
include async_tasks
@ -99,15 +101,13 @@ QtObject:
if (receivedData.activityCenterNotifications.len > 0):
self.handleNewNotificationsLoaded(receivedData.activityCenterNotifications)
proc parseActivityCenterNotifications*(self: Service, notificationsJson: JsonNode) =
var activityCenterNotifications: seq[ActivityCenterNotificationDto] = @[]
for notificationJson in notificationsJson:
activityCenterNotifications.add(notificationJson.toActivityCenterNotificationDto)
self.handleNewNotificationsLoaded(activityCenterNotifications)
proc parseActivityCenterResponse*(self: Service, response: RpcResponse[JsonNode]) =
if response.result{"activityCenterNotifications"} != nil:
self.parseActivityCenterNotifications(response.result["activityCenterNotifications"])
self.events.on(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS) do(e: Args):
let raw = RawActivityCenterNotificationsArgs(e)
if raw.activityCenterNotifications.kind != JNull:
var activityCenterNotifications: seq[ActivityCenterNotificationDto] = @[]
for notificationJson in raw.activityCenterNotifications:
activityCenterNotifications.add(notificationJson.toActivityCenterNotificationDto)
self.handleNewNotificationsLoaded(activityCenterNotifications)
proc setActiveNotificationGroup*(self: Service, group: ActivityCenterGroup) =
self.activeGroup = group

View File

@ -9,6 +9,8 @@ import ../activity_center/service as activity_center_service
import ../message/service as message_service
import ../chat/service as chat_service
import ../../common/activity_center
import ../../../app/global/global_singleton
import ../../../app/core/signals/types
import ../../../app/core/eventemitter
@ -556,7 +558,8 @@ QtObject:
if prev_community.isOwner and not community.isOwner:
self.events.emit(SIGNAL_COMMUNITY_LOST_OWNERSHIP, CommunityIdArgs(communityId: community.id))
let response = tokens_backend.registerLostOwnershipNotification(community.id)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
# If there's settings without `id` it means the original
# signal didn't include actual communitySettings, hence we
@ -1034,7 +1037,8 @@ QtObject:
proc leaveCommunity*(self: Service, communityId: string) =
try:
let response = status_go.leaveCommunity(communityId)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
if response.error != nil:
let error = Json.decode($response.error, RpcError)
@ -1664,7 +1668,8 @@ QtObject:
raise newException(CatchableError, rpcResponseObj{"error"}.getStr)
let rpcResponse = Json.decode($rpcResponseObj["response"], RpcResponse[JsonNode])
self.activityCenterService.parseActivityCenterResponse(rpcResponse)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: rpcResponse.result{"activityCenterNotifications"}))
if not self.processRequestsToJoinCommunity(rpcResponse.result):
raise newException(CatchableError, "no 'requestsToJoinCommunity' key in response")
@ -1755,10 +1760,9 @@ QtObject:
self.events.emit(SIGNAL_COMMUNITY_MEMBER_APPROVED,
CommunityMemberArgs(communityId: communityId, pubKey: userKey, requestId: requestId))
if rpcResponseObj["response"]["result"]{"activityCenterNotifications"}.kind != JNull:
self.activityCenterService.parseActivityCenterNotifications(
rpcResponseObj["response"]["result"]["activityCenterNotifications"]
)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications:
rpcResponseObj["response"]["result"]{"activityCenterNotifications"}))
except Exception as e:
let errMsg = e.msg
@ -2003,7 +2007,8 @@ QtObject:
error "error while cancel membership request ", msg
return
self.myCommunityRequests.delete(i)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
self.events.emit(SIGNAL_REQUEST_TO_JOIN_COMMUNITY_CANCELED, Args())
return
@ -2015,7 +2020,8 @@ QtObject:
proc declineRequestToJoinCommunity*(self: Service, communityId: string, requestId: string) =
try:
let response = status_go.declineRequestToJoinCommunity(requestId)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
let requestToJoin = response.result["requestsToJoinCommunity"][0].toCommunityMembershipRequestDto

View File

@ -22,6 +22,7 @@ import ../../../backend/backend
import ../../../backend/response_type
import ../../common/activity_center
import ../../common/conversion
import ../../common/account_constants
import ../../common/utils as common_utils
@ -297,7 +298,9 @@ QtObject:
let finaliseStatusArgs = FinaliseOwnershipStatusArgs(isPending: true, communityId: communityId)
self.events.emit(SIGNAL_FINALISE_OWNERSHIP_STATUS, finaliseStatusArgs)
let response = tokens_backend.registerOwnerTokenReceivedNotification(communityId)
self.acService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
except Exception as e:
error "Error registering owner token received notification", msg=e.msg
@ -318,7 +321,8 @@ QtObject:
communityId: contractDetails.communityId)
self.events.emit(SIGNAL_SET_SIGNER_STATUS, data)
let response = if transactionArgs.success: tokens_backend.registerReceivedOwnershipNotification(contractDetails.communityId) else: tokens_backend.registerSetSignerFailedNotification(contractDetails.communityId)
self.acService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
let notificationToSetRead = self.acService.getNotificationForTypeAndCommunityId(notification.ActivityCenterNotificationType.OwnerTokenReceived, contractDetails.communityId)
if notificationToSetRead != nil:
self.acService.markActivityCenterNotificationRead(notificationToSetRead.id)
@ -1278,7 +1282,8 @@ QtObject:
discard self.acService.deleteActivityCenterNotifications(@[notification.id])
try:
let response = tokens_backend.registerSetSignerDeclinedNotification(communityId)
self.acService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
except Exception as e:
error "Error registering decline set signer notification", msg=e.msg
let finaliseStatusArgs = FinaliseOwnershipStatusArgs(isPending: false, communityId: communityId)

View File

@ -4,10 +4,11 @@ import ../../../app/global/global_singleton
import ../../../app/core/signals/types
import ../../../app/core/eventemitter
import ../../../app/core/tasks/[qt, threadpool]
import ../../common/types as common_types
import ../../common/conversion as service_conversion
import ../../common/activity_center
import ../activity_center/service as activity_center_service
import ../settings/service as settings_service
import ../network/service as network_service
import ../visual_identity/service as procs_from_visual_identity_service
@ -96,7 +97,6 @@ QtObject:
threadpool: ThreadPool
networkService: network_service.Service
settingsService: settings_service.Service
activityCenterService: activity_center_service.Service
contacts: Table[string, ContactDetails] # [contact_id, ContactDetails]
contactsStatus: Table[string, StatusUpdateDto] # [contact_id, StatusUpdateDto]
receivedIdentityRequests: Table[string, VerificationRequest] # [from_id, VerificationRequest]
@ -122,8 +122,7 @@ QtObject:
events: EventEmitter,
threadpool: ThreadPool,
networkService: network_service.Service,
settingsService: settings_service.Service,
activityCenterService: activity_center_service.Service,
settingsService: settings_service.Service
): Service =
new(result, delete)
result.QObject.setup
@ -131,7 +130,6 @@ QtObject:
result.events = events
result.networkService = networkService
result.settingsService = settingsService
result.activityCenterService = activityCenterService
result.threadpool = threadpool
result.contacts = initTable[string, ContactDetails]()
result.contactsStatus = initTable[string, StatusUpdateDto]()
@ -472,7 +470,8 @@ QtObject:
return
self.parseContactsResponse(response)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
self.events.emit(SIGNAL_RELOAD_ONE_TO_ONE_CHAT, ReloadOneToOneArgs(sectionId: publicKey))
except Exception as e:
@ -492,7 +491,8 @@ QtObject:
return
self.parseContactsResponse(response)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
self.events.emit(SIGNAL_RELOAD_ONE_TO_ONE_CHAT, ReloadOneToOneArgs(sectionId: publicKey))
except Exception as e:
@ -512,7 +512,8 @@ QtObject:
return
self.parseContactsResponse(response)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
except Exception as e:
error "an error occurred while dismissing contact request", msg=e.msg
@ -560,7 +561,8 @@ QtObject:
self.events.emit(SIGNAL_RELOAD_ONE_TO_ONE_CHAT, ReloadOneToOneArgs(sectionId: publicKey))
self.parseContactsResponse(response)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
proc ensResolved*(self: Service, jsonObj: string) {.slot.} =
let jsonObj = jsonObj.parseJson()
@ -618,7 +620,8 @@ QtObject:
if not response.error.isNil:
let msg = response.error.message
raise newException(RpcException, msg)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
if self.contacts.hasKey(publicKey):
self.contacts[publicKey].dto.trustStatus = TrustStatus.Trusted
@ -643,7 +646,8 @@ QtObject:
if not response.error.isNil:
let msg = response.error.message
raise newException(RpcException, msg)
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
if self.contacts.hasKey(publicKey):
self.contacts[publicKey].dto.trustStatus = TrustStatus.Untrustworthy
@ -716,7 +720,8 @@ QtObject:
self.saveContact(contact)
self.events.emit(SIGNAL_CONTACT_VERIFICATION_SENT, ContactArgs(contactId: publicKey))
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
except Exception as e:
error "Error sending verification request", msg = e.msg
@ -739,7 +744,8 @@ QtObject:
self.saveContact(contact)
self.events.emit(SIGNAL_CONTACT_VERIFICATION_CANCELLED, ContactArgs(contactId: publicKey))
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
except Exception as e:
error "Error canceling verification request", msg = e.msg
@ -761,7 +767,8 @@ QtObject:
self.events.emit(SIGNAL_CONTACT_VERIFICATION_ACCEPTED,
VerificationRequestArgs(verificationRequest: request))
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
except Exception as e:
error "error accepting contact verification request", msg=e.msg
@ -780,7 +787,8 @@ QtObject:
self.receivedIdentityRequests[publicKey] = request
self.events.emit(SIGNAL_CONTACT_VERIFICATION_DECLINED, ContactArgs(contactId: publicKey))
self.activityCenterService.parseActivityCenterResponse(response)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: response.result{"activityCenterNotifications"}))
except Exception as e:
error "error declining contact verification request", msg=e.msg

View File

@ -124,8 +124,14 @@ const asyncMarkAllMessagesReadTask: Task = proc(argEncoded: string) {.gcsafe, ni
let arg = decode[AsyncMarkAllMessagesReadTaskArg](argEncoded)
let response = status_go.markAllMessagesFromChatWithIdAsRead(arg.chatId)
var activityCenterNotifications: JsonNode
if response.result{"activityCenterNotifications"} != nil:
activityCenterNotifications = response.result["activityCenterNotifications"]
let responseJson = %*{
"chatId": arg.chatId,
"activityCenterNotifications": activityCenterNotifications,
"error": response.error
}
arg.finish(responseJson)
@ -150,6 +156,10 @@ const asyncMarkCertainMessagesReadTask: Task = proc(argEncoded: string) {.gcsafe
var countWithMentions: int
discard response.result.getProp("countWithMentions", countWithMentions)
var activityCenterNotifications: JsonNode
if response.result{"activityCenterNotifications"} != nil:
activityCenterNotifications = response.result["activityCenterNotifications"]
var error = ""
if(count == 0):
error = "no message has updated"
@ -159,6 +169,7 @@ const asyncMarkCertainMessagesReadTask: Task = proc(argEncoded: string) {.gcsafe
"messagesIds": arg.messagesIds,
"count": count,
"countWithMentions": countWithMentions,
"activityCenterNotifications": activityCenterNotifications,
"error": error
}
arg.finish(responseJson)

View File

@ -21,6 +21,7 @@ import ./dto/urls_unfurling_plan
import ./dto/link_preview
import ./message_cursor
import ../../common/activity_center
import ../../common/message as message_common
import ../../common/conversion as service_conversion
@ -722,6 +723,8 @@ QtObject:
let data = MessagesMarkedAsReadArgs(chatId: chatId, allMessagesMarked: true)
self.events.emit(SIGNAL_MESSAGES_MARKED_AS_READ, data)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: responseObj{"activityCenterNotifications"}))
proc markAllMessagesRead*(self: Service, chatId: string) =
if (chatId.len == 0):
@ -771,6 +774,8 @@ QtObject:
messagesCount: count,
messagesWithMentionsCount: countWithMentions)
self.events.emit(SIGNAL_MESSAGES_MARKED_AS_READ, data)
self.events.emit(SIGNAL_PARSE_RAW_ACTIVITY_CENTER_NOTIFICATIONS,
RawActivityCenterNotificationsArgs(activityCenterNotifications: responseObj{"activityCenterNotifications"}))
proc markCertainMessagesRead*(self: Service, chatId: string, messagesIds: seq[string]) =
if (chatId.len == 0):

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit b7acde0910e78b2ce063a6437c2f043d8a10b441
Subproject commit 31d0782f6678c275a9009139c819bfda51482e21