diff --git a/src/app/modules/main/app_search/location_menu_sub_item.nim b/src/app/modules/main/app_search/location_menu_sub_item.nim index dfa7f6bf1a..acd15533fa 100644 --- a/src/app/modules/main/app_search/location_menu_sub_item.nim +++ b/src/app/modules/main/app_search/location_menu_sub_item.nim @@ -9,12 +9,14 @@ type isUserIcon: bool colorId: int colorHash: color_hash_model.Model + position: int proc initSubItem*(value, text, image, icon, iconColor: string, - isUserIcon: bool = false, colorId: int = 0, colorHash: seq[ColorHashSegment] = @[]): SubItem = + isUserIcon: bool = false, position: int, colorId: int = 0, colorHash: seq[ColorHashSegment] = @[]): SubItem = result = SubItem() result.setup(value, text, image, icon, iconColor) result.isUserIcon = isUserIcon + result.position = position result.colorId = colorId result.colorHash = color_hash_model.newModel() result.colorHash.setItems(map(colorHash, x => color_hash_item.initItem(x.len, x.colorIdx))) @@ -26,6 +28,7 @@ proc `$`*(self: SubItem): string = result = fmt"""SearchMenuSubItem( value: {self.value}, text: {self.text}, + position: {self.position}, imageSource: {self.image}, iconName: {self.icon}, iconColor: {self.iconColor}, @@ -35,6 +38,7 @@ proc toJsonNode*(self: SubItem): JsonNode = result = %* { "value": self.value, "text": self.text, + "position": self.position, "imageSource": self.image, "iconName": self.icon, "iconColor": self.iconColor, @@ -43,6 +47,9 @@ proc toJsonNode*(self: SubItem): JsonNode = "colorHash": self.colorHash.toJson() } +proc position*(self: SubItem): int = + return self.position + proc isUserIcon*(self: SubItem): bool = return self.isUserIcon diff --git a/src/app/modules/main/app_search/location_menu_sub_model.nim b/src/app/modules/main/app_search/location_menu_sub_model.nim index 534cde26b8..8db7bfb478 100644 --- a/src/app/modules/main/app_search/location_menu_sub_model.nim +++ b/src/app/modules/main/app_search/location_menu_sub_model.nim @@ -10,6 +10,7 @@ type Icon IconColor IsUserIcon + Position ColorId ColorHash @@ -57,6 +58,7 @@ QtObject: SubModelRole.Icon.int:"iconName", SubModelRole.IconColor.int:"iconColor", SubModelRole.IsUserIcon.int:"isUserIcon", + SubModelRole.Position.int:"position", SubModelRole.ColorId.int:"colorId", SubModelRole.ColorHash.int:"colorHash" }.toTable @@ -84,6 +86,8 @@ QtObject: result = newQVariant(item.iconColor) of SubModelRole.IsUserIcon: result = newQVariant(item.isUserIcon) + of SubModelRole.Position: + result = newQVariant(item.position) of SubModelRole.ColorId: result = newQVariant(item.colorId) of SubModelRole.ColorHash: diff --git a/src/app/modules/main/app_search/module.nim b/src/app/modules/main/app_search/module.nim index 80f941c058..c97f6cd645 100644 --- a/src/app/modules/main/app_search/module.nim +++ b/src/app/modules/main/app_search/module.nim @@ -1,5 +1,5 @@ import NimQml -import json, strutils, chronicles, sequtils +import json, strutils, chronicles, sequtils, tables, std/algorithm import io_interface import ../io_interface as delegate_interface import view, controller @@ -66,7 +66,10 @@ method viewDidLoad*(self: Module) = method getModuleAsVariant*(self: Module): QVariant = return self.viewVariant -proc getChatSubItems(self: Module, chats: seq[ChatDto]): seq[location_menu_sub_item.SubItem] = +proc getChatSubItems(self: Module, chats: seq[ChatDto], categories: seq[Category] = @[]): seq[location_menu_sub_item.SubItem] = + var highestPosition = 0 + var categoryChats: OrderedTable[int, seq[ChatDto]] = initOrderedTable[int, seq[ChatDto]]() + for chatDto in chats: if chatDto.isHiddenChat: continue @@ -76,10 +79,23 @@ proc getChatSubItems(self: Module, chats: seq[ChatDto]): seq[location_menu_sub_i var colorHash: ColorHashDto = @[] var colorId: int = 0 let isOneToOneChat = chatDto.chatType == ChatType.OneToOne - if(isOneToOneChat): + if isOneToOneChat: (chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(chatDto.id) colorHash = self.controller.getColorHash(chatDto.id) colorId = self.controller.getColorId(chatDto.id) + elif chatDto.chatType == ChatType.CommunityChat: + if chatDto.categoryId != "": + for cat in categories: + if cat.id == chatDto.categoryId: + if not categoryChats.hasKey(cat.position): + categoryChats[cat.position] = @[] + categoryChats[cat.position].add(chatDto) + break + continue + else: + if chatDto.position > highestPosition: + highestPosition = chatDto.position + let subItem = location_menu_sub_item.initSubItem( chatDto.id, chatName, @@ -87,11 +103,29 @@ proc getChatSubItems(self: Module, chats: seq[ChatDto]): seq[location_menu_sub_i "", chatDto.color, isOneToOneChat, + chatDto.position, colorId, - colorHash + colorHash, ) result.add(subItem) + # Add category chats by adjusting the position by taking into account the category position + let sortedKeys = toSeq(categoryChats.keys).sorted() + for categoryPosition in sortedKeys: + highestPosition.inc() + for chat in categoryChats[categoryPosition]: + let chatPosition = chat.position + highestPosition + result.add(location_menu_sub_item.initSubItem( + chat.id, + chat.name, + chat.emoji, + "", + chat.color, + isUserIcon = false, + chatPosition, + )) + highestPosition += categoryChats[categoryPosition].len + proc buildLocationMenuForCommunity(self: Module, community: CommunityDto): location_menu_item.Item = var item = location_menu_item.initItem( community.id, @@ -101,7 +135,7 @@ proc buildLocationMenuForCommunity(self: Module, community: CommunityDto): locat community.color ) - var subItems = self.getChatSubItems(community.chats) + var subItems = self.getChatSubItems(community.chats, community.categories) item.setSubItems(subItems) return item diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index 26cd3c29c9..bb5fc87e44 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -316,8 +316,6 @@ proc buildChatSectionUI( items.add(self.addCategoryItem(categoryDto, community.memberRole, community.id)) for chatDto in chats: - var categoryPosition = -1 - # Add an empty chat item that has the category info var isActive = false # restore on a startup last open channel for the section or @@ -326,12 +324,6 @@ proc buildChatSectionUI( selectedItemId = chatDto.id isActive = true - if chatDto.categoryId != "": - for category in community.categories: - if category.id == chatDto.categoryId: - categoryPosition = category.position - break - items.add(self.addOrUpdateChat( chatDto, belongsToCommunity = chatDto.communityId.len > 0, diff --git a/ui/StatusQ/src/StatusQ/Popups/StatusSearchLocationMenu.qml b/ui/StatusQ/src/StatusQ/Popups/StatusSearchLocationMenu.qml index 18188f9f43..8dc476cf4b 100644 --- a/ui/StatusQ/src/StatusQ/Popups/StatusSearchLocationMenu.qml +++ b/ui/StatusQ/src/StatusQ/Popups/StatusSearchLocationMenu.qml @@ -9,6 +9,8 @@ import StatusQ.Core.Theme 0.1 import StatusQ.Controls 0.1 import StatusQ.Core.Utils 0.1 as StatusQUtils +import SortFilterProxyModel 0.2 + StatusMenu { id: root @@ -116,7 +118,13 @@ StatusMenu { readonly property string parentIsIdenticon: subMenuDelegate.parentIsIdenticon menu: subMenuDelegate - model: subMenuDelegate.subItemsModel + model: SortFilterProxyModel { + sourceModel: subMenuDelegate.subItemsModel + sorters: RoleSorter { + roleName: "position" + sortOrder: Qt.AscendingOrder + } + } delegate: StatusSearchPopupMenuItem { value: model.value