feat(@desktop/chat): Displaying new type of chat message - bridge message
Show discord user as a message sender. Show discord avatar next to user name. Show "Bridged from Discord" label. Open adjusted profile context menu. Issue #13098
This commit is contained in:
parent
eee8ec8e32
commit
0a18dda176
|
@ -147,6 +147,7 @@ proc createMessageItemFromDto(self: Module, message: MessageDto, communityId: st
|
||||||
imagesAlbum,
|
imagesAlbum,
|
||||||
albumMessageIds,
|
albumMessageIds,
|
||||||
message.albumImagesCount,
|
message.albumImagesCount,
|
||||||
|
message.bridgeMessage,
|
||||||
))
|
))
|
||||||
|
|
||||||
method convertToItems*(
|
method convertToItems*(
|
||||||
|
|
|
@ -206,6 +206,7 @@ proc createMessageItemsFromMessageDtos(self: Module, messages: seq[MessageDto],
|
||||||
if (len(message.albumId) == 0): @[] else: @[message.image],
|
if (len(message.albumId) == 0): @[] else: @[message.image],
|
||||||
if (len(message.albumId) == 0): @[] else: @[message.id],
|
if (len(message.albumId) == 0): @[] else: @[message.id],
|
||||||
message.albumImagesCount,
|
message.albumImagesCount,
|
||||||
|
message.bridgeMessage,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.updateLinkPreviewsContacts(item, requestFromMailserver = item.seen)
|
self.updateLinkPreviewsContacts(item, requestFromMailserver = item.seen)
|
||||||
|
@ -284,6 +285,7 @@ proc createFetchMoreMessagesItem(self: Module): Item =
|
||||||
albumMessageImages = @[],
|
albumMessageImages = @[],
|
||||||
albumMessageIds = @[],
|
albumMessageIds = @[],
|
||||||
albumImagesCount = 0,
|
albumImagesCount = 0,
|
||||||
|
BridgeMessage(),
|
||||||
)
|
)
|
||||||
|
|
||||||
proc createChatIdentifierItem(self: Module): Item =
|
proc createChatIdentifierItem(self: Module): Item =
|
||||||
|
@ -349,6 +351,7 @@ proc createChatIdentifierItem(self: Module): Item =
|
||||||
albumMessageImages = @[],
|
albumMessageImages = @[],
|
||||||
albumMessageIds = @[],
|
albumMessageIds = @[],
|
||||||
albumImagesCount = 0,
|
albumImagesCount = 0,
|
||||||
|
bridgeMessage = BridgeMessage(),
|
||||||
)
|
)
|
||||||
|
|
||||||
proc checkIfMessageLoadedAndScrollToItIfItIs(self: Module) =
|
proc checkIfMessageLoadedAndScrollToItIfItIs(self: Module) =
|
||||||
|
|
|
@ -228,6 +228,7 @@ proc buildPinnedMessageItem(self: Module, message: MessageDto, actionInitiatedBy
|
||||||
if (len(message.albumId) == 0): @[] else: @[message.image],
|
if (len(message.albumId) == 0): @[] else: @[message.image],
|
||||||
if (len(message.albumId) == 0): @[] else: @[message.id],
|
if (len(message.albumId) == 0): @[] else: @[message.id],
|
||||||
message.albumImagesCount,
|
message.albumImagesCount,
|
||||||
|
message.bridgeMessage,
|
||||||
)
|
)
|
||||||
item.pinned = true
|
item.pinned = true
|
||||||
item.pinnedBy = actionInitiatedBy
|
item.pinnedBy = actionInitiatedBy
|
||||||
|
|
|
@ -70,6 +70,7 @@ type
|
||||||
albumMessageImages: seq[string]
|
albumMessageImages: seq[string]
|
||||||
albumMessageIds: seq[string]
|
albumMessageIds: seq[string]
|
||||||
albumImagesCount: int
|
albumImagesCount: int
|
||||||
|
bridgeName: string
|
||||||
|
|
||||||
proc initItem*(
|
proc initItem*(
|
||||||
id,
|
id,
|
||||||
|
@ -121,6 +122,7 @@ proc initItem*(
|
||||||
albumMessageImages: seq[string],
|
albumMessageImages: seq[string],
|
||||||
albumMessageIds: seq[string],
|
albumMessageIds: seq[string],
|
||||||
albumImagesCount: int,
|
albumImagesCount: int,
|
||||||
|
bridgeMessage: BridgeMessage,
|
||||||
): Item =
|
): Item =
|
||||||
result = Item()
|
result = Item()
|
||||||
result.id = id
|
result.id = id
|
||||||
|
@ -208,6 +210,13 @@ proc initItem*(
|
||||||
if attachment.contentType.contains("image"):
|
if attachment.contentType.contains("image"):
|
||||||
result.messageAttachments.add(attachment.localUrl)
|
result.messageAttachments.add(attachment.localUrl)
|
||||||
|
|
||||||
|
if contentType == ContentType.BridgeMessage:
|
||||||
|
result.messageText = bridgeMessage.content
|
||||||
|
result.unparsedText = bridgeMessage.content
|
||||||
|
result.senderDisplayName = bridgeMessage.userName
|
||||||
|
result.senderIcon = bridgeMessage.userAvatar
|
||||||
|
result.bridgeName = bridgeMessage.bridgeName
|
||||||
|
|
||||||
proc initNewMessagesMarkerItem*(clock, timestamp: int64): Item =
|
proc initNewMessagesMarkerItem*(clock, timestamp: int64): Item =
|
||||||
return initItem(
|
return initItem(
|
||||||
id = "",
|
id = "",
|
||||||
|
@ -259,6 +268,7 @@ proc initNewMessagesMarkerItem*(clock, timestamp: int64): Item =
|
||||||
albumMessageImages = @[],
|
albumMessageImages = @[],
|
||||||
albumMessageIds = @[],
|
albumMessageIds = @[],
|
||||||
albumImagesCount = 0,
|
albumImagesCount = 0,
|
||||||
|
bridgeMessage = BridgeMessage(),
|
||||||
)
|
)
|
||||||
|
|
||||||
proc `$`*(self: Item): string =
|
proc `$`*(self: Item): string =
|
||||||
|
@ -404,6 +414,9 @@ proc `albumMessageIds=`*(self: Item, value: seq[string]) {.inline.} =
|
||||||
proc albumImagesCount*(self: Item): int {.inline.} =
|
proc albumImagesCount*(self: Item): int {.inline.} =
|
||||||
self.albumImagesCount
|
self.albumImagesCount
|
||||||
|
|
||||||
|
proc bridgeName*(self: Item): string {.inline.} =
|
||||||
|
self.bridgeName
|
||||||
|
|
||||||
proc messageContainsMentions*(self: Item): bool {.inline.} =
|
proc messageContainsMentions*(self: Item): bool {.inline.} =
|
||||||
self.messageContainsMentions
|
self.messageContainsMentions
|
||||||
|
|
||||||
|
@ -542,6 +555,7 @@ proc toJsonNode*(self: Item): JsonNode =
|
||||||
"albumMessageImages": self.albumMessageImages,
|
"albumMessageImages": self.albumMessageImages,
|
||||||
"albumMessageIds": self.albumMessageIds,
|
"albumMessageIds": self.albumMessageIds,
|
||||||
"albumImagesCount": self.albumImagesCount,
|
"albumImagesCount": self.albumImagesCount,
|
||||||
|
"bridgeName": self.bridgeName
|
||||||
}
|
}
|
||||||
|
|
||||||
proc editMode*(self: Item): bool {.inline.} =
|
proc editMode*(self: Item): bool {.inline.} =
|
||||||
|
|
|
@ -73,6 +73,7 @@ type
|
||||||
QuotedMessageAlbumImagesCount
|
QuotedMessageAlbumImagesCount
|
||||||
AlbumMessageImages
|
AlbumMessageImages
|
||||||
AlbumImagesCount
|
AlbumImagesCount
|
||||||
|
BridgeName
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type
|
type
|
||||||
|
@ -178,6 +179,7 @@ QtObject:
|
||||||
ModelRole.QuotedMessageAlbumImagesCount.int: "quotedMessageAlbumImagesCount",
|
ModelRole.QuotedMessageAlbumImagesCount.int: "quotedMessageAlbumImagesCount",
|
||||||
ModelRole.AlbumMessageImages.int: "albumMessageImages",
|
ModelRole.AlbumMessageImages.int: "albumMessageImages",
|
||||||
ModelRole.AlbumImagesCount.int: "albumImagesCount",
|
ModelRole.AlbumImagesCount.int: "albumImagesCount",
|
||||||
|
ModelRole.BridgeName.int: "bridgeName",
|
||||||
}.toTable
|
}.toTable
|
||||||
|
|
||||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||||
|
@ -350,6 +352,8 @@ QtObject:
|
||||||
result = newQVariant(item.albumMessageImages.join(" "))
|
result = newQVariant(item.albumMessageImages.join(" "))
|
||||||
of ModelRole.AlbumImagesCount:
|
of ModelRole.AlbumImagesCount:
|
||||||
result = newQVariant(item.albumImagesCount)
|
result = newQVariant(item.albumImagesCount)
|
||||||
|
of ModelRole.BridgeName:
|
||||||
|
result = newQVariant(item.bridgeName)
|
||||||
|
|
||||||
proc updateItemAtIndex(self: Model, index: int) =
|
proc updateItemAtIndex(self: Model, index: int) =
|
||||||
let ind = self.createIndex(index, 0, nil)
|
let ind = self.createIndex(index, 0, nil)
|
||||||
|
|
|
@ -22,6 +22,7 @@ type
|
||||||
SystemMessageMutualEventSent = 15
|
SystemMessageMutualEventSent = 15
|
||||||
SystemMessageMutualEventAccepted = 16
|
SystemMessageMutualEventAccepted = 16
|
||||||
SystemMessageMutualEventRemoved = 17
|
SystemMessageMutualEventRemoved = 17
|
||||||
|
BridgeMessage = 18
|
||||||
|
|
||||||
proc toContentType*(value: int): ContentType =
|
proc toContentType*(value: int): ContentType =
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -56,6 +56,14 @@ type DiscordMessage* = object
|
||||||
author*: DiscordMessageAuthor
|
author*: DiscordMessageAuthor
|
||||||
attachments*: seq[DiscordMessageAttachment]
|
attachments*: seq[DiscordMessageAttachment]
|
||||||
|
|
||||||
|
type BridgeMessage* = object
|
||||||
|
bridgeName*: string
|
||||||
|
userName*: string
|
||||||
|
userAvatar*: string
|
||||||
|
userId*: string
|
||||||
|
content*: string
|
||||||
|
messageId*: string
|
||||||
|
parentMessageId*: string
|
||||||
|
|
||||||
type QuotedMessage* = object
|
type QuotedMessage* = object
|
||||||
`from`*: string
|
`from`*: string
|
||||||
|
@ -95,6 +103,7 @@ type MessageDto* = object
|
||||||
outgoingStatus*: string
|
outgoingStatus*: string
|
||||||
quotedMessage*: QuotedMessage
|
quotedMessage*: QuotedMessage
|
||||||
discordMessage*: DiscordMessage
|
discordMessage*: DiscordMessage
|
||||||
|
bridgeMessage*: BridgeMessage
|
||||||
rtl*: bool
|
rtl*: bool
|
||||||
parsedText*: seq[ParsedText]
|
parsedText*: seq[ParsedText]
|
||||||
lineCount*: int
|
lineCount*: int
|
||||||
|
@ -170,6 +179,16 @@ proc toDiscordMessage*(jsonObj: JsonNode): DiscordMessage =
|
||||||
for attachment in attachmentsArr:
|
for attachment in attachmentsArr:
|
||||||
result.attachments.add(toDiscordMessageAttachment(attachment))
|
result.attachments.add(toDiscordMessageAttachment(attachment))
|
||||||
|
|
||||||
|
proc toBridgeMessage*(jsonObj: JsonNode): BridgeMessage =
|
||||||
|
result = BridgeMessage()
|
||||||
|
discard jsonObj.getProp("userName", result.userName)
|
||||||
|
discard jsonObj.getProp("bridgeName", result.bridgeName)
|
||||||
|
discard jsonObj.getProp("userAvatar", result.userAvatar)
|
||||||
|
discard jsonObj.getProp("userID", result.userId)
|
||||||
|
discard jsonObj.getProp("content", result.content)
|
||||||
|
discard jsonObj.getProp("messageID", result.messageId)
|
||||||
|
discard jsonObj.getProp("parentMessageID", result.parentMessageId)
|
||||||
|
|
||||||
proc toQuotedMessage*(jsonObj: JsonNode): QuotedMessage =
|
proc toQuotedMessage*(jsonObj: JsonNode): QuotedMessage =
|
||||||
result = QuotedMessage()
|
result = QuotedMessage()
|
||||||
var contentType: int
|
var contentType: int
|
||||||
|
@ -263,6 +282,10 @@ proc toMessageDto*(jsonObj: JsonNode): MessageDto =
|
||||||
if(jsonObj.getProp("discordMessage", discordMessageObj)):
|
if(jsonObj.getProp("discordMessage", discordMessageObj)):
|
||||||
result.discordMessage = toDiscordMessage(discordMessageObj)
|
result.discordMessage = toDiscordMessage(discordMessageObj)
|
||||||
|
|
||||||
|
var bridgeMessageObj: JsonNode
|
||||||
|
if(jsonObj.getProp("bridgeMessage", bridgeMessageObj)):
|
||||||
|
result.bridgeMessage = toBridgeMessage(bridgeMessageObj)
|
||||||
|
|
||||||
var stickerObj: JsonNode
|
var stickerObj: JsonNode
|
||||||
if(jsonObj.getProp("sticker", stickerObj)):
|
if(jsonObj.getProp("sticker", stickerObj)):
|
||||||
result.sticker = toSticker(stickerObj)
|
result.sticker = toSticker(stickerObj)
|
||||||
|
|
|
@ -59,6 +59,7 @@ proc createTestMessageItem(id: string, clock: int64): Item =
|
||||||
albumMessageImages = @[],
|
albumMessageImages = @[],
|
||||||
albumMessageIds = @[],
|
albumMessageIds = @[],
|
||||||
albumImagesCount = 0,
|
albumImagesCount = 0,
|
||||||
|
bridgeMessage = BridgeMessage(),
|
||||||
)
|
)
|
||||||
|
|
||||||
let message0_chatIdentifier = createTestMessageItem("chat-identifier", -2)
|
let message0_chatIdentifier = createTestMessageItem("chat-identifier", -2)
|
||||||
|
|
|
@ -25,7 +25,8 @@ Control {
|
||||||
SystemMessagePinnedMessage = 14,
|
SystemMessagePinnedMessage = 14,
|
||||||
SystemMessageMutualEventSent = 15,
|
SystemMessageMutualEventSent = 15,
|
||||||
SystemMessageMutualEventAccepted = 16,
|
SystemMessageMutualEventAccepted = 16,
|
||||||
SystemMessageMutualEventRemoved = 17
|
SystemMessageMutualEventRemoved = 17,
|
||||||
|
BridgeMessage = 18
|
||||||
}
|
}
|
||||||
|
|
||||||
property list<Item> quickActions
|
property list<Item> quickActions
|
||||||
|
@ -221,6 +222,8 @@ Control {
|
||||||
name: root.messageDetails.sender.displayName
|
name: root.messageDetails.sender.displayName
|
||||||
asset: root.messageDetails.sender.profileImage.assetSettings
|
asset: root.messageDetails.sender.profileImage.assetSettings
|
||||||
ringSettings: root.messageDetails.sender.profileImage.ringSettings
|
ringSettings: root.messageDetails.sender.profileImage.ringSettings
|
||||||
|
bridgeBadge.visible: root.messageDetails.contentType === StatusMessage.ContentType.BridgeMessage
|
||||||
|
bridgeBadge.image.source: root.messageDetails.sender.badgeImage
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
@ -267,7 +270,8 @@ Control {
|
||||||
&& ((root.messageDetails.contentType === StatusMessage.ContentType.Text) ||
|
&& ((root.messageDetails.contentType === StatusMessage.ContentType.Text) ||
|
||||||
(root.messageDetails.contentType === StatusMessage.ContentType.Emoji) ||
|
(root.messageDetails.contentType === StatusMessage.ContentType.Emoji) ||
|
||||||
(root.messageDetails.contentType === StatusMessage.ContentType.DiscordMessage) ||
|
(root.messageDetails.contentType === StatusMessage.ContentType.DiscordMessage) ||
|
||||||
(root.messageDetails.contentType === StatusMessage.ContentType.Invitation)))
|
(root.messageDetails.contentType === StatusMessage.ContentType.Invitation) ||
|
||||||
|
(root.messageDetails.contentType === StatusMessage.ContentType.BridgeMessage)))
|
||||||
visible: active
|
visible: active
|
||||||
sourceComponent: StatusTextMessage {
|
sourceComponent: StatusTextMessage {
|
||||||
objectName: "StatusMessage_textMessage"
|
objectName: "StatusMessage_textMessage"
|
||||||
|
|
|
@ -12,6 +12,8 @@ QtObject {
|
||||||
property bool isContact: false
|
property bool isContact: false
|
||||||
property int trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
property int trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||||
|
|
||||||
|
property string badgeImage: ""
|
||||||
|
|
||||||
property StatusProfileImageSettings profileImage: StatusProfileImageSettings {
|
property StatusProfileImageSettings profileImage: StatusProfileImageSettings {
|
||||||
pubkey: root.id
|
pubkey: root.id
|
||||||
showRing: !root.isEnsVerified
|
showRing: !root.isEnsVerified
|
||||||
|
|
|
@ -12,6 +12,8 @@ Loader {
|
||||||
// Badge color properties must be set if badgeItem.visible = true
|
// Badge color properties must be set if badgeItem.visible = true
|
||||||
property alias badge: statusBadge
|
property alias badge: statusBadge
|
||||||
|
|
||||||
|
property alias bridgeBadge: bridgeBadge
|
||||||
|
|
||||||
property StatusAssetSettings asset: StatusAssetSettings {
|
property StatusAssetSettings asset: StatusAssetSettings {
|
||||||
width: 40
|
width: 40
|
||||||
height: 40
|
height: 40
|
||||||
|
@ -33,7 +35,7 @@ Loader {
|
||||||
|
|
||||||
property bool loading: false
|
property bool loading: false
|
||||||
property bool hoverEnabled: false
|
property bool hoverEnabled: false
|
||||||
readonly property bool hovered: (sourceComponent == roundedIcon && item) ?
|
readonly property bool hovered: (sourceComponent === roundedIcon && item) ?
|
||||||
item.hovered : false
|
item.hovered : false
|
||||||
signal clicked(var mouse)
|
signal clicked(var mouse)
|
||||||
|
|
||||||
|
@ -140,6 +142,20 @@ Loader {
|
||||||
z: root.dZ
|
z: root.dZ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusRoundedImage {
|
||||||
|
id: bridgeBadge
|
||||||
|
visible: false
|
||||||
|
anchors.bottom: root.bottom
|
||||||
|
anchors.right: root.right
|
||||||
|
anchors.rightMargin: -border.width
|
||||||
|
anchors.bottomMargin: -border.width
|
||||||
|
implicitHeight: 20
|
||||||
|
implicitWidth: 20
|
||||||
|
border.width: 3
|
||||||
|
border.color: Theme.palette.statusBadge.foregroundColor
|
||||||
|
z: root.dZ
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: loadingComp
|
id: loadingComp
|
||||||
LoadingComponent {
|
LoadingComponent {
|
||||||
|
|
|
@ -111,6 +111,7 @@ StatusDialog {
|
||||||
quotedMessageAuthorDetailsEnsVerified: model.quotedMessageAuthorEnsVerified
|
quotedMessageAuthorDetailsEnsVerified: model.quotedMessageAuthorEnsVerified
|
||||||
quotedMessageAuthorDetailsIsContact: model.quotedMessageAuthorIsContact
|
quotedMessageAuthorDetailsIsContact: model.quotedMessageAuthorIsContact
|
||||||
quotedMessageAuthorDetailsColorHash: model.quotedMessageAuthorColorHash
|
quotedMessageAuthorDetailsColorHash: model.quotedMessageAuthorColorHash
|
||||||
|
bridgeName: model.bridgeName
|
||||||
|
|
||||||
// This is possible since we have all data loaded before we load qml.
|
// This is possible since we have all data loaded before we load qml.
|
||||||
// When we fetch messages to fulfill a gap we have to set them at once.
|
// When we fetch messages to fulfill a gap we have to set them at once.
|
||||||
|
|
|
@ -325,6 +325,7 @@ Item {
|
||||||
quotedMessageAuthorDetailsColorHash: model.quotedMessageAuthorColorHash
|
quotedMessageAuthorDetailsColorHash: model.quotedMessageAuthorColorHash
|
||||||
quotedMessageAlbumMessageImages: model.quotedMessageAlbumMessageImages.split(" ")
|
quotedMessageAlbumMessageImages: model.quotedMessageAlbumMessageImages.split(" ")
|
||||||
quotedMessageAlbumImagesCount: model.quotedMessageAlbumImagesCount
|
quotedMessageAlbumImagesCount: model.quotedMessageAlbumImagesCount
|
||||||
|
bridgeName: model.bridgeName
|
||||||
|
|
||||||
gapFrom: model.gapFrom
|
gapFrom: model.gapFrom
|
||||||
gapTo: model.gapTo
|
gapTo: model.gapTo
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="16" height="16" rx="8" fill="#5865F2"/>
|
||||||
|
<g clip-path="url(#clip0_50821_248568)">
|
||||||
|
<path d="M11.471 4.66999C10.814 4.35248 10.1204 4.12724 9.40789 4C9.31039 4.18397 9.22218 4.37324 9.14361 4.56704C8.3847 4.44633 7.61293 4.44633 6.85401 4.56704C6.7754 4.37326 6.68719 4.18399 6.58974 4C5.87681 4.12831 5.18275 4.35409 4.52508 4.67165C3.21944 6.71067 2.8655 8.69904 3.04247 10.6592C3.80708 11.2555 4.66291 11.709 5.57275 12C5.77761 11.7092 5.9589 11.4006 6.11467 11.0776C5.8188 10.961 5.53324 10.8171 5.26128 10.6476C5.33285 10.5928 5.40285 10.5363 5.4705 10.4815C6.26183 10.8743 7.12552 11.078 7.99999 11.078C8.87446 11.078 9.73816 10.8743 10.5295 10.4815C10.5979 10.5405 10.6679 10.5969 10.7387 10.6476C10.4662 10.8174 10.1801 10.9615 9.88374 11.0785C10.0393 11.4013 10.2206 11.7096 10.4257 12C11.3363 11.7102 12.1928 11.2569 12.9575 10.66C13.1652 8.38688 12.6028 6.41677 11.471 4.66999ZM6.33883 9.45372C5.84567 9.45372 5.43825 8.98132 5.43825 8.40017C5.43825 7.81901 5.83152 7.34247 6.33726 7.34247C6.843 7.34247 7.24728 7.81901 7.23863 8.40017C7.22997 8.98132 6.84143 9.45372 6.33883 9.45372ZM9.66115 9.45372C9.16721 9.45372 8.76136 8.98132 8.76136 8.40017C8.76136 7.81901 9.15462 7.34247 9.66115 7.34247C10.1677 7.34247 10.5688 7.81901 10.5602 8.40017C10.5515 8.98132 10.1637 9.45372 9.66115 9.45372Z" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_50821_248568">
|
||||||
|
<rect width="10" height="8" fill="white" transform="translate(3 4)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -40,6 +40,7 @@ Item {
|
||||||
property bool editButtonVisible: displayNamePlusIconsVisible
|
property bool editButtonVisible: displayNamePlusIconsVisible
|
||||||
property bool loading: false
|
property bool loading: false
|
||||||
readonly property bool compact: root.imageSize === ProfileHeader.ImageSize.Compact
|
readonly property bool compact: root.imageSize === ProfileHeader.ImageSize.Compact
|
||||||
|
property bool isBridgedAccount: false
|
||||||
|
|
||||||
signal clicked()
|
signal clicked()
|
||||||
signal editClicked()
|
signal editClicked()
|
||||||
|
@ -119,6 +120,7 @@ Item {
|
||||||
imageHeight: imageWidth
|
imageHeight: imageWidth
|
||||||
ensVerified: root.userIsEnsVerified
|
ensVerified: root.userIsEnsVerified
|
||||||
loading: root.loading
|
loading: root.loading
|
||||||
|
isBridgedAccount: root.isBridgedAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusRoundButton {
|
StatusRoundButton {
|
||||||
|
@ -206,7 +208,7 @@ Item {
|
||||||
|
|
||||||
StatusContactVerificationIcons {
|
StatusContactVerificationIcons {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
visible: !root.isCurrentUser
|
visible: !root.isCurrentUser && !root.isBridgedAccount
|
||||||
isContact: root.isContact
|
isContact: root.isContact
|
||||||
trustIndicator: root.trustStatus
|
trustIndicator: root.trustStatus
|
||||||
}
|
}
|
||||||
|
@ -235,7 +237,7 @@ Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
visible: root.pubkeyVisible
|
visible: root.pubkeyVisible
|
||||||
text: Utils.getElidedCompressedPk(pubkey)
|
text: root.isBridgedAccount ? qsTr("Bridged from Discord") : Utils.getElidedCompressedPk(pubkey)
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
color: Style.current.secondaryText
|
color: Style.current.secondaryText
|
||||||
|
@ -243,7 +245,7 @@ Item {
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
visible: root.pubkeyVisibleWithCopy
|
visible: root.pubkeyVisibleWithCopy && !root.isBridgedAccount
|
||||||
StyledText {
|
StyledText {
|
||||||
id: txtChatKey
|
id: txtChatKey
|
||||||
text: qsTr("Chatkey:%1...").arg(pubkey.substring(0, 32))
|
text: qsTr("Chatkey:%1...").arg(pubkey.substring(0, 32))
|
||||||
|
@ -265,7 +267,7 @@ Item {
|
||||||
EmojiHash {
|
EmojiHash {
|
||||||
id: emojiHash
|
id: emojiHash
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
visible: root.emojiHashVisible
|
visible: root.emojiHashVisible && !root.isBridgedAccount
|
||||||
compact: root.compact
|
compact: root.compact
|
||||||
publicKey: root.pubkey
|
publicKey: root.pubkey
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,12 @@ Loader {
|
||||||
property string name
|
property string name
|
||||||
property string pubkey
|
property string pubkey
|
||||||
property string image
|
property string image
|
||||||
property bool showRing: !ensVerified
|
property bool showRing: !ensVerified && !root.isBridgedAccount
|
||||||
property bool interactive: true
|
property bool interactive: true
|
||||||
property bool disabled: false
|
property bool disabled: false
|
||||||
property bool ensVerified: false
|
property bool ensVerified: false
|
||||||
property bool loading: false
|
property bool loading: false
|
||||||
|
property bool isBridgedAccount: false
|
||||||
|
|
||||||
property int colorId: Utils.colorIdForPubkey(pubkey)
|
property int colorId: Utils.colorIdForPubkey(pubkey)
|
||||||
property var colorHash: Utils.getColorHashAsJson(pubkey, ensVerified)
|
property var colorHash: Utils.getColorHashAsJson(pubkey, ensVerified)
|
||||||
|
@ -41,6 +42,8 @@ Loader {
|
||||||
ringSpecModel: root.showRing ? root.colorHash : undefined
|
ringSpecModel: root.showRing ? root.colorHash : undefined
|
||||||
}
|
}
|
||||||
loading: root.loading
|
loading: root.loading
|
||||||
|
bridgeBadge.visible: root.isBridgedAccount
|
||||||
|
bridgeBadge.image.source: Style.svg("discord-bridge")
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
@ -128,13 +128,15 @@ Loader {
|
||||||
property bool stickersLoaded: false
|
property bool stickersLoaded: false
|
||||||
property string sticker
|
property string sticker
|
||||||
property int stickerPack: -1
|
property int stickerPack: -1
|
||||||
|
property string bridgeName: ""
|
||||||
|
|
||||||
property bool isEmoji: messageContentType === Constants.messageContentType.emojiType
|
property bool isEmoji: messageContentType === Constants.messageContentType.emojiType
|
||||||
property bool isImage: messageContentType === Constants.messageContentType.imageType || (isDiscordMessage && messageImage != "")
|
property bool isImage: messageContentType === Constants.messageContentType.imageType || (isDiscordMessage && messageImage != "")
|
||||||
property bool isAudio: messageContentType === Constants.messageContentType.audioType
|
property bool isAudio: messageContentType === Constants.messageContentType.audioType
|
||||||
property bool isSticker: messageContentType === Constants.messageContentType.stickerType
|
property bool isSticker: messageContentType === Constants.messageContentType.stickerType
|
||||||
property bool isDiscordMessage: messageContentType === Constants.messageContentType.discordMessageType
|
property bool isDiscordMessage: messageContentType === Constants.messageContentType.discordMessageType
|
||||||
property bool isText: messageContentType === Constants.messageContentType.messageType || messageContentType === Constants.messageContentType.contactRequestType || isDiscordMessage
|
property bool isBridgeMessage: messageContentType === Constants.messageContentType.bridgeMessageType
|
||||||
|
property bool isText: messageContentType === Constants.messageContentType.messageType || messageContentType === Constants.messageContentType.contactRequestType || isDiscordMessage || isBridgeMessage
|
||||||
property bool isMessage: isEmoji || isImage || isSticker || isText || isAudio
|
property bool isMessage: isEmoji || isImage || isSticker || isText || isAudio
|
||||||
|| messageContentType === Constants.messageContentType.communityInviteType || messageContentType === Constants.messageContentType.transactionType
|
|| messageContentType === Constants.messageContentType.communityInviteType || messageContentType === Constants.messageContentType.transactionType
|
||||||
|
|
||||||
|
@ -152,6 +154,7 @@ Loader {
|
||||||
selectedUserPublicKey: isReply ? quotedMessageFrom : root.senderId,
|
selectedUserPublicKey: isReply ? quotedMessageFrom : root.senderId,
|
||||||
selectedUserDisplayName: isReply ? quotedMessageAuthorDetailsDisplayName : root.senderDisplayName,
|
selectedUserDisplayName: isReply ? quotedMessageAuthorDetailsDisplayName : root.senderDisplayName,
|
||||||
selectedUserIcon: isReply ? quotedMessageAuthorDetailsThumbnailImage : root.senderIcon,
|
selectedUserIcon: isReply ? quotedMessageAuthorDetailsThumbnailImage : root.senderIcon,
|
||||||
|
isBridgedAccount: root.isBridgeMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
Global.openMenu(profileContextMenuComponent, sender, params)
|
Global.openMenu(profileContextMenuComponent, sender, params)
|
||||||
|
@ -239,6 +242,7 @@ Loader {
|
||||||
case Constants.messageContentType.communityInviteType:
|
case Constants.messageContentType.communityInviteType:
|
||||||
case Constants.messageContentType.discordMessageType:
|
case Constants.messageContentType.discordMessageType:
|
||||||
case Constants.messageContentType.contactRequestType:
|
case Constants.messageContentType.contactRequestType:
|
||||||
|
case Constants.messageContentType.bridgeMessageType:
|
||||||
return messageComponent
|
return messageComponent
|
||||||
case Constants.messageContentType.unknownContentType:
|
case Constants.messageContentType.unknownContentType:
|
||||||
// NOTE: We could display smth like "unknown message type, please upgrade Status to see it".
|
// NOTE: We could display smth like "unknown message type, please upgrade Status to see it".
|
||||||
|
@ -296,6 +300,8 @@ Loader {
|
||||||
return StatusMessage.ContentType.Invitation;
|
return StatusMessage.ContentType.Invitation;
|
||||||
case Constants.messageContentType.discordMessageType:
|
case Constants.messageContentType.discordMessageType:
|
||||||
return StatusMessage.ContentType.DiscordMessage;
|
return StatusMessage.ContentType.DiscordMessage;
|
||||||
|
case Constants.messageContentType.bridgeMessageType:
|
||||||
|
return StatusMessage.ContentType.BridgeMessage;
|
||||||
case Constants.messageContentType.systemMessagePinnedMessage:
|
case Constants.messageContentType.systemMessagePinnedMessage:
|
||||||
return StatusMessage.ContentType.SystemMessagePinnedMessage;
|
return StatusMessage.ContentType.SystemMessagePinnedMessage;
|
||||||
case Constants.messageContentType.systemMessageMutualEventSent:
|
case Constants.messageContentType.systemMessageMutualEventSent:
|
||||||
|
@ -333,6 +339,11 @@ Loader {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function correctBridgeNameCapitalization(bridgeName) {
|
||||||
|
return (bridgeName === "discord") ? "Discord" : bridgeName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
@ -724,7 +735,14 @@ Loader {
|
||||||
|
|
||||||
messageDetails: StatusMessageDetails {
|
messageDetails: StatusMessageDetails {
|
||||||
contentType: delegate.contentType
|
contentType: delegate.contentType
|
||||||
messageOriginInfo: isDiscordMessage ? qsTr("Imported from discord") : ""
|
messageOriginInfo: {
|
||||||
|
if (isDiscordMessage) {
|
||||||
|
return qsTr("Imported from discord")
|
||||||
|
} else if (isBridgeMessage) {
|
||||||
|
return qsTr("Bridged from %1").arg(d.correctBridgeNameCapitalization(root.bridgeName))
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
messageText: root.messageText
|
messageText: root.messageText
|
||||||
messageContent: {
|
messageContent: {
|
||||||
switch (delegate.contentType)
|
switch (delegate.contentType)
|
||||||
|
@ -747,9 +765,9 @@ Loader {
|
||||||
sender.id: root.senderIsEnsVerified ? "" : Utils.getCompressedPk(root.senderId)
|
sender.id: root.senderIsEnsVerified ? "" : Utils.getCompressedPk(root.senderId)
|
||||||
sender.displayName: root.senderDisplayName
|
sender.displayName: root.senderDisplayName
|
||||||
sender.secondaryName: root.senderOptionalName
|
sender.secondaryName: root.senderOptionalName
|
||||||
sender.isEnsVerified: root.senderIsEnsVerified
|
sender.isEnsVerified: root.isBridgeMessage ? false : root.senderIsEnsVerified
|
||||||
sender.isContact: root.senderIsAdded
|
sender.isContact: root.isBridgeMessage ? false : root.senderIsAdded
|
||||||
sender.trustIndicator: root.senderTrustStatus
|
sender.trustIndicator: root.isBridgeMessage ? StatusContactVerificationIcons.TrustedType.None: root.senderTrustStatus
|
||||||
sender.profileImage {
|
sender.profileImage {
|
||||||
width: 40
|
width: 40
|
||||||
height: 40
|
height: 40
|
||||||
|
@ -757,8 +775,9 @@ Loader {
|
||||||
pubkey: root.senderId
|
pubkey: root.senderId
|
||||||
colorId: Utils.colorIdForPubkey(root.senderId)
|
colorId: Utils.colorIdForPubkey(root.senderId)
|
||||||
colorHash: root.senderColorHash
|
colorHash: root.senderColorHash
|
||||||
showRing: !root.isDiscordMessage && !root.senderIsEnsVerified
|
showRing: !root.isDiscordMessage && !root.senderIsEnsVerified && !root.isBridgeMessage
|
||||||
}
|
}
|
||||||
|
sender.badgeImage: Style.svg("discord-bridge")
|
||||||
}
|
}
|
||||||
|
|
||||||
replyDetails: StatusMessageDetails {
|
replyDetails: StatusMessageDetails {
|
||||||
|
|
|
@ -25,6 +25,8 @@ StatusMenu {
|
||||||
property string selectedUserDisplayName: ""
|
property string selectedUserDisplayName: ""
|
||||||
property string selectedUserIcon: ""
|
property string selectedUserIcon: ""
|
||||||
|
|
||||||
|
property bool isBridgedAccount: false
|
||||||
|
|
||||||
readonly property bool isMe: {
|
readonly property bool isMe: {
|
||||||
return root.selectedUserPublicKey === root.store.contactsStore.myPublicKey;
|
return root.selectedUserPublicKey === root.store.contactsStore.myPublicKey;
|
||||||
}
|
}
|
||||||
|
@ -104,15 +106,18 @@ StatusMenu {
|
||||||
isContact: root.isContact
|
isContact: root.isContact
|
||||||
isCurrentUser: root.isMe
|
isCurrentUser: root.isMe
|
||||||
userIsEnsVerified: (!!contactDetails && contactDetails.ensVerified) || false
|
userIsEnsVerified: (!!contactDetails && contactDetails.ensVerified) || false
|
||||||
|
isBridgedAccount: root.isBridgedAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuSeparator {
|
StatusMenuSeparator {
|
||||||
topPadding: root.topPadding
|
topPadding: root.topPadding
|
||||||
|
visible: !root.isBridgedAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewProfileMenuItem {
|
ViewProfileMenuItem {
|
||||||
id: viewProfileAction
|
id: viewProfileAction
|
||||||
objectName: "viewProfile_StatusItem"
|
objectName: "viewProfile_StatusItem"
|
||||||
|
enabled: !root.isBridgedAccount
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.openProfileClicked(root.selectedUserPublicKey)
|
root.openProfileClicked(root.selectedUserPublicKey)
|
||||||
root.close()
|
root.close()
|
||||||
|
@ -122,7 +127,7 @@ StatusMenu {
|
||||||
SendMessageMenuItem {
|
SendMessageMenuItem {
|
||||||
id: sendMessageMenuItem
|
id: sendMessageMenuItem
|
||||||
objectName: "sendMessage_StatusItem"
|
objectName: "sendMessage_StatusItem"
|
||||||
enabled: root.isContact && !root.isBlockedContact
|
enabled: root.isContact && !root.isBlockedContact && !root.isBridgedAccount
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.createOneToOneChat("", root.selectedUserPublicKey, "")
|
root.createOneToOneChat("", root.selectedUserPublicKey, "")
|
||||||
root.close()
|
root.close()
|
||||||
|
@ -133,7 +138,7 @@ StatusMenu {
|
||||||
id: sendContactRequestMenuItem
|
id: sendContactRequestMenuItem
|
||||||
objectName: "sendContactRequest_StatusItem"
|
objectName: "sendContactRequest_StatusItem"
|
||||||
enabled: !root.isMe && !root.isContact
|
enabled: !root.isMe && !root.isContact
|
||||||
&& !root.isBlockedContact && !root.hasPendingContactRequest
|
&& !root.isBlockedContact && !root.hasPendingContactRequest && !root.isBridgedAccount
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
Global.openContactRequestPopup(root.selectedUserPublicKey, null)
|
Global.openContactRequestPopup(root.selectedUserPublicKey, null)
|
||||||
root.close()
|
root.close()
|
||||||
|
@ -149,6 +154,7 @@ StatusMenu {
|
||||||
&& !root.isBlockedContact
|
&& !root.isBlockedContact
|
||||||
&& root.outgoingVerificationStatus === Constants.verificationStatus.unverified
|
&& root.outgoingVerificationStatus === Constants.verificationStatus.unverified
|
||||||
&& !root.hasActiveReceivedVerificationRequestFrom
|
&& !root.hasActiveReceivedVerificationRequestFrom
|
||||||
|
&& !root.isBridgedAccount
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
Global.openSendIDRequestPopup(root.selectedUserPublicKey, null)
|
Global.openSendIDRequestPopup(root.selectedUserPublicKey, null)
|
||||||
root.close()
|
root.close()
|
||||||
|
@ -167,6 +173,7 @@ StatusMenu {
|
||||||
&& !root.isBlockedContact && !root.isTrusted
|
&& !root.isBlockedContact && !root.isTrusted
|
||||||
&& (root.hasActiveReceivedVerificationRequestFrom
|
&& (root.hasActiveReceivedVerificationRequestFrom
|
||||||
|| root.isVerificationRequestSent)
|
|| root.isVerificationRequestSent)
|
||||||
|
&& !root.isBridgedAccount
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (hasActiveReceivedVerificationRequestFrom) {
|
if (hasActiveReceivedVerificationRequestFrom) {
|
||||||
Global.openIncomingIDRequestPopup(root.selectedUserPublicKey, null)
|
Global.openIncomingIDRequestPopup(root.selectedUserPublicKey, null)
|
||||||
|
@ -183,7 +190,7 @@ StatusMenu {
|
||||||
objectName: "rename_StatusItem"
|
objectName: "rename_StatusItem"
|
||||||
text: qsTr("Rename")
|
text: qsTr("Rename")
|
||||||
icon.name: "edit_pencil"
|
icon.name: "edit_pencil"
|
||||||
enabled: !root.isMe
|
enabled: !root.isMe && !root.isBridgedAccount
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
Global.openNicknamePopupRequested(root.selectedUserPublicKey, contactDetails.localNickname,
|
Global.openNicknamePopupRequested(root.selectedUserPublicKey, contactDetails.localNickname,
|
||||||
"%1 (%2)".arg(root.selectedUserDisplayName).arg(Utils.getElidedCompressedPk(root.selectedUserPublicKey)))
|
"%1 (%2)".arg(root.selectedUserDisplayName).arg(Utils.getElidedCompressedPk(root.selectedUserPublicKey)))
|
||||||
|
@ -196,7 +203,7 @@ StatusMenu {
|
||||||
objectName: "unblock_StatusItem"
|
objectName: "unblock_StatusItem"
|
||||||
text: qsTr("Unblock User")
|
text: qsTr("Unblock User")
|
||||||
icon.name: "remove-circle"
|
icon.name: "remove-circle"
|
||||||
enabled: !root.isMe && root.isBlockedContact
|
enabled: !root.isMe && root.isBlockedContact && !root.isBridgedAccount
|
||||||
onTriggered: Global.unblockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
|
onTriggered: Global.unblockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +219,7 @@ StatusMenu {
|
||||||
text: qsTr("Mark as Untrustworthy")
|
text: qsTr("Mark as Untrustworthy")
|
||||||
icon.name: "warning"
|
icon.name: "warning"
|
||||||
type: StatusAction.Type.Danger
|
type: StatusAction.Type.Danger
|
||||||
enabled: !root.isMe && root.userTrustIsUnknown
|
enabled: !root.isMe && root.userTrustIsUnknown && !root.isBridgedAccount
|
||||||
onTriggered: root.store.contactsStore.markUntrustworthy(root.selectedUserPublicKey)
|
onTriggered: root.store.contactsStore.markUntrustworthy(root.selectedUserPublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +228,7 @@ StatusMenu {
|
||||||
objectName: "removeUntrustworthy_StatusItem"
|
objectName: "removeUntrustworthy_StatusItem"
|
||||||
text: qsTr("Remove Untrustworthy Mark")
|
text: qsTr("Remove Untrustworthy Mark")
|
||||||
icon.name: "warning"
|
icon.name: "warning"
|
||||||
enabled: !root.isMe && root.userIsUntrustworthy
|
enabled: !root.isMe && root.userIsUntrustworthy && !root.isBridgedAccount
|
||||||
onTriggered: root.store.contactsStore.removeTrustStatus(root.selectedUserPublicKey)
|
onTriggered: root.store.contactsStore.removeTrustStatus(root.selectedUserPublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +237,7 @@ StatusMenu {
|
||||||
objectName: "removeContact_StatusItem"
|
objectName: "removeContact_StatusItem"
|
||||||
icon.name: "remove-contact"
|
icon.name: "remove-contact"
|
||||||
type: StatusAction.Type.Danger
|
type: StatusAction.Type.Danger
|
||||||
enabled: root.isContact && !root.isBlockedContact && !root.hasPendingContactRequest
|
enabled: root.isContact && !root.isBlockedContact && !root.hasPendingContactRequest && !root.isBridgedAccount
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
Global.removeContactRequested(root.selectedUserDisplayName, root.selectedUserPublicKey)
|
Global.removeContactRequested(root.selectedUserDisplayName, root.selectedUserPublicKey)
|
||||||
root.close()
|
root.close()
|
||||||
|
@ -243,7 +250,7 @@ StatusMenu {
|
||||||
text: qsTr("Block User")
|
text: qsTr("Block User")
|
||||||
icon.name: "cancel"
|
icon.name: "cancel"
|
||||||
type: StatusAction.Type.Danger
|
type: StatusAction.Type.Danger
|
||||||
enabled: !root.isMe && !root.isBlockedContact
|
enabled: !root.isMe && !root.isBlockedContact && !root.isBridgedAccount
|
||||||
onTriggered: Global.blockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
|
onTriggered: Global.blockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -457,6 +457,7 @@ QtObject {
|
||||||
readonly property int systemMessageMutualEventSent: 15
|
readonly property int systemMessageMutualEventSent: 15
|
||||||
readonly property int systemMessageMutualEventAccepted: 16
|
readonly property int systemMessageMutualEventAccepted: 16
|
||||||
readonly property int systemMessageMutualEventRemoved: 17
|
readonly property int systemMessageMutualEventRemoved: 17
|
||||||
|
readonly property int bridgeMessageType: 18
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property QtObject messageModelRoles: QtObject {
|
readonly property QtObject messageModelRoles: QtObject {
|
||||||
|
|
Loading…
Reference in New Issue