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) self.mailserversService, self.sharedUrlsService, setChatAsActive = true)
if (self.isCommunitySection): 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): self.events.on(SIGNAL_COMMUNITY_CHANNEL_CREATED) do(e:Args):
let args = CommunityChatArgs(e) let args = CommunityChatArgs(e)
let belongsToCommunity = args.chat.communityId.len > 0 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) = proc reorderCommunityCategories*(self: Controller, categoryId: string, position: int) =
self.communityService.reorderCommunityCategories(self.sectionId, categoryId, position) self.communityService.reorderCommunityCategories(self.sectionId, categoryId, position)
proc toggleCollapsedCommunityCategory*(self: Controller, categoryId: string, collapsed: bool) = proc toggleCollapsedCommunityCategoryAsync*(self: Controller, categoryId: string, collapsed: bool) =
self.communityService.toggleCollapsedCommunityCategory(self.sectionId, categoryId, collapsed) self.communityService.toggleCollapsedCommunityCategoryAsync(self.sectionId, categoryId, collapsed)
proc reorderCommunityChat*(self: Controller, categoryId: string, chatId: string, position: int) = proc reorderCommunityChat*(self: Controller, categoryId: string, chatId: string, position: int) =
self.communityService.reorderCommunityChat(self.sectionId, categoryId, chatId, position) 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.} = method reorderCommunityCategories*(self: AccessInterface, categoryId: string, position: int) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method toggleCollapsedCommunityCategory*(self: AccessInterface, categoryId: string, collapsed: bool) {.base.} = method toggleCollapsedCommunityCategoryAsync*(self: AccessInterface, categoryId: string, collapsed: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method onToggleCollapsedCommunityCategory*(self: AccessInterface, categoryId: string, collapsed: bool) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method reorderCommunityChat*(self: AccessInterface, categoryId: string, chatId: string, position: int) {.base.} = 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) self.controller.reorderCommunityCategories(categoryId, finalPosition)
method toggleCollapsedCommunityCategory*(self: Module, categoryId: string, collapsed: bool) = method toggleCollapsedCommunityCategoryAsync*(self: Module, categoryId: string, collapsed: bool) =
self.controller.toggleCollapsedCommunityCategory(categoryId, collapsed) self.controller.toggleCollapsedCommunityCategoryAsync(categoryId, collapsed)
method onToggleCollapsedCommunityCategory*(self: Module, categoryId: string, collapsed: bool) =
self.view.chatsModel().changeCategoryOpened(categoryId, not collapsed)
method reorderCommunityChat*(self: Module, categoryId: string, chatId: string, toPosition: int) = method reorderCommunityChat*(self: Module, categoryId: string, chatId: string, toPosition: int) =
self.controller.reorderCommunityChat(categoryId, chatId, toPosition + 1) self.controller.reorderCommunityChat(categoryId, chatId, toPosition + 1)

View File

@ -357,7 +357,8 @@ QtObject:
self.delegate.reorderCommunityCategories(categoryId, categoryPosition) self.delegate.reorderCommunityCategories(categoryId, categoryPosition)
proc toggleCollapsedCommunityCategory*(self: View, categoryId: string, collapsed: bool) {.slot} = 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} = proc reorderCommunityChat*(self: View, categoryId: string, chatId: string, position: int) {.slot} =
self.delegate.reorderCommunityChat(categoryId, chatId, position) 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.} = method communityDataImported*(self: AccessInterface, community: CommunityDto) {.base.} =
raise newException(ValueError, "No implementation available") 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.} = method communityInfoRequestFailed*(self: AccessInterface, communityId: string, errorMsg: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -282,7 +282,6 @@ proc asyncReevaluateCommunityMembersPermissionsTask(argEncoded: string) {.gcsafe
"error": e.msg, "error": e.msg,
}) })
type type
AsyncSetCommunityShardArg = ref object of QObjectTaskArg AsyncSetCommunityShardArg = ref object of QObjectTaskArg
communityId: string communityId: string
@ -302,3 +301,26 @@ proc asyncSetCommunityShardTask(argEncoded: string) {.gcsafe, nimcall.} =
"communityId": arg.communityId, "communityId": arg.communityId,
"error": e.msg, "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_NAME_EDITED* = "communityCategoryNameEdited"
const SIGNAL_COMMUNITY_CATEGORY_DELETED* = "communityCategoryDeleted" const SIGNAL_COMMUNITY_CATEGORY_DELETED* = "communityCategoryDeleted"
const SIGNAL_COMMUNITY_CATEGORY_REORDERED* = "communityCategoryReordered" const SIGNAL_COMMUNITY_CATEGORY_REORDERED* = "communityCategoryReordered"
const SIGNAL_COMMUNITY_CATEGORY_COLLAPSED_TOGGLED* = "communityCategoryCollapsedToggled"
const SIGNAL_COMMUNITY_CHANNEL_CATEGORY_CHANGED* = "communityChannelCategoryChanged" const SIGNAL_COMMUNITY_CHANNEL_CATEGORY_CHANGED* = "communityChannelCategoryChanged"
const SIGNAL_COMMUNITY_MEMBER_APPROVED* = "communityMemberApproved" const SIGNAL_COMMUNITY_MEMBER_APPROVED* = "communityMemberApproved"
const SIGNAL_COMMUNITY_MEMBER_STATUS_CHANGED* = "communityMemberStatusChanged" const SIGNAL_COMMUNITY_MEMBER_STATUS_CHANGED* = "communityMemberStatusChanged"
@ -1479,19 +1478,28 @@ QtObject:
except Exception as e: except Exception as e:
error "Error creating community category", msg = e.msg, communityId, name 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: try:
let response = status_go.toggleCollapsedCommunityCategory(communityId, categoryId, collapsed) let rpcResponseObj = rpcResponse.parseJson
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
if response.error != nil: raise newException(CatchableError, rpcResponseObj["error"].getStr)
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))
if rpcResponseObj["response"]{"error"}.kind != JNull:
let error = Json.decode(rpcResponseObj["response"]["error"].getStr, RpcError)
raise newException(RpcException, error.message)
except Exception as e: 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*( proc editCommunityCategory*(
self: Service, self: Service,
@ -2362,17 +2370,14 @@ QtObject:
error "error while reevaluating community members permissions", msg = e.msg error "error while reevaluating community members permissions", msg = e.msg
proc asyncSetCommunityShard*(self: Service, communityId: string, shardIndex: int) = proc asyncSetCommunityShard*(self: Service, communityId: string, shardIndex: int) =
try: let arg = AsyncSetCommunityShardArg(
let arg = AsyncSetCommunityShardArg( tptr: asyncSetCommunityShardTask,
tptr: asyncSetCommunityShardTask, vptr: cast[ByteAddress](self.vptr),
vptr: cast[ByteAddress](self.vptr), slot: "onAsyncSetCommunityShardDone",
slot: "onAsyncSetCommunityShardDone", communityId: communityId,
communityId: communityId, shardIndex: shardIndex,
shardIndex: shardIndex, )
) self.threadpool.start(arg)
self.threadpool.start(arg)
except Exception as e:
error "Error request to join community", msg = e.msg
proc onAsyncSetCommunityShardDone*(self: Service, communityIdAndRpcResponse: string) {.slot.} = proc onAsyncSetCommunityShardDone*(self: Service, communityIdAndRpcResponse: string) {.slot.} =
let rpcResponseObj = communityIdAndRpcResponse.parseJson let rpcResponseObj = communityIdAndRpcResponse.parseJson