feat(chat): show "@" when logged in user has been mentioned in channel

Closes #516
This commit is contained in:
Pascal Precht 2020-07-09 13:46:25 +02:00 committed by Iuri Matias
parent abb9a25f53
commit 17db2f4056
6 changed files with 37 additions and 10 deletions

View File

@ -13,6 +13,7 @@ type
Identicon = UserRole + 5 Identicon = UserRole + 5
ChatType = UserRole + 6 ChatType = UserRole + 6
Color = UserRole + 7 Color = UserRole + 7
HasMentions = UserRole + 8
QtObject: QtObject:
type type
@ -52,6 +53,7 @@ QtObject:
of ChannelsRoles.Identicon: result = newQVariant(chatItem.identicon) of ChannelsRoles.Identicon: result = newQVariant(chatItem.identicon)
of ChannelsRoles.ChatType: result = newQVariant(chatItem.chatType.int) of ChannelsRoles.ChatType: result = newQVariant(chatItem.chatType.int)
of ChannelsRoles.Color: result = newQVariant(chatItem.color) of ChannelsRoles.Color: result = newQVariant(chatItem.color)
of ChannelsRoles.HasMentions: result = newQVariant(chatItem.hasMentions)
method roleNames(self: ChannelsList): Table[int, string] = method roleNames(self: ChannelsList): Table[int, string] =
{ {
@ -61,7 +63,8 @@ QtObject:
ChannelsRoles.UnreadMessages.int: "unviewedMessagesCount", ChannelsRoles.UnreadMessages.int: "unviewedMessagesCount",
ChannelsRoles.Identicon.int: "identicon", ChannelsRoles.Identicon.int: "identicon",
ChannelsRoles.ChatType.int: "chatType", ChannelsRoles.ChatType.int: "chatType",
ChannelsRoles.Color.int: "color" ChannelsRoles.Color.int: "color",
ChannelsRoles.HasMentions.int: "hasMentions"
}.toTable }.toTable
proc addChatItemToList*(self: ChannelsList, channel: Chat): int = proc addChatItemToList*(self: ChannelsList, channel: Chat): int =
@ -109,7 +112,7 @@ QtObject:
else: else:
self.chats[0] = channel 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) = proc clearUnreadMessagesCount*(self: ChannelsList, channel: var Chat) =
let idx = self.chats.findIndexById(channel.id) let idx = self.chats.findIndexById(channel.id)
@ -118,9 +121,10 @@ QtObject:
let topLeft = self.createIndex(0, 0, nil) let topLeft = self.createIndex(0, 0, nil)
let bottomRight = self.createIndex(self.chats.len, 0, nil) let bottomRight = self.createIndex(self.chats.len, 0, nil)
channel.unviewedMessagesCount = 0 channel.unviewedMessagesCount = 0
channel.hasMentions = false
self.chats[idx] = channel 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 = proc mention(self: ChannelsList, pubKey: string): string =
if self.status.chat.contacts.hasKey(pubKey): if self.status.chat.contacts.hasKey(pubKey):

View File

@ -60,6 +60,11 @@ QtObject:
QtProperty[QVariant] members: QtProperty[QVariant] members:
read = getMembers 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.} = proc isMember*(self: ChatItemView, pubKey: string): bool {.slot.} =
if self.chatItem.isNil: return false if self.chatItem.isNil: return false
return self.chatItem.isMember(pubKey) return self.chatItem.isMember(pubKey)

View File

@ -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/accounts as status_accounts
import ../status/libstatus/settings as status_settings
import ../status/chat/[chat, message] import ../status/chat/[chat, message]
import ../status/profile/[profile, devices] import ../status/profile/[profile, devices]
import types import types
@ -13,17 +15,28 @@ proc fromEvent*(event: JsonNode): Signal =
signal.messages = @[] signal.messages = @[]
signal.contacts = @[] signal.contacts = @[]
let pk = status_settings.getSetting[string]("public-key", "0x0")
if event["event"]{"contacts"} != nil: if event["event"]{"contacts"} != nil:
for jsonContact in event["event"]["contacts"]: for jsonContact in event["event"]["contacts"]:
signal.contacts.add(jsonContact.toProfileModel()) signal.contacts.add(jsonContact.toProfileModel())
var chatsWithMentions: seq[string] = @[]
if event["event"]{"messages"} != nil: if event["event"]{"messages"} != nil:
for jsonMsg in event["event"]["messages"]: 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: if event["event"]{"chats"} != nil:
for jsonChat in event["event"]["chats"]: 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: if event["event"]{"installations"} != nil:
for jsonInstallation in event["event"]["installations"]: for jsonInstallation in event["event"]["installations"]:
@ -71,7 +84,8 @@ proc newChat*(id: string, chatType: ChatType): Chat =
timestamp: 0, timestamp: 0,
lastClockValue: 0, lastClockValue: 0,
deletedAtClockValue: 0, deletedAtClockValue: 0,
unviewedMessagesCount: 0 unviewedMessagesCount: 0,
hasMentions: false
) )
if chatType == ChatType.OneToOne: if chatType == ChatType.OneToOne:
@ -92,6 +106,7 @@ proc toChat*(jsonChat: JsonNode): Chat =
lastClockValue: jsonChat{"lastClockValue"}.getBiggestInt, lastClockValue: jsonChat{"lastClockValue"}.getBiggestInt,
deletedAtClockValue: jsonChat{"deletedAtClockValue"}.getBiggestInt, deletedAtClockValue: jsonChat{"deletedAtClockValue"}.getBiggestInt,
unviewedMessagesCount: jsonChat{"unviewedMessagesCount"}.getInt, unviewedMessagesCount: jsonChat{"unviewedMessagesCount"}.getInt,
hasMentions: false
) )
if jsonChat["lastMessage"].kind != JNull: if jsonChat["lastMessage"].kind != JNull:

View File

@ -65,6 +65,7 @@ type Chat* = ref object
lastMessage*: Message lastMessage*: Message
members*: seq[ChatMember] members*: seq[ChatMember]
membershipUpdateEvents*: seq[ChatMembershipEvent] membershipUpdateEvents*: seq[ChatMembershipEvent]
hasMentions*: bool
proc `$`*(self: Chat): string = proc `$`*(self: Chat): string =
result = fmt"Chat(id:{self.id}, name:{self.name}, active:{self.isActive}, type:{self.chatType})" result = fmt"Chat(id:{self.id}, name:{self.name}, active:{self.isActive}, type:{self.chatType})"

View File

@ -9,6 +9,7 @@ Rectangle {
property string lastMessage: "My latest message\n with a return" property string lastMessage: "My latest message\n with a return"
property string timestamp: "20/2/2020" property string timestamp: "20/2/2020"
property string unviewedMessagesCount: "2" property string unviewedMessagesCount: "2"
property bool hasMentions: false
property int chatType: Constants.chatTypePublic property int chatType: Constants.chatTypePublic
property string searchStr: "" property string searchStr: ""
@ -135,10 +136,10 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Style.current.padding anchors.rightMargin: Style.current.padding
color: Style.current.blue color: Style.current.blue
visible: unviewedMessagesCount > 0 visible: (unviewedMessagesCount > 0) || wrapper.hasMentions
StyledText { StyledText {
id: contactNumberChats id: contactNumberChats
text: wrapper.unviewedMessagesCount < 100 ? wrapper.unviewedMessagesCount : "99" text: wrapper.hasMentions ? '@' : (wrapper.unviewedMessagesCount < 100 ? wrapper.unviewedMessagesCount : "99")
font.pixelSize: 12 font.pixelSize: 12
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter

View File

@ -27,6 +27,7 @@ Item {
timestamp: model.timestamp timestamp: model.timestamp
chatType: model.chatType chatType: model.chatType
unviewedMessagesCount: model.unviewedMessagesCount unviewedMessagesCount: model.unviewedMessagesCount
hasMentions: model.hasMentions
searchStr: chatGroupsContainer.searchStr searchStr: chatGroupsContainer.searchStr
} }
onCountChanged: { onCountChanged: {