From 17db2f4056f87e4b298abb3bd86b5f60b6a3920f Mon Sep 17 00:00:00 2001 From: Pascal Precht Date: Thu, 9 Jul 2020 13:46:25 +0200 Subject: [PATCH] feat(chat): show "@" when logged in user has been mentioned in channel Closes #516 --- src/app/chat/views/channels_list.nim | 12 ++++++---- src/app/chat/views/chat_item.nim | 5 ++++ src/signals/messages.nim | 23 +++++++++++++++---- src/status/chat/chat.nim | 1 + .../Chat/ContactsColumn/Channel.qml | 5 ++-- .../Chat/ContactsColumn/ChannelList.qml | 1 + 6 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/app/chat/views/channels_list.nim b/src/app/chat/views/channels_list.nim index f37942e76d..b25391f223 100644 --- a/src/app/chat/views/channels_list.nim +++ b/src/app/chat/views/channels_list.nim @@ -13,6 +13,7 @@ type Identicon = UserRole + 5 ChatType = UserRole + 6 Color = UserRole + 7 + HasMentions = UserRole + 8 QtObject: type @@ -52,6 +53,7 @@ QtObject: of ChannelsRoles.Identicon: result = newQVariant(chatItem.identicon) of ChannelsRoles.ChatType: result = newQVariant(chatItem.chatType.int) of ChannelsRoles.Color: result = newQVariant(chatItem.color) + of ChannelsRoles.HasMentions: result = newQVariant(chatItem.hasMentions) method roleNames(self: ChannelsList): Table[int, string] = { @@ -61,7 +63,8 @@ QtObject: ChannelsRoles.UnreadMessages.int: "unviewedMessagesCount", ChannelsRoles.Identicon.int: "identicon", ChannelsRoles.ChatType.int: "chatType", - ChannelsRoles.Color.int: "color" + ChannelsRoles.Color.int: "color", + ChannelsRoles.HasMentions.int: "hasMentions" }.toTable proc addChatItemToList*(self: ChannelsList, channel: Chat): int = @@ -109,7 +112,7 @@ QtObject: else: self.chats[0] = channel - self.dataChanged(topLeft, bottomRight, @[ChannelsRoles.Name.int, ChannelsRoles.LastMessage.int, ChannelsRoles.Timestamp.int, ChannelsRoles.UnreadMessages.int, ChannelsRoles.Identicon.int, ChannelsRoles.ChatType.int, ChannelsRoles.Color.int]) + self.dataChanged(topLeft, bottomRight, @[ChannelsRoles.Name.int, ChannelsRoles.LastMessage.int, ChannelsRoles.Timestamp.int, ChannelsRoles.UnreadMessages.int, ChannelsRoles.Identicon.int, ChannelsRoles.ChatType.int, ChannelsRoles.Color.int, ChannelsRoles.HasMentions.int]) proc clearUnreadMessagesCount*(self: ChannelsList, channel: var Chat) = let idx = self.chats.findIndexById(channel.id) @@ -118,9 +121,10 @@ QtObject: let topLeft = self.createIndex(0, 0, nil) let bottomRight = self.createIndex(self.chats.len, 0, nil) channel.unviewedMessagesCount = 0 + channel.hasMentions = false self.chats[idx] = channel - self.dataChanged(topLeft, bottomRight, @[ChannelsRoles.Name.int, ChannelsRoles.LastMessage.int, ChannelsRoles.Timestamp.int, ChannelsRoles.UnreadMessages.int, ChannelsRoles.Identicon.int, ChannelsRoles.ChatType.int, ChannelsRoles.Color.int]) + self.dataChanged(topLeft, bottomRight, @[ChannelsRoles.Name.int, ChannelsRoles.LastMessage.int, ChannelsRoles.Timestamp.int, ChannelsRoles.UnreadMessages.int, ChannelsRoles.Identicon.int, ChannelsRoles.ChatType.int, ChannelsRoles.Color.int, ChannelsRoles.HasMentions.int]) proc mention(self: ChannelsList, pubKey: string): string = if self.status.chat.contacts.hasKey(pubKey): @@ -140,4 +144,4 @@ QtObject: for children in pMsg.children: result = result & self.renderInline(children) else: - result = pMsg.literal \ No newline at end of file + result = pMsg.literal diff --git a/src/app/chat/views/chat_item.nim b/src/app/chat/views/chat_item.nim index 79db7f249b..79ea341228 100644 --- a/src/app/chat/views/chat_item.nim +++ b/src/app/chat/views/chat_item.nim @@ -60,6 +60,11 @@ QtObject: QtProperty[QVariant] members: read = getMembers + proc hasMentions*(self: ChatItemView): bool {.slot.} = result = ?.self.chatItem.hasMentions + + QtProperty[bool] hasMentions: + read = hasMentions + proc isMember*(self: ChatItemView, pubKey: string): bool {.slot.} = if self.chatItem.isNil: return false return self.chatItem.isMember(pubKey) diff --git a/src/signals/messages.nim b/src/signals/messages.nim index e9ec98bcfe..675d8193c7 100644 --- a/src/signals/messages.nim +++ b/src/signals/messages.nim @@ -1,5 +1,7 @@ -import json, random +import json, random, sequtils, sugar +import json_serialization import ../status/libstatus/accounts as status_accounts +import ../status/libstatus/settings as status_settings import ../status/chat/[chat, message] import ../status/profile/[profile, devices] import types @@ -13,17 +15,28 @@ proc fromEvent*(event: JsonNode): Signal = signal.messages = @[] signal.contacts = @[] + let pk = status_settings.getSetting[string]("public-key", "0x0") + if event["event"]{"contacts"} != nil: for jsonContact in event["event"]["contacts"]: signal.contacts.add(jsonContact.toProfileModel()) + var chatsWithMentions: seq[string] = @[] + if event["event"]{"messages"} != nil: for jsonMsg in event["event"]["messages"]: - signal.messages.add(jsonMsg.toMessage) + let message = jsonMsg.toMessage + let hasMentions = concat(message.parsedText.map(t => t.children.filter(c => c.textType == "mention" and c.literal == pk))).len > 0 + if hasMentions: + chatsWithMentions.add(message.chatId) + signal.messages.add(message) if event["event"]{"chats"} != nil: for jsonChat in event["event"]["chats"]: - signal.chats.add(jsonChat.toChat) + var chat = jsonChat.toChat + if chatsWithMentions.contains(chat.id): + chat.hasMentions = true + signal.chats.add(chat) if event["event"]{"installations"} != nil: for jsonInstallation in event["event"]["installations"]: @@ -71,7 +84,8 @@ proc newChat*(id: string, chatType: ChatType): Chat = timestamp: 0, lastClockValue: 0, deletedAtClockValue: 0, - unviewedMessagesCount: 0 + unviewedMessagesCount: 0, + hasMentions: false ) if chatType == ChatType.OneToOne: @@ -92,6 +106,7 @@ proc toChat*(jsonChat: JsonNode): Chat = lastClockValue: jsonChat{"lastClockValue"}.getBiggestInt, deletedAtClockValue: jsonChat{"deletedAtClockValue"}.getBiggestInt, unviewedMessagesCount: jsonChat{"unviewedMessagesCount"}.getInt, + hasMentions: false ) if jsonChat["lastMessage"].kind != JNull: diff --git a/src/status/chat/chat.nim b/src/status/chat/chat.nim index 7e23d67180..e87cd294ad 100644 --- a/src/status/chat/chat.nim +++ b/src/status/chat/chat.nim @@ -65,6 +65,7 @@ type Chat* = ref object lastMessage*: Message members*: seq[ChatMember] membershipUpdateEvents*: seq[ChatMembershipEvent] + hasMentions*: bool proc `$`*(self: Chat): string = result = fmt"Chat(id:{self.id}, name:{self.name}, active:{self.isActive}, type:{self.chatType})" diff --git a/ui/app/AppLayouts/Chat/ContactsColumn/Channel.qml b/ui/app/AppLayouts/Chat/ContactsColumn/Channel.qml index dbd542343c..74ab4a7973 100644 --- a/ui/app/AppLayouts/Chat/ContactsColumn/Channel.qml +++ b/ui/app/AppLayouts/Chat/ContactsColumn/Channel.qml @@ -9,6 +9,7 @@ Rectangle { property string lastMessage: "My latest message\n with a return" property string timestamp: "20/2/2020" property string unviewedMessagesCount: "2" + property bool hasMentions: false property int chatType: Constants.chatTypePublic property string searchStr: "" @@ -135,10 +136,10 @@ Rectangle { anchors.right: parent.right anchors.rightMargin: Style.current.padding color: Style.current.blue - visible: unviewedMessagesCount > 0 + visible: (unviewedMessagesCount > 0) || wrapper.hasMentions StyledText { id: contactNumberChats - text: wrapper.unviewedMessagesCount < 100 ? wrapper.unviewedMessagesCount : "99" + text: wrapper.hasMentions ? '@' : (wrapper.unviewedMessagesCount < 100 ? wrapper.unviewedMessagesCount : "99") font.pixelSize: 12 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter diff --git a/ui/app/AppLayouts/Chat/ContactsColumn/ChannelList.qml b/ui/app/AppLayouts/Chat/ContactsColumn/ChannelList.qml index 6f2d352f15..dc237247e5 100644 --- a/ui/app/AppLayouts/Chat/ContactsColumn/ChannelList.qml +++ b/ui/app/AppLayouts/Chat/ContactsColumn/ChannelList.qml @@ -27,6 +27,7 @@ Item { timestamp: model.timestamp chatType: model.chatType unviewedMessagesCount: model.unviewedMessagesCount + hasMentions: model.hasMentions searchStr: chatGroupsContainer.searchStr } onCountChanged: {