feat(communities): add category signal handling (add, delete and edit)

Fixes #4753
This commit is contained in:
Jonathan Rainville 2022-02-24 12:06:14 -05:00 committed by Iuri Matias
parent f7860310db
commit bd69d88163
7 changed files with 123 additions and 27 deletions

View File

@ -136,10 +136,20 @@ method init*(self: Controller) =
if (args.communityId == self.sectionId):
self.delegate.onCommunityCategoryEdited(args.category, args.chats)
self.events.on(SIGNAL_COMMUNITY_CATEGORY_REORDERED) do(e:Args):
let args = CommunityChatOrderArgs(e)
if (args.communityId == self.sectionId):
self.delegate.onReorderChatOrCategory(args.categoryId, args.position)
self.events.on(SIGNAL_COMMUNITY_CATEGORY_NAME_EDITED) do(e:Args):
let args = CommunityCategoryArgs(e)
if (args.communityId == self.sectionId):
self.delegate.onCategoryNameChanged(args.category)
self.events.on(SIGNAL_COMMUNITY_CHANNEL_REORDERED) do(e:Args):
let args = CommunityChatOrderArgs(e)
if (args.communityId == self.sectionId):
self.delegate.reorderChannels(args.chatId, args.categoryId, args.position)
self.delegate.onReorderChatOrCategory(args.chatId, args.position)
self.events.on(SIGNAL_CONTACT_NICKNAME_CHANGED) do(e: Args):
var args = ContactArgs(e)

View File

@ -304,8 +304,8 @@ QtObject:
result.notificationsCount = result.notificationsCount + self.items[i].BaseItem.notificationsCount
proc reorder*(self: Model, chatId, categoryId: string, position: int) =
let index = self.getItemIdxById(chatId)
proc reorder*(self: Model, chatOrCategoryId: string, position: int) =
let index = self.getItemIdxById(chatOrCategoryId)
if(index == -1):
return

View File

@ -421,7 +421,6 @@ method addNewChat*(
communityService, messageService, gifService, mailserversService)
self.chatContentModules[chatDto.id].load()
self.view.chatsModel().appendItem(item)
# make new added chat active one
if setChatAsActive:
self.setActiveItemSubItem(item.id, "")
else:
@ -437,9 +436,14 @@ method addNewChat*(
communityService, messageService, gifService, mailserversService)
self.chatContentModules[chatDto.id].load()
categoryItem.appendSubItem(channelItem)
self.setActiveItemSubItem(categoryItem.id, channelItem.id)
if setChatAsActive:
self.setActiveItemSubItem(categoryItem.id, channelItem.id)
method doesChatExist*(self: Module, chatId: string): bool =
method doesCatOrChatExist*(self: Module, id: string): bool =
return self.view.chatsModel().isItemWithIdAdded(id) or
not self.view.chatsModel().getSubItemById(id).isNil
method doesTopLevelChatExist*(self: Module, chatId: string): bool =
return self.view.chatsModel().isItemWithIdAdded(chatId)
method removeCommunityChat*(self: Module, chatId: string) =
@ -449,6 +453,8 @@ method removeCommunityChat*(self: Module, chatId: string) =
self.controller.removeCommunityChat(chatId)
method onCommunityCategoryCreated*(self: Module, cat: Category, chats: seq[ChatDto]) =
if (self.doesCatOrChatExist(cat.id)):
return
var categoryItem = initItem(cat.id, cat.name, "", false, "", "", ChatType.Unknown.int, false,
false, 0, muted=false, blocked=false, active=false, cat.position, cat.id)
var categoryChannels: seq[SubItem]
@ -460,7 +466,7 @@ method onCommunityCategoryCreated*(self: Module, cat: Category, chats: seq[ChatD
blocked=false, active=false, chatDto.position)
# Important:
# Since we're just adding an already added community channel to a certain commuinity, there is no need to call
# Since we're just adding an already added community channel to a certain community, there is no need to call
# `self.addSubmodule` here, since submodule (chat content module and modules beneath) were already added, so we're
# just updating the view from here, via model.
self.view.chatsModel().removeItemById(chatDto.id)
@ -472,6 +478,8 @@ method onCommunityCategoryCreated*(self: Module, cat: Category, chats: seq[ChatD
method onCommunityCategoryDeleted*(self: Module, cat: Category) =
let chats = self.controller.getChats(self.controller.getMySectionId(), cat.id)
for c in chats:
if (c.categoryId != cat.id or self.doesTopLevelChatExist(self.controller.getMySectionId() & c.id)):
continue
let chatDto = self.controller.getChatDetails(self.controller.getMySectionId(), c.id)
let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0
let notificationsCount = chatDto.unviewedMentionsCount
@ -483,6 +491,12 @@ method onCommunityCategoryDeleted*(self: Module, cat: Category) =
self.view.chatsModel().removeItemById(cat.id)
method onReorderChatOrCategory*(self: Module, chatOrCatId: string, position: int) =
self.view.chatsModel().reorder(chatOrCatId, position)
method onCategoryNameChanged*(self: Module, category: Category) =
self.view.chatsModel().renameItem(category.id, category.name)
method onCommunityCategoryEdited*(self: Module, cat: Category, chats: seq[ChatDto]) =
var categoryItem = self.view.chatsModel().getItemById(cat.id)
let amIChatAdmin = self.controller.getMyCommunity().admin
@ -664,9 +678,6 @@ method joinGroupChatFromInvitation*(self: Module, groupName: string, chatId: str
method onChatRenamed*(self: Module, chatId: string, newName: string) =
self.view.chatsModel().renameItem(chatId, newName)
method reorderChannels*(self: Module, chatId, categoryId: string, position: int) =
self.view.chatsModel().reorder(chatId, categoryId, position)
method acceptRequestToJoinCommunity*(self: Module, requestId: string) =
self.controller.acceptRequestToJoinCommunity(requestId)
@ -751,8 +762,8 @@ method addChatIfDontExist*(self: Module,
not belongsToCommunity and sectionId != conf.CHAT_SECTION_ID):
return
if self.doesChatExist(chat.id):
if self.doesCatOrChatExist(chat.id):
return
self.addNewChat(chat, belongsToCommunity, events, settingsService, contactService, chatService,
communityService, messageService, gifService, mailserversService, setChatAsActive)

View File

@ -11,7 +11,10 @@ method addNewChat*(self: AccessInterface, chatDto: ChatDto, belongsToCommunity:
mailserversService: mailservers_service.Service, setChatAsActive: bool = true) {.base.} =
raise newException(ValueError, "No implementation available")
method doesChatExist*(self: AccessInterface, chatId: string): bool {.base.} =
method doesCatOrChatExist*(self: AccessInterface, chatId: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method doesTopLevelChatExist*(self: AccessInterface, chatId: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method addChatIfDontExist*(self: AccessInterface,
@ -65,7 +68,7 @@ method onChatRenamed*(self: AccessInterface, chatId: string, newName: string) {.
method onCommunityChannelEdited*(self: AccessInterface, chat: ChatDto) {.base.} =
raise newException(ValueError, "No implementation available")
method reorderChannels*(self: AccessInterface, chatId, categoryId: string, position: int) {.base.} =
method onReorderChatOrCategory*(self: AccessInterface, chatOrCatId: string, position: int) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityCategoryCreated*(self: AccessInterface, category: Category, chats: seq[ChatDto]) {.base.} =
@ -77,5 +80,8 @@ method onCommunityCategoryDeleted*(self: AccessInterface, category: Category) {.
method onCommunityCategoryEdited*(self: AccessInterface, category: Category, chats: seq[ChatDto]) {.base.} =
raise newException(ValueError, "No implementation available")
method onCategoryNameChanged*(self: AccessInterface, category: Category) {.base.} =
raise newException(ValueError, "No implementation available")
method setLoadingHistoryMessagesInProgress*(self: AccessInterface, isLoading: bool) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -215,15 +215,25 @@ QtObject:
return true
return false
proc getItemIdxById*(self: SubModel, id: string): int =
var idx = 0
for it in self.items:
if(it.id == id):
return idx
idx.inc
return -1
proc removeItemById*(self: SubModel, id: string) =
for i in 0 ..< self.items.len:
if(self.items[i].id == id):
let parentModelIndex = newQModelIndex()
defer: parentModelIndex.delete
self.beginRemoveRows(parentModelIndex, i, i)
self.items.delete(i)
self.endRemoveRows()
self.countChanged()
let idx = self.getItemIdxById(id)
if idx == -1:
return
let parentModelIndex = newQModelIndex()
defer: parentModelIndex.delete
self.beginRemoveRows(parentModelIndex, idx, idx)
self.items.delete(idx)
self.endRemoveRows()
self.countChanged()
proc updateNotificationsForItemById*(self: SubModel, id: string, hasUnreadMessages: bool,
notificationsCount: int): bool =

View File

@ -100,6 +100,8 @@ proc toChatDto*(jsonObj: JsonNode): ChatDto =
discard jsonObj.getProp("alias", result.alias)
discard jsonObj.getProp("identicon", result.identicon)
discard jsonObj.getProp("muted", result.muted)
discard jsonObj.getProp("categoryId", result.categoryId)
discard jsonObj.getProp("position", result.position)
discard jsonObj.getProp("communityId", result.communityId)
discard jsonObj.getProp("profile", result.profile)
discard jsonObj.getProp("joined", result.joined)

View File

@ -77,7 +77,9 @@ const SIGNAL_COMMUNITY_CHANNEL_REORDERED* = "communityChannelReordered"
const SIGNAL_COMMUNITY_CHANNEL_DELETED* = "communityChannelDeleted"
const SIGNAL_COMMUNITY_CATEGORY_CREATED* = "communityCategoryCreated"
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_MEMBER_APPROVED* = "communityMemberApproved"
const SIGNAL_NEW_REQUEST_TO_JOIN_COMMUNITY* = "newRequestToJoinCommunity"
@ -174,6 +176,14 @@ QtObject:
return idx
return -1
proc findIndexById(id: string, categories: seq[Category]): int =
var idx = -1
for category in categories:
inc idx
if(category.id == id):
return idx
return -1
proc saveUpdatedJoinedCommunity(self: Service, community: var CommunityDto) =
# Community data we get from the signals and responses don't contgain the pending requests
# therefore, we must keep the old one
@ -182,6 +192,15 @@ QtObject:
# Update the joinded community list with the new data
self.joinedCommunities[community.id] = community
proc getChatsInCategory(self: Service, community: var CommunityDto, categoryId: string): seq[ChatDto] =
result = @[]
for chat in community.chats:
if (chat.categoryId == categoryId):
let fullChatId = community.id & chat.id
var chatDetails = self.chatService.getChatById(fullChatId)
chatDetails.updateMissingFields(chat)
result.add(chatDetails)
proc handleCommunityUpdates(self: Service, communities: seq[CommunityDto], updatedChats: seq[ChatDto]) =
var community = communities[0]
@ -195,7 +214,39 @@ QtObject:
let prev_community = self.joinedCommunities[community.id]
self.saveUpdatedJoinedCommunity(community)
# category was added
if(community.categories.len > prev_community.categories.len):
for category in community.categories:
if findIndexById(category.id, prev_community.categories) == -1:
let chats = self.getChatsInCategory(community, category.id)
self.events.emit(SIGNAL_COMMUNITY_CATEGORY_CREATED,
CommunityCategoryArgs(communityId: community.id, category: category, chats: chats))
# category was removed
elif(community.categories.len < prev_community.categories.len):
for prv_category in prev_community.categories:
if findIndexById(prv_category.id, community.categories) == -1:
self.events.emit(SIGNAL_COMMUNITY_CATEGORY_DELETED,
CommunityCategoryArgs(communityId: community.id, category: Category(id: prv_category.id)))
# some property has changed
else:
for category in community.categories:
# id is present
if findIndexById(category.id, prev_community.categories) == -1:
continue
# but something is different
for prev_category in prev_community.categories:
if(category.id == prev_category.id and category.position != prev_category.position):
self.events.emit(SIGNAL_COMMUNITY_CATEGORY_REORDERED,
CommunityChatOrderArgs(
communityId: community.id,
categoryId: category.id,
position: category.position))
if(category.id == prev_category.id and category.name != prev_category.name):
self.events.emit(SIGNAL_COMMUNITY_CATEGORY_NAME_EDITED,
CommunityCategoryArgs(communityId: community.id, category: category))
# channel was added
if(community.chats.len > prev_community.chats.len):
@ -223,10 +274,6 @@ QtObject:
continue
# but something is different
for prev_chat in prev_community.chats:
# Category changes not handled yet
#if(chat.id == prev_chat.id and chat.categoryId != prev_chat.categoryId):
# Handle position changes
if(chat.id == prev_chat.id and chat.position != prev_chat.position):
self.events.emit(SIGNAL_COMMUNITY_CHANNEL_REORDERED, CommunityChatOrderArgs(communityId: community.id,
@ -242,6 +289,7 @@ QtObject:
let data = CommunityChatArgs(chat: updatedChat)
self.events.emit(SIGNAL_COMMUNITY_CHANNEL_EDITED, data)
self.saveUpdatedJoinedCommunity(community)
self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[community]))
proc init*(self: Service) =
@ -542,6 +590,15 @@ QtObject:
if response.result.isNil or response.result.kind == JNull:
error "response is invalid", methodName="createCommunityChannel"
var chatsJArr: JsonNode
if(not response.result.getProp("chats", chatsJArr)):
raise newException(RpcException, fmt"createCommunityChannel; there is no `chats` key in the response for community id: {communityId}")
for chatObj in chatsJArr:
var chatDto = chatObj.toChatDto()
self.chatService.updateOrAddChat(chatDto)
let data = CommunityChatArgs(chat: chatDto)
self.events.emit(SIGNAL_COMMUNITY_CHANNEL_CREATED, data)
except Exception as e:
error "Error creating community channel", msg = e.msg, communityId, name, description, methodName="createCommunityChannel"