diff --git a/src/app/modules/main/chat_section/base_item.nim b/src/app/modules/main/chat_section/base_item.nim index 6343cf27e7..242306beb8 100644 --- a/src/app/modules/main/chat_section/base_item.nim +++ b/src/app/modules/main/chat_section/base_item.nim @@ -76,6 +76,9 @@ method `isIdenticon=`*(self: var BaseItem, value: bool) {.inline base.} = method color*(self: BaseItem): string {.inline base.} = self.color +method `color=`*(self: var BaseItem, value: string) {.inline base.} = + self.color = value + method emoji*(self: BaseItem): string {.inline base.} = self.emoji diff --git a/src/app/modules/main/chat_section/chat_content/module.nim b/src/app/modules/main/chat_section/chat_content/module.nim index 45b5403c4d..62611015ea 100644 --- a/src/app/modules/main/chat_section/chat_content/module.nim +++ b/src/app/modules/main/chat_section/chat_content/module.nim @@ -328,7 +328,7 @@ method onNotificationsUpdated*(self: Module, hasUnreadMessages: bool, notificati self.view.updateChatDetailsNotifications(hasUnreadMessages, notificationCount) method onChatEdited*(self: Module, chatDto: ChatDto) = - self.view.updateChatDetails(chatDto.name, chatDto.description, chatDto.emoji) + self.view.updateChatDetails(chatDto.name, chatDto.description, chatDto.emoji, chatDto.color) self.messagesModule.updateChatIdentifier() method onChatRenamed*(self: Module, newName: string) = diff --git a/src/app/modules/main/chat_section/chat_content/view.nim b/src/app/modules/main/chat_section/chat_content/view.nim index 7bc134b603..3b5e02dc4d 100644 --- a/src/app/modules/main/chat_section/chat_content/view.nim +++ b/src/app/modules/main/chat_section/chat_content/view.nim @@ -111,10 +111,11 @@ QtObject: proc amIChatAdmin*(self: View): bool {.slot.} = return self.delegate.amIChatAdmin() - proc updateChatDetails*(self: View, name, description, emoji: string) = + proc updateChatDetails*(self: View, name, description, emoji, color: string) = self.chatDetails.setName(name) self.chatDetails.setDescription(description) self.chatDetails.setEmoji(emoji) + self.chatDetails.setColor(color) self.chatDetailsChanged() proc updateChatDetailsName*(self: View, name: string) = diff --git a/src/app/modules/main/chat_section/controller.nim b/src/app/modules/main/chat_section/controller.nim index 0a499bb3e3..cbbabac741 100644 --- a/src/app/modules/main/chat_section/controller.nim +++ b/src/app/modules/main/chat_section/controller.nim @@ -318,8 +318,10 @@ method createCommunityChannel*( name: string, description: string, emoji: string, + color: string, categoryId: string) = - self.communityService.createCommunityChannel(self.sectionId, name, description, emoji, categoryId) + self.communityService.createCommunityChannel(self.sectionId, name, description, emoji, color, + categoryId) method editCommunityChannel*( self: Controller, @@ -327,6 +329,7 @@ method editCommunityChannel*( name: string, description: string, emoji: string, + color: string, categoryId: string, position: int) = self.communityService.editCommunityChannel( @@ -335,6 +338,7 @@ method editCommunityChannel*( name, description, emoji, + color, categoryId, position) diff --git a/src/app/modules/main/chat_section/controller_interface.nim b/src/app/modules/main/chat_section/controller_interface.nim index 2fe123a7f6..0f6917da65 100644 --- a/src/app/modules/main/chat_section/controller_interface.nim +++ b/src/app/modules/main/chat_section/controller_interface.nim @@ -119,10 +119,12 @@ method acceptRequestToJoinCommunity*(self: AccessInterface, requestId: string) { method declineRequestToJoinCommunity*(self: AccessInterface, requestId: string) {.base.} = raise newException(ValueError, "No implementation available") -method createCommunityChannel*(self: AccessInterface, name: string, description: string, emoji: string, categoryId: string) {.base.} = +method createCommunityChannel*(self: AccessInterface, name: string, description: string, + emoji: string, color: string, categoryId: string) {.base.} = raise newException(ValueError, "No implementation available") -method editCommunityChannel*(self: AccessInterface, channelId: string, name: string, description: string, emoji: string, categoryId: string, position: int) {.base.} = +method editCommunityChannel*(self: AccessInterface, channelId: string, name: string, + description: string, emoji: string, color: string, categoryId: string, position: int) {.base.} = raise newException(ValueError, "No implementation available") method createCommunityCategory*(self: AccessInterface, name: string, channels: seq[string]) {.base.} = diff --git a/src/app/modules/main/chat_section/model.nim b/src/app/modules/main/chat_section/model.nim index cc06a044b3..19b5b47908 100644 --- a/src/app/modules/main/chat_section/model.nim +++ b/src/app/modules/main/chat_section/model.nim @@ -272,16 +272,17 @@ QtObject: self.dataChanged(index, index, @[ModelRole.Name.int]) return - proc updateItemDetails*(self: Model, id, name, description, emoji: string) = + proc updateItemDetails*(self: Model, id, name, description, emoji, color: string) = ## This updates only first level items, it doesn't update subitems, since subitems cannot have custom icon. for i in 0 ..< self.items.len: if(self.items[i].id == id): self.items[i].BaseItem.name = name self.items[i].BaseItem.description = description self.items[i].BaseItem.emoji = emoji + self.items[i].BaseItem.color = color let index = self.createIndex(i, 0, nil) self.dataChanged(index, index, - @[ModelRole.Name.int, ModelRole.Description.int, ModelRole.Emoji.int]) + @[ModelRole.Name.int, ModelRole.Description.int, ModelRole.Emoji.int, ModelRole.Color.int]) return proc updateNotificationsForItemOrSubItemById*(self: Model, id: string, hasUnreadMessages: bool, diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index 501b86b111..52bbdf1e84 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -552,7 +552,8 @@ method onCommunityChannelDeletedOrChatLeft*(self: Module, chatId: string) = method onCommunityChannelEdited*(self: Module, chat: ChatDto) = if(not self.chatContentModules.contains(chat.id)): return - self.view.chatsModel().updateItemDetails(chat.id, chat.name, chat.description, chat.emoji) + self.view.chatsModel().updateItemDetails(chat.id, chat.name, chat.description, chat.emoji, + chat.color) method createOneToOneChat*(self: Module, communityID: string, chatId: string, ensName: string) = if(self.controller.isCommunity()): @@ -694,12 +695,13 @@ method acceptRequestToJoinCommunity*(self: Module, requestId: string) = method declineRequestToJoinCommunity*(self: Module, requestId: string) = self.controller.declineRequestToJoinCommunity(requestId) -method createCommunityChannel*(self: Module, name, description, emoji, categoryId: string) = - self.controller.createCommunityChannel(name, description, emoji, categoryId) +method createCommunityChannel*(self: Module, name, description, emoji, color, categoryId: string) = + self.controller.createCommunityChannel(name, description, emoji, color, categoryId) -method editCommunityChannel*(self: Module, channelId, name, description, emoji, categoryId: string, - position: int) = - self.controller.editCommunityChannel(channelId, name, description, emoji, categoryId, position) +method editCommunityChannel*(self: Module, channelId, name, description, emoji, color, + categoryId: string, position: int) = + self.controller.editCommunityChannel(channelId, name, description, emoji, color, categoryId, + position) method createCommunityCategory*(self: Module, name: string, channels: seq[string]) = self.controller.createCommunityCategory(name, channels) 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 0cec6fb731..2739eb7ef6 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 @@ -94,10 +94,12 @@ method acceptRequestToJoinCommunity*(self: AccessInterface, requestId: string) { method declineRequestToJoinCommunity*(self: AccessInterface, requestId: string) {.base.} = raise newException(ValueError, "No implementation available") -method createCommunityChannel*(self: AccessInterface, name: string, description: string, emoji: string, categoryId: string) {.base.} = +method createCommunityChannel*(self: AccessInterface, name: string, description: string, + emoji: string, color: string, categoryId: string) {.base.} = raise newException(ValueError, "No implementation available") -method editCommunityChannel*(self: AccessInterface, channelId, name, description, emoji, categoryId: string, position: int) {.base.} = +method editCommunityChannel*(self: AccessInterface, channelId, name, description, emoji, color, + categoryId: string, position: int) {.base.} = raise newException(ValueError, "No implementation available") method leaveCommunity*(self: AccessInterface) {.base.} = diff --git a/src/app/modules/main/chat_section/view.nim b/src/app/modules/main/chat_section/view.nim index 02df033153..4166fbfa7c 100644 --- a/src/app/modules/main/chat_section/view.nim +++ b/src/app/modules/main/chat_section/view.nim @@ -213,9 +213,10 @@ QtObject: name: string, description: string, emoji: string, + color: string, categoryId: string ) {.slot.} = - self.delegate.createCommunityChannel(name, description, emoji, categoryId) + self.delegate.createCommunityChannel(name, description, emoji, color, categoryId) proc editCommunityChannel*( self: View, @@ -223,6 +224,7 @@ QtObject: name: string, description: string, emoji: string, + color: string, categoryId: string, position: int ) {.slot.} = @@ -231,6 +233,7 @@ QtObject: name, description, emoji, + color, categoryId, position ) diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index 673ad5c3ee..8cb43d9829 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -581,9 +581,11 @@ QtObject: name: string, description: string, emoji: string, + color: string, categoryId: string) = try: - let response = status_go.createCommunityChannel(communityId, name, description, emoji, categoryId) + let response = status_go.createCommunityChannel(communityId, name, description, emoji, color, + categoryId) if not response.error.isNil: let error = Json.decode($response.error, RpcError) @@ -611,6 +613,7 @@ QtObject: name: string, description: string, emoji: string, + color: string, categoryId: string, position: int) = try: @@ -620,6 +623,7 @@ QtObject: name, description, emoji, + color, categoryId, position) diff --git a/src/backend/communities.nim b/src/backend/communities.nim index 0fe78be1dd..21d63a8053 100644 --- a/src/backend/communities.nim +++ b/src/backend/communities.nim @@ -85,6 +85,7 @@ proc createCommunityChannel*( name: string, description: string, emoji: string, + color: string, categoryId: string ): RpcResponse[JsonNode] {.raises: [Exception].} = result = callPrivateRPC("createCommunityChat".prefix, %*[ @@ -96,8 +97,8 @@ proc createCommunityChannel*( "identity": { "display_name": name, "description": description, - "emoji": emoji#, - # "color": color# + "emoji": emoji, + "color": color }, "category_id": categoryId }]) @@ -108,6 +109,7 @@ proc editCommunityChannel*( name: string, description: string, emoji: string, + color: string, categoryId: string, position: int ): RpcResponse[JsonNode] {.raises: [Exception].} = @@ -121,8 +123,8 @@ proc editCommunityChannel*( "identity": { "display_name": name, "description": description, - "emoji": emoji#, - # "color": color + "emoji": emoji, + "color": color }, "category_id": categoryId, "position": position diff --git a/ui/app/AppLayouts/Chat/popups/community/CreateChannelPopup.qml b/ui/app/AppLayouts/Chat/popups/community/CreateChannelPopup.qml index 2338b2bdb4..1ca8a992d3 100644 --- a/ui/app/AppLayouts/Chat/popups/community/CreateChannelPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/CreateChannelPopup.qml @@ -20,15 +20,20 @@ StatusModal { property string channelName: "" property string channelDescription: "" property string channelEmoji: "" + property string channelColor: "" property bool emojiPopupOpened: false property var emojiPopup: null readonly property string emojiRegexStr: 'alt="(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])"' + readonly property var communityColorValidator: Utils.Validate.NoEmpty + | Utils.Validate.TextHexColor readonly property int maxChannelNameLength: 30 readonly property int maxChannelDescLength: 140 - signal createCommunityChannel(string chName, string chDescription, string chEmoji, string chCategoryId) - signal editCommunityChannel(string chName, string chDescription, string chEmoji, string chCategoryId) + signal createCommunityChannel(string chName, string chDescription, string chEmoji, + string chColor, string chCategoryId) + signal editCommunityChannel(string chName, string chDescription, string chEmoji, string chColor, + string chCategoryId) //% "New channel" header.title: qsTrId("create-channel-title") @@ -61,7 +66,9 @@ StatusModal { function isFormValid() { return (scrollView.channelName.valid && - scrollView.channelDescription.valid) + scrollView.channelDescription.valid) && + Utils.validateAndReturnError(scrollView.channelColorDialog.color.toString().toUpperCase(), + communityColorValidator) === "" } contentItem: ScrollView { @@ -72,6 +79,7 @@ StatusModal { property alias channelName: nameInput property alias channelDescription: descriptionTextArea + property alias channelColorDialog: colorDialog property alias channelEmoji: emojiText contentHeight: content.height @@ -91,8 +99,9 @@ StatusModal { StatusInput { id: nameInput + label: qsTr("Channel name") charLimit: popup.maxChannelNameLength - input.placeholderText: qsTr("Channel name") + input.placeholderText: qsTr("Name the channel") input.onTextChanged: { input.text = Utils.convertSpacesToDashesAndUpperToLowerCase(input.text); input.cursorPosition = input.text.length @@ -104,9 +113,63 @@ StatusModal { }] } - StatusModalDivider { - topPadding: 8 - bottomPadding: 8 + Item { + id: spacer1 + height: 16 + width: parent.width + } + + StatusBaseText { + text: qsTr("Channel colour") + font.pixelSize: 15 + color: Theme.palette.directColor1 + anchors.left: parent.left + anchors.leftMargin: 16 + } + + Item { + anchors.horizontalCenter: parent.horizontalCenter + height: colorSelectorButton.height + 16 + width: parent.width - 32 + + StatusPickerButton { + id: colorSelectorButton + + property string validationError: "" + + bgColor: colorDialog.colorSelected ? + colorDialog.color : Theme.palette.baseColor2 + // TODO adjust text color depending on the background color to make it readable + // contentColor: colorDialog.colorSelected ? Theme.palette.indirectColor1 : Theme.palette.baseColor1 + text: colorDialog.colorSelected ? + colorDialog.color.toString().toUpperCase() : + //% "Pick a color" + qsTrId("pick-a-color") + + onClicked: colorDialog.open(); + onTextChanged: { + if (colorDialog.colorSelected) { + validationError = Utils.validateAndReturnError(text, communityColorValidator) + } + } + + ColorDialog { + id: colorDialog + property bool colorSelected: popup.isEdit && popup.channelColor + color: popup.isEdit && popup.channelColor ? popup.channelColor : + Theme.palette.primaryColor1 + onAccepted: colorSelected = true + } + } + + StatusBaseText { + text: colorSelectorButton.validationError + visible: !!text + color: Theme.palette.dangerColor1 + anchors.top: colorSelectorButton.bottom + anchors.topMargin: 4 + anchors.right: colorSelectorButton.right + } } StatusInput { @@ -245,14 +308,17 @@ StatusModal { emoji = found[1] } if (!isEdit) { + //popup.contentItem.communityColor.color.toString().toUpperCase() popup.createCommunityChannel(Utils.filterXSS(popup.contentItem.channelName.input.text), Utils.filterXSS(popup.contentItem.channelDescription.input.text), emoji, + popup.contentItem.channelColorDialog.color.toString().toUpperCase(), popup.categoryId) } else { popup.editCommunityChannel(Utils.filterXSS(popup.contentItem.channelName.input.text), Utils.filterXSS(popup.contentItem.channelDescription.input.text), emoji, + popup.contentItem.channelColorDialog.color.toString().toUpperCase(), popup.categoryId) } diff --git a/ui/app/AppLayouts/Chat/popups/community/CreateCommunityPopup.qml b/ui/app/AppLayouts/Chat/popups/community/CreateCommunityPopup.qml index f2991ce566..2aefebd910 100644 --- a/ui/app/AppLayouts/Chat/popups/community/CreateCommunityPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/CreateCommunityPopup.qml @@ -21,8 +21,7 @@ StatusModal { property var store property var communitySectionModule property bool isEdit: false - // Not Refactored Yet - property QtObject community: null //popup.store.chatsModelInst.communities.activeCommunity + property QtObject community: null property var onSave: () => {} readonly property int maxCommunityNameLength: 30 readonly property int maxCommunityDescLength: 140 diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml index 6f19715aa0..b4a7d98770 100644 --- a/ui/app/AppLayouts/Chat/stores/RootStore.qml +++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml @@ -189,19 +189,20 @@ QtObject { chatCommunitySectionModule.removeUserFromCommunity(pubKey); } - function createCommunityChannel(channelName, channelDescription, channelEmoji, categoryId) { - chatCommunitySectionModule.createCommunityChannel(channelName, channelDescription, channelEmoji, categoryId); + function createCommunityChannel(channelName, channelDescription, channelEmoji, channelColor, + categoryId) { + chatCommunitySectionModule.createCommunityChannel(channelName, channelDescription, + channelEmoji, channelColor, categoryId); } - function editCommunityChannel(chatId, newName, newDescription, newEmoji, newCategory, channelPosition) { - // TODO: pass the private value when private channels - // are implemented - //privateSwitch.checked) + function editCommunityChannel(chatId, newName, newDescription, newEmoji, newColor, + newCategory, channelPosition) { chatCommunitySectionModule.editCommunityChannel( chatId, newName, newDescription, newEmoji, + newColor, newCategory, channelPosition ) diff --git a/ui/app/AppLayouts/Chat/views/ChatContentView.qml b/ui/app/AppLayouts/Chat/views/ChatContentView.qml index 72b134d6d5..b04f461d90 100644 --- a/ui/app/AppLayouts/Chat/views/ChatContentView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatContentView.qml @@ -177,6 +177,7 @@ ColumnLayout { chatName = chatContentModule.chatDetails.name chatDescription = chatContentModule.chatDetails.description chatEmoji = chatContentModule.chatDetails.emoji + chatColor = chatContentModule.chatDetails.color chatType = chatContentModule.chatDetails.type chatMuted = chatContentModule.chatDetails.muted channelPosition = chatContentModule.chatDetails.position @@ -249,6 +250,7 @@ ColumnLayout { newName, newDescription, newEmoji, + newColor, newCategory, channelPosition // TODO change this to the signal once it is modifiable ) diff --git a/ui/app/AppLayouts/Chat/views/ChatContextMenuView.qml b/ui/app/AppLayouts/Chat/views/ChatContextMenuView.qml index 15cc4ec8b7..5676544cb0 100644 --- a/ui/app/AppLayouts/Chat/views/ChatContextMenuView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatContextMenuView.qml @@ -20,6 +20,7 @@ StatusPopupMenu { property string chatName: "" property string chatDescription: "" property string chatEmoji: "" + property string chatColor: "" property string chatIcon: "" property int chatType: -1 property bool chatMuted: false @@ -39,8 +40,8 @@ StatusPopupMenu { signal leaveChat(string chatId) signal leaveGroup(string chatId) - signal createCommunityChannel(string chatId, string newName, string newDescription, string newEmoji) - signal editCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newCategory) + signal createCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newColor) + signal editCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newColor, string newCategory) signal fetchMoreMessages(int timeFrame) signal addRemoveGroupMember() @@ -190,6 +191,7 @@ StatusPopupMenu { channelName: root.chatName, channelDescription: root.chatDescription, channelEmoji: root.chatEmoji, + channelColor: root.chatColor, categoryId: root.chatCategoryId }); } @@ -202,10 +204,11 @@ StatusPopupMenu { isEdit: true emojiPopup: root.emojiPopup onCreateCommunityChannel: { - root.createCommunityChannel(root.chatId, chName, chDescription, chEmoji); + root.createCommunityChannel(root.chatId, chName, chDescription, chEmoji, chColor); } onEditCommunityChannel: { - root.editCommunityChannel(root.chatId, chName, chDescription, chEmoji, chCategoryId); + root.editCommunityChannel(root.chatId, chName, chDescription, chEmoji, chColor, + chCategoryId); } onClosed: { destroy() diff --git a/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml b/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml index a1a01f6171..1104c4ed3b 100644 --- a/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml @@ -277,6 +277,7 @@ Item { chatDescription = obj.description chatEmoji = obj.emoji + chatColor = obj.color chatType = obj.type chatMuted = obj.muted channelPosition = obj.position @@ -332,6 +333,7 @@ Item { newName, newDescription, newEmoji, + newColor, newCategory, channelPosition // TODO change this to the signal once it is modifiable ) @@ -405,8 +407,10 @@ Item { CreateChannelPopup { anchors.centerIn: parent emojiPopup: root.emojiPopup - onCreateCommunityChannel: function (chName, chDescription, chEmoji, chCategoryId) { - root.store.createCommunityChannel(chName, chDescription, chEmoji, chCategoryId) + onCreateCommunityChannel: function (chName, chDescription, chEmoji, chColor, + chCategoryId) { + root.store.createCommunityChannel(chName, chDescription, chEmoji, chColor, + chCategoryId) } onClosed: { destroy() diff --git a/ui/app/AppLayouts/Chat/views/ContactsColumnView.qml b/ui/app/AppLayouts/Chat/views/ContactsColumnView.qml index 435e5044b7..032acfeb14 100644 --- a/ui/app/AppLayouts/Chat/views/ContactsColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/ContactsColumnView.qml @@ -184,6 +184,7 @@ Item { chatName = obj.name chatDescription = obj.description chatEmoji = obj.emoji + chatColor = obj.color chatType = obj.type chatMuted = obj.muted }