From 94ca1ff22a4aa3b843308deafa5ff7e7670920ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tinkl?= Date: Mon, 13 May 2024 10:05:53 +0200 Subject: [PATCH] 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 --- storybook/pages/LoginViewPage.qml | 10 ++++++- storybook/pages/ProfileDialogViewPage.qml | 2 +- storybook/src/Models/UsersModel.qml | 27 +++++++++++++++++-- .../Components/StatusMemberListItem.qml | 5 ++-- .../Components/StatusMessageHeader.qml | 2 +- ui/StatusQ/src/StatusQ/Core/Utils/Emoji.qml | 5 +++- .../AppLayouts/Chat/panels/UserListPanel.qml | 2 +- .../panels/AccountMenuItemPanel.qml | 26 +++++++++--------- .../AppLayouts/Onboarding/views/LoginView.qml | 5 ++-- .../shared/popups/CommonContactDialog.qml | 9 ++++--- ui/imports/shared/views/ProfileDialogView.qml | 9 ++++--- .../shared/views/chat/ProfileContextMenu.qml | 3 ++- 12 files changed, 73 insertions(+), 32 deletions(-) diff --git a/storybook/pages/LoginViewPage.qml b/storybook/pages/LoginViewPage.qml index e469e7ad19..af0a742134 100644 --- a/storybook/pages/LoginViewPage.qml +++ b/storybook/pages/LoginViewPage.qml @@ -44,13 +44,21 @@ SplitView { thumbnailImage: "" 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 bool keycardCreatedAccount: false readonly property int colorId: 0 - readonly property string username: "Alice" + readonly property string username: "8️⃣6️⃣.eth" readonly property string thumbnailImage: "" readonly property string keyUid: "uid_3" } diff --git a/storybook/pages/ProfileDialogViewPage.qml b/storybook/pages/ProfileDialogViewPage.qml index 7bfd6c6e30..a877ff923a 100644 --- a/storybook/pages/ProfileDialogViewPage.qml +++ b/storybook/pages/ProfileDialogViewPage.qml @@ -480,7 +480,7 @@ SplitView { TextField { id: name enabled: ensVerified.checked - text: ensVerified.checked ? "mock-ens-name.eth" : "" + text: ensVerified.checked ? "8⃣6⃣.eth" : "" placeholderText: "ENS name" } } diff --git a/storybook/src/Models/UsersModel.qml b/storybook/src/Models/UsersModel.qml index 61ad352dfa..f68836e6e7 100644 --- a/storybook/src/Models/UsersModel.qml +++ b/storybook/src/Models/UsersModel.qml @@ -18,6 +18,10 @@ ListModel { nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" colorId: 7 isEnsVerified: false + colorHash: [ + ListElement {colorId: 0; segmentLength: 2}, + ListElement {colorId: 17; segmentLength: 2} + ] } ListElement { pubKey: "0x04df12f12f12f12f1234" @@ -33,6 +37,10 @@ ListModel { icon: "" colorId: 9 isEnsVerified: false + colorHash: [ + ListElement {colorId: 0; segmentLength: 1}, + ListElement {colorId: 19; segmentLength: 2} + ] } ListElement { pubKey: "0x04d1b7cc0ef3f470f1238" @@ -58,8 +66,8 @@ ListModel { isUntrustworthy: true displayName: "Maria" alias: "meth" - localNickname: "" - ensName: "maria.eth" + localNickname: "86.eth" + ensName: "8⃣6⃣.eth" icon: "" colorId: 5 isEnsVerified: true @@ -79,4 +87,19 @@ ListModel { colorId: 3 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 + } } diff --git a/ui/StatusQ/src/StatusQ/Components/StatusMemberListItem.qml b/ui/StatusQ/src/StatusQ/Components/StatusMemberListItem.qml index ae6354d4d0..0f14fb7906 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusMemberListItem.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusMemberListItem.qml @@ -98,7 +98,7 @@ StatusListItem { function composeSubtitle() { var compose = "" if(root.userName !== "" && root.nickName !== "") - compose = "(" + root.userName + ")" + compose = "(" + Emoji.parse(root.userName, "12x12") + ")" if(compose !== "" && root.pubKey !== "") // Composition @@ -119,7 +119,8 @@ StatusListItem { } // 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 ? awaitingAddressComponent : statusContactVerificationIcons diff --git a/ui/StatusQ/src/StatusQ/Components/StatusMessageHeader.qml b/ui/StatusQ/src/StatusQ/Components/StatusMessageHeader.qml index ba9ce20461..525722665f 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusMessageHeader.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusMessageHeader.qml @@ -52,7 +52,7 @@ Item { font.pixelSize: Theme.primaryTextFontSize wrapMode: Text.WordWrap color: Theme.palette.primaryColor1 - text: root.amISender ? qsTr("You") : root.sender.displayName + text: root.amISender ? qsTr("You") : Emoji.parse(root.sender.displayName) MouseArea { id: mouseArea anchors.fill: parent diff --git a/ui/StatusQ/src/StatusQ/Core/Utils/Emoji.qml b/ui/StatusQ/src/StatusQ/Core/Utils/Emoji.qml index 9b4852ffc0..f72f88d337 100644 --- a/ui/StatusQ/src/StatusQ/Core/Utils/Emoji.qml +++ b/ui/StatusQ/src/StatusQ/Core/Utils/Emoji.qml @@ -26,7 +26,7 @@ QtObject { 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.ext = `.${renderFormat}` @@ -44,6 +44,7 @@ QtObject { }) } function iconSource(text) { + if (!text) return const parsed = parse(text); const match = parsed.match('src="(.*\.svg).*"'); return (match && match.length >= 2) ? match[1] : undefined; @@ -52,12 +53,14 @@ QtObject { return `${base}/svg/${unicode}.svg` } function iconId(text) { + if (!text) return const parsed = parse(text); const match = parsed.match('src=".*\/(.+?).svg'); return (match && match.length >= 2) ? match[1] : undefined; } // NOTE: doing the same thing as iconId but without checking Twemoji internal checks function iconHex(text) { + if (!text) return return text.codePointAt(0).toString(16); } function fromCodePoint(value) { diff --git a/ui/app/AppLayouts/Chat/panels/UserListPanel.qml b/ui/app/AppLayouts/Chat/panels/UserListPanel.qml index ac699d4ff2..5fbed89424 100644 --- a/ui/app/AppLayouts/Chat/panels/UserListPanel.qml +++ b/ui/app/AppLayouts/Chat/panels/UserListPanel.qml @@ -130,7 +130,7 @@ Item { Global.openMenu(profileContextMenuComponent, this, { myPublicKey: userProfile.pubKey, selectedUserPublicKey: model.pubKey, - selectedUserDisplayName: title, + selectedUserDisplayName: nickName || userName, selectedUserIcon: model.icon, }) } else if (mouse.button === Qt.LeftButton) { diff --git a/ui/app/AppLayouts/Onboarding/panels/AccountMenuItemPanel.qml b/ui/app/AppLayouts/Onboarding/panels/AccountMenuItemPanel.qml index 1d3a54e819..aa7441a449 100644 --- a/ui/app/AppLayouts/Onboarding/panels/AccountMenuItemPanel.qml +++ b/ui/app/AppLayouts/Onboarding/panels/AccountMenuItemPanel.qml @@ -6,6 +6,7 @@ import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Components 0.1 import StatusQ.Popups 0.1 +import StatusQ.Core.Utils 0.1 as StatusQUtils import shared.controls.chat 1.0 import utils 1.0 @@ -34,17 +35,6 @@ Item { : Theme.palette.statusSelect.menuItemBackgroundColor } - MouseArea { - id: sensor - cursorShape: Qt.PointingHandCursor - anchors.fill: root - hoverEnabled: true - - onClicked: { - root.clicked() - } - } - Loader { id: userImageOrIcon sourceComponent: !!root.image.toString() || !!root.colorId ? userImage : addIcon @@ -73,8 +63,7 @@ Item { } StatusBaseText { - text: root.label - font.pixelSize: 15 + text: StatusQUtils.Emoji.parse(root.label) anchors.verticalCenter: parent.verticalCenter anchors.left: userImageOrIcon.right anchors.right: root.keycardCreatedAccount? keycardIcon.left : parent.right @@ -100,5 +89,16 @@ Item { color: Theme.palette.baseColor1 } } + + MouseArea { + id: sensor + cursorShape: Qt.PointingHandCursor + anchors.fill: root + hoverEnabled: true + + onClicked: { + root.clicked() + } + } } diff --git a/ui/app/AppLayouts/Onboarding/views/LoginView.qml b/ui/app/AppLayouts/Onboarding/views/LoginView.qml index c2bc9ce92d..dd70b2f42c 100644 --- a/ui/app/AppLayouts/Onboarding/views/LoginView.qml +++ b/ui/app/AppLayouts/Onboarding/views/LoginView.qml @@ -10,6 +10,7 @@ import StatusQ.Components 0.1 import StatusQ.Controls 0.1 import StatusQ.Controls.Validators 0.1 import StatusQ.Popups 0.1 +import StatusQ.Core.Utils 0.1 as StatusQUtils import shared.popups.keycard.helpers 1.0 @@ -153,7 +154,7 @@ Item { ConfirmationDialog { id: obtainingPasswordErrorNotification height: 270 - confirmButtonLabel: qsTr("Ok") + confirmButtonLabel: qsTr("OK") onConfirmButtonClicked: { close() @@ -217,7 +218,7 @@ Item { StatusBaseText { id: usernameText objectName: "currentUserNameLabel" - text: root.startupStore.selectedLoginAccount.username + text: StatusQUtils.Emoji.parse(root.startupStore.selectedLoginAccount.username, "24x24") font.pixelSize: 17 anchors.left: userImage.right anchors.right: root.startupStore.selectedLoginAccount.keycardCreatedAccount? diff --git a/ui/imports/shared/popups/CommonContactDialog.qml b/ui/imports/shared/popups/CommonContactDialog.qml index bdbb4a1ff6..6cd5e34bd1 100644 --- a/ui/imports/shared/popups/CommonContactDialog.qml +++ b/ui/imports/shared/popups/CommonContactDialog.qml @@ -7,6 +7,7 @@ import StatusQ.Core.Theme 0.1 import StatusQ.Components 0.1 import StatusQ.Controls 0.1 import StatusQ.Popups.Dialog 0.1 +import StatusQ.Core.Utils 0.1 as StatusQUtils import utils 1.0 import shared.controls 1.0 @@ -23,9 +24,11 @@ StatusDialog { property ObjectModel rightButtons - readonly property string mainDisplayName: ProfileUtils.displayName(contactDetails.localNickname, contactDetails.name, - contactDetails.displayName, contactDetails.alias) - readonly property string optionalDisplayName: ProfileUtils.displayName("", contactDetails.name, contactDetails.displayName, contactDetails.alias) + readonly property string mainDisplayName: StatusQUtils.Emoji.parse( + ProfileUtils.displayName(contactDetails.localNickname, contactDetails.name, + contactDetails.displayName, contactDetails.alias)) + readonly property string optionalDisplayName: StatusQUtils.Emoji.parse( + ProfileUtils.displayName("", contactDetails.name, contactDetails.displayName, contactDetails.alias)) width: Math.max(implicitWidth, 480) horizontalPadding: 0 diff --git a/ui/imports/shared/views/ProfileDialogView.qml b/ui/imports/shared/views/ProfileDialogView.qml index a93ee6807a..260eab236a 100644 --- a/ui/imports/shared/views/ProfileDialogView.qml +++ b/ui/imports/shared/views/ProfileDialogView.qml @@ -265,7 +265,7 @@ Pane { id: shareProfileCmp ShareProfileDialog { 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 linkToProfile: d.linkToProfile qrCode: root.profileStore.getQrCodeSource(linkToProfile) @@ -505,7 +505,7 @@ Pane { font.pixelSize: 22 elide: Text.ElideRight text: root.dirty ? root.dirtyValues.displayName - : d.mainDisplayName + : StatusQUtils.Emoji.parse(d.mainDisplayName, StatusQUtils.Emoji.size.middle) } StatusContactVerificationIcons { id: verificationIcons @@ -525,7 +525,7 @@ Pane { StatusBaseText { id: contactSecondaryName color: Theme.palette.baseColor1 - text: d.optionalDisplayName + text: StatusQUtils.Emoji.parse(d.optionalDisplayName) visible: !!d.userNickName } Rectangle { @@ -560,7 +560,8 @@ Pane { StatusScrollView { id: bioScrollView Layout.fillWidth: true - Layout.preferredHeight: 116 + Layout.preferredHeight: implicitHeight + Layout.maximumHeight: 120 contentWidth: availableWidth Layout.topMargin: Style.current.halfPadding padding: 0 diff --git a/ui/imports/shared/views/chat/ProfileContextMenu.qml b/ui/imports/shared/views/chat/ProfileContextMenu.qml index 417b49338e..892e753777 100644 --- a/ui/imports/shared/views/chat/ProfileContextMenu.qml +++ b/ui/imports/shared/views/chat/ProfileContextMenu.qml @@ -2,6 +2,7 @@ import QtQuick 2.15 import StatusQ.Popups 0.1 import StatusQ.Components 0.1 +import StatusQ.Core.Utils 0.1 as StatusQUtils import utils 1.0 import shared 1.0 @@ -96,7 +97,7 @@ StatusMenu { displayNameVisible: false displayNamePlusIconsVisible: true editButtonVisible: false - displayName: root.selectedUserDisplayName + displayName: StatusQUtils.Emoji.parse(root.selectedUserDisplayName, StatusQUtils.Emoji.size.verySmall) pubkey: root.selectedUserPublicKey icon: root.selectedUserIcon trustStatus: contactDetails && contactDetails.trustStatus ? contactDetails.trustStatus