From 4b24497899c85c7f3e8cd6a40a372f95175ea90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tinkl?= Date: Fri, 9 Feb 2024 16:52:28 +0100 Subject: [PATCH] fix(profile): add online status badge to profile picture - adds the green/gray dot (aka online indicator) to Profile dialog and context menu (via ProfileHeader and UserImage components) - add the respective combobox to storybook too Fixes #13480 --- storybook/pages/ProfileDialogViewPage.qml | 16 ++++++++++++++-- .../StatusQ/Components/StatusSmartIdenticon.qml | 2 +- .../shared/controls/chat/ProfileHeader.qml | 3 ++- ui/imports/shared/controls/chat/UserImage.qml | 15 +++++++++++++++ .../shared/popups/SendContactRequestModal.qml | 1 + ui/imports/shared/views/ProfileDialogView.qml | 10 ++++++++-- .../shared/views/chat/ProfileContextMenu.qml | 6 +++++- .../shared/views/profile/ShareProfileDialog.qml | 1 + ui/imports/utils/Constants.qml | 1 + 9 files changed, 48 insertions(+), 7 deletions(-) diff --git a/storybook/pages/ProfileDialogViewPage.qml b/storybook/pages/ProfileDialogViewPage.qml index e7be4a980b..fd3da618c5 100644 --- a/storybook/pages/ProfileDialogViewPage.qml +++ b/storybook/pages/ProfileDialogViewPage.qml @@ -53,7 +53,7 @@ SplitView { // mainModuleInst mock QtObject { - function getContactDetailsAsJson(publicKey, getVerificationRequest=false) { + function getContactDetailsAsJson(publicKey, getVerificationRequest=true, getOnlineStatus=false, includeDetails=false) { return JSON.stringify({ displayName: displayName.text, optionalName: "", displayIcon: "", @@ -84,7 +84,8 @@ SplitView { text: "__github", url: "https://github.com/status-im", icon: "github" - }]) + }]), + onlineStatus: ctrlOnlineStatus.currentValue }) } Component.onCompleted: { @@ -354,6 +355,17 @@ SplitView { { value: Constants.trustStatus.untrustworthy, text: "untrustworthy" } ] } + Label { text: "onlineStatus" } + ComboBox { + id: ctrlOnlineStatus + textRole: "text" + valueRole: "value" + model: [ + { value: Constants.onlineStatus.unknown, text: "unknown" }, + { value: Constants.onlineStatus.inactive, text: "inactive" }, + { value: Constants.onlineStatus.online, text: "online" } + ] + } } RowLayout { Layout.fillWidth: true diff --git a/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml b/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml index e95924cabd..b1d64f44c5 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml @@ -9,7 +9,7 @@ Loader { property string name: "" property int dZ: 100 - // Badge color properties must be set if badgeItem.visible = true + // Badge color properties must be set if badge.visible = true property alias badge: statusBadge property alias bridgeBadge: bridgeBadge diff --git a/ui/imports/shared/controls/chat/ProfileHeader.qml b/ui/imports/shared/controls/chat/ProfileHeader.qml index 734b9cc7ea..52d9e2a4bf 100644 --- a/ui/imports/shared/controls/chat/ProfileHeader.qml +++ b/ui/imports/shared/controls/chat/ProfileHeader.qml @@ -25,6 +25,7 @@ Item { property string icon property url previewIcon: icon property int trustStatus + property int onlineStatus: Constants.onlineStatus.unknown property bool isContact: false property bool isBlocked property bool isCurrentUser @@ -121,6 +122,7 @@ Item { imageHeight: imageWidth ensVerified: root.userIsEnsVerified loading: root.loading + onlineStatus: root.onlineStatus isBridgedAccount: root.isBridgedAccount } @@ -279,7 +281,6 @@ Item { id: editImageMenuComponent StatusMenu { - StatusAction { text: !!root.icon ? qsTr("Select different image") : qsTr("Select image") assetSettings.name: "image" diff --git a/ui/imports/shared/controls/chat/UserImage.qml b/ui/imports/shared/controls/chat/UserImage.qml index 24e3977a0a..337c2044ce 100644 --- a/ui/imports/shared/controls/chat/UserImage.qml +++ b/ui/imports/shared/controls/chat/UserImage.qml @@ -22,6 +22,7 @@ Loader { property bool ensVerified: false property bool loading: false property bool isBridgedAccount: false + property int onlineStatus: Constants.onlineStatus.unknown property int colorId: Utils.colorIdForPubkey(pubkey) property var colorHash: Utils.getColorHashAsJson(pubkey, ensVerified) @@ -42,6 +43,20 @@ Loader { ringSpecModel: root.showRing ? root.colorHash : undefined } loading: root.loading + + badge.visible: root.onlineStatus !== Constants.onlineStatus.unknown && !root.isBridgedAccount + badge.width: root.imageWidth/4 + badge.height: root.imageWidth/4 + badge.border.width: 0.05 * root.imageWidth + badge.border.color: Theme.palette.statusBadge.foregroundColor + badge.color: { + if (root.onlineStatus === Constants.onlineStatus.online) + return Style.current.green + return Style.current.midGrey + } + badge.anchors.rightMargin: badge.border.width/2 + badge.anchors.bottomMargin: badge.border.width/2 + bridgeBadge.visible: root.isBridgedAccount bridgeBadge.image.source: Style.svg("discord-bridge") diff --git a/ui/imports/shared/popups/SendContactRequestModal.qml b/ui/imports/shared/popups/SendContactRequestModal.qml index d3212020fe..16987d21b8 100644 --- a/ui/imports/shared/popups/SendContactRequestModal.qml +++ b/ui/imports/shared/popups/SendContactRequestModal.qml @@ -85,6 +85,7 @@ StatusDialog { userIsEnsVerified: d.userIsEnsVerified isContact: d.contactDetails.isContact trustStatus: d.contactDetails.trustStatus + onlineStatus: d.contactDetails.onlineStatus isBlocked: d.contactDetails.isBlocked imageSize: ProfileHeader.ImageSize.Middle loading: d.loadingContactDetails diff --git a/ui/imports/shared/views/ProfileDialogView.qml b/ui/imports/shared/views/ProfileDialogView.qml index cab7dfa8fa..7f4de0e28e 100644 --- a/ui/imports/shared/views/ProfileDialogView.qml +++ b/ui/imports/shared/views/ProfileDialogView.qml @@ -49,10 +49,10 @@ Pane { QtObject { id: d - property var contactDetails: Utils.getContactDetailsAsJson(root.publicKey) + property var contactDetails: Utils.getContactDetailsAsJson(root.publicKey, !isCurrentUser, !isCurrentUser) function reload() { - contactDetails = Utils.getContactDetailsAsJson(root.publicKey) + contactDetails = Utils.getContactDetailsAsJson(root.publicKey, !isCurrentUser, !isCurrentUser) } readonly property bool isCurrentUser: root.profileStore.pubkey === root.publicKey @@ -299,6 +299,11 @@ Pane { imageWidth: 90 imageHeight: imageWidth ensVerified: d.contactDetails.ensVerified + + Binding on onlineStatus { + value: d.contactDetails.onlineStatus + when: !d.isCurrentUser + } } Item { Layout.fillWidth: true } @@ -577,6 +582,7 @@ Pane { Layout.topMargin: Style.current.halfPadding wrapMode: Text.WrapAtWordBoundaryOrAnywhere text: root.dirty ? root.dirtyValues.bio : d.contactDetails.bio + visible: !!text } EmojiHash { Layout.topMargin: Style.current.halfPadding diff --git a/ui/imports/shared/views/chat/ProfileContextMenu.qml b/ui/imports/shared/views/chat/ProfileContextMenu.qml index f3e9e55093..23440be94f 100644 --- a/ui/imports/shared/views/chat/ProfileContextMenu.qml +++ b/ui/imports/shared/views/chat/ProfileContextMenu.qml @@ -31,7 +31,7 @@ StatusMenu { if (root.selectedUserPublicKey === "" || isMe) { return {} } - return Utils.getContactDetailsAsJson(root.selectedUserPublicKey); + return Utils.getContactDetailsAsJson(root.selectedUserPublicKey, true, true); } readonly property bool isContact: { return root.selectedUserPublicKey !== "" && !!contactDetails.isContact @@ -100,6 +100,10 @@ StatusMenu { icon: root.selectedUserIcon trustStatus: contactDetails && contactDetails.trustStatus ? contactDetails.trustStatus : Constants.trustStatus.unknown + Binding on onlineStatus { + value: contactDetails.onlineStatus + when: !root.isMe + } isContact: root.isContact isBlocked: root.isBlockedContact isCurrentUser: root.isMe diff --git a/ui/imports/shared/views/profile/ShareProfileDialog.qml b/ui/imports/shared/views/profile/ShareProfileDialog.qml index 4f26c61eb3..c3cf970739 100644 --- a/ui/imports/shared/views/profile/ShareProfileDialog.qml +++ b/ui/imports/shared/views/profile/ShareProfileDialog.qml @@ -53,6 +53,7 @@ StatusDialog { topPadding: 0 bottomPadding: 0 placeholder.rightPadding: Style.current.halfPadding + placeholder.elide: Text.ElideMiddle placeholderText: root.linkToProfile placeholderTextColor: Theme.palette.directColor1 edit.readOnly: true diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index 92ed33bfd1..adf6fc8d02 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -406,6 +406,7 @@ QtObject { } readonly property QtObject onlineStatus: QtObject{ + readonly property int unknown: -1 readonly property int inactive: 0 readonly property int online: 1 }