2024-02-07 14:56:45 +00:00
|
|
|
import QtQuick 2.15
|
2023-05-19 16:07:50 +00:00
|
|
|
|
|
|
|
import StatusQ.Popups 0.1
|
|
|
|
import StatusQ.Components 0.1
|
2024-05-13 08:05:53 +00:00
|
|
|
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
2023-05-19 16:07:50 +00:00
|
|
|
|
|
|
|
import utils 1.0
|
|
|
|
import shared 1.0
|
|
|
|
import shared.panels 1.0
|
|
|
|
import shared.popups 1.0
|
|
|
|
import shared.status 1.0
|
|
|
|
import shared.controls.chat 1.0
|
|
|
|
import shared.controls.chat.menuItems 1.0
|
|
|
|
|
|
|
|
StatusMenu {
|
|
|
|
id: root
|
|
|
|
|
|
|
|
property var store
|
|
|
|
|
|
|
|
property string myPublicKey: ""
|
|
|
|
|
|
|
|
property string selectedUserPublicKey: ""
|
|
|
|
property string selectedUserDisplayName: ""
|
|
|
|
property string selectedUserIcon: ""
|
|
|
|
|
2024-01-05 15:34:20 +00:00
|
|
|
property bool isBridgedAccount: false
|
|
|
|
|
2023-05-19 16:07:50 +00:00
|
|
|
readonly property bool isMe: {
|
|
|
|
return root.selectedUserPublicKey === root.store.contactsStore.myPublicKey;
|
|
|
|
}
|
|
|
|
readonly property var contactDetails: {
|
|
|
|
if (root.selectedUserPublicKey === "" || isMe) {
|
|
|
|
return {}
|
|
|
|
}
|
2024-02-09 15:52:28 +00:00
|
|
|
return Utils.getContactDetailsAsJson(root.selectedUserPublicKey, true, true);
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
readonly property bool isContact: {
|
|
|
|
return root.selectedUserPublicKey !== "" && !!contactDetails.isContact
|
|
|
|
}
|
|
|
|
readonly property bool isBlockedContact: (!!contactDetails && contactDetails.isBlocked) || false
|
|
|
|
|
2024-05-29 08:33:36 +00:00
|
|
|
readonly property bool idVerificationFlowsEnabled: false // disabled temporarily as per https://github.com/status-im/status-desktop/issues/14954
|
|
|
|
|
2023-05-19 16:07:50 +00:00
|
|
|
readonly property int outgoingVerificationStatus: {
|
|
|
|
if (root.selectedUserPublicKey === "" || root.isMe || !root.isContact) {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return contactDetails.verificationStatus
|
|
|
|
}
|
|
|
|
readonly property int incomingVerificationStatus: {
|
|
|
|
if (root.selectedUserPublicKey === "" || root.isMe || !root.isContact) {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return contactDetails.incomingVerificationStatus
|
|
|
|
}
|
|
|
|
readonly property bool hasPendingContactRequest: {
|
|
|
|
return !root.isMe && root.selectedUserPublicKey !== "" &&
|
2024-02-29 21:01:33 +00:00
|
|
|
contactDetails.contactRequestState === Constants.ContactRequestState.Received
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
readonly property bool hasActiveReceivedVerificationRequestFrom: {
|
|
|
|
if (!root.selectedUserPublicKey || root.isMe || !root.isContact) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return contactDetails.incomingVerificationStatus === Constants.verificationStatus.verifying ||
|
|
|
|
contactDetails.incomingVerificationStatus === Constants.verificationStatus.verified
|
|
|
|
}
|
|
|
|
readonly property bool isVerificationRequestSent: {
|
|
|
|
if (!root.selectedUserPublicKey || root.isMe || !root.isContact) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return root.outgoingVerificationStatus !== Constants.verificationStatus.unverified &&
|
|
|
|
root.outgoingVerificationStatus !== Constants.verificationStatus.verified &&
|
|
|
|
root.outgoingVerificationStatus !== Constants.verificationStatus.trusted
|
|
|
|
}
|
|
|
|
readonly property bool isTrusted: {
|
|
|
|
if (!root.selectedUserPublicKey || root.isMe || !root.isContact) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return root.outgoingVerificationStatus === Constants.verificationStatus.trusted ||
|
|
|
|
root.incomingVerificationStatus === Constants.verificationStatus.trusted
|
|
|
|
}
|
|
|
|
|
|
|
|
readonly property bool userTrustIsUnknown: contactDetails && contactDetails.trustStatus === Constants.trustStatus.unknown
|
|
|
|
readonly property bool userIsUntrustworthy: contactDetails && contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
2024-02-26 09:39:08 +00:00
|
|
|
readonly property bool userIsLocallyTrusted: contactDetails && contactDetails.trustStatus === Constants.trustStatus.trusted
|
2023-05-19 16:07:50 +00:00
|
|
|
|
|
|
|
signal openProfileClicked(string publicKey)
|
|
|
|
signal createOneToOneChat(string communityId, string chatId, string ensName)
|
|
|
|
|
|
|
|
onClosed: {
|
|
|
|
// Reset selectedUserPublicKey so that associated properties get recalculated on re-open
|
|
|
|
selectedUserPublicKey = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
ProfileHeader {
|
|
|
|
width: parent.width
|
|
|
|
height: visible ? implicitHeight : 0
|
|
|
|
|
|
|
|
displayNameVisible: false
|
|
|
|
displayNamePlusIconsVisible: true
|
|
|
|
editButtonVisible: false
|
2024-05-13 08:05:53 +00:00
|
|
|
displayName: StatusQUtils.Emoji.parse(root.selectedUserDisplayName, StatusQUtils.Emoji.size.verySmall)
|
2023-05-19 16:07:50 +00:00
|
|
|
pubkey: root.selectedUserPublicKey
|
|
|
|
icon: root.selectedUserIcon
|
|
|
|
trustStatus: contactDetails && contactDetails.trustStatus ? contactDetails.trustStatus
|
|
|
|
: Constants.trustStatus.unknown
|
2024-02-09 15:52:28 +00:00
|
|
|
Binding on onlineStatus {
|
|
|
|
value: contactDetails.onlineStatus
|
|
|
|
when: !root.isMe
|
|
|
|
}
|
2023-05-19 16:07:50 +00:00
|
|
|
isContact: root.isContact
|
2024-02-07 14:56:45 +00:00
|
|
|
isBlocked: root.isBlockedContact
|
2023-05-19 16:07:50 +00:00
|
|
|
isCurrentUser: root.isMe
|
|
|
|
userIsEnsVerified: (!!contactDetails && contactDetails.ensVerified) || false
|
2024-01-05 15:34:20 +00:00
|
|
|
isBridgedAccount: root.isBridgedAccount
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StatusMenuSeparator {
|
|
|
|
topPadding: root.topPadding
|
2024-01-05 15:34:20 +00:00
|
|
|
visible: !root.isBridgedAccount
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ViewProfileMenuItem {
|
|
|
|
id: viewProfileAction
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "viewProfile_StatusItem"
|
2024-01-05 15:34:20 +00:00
|
|
|
enabled: !root.isBridgedAccount
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: {
|
|
|
|
root.openProfileClicked(root.selectedUserPublicKey)
|
|
|
|
root.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-29 21:01:33 +00:00
|
|
|
StatusAction {
|
|
|
|
text: qsTr("Review contact request")
|
|
|
|
objectName: "reviewContactRequest_StatusItem"
|
|
|
|
icon.name: "add-contact"
|
|
|
|
enabled: !root.isMe && !root.isContact && !root.isBridgedAccount && !root.isBlockedContact && root.hasPendingContactRequest
|
|
|
|
onTriggered: Global.openReviewContactRequestPopup(root.selectedUserPublicKey, root.contactDetails, null)
|
|
|
|
}
|
2024-02-07 14:56:45 +00:00
|
|
|
|
2023-05-19 16:07:50 +00:00
|
|
|
SendMessageMenuItem {
|
|
|
|
id: sendMessageMenuItem
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "sendMessage_StatusItem"
|
2024-01-05 15:34:20 +00:00
|
|
|
enabled: root.isContact && !root.isBlockedContact && !root.isBridgedAccount
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: {
|
|
|
|
root.createOneToOneChat("", root.selectedUserPublicKey, "")
|
|
|
|
root.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SendContactRequestMenuItem {
|
|
|
|
id: sendContactRequestMenuItem
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "sendContactRequest_StatusItem"
|
2024-04-18 22:10:45 +00:00
|
|
|
enabled: !root.isMe && !root.isContact && !root.isBlockedContact
|
|
|
|
&& (contactDetails.contactRequestState === Constants.ContactRequestState.None || contactDetails.contactRequestState === Constants.ContactRequestState.Dismissed)
|
|
|
|
&& !root.isBridgedAccount
|
2024-02-16 11:56:29 +00:00
|
|
|
onTriggered: Global.openContactRequestPopup(root.selectedUserPublicKey, root.contactDetails, null)
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StatusAction {
|
|
|
|
id: verifyIdentityAction
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Request ID verification")
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "verifyIdentity_StatusItem"
|
2023-05-19 16:07:50 +00:00
|
|
|
icon.name: "checkmark-circle"
|
2024-05-29 08:33:36 +00:00
|
|
|
enabled: idVerificationFlowsEnabled
|
|
|
|
&& !root.isMe && root.isContact
|
2024-02-26 09:39:08 +00:00
|
|
|
&& !root.isBlockedContact
|
|
|
|
&& !root.userIsLocallyTrusted
|
|
|
|
&& root.outgoingVerificationStatus === Constants.verificationStatus.unverified
|
|
|
|
&& !root.hasActiveReceivedVerificationRequestFrom
|
|
|
|
&& !root.isBridgedAccount
|
2024-02-16 11:56:29 +00:00
|
|
|
onTriggered: Global.openSendIDRequestPopup(root.selectedUserPublicKey, root.contactDetails, null)
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
2024-02-26 09:39:08 +00:00
|
|
|
StatusAction {
|
|
|
|
text: qsTr("Mark as ID verified")
|
|
|
|
objectName: "markAsVerified_StatusItem"
|
|
|
|
icon.name: "checkmark-circle"
|
2024-05-29 08:33:36 +00:00
|
|
|
enabled: idVerificationFlowsEnabled && !root.isMe && root.isContact && !root.isBridgedAccount && !root.isBlockedContact && !(root.isTrusted || root.userIsLocallyTrusted)
|
2024-02-26 09:39:08 +00:00
|
|
|
onTriggered: Global.openMarkAsIDVerifiedPopup(root.selectedUserPublicKey, root.contactDetails, null)
|
|
|
|
}
|
2023-05-19 16:07:50 +00:00
|
|
|
StatusAction {
|
|
|
|
id: pendingIdentityAction
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "pendingIdentity_StatusItem"
|
2024-02-26 18:54:05 +00:00
|
|
|
text: {
|
|
|
|
if (root.isVerificationRequestSent) {
|
|
|
|
if (root.incomingVerificationStatus !== Constants.verificationStatus.verified)
|
|
|
|
return qsTr("ID verification pending...")
|
|
|
|
return qsTr("Review ID verification reply")
|
|
|
|
}
|
|
|
|
return qsTr("Reply to ID verification request")
|
|
|
|
}
|
|
|
|
icon.name: root.isVerificationRequestSent && root.incomingVerificationStatus !== Constants.verificationStatus.verified ? "history"
|
|
|
|
: "checkmark-circle"
|
2024-05-29 08:33:36 +00:00
|
|
|
enabled: idVerificationFlowsEnabled && !root.isMe && root.isContact && !root.isBridgedAccount && !root.isBlockedContact && !(root.isTrusted || root.userIsLocallyTrusted) &&
|
2024-02-26 18:54:05 +00:00
|
|
|
(root.hasActiveReceivedVerificationRequestFrom || root.isVerificationRequestSent)
|
|
|
|
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: {
|
2024-02-26 18:54:05 +00:00
|
|
|
if (root.hasActiveReceivedVerificationRequestFrom) {
|
|
|
|
Global.openIncomingIDRequestPopup(root.selectedUserPublicKey, root.contactDetails, null)
|
2023-05-19 16:07:50 +00:00
|
|
|
} else if (root.isVerificationRequestSent) {
|
2024-02-26 18:54:05 +00:00
|
|
|
Global.openOutgoingIDRequestPopup(root.selectedUserPublicKey, root.contactDetails, null)
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
root.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StatusAction {
|
|
|
|
id: renameAction
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "rename_StatusItem"
|
2024-02-07 14:56:45 +00:00
|
|
|
text: contactDetails.localNickname ? qsTr("Edit nickname") : qsTr("Add nickname")
|
2023-05-19 16:07:50 +00:00
|
|
|
icon.name: "edit_pencil"
|
2024-01-05 15:34:20 +00:00
|
|
|
enabled: !root.isMe && !root.isBridgedAccount
|
2024-03-07 09:51:16 +00:00
|
|
|
onTriggered: Global.openNicknamePopupRequested(root.selectedUserPublicKey, root.contactDetails, null)
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-07 14:56:45 +00:00
|
|
|
StatusMenuSeparator {
|
2024-02-26 18:54:05 +00:00
|
|
|
visible: blockMenuItem.enabled || unblockAction.enabled
|
2024-02-07 14:56:45 +00:00
|
|
|
}
|
|
|
|
|
2024-02-14 12:52:54 +00:00
|
|
|
StatusAction {
|
|
|
|
text: qsTr("Remove nickname")
|
|
|
|
icon.name: "delete"
|
|
|
|
type: StatusAction.Type.Danger
|
|
|
|
enabled: !root.isMe && !!contactDetails.localNickname
|
|
|
|
onTriggered: root.store.contactsStore.changeContactNickname(root.selectedUserPublicKey, "", root.selectedUserDisplayName, true)
|
|
|
|
}
|
|
|
|
|
2023-05-19 16:07:50 +00:00
|
|
|
StatusAction {
|
|
|
|
id: unblockAction
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "unblock_StatusItem"
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Unblock user")
|
|
|
|
icon.name: "cancel"
|
|
|
|
type: StatusAction.Type.Danger
|
2024-01-05 15:34:20 +00:00
|
|
|
enabled: !root.isMe && root.isBlockedContact && !root.isBridgedAccount
|
2024-02-20 18:52:07 +00:00
|
|
|
onTriggered: Global.unblockContactRequested(root.selectedUserPublicKey, root.contactDetails)
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-26 09:39:08 +00:00
|
|
|
StatusAction {
|
|
|
|
objectName: "removeIDVerification_StatusItem"
|
|
|
|
text: qsTr("Remove ID verification")
|
|
|
|
icon.name: "delete"
|
|
|
|
type: StatusAction.Type.Danger
|
2024-05-29 08:33:36 +00:00
|
|
|
enabled: idVerificationFlowsEnabled && !root.isMe && root.isContact && !root.isBridgedAccount && (root.isTrusted || root.userIsLocallyTrusted)
|
2024-02-26 09:39:08 +00:00
|
|
|
onTriggered: Global.openRemoveIDVerificationDialog(root.selectedUserPublicKey, root.contactDetails, null)
|
|
|
|
}
|
2023-05-19 16:07:50 +00:00
|
|
|
|
|
|
|
StatusAction {
|
|
|
|
id: markUntrustworthyMenuItem
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "markUntrustworthy_StatusItem"
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Mark as untrusted")
|
2023-05-19 16:07:50 +00:00
|
|
|
icon.name: "warning"
|
|
|
|
type: StatusAction.Type.Danger
|
2024-02-16 17:34:09 +00:00
|
|
|
enabled: !root.isMe && !root.userIsUntrustworthy && !root.isBridgedAccount && !root.isBlockedContact
|
|
|
|
onTriggered: Global.markAsUntrustedRequested(root.selectedUserPublicKey, root.contactDetails)
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-26 18:54:05 +00:00
|
|
|
StatusAction {
|
|
|
|
text: qsTr("Cancel ID verification request")
|
|
|
|
icon.name: "delete"
|
|
|
|
type: StatusAction.Type.Danger
|
2024-05-29 08:33:36 +00:00
|
|
|
enabled: idVerificationFlowsEnabled && !root.isMe && root.isContact && !root.isBlockedContact && !root.isBridgedAccount && root.isVerificationRequestSent
|
2024-02-26 18:54:05 +00:00
|
|
|
onTriggered: root.store.contactsStore.cancelVerificationRequest(root.selectedUserPublicKey)
|
|
|
|
}
|
|
|
|
|
2023-05-19 16:07:50 +00:00
|
|
|
StatusAction {
|
|
|
|
id: removeUntrustworthyMarkMenuItem
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "removeUntrustworthy_StatusItem"
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Remove untrusted mark")
|
2023-05-19 16:07:50 +00:00
|
|
|
icon.name: "warning"
|
2024-02-07 14:56:45 +00:00
|
|
|
type: StatusAction.Type.Danger
|
2024-01-05 15:34:20 +00:00
|
|
|
enabled: !root.isMe && root.userIsUntrustworthy && !root.isBridgedAccount
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: root.store.contactsStore.removeTrustStatus(root.selectedUserPublicKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
StatusAction {
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Remove contact")
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "removeContact_StatusItem"
|
2023-05-19 16:07:50 +00:00
|
|
|
icon.name: "remove-contact"
|
|
|
|
type: StatusAction.Type.Danger
|
2024-01-05 15:34:20 +00:00
|
|
|
enabled: root.isContact && !root.isBlockedContact && !root.hasPendingContactRequest && !root.isBridgedAccount
|
2024-02-20 17:19:36 +00:00
|
|
|
onTriggered: Global.removeContactRequested(root.selectedUserPublicKey, root.contactDetails)
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StatusAction {
|
|
|
|
id: blockMenuItem
|
2023-12-18 10:12:57 +00:00
|
|
|
objectName: "blockUser_StatusItem"
|
2024-02-07 14:56:45 +00:00
|
|
|
text: qsTr("Block user")
|
2023-05-19 16:07:50 +00:00
|
|
|
icon.name: "cancel"
|
|
|
|
type: StatusAction.Type.Danger
|
2024-01-05 15:34:20 +00:00
|
|
|
enabled: !root.isMe && !root.isBlockedContact && !root.isBridgedAccount
|
2024-02-20 18:52:07 +00:00
|
|
|
onTriggered: Global.blockContactRequested(root.selectedUserPublicKey, root.contactDetails)
|
2023-05-19 16:07:50 +00:00
|
|
|
}
|
|
|
|
}
|