fix(categories): make categories collapsing async to fix performance (#16271)

Fixes #16270

Makes the category collapsing and opening async, so UI feedback is immediate, while the actual save in the DB is done async in the background.
This commit is contained in:
Jonathan Rainville 2024-09-12 11:55:16 -04:00 committed by GitHub
parent c5598d9ff9
commit 1a3b75fc9d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 57 additions and 44 deletions

View File

@ -173,12 +173,6 @@ proc init*(self: Controller) =
self.mailserversService, self.sharedUrlsService, setChatAsActive = true)
if (self.isCommunitySection):
self.events.on(SIGNAL_COMMUNITY_CATEGORY_COLLAPSED_TOGGLED) do(e: Args):
let args = CommunityCategoryCollapsedArgs(e)
if (args.communityId == self.sectionId):
self.delegate.onToggleCollapsedCommunityCategory(args.categoryId, args.collapsed)
self.events.on(SIGNAL_COMMUNITY_CHANNEL_CREATED) do(e:Args):
let args = CommunityChatArgs(e)
let belongsToCommunity = args.chat.communityId.len > 0
@ -699,8 +693,8 @@ proc shareCommunityToUsers*(self: Controller, pubKeys: string, inviteMessage: st
proc reorderCommunityCategories*(self: Controller, categoryId: string, position: int) =
self.communityService.reorderCommunityCategories(self.sectionId, categoryId, position)
proc toggleCollapsedCommunityCategory*(self: Controller, categoryId: string, collapsed: bool) =
self.communityService.toggleCollapsedCommunityCategory(self.sectionId, categoryId, collapsed)
proc toggleCollapsedCommunityCategoryAsync*(self: Controller, categoryId: string, collapsed: bool) =
self.communityService.toggleCollapsedCommunityCategoryAsync(self.sectionId, categoryId, collapsed)
proc reorderCommunityChat*(self: Controller, categoryId: string, chatId: string, position: int) =
self.communityService.reorderCommunityChat(self.sectionId, categoryId, chatId, position)

View File

@ -318,10 +318,7 @@ method prepareEditCategoryModel*(self: AccessInterface, categoryId: string) {.ba
method reorderCommunityCategories*(self: AccessInterface, categoryId: string, position: int) {.base.} =
raise newException(ValueError, "No implementation available")
method toggleCollapsedCommunityCategory*(self: AccessInterface, categoryId: string, collapsed: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method onToggleCollapsedCommunityCategory*(self: AccessInterface, categoryId: string, collapsed: bool) {.base.} =
method toggleCollapsedCommunityCategoryAsync*(self: AccessInterface, categoryId: string, collapsed: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method reorderCommunityChat*(self: AccessInterface, categoryId: string, chatId: string, position: int) {.base.} =

View File

@ -1427,11 +1427,8 @@ method reorderCommunityCategories*(self: Module, categoryId: string, categoryPos
self.controller.reorderCommunityCategories(categoryId, finalPosition)
method toggleCollapsedCommunityCategory*(self: Module, categoryId: string, collapsed: bool) =
self.controller.toggleCollapsedCommunityCategory(categoryId, collapsed)
method onToggleCollapsedCommunityCategory*(self: Module, categoryId: string, collapsed: bool) =
self.view.chatsModel().changeCategoryOpened(categoryId, not collapsed)
method toggleCollapsedCommunityCategoryAsync*(self: Module, categoryId: string, collapsed: bool) =
self.controller.toggleCollapsedCommunityCategoryAsync(categoryId, collapsed)
method reorderCommunityChat*(self: Module, categoryId: string, chatId: string, toPosition: int) =
self.controller.reorderCommunityChat(categoryId, chatId, toPosition + 1)

View File

@ -357,7 +357,8 @@ QtObject:
self.delegate.reorderCommunityCategories(categoryId, categoryPosition)
proc toggleCollapsedCommunityCategory*(self: View, categoryId: string, collapsed: bool) {.slot} =
self.delegate.toggleCollapsedCommunityCategory(categoryId, collapsed)
self.model.changeCategoryOpened(categoryId, not collapsed)
self.delegate.toggleCollapsedCommunityCategoryAsync(categoryId, collapsed)
proc reorderCommunityChat*(self: View, categoryId: string, chatId: string, position: int) {.slot} =
self.delegate.reorderCommunityChat(categoryId, chatId, position)

View File

@ -119,9 +119,6 @@ method communityImported*(self: AccessInterface, community: CommunityDto) {.base
method communityDataImported*(self: AccessInterface, community: CommunityDto) {.base.} =
raise newException(ValueError, "No implementation available")
method toggleCollapsedCommunityCategory*(self: AccessInterface, communityId:string, categoryId: string, collapsed: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method communityInfoRequestFailed*(self: AccessInterface, communityId: string, errorMsg: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -282,7 +282,6 @@ proc asyncReevaluateCommunityMembersPermissionsTask(argEncoded: string) {.gcsafe
"error": e.msg,
})
type
AsyncSetCommunityShardArg = ref object of QObjectTaskArg
communityId: string
@ -302,3 +301,26 @@ proc asyncSetCommunityShardTask(argEncoded: string) {.gcsafe, nimcall.} =
"communityId": arg.communityId,
"error": e.msg,
})
type
AsyncCollapseCategory = ref object of QObjectTaskArg
communityId: string
categoryId: string
collapsed: bool
proc asyncCollapseCategoryTask(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncCollapseCategory](argEncoded)
try:
let response = status_go.toggleCollapsedCommunityCategory(
arg.communityId,
arg.categoryId,
arg.collapsed,
)
arg.finish(%* {
"response": response,
"error": "",
})
except Exception as e:
arg.finish(%* {
"error": e.msg,
})

View File

@ -199,7 +199,6 @@ const SIGNAL_COMMUNITY_CATEGORY_EDITED* = "communityCategoryEdited"
const SIGNAL_COMMUNITY_CATEGORY_NAME_EDITED* = "communityCategoryNameEdited"
const SIGNAL_COMMUNITY_CATEGORY_DELETED* = "communityCategoryDeleted"
const SIGNAL_COMMUNITY_CATEGORY_REORDERED* = "communityCategoryReordered"
const SIGNAL_COMMUNITY_CATEGORY_COLLAPSED_TOGGLED* = "communityCategoryCollapsedToggled"
const SIGNAL_COMMUNITY_CHANNEL_CATEGORY_CHANGED* = "communityChannelCategoryChanged"
const SIGNAL_COMMUNITY_MEMBER_APPROVED* = "communityMemberApproved"
const SIGNAL_COMMUNITY_MEMBER_STATUS_CHANGED* = "communityMemberStatusChanged"
@ -1479,19 +1478,28 @@ QtObject:
except Exception as e:
error "Error creating community category", msg = e.msg, communityId, name
proc toggleCollapsedCommunityCategory*(self: Service, communityId: string, categoryId: string, collapsed: bool) =
proc toggleCollapsedCommunityCategoryAsync*(self: Service, communityId: string, categoryId: string, collapsed: bool) =
let arg = AsyncCollapseCategory(
tptr: asyncCollapseCategoryTask,
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncCollapseCategoryDone",
communityId: communityId,
categoryId: categoryId,
collapsed: collapsed,
)
self.threadpool.start(arg)
proc onAsyncCollapseCategoryDone*(self: Service, rpcResponse: string) {.slot.} =
try:
let response = status_go.toggleCollapsedCommunityCategory(communityId, categoryId, collapsed)
if response.error != nil:
let error = Json.decode($response.error, RpcError)
raise newException(RpcException, "Error toggling collapsed community category: " & error.message)
self.events.emit(SIGNAL_COMMUNITY_CATEGORY_COLLAPSED_TOGGLED, CommunityCategoryCollapsedArgs(
communityId: communityId, categoryId: categoryId, collapsed: collapsed))
let rpcResponseObj = rpcResponse.parseJson
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
raise newException(CatchableError, rpcResponseObj["error"].getStr)
if rpcResponseObj["response"]{"error"}.kind != JNull:
let error = Json.decode(rpcResponseObj["response"]["error"].getStr, RpcError)
raise newException(RpcException, error.message)
except Exception as e:
error "Error toggling collapsed community category ", msg = e.msg, communityId, collapsed
error "Error toggling collapsed community category", msg = e.msg
proc editCommunityCategory*(
self: Service,
@ -2362,7 +2370,6 @@ QtObject:
error "error while reevaluating community members permissions", msg = e.msg
proc asyncSetCommunityShard*(self: Service, communityId: string, shardIndex: int) =
try:
let arg = AsyncSetCommunityShardArg(
tptr: asyncSetCommunityShardTask,
vptr: cast[ByteAddress](self.vptr),
@ -2371,8 +2378,6 @@ QtObject:
shardIndex: shardIndex,
)
self.threadpool.start(arg)
except Exception as e:
error "Error request to join community", msg = e.msg
proc onAsyncSetCommunityShardDone*(self: Service, communityIdAndRpcResponse: string) {.slot.} =
let rpcResponseObj = communityIdAndRpcResponse.parseJson