diff --git a/src/app/modules/main/activity_center/module.nim b/src/app/modules/main/activity_center/module.nim
index c01501ad16..43e16a417f 100644
--- a/src/app/modules/main/activity_center/module.nim
+++ b/src/app/modules/main/activity_center/module.nim
@@ -98,7 +98,8 @@ proc createMessageItemFromDto(self: Module, message: MessageDto, chatDetails: Ch
contactDetails.details.trustStatus,
contactDetails.details.ensVerified,
message.discordMessage,
- resendError = ""
+ resendError = "",
+ message.mentioned
))
method convertToItems*(
@@ -257,4 +258,4 @@ method getChatDetailsAsJson*(self: Module, chatId: string): string =
jsonObject["icon"] = %* chatDto.icon
jsonObject["color"] = %* chatDto.color
jsonObject["emoji"] = %* chatDto.emoji
- return $jsonObject
\ No newline at end of file
+ return $jsonObject
diff --git a/src/app/modules/main/chat_section/chat_content/messages/module.nim b/src/app/modules/main/chat_section/chat_content/messages/module.nim
index 2a7c58b312..fb2fcbbc2e 100644
--- a/src/app/modules/main/chat_section/chat_content/messages/module.nim
+++ b/src/app/modules/main/chat_section/chat_content/messages/module.nim
@@ -100,7 +100,8 @@ proc createFetchMoreMessagesItem(self: Module): Item =
senderTrustStatus = TrustStatus.Unknown,
senderEnsVerified = false,
DiscordMessage(),
- resendError = ""
+ resendError = "",
+ mentioned = false
)
proc createChatIdentifierItem(self: Module): Item =
@@ -142,7 +143,8 @@ proc createChatIdentifierItem(self: Module): Item =
senderTrustStatus = TrustStatus.Unknown,
senderEnsVerified = false,
DiscordMessage(),
- resendError = ""
+ resendError = "",
+ mentioned = false
)
proc checkIfMessageLoadedAndScrollToItIfItIs(self: Module) =
@@ -223,7 +225,8 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
sender.details.trustStatus,
sender.details.ensVerified,
m.discordMessage,
- resendError = ""
+ resendError = "",
+ m.mentioned
)
for r in reactions:
@@ -323,7 +326,8 @@ method messageAdded*(self: Module, message: MessageDto) =
sender.details.trustStatus,
sender.details.ensVerified,
message.discordMessage,
- resendError = ""
+ resendError = "",
+ message.mentioned
)
self.view.model().insertItemBasedOnClock(item)
@@ -609,7 +613,8 @@ method getMessageById*(self: Module, messageId: string): message_item.Item =
sender.details.trustStatus,
sender.details.ensVerified,
m.discordMessage,
- resendError = ""
+ resendError = "",
+ m.mentioned
)
return item
return nil
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 afdfb95bbf..493a4f0b64 100644
--- a/src/app/modules/main/chat_section/chat_content/module.nim
+++ b/src/app/modules/main/chat_section/chat_content/module.nim
@@ -198,7 +198,8 @@ proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy:
contactDetails.details.trustStatus,
contactDetails.details.ensVerified,
m.discordMessage,
- resendError = ""
+ resendError = "",
+ m.mentioned
)
item.pinned = true
item.pinnedBy = actionInitiatedBy
diff --git a/src/app/modules/shared_models/message_item.nim b/src/app/modules/shared_models/message_item.nim
index 5cf2a5775f..5b2b2d9c80 100644
--- a/src/app/modules/shared_models/message_item.nim
+++ b/src/app/modules/shared_models/message_item.nim
@@ -43,6 +43,7 @@ type
senderEnsVerified: bool
messageAttachments: seq[string]
resendError: string
+ mentioned: bool
proc initItem*(
id,
@@ -72,7 +73,8 @@ proc initItem*(
senderTrustStatus: TrustStatus,
senderEnsVerified: bool,
discordMessage: DiscordMessage,
- resendError: string
+ resendError: string,
+ mentioned: bool
): Item =
result = Item()
result.id = id
@@ -109,6 +111,7 @@ proc initItem*(
result.senderEnsVerified = senderEnsVerified
result.messageAttachments = @[]
result.resendError = resendError
+ result.mentioned = mentioned
if ContentType.DiscordMessage == contentType:
if result.messageText == "":
@@ -157,7 +160,8 @@ proc initNewMessagesMarkerItem*(timestamp: int64): Item =
senderTrustStatus = TrustStatus.Unknown,
senderEnsVerified = false,
discordMessage = DiscordMessage(),
- resendError = ""
+ resendError = "",
+ mentioned = false
)
proc `$`*(self: Item): string =
@@ -401,3 +405,8 @@ proc gapTo*(self: Item): int64 {.inline.} =
proc `gapTo=`*(self: Item, value: int64) {.inline.} =
self.gapTo = value
+proc mentioned*(self: Item): bool {.inline.} =
+ self.mentioned
+
+proc `mentioned=`*(self: Item, value: bool) {.inline.} =
+ self.mentioned = value
diff --git a/src/app/modules/shared_models/message_item_qobject.nim b/src/app/modules/shared_models/message_item_qobject.nim
index 89dc24e2c7..0fe7d0b8d3 100644
--- a/src/app/modules/shared_models/message_item_qobject.nim
+++ b/src/app/modules/shared_models/message_item_qobject.nim
@@ -57,6 +57,10 @@ QtObject:
QtProperty[bool] amISender:
read = amISender
+ proc mentioned*(self: MessageItem): bool {.slot.} = result = ?.self.messageItem.mentioned
+ QtProperty[bool] mentioned:
+ read = mentioned
+
proc senderIcon*(self: MessageItem): string {.slot.} = result = ?.self.messageItem.senderIcon
QtProperty[string] senderIcon:
read = senderIcon
diff --git a/src/app/modules/shared_models/message_model.nim b/src/app/modules/shared_models/message_model.nim
index 52625616cf..4b18bb32c6 100644
--- a/src/app/modules/shared_models/message_model.nim
+++ b/src/app/modules/shared_models/message_model.nim
@@ -43,6 +43,7 @@ type
SenderEnsVerified
MessageAttachments
ResendError
+ Mentioned
QtObject:
type
@@ -103,6 +104,7 @@ QtObject:
ModelRole.Seen.int:"seen",
ModelRole.OutgoingStatus.int:"outgoingStatus",
ModelRole.ResendError.int:"resendError",
+ ModelRole.Mentioned.int:"mentioned",
ModelRole.MessageText.int:"messageText",
ModelRole.MessageImage.int:"messageImage",
ModelRole.MessageContainsMentions.int:"messageContainsMentions",
@@ -173,6 +175,8 @@ QtObject:
result = newQVariant(item.outgoingStatus)
of ModelRole.ResendError:
result = newQVariant(item.resendError)
+ of ModelRole.Mentioned:
+ result = newQVariant(item.mentioned)
of ModelRole.MessageText:
result = newQVariant(item.messageText)
of ModelRole.MessageImage:
diff --git a/src/app_service/common/conversion.nim b/src/app_service/common/conversion.nim
index 49854da19f..ee5ddb3d2d 100644
--- a/src/app_service/common/conversion.nim
+++ b/src/app_service/common/conversion.nim
@@ -3,9 +3,16 @@ from web3 import Address, fromHex
const CompressedKeyChars* = {'0'..'9', 'A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
+const SystemMentionChars* = {'0'..'9', 'x'}
+
+const SystemTagMapping* = [("@everyone", "@0x00001")]
+
proc isCompressedPubKey*(strPubKey: string): bool =
return strPubKey.startsWith("zQ3") and allCharsInSet(strPubKey, CompressedKeyChars)
+proc isSystemMention*(mention: string) : bool =
+ mention.startsWith("0x") and allCharsInSet(mention, SystemMentionChars)
+
proc parseAddress*(strAddress: string): Address =
var hexAddressValue: Address
try:
diff --git a/src/app_service/common/message.nim b/src/app_service/common/message.nim
index 03a67c3e91..cd62d34673 100644
--- a/src/app_service/common/message.nim
+++ b/src/app_service/common/message.nim
@@ -1,5 +1,6 @@
import sequtils, strutils, sugar, re
import ../service/contacts/dto/contacts
+from conversion import SystemTagMapping
proc replaceMentionsWithPubKeys*(allKnownContacts: seq[ContactsDto], message: string): string =
let aliasPattern = re(r"(@[A-z][a-z]+ [A-z][a-z]* [A-z][a-z]*)", flags = {reStudy, reIgnoreCase})
@@ -11,6 +12,10 @@ proc replaceMentionsWithPubKeys*(allKnownContacts: seq[ContactsDto], message: st
let nameMentions = findAll(message, namePattern)
var updatedMessage = message
+ # replace system tag with system ID
+ for pair in SystemTagMapping:
+ updatedMessage = updatedMessage.replaceWord(pair[0], pair[1])
+
# In the following lines we're free to compare to `x.userDefaultDisplayName()` cause that's actually what we're displaying
# in the mentions suggestion list.
for mention in aliasMentions:
diff --git a/src/app_service/service/message/dto/message.nim b/src/app_service/service/message/dto/message.nim
index 99d2c6b29a..a0320a16ac 100644
--- a/src/app_service/service/message/dto/message.nim
+++ b/src/app_service/service/message/dto/message.nim
@@ -4,6 +4,8 @@ import json, strutils
include ../../../common/json_utils
+from ../../../common/conversion import SystemTagMapping
+
const PARSED_TEXT_TYPE_PARAGRAPH* = "paragraph"
const PARSED_TEXT_TYPE_BLOCKQUOTE* = "blockquote"
const PARSED_TEXT_TYPE_CODEBLOCK* = "codeblock"
@@ -108,6 +110,7 @@ type MessageDto* = object
deleted*: bool
deletedForMe*: bool
transactionParameters*: TransactionParameters
+ mentioned*: bool
proc toParsedText*(jsonObj: JsonNode): ParsedText =
result = ParsedText()
@@ -213,6 +216,7 @@ proc toMessageDto*(jsonObj: JsonNode): MessageDto =
discard jsonObj.getProp("editedAt", result.editedAt)
discard jsonObj.getProp("deleted", result.deleted)
discard jsonObj.getProp("deletedForMe", result.deletedForMe)
+ discard jsonObj.getProp("mentioned", result.mentioned)
var quotedMessageObj: JsonNode
if(jsonObj.getProp("quotedMessage", quotedMessageObj)):
@@ -259,7 +263,13 @@ proc isPersonalMention*(self: MessageDto, publicKey: string): bool =
return false
proc isGlobalMention*(self: MessageDto): bool =
- # TODO: we should check here if message contains global mention.
+ for pText in self.parsedText:
+ for child in pText.children:
+ if child.type == PARSED_TEXT_CHILD_TYPE_MENTION:
+ for pair in SystemTagMapping:
+ if child.literal.contains(pair[1]):
+ return true
+
return false
proc mentionedUsersPks*(self: MessageDto): seq[string] =
diff --git a/src/app_service/service/message/service.nim b/src/app_service/service/message/service.nim
index 63d57c379a..a2da37c688 100644
--- a/src/app_service/service/message/service.nim
+++ b/src/app_service/service/message/service.nim
@@ -703,10 +703,18 @@ proc renderInline(self: Service, parsedText: ParsedText): string =
result = fmt(" {value} ")
of PARSED_TEXT_CHILD_TYPE_MENTION:
var id = value
- if isCompressedPubKey(id):
- id = status_accounts.decompressPk(id).result
- let contactDto = self.contactService.getContactById(id)
- result = fmt("{contactDto.userDefaultDisplayName()}")
+ if isSystemMention(id):
+ var tag = id
+ for pair in SystemTagMapping:
+ if pair[1] == "@" & id:
+ tag = pair[0]
+ break
+ result = fmt("{tag}")
+ else:
+ if isCompressedPubKey(id):
+ id = status_accounts.decompressPk(id).result
+ let contactDto = self.contactService.getContactById(id)
+ result = fmt("{contactDto.userDefaultDisplayName()}")
of PARSED_TEXT_CHILD_TYPE_STATUS_TAG:
result = fmt("#{value}")
of PARSED_TEXT_CHILD_TYPE_DEL:
diff --git a/ui/app/AppLayouts/Chat/panels/SuggestionFilterPanel.qml b/ui/app/AppLayouts/Chat/panels/SuggestionFilterPanel.qml
index 0e2bf0ff70..a2f1cf6903 100644
--- a/ui/app/AppLayouts/Chat/panels/SuggestionFilterPanel.qml
+++ b/ui/app/AppLayouts/Chat/panels/SuggestionFilterPanel.qml
@@ -13,6 +13,7 @@ Item {
property int cursorPosition: 0
property int lastAtPosition: 0
property var property: ([])
+ property bool addSystemSuggestions: false
onFilterChanged: invalidateFilter()
onPropertyChanged: invalidateFilter()
@@ -78,6 +79,15 @@ Item {
filterModel.append(item)
}
}
+
+ const everyoneItem = {
+ publicKey: "0x00001",
+ name: "@everyone",
+ icon: ""
+ }
+ if (suggestionsPanelRoot.addSystemSuggestions && isAcceptedItem(filter, everyoneItem)) {
+ filterModel.append(everyoneItem)
+ }
}
function getFilter() {
diff --git a/ui/app/AppLayouts/Chat/views/ChatContentView.qml b/ui/app/AppLayouts/Chat/views/ChatContentView.qml
index 637a223209..0aff73a12d 100644
--- a/ui/app/AppLayouts/Chat/views/ChatContentView.qml
+++ b/ui/app/AppLayouts/Chat/views/ChatContentView.qml
@@ -190,6 +190,7 @@ ColumnLayout {
isActiveChannel: root.isActiveChannel
anchors.bottom: parent.bottom
chatType: chatContentModule? chatContentModule.chatDetails.type : Constants.chatType.unknown
+ suggestions.suggestionFilter.addSystemSuggestions: chatType == Constants.chatType.communityChat
Binding on chatInputPlaceholder {
when: root.isBlocked
diff --git a/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml b/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml
index 6184c1ca0a..9fb4fea3f8 100644
--- a/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml
+++ b/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml
@@ -276,7 +276,7 @@ Item {
linkUrls: model.links
messageAttachments: model.messageAttachments
transactionParams: model.transactionParameters
- hasMention: model.mentionedUsersPks.split(" ").includes(root.rootStore.userProfileInst.pubKey)
+ hasMention: model.mentioned
gapFrom: model.gapFrom
gapTo: model.gapTo
diff --git a/vendor/status-go b/vendor/status-go
index 4a0eb56574..b4bdfd3df6 160000
--- a/vendor/status-go
+++ b/vendor/status-go
@@ -1 +1 @@
-Subproject commit 4a0eb56574a3cfd8f5732f0069cc62cb04f9dd29
+Subproject commit b4bdfd3df6cf5fb91ab2d0e9f3b38e8d1b9703e5