diff --git a/src/app/chat/view.nim b/src/app/chat/view.nim index d0e4309a4d..f70956f1f9 100644 --- a/src/app/chat/view.nim +++ b/src/app/chat/view.nim @@ -330,6 +330,8 @@ QtObject: proc sendingMessageFailed*(self: ChatsView) {.signal.} proc alias*(self: ChatsView, pubKey: string): string {.slot.} = + if (pubKey == ""): + return "" generateAlias(pubKey) proc userNameOrAlias*(self: ChatsView, pubKey: string): string {.slot.} = @@ -464,12 +466,17 @@ QtObject: proc isAddedContact*(self: ChatsView, id: string): bool {.slot.} = result = self.status.contacts.isAdded(id) - proc pushPinnedMessages*(self:ChatsView, messages: var seq[Message]) = - for msg in messages.mitems: + proc pushPinnedMessages*(self:ChatsView, pinnedMessages: var seq[Message]) = + for msg in pinnedMessages.mitems: self.upsertChannel(msg.chatId) - self.pinnedMessagesList[msg.chatId].add(msg) + + var message = self.messageList[msg.chatId].getMessageById(msg.id) + message.pinnedBy = msg.pinnedBy + message.isPinned = true + + self.pinnedMessagesList[msg.chatId].add(message) # put the message as pinned in the message list - self.messageList[msg.chatId].changeMessagePinned(msg.id, true) + self.messageList[msg.chatId].changeMessagePinned(msg.id, true, msg.pinnedBy) proc pushMessages*(self:ChatsView, messages: var seq[Message]) = for msg in messages.mitems: @@ -628,7 +635,7 @@ QtObject: self.status.chat.chatReactions(rpcResponseObj["chatId"].getStr, true, reactions[0], reactions[1]) if(rpcResponseObj["pinnedMessages"].kind != JNull): - let pinnedMessages = parseChatMessagesResponse(rpcResponseObj["chatId"].getStr, rpcResponseObj["pinnedMessages"]) + let pinnedMessages = parseChatMessagesResponse(rpcResponseObj["chatId"].getStr, rpcResponseObj["pinnedMessages"], true) self.status.chat.pinnedMessagesByChatID(rpcResponseObj["chatId"].getStr, pinnedMessages[0], pinnedMessages[1]) proc hideLoadingIndicator*(self: ChatsView) {.slot.} = @@ -867,14 +874,16 @@ QtObject: if(id == msg.id): return idx return idx - proc addPinMessage*(self: ChatsView, messageId: string, chatId: string) = + proc addPinMessage*(self: ChatsView, messageId: string, chatId: string, pinnedBy: string) = self.upsertChannel(chatId) - self.messageList[chatId].changeMessagePinned(messageId, true) - self.pinnedMessagesList[chatId].add(self.messageList[chatId].getMessageById(messageId)) + self.messageList[chatId].changeMessagePinned(messageId, true, pinnedBy) + var message = self.messageList[chatId].getMessageById(messageId) + message.pinnedBy = pinnedBy + self.pinnedMessagesList[chatId].add(message) proc removePinMessage*(self: ChatsView, messageId: string, chatId: string) = self.upsertChannel(chatId) - self.messageList[chatId].changeMessagePinned(messageId, false) + self.messageList[chatId].changeMessagePinned(messageId, false, "") try: self.pinnedMessagesList[chatId].remove(messageId) except Exception as e: @@ -883,7 +892,7 @@ QtObject: proc pinMessage*(self: ChatsView, messageId: string, chatId: string) {.slot.} = self.status.chat.setPinMessage(messageId, chatId, true) - self.addPinMessage(messageId, chatId) + self.addPinMessage(messageId, chatId, self.pubKey) proc unPinMessage*(self: ChatsView, messageId: string, chatId: string) {.slot.} = self.status.chat.setPinMessage(messageId, chatId, false) @@ -892,7 +901,7 @@ QtObject: proc addPinnedMessages*(self: ChatsView, pinnedMessages: seq[Message]) = for pinnedMessage in pinnedMessages: if (pinnedMessage.isPinned): - self.addPinMessage(pinnedMessage.id, pinnedMessage.localChatId) + self.addPinMessage(pinnedMessage.id, pinnedMessage.localChatId, pinnedMessage.pinnedBy) else: self.removePinMessage(pinnedMessage.id, pinnedMessage.localChatId) diff --git a/src/app/chat/views/message_list.nim b/src/app/chat/views/message_list.nim index 0b5cc65883..282b8d74a6 100644 --- a/src/app/chat/views/message_list.nim +++ b/src/app/chat/views/message_list.nim @@ -38,8 +38,9 @@ type HasMention = UserRole + 28 StickerPackId = UserRole + 29 IsPinned = UserRole + 30 - GapFrom = UserRole + 31 - GapTo = UserRole + 32 + PinnedBy = UserRole + 31 + GapFrom = UserRole + 32 + GapTo = UserRole + 33 QtObject: type @@ -172,6 +173,7 @@ QtObject: of ChatMessageRoles.CommunityId: result = newQVariant(message.communityId) of ChatMessageRoles.HasMention: result = newQVariant(message.hasMention) of ChatMessageRoles.IsPinned: result = newQVariant(message.isPinned) + of ChatMessageRoles.PinnedBy: result = newQVariant(message.pinnedBy) # Pass the command parameters as a JSON string of ChatMessageRoles.CommandParameters: result = newQVariant($(%*{ "id": message.commandParameters.id, @@ -217,6 +219,7 @@ QtObject: ChatMessageRoles.Alias.int:"alias", ChatMessageRoles.HasMention.int:"hasMention", ChatMessageRoles.IsPinned.int:"isPinned", + ChatMessageRoles.PinnedBy.int:"pinnedBy", ChatMessageRoles.LocalName.int:"localName", ChatMessageRoles.StickerPackId.int:"stickerPackId", ChatMessageRoles.GapFrom.int:"gapFrom", @@ -293,15 +296,16 @@ QtObject: let bottomRight = self.createIndex(msgIdx, 0, nil) self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.EmojiReactions.int]) - proc changeMessagePinned*(self: ChatMessageList, messageId: string, pinned: bool) = + proc changeMessagePinned*(self: ChatMessageList, messageId: string, pinned: bool, pinnedBy: string) = if not self.messageIndex.hasKey(messageId): return let msgIdx = self.messageIndex[messageId] var message = self.messages[msgIdx] message.isPinned = pinned + message.pinnedBy = pinnedBy self.messages[msgIdx] = message let topLeft = self.createIndex(msgIdx, 0, nil) let bottomRight = self.createIndex(msgIdx, 0, nil) - self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.IsPinned.int]) + self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.IsPinned.int, ChatMessageRoles.PinnedBy.int]) proc markMessageAsSent*(self: ChatMessageList, messageId: string)= let topLeft = self.createIndex(0, 0, nil) diff --git a/src/status/chat/message.nim b/src/status/chat/message.nim index bd6261bf46..68775439af 100644 --- a/src/status/chat/message.nim +++ b/src/status/chat/message.nim @@ -69,6 +69,7 @@ type Message* = object audioDurationMs*: int hasMention*: bool isPinned*: bool + pinnedBy*: string type Reaction* = object id*: string diff --git a/src/status/libstatus/chat.nim b/src/status/libstatus/chat.nim index 423e898657..0d1a3b5431 100644 --- a/src/status/libstatus/chat.nim +++ b/src/status/libstatus/chat.nim @@ -73,13 +73,13 @@ proc loadChats*(): seq[Chat] = result.add(chat) result.sort(sortChats) -proc parseChatMessagesResponse*(chatId: string, rpcResult: JsonNode): (string, seq[Message]) = +proc parseChatMessagesResponse*(chatId: string, rpcResult: JsonNode, isPin: bool = false): (string, seq[Message]) = let pk = status_settings.getSetting[string](Setting.PublicKey, "0x0") var messages: seq[Message] = @[] var msg: Message if rpcResult["messages"].kind != JNull: for jsonMsg in rpcResult["messages"]: - messages.add(jsonMsg.toMessage(pk)) + messages.add(jsonMsg.toMessage(pk, isPin)) return (rpcResult{"cursor"}.getStr, messages) proc rpcChatMessages*(chatId: string, cursorVal: JsonNode, limit: int, success: var bool): string = @@ -474,7 +474,7 @@ proc pinnedMessagesByChatID*(chatId: string, cursor: string): (string, seq[Messa var success: bool let callResult = rpcPinnedChatMessages(chatId, cursorVal, 20, success) if success: - result = parseChatMessagesResponse(chatId, callResult.parseJson()["result"]) + result = parseChatMessagesResponse(chatId, callResult.parseJson()["result"], true) proc setPinMessage*(messageId: string, chatId: string, pinned: bool) = discard callPrivateRPC("sendPinMessage".prefix, %*[{ diff --git a/src/status/signals/messages.nim b/src/status/signals/messages.nim index 16fe9051c4..8acc82bdc3 100644 --- a/src/status/signals/messages.nim +++ b/src/status/signals/messages.nim @@ -13,7 +13,7 @@ import types import web3/conversions from ../libstatus/utils import parseAddress, wei2Eth -proc toMessage*(jsonMsg: JsonNode, pk: string): Message +proc toMessage*(jsonMsg: JsonNode, pk: string, isPin: bool = false): Message proc toChat*(jsonChat: JsonNode): Chat @@ -78,7 +78,7 @@ proc fromEvent*(event: JsonNode): Signal = id: jsonPinnedMessage{"message_id"}.getStr, chatId: jsonPinnedMessage{"chat_id"}.getStr, localChatId: jsonPinnedMessage{"localChatId"}.getStr, - fromAuthor: jsonPinnedMessage{"from"}.getStr, + pinnedBy: jsonPinnedMessage{"from"}.getStr, identicon: jsonPinnedMessage{"identicon"}.getStr, alias: jsonPinnedMessage{"alias"}.getStr, clock: jsonPinnedMessage{"clock"}.getInt, @@ -267,7 +267,7 @@ proc toTextItem*(jsonText: JsonNode): TextItem = result.children.add(child.toTextItem) -proc toMessage*(jsonMsg: JsonNode, pk: string): Message = +proc toMessage*(jsonMsg: JsonNode, pk: string, isPin: bool = false): Message = var contentType: ContentType try: contentType = ContentType(jsonMsg{"contentType"}.getInt) @@ -309,6 +309,10 @@ proc toMessage*(jsonMsg: JsonNode, pk: string): Message = hasMention: false ) + if isPin: + message.pinnedBy = message.fromAuthor + message.fromAuthor = "" + if contentType == ContentType.Gap: message.gapFrom = jsonMsg["gapParameters"]["from"].getInt message.gapTo = jsonMsg["gapParameters"]["to"].getInt diff --git a/ui/app/AppLayouts/Chat/ChatColumn.qml b/ui/app/AppLayouts/Chat/ChatColumn.qml index edf1df1dc0..8ee8079ac9 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn.qml @@ -14,6 +14,8 @@ import "../Wallet" StackLayout { id: chatColumnLayout + property alias pinnedMessagesPopupComponent: pinnedMessagesPopupComponent + property int chatGroupsListViewCount: 0 property bool isReply: false @@ -35,6 +37,25 @@ StackLayout { property alias input: chatInput + property string hoveredMessage + property string activeMessage + + function setHovered(messageId, hovered) { + if (hovered) { + hoveredMessage = messageId + } else if (hoveredMessage === messageId) { + hoveredMessage = "" + } + } + + function setMessageActive(messageId, active) { + if (active) { + activeMessage = messageId + } else if (activeMessage === messageId) { + activeMessage = "" + } + } + Component.onCompleted: { chatInput.textInput.forceActiveFocus(Qt.MouseFocusReason) } @@ -45,6 +66,21 @@ StackLayout { currentIndex: chatsModel.activeChannelIndex > -1 && chatGroupsListViewCount > 0 ? 0 : 1 + Component { + id: pinnedMessagesPopupComponent + PinnedMessagesPopup { + id: pinnedMessagesPopup + onClosed: destroy() + } + } + + StatusImageModal { + id: imagePopup + } + + MessageContextMenu { + id: messageContextMenu + } property var idMap: ({}) property var suggestionsObj: ([]) @@ -263,18 +299,10 @@ StackLayout { } } - StatusImageModal { - id: imagePopup - } - EmojiReactions { id: reactionModel } - MessageContextMenu { - id: messageContextMenu - } - Connections { target: chatsModel onActiveChannelChanged: { diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatMessages.qml b/ui/app/AppLayouts/Chat/ChatColumn/ChatMessages.qml index 4abcce6c91..7b07741bd0 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatMessages.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/ChatMessages.qml @@ -22,25 +22,6 @@ ScrollView { property real scrollY: chatLogView.visibleArea.yPosition * chatLogView.contentHeight property int newMessages: 0 - property string hoveredMessage - property string activeMessage - - function setHovered(messageId, hovered) { - if (hovered) { - hoveredMessage = messageId - } else if (hoveredMessage === messageId) { - hoveredMessage = "" - } - } - - function setMessageActive(messageId, active) { - if (active) { - activeMessage = messageId - } else if (activeMessage === messageId) { - activeMessage = "" - } - } - contentItem: chatLogView Layout.fillWidth: true Layout.fillHeight: true @@ -336,6 +317,7 @@ ScrollView { hasMention: model.hasMention stickerPackId: model.stickerPackId pinnedMessage: model.isPinned + pinnedBy: model.pinnedBy gapFrom: model.gapFrom gapTo: model.gapTo prevMessageIndex: { diff --git a/ui/app/AppLayouts/Chat/ChatColumn/Message.qml b/ui/app/AppLayouts/Chat/ChatColumn/Message.qml index 4776bcd734..d375d50a2b 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/Message.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/Message.qml @@ -30,12 +30,21 @@ Item { property string linkUrls: "" property bool placeholderMessage: false property bool pinnedMessage: false + property string pinnedBy property bool forceHoverHandler: false // Used to force the HoverHandler to be active (useful for messages in popups) property string communityId: "" property int stickerPackId: -1 property int gapFrom: 0 property int gapTo: 0 + z: { + if (typeof chatLogView === "undefined") { + return 1 + } + + return chatLogView.count - index + } + property string displayUserName: { if (isCurrentUser) { //% "You" diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatButtons.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatButtons.qml index 81912d852e..433f4bbde6 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatButtons.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatButtons.qml @@ -11,7 +11,7 @@ Rectangle { property int contentType: 2 id: buttonsContainer - visible: (buttonsContainer.parentIsHovered || isMessageActive) && contentType != Constants.transactionType + visible: (buttonsContainer.parentIsHovered || isMessageActive) && contentType !== Constants.transactionType width: buttonRow.width + buttonsContainer.containerMargin * 2 height: 36 radius: Style.current.radius @@ -61,10 +61,12 @@ Rectangle { onClicked: { setMessageActive(messageId, true) clickMessage(false, false, false, null, true) - messageContextMenu.x = buttonsContainer.x + buttonsContainer.width - messageContextMenu.width + if (!forceHoverHandler) { + messageContextMenu.x = buttonsContainer.x + buttonsContainer.width - messageContextMenu.width - // The Math.max is to make sure that the menu is rendered - messageContextMenu.y -= Math.max(messageContextMenu.emojiContainer.height, 56) + Style.current.padding + // The Math.max is to make sure that the menu is rendered + messageContextMenu.y -= Math.max(messageContextMenu.emojiContainer.height, 56) + Style.current.padding + } } onHoveredChanged: { buttonsContainer.hoverChanged(this.hovered) @@ -104,7 +106,7 @@ Rectangle { height: 32 onClicked: { if (typeof isMessageActive !== "undefined") { - isMessageActive = true + setMessageActive(messageId, true) } clickMessage(false, isSticker, false, null, false, true) } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml index 096898e707..bc0b0a45b5 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml @@ -99,6 +99,8 @@ Item { source: "../../../../img/pin.svg" anchors.left: parent.left anchors.leftMargin: 3 + width: 16 + height: 16 anchors.verticalCenter: parent.verticalCenter ColorOverlay { @@ -109,7 +111,7 @@ Item { } StyledText { - text: qsTr("Pinned") + text: qsTr("Pinned by %1").arg(chatsModel.alias(pinnedBy)) anchors.left: pinImage.right anchors.verticalCenter: parent.verticalCenter font.pixelSize: 13 diff --git a/ui/app/AppLayouts/Chat/ChatColumn/TopBar.qml b/ui/app/AppLayouts/Chat/ChatColumn/TopBar.qml index 342a4c6074..a2c5034832 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/TopBar.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/TopBar.qml @@ -64,9 +64,6 @@ Item { } } - PinnedMessagesPopup { - id: pinnedMessagesPopup - } StatusContextMenuButton { id: moreActionsBtn anchors.verticalCenter: parent.verticalCenter diff --git a/ui/app/AppLayouts/Chat/ChatLayout.qml b/ui/app/AppLayouts/Chat/ChatLayout.qml index 4743e90557..2c326cad54 100644 --- a/ui/app/AppLayouts/Chat/ChatLayout.qml +++ b/ui/app/AppLayouts/Chat/ChatLayout.qml @@ -46,7 +46,9 @@ SplitView { Component { id: groupInfoPopupComponent - GroupInfoPopup {} + GroupInfoPopup { + pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent + } } ChatColumn { diff --git a/ui/app/AppLayouts/Chat/components/GroupInfoPopup.qml b/ui/app/AppLayouts/Chat/components/GroupInfoPopup.qml index 06dba84c69..9dd3c186b9 100644 --- a/ui/app/AppLayouts/Chat/components/GroupInfoPopup.qml +++ b/ui/app/AppLayouts/Chat/components/GroupInfoPopup.qml @@ -15,6 +15,7 @@ ModalPopup { property var pubKeys: [] property var channel property bool isAdmin: false + property Component pinnedMessagesPopupComponent function resetSelectedMembers(){ pubKeys = []; @@ -98,7 +99,7 @@ ModalPopup { anchors.top: groupName.bottom anchors.topMargin: 2 font.pixelSize: 14 - color: Style.current.darkGrey + color: Style.current.secondaryText } Rectangle { @@ -107,7 +108,7 @@ ModalPopup { height: 24 width: 24 anchors.verticalCenter: groupName.verticalCenter - anchors.leftMargin: 4 + anchors.leftMargin: Style.current.halfPadding anchors.left: groupName.right radius: 8 @@ -199,16 +200,44 @@ ModalPopup { anchors.rightMargin: -Style.current.padding } + StatusSettingsLineButton { + property int pinnedCount: chatsModel.pinnedMessagesList.count + + id: pinnedMessagesBtn + visible: pinnedCount > 0 + height: visible ? implicitHeight : 0 + text: qsTr("Pinned messages") + currentValue: pinnedCount + anchors.top: separator.bottom + anchors.topMargin: visible ? Style.current.halfPadding : 0 + anchors.leftMargin: 0 + anchors.rightMargin: 0 + onClicked: openPopup(pinnedMessagesPopupComponent) + iconSource: "../../../img/pin.svg" + } + + Separator { + id: separator2 + visible: pinnedMessagesBtn.visible + anchors.left: parent.left + anchors.leftMargin: -Style.current.padding + anchors.right: parent.right + anchors.rightMargin: -Style.current.padding + anchors.top: pinnedMessagesBtn.bottom + anchors.topMargin: visible ? Style.current.halfPadding : 0 + } + ListView { id: memberList - anchors.fill: parent - anchors.top: separator.bottom + anchors.top: separator2.bottom anchors.bottom: popup.bottom - anchors.topMargin: addMembers ? 30 : 15 + anchors.topMargin: addMembers ? 30 : Style.current.padding anchors.bottomMargin: Style.current.padding - anchors.leftMargin: 15 - anchors.rightMargin: 15 - spacing: 15 + anchors.left: parent.left + anchors.leftMargin: Style.current.padding + anchors.right: parent.right + anchors.rightMargin: Style.current.padding + spacing: Style.current.padding Layout.fillWidth: true Layout.fillHeight: true model: popup.channel.members diff --git a/ui/app/AppLayouts/Chat/components/MessageContextMenu.qml b/ui/app/AppLayouts/Chat/components/MessageContextMenu.qml index 72f1245d67..d3c995693b 100644 --- a/ui/app/AppLayouts/Chat/components/MessageContextMenu.qml +++ b/ui/app/AppLayouts/Chat/components/MessageContextMenu.qml @@ -134,7 +134,7 @@ PopupMenu { Separator { anchors.bottom: viewProfileAction.top - visible: !messageContextMenu.emojiOnly + visible: !messageContextMenu.emojiOnly && !messageContextMenu.hideEmojiPicker } Action { @@ -153,7 +153,17 @@ PopupMenu { icon.source: "../../../img/pin" icon.width: 16 icon.height: 16 - enabled: chatsModel.activeChannel.chatType !== Constants.chatTypePublic + enabled: { + switch (chatsModel.activeChannel.chatType) { + case Constants.chatTypePublic: return false + case Constants.chatTypeStatusUpdate: return false + case Constants.chatTypeOneToOne: return true + case Constants.chatTypePrivateGroupChat: return chatsModel.activeChannel.isAdmin(profileModel.profile.pubKey) + case Constants.chatTypeCommunity: return chatsModel.communities.activeCommunity.admin + } + + return false + } } Action { diff --git a/ui/app/AppLayouts/Chat/components/PinnedMessagesPopup.qml b/ui/app/AppLayouts/Chat/components/PinnedMessagesPopup.qml index 46389020ff..aaac0961d0 100644 --- a/ui/app/AppLayouts/Chat/components/PinnedMessagesPopup.qml +++ b/ui/app/AppLayouts/Chat/components/PinnedMessagesPopup.qml @@ -21,8 +21,11 @@ ModalPopup { } StyledText { + property int nbMessages: pinnedMessageListView.count + id: nbPinnedMessages - text: qsTr("%1 message").arg(pinnedMessageListView.count) + text: nbMessages > 1 ? qsTr("%1 messages").arg(nbMessages) : + qsTr("%1 message").arg(nbMessages) anchors.left: parent.left anchors.top: title.bottom anchors.topMargin: 2 @@ -40,44 +43,60 @@ ModalPopup { } } - ListView { - id: pinnedMessageListView - model: chatsModel.pinnedMessagesList - height: parent.height - anchors.left: parent.left - anchors.leftMargin: -Style.current.padding - anchors.right: parent.right - anchors.rightMargin: -Style.current.padding - clip: true + Item { + anchors.fill: parent - delegate: Message { - fromAuthor: model.fromAuthor - chatId: model.chatId - userName: model.userName - alias: model.alias - localName: model.localName - message: model.message - plainText: model.plainText - identicon: model.identicon - isCurrentUser: model.isCurrentUser - timestamp: model.timestamp - sticker: model.sticker - contentType: model.contentType - outgoingStatus: model.outgoingStatus - responseTo: model.responseTo - imageClick: imagePopup.openPopup.bind(imagePopup) - messageId: model.messageId - emojiReactions: model.emojiReactions - linkUrls: model.linkUrls - communityId: model.communityId - hasMention: model.hasMention - stickerPackId: model.stickerPackId - timeout: model.timeout - pinnedMessage: true - forceHoverHandler: true + StyledText { + visible: pinnedMessageListView.count === 0 + text: qsTr("Pinned messages will appear here.") + anchors.centerIn: parent + color: Style.current.secondaryText + } + + ListView { + id: pinnedMessageListView + model: chatsModel.pinnedMessagesList + height: parent.height + anchors.left: parent.left + anchors.leftMargin: -Style.current.padding + anchors.right: parent.right + anchors.rightMargin: -Style.current.padding + topMargin: Style.current.halfPadding + anchors.top: parent.top + anchors.topMargin: -Style.current.halfPadding + clip: true + + delegate: Message { + fromAuthor: model.fromAuthor + chatId: model.chatId + userName: model.userName + alias: model.alias + localName: model.localName + message: model.message + plainText: model.plainText + identicon: model.identicon + isCurrentUser: model.isCurrentUser + timestamp: model.timestamp + sticker: model.sticker + contentType: model.contentType + outgoingStatus: model.outgoingStatus + responseTo: model.responseTo + imageClick: imagePopup.openPopup.bind(imagePopup) + messageId: model.messageId + emojiReactions: model.emojiReactions + linkUrls: model.linkUrls + communityId: model.communityId + hasMention: model.hasMention + stickerPackId: model.stickerPackId + timeout: model.timeout + pinnedMessage: true + pinnedBy: model.pinnedBy + forceHoverHandler: true + } } } + footer: StatusRoundButton { id: btnBack anchors.left: parent.left diff --git a/ui/imports/Themes/LightTheme.qml b/ui/imports/Themes/LightTheme.qml index b5c93ade8d..c71fbf0640 100644 --- a/ui/imports/Themes/LightTheme.qml +++ b/ui/imports/Themes/LightTheme.qml @@ -93,7 +93,7 @@ Theme { property color pinnedMessageBorder: "#FE8F59" property color pinnedMessageBackground: "#1aFF9F0F" property color pinnedMessageBackgroundHovered: "#33FF9F0F" - property color pinnedRectangleBackground: "#1affffff" + property color pinnedRectangleBackground: "#1aFE8F59" property color roundedButtonForegroundColor: buttonForegroundColor property color roundedButtonBackgroundColor: secondaryBackground diff --git a/ui/shared/status/StatusChatInfo.qml b/ui/shared/status/StatusChatInfo.qml index 5304f6aa5d..0be7cb504e 100644 --- a/ui/shared/status/StatusChatInfo.qml +++ b/ui/shared/status/StatusChatInfo.qml @@ -187,7 +187,7 @@ Item { hoverEnabled: true onEntered: pinnedMessagesGroup.hovered = true onExited: pinnedMessagesGroup.hovered = false - onClicked: pinnedMessagesPopup.open() + onClicked: openPopup(pinnedMessagesPopupComponent) } } } diff --git a/ui/shared/status/StatusSettingsLineButton.qml b/ui/shared/status/StatusSettingsLineButton.qml index 0a8687532d..060b77771e 100644 --- a/ui/shared/status/StatusSettingsLineButton.qml +++ b/ui/shared/status/StatusSettingsLineButton.qml @@ -15,9 +15,10 @@ Rectangle { signal clicked(bool checked) property bool isHovered: false property int badgeSize: 18 + property url iconSource id: root - height: 52 + implicitHeight: 52 color: isHovered ? Style.current.backgroundHover : Style.current.transparent radius: Style.current.radius border.width: 0 @@ -26,9 +27,24 @@ Rectangle { anchors.right: parent.right anchors.rightMargin: -Style.current.padding + RoundedIcon { + id: pinImage + visible: !!root.iconSource.toString() + source: root.iconSource + iconColor: Style.current.primary + color: Style.current.secondaryBackground + width: 40 + height: 40 + iconWidth: 24 + iconHeight: 24 + anchors.left: parent.left + anchors.leftMargin: Style.current.padding + anchors.verticalCenter: parent.verticalCenter + } + StyledText { id: textItem - anchors.left: parent.left + anchors.left: pinImage.visible ? pinImage.right : parent.left anchors.leftMargin: Style.current.padding anchors.verticalCenter: parent.verticalCenter text: root.text