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
|
|
|
|
|
|
|
|
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 {}
|
|
|
|
}
|
|
|
|
return Utils.getContactDetailsAsJson(root.selectedUserPublicKey);
|
|
|
|
}
|
|
|
|
readonly property bool isContact: {
|
|
|
|
return root.selectedUserPublicKey !== "" && !!contactDetails.isContact
|
|
|
|
}
|
|
|
|
readonly property bool isBlockedContact: (!!contactDetails && contactDetails.isBlocked) || false
|
|
|
|
|
|
|
|
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 !== "" &&
|
|
|
|
root.store.contactsStore.hasPendingContactRequest(root.selectedUserPublicKey);
|
|
|
|
}
|
|
|
|
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
|
|
|
|
|
|
|
|
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
|
|
|
|
displayName: root.selectedUserDisplayName
|
|
|
|
pubkey: root.selectedUserPublicKey
|
|
|
|
icon: root.selectedUserIcon
|
|
|
|
trustStatus: contactDetails && contactDetails.trustStatus ? contactDetails.trustStatus
|
|
|
|
: Constants.trustStatus.unknown
|
|
|
|
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-07 14:56:45 +00:00
|
|
|
// TODO Review contact request popup
|
|
|
|
|
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"
|
2023-05-19 16:07:50 +00:00
|
|
|
enabled: !root.isMe && !root.isContact
|
2024-01-05 15:34:20 +00:00
|
|
|
&& !root.isBlockedContact && !root.hasPendingContactRequest && !root.isBridgedAccount
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: {
|
|
|
|
Global.openContactRequestPopup(root.selectedUserPublicKey, null)
|
|
|
|
root.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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"
|
|
|
|
enabled: !root.isMe && root.isContact
|
|
|
|
&& !root.isBlockedContact
|
|
|
|
&& root.outgoingVerificationStatus === Constants.verificationStatus.unverified
|
|
|
|
&& !root.hasActiveReceivedVerificationRequestFrom
|
2024-01-05 15:34:20 +00:00
|
|
|
&& !root.isBridgedAccount
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: {
|
|
|
|
Global.openSendIDRequestPopup(root.selectedUserPublicKey, null)
|
|
|
|
root.close()
|
|
|
|
}
|
|
|
|
}
|
2024-02-07 14:56:45 +00:00
|
|
|
// TODO Mark as ID verified
|
2023-05-19 16:07:50 +00:00
|
|
|
StatusAction {
|
|
|
|
id: pendingIdentityAction
|
2023-11-28 09:29:18 +00:00
|
|
|
objectName: "pendingIdentity_StatusItem"
|
2024-02-07 14:56:45 +00:00
|
|
|
text: isVerificationRequestSent || root.incomingVerificationStatus === Constants.verificationStatus.verified ? qsTr("ID Request Pending...")
|
|
|
|
: qsTr("Respond to ID Request...")
|
2023-05-19 16:07:50 +00:00
|
|
|
icon.name: "checkmark-circle"
|
|
|
|
enabled: !root.isMe && root.isContact
|
|
|
|
&& !root.isBlockedContact && !root.isTrusted
|
|
|
|
&& (root.hasActiveReceivedVerificationRequestFrom
|
|
|
|
|| root.isVerificationRequestSent)
|
2024-01-05 15:34:20 +00:00
|
|
|
&& !root.isBridgedAccount
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: {
|
|
|
|
if (hasActiveReceivedVerificationRequestFrom) {
|
|
|
|
Global.openIncomingIDRequestPopup(root.selectedUserPublicKey, null)
|
|
|
|
} else if (root.isVerificationRequestSent) {
|
|
|
|
Global.openOutgoingIDRequestPopup(root.selectedUserPublicKey, null)
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: {
|
|
|
|
Global.openNicknamePopupRequested(root.selectedUserPublicKey, contactDetails.localNickname,
|
|
|
|
"%1 (%2)".arg(root.selectedUserDisplayName).arg(Utils.getElidedCompressedPk(root.selectedUserPublicKey)))
|
|
|
|
root.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-07 14:56:45 +00:00
|
|
|
StatusMenuSeparator {
|
|
|
|
visible: blockMenuItem.enabled
|
|
|
|
|| markUntrustworthyMenuItem.enabled
|
|
|
|
|| removeUntrustworthyMarkMenuItem.enabled
|
|
|
|
}
|
|
|
|
|
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
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: Global.unblockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
|
|
|
|
}
|
|
|
|
|
2024-02-07 14:56:45 +00:00
|
|
|
// TODO Remove ID verification + confirmation dialog
|
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-07 14:56:45 +00:00
|
|
|
enabled: !root.isMe && root.userTrustIsUnknown && !root.isBridgedAccount && !root.isBlockedContact
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: root.store.contactsStore.markUntrustworthy(root.selectedUserPublicKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: {
|
|
|
|
Global.removeContactRequested(root.selectedUserDisplayName, root.selectedUserPublicKey)
|
|
|
|
root.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2023-05-19 16:07:50 +00:00
|
|
|
onTriggered: Global.blockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
|
|
|
|
}
|
|
|
|
}
|