fix: ENS keycap display issues

- run the user's display name (ENS name) thru the `Emoji.parse()`
function as that will convert the potentially UTF-16 encoded name
containing emojis into an image

Fixes #12290
This commit is contained in:
Lukáš Tinkl 2024-05-13 10:05:53 +02:00 committed by Lukáš Tinkl
parent 587594f3b9
commit 94ca1ff22a
12 changed files with 73 additions and 32 deletions

View File

@ -44,13 +44,21 @@ SplitView {
thumbnailImage: "" thumbnailImage: ""
keyUid: "uid_2" keyUid: "uid_2"
} }
ListElement {
keycardCreatedAccount: true
colorId: 3
colorHash: "0xAB38"
username: "8⃣6⃣.eth"
thumbnailImage: ""
keyUid: "uid_4"
}
} }
} }
readonly property QtObject selectedLoginAccount: QtObject { readonly property QtObject selectedLoginAccount: QtObject {
readonly property bool keycardCreatedAccount: false readonly property bool keycardCreatedAccount: false
readonly property int colorId: 0 readonly property int colorId: 0
readonly property string username: "Alice" readonly property string username: "8⃣6⃣.eth"
readonly property string thumbnailImage: "" readonly property string thumbnailImage: ""
readonly property string keyUid: "uid_3" readonly property string keyUid: "uid_3"
} }

View File

@ -480,7 +480,7 @@ SplitView {
TextField { TextField {
id: name id: name
enabled: ensVerified.checked enabled: ensVerified.checked
text: ensVerified.checked ? "mock-ens-name.eth" : "" text: ensVerified.checked ? "8⃣6⃣.eth" : ""
placeholderText: "ENS name" placeholderText: "ENS name"
} }
} }

View File

@ -18,6 +18,10 @@ ListModel {
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
colorId: 7 colorId: 7
isEnsVerified: false isEnsVerified: false
colorHash: [
ListElement {colorId: 0; segmentLength: 2},
ListElement {colorId: 17; segmentLength: 2}
]
} }
ListElement { ListElement {
pubKey: "0x04df12f12f12f12f1234" pubKey: "0x04df12f12f12f12f1234"
@ -33,6 +37,10 @@ ListModel {
icon: "" icon: ""
colorId: 9 colorId: 9
isEnsVerified: false isEnsVerified: false
colorHash: [
ListElement {colorId: 0; segmentLength: 1},
ListElement {colorId: 19; segmentLength: 2}
]
} }
ListElement { ListElement {
pubKey: "0x04d1b7cc0ef3f470f1238" pubKey: "0x04d1b7cc0ef3f470f1238"
@ -58,8 +66,8 @@ ListModel {
isUntrustworthy: true isUntrustworthy: true
displayName: "Maria" displayName: "Maria"
alias: "meth" alias: "meth"
localNickname: "" localNickname: "86.eth"
ensName: "maria.eth" ensName: "8⃣6⃣.eth"
icon: "" icon: ""
colorId: 5 colorId: 5
isEnsVerified: true isEnsVerified: true
@ -79,4 +87,19 @@ ListModel {
colorId: 3 colorId: 3
isEnsVerified: true isEnsVerified: true
} }
ListElement {
pubKey: "0x04d1bed192343f470fabc"
onlineStatus: 0
isContact: true
isVerified: false
isAdmin: false
isUntrustworthy: false
displayName: ""
alias: ""
localNickname: ""
ensName: "8⃣6⃣.eth"
icon: ""
colorId: 7
isEnsVerified: true
}
} }

View File

@ -98,7 +98,7 @@ StatusListItem {
function composeSubtitle() { function composeSubtitle() {
var compose = "" var compose = ""
if(root.userName !== "" && root.nickName !== "") if(root.userName !== "" && root.nickName !== "")
compose = "(" + root.userName + ")" compose = "(" + Emoji.parse(root.userName, "12x12") + ")"
if(compose !== "" && root.pubKey !== "") if(compose !== "" && root.pubKey !== "")
// Composition // Composition
@ -119,7 +119,8 @@ StatusListItem {
} }
// root object settings: // root object settings:
title: root.nickName || root.userName title: root.nickName || Emoji.parse(root.userName)
statusListItemIcon.name: root.nickName || root.userName
statusListItemTitleIcons.sourceComponent: root.isAwaitingAddress ? statusListItemTitleIcons.sourceComponent: root.isAwaitingAddress ?
awaitingAddressComponent : statusContactVerificationIcons awaitingAddressComponent : statusContactVerificationIcons

View File

@ -52,7 +52,7 @@ Item {
font.pixelSize: Theme.primaryTextFontSize font.pixelSize: Theme.primaryTextFontSize
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
color: Theme.palette.primaryColor1 color: Theme.palette.primaryColor1
text: root.amISender ? qsTr("You") : root.sender.displayName text: root.amISender ? qsTr("You") : Emoji.parse(root.sender.displayName)
MouseArea { MouseArea {
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent

View File

@ -26,7 +26,7 @@ QtObject {
throw new Error("Invalid value for 'renderSize' parameter: ", renderSize); throw new Error("Invalid value for 'renderSize' parameter: ", renderSize);
} }
const path = renderFormat == format.svg ? "svg/" : "72x72/" const path = renderFormat === format.svg ? "svg/" : "72x72/"
Twemoji.twemoji.base = base + path Twemoji.twemoji.base = base + path
Twemoji.twemoji.ext = `.${renderFormat}` Twemoji.twemoji.ext = `.${renderFormat}`
@ -44,6 +44,7 @@ QtObject {
}) })
} }
function iconSource(text) { function iconSource(text) {
if (!text) return
const parsed = parse(text); const parsed = parse(text);
const match = parsed.match('src="(.*\.svg).*"'); const match = parsed.match('src="(.*\.svg).*"');
return (match && match.length >= 2) ? match[1] : undefined; return (match && match.length >= 2) ? match[1] : undefined;
@ -52,12 +53,14 @@ QtObject {
return `${base}/svg/${unicode}.svg` return `${base}/svg/${unicode}.svg`
} }
function iconId(text) { function iconId(text) {
if (!text) return
const parsed = parse(text); const parsed = parse(text);
const match = parsed.match('src=".*\/(.+?).svg'); const match = parsed.match('src=".*\/(.+?).svg');
return (match && match.length >= 2) ? match[1] : undefined; return (match && match.length >= 2) ? match[1] : undefined;
} }
// NOTE: doing the same thing as iconId but without checking Twemoji internal checks // NOTE: doing the same thing as iconId but without checking Twemoji internal checks
function iconHex(text) { function iconHex(text) {
if (!text) return
return text.codePointAt(0).toString(16); return text.codePointAt(0).toString(16);
} }
function fromCodePoint(value) { function fromCodePoint(value) {

View File

@ -130,7 +130,7 @@ Item {
Global.openMenu(profileContextMenuComponent, this, { Global.openMenu(profileContextMenuComponent, this, {
myPublicKey: userProfile.pubKey, myPublicKey: userProfile.pubKey,
selectedUserPublicKey: model.pubKey, selectedUserPublicKey: model.pubKey,
selectedUserDisplayName: title, selectedUserDisplayName: nickName || userName,
selectedUserIcon: model.icon, selectedUserIcon: model.icon,
}) })
} else if (mouse.button === Qt.LeftButton) { } else if (mouse.button === Qt.LeftButton) {

View File

@ -6,6 +6,7 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import shared.controls.chat 1.0 import shared.controls.chat 1.0
import utils 1.0 import utils 1.0
@ -34,17 +35,6 @@ Item {
: Theme.palette.statusSelect.menuItemBackgroundColor : Theme.palette.statusSelect.menuItemBackgroundColor
} }
MouseArea {
id: sensor
cursorShape: Qt.PointingHandCursor
anchors.fill: root
hoverEnabled: true
onClicked: {
root.clicked()
}
}
Loader { Loader {
id: userImageOrIcon id: userImageOrIcon
sourceComponent: !!root.image.toString() || !!root.colorId ? userImage : addIcon sourceComponent: !!root.image.toString() || !!root.colorId ? userImage : addIcon
@ -73,8 +63,7 @@ Item {
} }
StatusBaseText { StatusBaseText {
text: root.label text: StatusQUtils.Emoji.parse(root.label)
font.pixelSize: 15
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: userImageOrIcon.right anchors.left: userImageOrIcon.right
anchors.right: root.keycardCreatedAccount? keycardIcon.left : parent.right anchors.right: root.keycardCreatedAccount? keycardIcon.left : parent.right
@ -100,5 +89,16 @@ Item {
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
} }
} }
MouseArea {
id: sensor
cursorShape: Qt.PointingHandCursor
anchors.fill: root
hoverEnabled: true
onClicked: {
root.clicked()
}
}
} }

View File

@ -10,6 +10,7 @@ import StatusQ.Components 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1 import StatusQ.Controls.Validators 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import shared.popups.keycard.helpers 1.0 import shared.popups.keycard.helpers 1.0
@ -153,7 +154,7 @@ Item {
ConfirmationDialog { ConfirmationDialog {
id: obtainingPasswordErrorNotification id: obtainingPasswordErrorNotification
height: 270 height: 270
confirmButtonLabel: qsTr("Ok") confirmButtonLabel: qsTr("OK")
onConfirmButtonClicked: { onConfirmButtonClicked: {
close() close()
@ -217,7 +218,7 @@ Item {
StatusBaseText { StatusBaseText {
id: usernameText id: usernameText
objectName: "currentUserNameLabel" objectName: "currentUserNameLabel"
text: root.startupStore.selectedLoginAccount.username text: StatusQUtils.Emoji.parse(root.startupStore.selectedLoginAccount.username, "24x24")
font.pixelSize: 17 font.pixelSize: 17
anchors.left: userImage.right anchors.left: userImage.right
anchors.right: root.startupStore.selectedLoginAccount.keycardCreatedAccount? anchors.right: root.startupStore.selectedLoginAccount.keycardCreatedAccount?

View File

@ -7,6 +7,7 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Popups.Dialog 0.1 import StatusQ.Popups.Dialog 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import utils 1.0 import utils 1.0
import shared.controls 1.0 import shared.controls 1.0
@ -23,9 +24,11 @@ StatusDialog {
property ObjectModel rightButtons property ObjectModel rightButtons
readonly property string mainDisplayName: ProfileUtils.displayName(contactDetails.localNickname, contactDetails.name, readonly property string mainDisplayName: StatusQUtils.Emoji.parse(
contactDetails.displayName, contactDetails.alias) ProfileUtils.displayName(contactDetails.localNickname, contactDetails.name,
readonly property string optionalDisplayName: ProfileUtils.displayName("", contactDetails.name, contactDetails.displayName, contactDetails.alias) contactDetails.displayName, contactDetails.alias))
readonly property string optionalDisplayName: StatusQUtils.Emoji.parse(
ProfileUtils.displayName("", contactDetails.name, contactDetails.displayName, contactDetails.alias))
width: Math.max(implicitWidth, 480) width: Math.max(implicitWidth, 480)
horizontalPadding: 0 horizontalPadding: 0

View File

@ -265,7 +265,7 @@ Pane {
id: shareProfileCmp id: shareProfileCmp
ShareProfileDialog { ShareProfileDialog {
destroyOnClose: true destroyOnClose: true
title: d.isCurrentUser ? qsTr("Share your profile") : qsTr("%1's profile").arg(d.mainDisplayName) title: d.isCurrentUser ? qsTr("Share your profile") : qsTr("%1's profile").arg(StatusQUtils.Emoji.parse(d.mainDisplayName))
publicKey: root.publicKey publicKey: root.publicKey
linkToProfile: d.linkToProfile linkToProfile: d.linkToProfile
qrCode: root.profileStore.getQrCodeSource(linkToProfile) qrCode: root.profileStore.getQrCodeSource(linkToProfile)
@ -505,7 +505,7 @@ Pane {
font.pixelSize: 22 font.pixelSize: 22
elide: Text.ElideRight elide: Text.ElideRight
text: root.dirty ? root.dirtyValues.displayName text: root.dirty ? root.dirtyValues.displayName
: d.mainDisplayName : StatusQUtils.Emoji.parse(d.mainDisplayName, StatusQUtils.Emoji.size.middle)
} }
StatusContactVerificationIcons { StatusContactVerificationIcons {
id: verificationIcons id: verificationIcons
@ -525,7 +525,7 @@ Pane {
StatusBaseText { StatusBaseText {
id: contactSecondaryName id: contactSecondaryName
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
text: d.optionalDisplayName text: StatusQUtils.Emoji.parse(d.optionalDisplayName)
visible: !!d.userNickName visible: !!d.userNickName
} }
Rectangle { Rectangle {
@ -560,7 +560,8 @@ Pane {
StatusScrollView { StatusScrollView {
id: bioScrollView id: bioScrollView
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 116 Layout.preferredHeight: implicitHeight
Layout.maximumHeight: 120
contentWidth: availableWidth contentWidth: availableWidth
Layout.topMargin: Style.current.halfPadding Layout.topMargin: Style.current.halfPadding
padding: 0 padding: 0

View File

@ -2,6 +2,7 @@ import QtQuick 2.15
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
@ -96,7 +97,7 @@ StatusMenu {
displayNameVisible: false displayNameVisible: false
displayNamePlusIconsVisible: true displayNamePlusIconsVisible: true
editButtonVisible: false editButtonVisible: false
displayName: root.selectedUserDisplayName displayName: StatusQUtils.Emoji.parse(root.selectedUserDisplayName, StatusQUtils.Emoji.size.verySmall)
pubkey: root.selectedUserPublicKey pubkey: root.selectedUserPublicKey
icon: root.selectedUserIcon icon: root.selectedUserIcon
trustStatus: contactDetails && contactDetails.trustStatus ? contactDetails.trustStatus trustStatus: contactDetails && contactDetails.trustStatus ? contactDetails.trustStatus