refactor(community): make community data calls async

Fixes #9825
This commit is contained in:
Jonathan Rainville 2023-03-09 16:13:09 -05:00
parent fee9b31a88
commit 964aa7ebc9
9 changed files with 161 additions and 65 deletions

View File

@ -37,6 +37,9 @@ proc delete*(self: Controller) =
discard
proc init*(self: Controller) =
self.events.on(SIGNAL_COMMUNITY_DATA_LOADED) do(e:Args):
self.delegate.communityDataLoaded()
self.events.on(SIGNAL_COMMUNITY_CREATED) do(e:Args):
let args = CommunityArgs(e)
self.delegate.communityAdded(args.community)

View File

@ -17,6 +17,9 @@ method isLoaded*(self: AccessInterface): bool {.base.} =
method onActivated*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method communityDataLoaded*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method setCommunityTags*(self: AccessInterface, communityTags: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -91,11 +91,12 @@ method isLoaded*(self: Module): bool =
method viewDidLoad*(self: Module) =
self.moduleLoaded = true
self.delegate.communitiesModuleDidLoad()
method communityDataLoaded*(self: Module) =
self.setCommunityTags(self.controller.getCommunityTags())
self.setAllCommunities(self.controller.getAllCommunities())
self.delegate.communitiesModuleDidLoad()
method onActivated*(self: Module) =
if self.curatedCommunitiesLoaded:
return

View File

@ -120,6 +120,22 @@ proc init*(self: Controller) =
self.communityTokensService
)
self.events.on(SIGNAL_COMMUNITY_DATA_LOADED) do(e:Args):
self.delegate.onCommunityDataLoaded(
self.events,
self.settingsService,
self.nodeConfigurationService,
self.contactsService,
self.chatService,
self.communityService,
self.messageService,
self.gifService,
self.mailserversService,
self.walletAccountService,
self.tokenService,
self.communityTokensService
)
self.events.on(SIGNAL_CHATS_LOADING_FAILED) do(e:Args):
self.delegate.onChatsLoadingFailed()

View File

@ -90,6 +90,23 @@ method onChatsLoaded*(
{.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityDataLoaded*(
self: AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service)
{.base.} =
raise newException(ValueError, "No implementation available")
method onChatsLoadingFailed*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -99,6 +99,8 @@ type
keycardSharedModule: keycard_shared_module.AccessInterface
keycardSharedModuleKeycardSyncPurpose: keycard_shared_module.AccessInterface
moduleLoaded: bool
chatsLoaded: bool
communityDataLoaded: bool
statusUrlCommunityToSpectate: string
# Forward declaration
@ -165,6 +167,8 @@ proc newModule*[T](
networkService
)
result.moduleLoaded = false
result.chatsLoaded = false
result.communityDataLoaded = false
result.events = events
result.urlsManager = urlsManager
@ -534,6 +538,9 @@ method onChatsLoaded*[T](
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service
) =
self.chatsLoaded = true
if not self.communityDataLoaded:
return
var activeSection: SectionItem
var activeSectionId = singletonInstance.localAccountSensitiveSettings.getActiveSection()
if activeSectionId == "":
@ -574,6 +581,41 @@ method onChatsLoaded*[T](
self.view.chatsLoaded()
method onCommunityDataLoaded*[T](
self: Module[T],
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service
) =
self.communityDataLoaded = true
if not self.chatsLoaded:
return
self.onChatsLoaded(
self.controller.getChannelGroups(),
events,
settingsService,
nodeConfigurationService,
contactsService,
chatService,
communityService,
messageService,
gifService,
mailserversService,
walletAccountService,
tokenService,
communityTokensService
)
method onChatsLoadingFailed*[T](self: Module[T]) =
self.view.chatsLoadingFailed()

View File

@ -1,6 +1,32 @@
include ../../common/json_utils
include ../../../app/core/tasks/common
type
AsyncLoadCommunitiesDataTaskArg = ref object of QObjectTaskArg
const asyncLoadCommunitiesDataTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncLoadCommunitiesDataTaskArg](argEncoded)
try:
let responseTags = status_go.getCommunityTags()
let responseCommunities = status_go.getAllCommunities()
let responseSettings = status_go.getCommunitiesSettings()
let responseMyPendingRequestsToJoin = status_go.myPendingRequestsToJoin()
arg.finish(%* {
"tags": responseTags,
"communities": responseCommunities,
"settings": responseSettings,
"myPendingRequestsToJoin": responseMyPendingRequestsToJoin,
"error": "",
})
except Exception as e:
arg.finish(%* {
"error": e.msg,
})
type
AsyncRequestCommunityInfoTaskArg = ref object of QObjectTaskArg
communityId: string

View File

@ -331,8 +331,8 @@ proc toCommunitySettingsDto*(jsonObj: JsonNode): CommunitySettingsDto =
discard jsonObj.getProp("communityId", result.id)
discard jsonObj.getProp("historyArchiveSupportEnabled", result.historyArchiveSupportEnabled)
proc parseCommunities*(response: RpcResponse[JsonNode]): seq[CommunityDto] =
result = map(response.result.getElems(),
proc parseCommunities*(response: JsonNode): seq[CommunityDto] =
result = map(response["result"].getElems(),
proc(x: JsonNode): CommunityDto = x.toCommunityDto())
proc parseKnownCuratedCommunities(jsonCommunities: JsonNode): seq[CommunityDto] =
@ -391,8 +391,8 @@ proc toChannelGroupDto*(communityDto: CommunityDto): ChannelGroupDto =
encrypted: communityDto.encrypted,
)
proc parseCommunitiesSettings*(response: RpcResponse[JsonNode]): seq[CommunitySettingsDto] =
result = map(response.result.getElems(),
proc parseCommunitiesSettings*(response: JsonNode): seq[CommunitySettingsDto] =
result = map(response["result"].getElems(),
proc(x: JsonNode): CommunitySettingsDto = x.toCommunitySettingsDto())
proc parseDiscordCategories*(response: RpcResponse[JsonNode]): seq[DiscordCategoryDto] =

View File

@ -110,6 +110,7 @@ type
currentChunk*: int
# Signals which may be emitted by this service:
const SIGNAL_COMMUNITY_DATA_LOADED* = "communityDataLoaded"
const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
const SIGNAL_COMMUNITY_SPECTATED* = "communitySpectated"
const SIGNAL_COMMUNITY_MY_REQUEST_ADDED* = "communityMyRequestAdded"
@ -177,11 +178,7 @@ QtObject:
# Forward declaration
proc loadCommunityTags(self: Service): string
proc loadAllCommunities(self: Service): seq[CommunityDto]
proc asyncLoadCuratedCommunities*(self: Service)
proc loadCommunitiesSettings(self: Service): seq[CommunitySettingsDto]
proc loadMyPendingRequestsToJoin*(self: Service)
proc loadMyCanceledRequestsToJoin*(self: Service)
proc handleCommunityUpdates(self: Service, communities: seq[CommunityDto], updatedChats: seq[ChatDto], removedChats: seq[string])
proc handleCommunitiesSettingsUpdates(self: Service, communitiesSettings: seq[CommunitySettingsDto])
proc pendingRequestsToJoinForCommunity*(self: Service, communityId: string): seq[CommunityMembershipRequestDto]
@ -585,22 +582,55 @@ QtObject:
proc init*(self: Service) =
self.doConnect()
self.communityTags = self.loadCommunityTags();
let communities = self.loadAllCommunities()
for community in communities:
self.communities[community.id] = community
if (community.admin):
self.communities[community.id].pendingRequestsToJoin = self.pendingRequestsToJoinForCommunity(community.id)
self.communities[community.id].declinedRequestsToJoin = self.declinedRequestsToJoinForCommunity(community.id)
self.communities[community.id].canceledRequestsToJoin = self.canceledRequestsToJoinForCommunity(community.id)
try:
let arg = AsyncLoadCommunitiesDataTaskArg(
tptr: cast[ByteAddress](asyncLoadCommunitiesDataTask),
vptr: cast[ByteAddress](self.vptr),
slot: "asyncCommunitiesDataLoaded",
)
self.threadpool.start(arg)
except Exception as e:
error "Error requesting communities data", msg = e.msg
let communitiesSettings = self.loadCommunitiesSettings()
for settings in communitiesSettings:
if self.communities.hasKey(settings.id):
self.communities[settings.id].settings = settings
proc asyncCommunitiesDataLoaded(self: Service, response: string) {.slot.} =
try:
let responseObj = response.parseJson
if (responseObj{"error"}.kind != JNull and responseObj{"error"}.getStr != ""):
error "error loading communities data", msg = responseObj{"error"}.getStr
return
self.loadMyPendingRequestsToJoin()
# Tags
var resultTags = newString(0)
toUgly(resultTags, responseObj["tags"]["result"])
self.communityTags = resultTags
# All communities
let communities = parseCommunities(responseObj["communities"])
for community in communities:
self.communities[community.id] = community
if (community.admin):
self.communities[community.id].pendingRequestsToJoin = self.pendingRequestsToJoinForCommunity(community.id)
self.communities[community.id].declinedRequestsToJoin = self.declinedRequestsToJoinForCommunity(community.id)
self.communities[community.id].canceledRequestsToJoin = self.canceledRequestsToJoinForCommunity(community.id)
# Communities settings
let communitiesSettings = parseCommunitiesSettings(responseObj["settings"])
for settings in communitiesSettings:
if self.communities.hasKey(settings.id):
self.communities[settings.id].settings = settings
# My pending requests
let myPendingRequestResponse = responseObj["myPendingRequestsToJoin"]
if myPendingRequestResponse{"result"}.kind != JNull:
for jsonCommunityReqest in myPendingRequestResponse["result"]:
let communityRequest = jsonCommunityReqest.toCommunityMembershipRequestDto()
self.myCommunityRequests.add(communityRequest)
self.events.emit(SIGNAL_COMMUNITY_DATA_LOADED, Args())
except Exception as e:
let errDesription = e.msg
error "error loading all communities: ", errDesription
proc loadCommunityTags(self: Service): string =
let response = status_go.getCommunityTags()
@ -608,24 +638,6 @@ QtObject:
toUgly(result, response.result)
return result
proc loadAllCommunities(self: Service): seq[CommunityDto] =
try:
let response = status_go.getAllCommunities()
return parseCommunities(response)
except Exception as e:
let errDesription = e.msg
error "error loading all communities: ", errDesription
return @[]
proc loadCommunitiesSettings(self: Service): seq[CommunitySettingsDto] =
try:
let response = status_go.getCommunitiesSettings()
return parseCommunitiesSettings(response)
except Exception as e:
let errDesription = e.msg
error "error loading communities settings: ", errDesription
return
proc getCommunityTags*(self: Service): string =
return self.communityTags
@ -804,30 +816,6 @@ QtObject:
except Exception as e:
error "Error requesting to join the community", msg = e.msg, communityId, ensName
proc loadMyPendingRequestsToJoin*(self: Service) =
try:
let response = status_go.myPendingRequestsToJoin()
if response.result.kind != JNull:
for jsonCommunityReqest in response.result:
let communityRequest = jsonCommunityReqest.toCommunityMembershipRequestDto()
self.myCommunityRequests.add(communityRequest)
self.events.emit(SIGNAL_COMMUNITY_MY_REQUEST_ADDED, CommunityRequestArgs(communityRequest: communityRequest))
except Exception as e:
error "Error fetching my community requests", msg = e.msg
proc loadMyCanceledRequestsToJoin*(self: Service) =
try:
let response = status_go.myCanceledRequestsToJoin()
if response.result.kind != JNull:
for jsonCommunityReqest in response.result:
let communityRequest = jsonCommunityReqest.toCommunityMembershipRequestDto()
self.myCommunityRequests.add(communityRequest)
self.events.emit(SIGNAL_COMMUNITY_MY_REQUEST_ADDED, CommunityRequestArgs(communityRequest: communityRequest))
except Exception as e:
error "Error fetching my community requests", msg = e.msg
proc canceledRequestsToJoinForCommunity*(self: Service, communityId: string): seq[CommunityMembershipRequestDto] =
try:
let response = status_go.canceledRequestsToJoinForCommunity(communityId)