diff --git a/src/app/modules/main/chat_section/controller.nim b/src/app/modules/main/chat_section/controller.nim index 5c9dcc209b..6e2554936d 100644 --- a/src/app/modules/main/chat_section/controller.nim +++ b/src/app/modules/main/chat_section/controller.nim @@ -129,6 +129,11 @@ method init*(self: Controller) = let args = CommunityCategoryArgs(e) if (args.communityId == self.sectionId): self.delegate.onCommunityCategoryDeleted(args.category) + + self.events.on(SIGNAL_COMMUNITY_CATEGORY_EDITED) do(e:Args): + let args = CommunityCategoryArgs(e) + if (args.communityId == self.sectionId): + self.delegate.onCommunityCategoryEdited(args.category, args.chats) self.events.on(SIGNAL_COMMUNITY_CHANNEL_REORDERED) do(e:Args): let args = CommunityChatOrderArgs(e) @@ -311,6 +316,9 @@ method editCommunityChannel*( method createCommunityCategory*(self: Controller, name: string, channels: seq[string]) = self.communityService.createCommunityCategory(self.sectionId, name, channels) +method editCommunityCategory*(self: Controller, categoryId: string, name: string, channels: seq[string]) = + self.communityService.editCommunityCategory(self.sectionId, categoryId, name, channels) + method deleteCommunityCategory*(self: Controller, categoryId: string) = self.communityService.deleteCommunityCategory(self.sectionId, categoryId) diff --git a/src/app/modules/main/chat_section/controller_interface.nim b/src/app/modules/main/chat_section/controller_interface.nim index 0e21f580a0..d859d4d9f6 100644 --- a/src/app/modules/main/chat_section/controller_interface.nim +++ b/src/app/modules/main/chat_section/controller_interface.nim @@ -131,6 +131,9 @@ method editCommunityChannel*(self: AccessInterface, channelId: string, name: str method createCommunityCategory*(self: AccessInterface, name: string, channels: seq[string]) {.base.} = raise newException(ValueError, "No implementation available") +method editCommunityCategory*(self: AccessInterface, categoryId: string, name: string, channels: seq[string]) {.base.} = + raise newException(ValueError, "No implementation available") + method deleteCommunityCategory*(self: AccessInterface, categoryId: string) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/chat_section/model.nim b/src/app/modules/main/chat_section/model.nim index 0f7a6b4449..77d3e1662a 100644 --- a/src/app/modules/main/chat_section/model.nim +++ b/src/app/modules/main/chat_section/model.nim @@ -20,6 +20,7 @@ type Position SubItems IsCategory + CategoryId QtObject: type @@ -80,7 +81,8 @@ QtObject: ModelRole.Active.int:"active", ModelRole.Position.int:"position", ModelRole.SubItems.int:"subItems", - ModelRole.IsCategory.int:"isCategory" + ModelRole.IsCategory.int:"isCategory", + ModelRole.CategoryId.int:"categoryId" }.toTable method data(self: Model, index: QModelIndex, role: int): QVariant = @@ -126,6 +128,8 @@ QtObject: result = newQVariant(item.subItems) of ModelRole.IsCategory: result = newQVariant(item.`type` == ChatType.Unknown.int) + of ModelRole.CategoryId: + result = newQVariant(item.categoryId) proc appendItem*(self: Model, item: Item) = let parentModelIndex = newQModelIndex() @@ -302,3 +306,7 @@ QtObject: self.items[index] = tempItem self.endResetModel() + proc clearItems*(self: Model) = + self.beginResetModel() + self.items = @[] + self.endResetModel() diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index 5c6e7e4641..29179939b7 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -450,10 +450,34 @@ method onCommunityCategoryDeleted*(self: Module, cat: Category) = let amIChatAdmin = self.controller.getMyCommunity().admin let channelItem = initItem(chatDto.id, chatDto.name, chatDto.identicon, false, chatDto.color, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, notificationsCount, - chatDto.muted, active = false, chatDto.position, "") + chatDto.muted, false, active = false, chatDto.position, "") self.view.chatsModel().appendItem(channelItem) self.view.chatsModel().removeItemById(cat.id) + +method onCommunityCategoryEdited*(self: Module, cat: Category, chats: seq[ChatDto]) = + var categoryItem = self.view.chatsModel().getItemById(cat.id) + let amIChatAdmin = self.controller.getMyCommunity().admin + + self.view.chatsModel.renameItem(cat.id, cat.name) + + for chatDto in chats: + let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0 + let notificationsCount = chatDto.unviewedMentionsCount + + self.view.chatsModel().removeItemById(chatDto.id) + categoryItem.subItems().removeItemById(chatDto.id) + + if chatDto.categoryId == cat.id: + let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.identicon, false, chatDto.color, + chatDto.description, chatDto.chatType.int, true, hasNotification, notificationsCount, chatDto.muted, + false, false, chatDto.position) + categoryItem.prependSubItem(channelItem) + else: + let channelItem = initItem(chatDto.id, chatDto.name, chatDto.identicon, false, chatDto.color, + chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, notificationsCount, + chatDto.muted, false, active = false, chatDto.position, "") + self.view.chatsModel().appendItem(channelItem) method onCommunityChannelDeletedOrChatLeft*(self: Module, chatId: string) = if(not self.chatContentModules.contains(chatId)): @@ -613,6 +637,9 @@ method editCommunityChannel*(self: Module, channelId, name, description, categor method createCommunityCategory*(self: Module, name: string, channels: seq[string]) = self.controller.createCommunityCategory(name, channels) +method editCommunityCategory*(self: Module, categoryId: string, name: string, channels: seq[string]) = + self.controller.editCommunityCategory(categoryId, name, channels) + method deleteCommunityCategory*(self: Module, categoryId: string) = self.controller.deleteCommunityCategory(categoryId) @@ -632,4 +659,20 @@ method setCommunityMuted*(self: Module, muted: bool) = self.controller.setCommunityMuted(muted) method inviteUsersToCommunity*(self: Module, pubKeysJSON: string): string = - result = self.controller.inviteUsersToCommunity(pubKeysJSON) \ No newline at end of file + result = self.controller.inviteUsersToCommunity(pubKeysJSON) + +method prepareEditCategoryModel*(self: Module, categoryId: string) = + self.view.editCategoryChannelsModel().clearItems() + let communityId = self.controller.getMySectionId() + let chats = self.controller.getChats(communityId, "") + for chat in chats: + let c = self.controller.getChatDetails(communityId, chat.id) + let item = initItem(c.id, c.name, "", false, c.color, c.description, c.chatType.int, false, + false, 0, c.muted, false, active = false, c.position, "") + self.view.editCategoryChannelsModel().appendItem(item) + let catChats = self.controller.getChats(communityId, categoryId) + for chat in catChats: + let c = self.controller.getChatDetails(communityId, chat.id) + let item = initItem(c.id, c.name, "", false, c.color, c.description, c.chatType.int, false, + false, 0, c.muted, false, active = false, c.position, categoryId) + self.view.editCategoryChannelsModel().appendItem(item) \ No newline at end of file diff --git a/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim b/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim index ca4b0d7004..efc373f8b2 100644 --- a/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim +++ b/src/app/modules/main/chat_section/private_interfaces/module_controller_delegate_interface.nim @@ -56,3 +56,6 @@ method onCommunityCategoryCreated*(self: AccessInterface, category: Category, ch method onCommunityCategoryDeleted*(self: AccessInterface, category: Category) {.base.} = raise newException(ValueError, "No implementation available") + +method onCommunityCategoryEdited*(self: AccessInterface, category: Category, chats: seq[ChatDto]) {.base.} = + raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/chat_section/private_interfaces/module_view_delegate_interface.nim b/src/app/modules/main/chat_section/private_interfaces/module_view_delegate_interface.nim index 08bec5a951..62be8bf8e9 100644 --- a/src/app/modules/main/chat_section/private_interfaces/module_view_delegate_interface.nim +++ b/src/app/modules/main/chat_section/private_interfaces/module_view_delegate_interface.nim @@ -115,5 +115,11 @@ method inviteUsersToCommunity*(self: AccessInterface, pubKeysJSON: string): stri method createCommunityCategory*(self: AccessInterface, name: string, channels: seq[string]) {.base.} = raise newException(ValueError, "No implementation available") +method editCommunityCategory*(self: AccessInterface, categoryId: string, name: string, channels: seq[string]) {.base.} = + raise newException(ValueError, "No implementation available") + method deleteCommunityCategory*(self: AccessInterface, categoryId: string) {.base.} = raise newException(ValueError, "No implementation available") + +method prepareEditCategoryModel*(self: AccessInterface, categoryId: string) {.base.} = + raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/chat_section/sub_model.nim b/src/app/modules/main/chat_section/sub_model.nim index 751996c9ca..ba38854644 100644 --- a/src/app/modules/main/chat_section/sub_model.nim +++ b/src/app/modules/main/chat_section/sub_model.nim @@ -212,6 +212,16 @@ QtObject: return true return false + 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() + proc updateNotificationsForItemById*(self: SubModel, id: string, hasUnreadMessages: bool, notificationsCount: int): bool = for i in 0 ..< self.items.len: diff --git a/src/app/modules/main/chat_section/view.nim b/src/app/modules/main/chat_section/view.nim index 57dbe3c181..4312a4624e 100644 --- a/src/app/modules/main/chat_section/view.nim +++ b/src/app/modules/main/chat_section/view.nim @@ -17,6 +17,8 @@ QtObject: contactRequestsModelVariant: QVariant listOfMyContacts: contacts_model.Model listOfMyContactsVariant: QVariant + editCategoryChannelsModel: chats_model.Model + editCategoryChannelsVariant: QVariant proc delete*(self: View) = self.model.delete @@ -27,6 +29,8 @@ QtObject: self.contactRequestsModelVariant.delete self.listOfMyContacts.delete self.listOfMyContactsVariant.delete + self.editCategoryChannelsModel.delete + self.editCategoryChannelsVariant.delete self.QObject.delete proc newView*(delegate: io_interface.AccessInterface): View = @@ -35,6 +39,8 @@ QtObject: result.delegate = delegate result.model = chats_model.newModel() result.modelVariant = newQVariant(result.model) + result.editCategoryChannelsModel = chats_model.newModel() + result.editCategoryChannelsVariant = newQVariant(result.editCategoryChannelsModel) result.activeItem = newActiveItem() result.activeItemVariant = newQVariant(result.activeItem) result.contactRequestsModel = contacts_model.newModel() @@ -53,9 +59,19 @@ QtObject: proc getModel(self: View): QVariant {.slot.} = return self.modelVariant + QtProperty[QVariant] model: read = getModel + proc editCategoryChannelsModel*(self: View): chats_model.Model = + return self.editCategoryChannelsModel + + proc getEditCategoryChannels(self: View): QVariant {.slot.} = + return self.editCategoryChannelsVariant + + QtProperty[QVariant] editCategoryChannelsModel: + read = getEditCategoryChannels + proc contactRequestsModel*(self: View): contacts_model.Model = return self.contactRequestsModel @@ -225,5 +241,12 @@ QtObject: let channelsSeq = map(parseJson(channels).getElems(), proc(x:JsonNode):string = x.getStr()) self.delegate.createCommunityCategory(name, channelsSeq) + proc editCommunityCategory*(self: View, categoryId: string, name: string, channels: string) {.slot.} = + let channelsSeq = map(parseJson(channels).getElems(), proc(x:JsonNode):string = x.getStr()) + self.delegate.editCommunityCategory(categoryId, name, channelsSeq) + proc deleteCommunityCategory*(self: View, categoryId: string) {.slot.} = self.delegate.deleteCommunityCategory(categoryId) + + proc prepareEditCategoryModel*(self: View, categoryId: string) {.slot.} = + self.delegate.prepareEditCategoryModel(categoryId) \ No newline at end of file diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index e0306fe342..28759c1849 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -596,18 +596,31 @@ QtObject: channels: seq[string]) = try: let response = status_go.editCommunityCategory(communityId, categoryId, name, channels) - if response.error != nil: let error = Json.decode($response.error, RpcError) raise newException(RpcException, "Error creating community category: " & error.message) if response.result != nil and response.result.kind != JNull: + var chats: seq[ChatDto] = @[] + for chatId, v in response.result["communityChanges"].getElems()[0]["chatsModified"].pairs(): + let idx = findIndexById(chatId, self.joinedCommunities[communityId].chats) + if idx > -1: + self.joinedCommunities[communityId].chats[idx].categoryId = v["CategoryModified"].getStr() + self.joinedCommunities[communityId].chats[idx].position = v["PositionModified"].getInt() + + let fullChatId = communityId & chatId + var chatDetails = self.chatService.getChatById(fullChatId) # we are free to do this cause channel must be created before we add it to a category + chatDetails.updateMissingFields(self.joinedCommunities[communityId].chats[idx]) + self.chatService.updateOrAddChat(chatDetails) # we have to update chats stored in the chat service. + chats.add(chatDetails) + for k, v in response.result["communityChanges"].getElems()[0]["categoriesModified"].pairs(): let category = v.toCategory() self.events.emit(SIGNAL_COMMUNITY_CATEGORY_EDITED, - CommunityCategoryArgs(communityId: communityId, category: category #[, channels: channels]#)) # TODO: add channels + CommunityCategoryArgs(communityId: communityId, category: category, chats: chats)) + except Exception as e: - error "Error creating community category", msg = e.msg, communityId, name + error "Error editing community category", msg = e.msg, communityId, name proc deleteCommunityCategory*(self: Service, communityId: string, categoryId: string) = try: diff --git a/ui/app/AppLayouts/Chat/popups/community/CreateCategoryPopup.qml b/ui/app/AppLayouts/Chat/popups/community/CreateCategoryPopup.qml index 8470ffeb15..542fce31ee 100644 --- a/ui/app/AppLayouts/Chat/popups/community/CreateCategoryPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/CreateCategoryPopup.qml @@ -30,8 +30,8 @@ StatusModal { onOpened: { if(isEdit){ root.contentItem.categoryName.input.text = categoryName - // Not Refactored Yet - // channels = //JSON.parse(root.store.chatsModelInst.communities.activeCommunity.getChatIdsByCategory(categoryId)) + root.channels = [] + root.store.prepareEditCategoryModel(categoryId); } root.contentItem.categoryName.input.forceActiveFocus(Qt.MouseFocusReason) } @@ -110,16 +110,13 @@ StatusModal { anchors.top: channelsLabel.bottom height: childrenRect.height width: parent.width - model: root.store.chatCommunitySectionModule.model + model: isEdit ? root.store.chatCommunitySectionModule.editCategoryChannelsModel : root.store.chatCommunitySectionModule.model interactive: false clip: true delegate: StatusListItem { anchors.horizontalCenter: parent.horizontalCenter - visible: { - // TODO: if edit, show only the subitems of the current category - return root.isEdit ? null : model.type != Constants.chatType.unknown - } + visible: model.type != Constants.chatType.unknown height: visible ? implicitHeight : 0 title: "#" + model.name icon.isLetterIdenticon: true @@ -129,17 +126,15 @@ StatusModal { components: [ StatusCheckBox { id: channelItemCheckbox - checked: root.isEdit ? root.channels.indexOf(model.itemId) > - 1 : false + checked: root.isEdit ? model.categoryId == root.categoryId : false onCheckedChanged: { - var idx = root.channels.indexOf(model.itemId) if(checked){ + var idx = root.channels.indexOf(model.itemId) if(idx === -1){ root.channels.push(model.itemId) } } else { - if(idx > -1){ - root.channels.splice(idx, 1); - } + root.channels = root.channels.filter(el => el !== model.itemId); } } } @@ -219,11 +214,10 @@ StatusModal { } let error = "" - if (isEdit) { -// error = root.store.editCommunityCategory(communityId, categoryId, Utils.filterXSS(root.contentItem.categoryName.input.text), JSON.stringify(channels)); + error = root.store.editCommunityCategory(root.categoryId, Utils.filterXSS(root.contentItem.categoryName.input.text), JSON.stringify(channels)); } else { - error = root.store.createCommunityCategory(root.contentItem.categoryName.input.text, JSON.stringify(channels)); + error = root.store.createCommunityCategory(Utils.filterXSS(root.contentItem.categoryName.input.text), JSON.stringify(channels)); } if (error) { diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml index bdf771042f..0d358d8187 100644 --- a/ui/app/AppLayouts/Chat/stores/RootStore.qml +++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml @@ -154,14 +154,18 @@ QtObject { chatCommunitySectionModule.createCommunityCategory(categoryName, channels) } - function editCommunityCategory(communityId, categoryId, categoryName, channels) { - communitiesModuleInst.editCommunityCategory(communityId, categoryId, categoryName, channels); + function editCommunityCategory(categoryId, categoryName, channels) { + chatCommunitySectionModule.editCommunityCategory(categoryId, categoryName, channels); } function deleteCommunityCategory(categoryId) { chatCommunitySectionModule.deleteCommunityCategory(categoryId); } + function prepareEditCategoryModel(categoryId) { + chatCommunitySectionModule.prepareEditCategoryModel(categoryId); + } + function leaveCommunity() { chatCommunitySectionModule.leaveCommunity(); } diff --git a/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml b/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml index fbaf838119..308490dabd 100644 --- a/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml @@ -227,6 +227,7 @@ Item { onTriggered: { Global.openPopup(createCategoryPopup, { isEdit: true, + channels: [], categoryId: categoryItem.categoryId, categoryName: categoryItem.name })