2023-02-28 15:00:10 +00:00
|
|
|
import QtQuick 2.15
|
|
|
|
import QtQuick.Controls 2.15
|
|
|
|
import QtQuick.Layouts 1.15
|
|
|
|
import QtGraphicalEffects 1.15
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
import StatusQ.Core 0.1
|
|
|
|
import StatusQ.Core.Theme 0.1
|
|
|
|
import StatusQ.Controls 0.1
|
|
|
|
import StatusQ.Components 0.1
|
|
|
|
import StatusQ.Popups 0.1
|
|
|
|
import StatusQ.Popups.Dialog 0.1
|
2023-02-28 15:00:10 +00:00
|
|
|
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
import utils 1.0
|
|
|
|
import shared.controls 1.0
|
|
|
|
import shared.panels 1.0
|
|
|
|
import shared.popups 1.0
|
|
|
|
import shared.controls.chat 1.0
|
|
|
|
import shared.controls.chat.menuItems 1.0
|
2023-02-28 15:00:10 +00:00
|
|
|
import shared.views.profile 1.0
|
|
|
|
|
|
|
|
import SortFilterProxyModel 0.2
|
|
|
|
|
|
|
|
import AppLayouts.Wallet.stores 1.0 as WalletNS
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
Pane {
|
|
|
|
id: root
|
|
|
|
|
2023-02-28 15:00:10 +00:00
|
|
|
property bool readOnly // inside settings/profile/preview
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
property string publicKey: contactsStore.myPublicKey
|
2024-03-25 13:29:31 +00:00
|
|
|
readonly property alias isCurrentUser: d.isCurrentUser
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
property var profileStore
|
|
|
|
property var contactsStore
|
2024-03-29 11:43:49 +00:00
|
|
|
|
|
|
|
property alias sendToAccountEnabled: showcaseView.sendToAccountEnabled
|
2022-09-27 21:26:26 +00:00
|
|
|
|
2024-02-07 09:54:45 +00:00
|
|
|
property var dirtyValues: ({})
|
2022-11-08 18:30:50 +00:00
|
|
|
property bool dirty: false
|
|
|
|
|
2024-03-29 11:43:49 +00:00
|
|
|
property var showcaseCommunitiesModel
|
|
|
|
property var showcaseAccountsModel
|
|
|
|
property var showcaseCollectiblesModel
|
|
|
|
property var showcaseSocialLinksModel
|
|
|
|
property var showcaseAssetsModel
|
2024-03-25 13:29:31 +00:00
|
|
|
|
|
|
|
property alias showcaseMaxVisibility: showcaseView.maxVisibility
|
2024-03-29 11:43:49 +00:00
|
|
|
|
2024-02-15 09:25:40 +00:00
|
|
|
property alias assetsModel: showcaseView.globalAssetsModel
|
|
|
|
property alias collectiblesModel: showcaseView.globalCollectiblesModel
|
|
|
|
|
2022-09-27 21:26:26 +00:00
|
|
|
signal closeRequested()
|
|
|
|
|
|
|
|
padding: 0
|
2024-02-07 09:54:45 +00:00
|
|
|
topPadding: 32
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
background: StatusDialogBackground {
|
|
|
|
id: background
|
|
|
|
}
|
|
|
|
|
|
|
|
QtObject {
|
|
|
|
id: d
|
2024-02-20 18:52:07 +00:00
|
|
|
property var contactDetails: Utils.getContactDetailsAsJson(root.publicKey, !isCurrentUser, !isCurrentUser, true)
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
function reload() {
|
2024-02-20 18:52:07 +00:00
|
|
|
contactDetails = Utils.getContactDetailsAsJson(root.publicKey, !isCurrentUser, !isCurrentUser, true)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
readonly property bool isCurrentUser: root.profileStore.pubkey === root.publicKey
|
|
|
|
readonly property string userDisplayName: contactDetails.displayName
|
|
|
|
readonly property string userNickName: contactDetails.localNickname
|
2022-11-08 11:37:25 +00:00
|
|
|
readonly property string prettyEnsName: contactDetails.name
|
2022-12-05 09:56:44 +00:00
|
|
|
readonly property string aliasName: contactDetails.alias
|
|
|
|
readonly property string mainDisplayName: ProfileUtils.displayName(userNickName, prettyEnsName, userDisplayName, aliasName)
|
|
|
|
readonly property string optionalDisplayName: ProfileUtils.displayName("", prettyEnsName, userDisplayName, aliasName)
|
|
|
|
|
2022-09-27 21:26:26 +00:00
|
|
|
readonly property bool isContact: contactDetails.isContact
|
|
|
|
readonly property bool isBlocked: contactDetails.isBlocked
|
|
|
|
|
2023-04-18 15:08:24 +00:00
|
|
|
readonly property int contactRequestState: contactDetails.contactRequestState
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
readonly property int outgoingVerificationStatus: contactDetails.verificationStatus
|
|
|
|
readonly property int incomingVerificationStatus: contactDetails.incomingVerificationStatus
|
|
|
|
|
|
|
|
readonly property bool isVerificationRequestSent:
|
|
|
|
outgoingVerificationStatus !== Constants.verificationStatus.unverified &&
|
|
|
|
outgoingVerificationStatus !== Constants.verificationStatus.verified &&
|
|
|
|
outgoingVerificationStatus !== Constants.verificationStatus.trusted
|
2023-02-17 10:25:48 +00:00
|
|
|
readonly property bool isVerificationRequestReceived: incomingVerificationStatus === Constants.verificationStatus.verifying ||
|
|
|
|
incomingVerificationStatus === Constants.verificationStatus.verified
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
readonly property bool isTrusted: outgoingVerificationStatus === Constants.verificationStatus.trusted ||
|
|
|
|
incomingVerificationStatus === Constants.verificationStatus.trusted
|
2024-02-26 09:39:08 +00:00
|
|
|
readonly property bool isLocallyTrusted: contactDetails.trustStatus === Constants.trustStatus.trusted
|
2022-09-27 21:26:26 +00:00
|
|
|
|
2023-07-06 11:26:30 +00:00
|
|
|
readonly property string linkToProfile: root.contactsStore.getLinkToProfile(root.publicKey)
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
readonly property var conns: Connections {
|
2023-02-28 14:54:10 +00:00
|
|
|
target: root.contactsStore.myContactsModel ?? null
|
2022-12-09 12:33:20 +00:00
|
|
|
|
|
|
|
function onItemChanged(pubKey) {
|
|
|
|
if (pubKey === root.publicKey)
|
|
|
|
d.reload()
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
2022-12-09 12:33:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: use myContactsModel for identity verification
|
|
|
|
readonly property var conns2: Connections {
|
2023-02-28 14:54:10 +00:00
|
|
|
target: root.contactsStore.receivedContactRequestsModel ?? null
|
2022-12-09 12:33:20 +00:00
|
|
|
|
|
|
|
function onItemChanged(pubKey) {
|
|
|
|
if (pubKey === root.publicKey)
|
|
|
|
d.reload()
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
2022-11-16 09:54:45 +00:00
|
|
|
|
2023-02-07 14:21:32 +00:00
|
|
|
readonly property var conns3: Connections {
|
2023-02-28 14:54:10 +00:00
|
|
|
target: root.contactsStore.sentContactRequestsModel ?? null
|
2023-02-07 14:21:32 +00:00
|
|
|
|
|
|
|
function onItemChanged(pubKey) {
|
|
|
|
if (pubKey === root.publicKey)
|
|
|
|
d.reload()
|
|
|
|
}
|
|
|
|
}
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function reload() {
|
|
|
|
d.reload()
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: btnEditProfileComponent
|
|
|
|
StatusButton {
|
2022-12-16 18:24:51 +00:00
|
|
|
objectName: "editProfileButton"
|
2022-09-27 21:26:26 +00:00
|
|
|
size: StatusButton.Size.Small
|
|
|
|
text: qsTr("Edit Profile")
|
2024-03-12 15:44:27 +00:00
|
|
|
interactive: !root.readOnly
|
|
|
|
tooltip.text: interactive ? "" : qsTr("Not available in preview mode")
|
2022-09-27 21:26:26 +00:00
|
|
|
onClicked: {
|
|
|
|
Global.changeAppSectionBySectionType(Constants.appSection.profile)
|
|
|
|
root.closeRequested()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: btnSendMessageComponent
|
|
|
|
StatusButton {
|
|
|
|
size: StatusButton.Size.Small
|
|
|
|
text: qsTr("Send Message")
|
|
|
|
onClicked: {
|
|
|
|
root.contactsStore.joinPrivateChat(root.publicKey)
|
|
|
|
root.closeRequested()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: btnAcceptContactRequestComponent
|
2024-02-29 21:01:33 +00:00
|
|
|
StatusButton {
|
|
|
|
objectName: "profileDialog_reviewContactRequestButton"
|
|
|
|
size: StatusButton.Size.Small
|
|
|
|
text: qsTr("Review contact request")
|
|
|
|
onClicked: Global.openReviewContactRequestPopup(root.publicKey, d.contactDetails,
|
|
|
|
popup => popup.closed.connect(d.reload))
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: btnSendContactRequestComponent
|
|
|
|
StatusButton {
|
2022-12-26 21:53:47 +00:00
|
|
|
objectName: "profileDialog_sendContactRequestButton"
|
2022-09-27 21:26:26 +00:00
|
|
|
size: StatusButton.Size.Small
|
2024-02-16 11:56:29 +00:00
|
|
|
text: qsTr("Send contact request")
|
2024-02-29 21:01:33 +00:00
|
|
|
onClicked: Global.openContactRequestPopup(root.publicKey, d.contactDetails,
|
2024-03-07 09:51:16 +00:00
|
|
|
popup => popup.accepted.connect(d.reload))
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: btnBlockUserComponent
|
|
|
|
StatusButton {
|
|
|
|
size: StatusButton.Size.Small
|
|
|
|
type: StatusBaseButton.Type.Danger
|
2024-02-20 18:52:07 +00:00
|
|
|
text: qsTr("Block user")
|
|
|
|
onClicked: Global.blockContactRequested(root.publicKey, d.contactDetails)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: btnUnblockUserComponent
|
|
|
|
StatusButton {
|
|
|
|
size: StatusButton.Size.Small
|
2024-02-20 18:52:07 +00:00
|
|
|
text: qsTr("Unblock user")
|
|
|
|
onClicked: Global.unblockContactRequested(root.publicKey, d.contactDetails)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: txtPendingContactRequestComponent
|
2024-02-07 14:56:45 +00:00
|
|
|
RowLayout {
|
|
|
|
StatusIcon {
|
|
|
|
icon: "history"
|
|
|
|
width: 16
|
|
|
|
height: width
|
|
|
|
color: Theme.palette.baseColor1
|
|
|
|
}
|
|
|
|
StatusBaseText {
|
|
|
|
font.pixelSize: 13
|
|
|
|
font.weight: Font.Medium
|
|
|
|
color: Theme.palette.baseColor1
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
2024-02-16 11:56:29 +00:00
|
|
|
text: qsTr("Contact Request Pending")
|
2024-02-07 14:56:45 +00:00
|
|
|
}
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
2024-02-26 18:54:05 +00:00
|
|
|
id: btnReplyToIdRequestComponent
|
|
|
|
StatusFlatButton {
|
2022-09-27 21:26:26 +00:00
|
|
|
size: StatusButton.Size.Small
|
2024-02-26 18:54:05 +00:00
|
|
|
text: qsTr("Reply to ID verification request")
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "respondToIDRequest_StatusItem"
|
2024-02-26 18:54:05 +00:00
|
|
|
icon.name: "checkmark-circle"
|
|
|
|
onClicked: Global.openIncomingIDRequestPopup(root.publicKey, d.contactDetails,
|
|
|
|
popup => popup.closed.connect(d.reload))
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-26 09:39:08 +00:00
|
|
|
Component {
|
|
|
|
id: btnRequestIDVerification
|
|
|
|
StatusFlatButton {
|
|
|
|
size: StatusButton.Size.Small
|
|
|
|
text: qsTr("Request ID verification")
|
2024-02-26 18:54:05 +00:00
|
|
|
objectName: "requestIDVerification_StatusItem"
|
2024-02-26 09:39:08 +00:00
|
|
|
icon.name: "checkmark-circle"
|
2024-02-26 18:54:05 +00:00
|
|
|
onClicked: Global.openSendIDRequestPopup(root.publicKey, d.contactDetails,
|
|
|
|
popup => popup.accepted.connect(d.reload))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: btnReviewIDVerificationReply
|
|
|
|
StatusFlatButton {
|
|
|
|
size: StatusButton.Size.Small
|
|
|
|
text: d.incomingVerificationStatus !== Constants.verificationStatus.verified ? qsTr("ID verification pending")
|
|
|
|
: qsTr("Review ID verification reply")
|
|
|
|
icon.name: d.incomingVerificationStatus !== Constants.verificationStatus.verified ? "history" : "checkmark-circle"
|
|
|
|
onClicked: Global.openOutgoingIDRequestPopup(root.publicKey, d.contactDetails,
|
|
|
|
popup => popup.closed.connect(d.reload))
|
2024-02-26 09:39:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: btnShareProfile
|
|
|
|
StatusFlatButton {
|
|
|
|
size: StatusButton.Size.Small
|
|
|
|
text: qsTr("Share Profile")
|
|
|
|
onClicked: Global.openPopup(shareProfileCmp)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-07 14:56:45 +00:00
|
|
|
Component {
|
|
|
|
id: shareProfileCmp
|
|
|
|
ShareProfileDialog {
|
|
|
|
destroyOnClose: true
|
|
|
|
title: d.isCurrentUser ? qsTr("Share your profile") : qsTr("%1's profile").arg(d.mainDisplayName)
|
|
|
|
publicKey: root.publicKey
|
|
|
|
linkToProfile: d.linkToProfile
|
2024-02-13 14:10:07 +00:00
|
|
|
qrCode: root.profileStore.getQrCodeSource(linkToProfile)
|
|
|
|
displayName: userImage.name
|
|
|
|
largeImage: userImage.image
|
2024-02-07 14:56:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-27 21:26:26 +00:00
|
|
|
ColumnLayout {
|
|
|
|
id: column
|
|
|
|
spacing: 20
|
|
|
|
anchors {
|
|
|
|
fill: parent
|
|
|
|
leftMargin: Style.current.bigPadding
|
|
|
|
rightMargin: Style.current.bigPadding
|
|
|
|
}
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
Layout.fillWidth: true
|
|
|
|
spacing: Style.current.halfPadding
|
|
|
|
|
|
|
|
UserImage {
|
2024-02-13 14:10:07 +00:00
|
|
|
id: userImage
|
2022-09-27 21:26:26 +00:00
|
|
|
Layout.alignment: Qt.AlignTop
|
|
|
|
objectName: "ProfileDialog_userImage"
|
2022-11-08 18:30:50 +00:00
|
|
|
name: root.dirty ? root.dirtyValues.displayName
|
2022-12-05 09:56:44 +00:00
|
|
|
: d.mainDisplayName
|
2022-09-27 21:26:26 +00:00
|
|
|
pubkey: root.publicKey
|
2022-11-08 18:30:50 +00:00
|
|
|
image: root.dirty ? root.dirtyValues.profileLargeImage
|
2024-01-26 15:54:30 +00:00
|
|
|
: Utils.addTimestampToURL(d.contactDetails.largeImage)
|
2022-09-27 21:26:26 +00:00
|
|
|
interactive: false
|
2024-02-07 14:56:45 +00:00
|
|
|
imageWidth: 90
|
2022-09-27 21:26:26 +00:00
|
|
|
imageHeight: imageWidth
|
2022-12-01 10:24:25 +00:00
|
|
|
ensVerified: d.contactDetails.ensVerified
|
2024-02-09 15:52:28 +00:00
|
|
|
|
|
|
|
Binding on onlineStatus {
|
|
|
|
value: d.contactDetails.onlineStatus
|
|
|
|
when: !d.isCurrentUser
|
|
|
|
}
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
|
2024-02-07 14:56:45 +00:00
|
|
|
Item { Layout.fillWidth: true }
|
2023-07-25 13:37:04 +00:00
|
|
|
|
2024-02-26 18:54:05 +00:00
|
|
|
// secondary action button
|
2024-02-26 09:39:08 +00:00
|
|
|
Loader {
|
2024-02-07 14:56:45 +00:00
|
|
|
Layout.alignment: Qt.AlignTop
|
|
|
|
Layout.preferredHeight: menuButton.visible ? menuButton.height : -1
|
2024-02-26 09:39:08 +00:00
|
|
|
sourceComponent: {
|
|
|
|
if (d.isCurrentUser && !root.readOnly)
|
|
|
|
return btnShareProfile
|
|
|
|
|
2024-02-26 18:54:05 +00:00
|
|
|
if (d.isContact && !(d.isTrusted || d.isLocallyTrusted) && !d.isBlocked) {
|
|
|
|
if (d.isVerificationRequestSent)
|
|
|
|
return btnReviewIDVerificationReply
|
|
|
|
else if (d.isVerificationRequestReceived)
|
|
|
|
return btnReplyToIdRequestComponent
|
|
|
|
else if (d.outgoingVerificationStatus === Constants.verificationStatus.unverified)
|
|
|
|
return btnRequestIDVerification
|
|
|
|
}
|
2024-02-26 09:39:08 +00:00
|
|
|
}
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
|
2024-02-26 18:54:05 +00:00
|
|
|
// primary action button
|
2022-09-27 21:26:26 +00:00
|
|
|
Loader {
|
|
|
|
Layout.alignment: Qt.AlignTop
|
|
|
|
Layout.preferredHeight: menuButton.visible ? menuButton.height : -1
|
2024-02-07 14:56:45 +00:00
|
|
|
|
2022-09-27 21:26:26 +00:00
|
|
|
sourceComponent: {
|
|
|
|
// current user
|
|
|
|
if (d.isCurrentUser)
|
|
|
|
return btnEditProfileComponent
|
|
|
|
|
2024-02-20 18:52:07 +00:00
|
|
|
// blocked user
|
2023-04-18 11:43:28 +00:00
|
|
|
if (d.isBlocked)
|
|
|
|
return btnUnblockUserComponent
|
|
|
|
|
2024-02-16 17:34:09 +00:00
|
|
|
// accept incoming CR
|
|
|
|
if (d.contactRequestState === Constants.ContactRequestState.Received)
|
|
|
|
return btnAcceptContactRequestComponent
|
|
|
|
|
2024-02-07 14:56:45 +00:00
|
|
|
// mutual contact
|
|
|
|
if (d.isContact || d.contactRequestState === Constants.ContactRequestState.Mutual)
|
|
|
|
return btnSendMessageComponent
|
|
|
|
|
2023-04-18 15:08:24 +00:00
|
|
|
// depend on contactRequestState
|
|
|
|
switch (d.contactRequestState) {
|
|
|
|
case Constants.ContactRequestState.Sent:
|
2022-09-27 21:26:26 +00:00
|
|
|
return txtPendingContactRequestComponent
|
2023-04-18 15:08:24 +00:00
|
|
|
case Constants.ContactRequestState.Received:
|
2024-02-16 17:34:09 +00:00
|
|
|
break // handled above
|
2023-04-18 15:08:24 +00:00
|
|
|
case Constants.ContactRequestState.Mutual: {
|
2024-02-26 18:54:05 +00:00
|
|
|
if (d.outgoingVerificationStatus === Constants.verificationStatus.declined) {
|
2023-04-18 15:08:24 +00:00
|
|
|
return btnBlockUserComponent
|
|
|
|
}
|
2024-02-07 14:56:45 +00:00
|
|
|
break
|
2023-03-15 14:26:10 +00:00
|
|
|
}
|
2023-04-18 15:08:24 +00:00
|
|
|
case Constants.ContactRequestState.None:
|
|
|
|
case Constants.ContactRequestState.Dismissed:
|
2022-09-27 21:26:26 +00:00
|
|
|
return btnSendContactRequestComponent
|
2023-04-18 15:08:24 +00:00
|
|
|
default:
|
|
|
|
console.warn("!!! UNHANDLED CONTACT ACTION BUTTON; PUBKEY", root.publicKey)
|
|
|
|
return null
|
|
|
|
}
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StatusFlatButton {
|
|
|
|
id: menuButton
|
|
|
|
Layout.alignment: Qt.AlignTop
|
|
|
|
Layout.preferredWidth: height
|
|
|
|
|
|
|
|
visible: !d.isCurrentUser
|
|
|
|
horizontalPadding: 6
|
|
|
|
verticalPadding: 6
|
|
|
|
icon.name: "more"
|
|
|
|
icon.color: Theme.palette.directColor1
|
|
|
|
highlighted: moreMenu.opened
|
|
|
|
onClicked: moreMenu.popup(-moreMenu.width + width, height + 4)
|
|
|
|
|
2022-12-01 16:58:37 +00:00
|
|
|
StatusMenu {
|
2022-09-27 21:26:26 +00:00
|
|
|
id: moreMenu
|
2023-06-15 10:27:09 +00:00
|
|
|
|
2022-09-27 21:26:26 +00:00
|
|
|
SendContactRequestMenuItem {
|
2023-04-26 09:12:45 +00:00
|
|
|
enabled: !d.isContact && !d.isBlocked && d.contactRequestState !== Constants.ContactRequestState.Sent &&
|
2022-09-27 21:26:26 +00:00
|
|
|
d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy // we have an action button otherwise
|
|
|
|
onTriggered: {
|
2024-02-16 11:56:29 +00:00
|
|
|
Global.openContactRequestPopup(root.publicKey, d.contactDetails, null)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
2022-12-01 16:58:37 +00:00
|
|
|
StatusAction {
|
2024-02-26 09:39:08 +00:00
|
|
|
text: qsTr("Mark as ID verified")
|
2022-09-27 21:26:26 +00:00
|
|
|
icon.name: "checkmark-circle"
|
2024-02-26 09:39:08 +00:00
|
|
|
enabled: d.isContact && !d.isBlocked && !(d.isTrusted || d.isLocallyTrusted)
|
|
|
|
onTriggered: Global.openMarkAsIDVerifiedPopup(root.publicKey, d.contactDetails,
|
|
|
|
popup => popup.accepted.connect(d.reload))
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
2022-12-01 16:58:37 +00:00
|
|
|
StatusAction {
|
2024-02-07 14:56:45 +00:00
|
|
|
text: d.userNickName ? qsTr("Edit nickname") : qsTr("Add nickname")
|
2022-09-27 21:26:26 +00:00
|
|
|
icon.name: "edit_pencil"
|
|
|
|
onTriggered: {
|
2024-03-07 09:51:16 +00:00
|
|
|
Global.openNicknamePopupRequested(root.publicKey, d.contactDetails,
|
|
|
|
popup => popup.closed.connect(d.reload))
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
2022-12-01 16:58:37 +00:00
|
|
|
StatusAction {
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Show QR code")
|
|
|
|
icon.name: "qr"
|
|
|
|
enabled: !d.isCurrentUser
|
|
|
|
onTriggered: {
|
|
|
|
Global.openPopup(shareProfileCmp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
StatusAction {
|
|
|
|
text: qsTr("Copy link to profile")
|
2022-09-27 21:26:26 +00:00
|
|
|
icon.name: "copy"
|
|
|
|
onTriggered: {
|
|
|
|
root.profileStore.copyToClipboard(d.linkToProfile)
|
|
|
|
}
|
|
|
|
}
|
2024-02-07 14:56:45 +00:00
|
|
|
StatusMenuSeparator {}
|
2024-02-20 18:52:07 +00:00
|
|
|
StatusAction {
|
|
|
|
text: qsTr("Remove ID verification")
|
2024-02-26 09:39:08 +00:00
|
|
|
icon.name: "delete"
|
2024-02-20 18:52:07 +00:00
|
|
|
type: StatusAction.Type.Danger
|
2024-02-26 09:39:08 +00:00
|
|
|
enabled: d.isContact && (d.isTrusted || d.isLocallyTrusted)
|
|
|
|
onTriggered: Global.openRemoveIDVerificationDialog(root.publicKey, d.contactDetails,
|
2024-03-07 09:51:16 +00:00
|
|
|
popup => popup.accepted.connect(d.reload))
|
2024-02-20 18:52:07 +00:00
|
|
|
}
|
2024-02-14 12:52:54 +00:00
|
|
|
StatusAction {
|
|
|
|
text: qsTr("Remove nickname")
|
|
|
|
icon.name: "delete"
|
|
|
|
type: StatusAction.Type.Danger
|
|
|
|
enabled: !d.isCurrentUser && !!d.contactDetails.localNickname
|
|
|
|
onTriggered: root.contactsStore.changeContactNickname(root.publicKey, "", d.optionalDisplayName, true)
|
|
|
|
}
|
2022-12-01 16:58:37 +00:00
|
|
|
StatusAction {
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Mark as untrusted")
|
2022-09-27 21:26:26 +00:00
|
|
|
icon.name: "warning"
|
2022-12-01 16:58:37 +00:00
|
|
|
type: StatusAction.Type.Danger
|
2024-02-16 17:34:09 +00:00
|
|
|
enabled: d.contactDetails.trustStatus !== Constants.trustStatus.untrustworthy && !d.isBlocked
|
2022-09-27 21:26:26 +00:00
|
|
|
onTriggered: {
|
2024-02-16 17:34:09 +00:00
|
|
|
Global.markAsUntrustedRequested(root.publicKey, d.contactDetails)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-26 18:54:05 +00:00
|
|
|
StatusAction {
|
|
|
|
text: qsTr("Cancel ID verification request")
|
|
|
|
icon.name: "delete"
|
|
|
|
type: StatusAction.Type.Danger
|
|
|
|
enabled: d.isContact && !d.isBlocked && d.isVerificationRequestSent
|
|
|
|
onTriggered: root.contactsStore.cancelVerificationRequest(root.publicKey)
|
|
|
|
}
|
2022-12-01 16:58:37 +00:00
|
|
|
StatusAction {
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Remove untrusted mark")
|
2022-09-27 21:26:26 +00:00
|
|
|
icon.name: "warning"
|
2024-02-07 14:56:45 +00:00
|
|
|
type: StatusAction.Type.Danger
|
|
|
|
enabled: d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy && !d.isBlocked
|
2022-09-27 21:26:26 +00:00
|
|
|
onTriggered: {
|
|
|
|
root.contactsStore.removeTrustStatus(root.publicKey)
|
|
|
|
}
|
|
|
|
}
|
2022-12-01 16:58:37 +00:00
|
|
|
StatusAction {
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Remove contact")
|
2022-09-27 21:26:26 +00:00
|
|
|
icon.name: "remove-contact"
|
2022-12-01 16:58:37 +00:00
|
|
|
type: StatusAction.Type.Danger
|
2023-04-18 15:08:24 +00:00
|
|
|
enabled: d.isContact && !d.isBlocked && d.contactRequestState !== Constants.ContactRequestState.Sent
|
2022-09-27 21:26:26 +00:00
|
|
|
onTriggered: {
|
2024-02-20 17:19:36 +00:00
|
|
|
Global.removeContactRequested(root.publicKey, d.contactDetails)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
2022-12-01 16:58:37 +00:00
|
|
|
StatusAction {
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Block user")
|
2022-09-27 21:26:26 +00:00
|
|
|
icon.name: "cancel"
|
2022-12-01 16:58:37 +00:00
|
|
|
type: StatusAction.Type.Danger
|
2022-09-27 21:26:26 +00:00
|
|
|
enabled: !d.isBlocked
|
|
|
|
onTriggered: {
|
2024-02-20 18:52:07 +00:00
|
|
|
Global.blockContactRequested(root.publicKey, d.contactDetails)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-07 14:56:45 +00:00
|
|
|
ColumnLayout {
|
2022-09-27 21:26:26 +00:00
|
|
|
Layout.fillWidth: true
|
2024-02-07 14:56:45 +00:00
|
|
|
spacing: 4
|
|
|
|
Item {
|
|
|
|
id: contactRow
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.preferredHeight: childrenRect.height
|
|
|
|
StatusBaseText {
|
|
|
|
id: contactName
|
|
|
|
anchors.left: parent.left
|
|
|
|
width: Math.min(implicitWidth, contactRow.width - verificationIcons.width - verificationIcons.anchors.leftMargin)
|
|
|
|
objectName: "ProfileDialog_displayName"
|
|
|
|
font.bold: true
|
|
|
|
font.pixelSize: 22
|
|
|
|
elide: Text.ElideRight
|
|
|
|
text: root.dirty ? root.dirtyValues.displayName
|
|
|
|
: d.mainDisplayName
|
|
|
|
}
|
|
|
|
StatusContactVerificationIcons {
|
|
|
|
id: verificationIcons
|
|
|
|
anchors.left: contactName.right
|
|
|
|
anchors.leftMargin: Style.current.halfPadding
|
|
|
|
anchors.verticalCenter: contactName.verticalCenter
|
|
|
|
objectName: "ProfileDialog_userVerificationIcons"
|
|
|
|
visible: !d.isCurrentUser
|
|
|
|
isContact: d.isContact
|
|
|
|
trustIndicator: d.contactDetails.trustStatus
|
|
|
|
isBlocked: d.isBlocked
|
|
|
|
tiny: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RowLayout {
|
|
|
|
spacing: Style.current.halfPadding
|
|
|
|
StatusBaseText {
|
|
|
|
id: contactSecondaryName
|
|
|
|
color: Theme.palette.baseColor1
|
|
|
|
text: d.optionalDisplayName
|
|
|
|
visible: !!d.userNickName
|
|
|
|
}
|
|
|
|
Rectangle {
|
|
|
|
Layout.preferredWidth: 4
|
|
|
|
Layout.preferredHeight: 4
|
|
|
|
radius: width/2
|
|
|
|
color: Theme.palette.baseColor1
|
|
|
|
visible: contactSecondaryName.visible
|
|
|
|
}
|
|
|
|
StatusBaseText {
|
|
|
|
color: Theme.palette.baseColor1
|
|
|
|
text: Utils.getElidedCompressedPk(root.publicKey)
|
2024-02-16 11:56:29 +00:00
|
|
|
HoverHandler {
|
|
|
|
id: keyHoverHandler
|
|
|
|
}
|
|
|
|
StatusToolTip {
|
|
|
|
text: Utils.getCompressedPk(root.publicKey)
|
|
|
|
visible: keyHoverHandler.hovered
|
|
|
|
}
|
2024-02-07 14:56:45 +00:00
|
|
|
}
|
|
|
|
CopyButton {
|
|
|
|
Layout.leftMargin: -4
|
|
|
|
Layout.preferredWidth: 16
|
|
|
|
Layout.preferredHeight: 16
|
|
|
|
textToCopy: Utils.getCompressedPk(root.publicKey)
|
|
|
|
StatusToolTip {
|
|
|
|
text: qsTr("Copy Chat Key")
|
|
|
|
visible: parent.hovered
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
StatusBaseText {
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.topMargin: Style.current.halfPadding
|
|
|
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
|
|
|
text: root.dirty ? root.dirtyValues.bio : d.contactDetails.bio
|
2024-02-09 15:52:28 +00:00
|
|
|
visible: !!text
|
2024-02-07 14:56:45 +00:00
|
|
|
}
|
|
|
|
EmojiHash {
|
|
|
|
Layout.topMargin: Style.current.halfPadding
|
|
|
|
objectName: "ProfileDialog_userEmojiHash"
|
|
|
|
publicKey: root.publicKey
|
|
|
|
oneRow: true
|
|
|
|
}
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StatusScrollView {
|
|
|
|
id: scrollView
|
|
|
|
Layout.fillWidth: true
|
2023-02-28 15:00:10 +00:00
|
|
|
Layout.fillHeight: true
|
2022-09-27 21:26:26 +00:00
|
|
|
Layout.leftMargin: -column.anchors.leftMargin
|
|
|
|
Layout.rightMargin: -column.anchors.rightMargin
|
|
|
|
padding: 0
|
2023-05-31 20:58:23 +00:00
|
|
|
contentWidth: availableWidth
|
2022-09-27 21:26:26 +00:00
|
|
|
|
|
|
|
ColumnLayout {
|
2023-05-31 20:58:23 +00:00
|
|
|
width: scrollView.availableWidth
|
2022-09-27 21:26:26 +00:00
|
|
|
spacing: 20
|
|
|
|
|
|
|
|
StatusTabBar {
|
2023-02-28 15:00:10 +00:00
|
|
|
id: showcaseTabBar
|
2022-09-27 21:26:26 +00:00
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.leftMargin: column.anchors.leftMargin
|
|
|
|
Layout.rightMargin: column.anchors.rightMargin
|
|
|
|
bottomPadding: -4
|
|
|
|
StatusTabButton {
|
2023-04-19 16:48:57 +00:00
|
|
|
leftPadding: 0
|
2022-09-27 21:26:26 +00:00
|
|
|
width: implicitWidth
|
2023-02-28 15:00:10 +00:00
|
|
|
text: qsTr("Communities")
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
StatusTabButton {
|
|
|
|
width: implicitWidth
|
2023-02-28 15:00:10 +00:00
|
|
|
text: qsTr("Accounts")
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
StatusTabButton {
|
|
|
|
width: implicitWidth
|
2023-02-28 15:00:10 +00:00
|
|
|
text: qsTr("Collectibles")
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
2024-03-04 22:07:09 +00:00
|
|
|
// StatusTabButton {
|
|
|
|
// width: implicitWidth
|
|
|
|
// text: qsTr("Assets")
|
|
|
|
// }
|
2024-02-15 09:25:40 +00:00
|
|
|
StatusTabButton {
|
|
|
|
width: implicitWidth
|
|
|
|
text: qsTr("Web")
|
|
|
|
}
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
|
2023-02-28 15:00:10 +00:00
|
|
|
// Profile Showcase
|
|
|
|
ProfileShowcaseView {
|
2024-03-29 11:43:49 +00:00
|
|
|
id: showcaseView
|
|
|
|
|
2022-09-27 21:26:26 +00:00
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.topMargin: -column.spacing
|
|
|
|
Layout.preferredHeight: 300
|
|
|
|
|
2023-02-28 15:00:10 +00:00
|
|
|
currentTabIndex: showcaseTabBar.currentIndex
|
|
|
|
mainDisplayName: d.mainDisplayName
|
|
|
|
readOnly: root.readOnly
|
2024-03-14 17:31:38 +00:00
|
|
|
|
2024-03-29 11:43:49 +00:00
|
|
|
communitiesModel: root.showcaseCommunitiesModel
|
|
|
|
accountsModel: root.showcaseAccountsModel
|
|
|
|
collectiblesModel: root.showcaseCollectiblesModel
|
2024-02-15 09:25:40 +00:00
|
|
|
socialLinksModel: root.showcaseSocialLinksModel
|
2024-03-29 11:43:49 +00:00
|
|
|
// assetsModel: root.showcaseAssetsModel
|
2022-09-27 21:26:26 +00:00
|
|
|
|
2024-02-27 17:11:03 +00:00
|
|
|
walletStore: WalletNS.RootStore
|
|
|
|
|
2023-02-28 15:00:10 +00:00
|
|
|
onCloseRequested: root.closeRequested()
|
2024-03-29 11:43:49 +00:00
|
|
|
onCopyToClipboard: root.profileStore.copyToClipboard(text)
|
2022-09-27 21:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
layer.enabled: !root.readOnly // profile preview has its own layer.effect
|
|
|
|
layer.effect: OpacityMask {
|
|
|
|
maskSource: Rectangle {
|
|
|
|
anchors.centerIn: parent
|
|
|
|
width: column.width
|
|
|
|
height: column.height
|
|
|
|
radius: background.radius
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|