fix: ENS name issues

- don't display identicon rings for contacts with an ENS name
- prefer the at-form (@foo-user) whenever possible, and don't display their
  username or pubkey unless they are locally given a nickname
- show compressed keys everywhere instead of the regular ones

Fixes: #7319
Fixes: #7515
This commit is contained in:
Lukáš Tinkl 2022-09-23 00:18:15 +02:00 committed by Lukáš Tinkl
parent 54c73b0be7
commit a209d39881
22 changed files with 94 additions and 51 deletions

View File

@ -23,6 +23,8 @@ Column {
property Component popupMenu
property var isEnsVerified: function(pubKey) { return false }
signal chatItemSelected(string categoryId, string id)
signal chatItemUnmuted(string id)
signal chatItemReordered(string id, int from, int to)
@ -122,8 +124,8 @@ Column {
asset.color: !!model.color ? model.color : Theme.palette.userCustomizationColors[model.colorId]
asset.isImage: model.icon.includes("data")
asset.name: model.icon
ringSettings.ringSpecModel: model.colorHash
onlineStatus: model.onlineStatus
ringSettings.ringSpecModel: type === StatusChatListItem.Type.OneToOneChat && root.isEnsVerified(chatId) ? undefined : model.colorHash
onlineStatus: !!model.onlineStatus ? model.onlineStatus : StatusChatListItem.OnlineStatus.Inactive
sensor.cursorShape: dragSensor.cursorShape

View File

@ -87,7 +87,7 @@ StatusListItem {
id: d
// Subtitle composition:
function composeSubtitile() {
function composeSubtitle() {
var compose = ""
if(root.userName !== "" && root.nickName !== "")
compose = "(" + root.userName + ")"
@ -104,21 +104,25 @@ StatusListItem {
// Short keychat composition:
function composeShortKeyChat(pubKey) {
if (!pubKey)
return ""
return pubKey.substring(0, 5) + "..." + pubKey.substring(pubKey.length - 3)
}
}
// root object settings:
title: (root.nickName === "") ? root.userName : root.nickName
title: root.nickName || root.userName
statusListItemTitleIcons.sourceComponent: StatusContactVerificationIcons {
isContact: root.isContact
trustIndicator: {
if (root.isVerified) return StatusContactVerificationIcons.TrustedType.Verified
else if (root.isUntrustworthy) return StatusContactVerificationIcons.TrustedType.Untrustworthy
if (root.isVerified)
return StatusContactVerificationIcons.TrustedType.Verified
if (root.isUntrustworthy)
return StatusContactVerificationIcons.TrustedType.Untrustworthy
return StatusContactVerificationIcons.TrustedType.None
}
}
subTitle: d.composeSubtitile()
subTitle: d.composeSubtitle()
statusListItemSubTitle.font.pixelSize: 10
statusListItemIcon.badge.visible: true
statusListItemIcon.badge.color: root.status === 1 ? Theme.palette.successColor1 : Theme.palette.baseColor1 // FIXME
@ -130,6 +134,8 @@ StatusListItem {
leftPadding: 8
asset.width: 32
asset.height: 32
asset.charactersLen: 2
asset.letterSize: asset._twoLettersSize
statusListItemIcon.anchors.verticalCenter: sensor.verticalCenter
statusListItemIcon.anchors.top: undefined
statusListItemIcon.badge.border.width: 2

View File

@ -35,16 +35,13 @@ Item {
RowLayout {
id: layout
spacing: 4
TextEdit {
StatusBaseText {
id: primaryDisplayName
Layout.alignment: Qt.AlignBottom
font.family: Theme.palette.baseFont.name
verticalAlignment: Text.AlignVCenter
Layout.bottomMargin: 2 // offset for the underline to stay vertically centered
font.weight: Font.Medium
font.pixelSize: 15
font.underline: mouseArea.containsMouse
readOnly: true
wrapMode: Text.WordWrap
selectByMouse: true
color: Theme.palette.primaryColor1
text: root.amISender ? qsTr("You") : root.sender.displayName
MouseArea {
@ -61,53 +58,55 @@ Item {
}
StatusBaseText {
id: messageOriginInfo
Layout.alignment: Qt.AlignVCenter
visible: root.messageOriginInfo !== ""
verticalAlignment: Text.AlignVCenter
visible: text
color: Theme.palette.baseColor1
font.pixelSize: 10
text: root.messageOriginInfo
}
StatusContactVerificationIcons {
id: verificationIcons
visible: !root.amISender
isContact: root.isContact
trustIndicator: root.trustIndicator
}
StatusBaseText {
id: secondaryDisplayName
Layout.alignment: Qt.AlignVCenter
verticalAlignment: Text.AlignVCenter
visible: !root.amISender && !!root.sender.secondaryName
color: Theme.palette.baseColor1
font.pixelSize: 10
text: `(${root.sender.secondaryName})`
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
visible: secondaryDisplayName.visible
verticalAlignment: Text.AlignVCenter
visible: secondaryDisplayName.visible && tertiaryDetailText.visible
font.pixelSize: 10
color: Theme.palette.baseColor1
text: "•"
}
StatusBaseText {
id: tertiaryDetailText
visible: !root.amISender && root.messageOriginInfo === ""
Layout.alignment: Qt.AlignVCenter
verticalAlignment: Text.AlignVCenter
visible: !root.amISender && root.messageOriginInfo === "" && text
font.pixelSize: 10
elide: Text.ElideMiddle
color: Theme.palette.baseColor1
text: Utils.elideText(tertiaryDetail, 5, 3)
text: root.tertiaryDetail ? Utils.elideText(root.tertiaryDetail, 5, 3) : ""
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
visible: tertiaryDetailText.visible
verticalAlignment: Text.AlignVCenter
visible: verificationIcons.width <= 0 || secondaryDisplayName.visible || root.amISender || tertiaryDetailText.visible
font.pixelSize: 10
color: Theme.palette.baseColor1
text: "•"
}
StatusTimeStampLabel {
verticalAlignment: Text.AlignVCenter
id: timestampText
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
verticalAlignment: Text.AlignVCenter
color: Theme.palette.dangerColor1
font.pixelSize: 12
text: root.resendText

View File

@ -144,7 +144,9 @@ Item {
Connections {
target: root.settings
onRingSpecModelChanged: requestPaint()
function onRingSpecModelChanged() {
requestPaint()
}
}
}
}

View File

@ -10,8 +10,6 @@ import shared.panels 1.0
import shared.status 1.0
import utils 1.0
import "../controls"
import SortFilterProxyModel 0.2
Item {
@ -74,8 +72,8 @@ Item {
delegate: StatusMemberListItem {
width: ListView.view.width
nickName: model.localNickname
userName: model.displayName !== "" ? model.displayName : model.alias
pubKey: Utils.getCompressedPk(model.pubKey)
userName: !!model.ensName ? "@" + Utils.removeStatusEns(model.ensName) : model.displayName !== "" ? model.displayName : model.alias
pubKey: !!model.ensName ? "" : Utils.getCompressedPk(model.pubKey)
isContact: model.isContact
isVerified: model.isVerified
isUntrustworthy: model.isUntrustworthy
@ -95,7 +93,7 @@ Item {
asset.isLetterIdenticon: (asset.name === "")
asset.color: Utils.colorForColorId(model.colorId)
status: model.onlineStatus
ringSettings.ringSpecModel: Utils.getColorHashAsJson(model.pubKey) // FIXME: use model.colorHash
ringSettings.ringSpecModel: !!model.ensName ? undefined : Utils.getColorHashAsJson(model.pubKey, true) // FIXME: use model.colorHash
onClicked: {
if (mouse.button === Qt.RightButton) {
// Set parent, X & Y positions for the messageContextMenu

View File

@ -82,9 +82,7 @@ SettingsPageLayout {
if (root.membersModel.count === 0) {
return qsTr("No members to search")
} else {
return qsTr("Search %1's %2 member%3").arg(root.communityName)
.arg(root.membersModel.count)
.arg(root.membersModel.count > 1 ? "s" : "")
return qsTr("Search %1's %n member(s)", "", root.membersModel.count).arg(root.communityName)
}
}
panelType: CommunityMembersTabPanel.TabType.AllMembers

View File

@ -42,7 +42,7 @@ Item {
StatusInput {
id: memberSearch
Layout.preferredWidth: 350
Layout.preferredWidth: 400
Layout.leftMargin: 12
maximumHeight: 36
topPadding: 0
@ -126,7 +126,7 @@ Item {
height: visible ? implicitHeight : 0
color: "transparent"
pubKey: Utils.getElidedCompressedPk(model.pubKey)
pubKey: model.ensName ? "" : Utils.getElidedCompressedPk(model.pubKey)
nickName: model.localNickname
userName: model.displayName
status: model.onlineStatus
@ -136,7 +136,7 @@ Item {
asset.isLetterIdenticon: !model.icon
asset.width: 40
asset.height: 40
ringSettings.ringSpecModel: Utils.getColorHashAsJson(model.pubKey)
ringSettings.ringSpecModel: !!model.ensName ? undefined : Utils.getColorHashAsJson(model.pubKey, true)
statusListItemIcon.badge.visible: (root.panelType === CommunityMembersTabPanel.TabType.AllMembers)
onClicked: root.userProfileClicked(model.pubKey)

View File

@ -252,7 +252,19 @@ RowLayout {
StatusChatInfoButton {
objectName: "chatInfoBtnInHeader"
title: chatContentModule? chatContentModule.chatDetails.name : ""
title: {
const module = root.rootStore.currentChatContentModule()
if(!module)
return ""
if (module.chatDetails.type === Constants.chatType.oneToOne) {
const d = Utils.getContactDetailsAsJson(module.chatDetails.id)
if (!!d.displayName)
return d.displayName
}
return module.chatDetails.name
}
subTitle: {
if(!chatContentModule)
return ""

View File

@ -158,6 +158,7 @@ Item {
}
highlightItem: !root.store.openCreateChat
isEnsVerified: function(pubKey) { return Utils.isEnsVerified(pubKey) }
onChatItemSelected: {
Global.closeCreateChatView()
root.chatSectionModule.setActiveItem(id, "")

View File

@ -9,7 +9,8 @@ StatusListItem {
subTitle: community.amISectionAdmin ? qsTr("Admin") : qsTr("Member")
asset.name: !!community.image ? community.image : community.name
asset.isImage: asset.name.includes("data")
asset.letterSize: 14
asset.isLetterIdenticon: !community.image
asset.color: community.color
asset.width: 40
asset.height: 40
}

View File

@ -50,18 +50,27 @@ StatusListItem {
signal rejectionRemoved(string publicKey)
signal textClicked(string publicKey)
subTitle: Utils.getElidedCompressedPk(root.publicKey)
readonly property var d: Utils.getContactDetailsAsJson(root.publicKey)
subTitle: {
if (d.ensVerified) {
if (d.localNickname)
return '@' + Utils.removeStatusEns(d.name)
return ""
}
return Utils.getElidedCompressedPk(root.publicKey)
}
asset.width: 40
asset.height: 40
asset.color: Utils.colorForPubkey(root.publicKey)
asset.letterSize: Math.max(4, root.asset.width / 2.4)
asset.letterSize: asset._twoLettersSize
asset.charactersLen: 2
asset.name: root.iconSource
asset.isImage: asset.name.includes("data")
asset.isLetterIdenticon: root.iconSource.toString() === ""
ringSettings {
ringSpecModel: root.name.startsWith('@') ? undefined : Utils.getColorHashAsJson(root.publicKey)
ringSpecModel: Utils.getColorHashAsJson(root.publicKey)
ringPxSize: Math.max(asset.width / 24.0)
}

View File

@ -361,7 +361,7 @@ Item {
identicon.asset.height: height
identicon.asset.charactersLen: 2
identicon.asset.color: Utils.colorForPubkey(appMain.rootStore.userProfileInst.pubKey)
identicon.ringSettings.ringSpecModel: Utils.getColorHashAsJson(appMain.rootStore.userProfileInst.pubKey)
identicon.ringSettings.ringSpecModel: appMain.rootStore.userProfileInst.ensName ? undefined : Utils.getColorHashAsJson(appMain.rootStore.userProfileInst.pubKey, true)
badge.visible: true
badge.anchors {

View File

@ -26,6 +26,7 @@ Item {
property int trustStatus
property bool isContact: false
property bool isCurrentUser
property bool userIsEnsVerified
property int imageSize: ProfileHeader.ImageSize.Compact
property bool displayNameVisible: true
@ -80,6 +81,7 @@ Item {
interactive: false
imageWidth: d.getSize(36, 80, 160)
imageHeight: imageWidth
showRing: !root.userIsEnsVerified
}
StatusRoundButton {

View File

@ -14,8 +14,9 @@ StatusMemberListItem {
id: root
readonly property string _pubKey: model.pubKey // expose uncompressed pubkey
readonly property bool hasEnsName: Utils.isEnsVerified(model.pubKey)
pubKey: Utils.getCompressedPk(model.pubKey)
pubKey: hasEnsName ? "" : Utils.getCompressedPk(model.pubKey)
nickName: model.localNickname
userName: model.displayName
isVerified: model.isVerified
@ -27,6 +28,6 @@ StatusMemberListItem {
asset.isLetterIdenticon: (asset.name === "")
status: model.onlineStatus
statusListItemIcon.badge.border.color: sensor.containsMouse ? Theme.palette.baseColor2 : Theme.palette.baseColor4
ringSettings.ringSpecModel: Utils.getColorHashAsJson(model.pubKey)
ringSettings.ringSpecModel: hasEnsName ? undefined : Utils.getColorHashAsJson(model.pubKey, true)
color: (sensor.containsMouse || highlighted) ? Theme.palette.baseColor2 : "transparent"
}

View File

@ -462,6 +462,7 @@ StatusDialog {
userPublicKey: popup.userPublicKey
userDisplayName: popup.userDisplayName
userIcon: popup.userIcon
userIsEnsVerified: popup.userIsEnsVerified
onAccepted: popup.contactsStore.sendContactRequest(userPublicKey, message)
onClosed: popup.close()
}

View File

@ -17,6 +17,7 @@ StatusModal {
property string userPublicKey: ""
property string userDisplayName: ""
property string userIcon: ""
property bool userIsEnsVerified
signal accepted(string message)
@ -42,6 +43,7 @@ StatusModal {
displayName: root.userDisplayName
pubkey: root.userPublicKey
icon: root.userIcon
userIsEnsVerified: root.userIsEnsVerified
displayNameVisible: true
pubkeyVisible: true

View File

@ -23,6 +23,7 @@ StatusPopupMenu {
displayName: root.store.userProfileInst.name
pubkey: root.store.userProfileInst.pubKey
icon: root.store.userProfileInst.icon
userIsEnsVerified: !!root.store.userProfileInst.ensName
}
StatusMenuSeparator {

View File

@ -60,7 +60,7 @@ Item {
asset.width: 40
asset.height: 40
asset.color: Utils.colorForColorId(model.colorId)
ringSettings.ringSpecModel: Utils.getColorHashAsJson(model.pubKey)
ringSettings.ringSpecModel: model.ensName ? undefined : Utils.getColorHashAsJson(model.pubKey, true)
statusListItemIcon.badge.border.color: Theme.palette.baseColor4
statusListItemIcon.badge.implicitHeight: 14 // 10 px + 2 px * 2 borders
statusListItemIcon.badge.implicitWidth: 14 // 10 px + 2 px * 2 borders

View File

@ -173,6 +173,7 @@ Rectangle {
isContact: root.isContact
store: root.profileStore
isCurrentUser: root.isCurrentUser
userIsEnsVerified: root.userIsEnsVerified
displayNameVisible: false
displayNamePlusIconsVisible: true

View File

@ -195,6 +195,7 @@ StatusPopupMenu {
: Constants.trustStatus.unknown
isContact: root.isContact
isCurrentUser: root.isMe
userIsEnsVerified: !!d.contactDetails && d.contactDetails.ensVerified
}
Item {

View File

@ -212,7 +212,6 @@ Loader {
// }
// }
height: implicitHeight
z: (typeof chatLogView === "undefined") ? 1 : (chatLogView.count - index)
sourceComponent: {
@ -562,7 +561,7 @@ Loader {
}
amISender: root.amISender
sender.id: root.senderId
sender.id: root.senderIsEnsVerified ? "" : Utils.getCompressedPk(root.senderId)
sender.displayName: root.senderDisplayName
sender.secondaryName: root.senderOptionalName
sender.isEnsVerified: root.senderIsEnsVerified

View File

@ -562,6 +562,12 @@ QtObject {
}
}
function isEnsVerified(publicKey) {
if (!publicKey)
return false
return getContactDetailsAsJson(publicKey).ensVerified
}
function getEmojiHashAsJson(publicKey) {
if (publicKey === "") {
return ""
@ -570,10 +576,11 @@ QtObject {
return JSON.parse(jsonObj)
}
function getColorHashAsJson(publicKey) {
if (publicKey === "") {
return ""
}
function getColorHashAsJson(publicKey, force=false) {
if (publicKey === "")
return
if (!force && isEnsVerified(publicKey))
return
let jsonObj = globalUtils.getColorHashAsJson(publicKey)
return JSON.parse(jsonObj)
}