diff --git a/src/app/modules/main/chat_section/base_item.nim b/src/app/modules/main/chat_section/base_item.nim index 413a7123d0..c5a72b268a 100644 --- a/src/app/modules/main/chat_section/base_item.nim +++ b/src/app/modules/main/chat_section/base_item.nim @@ -1,3 +1,9 @@ +import sequtils, sugar +import color_hash_item, color_hash_model + +type + ColorHashSegment* = tuple[len, colorIdx: int] + type BaseItem* {.pure inheritable.} = ref object of RootObj id: string @@ -7,6 +13,7 @@ type icon: string color: string emoji: string + colorHash: color_hash_model.Model description: string hasUnreadMessages: bool notificationsCount: int @@ -19,13 +26,15 @@ type proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: string, `type`: int, amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, - position: int, categoryId: string = "", highlight: bool = false) = + position: int, categoryId: string = "", colorHash: seq[ColorHashSegment] = @[], highlight: bool = false) = self.id = id self.name = name self.amIChatAdmin = amIChatAdmin self.icon = icon self.color = color self.emoji = emoji + self.colorHash = color_hash_model.newModel() + self.colorHash.setItems(map(colorHash, x => color_hash_item.initItem(x.len, x.colorIdx))) self.description = description self.`type` = `type` self.hasUnreadMessages = hasUnreadMessages @@ -39,10 +48,10 @@ proc setup*(self: BaseItem, id, name, icon: string, color, emoji, description: s proc initBaseItem*(id, name, icon: string, color, emoji, description: string, `type`: int, amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, blocked, active: bool, - position: int, categoryId: string = "", highlight: bool = false): BaseItem = + position: int, categoryId: string = "", colorHash: seq[ColorHashSegment] = @[], highlight: bool = false): BaseItem = result = BaseItem() result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, - hasUnreadMessages, notificationsCount, muted, blocked, active, position, categoryId, highlight) + hasUnreadMessages, notificationsCount, muted, blocked, active, position, categoryId, colorHash, highlight) proc delete*(self: BaseItem) = discard @@ -77,6 +86,9 @@ method emoji*(self: BaseItem): string {.inline base.} = method `emoji=`*(self: var BaseItem, value: string) {.inline base.} = self.emoji = value +method colorHash*(self: BaseItem): color_hash_model.Model {.inline base.} = + self.colorHash + method description*(self: BaseItem): string {.inline base.} = self.description diff --git a/src/app/modules/main/chat_section/color_hash_item.nim b/src/app/modules/main/chat_section/color_hash_item.nim new file mode 100644 index 0000000000..b4fb07c95f --- /dev/null +++ b/src/app/modules/main/chat_section/color_hash_item.nim @@ -0,0 +1,23 @@ +import strformat + +type + Item* = ref object + segmentLength: int + colorId: int + +proc initItem*(segmentLength: int, colorId: int): Item = + result = Item() + result.segmentLength = segmentLength + result.colorId = colorId + +proc `$`*(self: Item): string = + result = fmt"""ColorHashItem( + segmentLength: {$self.segmentLength}, + colorId: {$self.colorId}, + ]""" + +proc segmentLength*(self: Item): int {.inline.} = + self.segmentLength + +proc colorId*(self: Item): int {.inline.} = + self.colorId diff --git a/src/app/modules/main/chat_section/color_hash_model.nim b/src/app/modules/main/chat_section/color_hash_model.nim new file mode 100644 index 0000000000..87af4327c4 --- /dev/null +++ b/src/app/modules/main/chat_section/color_hash_model.nim @@ -0,0 +1,53 @@ +import NimQml, Tables + +import color_hash_item + +type + ModelRole {.pure.} = enum + SegmentLength = UserRole + 1 + ColorId + +QtObject: + type + Model* = ref object of QAbstractListModel + items: seq[Item] + + proc delete(self: Model) = + self.items = @[] + self.QAbstractListModel.delete + + proc setup(self: Model) = + self.QAbstractListModel.setup + + proc newModel*(): Model = + new(result, delete) + result.setup + + proc setItems*(self: Model, items: seq[Item]) = + self.beginResetModel() + self.items = items + self.endResetModel() + + method rowCount(self: Model, index: QModelIndex = nil): int = + return self.items.len + + method data(self: Model, index: QModelIndex, role: int): QVariant = + if not index.isValid: + return + if index.row < 0 or index.row >= self.items.len: + return + + let item = self.items[index.row] + let enumRole = role.ModelRole + + case enumRole: + of ModelRole.SegmentLength: + result = newQVariant(item.segmentLength) + of ModelRole.ColorId: + result = newQVariant(item.colorId) + + method roleNames(self: Model): Table[int, string] = + { + ModelRole.SegmentLength.int:"segmentLength", + ModelRole.ColorId.int:"colorId", + }.toTable diff --git a/src/app/modules/main/chat_section/controller.nim b/src/app/modules/main/chat_section/controller.nim index 0c8d011ab4..9d80345aac 100644 --- a/src/app/modules/main/chat_section/controller.nim +++ b/src/app/modules/main/chat_section/controller.nim @@ -9,6 +9,7 @@ import ../../../../app_service/service/community/service as community_service import ../../../../app_service/service/message/service as message_service import ../../../../app_service/service/gif/service as gif_service import ../../../../app_service/service/mailservers/service as mailservers_service +import ../../../../app_service/service/visual_identity/service as procs_from_visual_identity_service import ../../../core/signals/types import ../../../global/app_signals @@ -395,3 +396,6 @@ proc reorderCommunityChat*(self: Controller, categoryId: string, chatId: string, proc getRenderedText*(self: Controller, parsedTextArray: seq[ParsedText]): string = return self.messageService.getRenderedText(parsedTextArray) + +proc getColorHash*(self: Controller, pubkey: string): ColorHashDto = + procs_from_visual_identity_service.colorHashOf(pubkey) diff --git a/src/app/modules/main/chat_section/item.nim b/src/app/modules/main/chat_section/item.nim index 6fc2be3cf2..ef00288d01 100644 --- a/src/app/modules/main/chat_section/item.nim +++ b/src/app/modules/main/chat_section/item.nim @@ -7,10 +7,10 @@ type proc initItem*(id, name, icon: string, color, emoji, description: string, `type`: int, amIChatAdmin: bool, hasUnreadMessages: bool, notificationsCount: int, muted, - blocked, active: bool, position: int, categoryId: string, highlight: bool = false): Item = + blocked, active: bool, position: int, categoryId: string, colorHash: seq[ColorHashSegment] = @[], highlight: bool = false): Item = result = Item() result.setup(id, name, icon, color, emoji, description, `type`, amIChatAdmin, hasUnreadMessages, - notificationsCount, muted, blocked, active, position, categoryId, highlight) + notificationsCount, muted, blocked, active, position, categoryId, colorHash, highlight) result.subItems = newSubModel() proc delete*(self: Item) = diff --git a/src/app/modules/main/chat_section/model.nim b/src/app/modules/main/chat_section/model.nim index 1b9a8b3b9f..a861853b1f 100644 --- a/src/app/modules/main/chat_section/model.nim +++ b/src/app/modules/main/chat_section/model.nim @@ -10,6 +10,7 @@ type Icon Color Emoji + ColorHash Description Type HasUnreadMessages @@ -76,6 +77,7 @@ QtObject: ModelRole.Icon.int:"icon", ModelRole.Color.int:"color", ModelRole.Emoji.int:"emoji", + ModelRole.ColorHash.int:"colorHash", ModelRole.Description.int:"description", ModelRole.Type.int:"type", ModelRole.HasUnreadMessages.int:"hasUnreadMessages", @@ -113,6 +115,8 @@ QtObject: result = newQVariant(item.color) of ModelRole.Emoji: result = newQVariant(item.emoji) + of ModelRole.ColorHash: + result = newQVariant(item.colorHash) of ModelRole.Description: result = newQVariant(item.description) of ModelRole.Type: diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim index e8a6f74ab2..c917b79dd3 100644 --- a/src/app/modules/main/chat_section/module.nim +++ b/src/app/modules/main/chat_section/module.nim @@ -19,6 +19,7 @@ import ../../../../app_service/service/community/service as community_service import ../../../../app_service/service/message/service as message_service import ../../../../app_service/service/mailservers/service as mailservers_service import ../../../../app_service/service/gif/service as gif_service +import ../../../../app_service/service/visual_identity/service as visual_identity export io_interface @@ -112,6 +113,7 @@ proc buildChatUI(self: Module, events: EventEmitter, let notificationsCount = c.unviewedMentionsCount var chatName = c.name var chatImage = "" + var colorHash: ColorHashDto = @[] var isUsersListAvailable = true var blocked = false if(c.chatType == ChatType.OneToOne): @@ -120,12 +122,13 @@ proc buildChatUI(self: Module, events: EventEmitter, chatName = contactDetails.displayName chatImage = contactDetails.icon blocked = contactDetails.details.isBlocked() + colorHash = self.controller.getColorHash(c.id) let amIChatAdmin = self.amIMarkedAsAdminUser(c.members) let item = initItem(c.id, chatName, chatImage, c.color, c.emoji, c.description, c.chatType.int, amIChatAdmin, hasNotification, notificationsCount, c.muted, blocked, - active=false, c.position, c.categoryId) + active=false, c.position, c.categoryId, colorHash) self.view.chatsModel().appendItem(item) self.addSubmodule(c.id, false, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) @@ -395,10 +398,12 @@ method addNewChat*( let notificationsCount = chatDto.unviewedMentionsCount var chatName = chatDto.name var chatImage = chatDto.identicon + var colorHash: ColorHashDto = @[] var isUsersListAvailable = true if(chatDto.chatType == ChatType.OneToOne): isUsersListAvailable = false (chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(chatDto.id) + colorHash = self.controller.getColorHash(chatDto.id) var amIChatAdmin = false if(belongsToCommunity): amIChatAdmin = self.controller.getMyCommunity().admin @@ -408,7 +413,7 @@ method addNewChat*( if chatDto.categoryId.len == 0: let item = initItem(chatDto.id, chatName, chatImage, chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, notificationsCount, - chatDto.muted, blocked=false, active=false, position = 0, chatDto.categoryId, chatDto.highlight) + chatDto.muted, blocked=false, active=false, position = 0, chatDto.categoryId, colorHash, chatDto.highlight) self.addSubmodule(chatDto.id, belongsToCommunity, isUsersListAvailable, events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) self.chatContentModules[chatDto.id].load() diff --git a/ui/app/AppLayouts/Chat/views/ChatContentView.qml b/ui/app/AppLayouts/Chat/views/ChatContentView.qml index 32dc5c14e1..f5d70d90cf 100644 --- a/ui/app/AppLayouts/Chat/views/ChatContentView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatContentView.qml @@ -93,6 +93,8 @@ ColumnLayout { } } chatInfoButton.image.source: chatContentModule? chatContentModule.chatDetails.icon : "" + chatInfoButton.ringSettings.ringSpecModel: chatContentModule && chatContentModule.chatDetails.type === Constants.chatType.oneToOne ? + Utils.getColorHashAsJson(chatContentModule.chatDetails.id) : "" chatInfoButton.icon.color: chatContentModule? chatContentModule.chatDetails.color : "" chatInfoButton.icon.emoji: chatContentModule? chatContentModule.chatDetails.emoji : "" chatInfoButton.icon.emojiSize: "24x24" diff --git a/ui/app/AppLayouts/Onboarding/controls/AccountViewDelegate.qml b/ui/app/AppLayouts/Onboarding/controls/AccountViewDelegate.qml index aa4cc69edc..de6b2bb771 100644 --- a/ui/app/AppLayouts/Onboarding/controls/AccountViewDelegate.qml +++ b/ui/app/AppLayouts/Onboarding/controls/AccountViewDelegate.qml @@ -11,7 +11,7 @@ import StatusQ.Controls 0.1 as StatusQControls import StatusQ.Components 0.1 Rectangle { - id: accountViewDelegate + id: root property string username: "Jotaro Kujo" property string keyUid: "0x123345677890987654321123456" @@ -42,7 +42,9 @@ Rectangle { anchors.left: parent.left anchors.leftMargin: Style.current.padding anchors.verticalCenter: parent.verticalCenter - image.source: accountViewDelegate.image + name: root.username + image.source: root.image + icon.charactersLen: 2 } StyledText { @@ -76,7 +78,7 @@ Rectangle { anchors.right: parent.right anchors.rightMargin: Style.current.padding anchors.verticalCenter: parent.verticalCenter - checked: accountViewDelegate.selected + checked: root.selected } MouseArea { @@ -87,10 +89,10 @@ Rectangle { onAccountSelect(index) } onEntered: { - accountViewDelegate.isHovered = true + root.isHovered = true } onExited: { - accountViewDelegate.isHovered = false + root.isHovered = false } } } diff --git a/ui/app/AppLayouts/Onboarding/views/LoginView.qml b/ui/app/AppLayouts/Onboarding/views/LoginView.qml index 4c282346d1..9614c75ea9 100644 --- a/ui/app/AppLayouts/Onboarding/views/LoginView.qml +++ b/ui/app/AppLayouts/Onboarding/views/LoginView.qml @@ -91,7 +91,8 @@ Item { id: userImage anchors.horizontalCenter: parent.horizontalCenter image.source: LoginStore.currentAccount.thumbnailImage - + name: LoginStore.currentAccount.username + icon.charactersLen: 2 } StyledText { diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index 9dd6097dd5..f0503fa3ea 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -362,6 +362,9 @@ Item { name: appMain.rootStore.userProfileInst.name icon.source: appMain.rootStore.userProfileInst.icon + identicon.icon.charactersLen: 2 + identicon.ringSettings.ringSpecModel: Utils.getColorHashAsJson(appMain.rootStore.userProfileInst.pubKey) + badge.visible: true badge.anchors.rightMargin: 4 badge.anchors.topMargin: 25 diff --git a/ui/imports/shared/controls/chat/UserImage.qml b/ui/imports/shared/controls/chat/UserImage.qml index 2d32cdb824..037caf5444 100644 --- a/ui/imports/shared/controls/chat/UserImage.qml +++ b/ui/imports/shared/controls/chat/UserImage.qml @@ -35,12 +35,10 @@ Loader { height: root.imageHeight color: Style.current.background textColor: Style.current.secondaryText - letterSize: Math.max(4, root.imageWidth / 2.4) charactersLen: 2 } ringSettings { ringSpecModel: root.showRing ? Utils.getColorHashAsJson(root.pubkey) : undefined - ringPxSize: Math.max(root.imageWidth / 24.0) } Loader { diff --git a/ui/imports/shared/views/chat/ChannelIdentifierView.qml b/ui/imports/shared/views/chat/ChannelIdentifierView.qml index b9b893d25b..a41697f2b4 100644 --- a/ui/imports/shared/views/chat/ChannelIdentifierView.qml +++ b/ui/imports/shared/views/chat/ChannelIdentifierView.qml @@ -3,6 +3,8 @@ import shared 1.0 import shared.panels 1.0 import StatusQ.Core.Utils 0.1 as StatusQUtils +import StatusQ.Components 0.1 + import utils 1.0 Column { @@ -14,6 +16,7 @@ Column { property bool amIChatAdmin: false property string chatName: "" + property string chatId: "" property int chatType: -1 property string chatColor: "" property string chatEmoji: "" @@ -23,39 +26,22 @@ Column { signal joinChatClicked() signal rejectJoiningChatClicked() - Rectangle { - id: circleId + StatusSmartIdenticon { anchors.horizontalCenter: parent.horizontalCenter - width: 120 - height: 120 - radius: 120 - border.width: root.chatType === Constants.chatType.oneToOne ? 2 : 0 - border.color: Style.current.border - color: root.chatColor - - RoundedImage { - visible: root.chatType === Constants.chatType.oneToOne - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter + name: root.chatName + icon { + width: 120 + height: 120 + color: root.chatColor + emoji: root.chatEmoji + charactersLen: root.chatType === Constants.chatType.oneToOne ? 2 : 1 + } + image { width: 120 height: 120 source: root.chatIcon - smooth: false - antialiasing: true - } - - StyledText { - visible: root.chatType !== Constants.chatType.oneToOne - text: root.chatEmoji ? - StatusQUtils.Emoji.parse(root.chatEmoji, StatusQUtils.Emoji.size.veryBig) : - root.chatName.charAt(0).toUpperCase() - opacity: root.chatEmoji ? 1 : 0.7 - font.weight: Font.Bold - font.pixelSize: 51 - color: Style.current.white - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter } + ringSettings.ringSpecModel: root.chatType === Constants.chatType.oneToOne ? Utils.getColorHashAsJson(root.chatId) : undefined } StyledText { diff --git a/ui/imports/shared/views/chat/MessageView.qml b/ui/imports/shared/views/chat/MessageView.qml index 9a87a363c2..e1d1f542ef 100644 --- a/ui/imports/shared/views/chat/MessageView.qml +++ b/ui/imports/shared/views/chat/MessageView.qml @@ -288,6 +288,7 @@ Column { id: channelIdentifierComponent ChannelIdentifierView { chatName: root.senderDisplayName + chatId: root.messageStore.getChatId() chatType: root.messageStore.getChatType() chatColor: root.messageStore.getChatColor() chatEmoji: root.channelEmoji