mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-22 04:21:44 +00:00
feat(contacts): add respond to request and pending contact menu options
Fixes #6251 Adds the "Respond to Contact Request" and "Contact Request Pending" options to the MessageContextMenu Also fixes some small issues with contact verification where the state of the incoming request was not correct
This commit is contained in:
parent
03780d4875
commit
16b2ca5c2c
@ -321,3 +321,6 @@ proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
|
|||||||
|
|
||||||
proc getStatusForContactWithId*(self: Controller, publicKey: string): StatusUpdateDto =
|
proc getStatusForContactWithId*(self: Controller, publicKey: string): StatusUpdateDto =
|
||||||
return self.contactsService.getStatusForContactWithId(publicKey)
|
return self.contactsService.getStatusForContactWithId(publicKey)
|
||||||
|
|
||||||
|
proc getVerificationRequestFrom*(self: Controller, publicKey: string): VerificationRequest =
|
||||||
|
self.contactsService.getVerificationRequestFrom(publicKey)
|
||||||
|
@ -202,7 +202,8 @@ method onStatusUrlRequested*(self: AccessInterface, action: StatusUrlAction, com
|
|||||||
url: string, userId: string, groupName: string, listOfUserIds: seq[string]) {.base.} =
|
url: string, userId: string, groupName: string, listOfUserIds: seq[string]) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method getVerificationRequestFrom*(self: AccessInterface, publicKey: string): VerificationRequest {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
# This way (using concepts) is used only for the modules managed by AppController
|
# This way (using concepts) is used only for the modules managed by AppController
|
||||||
type
|
type
|
||||||
|
@ -677,9 +677,13 @@ method communityEdited*[T](
|
|||||||
let channelGroup = community.toChannelGroupDto()
|
let channelGroup = community.toChannelGroupDto()
|
||||||
self.view.editItem(self.createChannelGroupItem(channelGroup))
|
self.view.editItem(self.createChannelGroupItem(channelGroup))
|
||||||
|
|
||||||
|
method getVerificationRequestFrom*[T](self: Module[T], publicKey: string): VerificationRequest =
|
||||||
|
self.controller.getVerificationRequestFrom(publicKey)
|
||||||
|
|
||||||
method getContactDetailsAsJson*[T](self: Module[T], publicKey: string): string =
|
method getContactDetailsAsJson*[T](self: Module[T], publicKey: string): string =
|
||||||
let contact = self.controller.getContact(publicKey)
|
let contact = self.controller.getContact(publicKey)
|
||||||
let (name, _, _) = self.controller.getContactNameAndImage(contact.id)
|
let (name, _, _) = self.controller.getContactNameAndImage(contact.id)
|
||||||
|
let request = self.getVerificationRequestFrom(publicKey)
|
||||||
let jsonObj = %* {
|
let jsonObj = %* {
|
||||||
"displayName": name,
|
"displayName": name,
|
||||||
"displayIcon": contact.image.thumbnail,
|
"displayIcon": contact.image.thumbnail,
|
||||||
@ -699,7 +703,9 @@ method getContactDetailsAsJson*[T](self: Module[T], publicKey: string): string =
|
|||||||
"isSyncing": contact.isSyncing,
|
"isSyncing": contact.isSyncing,
|
||||||
"removed": contact.removed,
|
"removed": contact.removed,
|
||||||
"trustStatus": contact.trustStatus.int,
|
"trustStatus": contact.trustStatus.int,
|
||||||
|
# TODO rename verificationStatus to outgoingVerificationStatus
|
||||||
"verificationStatus": contact.verificationStatus.int,
|
"verificationStatus": contact.verificationStatus.int,
|
||||||
|
"incomingVerificationStatus": request.status.int,
|
||||||
"hasAddedUs": contact.hasAddedUs
|
"hasAddedUs": contact.hasAddedUs
|
||||||
}
|
}
|
||||||
return $jsonObj
|
return $jsonObj
|
||||||
|
@ -615,8 +615,9 @@ QtObject:
|
|||||||
return self.receivedIdentityRequests[publicKey]
|
return self.receivedIdentityRequests[publicKey]
|
||||||
|
|
||||||
let response = status_contacts.getVerificationRequestFrom(publicKey)
|
let response = status_contacts.getVerificationRequestFrom(publicKey)
|
||||||
result = response.result.toVerificationRequest()
|
if not response.result.isNil and response.result.kind == JObject:
|
||||||
self.receivedIdentityRequests[publicKey] = result
|
result = response.result.toVerificationRequest()
|
||||||
|
self.receivedIdentityRequests[publicKey] = result
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
let errDesription = e.msg
|
let errDesription = e.msg
|
||||||
error "error obtaining verification request", errDesription
|
error "error obtaining verification request", errDesription
|
||||||
|
@ -32,7 +32,8 @@ StatusModal {
|
|||||||
property string userEnsName: ""
|
property string userEnsName: ""
|
||||||
property string userIcon: ""
|
property string userIcon: ""
|
||||||
property int userTrustStatus: Constants.trustStatus.unknown
|
property int userTrustStatus: Constants.trustStatus.unknown
|
||||||
property int verificationStatus: Constants.verificationStatus.unverified
|
property int outgoingVerificationStatus: Constants.verificationStatus.unverified
|
||||||
|
property int incomingVerificationStatus: Constants.verificationStatus.unverified
|
||||||
property string text: ""
|
property string text: ""
|
||||||
property string challenge: ""
|
property string challenge: ""
|
||||||
property string response: ""
|
property string response: ""
|
||||||
@ -85,8 +86,9 @@ StatusModal {
|
|||||||
userTrustStatus = contactDetails.trustStatus
|
userTrustStatus = contactDetails.trustStatus
|
||||||
userTrustIsUnknown = contactDetails.trustStatus === Constants.trustStatus.unknown
|
userTrustIsUnknown = contactDetails.trustStatus === Constants.trustStatus.unknown
|
||||||
userIsUntrustworthy = contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
userIsUntrustworthy = contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
||||||
verificationStatus = contactDetails.verificationStatus
|
outgoingVerificationStatus = contactDetails.verificationStatus
|
||||||
isVerificationSent = verificationStatus !== Constants.verificationStatus.unverified
|
incomingVerificationStatus = contactDetails.incomingVerificationStatus
|
||||||
|
isVerificationSent = outgoingVerificationStatus !== Constants.verificationStatus.unverified
|
||||||
|
|
||||||
if (isContact && popup.contactsStore.hasReceivedVerificationRequestFrom(publicKey)) {
|
if (isContact && popup.contactsStore.hasReceivedVerificationRequestFrom(publicKey)) {
|
||||||
popup.hasReceivedVerificationRequest = true
|
popup.hasReceivedVerificationRequest = true
|
||||||
@ -95,7 +97,7 @@ StatusModal {
|
|||||||
if(isContact && isVerificationSent) {
|
if(isContact && isVerificationSent) {
|
||||||
let verificationDetails = popup.contactsStore.getSentVerificationDetailsAsJson(publicKey);
|
let verificationDetails = popup.contactsStore.getSentVerificationDetailsAsJson(publicKey);
|
||||||
|
|
||||||
verificationStatus = verificationDetails.requestStatus;
|
outgoingVerificationStatus = verificationDetails.requestStatus;
|
||||||
verificationChallenge = verificationDetails.challenge;
|
verificationChallenge = verificationDetails.challenge;
|
||||||
verificationResponse = verificationDetails.response;
|
verificationResponse = verificationDetails.response;
|
||||||
verificationResponseDisplayName = verificationDetails.displayName;
|
verificationResponseDisplayName = verificationDetails.displayName;
|
||||||
@ -103,8 +105,9 @@ StatusModal {
|
|||||||
verificationRequestedAt = verificationDetails.requestedAt;
|
verificationRequestedAt = verificationDetails.requestedAt;
|
||||||
verificationRepliedAt = verificationDetails.repliedAt;
|
verificationRepliedAt = verificationDetails.repliedAt;
|
||||||
}
|
}
|
||||||
isTrusted = verificationStatus === Constants.verificationStatus.trusted
|
isTrusted = outgoingVerificationStatus === Constants.verificationStatus.trusted
|
||||||
isVerified = verificationStatus === Constants.verificationStatus.verified
|
|| incomingVerificationStatus === Constants.verificationStatus.trusted
|
||||||
|
isVerified = outgoingVerificationStatus === Constants.verificationStatus.verified
|
||||||
|
|
||||||
text = ""; // this is most likely unneeded
|
text = ""; // this is most likely unneeded
|
||||||
isCurrentUser = popup.profileStore.pubkey === publicKey;
|
isCurrentUser = popup.profileStore.pubkey === publicKey;
|
||||||
@ -112,16 +115,21 @@ StatusModal {
|
|||||||
showFooter = !isCurrentUser;
|
showFooter = !isCurrentUser;
|
||||||
popup.open();
|
popup.open();
|
||||||
|
|
||||||
if (state === "openNickname") {
|
if (state === Constants.profilePopupStates.openNickname) {
|
||||||
profileView.nicknamePopup.open();
|
profileView.nicknamePopup.open();
|
||||||
} else if (state === "contactRequest") {
|
} else if (state === Constants.profilePopupStates.contactRequest) {
|
||||||
sendContactRequestModal.open()
|
sendContactRequestModal.open()
|
||||||
} else if (state === "blockUser") {
|
} else if (state === Constants.profilePopupStates.blockUser) {
|
||||||
blockUser();
|
blockUser();
|
||||||
} else if (state === "unblockUser") {
|
} else if (state === Constants.profilePopupStates.unblockUser) {
|
||||||
unblockUser();
|
unblockUser();
|
||||||
} else if (state === "verifyIdentity") {
|
} else if (state === Constants.profilePopupStates.verifyIdentity) {
|
||||||
showVerifyIdentitySection = true;
|
showVerifyIdentitySection = true;
|
||||||
|
} else if (state === Constants.profilePopupStates.respondToPendingRequest) {
|
||||||
|
popup.openPendingRequestPopup()
|
||||||
|
} else if (state === Constants.profilePopupStates.showVerificationPendingSection) {
|
||||||
|
popup.showVerificationPendingSection = true
|
||||||
|
profileView.wizardAnimation.running = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +145,23 @@ StatusModal {
|
|||||||
profileView.unblockContactConfirmationDialog.open();
|
profileView.unblockContactConfirmationDialog.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openPendingRequestPopup() {
|
||||||
|
try {
|
||||||
|
let request = popup.contactsStore.getVerificationDetailsFromAsJson(popup.userPublicKey)
|
||||||
|
Global.openPopup(contactVerificationRequestPopupComponent, {
|
||||||
|
senderPublicKey: request.from,
|
||||||
|
senderDisplayName: request.displayName,
|
||||||
|
senderIcon: request.icon,
|
||||||
|
challengeText: request.challenge,
|
||||||
|
responseText: request.response,
|
||||||
|
messageTimestamp: request.requestedAt,
|
||||||
|
responseTimestamp: request.repliedAt
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error getting or parsing verification data", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
width: 700
|
width: 700
|
||||||
|
|
||||||
header.title: {
|
header.title: {
|
||||||
@ -186,7 +211,7 @@ StatusModal {
|
|||||||
hasReceivedVerificationRequest: popup.hasReceivedVerificationRequest
|
hasReceivedVerificationRequest: popup.hasReceivedVerificationRequest
|
||||||
|
|
||||||
userTrustStatus: popup.userTrustStatus
|
userTrustStatus: popup.userTrustStatus
|
||||||
verificationStatus: popup.verificationStatus
|
outgoingVerificationStatus: popup.outgoingVerificationStatus
|
||||||
|
|
||||||
showVerifyIdentitySection: popup.showVerifyIdentitySection
|
showVerifyIdentitySection: popup.showVerifyIdentitySection
|
||||||
showVerificationPendingSection: popup.showVerificationPendingSection
|
showVerificationPendingSection: popup.showVerificationPendingSection
|
||||||
@ -354,20 +379,7 @@ StatusModal {
|
|||||||
(hasReceivedVerificationRequest && !isTrusted)
|
(hasReceivedVerificationRequest && !isTrusted)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (hasReceivedVerificationRequest) {
|
if (hasReceivedVerificationRequest) {
|
||||||
try {
|
popup.openPendingRequestPopup()
|
||||||
let request = popup.contactsStore.getVerificationDetailsFromAsJson(popup.userPublicKey)
|
|
||||||
Global.openPopup(contactVerificationRequestPopupComponent, {
|
|
||||||
senderPublicKey: request.from,
|
|
||||||
senderDisplayName: request.displayName,
|
|
||||||
senderIcon: request.icon,
|
|
||||||
challengeText: request.challenge,
|
|
||||||
responseText: request.response,
|
|
||||||
messageTimestamp: request.requestedAt,
|
|
||||||
responseTimestamp: request.repliedAt
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error getting or parsing verification data", e)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
popup.showVerificationPendingSection = true
|
popup.showVerificationPendingSection = true
|
||||||
profileView.wizardAnimation.running = true
|
profileView.wizardAnimation.running = true
|
||||||
|
@ -39,7 +39,7 @@ Rectangle {
|
|||||||
property bool isAddedContact: false
|
property bool isAddedContact: false
|
||||||
|
|
||||||
property int userTrustStatus: Constants.trustStatus.unknown
|
property int userTrustStatus: Constants.trustStatus.unknown
|
||||||
property int verificationStatus: Constants.verificationStatus.unverified
|
property int outgoingVerificationStatus: Constants.verificationStatus.unverified
|
||||||
|
|
||||||
property string challenge: ""
|
property string challenge: ""
|
||||||
property string response: ""
|
property string response: ""
|
||||||
@ -140,7 +140,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
ScriptAction {
|
ScriptAction {
|
||||||
script: {
|
script: {
|
||||||
if (verificationStatus === Constants.verificationStatus.trusted) {
|
if (outgoingVerificationStatus === Constants.verificationStatus.trusted) {
|
||||||
stepsListModel.setProperty(2, "stepCompleted", true);
|
stepsListModel.setProperty(2, "stepCompleted", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,15 +62,19 @@ StatusPopupMenu {
|
|||||||
return root.selectedUserPublicKey !== "" && !!contactDetails.isContact
|
return root.selectedUserPublicKey !== "" && !!contactDetails.isContact
|
||||||
}
|
}
|
||||||
readonly property bool isBlockedContact: d.contactDetails && d.contactDetails.isBlocked
|
readonly property bool isBlockedContact: d.contactDetails && d.contactDetails.isBlocked
|
||||||
readonly property bool isBlockedContact: {
|
|
||||||
return root.selectedUserPublicKey !== "" && !!contactDetails.isBlocked
|
|
||||||
}
|
|
||||||
readonly property int outgoingVerificationStatus: {
|
readonly property int outgoingVerificationStatus: {
|
||||||
if (root.selectedUserPublicKey === "" || root.isMe || !root.isContact) {
|
if (root.selectedUserPublicKey === "" || root.isMe || !root.isContact) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return contactDetails.verificationStatus
|
return contactDetails.verificationStatus
|
||||||
}
|
}
|
||||||
|
readonly property int incomingVerificationStatus: {
|
||||||
|
if (root.selectedUserPublicKey === "" || root.isMe || !root.isContact) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return contactDetails.incomingVerificationStatus
|
||||||
|
}
|
||||||
readonly property bool hasPendingContactRequest: {
|
readonly property bool hasPendingContactRequest: {
|
||||||
return !root.isMe && root.selectedUserPublicKey !== "" &&
|
return !root.isMe && root.selectedUserPublicKey !== "" &&
|
||||||
root.store.contactsStore.hasPendingContactRequest(root.selectedUserPublicKey);
|
root.store.contactsStore.hasPendingContactRequest(root.selectedUserPublicKey);
|
||||||
@ -87,6 +91,13 @@ StatusPopupMenu {
|
|||||||
}
|
}
|
||||||
return root.outgoingVerificationStatus !== Constants.verificationStatus.unverified
|
return root.outgoingVerificationStatus !== Constants.verificationStatus.unverified
|
||||||
}
|
}
|
||||||
|
readonly property bool isTrusted: {
|
||||||
|
if (!root.selectedUserPublicKey || root.isMe || !root.isContact) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return root.verificationStatus === Constants.verificationStatus.trusted ||
|
||||||
|
root.incomingVerificationStatus === Constants.verificationStatus.trusted
|
||||||
|
}
|
||||||
|
|
||||||
readonly property bool userTrustIsUnknown: d.contactDetails && d.contactDetails.trustStatus === Constants.trustStatus.unknown
|
readonly property bool userTrustIsUnknown: d.contactDetails && d.contactDetails.trustStatus === Constants.trustStatus.unknown
|
||||||
readonly property bool userIsUntrustworthy: d.contactDetails && d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
readonly property bool userIsUntrustworthy: d.contactDetails && d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
||||||
@ -252,17 +263,8 @@ StatusPopupMenu {
|
|||||||
enabled: root.isProfile && !root.isMe && !root.isContact
|
enabled: root.isProfile && !root.isMe && !root.isContact
|
||||||
&& !root.isBlockedContact && !root.hasPendingContactRequest
|
&& !root.isBlockedContact && !root.hasPendingContactRequest
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.openProfileClicked(root.selectedUserPublicKey, "contactRequest")
|
root.openProfileClicked(root.selectedUserPublicKey,
|
||||||
root.close()
|
Constants.profilePopupStates.contactRequest)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusMenuItem {
|
|
||||||
text: qsTr("Rename")
|
|
||||||
icon.name: "edit_pencil"
|
|
||||||
enabled: root.isProfile && !root.isMe
|
|
||||||
onTriggered: {
|
|
||||||
root.openProfileClicked(root.selectedUserPublicKey, "openNickname")
|
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,7 +276,42 @@ StatusPopupMenu {
|
|||||||
&& !root.isBlockedContact && !root.isVerificationRequestSent
|
&& !root.isBlockedContact && !root.isVerificationRequestSent
|
||||||
&& !root.hasReceivedVerificationRequestFrom
|
&& !root.hasReceivedVerificationRequestFrom
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.openProfileClicked(root.selectedUserPublicKey, "verifyIdentity")
|
root.openProfileClicked(root.selectedUserPublicKey,
|
||||||
|
Constants.profilePopupStates.verifyIdentity)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusMenuItem {
|
||||||
|
text: isVerificationRequestSent ||
|
||||||
|
root.incomingVerificationStatus === Constants.verificationStatus.verified ?
|
||||||
|
qsTr("ID Request Pending....") :
|
||||||
|
qsTr("Respond to ID Request...")
|
||||||
|
icon.name: "checkmark-circle"
|
||||||
|
enabled: root.isProfile && !root.isMe && root.isContact
|
||||||
|
&& !root.isBlockedContact && !root.isTrusted
|
||||||
|
&& (root.hasReceivedVerificationRequestFrom
|
||||||
|
|| root.isVerificationRequestSent)
|
||||||
|
onTriggered: {
|
||||||
|
if (hasReceivedVerificationRequestFrom) {
|
||||||
|
root.openProfileClicked(root.selectedUserPublicKey,
|
||||||
|
Constants.profilePopupStates.respondToPendingRequest)
|
||||||
|
} else if (root.isVerificationRequestSent) {
|
||||||
|
root.openProfileClicked(root.selectedUserPublicKey,
|
||||||
|
Constants.profilePopupStates.showVerificationPendingSection)
|
||||||
|
}
|
||||||
|
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Rename")
|
||||||
|
icon.name: "edit_pencil"
|
||||||
|
enabled: root.isProfile && !root.isMe
|
||||||
|
onTriggered: {
|
||||||
|
root.openProfileClicked(root.selectedUserPublicKey,
|
||||||
|
Constants.profilePopupStates.openNickname)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,6 +153,16 @@ QtObject {
|
|||||||
readonly property int blockedContacts: 6
|
readonly property int blockedContacts: 6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property QtObject profilePopupStates: QtObject {
|
||||||
|
readonly property string openNickname: "openNickname"
|
||||||
|
readonly property string contactRequest: "contactRequest"
|
||||||
|
readonly property string blockUser: "blockUser"
|
||||||
|
readonly property string unblockUser: "unblockUser"
|
||||||
|
readonly property string verifyIdentity: "verifyIdentity"
|
||||||
|
readonly property string showVerificationPendingSection: "showVerificationPendingSection"
|
||||||
|
readonly property string respondToPendingRequest: "respondToPendingRequest"
|
||||||
|
}
|
||||||
|
|
||||||
readonly property QtObject validators: QtObject {
|
readonly property QtObject validators: QtObject {
|
||||||
readonly property list<StatusValidator> displayName: [
|
readonly property list<StatusValidator> displayName: [
|
||||||
StatusMinLengthValidator {
|
StatusMinLengthValidator {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user