|
@ -760,6 +760,7 @@ method getContactDetailsAsJson*[T](self: Module[T], publicKey: string, getVerifi
|
||||||
requestStatus = self.getVerificationRequestFrom(publicKey).status.int
|
requestStatus = self.getVerificationRequestFrom(publicKey).status.int
|
||||||
let jsonObj = %* {
|
let jsonObj = %* {
|
||||||
"displayName": name,
|
"displayName": name,
|
||||||
|
"optionalName": self.controller.getContactDetails(contact.id).optionalName, # original display name, if renamed
|
||||||
"displayIcon": contact.image.thumbnail,
|
"displayIcon": contact.image.thumbnail,
|
||||||
"publicKey": contact.id,
|
"publicKey": contact.id,
|
||||||
"name": contact.name,
|
"name": contact.name,
|
||||||
|
@ -982,4 +983,4 @@ method runAuthenticationPopup*[T](self: Module[T], keyUid: string, bip44Path: st
|
||||||
self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.Authentication, keyUid, bip44Path, txHash)
|
self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.Authentication, keyUid, bip44Path, txHash)
|
||||||
|
|
||||||
method onDisplayKeycardSharedModuleFlow*[T](self: Module[T]) =
|
method onDisplayKeycardSharedModuleFlow*[T](self: Module[T]) =
|
||||||
self.view.emitDisplayKeycardSharedModuleFlow()
|
self.view.emitDisplayKeycardSharedModuleFlow()
|
||||||
|
|
|
@ -229,6 +229,7 @@ QtObject:
|
||||||
self.items[ind].ensName = ensName
|
self.items[ind].ensName = ensName
|
||||||
self.items[ind].localNickname = localNickname
|
self.items[ind].localNickname = localNickname
|
||||||
self.items[ind].alias = alias
|
self.items[ind].alias = alias
|
||||||
|
self.items[ind].icon = icon
|
||||||
self.items[ind].isUntrustworthy = isUntrustworthy
|
self.items[ind].isUntrustworthy = isUntrustworthy
|
||||||
|
|
||||||
let index = self.createIndex(ind, 0, nil)
|
let index = self.createIndex(ind, 0, nil)
|
||||||
|
@ -310,4 +311,4 @@ QtObject:
|
||||||
return self.items.map(i => i.pubKey)
|
return self.items.map(i => i.pubKey)
|
||||||
|
|
||||||
proc containsItemWithPubKey*(self: Model, pubKey: string): bool =
|
proc containsItemWithPubKey*(self: Model, pubKey: string): bool =
|
||||||
return self.findIndexByPubKey(pubKey) != -1
|
return self.findIndexByPubKey(pubKey) != -1
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.14
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isContact: false
|
property bool isContact: false
|
||||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
property int trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||||
|
property bool tiny: true
|
||||||
|
|
||||||
property StatusAssetSettings mutualConnectionIcon: StatusAssetSettings {
|
property StatusAssetSettings mutualConnectionIcon: StatusAssetSettings {
|
||||||
name: "tiny/tiny-contact"
|
name: root.tiny ? "tiny/tiny-contact" : "tiny/contact"
|
||||||
color: Theme.palette.indirectColor1
|
color: Theme.palette.indirectColor1
|
||||||
width: dummyImage.width
|
width: Math.min(bgWidth, dummyImage.width)
|
||||||
height: dummyImage.height
|
height: Math.min(bgHeight, dummyImage.height)
|
||||||
bgWidth: 10
|
bgWidth: root.tiny ? 10 : 16.5
|
||||||
bgHeight: 10
|
bgHeight: root.tiny ? 10 : 16.5
|
||||||
bgColor: Theme.palette.primaryColor1
|
bgColor: Theme.palette.primaryColor1
|
||||||
// Only used to get implicit width and height from the actual image
|
// Only used to get implicit width and height from the actual image
|
||||||
property Image dummyImage: Image {
|
property Image dummyImage: Image {
|
||||||
|
@ -26,12 +28,13 @@ Row {
|
||||||
|
|
||||||
property StatusAssetSettings trustContactIcon: StatusAssetSettings {
|
property StatusAssetSettings trustContactIcon: StatusAssetSettings {
|
||||||
// None and Untrustworthy types, same aspect (Icon will not be visible in case of None type):
|
// None and Untrustworthy types, same aspect (Icon will not be visible in case of None type):
|
||||||
name: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? "tiny/tiny-checkmark" : "tiny/subtract"
|
name: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? root.tiny ? "tiny/tiny-checkmark" : "tiny/checkmark"
|
||||||
|
: root.tiny ? "tiny/tiny-exclamation" : "tiny/exclamation"
|
||||||
color: Theme.palette.indirectColor1
|
color: Theme.palette.indirectColor1
|
||||||
width: dummyImage.width
|
width: Math.min(bgWidth, dummyImage.width)
|
||||||
height: dummyImage.height
|
height: Math.min(bgHeight, dummyImage.height)
|
||||||
bgWidth: 10
|
bgWidth: root.tiny ? 10 : 16
|
||||||
bgHeight: 10
|
bgHeight: root.tiny ? 10 : 16
|
||||||
bgColor: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
|
bgColor: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
|
||||||
// Only used to get implicit width and height from the actual image
|
// Only used to get implicit width and height from the actual image
|
||||||
property Image dummyImage: Image {
|
property Image dummyImage: Image {
|
||||||
|
@ -49,27 +52,34 @@ Row {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
visible: root.isContact || (root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None)
|
visible: root.isContact || (root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None)
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
id: hoverHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusToolTip {
|
||||||
|
text: {
|
||||||
|
if (root.isContact) {
|
||||||
|
if (root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified)
|
||||||
|
return qsTr("Verified contact")
|
||||||
|
if (root.trustIndicator === StatusContactVerificationIcons.TrustedType.Untrustworthy)
|
||||||
|
return qsTr("Untrustworthy contact")
|
||||||
|
return qsTr("Contact")
|
||||||
|
}
|
||||||
|
if (root.trustIndicator === StatusContactVerificationIcons.TrustedType.Untrustworthy)
|
||||||
|
return qsTr("Untrustworthy")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: hoverHandler.hovered && text
|
||||||
|
}
|
||||||
|
|
||||||
StatusRoundIcon {
|
StatusRoundIcon {
|
||||||
visible: root.isContact
|
visible: root.isContact && root.trustIndicator !== StatusContactVerificationIcons.TrustedType.Verified
|
||||||
asset.name: root.mutualConnectionIcon.name
|
asset: root.mutualConnectionIcon
|
||||||
asset.width: root.mutualConnectionIcon.width
|
|
||||||
asset.height: root.mutualConnectionIcon.height
|
|
||||||
asset.rotation: root.mutualConnectionIcon.rotation
|
|
||||||
asset.color: root.mutualConnectionIcon.color
|
|
||||||
asset.bgColor: root.mutualConnectionIcon.bgColor
|
|
||||||
asset.bgWidth: root.mutualConnectionIcon.bgWidth
|
|
||||||
asset.bgHeight: root.mutualConnectionIcon.bgHeight
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusRoundIcon {
|
StatusRoundIcon {
|
||||||
visible: root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None
|
visible: root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None
|
||||||
asset.name: root.trustContactIcon.name
|
asset: root.trustContactIcon
|
||||||
asset.width: root.trustContactIcon.width
|
|
||||||
asset.height: root.trustContactIcon.height
|
|
||||||
asset.rotation: root.trustContactIcon.rotation
|
|
||||||
asset.color: root.trustContactIcon.color
|
|
||||||
asset.bgColor: root.trustContactIcon.bgColor
|
|
||||||
asset.bgWidth: root.trustContactIcon.bgWidth
|
|
||||||
asset.bgHeight: root.trustContactIcon.bgHeight
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ Button {
|
||||||
|
|
||||||
icon.height: 24
|
icon.height: 24
|
||||||
icon.width: 24
|
icon.width: 24
|
||||||
|
icon.color: d.textColor
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
radius: root.radius
|
radius: root.radius
|
||||||
|
@ -90,7 +91,7 @@ Button {
|
||||||
rotation: root.asset.rotation
|
rotation: root.asset.rotation
|
||||||
opacity: !loading && root.icon.name !== ""
|
opacity: !loading && root.icon.name !== ""
|
||||||
visible: root.icon.name !== ""
|
visible: root.icon.name !== ""
|
||||||
color: d.textColor
|
color: root.icon.color
|
||||||
}
|
}
|
||||||
StatusEmoji {
|
StatusEmoji {
|
||||||
Layout.preferredWidth: visible ? root.icon.width : 0
|
Layout.preferredWidth: visible ? root.icon.width : 0
|
||||||
|
|
|
@ -14,7 +14,7 @@ Button {
|
||||||
property var type: StatusPickerButton.Type.Next
|
property var type: StatusPickerButton.Type.Next
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty StatusAssetSettings StatusPickerButton::image
|
\qmlproperty StatusAssetSettings StatusPickerButton::asset
|
||||||
This property holds the image settings information.
|
This property holds the image settings information.
|
||||||
*/
|
*/
|
||||||
property StatusAssetSettings asset: StatusAssetSettings {
|
property StatusAssetSettings asset: StatusAssetSettings {
|
||||||
|
|
|
@ -57,10 +57,14 @@ Item {
|
||||||
|
|
||||||
onCenteredChanged: flow.onPositioningComplete()
|
onCenteredChanged: flow.onPositioningComplete()
|
||||||
|
|
||||||
|
implicitHeight: flow.implicitHeight
|
||||||
|
|
||||||
Flow {
|
Flow {
|
||||||
id: flow
|
id: flow
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
onPositioningComplete: {
|
onPositioningComplete: {
|
||||||
if (!root.centered || children.length === 0)
|
if (!root.centered || children.length === 0)
|
||||||
|
|
|
@ -14,7 +14,7 @@ QtObject {
|
||||||
FontSizeXXL
|
FontSizeXXL
|
||||||
}
|
}
|
||||||
|
|
||||||
property QtObject palette: StatusLightTheme {}
|
property ThemePalette palette: StatusLightTheme {}
|
||||||
|
|
||||||
property int primaryTextFontSize: 15
|
property int primaryTextFontSize: 15
|
||||||
property int secondaryTextFontSize: 14
|
property int secondaryTextFontSize: 14
|
||||||
|
|
|
@ -10,6 +10,8 @@ import StatusQ.Core.Theme 0.1
|
||||||
Dialog {
|
Dialog {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property string subtitle
|
||||||
|
|
||||||
anchors.centerIn: Overlay.overlay
|
anchors.centerIn: Overlay.overlay
|
||||||
|
|
||||||
padding: 16
|
padding: 16
|
||||||
|
@ -25,8 +27,9 @@ Dialog {
|
||||||
background: StatusDialogBackground {}
|
background: StatusDialogBackground {}
|
||||||
|
|
||||||
header: StatusDialogHeader {
|
header: StatusDialogHeader {
|
||||||
visible: root.title
|
visible: root.title || root.subtitle
|
||||||
headline.title: root.title
|
headline.title: root.title
|
||||||
|
headline.subtitle: root.subtitle
|
||||||
actions.closeButton.onClicked: root.close()
|
actions.closeButton.onClicked: root.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ StatusModal {
|
||||||
validators: [
|
validators: [
|
||||||
StatusRegularExpressionValidator {
|
StatusRegularExpressionValidator {
|
||||||
regularExpression: /^#(?:[0-9a-fA-F]{3}){1,2}$/
|
regularExpression: /^#(?:[0-9a-fA-F]{3}){1,2}$/
|
||||||
errorMessage: qsTr("This is not a valid color")
|
errorMessage: qsTr("This is not a valid colour")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
validationMode: StatusInput.ValidationMode.Always
|
validationMode: StatusInput.ValidationMode.Always
|
||||||
|
@ -115,7 +115,7 @@ StatusModal {
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
text: qsTr("Standart colours")
|
text: qsTr("Standard colours")
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M16.624 8.41603C16.8538 8.07138 16.7607 7.60573 16.416 7.37596C16.0714 7.1462 15.6057 7.23933 15.376 7.58397L9.88343 15.8228L7.53033 13.4697C7.23744 13.1768 6.76256 13.1768 6.46967 13.4697C6.17678 13.7626 6.17678 14.2374 6.46967 14.5303L9.46967 17.5303C9.62855 17.6892 9.8503 17.7685 10.0739 17.7464C10.2975 17.7242 10.4994 17.603 10.624 17.416L16.624 8.41603Z" fill="black"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.5 12C20.5 16.6944 16.6944 20.5 12 20.5C7.30558 20.5 3.5 16.6944 3.5 12C3.5 7.30558 7.30558 3.5 12 3.5C16.6944 3.5 20.5 7.30558 20.5 12ZM22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM16.7728 10.1161C17.0657 9.82318 17.0657 9.34831 16.7728 9.05541C16.4799 8.76252 16.0051 8.76252 15.7122 9.05541L10.5856 14.1819L8.28754 11.8838C7.99465 11.5909 7.51977 11.5909 7.22688 11.8838C6.93398 12.1767 6.93399 12.6516 7.22688 12.9445L10.0553 15.7729C10.3482 16.0658 10.8231 16.0658 11.116 15.7729L16.7728 10.1161Z" fill="#0D1625"/>
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20.5C7.30558 20.5 3.5 16.6944 3.5 12C3.5 7.30558 7.30558 3.5 12 3.5C16.6944 3.5 20.5 7.30558 20.5 12C20.5 16.6944 16.6944 20.5 12 20.5Z" fill="black"/>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 807 B After Width: | Height: | Size: 743 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 2C7.30964 2 6.75 2.55964 6.75 3.25V7.75C6.75 8.44036 7.30964 9 8 9C8.69036 9 9.25 8.44036 9.25 7.75V3.25C9.25 2.55964 8.69036 2 8 2ZM8 13.5C8.69036 13.5 9.25 12.9404 9.25 12.25C9.25 11.5596 8.69036 11 8 11C7.30964 11 6.75 11.5596 6.75 12.25C6.75 12.9404 7.30964 13.5 8 13.5Z" fill="#0D1625"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 531 B After Width: | Height: | Size: 531 B |
|
@ -1,5 +1,3 @@
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M12 6.25C12.4142 6.25 12.75 6.58579 12.75 7V14C12.75 14.4142 12.4142 14.75 12 14.75C11.5858 14.75 11.25 14.4142 11.25 14V7C11.25 6.58579 11.5858 6.25 12 6.25Z" fill="black"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 3.75C7.44365 3.75 3.75 7.44365 3.75 12C3.75 16.5563 7.44365 20.25 12 20.25C16.5563 20.25 20.25 16.5563 20.25 12C20.25 7.44365 16.5563 3.75 12 3.75ZM2.25 12C2.25 6.61522 6.61522 2.25 12 2.25C17.3848 2.25 21.75 6.61522 21.75 12C21.75 17.3848 17.3848 21.75 12 21.75C6.61522 21.75 2.25 17.3848 2.25 12ZM12 6.25C12.4142 6.25 12.75 6.58579 12.75 7V13C12.75 13.4142 12.4142 13.75 12 13.75C11.5858 13.75 11.25 13.4142 11.25 13V7C11.25 6.58579 11.5858 6.25 12 6.25ZM13 17C13 17.5523 12.5523 18 12 18C11.4477 18 11 17.5523 11 17C11 16.4477 11.4477 16 12 16C12.5523 16 13 16.4477 13 17Z" fill="#0D1625"/>
|
||||||
<path d="M12 18.75C12.6904 18.75 13.25 18.1904 13.25 17.5C13.25 16.8096 12.6904 16.25 12 16.25C11.3096 16.25 10.75 16.8096 10.75 17.5C10.75 18.1904 11.3096 18.75 12 18.75Z" fill="black"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12ZM3.5 12C3.5 16.6944 7.30558 20.5 12 20.5C16.6944 20.5 20.5 16.6944 20.5 12C20.5 7.30558 16.6944 3.5 12 3.5C7.30558 3.5 3.5 7.30558 3.5 12Z" fill="black"/>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 791 B After Width: | Height: | Size: 750 B |
|
@ -37,9 +37,7 @@ ModalPopup {
|
||||||
Global.openProfilePopup(model.pubKey)
|
Global.openProfilePopup(model.pubKey)
|
||||||
}
|
}
|
||||||
onBlockContactActionTriggered: {
|
onBlockContactActionTriggered: {
|
||||||
blockContactConfirmationDialog.contactName = model.displayName
|
Global.blockContactRequested(model.pubKey, model.displayName)
|
||||||
blockContactConfirmationDialog.contactAddress = model.pubKey
|
|
||||||
blockContactConfirmationDialog.open()
|
|
||||||
}
|
}
|
||||||
onAcceptClicked: {
|
onAcceptClicked: {
|
||||||
popup.store.acceptContactRequest(model.pubKey)
|
popup.store.acceptContactRequest(model.pubKey)
|
||||||
|
@ -54,14 +52,6 @@ ModalPopup {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: children[0].height
|
height: children[0].height
|
||||||
|
|
||||||
BlockContactConfirmationDialog {
|
|
||||||
id: blockContactConfirmationDialog
|
|
||||||
onBlockButtonClicked: {
|
|
||||||
popup.store.blockContact(blockContactConfirmationDialog.contactAddress)
|
|
||||||
blockContactConfirmationDialog.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfirmationDialog {
|
ConfirmationDialog {
|
||||||
id: declineAllDialog
|
id: declineAllDialog
|
||||||
header.title: qsTr("Decline all contacts")
|
header.title: qsTr("Decline all contacts")
|
||||||
|
|
|
@ -23,7 +23,6 @@ StatusDialog {
|
||||||
|
|
||||||
signal updateGroupChatDetails(string groupName, string groupColor, string groupImage)
|
signal updateGroupChatDetails(string groupName, string groupColor, string groupImage)
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
title: qsTr("Edit group name and image")
|
title: qsTr("Edit group name and image")
|
||||||
width: 480
|
width: 480
|
||||||
height: 610
|
height: 610
|
||||||
|
@ -34,7 +33,7 @@ StatusDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
groupName.forceActiveFocus(Qt.MouseFocusReason)
|
groupName.input.edit.forceActiveFocus()
|
||||||
groupName.text = root.activeGroupName.substring(0, d.nameCharLimit)
|
groupName.text = root.activeGroupName.substring(0, d.nameCharLimit)
|
||||||
|
|
||||||
colorSelectionGrid.selectedColor = activeGroupColor
|
colorSelectionGrid.selectedColor = activeGroupColor
|
||||||
|
|
|
@ -81,7 +81,7 @@ StatusModal {
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
text: qsTr("%1 members").arg(nbMembers)
|
text: qsTr("%n member(s)", "", nbMembers)
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
|
|
|
@ -34,7 +34,7 @@ StatusModal {
|
||||||
root.channels = []
|
root.channels = []
|
||||||
root.store.prepareEditCategoryModel(categoryId);
|
root.store.prepareEditCategoryModel(categoryId);
|
||||||
}
|
}
|
||||||
root.contentItem.categoryName.input.forceActiveFocus(Qt.MouseFocusReason)
|
root.contentItem.categoryName.input.edit.forceActiveFocus()
|
||||||
}
|
}
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
|
|
||||||
|
@ -42,9 +42,7 @@ StatusModal {
|
||||||
return contentItem.categoryName.valid
|
return contentItem.categoryName.valid
|
||||||
}
|
}
|
||||||
|
|
||||||
header.title: isEdit ?
|
header.title: isEdit ? qsTr("Edit category") : qsTr("New category")
|
||||||
qsTr("Edit category") :
|
|
||||||
qsTr("New category")
|
|
||||||
|
|
||||||
contentItem: Column {
|
contentItem: Column {
|
||||||
property alias categoryName: nameInput
|
property alias categoryName: nameInput
|
||||||
|
@ -59,6 +57,7 @@ StatusModal {
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
|
||||||
input.edit.objectName: "createOrEditCommunityCategoryNameInput"
|
input.edit.objectName: "createOrEditCommunityCategoryNameInput"
|
||||||
|
input.clearable: true
|
||||||
label: qsTr("Category title")
|
label: qsTr("Category title")
|
||||||
charLimit: maxCategoryNameLength
|
charLimit: maxCategoryNameLength
|
||||||
placeholderText: qsTr("Name the category")
|
placeholderText: qsTr("Name the category")
|
||||||
|
@ -123,6 +122,8 @@ StatusModal {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
title: "#" + model.name
|
title: "#" + model.name
|
||||||
|
asset.width: 30
|
||||||
|
asset.height: 30
|
||||||
asset.emoji: model.emoji
|
asset.emoji: model.emoji
|
||||||
asset.color: model.color
|
asset.color: model.color
|
||||||
asset.imgIsIdenticon: false
|
asset.imgIsIdenticon: false
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.14
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
@ -172,7 +170,7 @@ QtObject {
|
||||||
|
|
||||||
function interpretMessage(msg) {
|
function interpretMessage(msg) {
|
||||||
if (msg.startsWith("/shrug")) {
|
if (msg.startsWith("/shrug")) {
|
||||||
return msg.replace("/shrug", "") + " ¯\\\\\\_(ツ)\\_/¯"
|
return msg.replace("/shrug", "") + " ¯\\\\\\_(ツ)\\_/¯"
|
||||||
}
|
}
|
||||||
if (msg.startsWith("/tableflip")) {
|
if (msg.startsWith("/tableflip")) {
|
||||||
return msg.replace("/tableflip", "") + " (╯°□°)╯︵ ┻━┻"
|
return msg.replace("/tableflip", "") + " (╯°□°)╯︵ ┻━┻"
|
||||||
|
|
|
@ -401,9 +401,9 @@ QtObject {
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
const pk = link.substring(index + 3)
|
const pk = link.substring(index + 3)
|
||||||
result.title = qsTr("Start a 1-on-1 chat with %1")
|
result.title = qsTr("Start a 1-on-1 chat with %1")
|
||||||
.arg(isChatKey(pk) ? globalUtils.generateAlias(pk) : ("@" + removeStatusEns(pk)))
|
.arg(Utils.isChatKey(pk) ? globalUtils.generateAlias(pk) : ("@" + Utils.removeStatusEns(pk)))
|
||||||
result.callback = function () {
|
result.callback = function () {
|
||||||
if (isChatKey(pk)) {
|
if (Utils.isChatKey(pk)) {
|
||||||
chatCommunitySectionModule.createOneToOneChat("", pk, "")
|
chatCommunitySectionModule.createOneToOneChat("", pk, "")
|
||||||
} else {
|
} else {
|
||||||
// Not Refactored Yet
|
// Not Refactored Yet
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
import QtQuick 2.3
|
import QtQml.Models 2.14
|
||||||
import QtQuick.Controls 2.3
|
|
||||||
import QtQuick.Controls 2.12 as QQC2
|
|
||||||
import QtQuick.Layouts 1.3
|
|
||||||
import Qt.labs.platform 1.1
|
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
ListElement {
|
ListElement {
|
||||||
|
@ -58,9 +54,3 @@ ListModel {
|
||||||
url: "QmY4QULmzFQ2AAbEuMvnd3Nd7qD8eWtyxiLD9CAf3kFZWU"
|
url: "QmY4QULmzFQ2AAbEuMvnd3Nd7qD8eWtyxiLD9CAf3kFZWU"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*##^##
|
|
||||||
Designer {
|
|
||||||
D{i:0;autoSize:true;height:480;width:640}
|
|
||||||
}
|
|
||||||
##^##*/
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import QtQuick 2.13
|
import QtQml.Models 2.14
|
||||||
import QtQuick.Controls 2.13
|
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
ListElement {
|
ListElement {
|
||||||
|
@ -24,9 +23,3 @@ ListModel {
|
||||||
thumbnail: "QmZdTTRiMvupRUWq6ctVbuPfEmc8Js53TmBKyjSYNHmGdi"
|
thumbnail: "QmZdTTRiMvupRUWq6ctVbuPfEmc8Js53TmBKyjSYNHmGdi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*##^##
|
|
||||||
Designer {
|
|
||||||
D{i:0;autoSize:true;height:480;width:640}
|
|
||||||
}
|
|
||||||
##^##*/
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpenProfileClicked: {
|
onOpenProfileClicked: {
|
||||||
Global.openProfilePopup(publicKey, null, state)
|
Global.openProfilePopup(publicKey, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
onDeleteMessage: {
|
onDeleteMessage: {
|
||||||
|
|
|
@ -185,9 +185,6 @@ StatusPopupMenu {
|
||||||
Global.openPopup(deleteChatConfirmationDialogComponent)
|
Global.openPopup(deleteChatConfirmationDialogComponent)
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
onClosed: {
|
|
||||||
destroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,26 +173,12 @@ StatusSectionLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmationDialog {
|
|
||||||
id: removeContactConfirmationDialog
|
|
||||||
header.title: qsTr("Remove contact")
|
|
||||||
confirmationText: qsTr("Are you sure you want to remove this contact?")
|
|
||||||
onConfirmButtonClicked: {
|
|
||||||
let pk = chatColumn.contactToRemove
|
|
||||||
if (Utils.getContactDetailsAsJson(pk).isAdded) {
|
|
||||||
root.contactsStore.removeContact(pk)
|
|
||||||
}
|
|
||||||
removeContactConfirmationDialog.parentPopup.close();
|
|
||||||
removeContactConfirmationDialog.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageContextMenuView {
|
MessageContextMenuView {
|
||||||
id: quickActionMessageOptionsMenu
|
id: quickActionMessageOptionsMenu
|
||||||
store: root.rootStore
|
store: root.rootStore
|
||||||
|
|
||||||
onOpenProfileClicked: {
|
onOpenProfileClicked: {
|
||||||
Global.openProfilePopup(publicKey, null, state)
|
Global.openProfilePopup(publicKey, null)
|
||||||
}
|
}
|
||||||
onCreateOneToOneChat: {
|
onCreateOneToOneChat: {
|
||||||
Global.changeAppSectionBySectionType(Constants.appSection.chat)
|
Global.changeAppSectionBySectionType(Constants.appSection.chat)
|
||||||
|
|
|
@ -14,7 +14,6 @@ StatusDialog {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
width: 480
|
width: 480
|
||||||
anchors.centerIn: parent
|
|
||||||
closePolicy: Popup.NoAutoClose
|
closePolicy: Popup.NoAutoClose
|
||||||
|
|
||||||
header: StatusDialogHeader {
|
header: StatusDialogHeader {
|
||||||
|
|
|
@ -38,10 +38,6 @@ StatusSectionLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
Global.privacyModuleInst = store.privacyStore.privacyModule
|
|
||||||
}
|
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
|
@ -106,6 +102,7 @@ StatusSectionLayout {
|
||||||
walletStore: root.store.walletStore
|
walletStore: root.store.walletStore
|
||||||
profileStore: root.store.profileStore
|
profileStore: root.store.profileStore
|
||||||
privacyStore: root.store.privacyStore
|
privacyStore: root.store.privacyStore
|
||||||
|
contactsStore: root.store.contactsStore
|
||||||
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.profile)
|
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.profile)
|
||||||
contentWidth: d.contentWidth
|
contentWidth: d.contentWidth
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ StatusListItem {
|
||||||
asset.letterSize: 14
|
asset.letterSize: 14
|
||||||
asset.isLetterIdenticon: !!account.emoji
|
asset.isLetterIdenticon: !!account.emoji
|
||||||
asset.bgColor: Theme.palette.primaryColor3
|
asset.bgColor: Theme.palette.primaryColor3
|
||||||
|
asset.width: 40
|
||||||
|
asset.height: 40
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
components: !showShevronIcon ? [] : [ shevronIcon ]
|
components: !showShevronIcon ? [] : [ shevronIcon ]
|
||||||
|
|
|
@ -70,7 +70,7 @@ StatusListItem {
|
||||||
asset.isImage: asset.name.includes("data")
|
asset.isImage: asset.name.includes("data")
|
||||||
asset.isLetterIdenticon: root.iconSource.toString() === ""
|
asset.isLetterIdenticon: root.iconSource.toString() === ""
|
||||||
ringSettings {
|
ringSettings {
|
||||||
ringSpecModel: Utils.getColorHashAsJson(root.publicKey)
|
ringSpecModel: d.ensVerified ? undefined : Utils.getColorHashAsJson(root.publicKey, true)
|
||||||
ringPxSize: Math.max(asset.width / 24.0)
|
ringPxSize: Math.max(asset.width / 24.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ QtObject {
|
||||||
|
|
||||||
property var profileSectionModuleInst: profileSectionModule
|
property var profileSectionModuleInst: profileSectionModule
|
||||||
|
|
||||||
property bool fetchingUpdate: aboutModule.fetching
|
readonly property bool fetchingUpdate: aboutModuleInst.fetching
|
||||||
|
|
||||||
property ContactsStore contactsStore: ContactsStore {
|
property ContactsStore contactsStore: ContactsStore {
|
||||||
contactsModule: profileSectionModuleInst.contactsModule
|
contactsModule: profileSectionModuleInst.contactsModule
|
||||||
|
|
|
@ -27,8 +27,6 @@ SettingsContentBase {
|
||||||
|
|
||||||
headerComponents: [
|
headerComponents: [
|
||||||
StatusButton {
|
StatusButton {
|
||||||
implicitHeight: 38
|
|
||||||
size: StatusBaseButton.Size.Normal
|
|
||||||
text: qsTr("Send contact request to chat key")
|
text: qsTr("Send contact request to chat key")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
sendContactRequest.open()
|
sendContactRequest.open()
|
||||||
|
@ -54,8 +52,8 @@ SettingsContentBase {
|
||||||
store: ({contactsStore: root.contactsStore})
|
store: ({contactsStore: root.contactsStore})
|
||||||
isProfile: true
|
isProfile: true
|
||||||
|
|
||||||
onOpenProfileClicked: function (pubkey, state) {
|
onOpenProfileClicked: function (pubkey) {
|
||||||
Global.openProfilePopup(pubkey, null, state)
|
Global.openProfilePopup(pubkey, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
onCreateOneToOneChat: function (communityId, chatId, ensName) {
|
onCreateOneToOneChat: function (communityId, chatId, ensName) {
|
||||||
|
@ -196,6 +194,10 @@ SettingsContentBase {
|
||||||
contactsModel: root.contactsStore.receivedContactRequestsModel
|
contactsModel: root.contactsStore.receivedContactRequestsModel
|
||||||
panelUsage: Constants.contactsPanelUsage.receivedContactRequest
|
panelUsage: Constants.contactsPanelUsage.receivedContactRequest
|
||||||
|
|
||||||
|
onSendMessageActionTriggered: {
|
||||||
|
root.contactsStore.joinPrivateChat(publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
onContactRequestAccepted: {
|
onContactRequestAccepted: {
|
||||||
root.contactsStore.acceptContactRequest(publicKey)
|
root.contactsStore.acceptContactRequest(publicKey)
|
||||||
}
|
}
|
||||||
|
@ -205,20 +207,7 @@ SettingsContentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
onShowVerificationRequest: {
|
onShowVerificationRequest: {
|
||||||
try {
|
Global.openIncomingIDRequestPopup(publicKey)
|
||||||
let request = root.contactsStore.getVerificationDetailsFromAsJson(publicKey)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,41 +300,6 @@ SettingsContentBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make BlockContactConfirmationDialog a dynamic component on a future refactor
|
|
||||||
BlockContactConfirmationDialog {
|
|
||||||
id: blockContactConfirmationDialog
|
|
||||||
onBlockButtonClicked: {
|
|
||||||
root.contactsStore.blockContact(blockContactConfirmationDialog.contactAddress)
|
|
||||||
blockContactConfirmationDialog.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: Make ConfirmationDialog a dynamic component on a future refactor
|
|
||||||
ConfirmationDialog {
|
|
||||||
id: removeContactConfirmationDialog
|
|
||||||
header.title: qsTr("Remove contact")
|
|
||||||
confirmationText: qsTr("Are you sure you want to remove this contact?")
|
|
||||||
onConfirmButtonClicked: {
|
|
||||||
if (Utils.getContactDetailsAsJson(removeContactConfirmationDialog.value).isAdded) {
|
|
||||||
root.contactsStore.removeContact(removeContactConfirmationDialog.value);
|
|
||||||
}
|
|
||||||
removeContactConfirmationDialog.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: contactVerificationRequestPopupComponent
|
|
||||||
ContactVerificationRequestPopup {
|
|
||||||
onResponseSent: {
|
|
||||||
root.contactsStore.acceptVerificationRequest(senderPublicKey, response)
|
|
||||||
}
|
|
||||||
onVerificationRefused: {
|
|
||||||
root.contactsStore.declineVerificationRequest(senderPublicKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: sendContactRequest
|
id: sendContactRequest
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
|
@ -64,7 +64,7 @@ Item {
|
||||||
gasPrice,
|
gasPrice,
|
||||||
tipLimit,
|
tipLimit,
|
||||||
overallLimit,
|
overallLimit,
|
||||||
password,
|
password,
|
||||||
eip1559Enabled,
|
eip1559Enabled,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,7 @@ SettingsContentBase {
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Global
|
target: Global
|
||||||
onSettingsLoaded: {
|
function onSettingsLoaded() {
|
||||||
generalColumn.populatePreviewableSites()
|
generalColumn.populatePreviewableSites()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ SettingsContentBase {
|
||||||
property WalletStore walletStore
|
property WalletStore walletStore
|
||||||
property ProfileStore profileStore
|
property ProfileStore profileStore
|
||||||
property PrivacyStore privacyStore
|
property PrivacyStore privacyStore
|
||||||
|
property ContactsStore contactsStore
|
||||||
|
|
||||||
titleRowComponentLoader.sourceComponent: StatusButton {
|
titleRowComponentLoader.sourceComponent: StatusButton {
|
||||||
objectName: "profileSettingsChangePasswordButton"
|
objectName: "profileSettingsChangePasswordButton"
|
||||||
|
@ -35,8 +36,14 @@ SettingsContentBase {
|
||||||
dirty: settingsView.dirty
|
dirty: settingsView.dirty
|
||||||
saveChangesButtonEnabled: settingsView.valid
|
saveChangesButtonEnabled: settingsView.valid
|
||||||
|
|
||||||
onResetChangesClicked: settingsView.reset()
|
onResetChangesClicked: {
|
||||||
onSaveChangesClicked: settingsView.save()
|
settingsView.reset()
|
||||||
|
profilePreview.reload()
|
||||||
|
}
|
||||||
|
onSaveChangesClicked: {
|
||||||
|
settingsView.save()
|
||||||
|
profilePreview.reload()
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: layout
|
id: layout
|
||||||
|
@ -73,6 +80,7 @@ SettingsContentBase {
|
||||||
id: profilePreview
|
id: profilePreview
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
profileStore: root.profileStore
|
profileStore: root.profileStore
|
||||||
|
contactsStore: root.contactsStore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ SettingsContentBase {
|
||||||
StatusListItem {
|
StatusListItem {
|
||||||
property string lowerCaseSearchString: searchBox.text.toLowerCase()
|
property string lowerCaseSearchString: searchBox.text.toLowerCase()
|
||||||
|
|
||||||
width: parent.width
|
width: ListView.view.width
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
visible: lowerCaseSearchString === "" ||
|
visible: lowerCaseSearchString === "" ||
|
||||||
model.itemId.toLowerCase().includes(lowerCaseSearchString) ||
|
model.itemId.toLowerCase().includes(lowerCaseSearchString) ||
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.14
|
||||||
import QtGraphicalEffects 1.14
|
import QtGraphicalEffects 1.14
|
||||||
|
|
||||||
import shared.views 1.0 as SharedViews
|
import shared.views 1.0 as SharedViews
|
||||||
|
@ -7,6 +7,7 @@ import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property alias profileStore: profilePreview.profileStore
|
property alias profileStore: profilePreview.profileStore
|
||||||
|
property alias contactsStore: profilePreview.contactsStore
|
||||||
|
|
||||||
implicitHeight: profilePreview.implicitHeight
|
implicitHeight: profilePreview.implicitHeight
|
||||||
+ profilePreview.anchors.topMargin
|
+ profilePreview.anchors.topMargin
|
||||||
|
@ -16,10 +17,15 @@ Item {
|
||||||
+ profilePreview.anchors.leftMargin
|
+ profilePreview.anchors.leftMargin
|
||||||
+ profilePreview.anchors.rightMargin
|
+ profilePreview.anchors.rightMargin
|
||||||
|
|
||||||
SharedViews.ProfileView {
|
function reload() {
|
||||||
|
profilePreview.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedViews.ProfileDialogView {
|
||||||
id: profilePreview
|
id: profilePreview
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 24
|
anchors.margins: 24
|
||||||
|
readOnly: true
|
||||||
}
|
}
|
||||||
|
|
||||||
DropShadow {
|
DropShadow {
|
||||||
|
@ -32,4 +38,4 @@ Item {
|
||||||
color: "#40000000"
|
color: "#40000000"
|
||||||
source: profilePreview
|
source: profilePreview
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,6 @@ ColumnLayout {
|
||||||
visible: communitiesRepeater.count == 0
|
visible: communitiesRepeater.count == 0
|
||||||
width: parent.width
|
width: parent.width
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font.pixelSize: 15
|
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
text: qsTr("You haven't joined any communities yet")
|
text: qsTr("You haven't joined any communities yet")
|
||||||
}
|
}
|
||||||
|
@ -204,7 +203,6 @@ ColumnLayout {
|
||||||
visible: accountsRepeater.count == 0
|
visible: accountsRepeater.count == 0
|
||||||
width: parent.width
|
width: parent.width
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font.pixelSize: 15
|
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
text: qsTr("You don't have any wallet accounts yet")
|
text: qsTr("You don't have any wallet accounts yet")
|
||||||
}
|
}
|
||||||
|
@ -233,5 +231,4 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
|
||||||
WalletHeader {
|
WalletHeader {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
locale: RootStore.locale
|
locale: RootStore.locale
|
||||||
|
|
|
@ -84,13 +84,19 @@ Item {
|
||||||
})
|
})
|
||||||
return downloadPage
|
return downloadPage
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpenProfilePopupRequested: {
|
onOpenProfilePopupRequested: {
|
||||||
var popup = profilePopupComponent.createObject(appMain);
|
Global.openPopup(profilePopupComponent, {publicKey: publicKey, parentPopup: parentPopup})
|
||||||
if (parentPopup) {
|
Global.profilePopupOpened = true
|
||||||
popup.parentPopup = parentPopup;
|
}
|
||||||
}
|
onOpenNicknamePopupRequested: {
|
||||||
popup.openPopup(publicKey, state);
|
Global.openPopup(nicknamePopupComponent, {publicKey: publicKey, nickname: nickname, "header.subTitle": subtitle})
|
||||||
Global.profilePopupOpened = true;
|
}
|
||||||
|
onBlockContactRequested: {
|
||||||
|
Global.openPopup(blockContactConfirmationComponent, {contactName: contactName, contactAddress: publicKey})
|
||||||
|
}
|
||||||
|
onUnblockContactRequested: {
|
||||||
|
Global.openPopup(unblockContactConfirmationComponent, {contactName: contactName, contactAddress: publicKey})
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpenActivityCenterPopupRequested: {
|
onOpenActivityCenterPopupRequested: {
|
||||||
|
@ -106,28 +112,30 @@ Item {
|
||||||
onDisplayToastMessage: {
|
onDisplayToastMessage: {
|
||||||
appMain.rootStore.mainModuleInst.displayEphemeralNotification(title, subTitle, icon, loading, ephNotifType, url);
|
appMain.rootStore.mainModuleInst.displayEphemeralNotification(title, subTitle, icon, loading, ephNotifType, url);
|
||||||
}
|
}
|
||||||
onOpenEditDisplayNamePopup: {
|
onOpenEditDisplayNamePopup: Global.openPopup(displayNamePopupComponent)
|
||||||
var popup = displayNamePopupComponent.createObject(appMain)
|
|
||||||
popup.open()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeAppSectionBySectionId(sectionId) {
|
function changeAppSectionBySectionId(sectionId) {
|
||||||
mainModule.setActiveSectionById(sectionId)
|
mainModule.setActiveSectionById(sectionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
property Component backupSeedModalComponent: BackupSeedModal {
|
Component {
|
||||||
id: backupSeedModal
|
id: backupSeedModalComponent
|
||||||
anchors.centerIn: parent
|
BackupSeedModal {
|
||||||
privacyStore: appMain.rootStore.profileSectionStore.privacyStore
|
anchors.centerIn: parent
|
||||||
onClosed: destroy()
|
privacyStore: appMain.rootStore.profileSectionStore.privacyStore
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property Component displayNamePopupComponent: DisplayNamePopup {
|
Component {
|
||||||
anchors.centerIn: parent
|
id: displayNamePopupComponent
|
||||||
profileStore: appMain.rootStore.profileSectionStore.profileStore
|
DisplayNamePopup {
|
||||||
onClosed: {
|
anchors.centerIn: parent
|
||||||
destroy()
|
profileStore: appMain.rootStore.profileSectionStore.profileStore
|
||||||
|
onClosed: {
|
||||||
|
destroy()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,21 +172,24 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property Component profilePopupComponent: ProfilePopup {
|
Component {
|
||||||
id: profilePopup
|
id: profilePopupComponent
|
||||||
anchors.centerIn: parent
|
ProfileDialog {
|
||||||
profileStore: appMain.rootStore.profileSectionStore.profileStore
|
id: profilePopup
|
||||||
contactsStore: appMain.rootStore.profileSectionStore.contactsStore
|
profileStore: appMain.rootStore.profileSectionStore.profileStore
|
||||||
onClosed: {
|
contactsStore: appMain.rootStore.profileSectionStore.contactsStore
|
||||||
if (profilePopup.parentPopup) {
|
onClosed: {
|
||||||
profilePopup.parentPopup.close();
|
if (profilePopup.parentPopup) {
|
||||||
|
profilePopup.parentPopup.close()
|
||||||
|
}
|
||||||
|
Global.profilePopupOpened = false
|
||||||
|
destroy()
|
||||||
}
|
}
|
||||||
Global.profilePopupOpened = false;
|
|
||||||
destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property Component changeProfilePicComponent: Component {
|
Component {
|
||||||
|
id: changeProfilePicComponent
|
||||||
ImageCropWorkflow {
|
ImageCropWorkflow {
|
||||||
title: qsTr("Profile Picture")
|
title: qsTr("Profile Picture")
|
||||||
acceptButtonText: qsTr("Make this my Profile Pic")
|
acceptButtonText: qsTr("Make this my Profile Pic")
|
||||||
|
@ -636,7 +647,6 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
@ -711,8 +721,6 @@ Item {
|
||||||
|
|
||||||
ChatLayout {
|
ChatLayout {
|
||||||
id: chatLayoutContainer
|
id: chatLayoutContainer
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
chatView.emojiPopup: statusEmojiPopup
|
chatView.emojiPopup: statusEmojiPopup
|
||||||
|
|
||||||
|
@ -955,6 +963,44 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: nicknamePopupComponent
|
||||||
|
NicknamePopup {
|
||||||
|
onEditDone: {
|
||||||
|
if (nickname !== newNickname) {
|
||||||
|
appMain.rootStore.contactStore.changeContactNickname(publicKey, newNickname)
|
||||||
|
Global.nickNameChanged(publicKey, newNickname)
|
||||||
|
}
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: unblockContactConfirmationComponent
|
||||||
|
UnblockContactConfirmationDialog {
|
||||||
|
onUnblockButtonClicked: {
|
||||||
|
appMain.rootStore.contactStore.unblockContact(contactAddress)
|
||||||
|
Global.contactUnblocked(contactAddress)
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: blockContactConfirmationComponent
|
||||||
|
BlockContactConfirmationDialog {
|
||||||
|
onBlockButtonClicked: {
|
||||||
|
appMain.rootStore.contactStore.blockContact(contactAddress)
|
||||||
|
Global.contactBlocked(contactAddress)
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add SendModal here as it is used by the Wallet as well as the Browser
|
// Add SendModal here as it is used by the Wallet as well as the Browser
|
||||||
Loader {
|
Loader {
|
||||||
id: sendModal
|
id: sendModal
|
||||||
|
@ -1183,8 +1229,8 @@ Item {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Could not parse the whitelist for sites', e)
|
console.error('Could not parse the whitelist for sites', e)
|
||||||
}
|
}
|
||||||
|
Global.privacyModuleInst = appMain.rootStore.profileSectionStore.privacyStore.privacyModule
|
||||||
Global.settingsHasLoaded();
|
Global.settingsHasLoaded();
|
||||||
Global.errorSound = errorSound;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
|
|
@ -44,6 +44,7 @@ Item {
|
||||||
|
|
||||||
onItemClicked: {
|
onItemClicked: {
|
||||||
appSearch.store.setSearchLocation(firstLevelItemValue, secondLevelItemValue)
|
appSearch.store.setSearchLocation(firstLevelItemValue, secondLevelItemValue)
|
||||||
|
searchPopup.forceActiveFocus()
|
||||||
if(searchPopup.searchText !== "")
|
if(searchPopup.searchText !== "")
|
||||||
searchMessages(searchPopup.searchText)
|
searchMessages(searchPopup.searchText)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ Item {
|
||||||
property string ensAsyncValidationError: qsTr("ENS Username not found")
|
property string ensAsyncValidationError: qsTr("ENS Username not found")
|
||||||
property alias input: contactFieldAndList.chatKey
|
property alias input: contactFieldAndList.chatKey
|
||||||
property string selectedAddress
|
property string selectedAddress
|
||||||
property var isValid: false
|
property bool isValid: false
|
||||||
property alias isPending: contactFieldAndList.loading
|
property alias isPending: contactFieldAndList.loading
|
||||||
property bool isResolvedAddress: false
|
property bool isResolvedAddress: false
|
||||||
property int parentWidth
|
property int parentWidth
|
||||||
|
|
|
@ -2,8 +2,6 @@ import QtQuick 2.13
|
||||||
|
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Controls 0.1
|
||||||
|
|
||||||
import shared.stores 1.0
|
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
StatusRoundButton {
|
StatusRoundButton {
|
||||||
|
@ -32,16 +30,6 @@ StatusRoundButton {
|
||||||
id: toolTip
|
id: toolTip
|
||||||
text: qsTr("Copied!")
|
text: qsTr("Copied!")
|
||||||
orientation: tooltipUnder ? StatusToolTip.Orientation.Bottom: StatusToolTip.Orientation.Top
|
orientation: tooltipUnder ? StatusToolTip.Orientation.Bottom: StatusToolTip.Orientation.Top
|
||||||
}
|
timeout: 2000
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: hideTimer
|
|
||||||
interval: 2000
|
|
||||||
running: toolTip.visible
|
|
||||||
onTriggered: {
|
|
||||||
toolTip.visible = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,12 @@ import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||||
import StatusQ.Components 0.1
|
import StatusQ.Components 0.1
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import shared.panels 1.0
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool compact: false
|
property bool compact: false
|
||||||
|
property bool oneRow
|
||||||
property string publicKey
|
property string publicKey
|
||||||
|
|
||||||
readonly property real size: compact ? 10 : 15
|
readonly property real size: compact ? 10 : 15
|
||||||
|
@ -20,8 +20,8 @@ Item {
|
||||||
Grid {
|
Grid {
|
||||||
id: positioner
|
id: positioner
|
||||||
|
|
||||||
rows: 2
|
rows: root.oneRow ? 1 : 2
|
||||||
columnSpacing: 0.2
|
columnSpacing: root.oneRow ? 4 : 2
|
||||||
rowSpacing: root.compact ? 4 : 6
|
rowSpacing: root.compact ? 4 : 6
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
|
@ -140,24 +140,11 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
StatusContactVerificationIcons {
|
||||||
sourceComponent: SVGImage {
|
Layout.alignment: Qt.AlignVCenter
|
||||||
height: compact ? 10 : 16
|
visible: !root.isCurrentUser
|
||||||
width: compact ? 10 : 16
|
isContact: root.isContact
|
||||||
source: Style.svg("contact")
|
trustIndicator: root.trustStatus
|
||||||
}
|
|
||||||
active: isContact && !root.isCurrentUser
|
|
||||||
visible: active
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
sourceComponent: VerificationLabel {
|
|
||||||
trustStatus: root.trustStatus
|
|
||||||
height: compact ? 10 : 16
|
|
||||||
width: compact ? 10 : 16
|
|
||||||
}
|
|
||||||
active: root.trustStatus !== Constants.trustStatus.unknown && !root.isCurrentUser
|
|
||||||
visible: active
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
|
|
@ -5,6 +5,6 @@ import StatusQ.Popups 0.1
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
property bool muted: false
|
property bool muted: false
|
||||||
|
|
||||||
text: !muted ? qsTr("Mute chat") : qsTr("Unmute chat")
|
text: muted ? qsTr("Unmute Chat") : qsTr("Mute Chat")
|
||||||
icon.name: "notification"
|
icon.name: "notification"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,6 @@ import QtQuick 2.14
|
||||||
import StatusQ.Popups 0.1
|
import StatusQ.Popups 0.1
|
||||||
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
text: qsTr("Send message")
|
text: qsTr("Send Message")
|
||||||
icon.name: "chat"
|
icon.name: "chat"
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,26 +10,16 @@ import shared.controls.chat.menuItems 1.0
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: root
|
id: root
|
||||||
|
height: declineBtn.height
|
||||||
|
spacing: Style.current.halfPadding
|
||||||
|
|
||||||
|
property alias menuButton: menuButton
|
||||||
|
|
||||||
signal acceptClicked()
|
signal acceptClicked()
|
||||||
signal declineClicked()
|
signal declineClicked()
|
||||||
signal blockClicked()
|
signal blockClicked()
|
||||||
signal profileClicked()
|
signal profileClicked()
|
||||||
|
|
||||||
height: acceptBtn.height
|
|
||||||
spacing: Style.current.halfPadding
|
|
||||||
|
|
||||||
StatusFlatRoundButton {
|
|
||||||
id: acceptBtn
|
|
||||||
width: 32
|
|
||||||
height: 32
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
icon.name: "checkmark-circle"
|
|
||||||
icon.color: Style.current.success
|
|
||||||
backgroundHoverColor: Utils.setColorAlpha(Style.current.success, 0.1)
|
|
||||||
onClicked: root.acceptClicked()
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusFlatRoundButton {
|
StatusFlatRoundButton {
|
||||||
id: declineBtn
|
id: declineBtn
|
||||||
width: 32
|
width: 32
|
||||||
|
@ -41,6 +31,16 @@ Row {
|
||||||
onClicked: root.declineClicked()
|
onClicked: root.declineClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusFlatRoundButton {
|
||||||
|
id: acceptBtn
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
icon.name: "checkmark-circle"
|
||||||
|
icon.color: Style.current.success
|
||||||
|
backgroundHoverColor: Utils.setColorAlpha(Style.current.success, 0.1)
|
||||||
|
onClicked: root.acceptClicked()
|
||||||
|
}
|
||||||
|
|
||||||
StatusFlatRoundButton {
|
StatusFlatRoundButton {
|
||||||
id: menuButton
|
id: menuButton
|
||||||
|
|
|
@ -55,7 +55,7 @@ Rectangle {
|
||||||
Connections {
|
Connections {
|
||||||
enabled: !!mainModule
|
enabled: !!mainModule
|
||||||
target: enabled ? mainModule : undefined
|
target: enabled ? mainModule : undefined
|
||||||
onOnlineStatusChanged: {
|
function onOnlineStatusChanged(connected) {
|
||||||
if (connected && root.state !== "ready" &&
|
if (connected && root.state !== "ready" &&
|
||||||
root.visible &&
|
root.visible &&
|
||||||
root.source &&
|
root.source &&
|
||||||
|
|
|
@ -8,9 +8,6 @@ import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
@ -29,7 +26,7 @@ Item {
|
||||||
signal clicked()
|
signal clicked()
|
||||||
signal closeClicked()
|
signal closeClicked()
|
||||||
signal showStarted()
|
signal showStarted()
|
||||||
signal showFinihsed()
|
signal showFinished()
|
||||||
signal hideStarted()
|
signal hideStarted()
|
||||||
signal hideFinished()
|
signal hideFinished()
|
||||||
|
|
||||||
|
@ -73,7 +70,7 @@ Item {
|
||||||
root.showStarted()
|
root.showStarted()
|
||||||
}
|
}
|
||||||
onFinished: {
|
onFinished: {
|
||||||
root.showFinihsed()
|
root.showFinished()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +131,6 @@ Item {
|
||||||
text: root.text
|
text: root.text
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
color: Theme.palette.indirectColor1
|
color: Theme.palette.indirectColor1
|
||||||
linkColor: color
|
linkColor: color
|
||||||
onLinkActivated: root.linkActivated(link)
|
onLinkActivated: root.linkActivated(link)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.14
|
||||||
import QtQml.Models 2.14
|
import QtQml.Models 2.14
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ import "../controls"
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
Item {
|
Control {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string bio
|
property string bio
|
||||||
|
@ -18,9 +19,6 @@ Item {
|
||||||
|
|
||||||
onUserSocialLinksJsonChanged: d.buildSocialLinksModel()
|
onUserSocialLinksJsonChanged: d.buildSocialLinksModel()
|
||||||
|
|
||||||
implicitWidth: layout.implicitWidth
|
|
||||||
implicitHeight: layout.implicitHeight
|
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
|
@ -83,11 +81,7 @@ Item {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
id: layout
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
spacing: 20
|
spacing: 20
|
||||||
|
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
|
@ -95,15 +89,15 @@ Item {
|
||||||
visible: text !== ""
|
visible: text !== ""
|
||||||
text: root.bio
|
text: root.bio
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
font.weight: Font.Medium
|
||||||
|
lineHeight: 1.2
|
||||||
}
|
}
|
||||||
|
|
||||||
Flow {
|
StatusCenteredFlow {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.leftMargin: 10
|
|
||||||
Layout.rightMargin: 10
|
|
||||||
|
|
||||||
spacing: 16
|
spacing: Style.current.halfPadding
|
||||||
visible: repeater.count > 0
|
visible: repeater.count > 0
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
|
@ -10,10 +10,10 @@ Item {
|
||||||
height: root.visible ? implicitHeight : 0
|
height: root.visible ? implicitHeight : 0
|
||||||
anchors.topMargin: Style.current.padding
|
anchors.topMargin: Style.current.padding
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: separator
|
id: separator
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 1
|
height: 1
|
||||||
color: root.color
|
color: root.color
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ ModalPopup {
|
||||||
height: 237
|
height: 237
|
||||||
width: 400
|
width: 400
|
||||||
|
|
||||||
property Popup parentPopup
|
|
||||||
property string contactAddress: ""
|
property string contactAddress: ""
|
||||||
property string contactName: ""
|
property string contactName: ""
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
import QtQuick.Dialogs 1.3
|
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
|
@ -37,9 +36,6 @@ StatusModal {
|
||||||
onOpened: {
|
onOpened: {
|
||||||
verificationResponse.input.edit.forceActiveFocus(Qt.MouseFocusReason)
|
verificationResponse.input.edit.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
}
|
}
|
||||||
onClosed: {
|
|
||||||
root.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
@ -69,6 +65,7 @@ StatusModal {
|
||||||
messageTimestamp: root.messageTimestamp
|
messageTimestamp: root.messageTimestamp
|
||||||
senderId: root.senderPublicKey
|
senderId: root.senderPublicKey
|
||||||
senderDisplayName: root.senderDisplayName
|
senderDisplayName: root.senderDisplayName
|
||||||
|
senderIsEnsVerified: Utils.isEnsVerified(root.senderPublicKey)
|
||||||
senderIcon: root.senderIcon
|
senderIcon: root.senderIcon
|
||||||
messageText: root.challengeText
|
messageText: root.challengeText
|
||||||
messageContentType: Constants.messageContentType.messageType
|
messageContentType: Constants.messageContentType.messageType
|
||||||
|
@ -100,7 +97,8 @@ StatusModal {
|
||||||
shouldRepeatHeader: true
|
shouldRepeatHeader: true
|
||||||
messageTimestamp: root.responseTimestamp
|
messageTimestamp: root.responseTimestamp
|
||||||
senderId: userProfile.pubKey
|
senderId: userProfile.pubKey
|
||||||
senderDisplayName: userProfile.name
|
senderDisplayName: userProfile.displayName
|
||||||
|
senderIsEnsVerified: !!userProfile.ensName
|
||||||
senderIcon: userProfile.icon
|
senderIcon: userProfile.icon
|
||||||
messageText: root.responseText
|
messageText: root.responseText
|
||||||
messageContentType: Constants.messageContentType.messageType
|
messageContentType: Constants.messageContentType.messageType
|
||||||
|
@ -115,9 +113,9 @@ StatusModal {
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
anchors.top: responseMessage.bottom
|
anchors.top: responseMessage.bottom
|
||||||
anchors.topMargin: 58
|
anchors.topMargin: 58
|
||||||
text: qsTr("You're answer has been sent to %1.").arg(root.senderDisplayName)
|
text: qsTr("Your answer has been sent to %1.").arg(root.senderDisplayName)
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,6 @@ StatusModal {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
onOpened: { displayNameInput.input.forceActiveFocus(Qt.MouseFocusReason) }
|
onOpened: { displayNameInput.input.edit.forceActiveFocus() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,15 +18,18 @@ StatusModal {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
header.title: qsTr("Nickname")
|
header.title: qsTr("Nickname")
|
||||||
|
header.subTitleElide: Text.ElideMiddle
|
||||||
|
|
||||||
|
/*required*/ property string publicKey
|
||||||
|
property string nickname
|
||||||
|
|
||||||
property alias nickname: nicknameInput.text
|
|
||||||
readonly property int nicknameLength: nicknameInput.text.length
|
readonly property int nicknameLength: nicknameInput.text.length
|
||||||
readonly property int maxNicknameLength: 32
|
readonly property int maxNicknameLength: 32
|
||||||
|
|
||||||
signal editDone(string newNickname)
|
signal editDone(string newNickname)
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
nicknameInput.forceActiveFocus(Qt.MouseFocusReason);
|
nicknameInput.input.edit.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
|
@ -51,9 +54,9 @@ StatusModal {
|
||||||
StatusInput {
|
StatusInput {
|
||||||
id: nicknameInput
|
id: nicknameInput
|
||||||
placeholderText: qsTr("Nickname")
|
placeholderText: qsTr("Nickname")
|
||||||
|
input.clearable: true
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
text: popup.nickname
|
||||||
charLimit: maxNicknameLength
|
charLimit: maxNicknameLength
|
||||||
validationMode: StatusInput.ValidationMode.IgnoreInvalidInput
|
validationMode: StatusInput.ValidationMode.IgnoreInvalidInput
|
||||||
validators: [
|
validators: [
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
|
import QtQml.Models 2.14
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Popups.Dialog 0.1
|
||||||
|
|
||||||
|
import shared.views.chat 1.0
|
||||||
|
|
||||||
|
StatusDialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
/* required*/ property string userPublicKey
|
||||||
|
property int verificationStatus
|
||||||
|
property string verificationChallenge
|
||||||
|
property string verificationResponse
|
||||||
|
property string verificationResponseDisplayName
|
||||||
|
property string verificationResponseIcon
|
||||||
|
property string verificationRequestedAt
|
||||||
|
property string verificationRepliedAt
|
||||||
|
|
||||||
|
signal verificationRequestCanceled(string userPublicKey)
|
||||||
|
signal untrustworthyVerified(string userPublicKey)
|
||||||
|
signal trustedVerified(string userPublicKey)
|
||||||
|
|
||||||
|
title: qsTr("Verify %1's Identity").arg(root.verificationResponseDisplayName)
|
||||||
|
|
||||||
|
footer: StatusDialogFooter {
|
||||||
|
leftButtons: ObjectModel {
|
||||||
|
StatusButton {
|
||||||
|
text: qsTr("Cancel verification")
|
||||||
|
type: StatusBaseButton.Type.Danger
|
||||||
|
visible: root.verificationStatus !== Constants.verificationStatus.verified
|
||||||
|
onClicked: {
|
||||||
|
root.verificationRequestCanceled(root.userPublicKey)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rightButtons: ObjectModel {
|
||||||
|
StatusButton {
|
||||||
|
text: qsTr("Mark Untrustworthy")
|
||||||
|
enabled: root.verificationResponse !== ""
|
||||||
|
type: StatusBaseButton.Type.Danger
|
||||||
|
onClicked: {
|
||||||
|
root.untrustworthyVerified(root.userPublicKey)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusButton {
|
||||||
|
text: qsTr("Confirm Identity")
|
||||||
|
enabled: root.verificationResponse !== ""
|
||||||
|
type: StatusBaseButton.Type.Primary
|
||||||
|
onClicked: {
|
||||||
|
root.trustedVerified(root.userPublicKey)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
MessageView {
|
||||||
|
id: challengeMessage
|
||||||
|
Layout.fillWidth: true
|
||||||
|
isMessage: true
|
||||||
|
shouldRepeatHeader: true
|
||||||
|
messageTimestamp: root.verificationRequestedAt
|
||||||
|
senderId: userProfile.pubKey
|
||||||
|
senderDisplayName: userProfile.name
|
||||||
|
senderIcon: userProfile.icon
|
||||||
|
senderIsEnsVerified: !!userProfile.ensName
|
||||||
|
messageText: root.verificationChallenge
|
||||||
|
messageContentType: Constants.messageContentType.messageType
|
||||||
|
placeholderMessage: true
|
||||||
|
}
|
||||||
|
MessageView {
|
||||||
|
id: responseMessage
|
||||||
|
visible: root.verificationResponse !== ""
|
||||||
|
Layout.fillWidth: true
|
||||||
|
isMessage: true
|
||||||
|
shouldRepeatHeader: true
|
||||||
|
messageTimestamp: root.verificationRepliedAt
|
||||||
|
senderId: root.userPublicKey
|
||||||
|
senderDisplayName: root.verificationResponseDisplayName
|
||||||
|
senderIcon: root.verificationResponseIcon
|
||||||
|
senderIsEnsVerified: Utils.isEnsVerified(root.userPublicKey)
|
||||||
|
messageText: root.verificationResponse
|
||||||
|
messageContentType: Constants.messageContentType.messageType
|
||||||
|
placeholderMessage: true
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
id: waitingForText
|
||||||
|
visible: !root.verificationResponse
|
||||||
|
text: qsTr("Waiting for %1's response...").arg(root.verificationResponseDisplayName)
|
||||||
|
font.pixelSize: Style.current.additionalTextSize
|
||||||
|
horizontalAlignment : Text.AlignHCenter
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import QtQuick 2.14
|
||||||
|
|
||||||
|
import StatusQ.Popups.Dialog 0.1
|
||||||
|
|
||||||
|
import shared.views 1.0
|
||||||
|
|
||||||
|
StatusDialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var parentPopup
|
||||||
|
|
||||||
|
property string publicKey
|
||||||
|
|
||||||
|
property var profileStore
|
||||||
|
property var contactsStore
|
||||||
|
|
||||||
|
width: 640
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
header: null
|
||||||
|
footer: null
|
||||||
|
|
||||||
|
contentItem: ProfileDialogView {
|
||||||
|
publicKey: root.publicKey
|
||||||
|
profileStore: root.profileStore
|
||||||
|
contactsStore: root.contactsStore
|
||||||
|
onCloseRequested: root.close()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,474 +0,0 @@
|
||||||
import QtQuick 2.13
|
|
||||||
import QtQuick.Controls 2.13
|
|
||||||
import QtQuick.Layouts 1.13
|
|
||||||
import QtQml.Models 2.14
|
|
||||||
import QtGraphicalEffects 1.13
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
import shared 1.0
|
|
||||||
import shared.popups 1.0
|
|
||||||
import shared.stores 1.0
|
|
||||||
import shared.views 1.0 as SharedViews
|
|
||||||
import shared.controls.chat 1.0
|
|
||||||
import shared.panels 1.0
|
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import StatusQ.Popups.Dialog 0.1
|
|
||||||
|
|
||||||
StatusDialog {
|
|
||||||
id: popup
|
|
||||||
|
|
||||||
property Popup parentPopup
|
|
||||||
|
|
||||||
property var profileStore
|
|
||||||
property var contactsStore
|
|
||||||
|
|
||||||
property string userPublicKey: ""
|
|
||||||
property string userDisplayName: ""
|
|
||||||
property string userName: ""
|
|
||||||
property string userNickname: ""
|
|
||||||
property string userEnsName: ""
|
|
||||||
property string userIcon: ""
|
|
||||||
property string userBio: ""
|
|
||||||
property string userSocialLinks: ""
|
|
||||||
property int userTrustStatus: Constants.trustStatus.unknown
|
|
||||||
property int outgoingVerificationStatus: Constants.verificationStatus.unverified
|
|
||||||
property int incomingVerificationStatus: Constants.verificationStatus.unverified
|
|
||||||
property string text: ""
|
|
||||||
property string challenge: ""
|
|
||||||
property string response: ""
|
|
||||||
|
|
||||||
property bool userIsEnsVerified: false
|
|
||||||
property bool userIsBlocked: false
|
|
||||||
property bool userIsUntrustworthy: false
|
|
||||||
property bool userTrustIsUnknown: false
|
|
||||||
property bool isCurrentUser: false
|
|
||||||
property bool isAddedContact: false
|
|
||||||
property bool isContact: false
|
|
||||||
property bool isVerificationSent: false
|
|
||||||
property bool isVerified: false
|
|
||||||
property bool isTrusted: false
|
|
||||||
property bool hasReceivedVerificationRequest: false
|
|
||||||
|
|
||||||
property bool showRemoveVerified: false
|
|
||||||
property bool showVerifyIdentitySection: false
|
|
||||||
property bool showVerificationPendingSection: false
|
|
||||||
property bool showIdentityVerified: false
|
|
||||||
property bool showIdentityVerifiedUntrustworthy: false
|
|
||||||
|
|
||||||
property string verificationChallenge: ""
|
|
||||||
property string verificationResponse: ""
|
|
||||||
property string verificationResponseDisplayName: ""
|
|
||||||
property string verificationResponseIcon: ""
|
|
||||||
property string verificationRequestedAt: ""
|
|
||||||
property string verificationRepliedAt: ""
|
|
||||||
|
|
||||||
signal blockButtonClicked(name: string, address: string)
|
|
||||||
signal unblockButtonClicked(name: string, address: string)
|
|
||||||
signal removeButtonClicked(address: string)
|
|
||||||
|
|
||||||
signal contactUnblocked(publicKey: string)
|
|
||||||
signal contactBlocked(publicKey: string)
|
|
||||||
|
|
||||||
function openPopup(publicKey, state = "") {
|
|
||||||
// All this should be improved more, but for now we leave it like this.
|
|
||||||
const contactDetails = Utils.getContactDetailsAsJson(publicKey);
|
|
||||||
|
|
||||||
isCurrentUser = popup.profileStore.pubkey === publicKey;
|
|
||||||
|
|
||||||
userPublicKey = publicKey;
|
|
||||||
userDisplayName = isCurrentUser ? Qt.binding(() => { return popup.profileStore.displayName }) : contactDetails.displayName;
|
|
||||||
userName = contactDetails.alias;
|
|
||||||
userNickname = contactDetails.localNickname;
|
|
||||||
userEnsName = contactDetails.name;
|
|
||||||
userIcon = contactDetails.largeImage;
|
|
||||||
userBio = contactDetails.bio;
|
|
||||||
userSocialLinks = contactDetails.socialLinks;
|
|
||||||
userIsEnsVerified = contactDetails.ensVerified;
|
|
||||||
userIsBlocked = contactDetails.isBlocked;
|
|
||||||
isAddedContact = contactDetails.isAdded;
|
|
||||||
isContact = contactDetails.isContact
|
|
||||||
userTrustStatus = contactDetails.trustStatus
|
|
||||||
userTrustIsUnknown = contactDetails.trustStatus === Constants.trustStatus.unknown
|
|
||||||
userIsUntrustworthy = contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
|
||||||
outgoingVerificationStatus = contactDetails.verificationStatus
|
|
||||||
incomingVerificationStatus = contactDetails.incomingVerificationStatus
|
|
||||||
isVerificationSent = outgoingVerificationStatus !== Constants.verificationStatus.unverified
|
|
||||||
|
|
||||||
if (isContact && popup.contactsStore.hasReceivedVerificationRequestFrom(publicKey)) {
|
|
||||||
popup.hasReceivedVerificationRequest = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isContact && isVerificationSent) {
|
|
||||||
let verificationDetails = popup.contactsStore.getSentVerificationDetailsAsJson(publicKey);
|
|
||||||
|
|
||||||
outgoingVerificationStatus = verificationDetails.requestStatus;
|
|
||||||
verificationChallenge = verificationDetails.challenge;
|
|
||||||
verificationResponse = verificationDetails.response;
|
|
||||||
verificationResponseDisplayName = verificationDetails.displayName;
|
|
||||||
verificationResponseIcon = verificationDetails.icon;
|
|
||||||
verificationRequestedAt = verificationDetails.requestedAt;
|
|
||||||
verificationRepliedAt = verificationDetails.repliedAt;
|
|
||||||
}
|
|
||||||
isTrusted = outgoingVerificationStatus === Constants.verificationStatus.trusted
|
|
||||||
|| incomingVerificationStatus === Constants.verificationStatus.trusted
|
|
||||||
isVerified = outgoingVerificationStatus === Constants.verificationStatus.verified
|
|
||||||
|
|
||||||
text = ""; // this is most likely unneeded
|
|
||||||
|
|
||||||
popup.open();
|
|
||||||
|
|
||||||
if (state === Constants.profilePopupStates.openNickname) {
|
|
||||||
profileView.nicknamePopup.open();
|
|
||||||
} else if (state === Constants.profilePopupStates.contactRequest) {
|
|
||||||
d.openContactRequestPopup()
|
|
||||||
} else if (state === Constants.profilePopupStates.blockUser) {
|
|
||||||
blockUser();
|
|
||||||
} else if (state === Constants.profilePopupStates.unblockUser) {
|
|
||||||
unblockUser();
|
|
||||||
} else if (state === Constants.profilePopupStates.verifyIdentity) {
|
|
||||||
showVerifyIdentitySection = true;
|
|
||||||
} else if (state === Constants.profilePopupStates.respondToPendingRequest) {
|
|
||||||
popup.openPendingRequestPopup()
|
|
||||||
} else if (state === Constants.profilePopupStates.showVerificationPendingSection) {
|
|
||||||
popup.showVerificationPendingSection = true
|
|
||||||
profileView.wizardAnimation.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function blockUser() {
|
|
||||||
profileView.blockContactConfirmationDialog.contactName = userDisplayName;
|
|
||||||
profileView.blockContactConfirmationDialog.contactAddress = userPublicKey;
|
|
||||||
profileView.blockContactConfirmationDialog.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
function unblockUser() {
|
|
||||||
profileView.unblockContactConfirmationDialog.contactName = userDisplayName;
|
|
||||||
profileView.unblockContactConfirmationDialog.contactAddress = userPublicKey;
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
|
|
||||||
function openContactRequestPopup() {
|
|
||||||
let contactRequestPopup = Global.openContactRequestPopup(popup.userPublicKey)
|
|
||||||
contactRequestPopup.closed.connect(popup.close)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 700
|
|
||||||
padding: 8
|
|
||||||
|
|
||||||
header: StatusDialogHeader {
|
|
||||||
id: dialogHeader
|
|
||||||
headline.title: {
|
|
||||||
if(showVerifyIdentitySection || showVerificationPendingSection){
|
|
||||||
return qsTr("Verify %1's Identity").arg(userDisplayName)
|
|
||||||
}
|
|
||||||
return popup.isCurrentUser ? qsTr("My Profile") :
|
|
||||||
qsTr("%1's Profile").arg(userDisplayName)
|
|
||||||
}
|
|
||||||
|
|
||||||
headline.subtitle: popup.isCurrentUser ? "" : Utils.getElidedCompressedPk(userPublicKey)
|
|
||||||
|
|
||||||
actions {
|
|
||||||
customButtons: ObjectModel {
|
|
||||||
StatusFlatRoundButton {
|
|
||||||
type: StatusFlatRoundButton.Type.Secondary
|
|
||||||
width: 32
|
|
||||||
height: 32
|
|
||||||
|
|
||||||
icon.width: 20
|
|
||||||
icon.height: 20
|
|
||||||
icon.name: "qr"
|
|
||||||
onClicked: profileView.qrCodePopup.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closeButton.onClicked: popup.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer: StatusDialogFooter {
|
|
||||||
visible: !popup.isCurrentUser
|
|
||||||
|
|
||||||
leftButtons: ObjectModel {
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Cancel verification")
|
|
||||||
visible: !isVerified && isContact && isVerificationSent && showVerificationPendingSection
|
|
||||||
onClicked: {
|
|
||||||
popup.contactsStore.cancelVerificationRequest(userPublicKey);
|
|
||||||
popup.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rightButtons: ObjectModel {
|
|
||||||
StatusFlatButton {
|
|
||||||
text: userIsBlocked ?
|
|
||||||
qsTr("Unblock User") :
|
|
||||||
qsTr("Block User")
|
|
||||||
type: StatusBaseButton.Type.Danger
|
|
||||||
visible: !isAddedContact
|
|
||||||
onClicked: userIsBlocked ? unblockUser() : blockUser()
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusFlatButton {
|
|
||||||
visible: !showRemoveVerified && !showIdentityVerified && !showVerifyIdentitySection && !showVerificationPendingSection && !userIsBlocked && isAddedContact
|
|
||||||
type: StatusBaseButton.Type.Danger
|
|
||||||
text: qsTr('Remove Contact')
|
|
||||||
onClicked: {
|
|
||||||
profileView.removeContactConfirmationDialog.parentPopup = popup;
|
|
||||||
profileView.removeContactConfirmationDialog.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Send Contact Request")
|
|
||||||
visible: !userIsBlocked && !isAddedContact
|
|
||||||
onClicked: d.openContactRequestPopup()
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Mark Untrustworthy")
|
|
||||||
visible: !showIdentityVerifiedUntrustworthy && !showIdentityVerified && !showVerifyIdentitySection && userTrustIsUnknown
|
|
||||||
enabled: !showVerificationPendingSection || verificationResponse !== ""
|
|
||||||
type: StatusBaseButton.Type.Danger
|
|
||||||
onClicked: {
|
|
||||||
if (showVerificationPendingSection) {
|
|
||||||
popup.showIdentityVerified = false;
|
|
||||||
popup.showIdentityVerifiedUntrustworthy = true;
|
|
||||||
popup.showVerificationPendingSection = false;
|
|
||||||
popup.showVerifyIdentitySection = false;
|
|
||||||
profileView.stepsListModel.setProperty(2, "stepCompleted", true);
|
|
||||||
popup.contactsStore.verifiedUntrustworthy(userPublicKey);
|
|
||||||
} else {
|
|
||||||
popup.contactsStore.markUntrustworthy(userPublicKey);
|
|
||||||
popup.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Remove 'Identity Verified' status")
|
|
||||||
visible: isTrusted && !showIdentityVerified && !showRemoveVerified
|
|
||||||
type: StatusBaseButton.Type.Danger
|
|
||||||
onClicked: {
|
|
||||||
showRemoveVerified = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("No")
|
|
||||||
visible: showRemoveVerified
|
|
||||||
type: StatusBaseButton.Type.Danger
|
|
||||||
onClicked: {
|
|
||||||
showRemoveVerified = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Yes")
|
|
||||||
visible: showRemoveVerified
|
|
||||||
onClicked: {
|
|
||||||
popup.contactsStore.removeTrustStatus(userPublicKey);
|
|
||||||
popup.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Remove Untrustworthy Mark")
|
|
||||||
visible: userIsUntrustworthy
|
|
||||||
onClicked: {
|
|
||||||
popup.contactsStore.removeTrustStatus(userPublicKey);
|
|
||||||
popup.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Verify Identity")
|
|
||||||
visible: !showIdentityVerifiedUntrustworthy && !showIdentityVerified &&
|
|
||||||
!showVerifyIdentitySection && isContact && !isVerificationSent
|
|
||||||
&& !hasReceivedVerificationRequest
|
|
||||||
onClicked: {
|
|
||||||
popup.showVerifyIdentitySection = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Verify Identity pending...")
|
|
||||||
visible: (!showIdentityVerifiedUntrustworthy && !showIdentityVerified && !isTrusted
|
|
||||||
&& isContact && isVerificationSent && !showVerificationPendingSection) ||
|
|
||||||
(hasReceivedVerificationRequest && !isTrusted)
|
|
||||||
onClicked: {
|
|
||||||
if (hasReceivedVerificationRequest) {
|
|
||||||
popup.openPendingRequestPopup()
|
|
||||||
} else {
|
|
||||||
popup.showVerificationPendingSection = true
|
|
||||||
profileView.wizardAnimation.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Send verification request")
|
|
||||||
visible: showVerifyIdentitySection && isContact && !isVerificationSent
|
|
||||||
onClicked: {
|
|
||||||
popup.contactsStore.sendVerificationRequest(userPublicKey, Utils.escapeHtml(profileView.challengeTxt.input.text));
|
|
||||||
profileView.stepsListModel.setProperty(1, "stepCompleted", true);
|
|
||||||
Global.displayToastMessage(qsTr("Verification request sent"),
|
|
||||||
"",
|
|
||||||
"checkmark-circle",
|
|
||||||
false,
|
|
||||||
Constants.ephemeralNotificationType.normal,
|
|
||||||
"");
|
|
||||||
popup.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
text: qsTr("Confirm Identity")
|
|
||||||
visible: isContact && isVerificationSent && !isTrusted && showVerificationPendingSection
|
|
||||||
enabled: verificationChallenge !== "" && verificationResponse !== ""
|
|
||||||
onClicked: {
|
|
||||||
popup.showIdentityVerified = true;
|
|
||||||
popup.showIdentityVerifiedUntrustworthy = false;
|
|
||||||
popup.showVerificationPendingSection = false;
|
|
||||||
popup.showVerifyIdentitySection = false;
|
|
||||||
profileView.stepsListModel.setProperty(2, "stepCompleted", true);
|
|
||||||
popup.contactsStore.verifiedTrusted(userPublicKey);
|
|
||||||
popup.isTrusted = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
visible: showIdentityVerified || showIdentityVerifiedUntrustworthy
|
|
||||||
text: qsTr("Rename")
|
|
||||||
onClicked: {
|
|
||||||
profileView.nicknamePopup.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusButton {
|
|
||||||
visible: showIdentityVerified || showIdentityVerifiedUntrustworthy
|
|
||||||
text: qsTr("Close")
|
|
||||||
onClicked: {
|
|
||||||
popup.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusScrollView {
|
|
||||||
id: scrollView
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
padding: 0
|
|
||||||
|
|
||||||
SharedViews.ProfileView {
|
|
||||||
id: profileView
|
|
||||||
|
|
||||||
width: scrollView.availableWidth
|
|
||||||
|
|
||||||
profileStore: popup.profileStore
|
|
||||||
contactsStore: popup.contactsStore
|
|
||||||
|
|
||||||
|
|
||||||
userPublicKey: popup.userPublicKey
|
|
||||||
userDisplayName: popup.userDisplayName
|
|
||||||
userName: popup.userName
|
|
||||||
userNickname: popup.userNickname
|
|
||||||
userEnsName: popup.userEnsName
|
|
||||||
userIcon: popup.userIcon
|
|
||||||
userBio: popup.userBio
|
|
||||||
userSocialLinks: popup.userSocialLinks
|
|
||||||
userIsEnsVerified: popup.userIsEnsVerified
|
|
||||||
userIsBlocked: popup.userIsBlocked
|
|
||||||
isAddedContact: popup.isAddedContact
|
|
||||||
isCurrentUser: popup.isCurrentUser
|
|
||||||
|
|
||||||
isContact: popup.isContact
|
|
||||||
isVerificationSent: popup.isVerificationSent
|
|
||||||
isVerified: popup.isVerified
|
|
||||||
isTrusted: popup.isTrusted
|
|
||||||
hasReceivedVerificationRequest: popup.hasReceivedVerificationRequest
|
|
||||||
|
|
||||||
userTrustStatus: popup.userTrustStatus
|
|
||||||
outgoingVerificationStatus: popup.outgoingVerificationStatus
|
|
||||||
|
|
||||||
showVerifyIdentitySection: popup.showVerifyIdentitySection
|
|
||||||
showVerificationPendingSection: popup.showVerificationPendingSection
|
|
||||||
showIdentityVerified: popup.showIdentityVerified
|
|
||||||
showIdentityVerifiedUntrustworthy: popup.showIdentityVerifiedUntrustworthy
|
|
||||||
|
|
||||||
challenge: popup.challenge
|
|
||||||
response: popup.response
|
|
||||||
|
|
||||||
userIsUntrustworthy: popup.userIsUntrustworthy
|
|
||||||
userTrustIsUnknown: popup.userTrustIsUnknown
|
|
||||||
|
|
||||||
verificationChallenge: popup.verificationChallenge
|
|
||||||
verificationResponse: popup.verificationResponse
|
|
||||||
verificationResponseDisplayName: popup.verificationResponseDisplayName
|
|
||||||
verificationResponseIcon: popup.verificationResponseIcon
|
|
||||||
verificationRequestedAt: popup.verificationRequestedAt
|
|
||||||
verificationRepliedAt: popup.verificationRepliedAt
|
|
||||||
|
|
||||||
onContactUnblocked: {
|
|
||||||
popup.close()
|
|
||||||
popup.contactUnblocked(publicKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
onContactBlocked: {
|
|
||||||
popup.close()
|
|
||||||
popup.contactBlocked(publicKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
onContactAdded: {
|
|
||||||
popup.close()
|
|
||||||
popup.contactAdded(publicKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
onContactRemoved: {
|
|
||||||
popup.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
onNicknameEdited: {
|
|
||||||
popup.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: contactVerificationRequestPopupComponent
|
|
||||||
ContactVerificationRequestPopup {
|
|
||||||
onResponseSent: {
|
|
||||||
popup.contactsStore.acceptVerificationRequest(senderPublicKey, response)
|
|
||||||
}
|
|
||||||
onVerificationRefused: {
|
|
||||||
popup.contactsStore.declineVerificationRequest(senderPublicKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,9 +19,12 @@ StatusModal {
|
||||||
property string userIcon: ""
|
property string userIcon: ""
|
||||||
property bool userIsEnsVerified
|
property bool userIsEnsVerified
|
||||||
|
|
||||||
|
property string challengeText: qsTr("Say who you are / why you want to become a contact...")
|
||||||
|
property string buttonText: qsTr("Send Contact Request")
|
||||||
|
|
||||||
signal accepted(string message)
|
signal accepted(string message)
|
||||||
|
|
||||||
padding: 16
|
padding: Style.current.padding
|
||||||
header.title: qsTr("Send Contact Request to %1").arg(userDisplayName)
|
header.title: qsTr("Send Contact Request to %1").arg(userDisplayName)
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
|
@ -33,6 +36,10 @@ StatusModal {
|
||||||
readonly property int contentSpacing: 5
|
readonly property int contentSpacing: 5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAboutToShow: {
|
||||||
|
messageInput.input.edit.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -55,7 +62,7 @@ StatusModal {
|
||||||
id: messageInput
|
id: messageInput
|
||||||
charLimit: d.maxMsgLength
|
charLimit: d.maxMsgLength
|
||||||
|
|
||||||
placeholderText: qsTr("Say who you are / why you want to become a contact...")
|
placeholderText: root.challengeText
|
||||||
input.multiline: true
|
input.multiline: true
|
||||||
minimumHeight: d.msgHeight
|
minimumHeight: d.msgHeight
|
||||||
maximumHeight: d.msgHeight
|
maximumHeight: d.msgHeight
|
||||||
|
@ -71,7 +78,7 @@ StatusModal {
|
||||||
|
|
||||||
rightButtons: StatusButton {
|
rightButtons: StatusButton {
|
||||||
enabled: messageInput.valid
|
enabled: messageInput.valid
|
||||||
text: qsTr("Send Contact Request")
|
text: root.buttonText
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.accepted(Utils.escapeHtml(messageInput.text));
|
root.accepted(Utils.escapeHtml(messageInput.text));
|
||||||
root.close();
|
root.close();
|
||||||
|
|
|
@ -15,7 +15,6 @@ ModalPopup {
|
||||||
height: 237
|
height: 237
|
||||||
width: 400
|
width: 400
|
||||||
|
|
||||||
property Popup parentPopup
|
|
||||||
property string contactAddress: ""
|
property string contactAddress: ""
|
||||||
property string contactName: ""
|
property string contactName: ""
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ SettingsDirtyToastMessage 1.0 SettingsDirtyToastMessage.qml
|
||||||
ConfirmationDialog 1.0 ConfirmationDialog.qml
|
ConfirmationDialog 1.0 ConfirmationDialog.qml
|
||||||
CommunityIntroDialog 1.0 CommunityIntroDialog.qml
|
CommunityIntroDialog 1.0 CommunityIntroDialog.qml
|
||||||
ContactVerificationRequestPopup 1.0 ContactVerificationRequestPopup.qml
|
ContactVerificationRequestPopup 1.0 ContactVerificationRequestPopup.qml
|
||||||
|
OutgoingContactVerificationRequestPopup 1.0 OutgoingContactVerificationRequestPopup.qml
|
||||||
DownloadModal 1.0 DownloadModal.qml
|
DownloadModal 1.0 DownloadModal.qml
|
||||||
DownloadPage 1.0 DownloadPage.qml
|
DownloadPage 1.0 DownloadPage.qml
|
||||||
InviteFriendsPopup 1.0 InviteFriendsPopup.qml
|
InviteFriendsPopup 1.0 InviteFriendsPopup.qml
|
||||||
|
@ -17,7 +18,7 @@ UnblockContactConfirmationDialog 1.0 UnblockContactConfirmationDialog.qml
|
||||||
UserStatusContextMenu 1.0 UserStatusContextMenu.qml
|
UserStatusContextMenu 1.0 UserStatusContextMenu.qml
|
||||||
SignTransactionModal 1.0 SignTransactionModal.qml
|
SignTransactionModal 1.0 SignTransactionModal.qml
|
||||||
SelectAccountModal 1.0 SelectAccountModal.qml
|
SelectAccountModal 1.0 SelectAccountModal.qml
|
||||||
ProfilePopup 1.0 ProfilePopup.qml
|
ProfileDialog 1.0 ProfileDialog.qml
|
||||||
ImageCropWorkflow 1.0 ImageCropWorkflow.qml
|
ImageCropWorkflow 1.0 ImageCropWorkflow.qml
|
||||||
ImportCommunityPopup 1.0 ImportCommunityPopup.qml
|
ImportCommunityPopup 1.0 ImportCommunityPopup.qml
|
||||||
DisplayNamePopup 1.0 DisplayNamePopup.qml
|
DisplayNamePopup 1.0 DisplayNamePopup.qml
|
||||||
|
|
|
@ -8,7 +8,7 @@ import ".."
|
||||||
|
|
||||||
StatusChatImageValidator {
|
StatusChatImageValidator {
|
||||||
id: root
|
id: root
|
||||||
errorMessage: qsTr("You can only upload %1 images at a time").arg(Constants.maxUploadFiles)
|
errorMessage: qsTr("You can only upload %n image(s) at a time", "", Constants.maxUploadFiles)
|
||||||
|
|
||||||
onImagesChanged: {
|
onImagesChanged: {
|
||||||
root.isValid = images.length <= Constants.maxUploadFiles
|
root.isValid = images.length <= Constants.maxUploadFiles
|
||||||
|
|
|
@ -57,7 +57,7 @@ ModalPopup {
|
||||||
root.close();
|
root.close();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error sending the transaction', e)
|
console.error('Error sending the transaction', e)
|
||||||
sendingError.text = "Error sending the transaction: " + e.message;
|
sendingError.text = qsTr("Error sending the transaction: %1").arg(e.message);
|
||||||
return sendingError.open()
|
return sendingError.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,6 @@ Popup {
|
||||||
searchBox.input.edit.forceActiveFocus()
|
searchBox.input.edit.forceActiveFocus()
|
||||||
if (RootStore.isTenorWarningAccepted) {
|
if (RootStore.isTenorWarningAccepted) {
|
||||||
RootStore.getTrendingsGifs()
|
RootStore.getTrendingsGifs()
|
||||||
} else {
|
|
||||||
confirmationPopupLoader.active = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +200,7 @@ Popup {
|
||||||
sourceComponent: ConfirmationPopup {
|
sourceComponent: ConfirmationPopup {
|
||||||
visible: true
|
visible: true
|
||||||
}
|
}
|
||||||
active: false
|
active: !RootStore.isTenorWarningAccepted
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
|
@ -45,7 +45,7 @@ Popup {
|
||||||
}
|
}
|
||||||
Connections {
|
Connections {
|
||||||
target: mainModule
|
target: mainModule
|
||||||
onOnlineStatusChanged: {
|
function onOnlineStatusChanged() {
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,6 @@ QtObject {
|
||||||
|
|
||||||
function findTokenSymbolByAddress(address) {
|
function findTokenSymbolByAddress(address) {
|
||||||
return walletSectionAllTokens.findTokenSymbolByAddress(address)
|
return walletSectionAllTokens.findTokenSymbolByAddress(address)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNameForSavedWalletAddress(address) {
|
function getNameForSavedWalletAddress(address) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ Item {
|
||||||
delegate: StatusListItem {
|
delegate: StatusListItem {
|
||||||
readonly property string balance: enabledNetworkBalance // Needed for the tests
|
readonly property string balance: enabledNetworkBalance // Needed for the tests
|
||||||
objectName: "AssetView_TokenListItem_" + symbol
|
objectName: "AssetView_TokenListItem_" + symbol
|
||||||
width: parent.width
|
width: ListView.view.width
|
||||||
title: name
|
title: name
|
||||||
subTitle: `${enabledNetworkBalance} ${symbol}`
|
subTitle: `${enabledNetworkBalance} ${symbol}`
|
||||||
asset.name: symbol ? Style.png("tokens/" + symbol) : ""
|
asset.name: symbol ? Style.png("tokens/" + symbol) : ""
|
||||||
|
|
|
@ -35,7 +35,7 @@ ColumnLayout {
|
||||||
target: RootStore.history
|
target: RootStore.history
|
||||||
onLoadingTrxHistoryChanged: function(isLoading, address) {
|
onLoadingTrxHistoryChanged: function(isLoading, address) {
|
||||||
if (historyView.account.address.toLowerCase() === address.toLowerCase()) {
|
if (historyView.account.address.toLowerCase() === address.toLowerCase()) {
|
||||||
root.isLoading = isLoading
|
historyView.isLoading = isLoading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,704 @@
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
|
import QtGraphicalEffects 1.14
|
||||||
|
|
||||||
|
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
|
||||||
|
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool readOnly
|
||||||
|
|
||||||
|
property string publicKey: contactsStore.myPublicKey
|
||||||
|
|
||||||
|
property var profileStore
|
||||||
|
property var contactsStore
|
||||||
|
|
||||||
|
signal closeRequested()
|
||||||
|
|
||||||
|
padding: 0
|
||||||
|
topPadding: 40
|
||||||
|
|
||||||
|
background: StatusDialogBackground {
|
||||||
|
id: background
|
||||||
|
}
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
property var contactDetails: Utils.getContactDetailsAsJson(root.publicKey)
|
||||||
|
|
||||||
|
function reload() {
|
||||||
|
contactDetails = Utils.getContactDetailsAsJson(root.publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property bool isCurrentUser: root.profileStore.pubkey === root.publicKey
|
||||||
|
readonly property string userDisplayName: contactDetails.displayName
|
||||||
|
readonly property string userNickName: contactDetails.localNickname
|
||||||
|
readonly property string prettyEnsName: '@' + Utils.removeStatusEns(contactDetails.name)
|
||||||
|
readonly property bool isContact: contactDetails.isContact
|
||||||
|
readonly property bool isBlocked: contactDetails.isBlocked
|
||||||
|
|
||||||
|
readonly property bool isContactRequestSent: contactDetails.isAdded
|
||||||
|
readonly property bool isContactRequestReceived: contactDetails.hasAddedUs
|
||||||
|
|
||||||
|
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
|
||||||
|
readonly property bool isVerificationRequestReceived: d.isCurrentUser ? false : root.contactsStore.hasReceivedVerificationRequestFrom(root.publicKey)
|
||||||
|
|
||||||
|
readonly property bool isTrusted: outgoingVerificationStatus === Constants.verificationStatus.trusted ||
|
||||||
|
incomingVerificationStatus === Constants.verificationStatus.trusted
|
||||||
|
readonly property bool isVerified: outgoingVerificationStatus === Constants.verificationStatus.verified
|
||||||
|
|
||||||
|
readonly property string linkToProfile: {
|
||||||
|
let user = ""
|
||||||
|
if (d.isCurrentUser)
|
||||||
|
user = root.profileStore.ensName
|
||||||
|
else
|
||||||
|
user = contactDetails.name
|
||||||
|
if (!user)
|
||||||
|
user = root.publicKey
|
||||||
|
return Constants.userLinkPrefix + user
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var conns: Connections {
|
||||||
|
target: Global
|
||||||
|
function onNickNameChanged(publicKey, nickname) {
|
||||||
|
if (publicKey === root.publicKey) d.reload()
|
||||||
|
}
|
||||||
|
function onContactBlocked(publicKey) {
|
||||||
|
if (publicKey === root.publicKey) d.reload()
|
||||||
|
}
|
||||||
|
function onContactUnblocked(publicKey) {
|
||||||
|
if (publicKey === root.publicKey) d.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reload() {
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: btnEditProfileComponent
|
||||||
|
StatusButton {
|
||||||
|
size: StatusButton.Size.Small
|
||||||
|
text: qsTr("Edit Profile")
|
||||||
|
enabled: !root.readOnly
|
||||||
|
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
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.current.halfPadding
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
font.pixelSize: 13
|
||||||
|
text: qsTr("Respond to contact request")
|
||||||
|
}
|
||||||
|
|
||||||
|
AcceptRejectOptionsButtonsPanel {
|
||||||
|
menuButton.visible: false
|
||||||
|
onAcceptClicked: {
|
||||||
|
root.contactsStore.acceptContactRequest(root.publicKey)
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
onDeclineClicked: {
|
||||||
|
root.contactsStore.dismissContactRequest(root.publicKey)
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: btnSendContactRequestComponent
|
||||||
|
StatusButton {
|
||||||
|
size: StatusButton.Size.Small
|
||||||
|
text: qsTr("Send Contact Request")
|
||||||
|
onClicked: {
|
||||||
|
let contactRequestPopup = Global.openContactRequestPopup(root.publicKey)
|
||||||
|
contactRequestPopup.accepted.connect(d.reload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: btnBlockUserComponent
|
||||||
|
StatusButton {
|
||||||
|
size: StatusButton.Size.Small
|
||||||
|
type: StatusBaseButton.Type.Danger
|
||||||
|
text: qsTr("Block User")
|
||||||
|
onClicked: Global.blockContactRequested(root.publicKey, d.userDisplayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: btnUnblockUserComponent
|
||||||
|
StatusButton {
|
||||||
|
size: StatusButton.Size.Small
|
||||||
|
text: qsTr("Unblock User")
|
||||||
|
onClicked: Global.unblockContactRequested(root.publicKey, d.userDisplayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: txtPendingContactRequestComponent
|
||||||
|
StatusBaseText {
|
||||||
|
font.pixelSize: 13
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
text: qsTr("Contact Request Pending...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: txtRejectedContactRequestComponent
|
||||||
|
StatusBaseText {
|
||||||
|
font.pixelSize: 13
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
text: qsTr("Contact Request Rejected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: btnRespondToIdRequestComponent
|
||||||
|
StatusButton {
|
||||||
|
size: StatusButton.Size.Small
|
||||||
|
text: qsTr("Respond to ID Request")
|
||||||
|
onClicked: {
|
||||||
|
let idRequestPopup = Global.openIncomingIDRequestPopup(root.publicKey)
|
||||||
|
idRequestPopup.closed.connect(d.reload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfirmationDialog {
|
||||||
|
id: removeContactConfirmationDialog
|
||||||
|
header.title: qsTr("Remove contact '%1'").arg(d.userDisplayName)
|
||||||
|
confirmationText: qsTr("This will remove the user as a contact. Please confirm.")
|
||||||
|
onConfirmButtonClicked: {
|
||||||
|
root.contactsStore.removeContact(root.publicKey)
|
||||||
|
close()
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfirmationDialog {
|
||||||
|
id: removeVerificationConfirmationDialog
|
||||||
|
header.title: qsTr("Remove contact verification")
|
||||||
|
confirmationText: qsTr("This will remove the contact's verified status. Please confirm.")
|
||||||
|
onConfirmButtonClicked: {
|
||||||
|
root.contactsStore.removeTrustStatus(root.publicKey)
|
||||||
|
close()
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
objectName: "ProfileDialog_userImage"
|
||||||
|
name: d.userDisplayName
|
||||||
|
pubkey: root.publicKey
|
||||||
|
image: d.contactDetails.largeImage
|
||||||
|
interactive: false
|
||||||
|
imageWidth: 80
|
||||||
|
imageHeight: imageWidth
|
||||||
|
showRing: !d.contactDetails.ensVerified
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 4
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
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: d.userDisplayName
|
||||||
|
}
|
||||||
|
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
|
||||||
|
tiny: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusBaseText {
|
||||||
|
id: contactSecondaryName
|
||||||
|
font.pixelSize: 12
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
text: {
|
||||||
|
let result = ""
|
||||||
|
if (d.userNickName) {
|
||||||
|
if (d.contactDetails.ensVerified)
|
||||||
|
result = d.prettyEnsName
|
||||||
|
else
|
||||||
|
result = d.contactDetails.optionalName // original display name
|
||||||
|
}
|
||||||
|
if (result)
|
||||||
|
return "(%1)".arg(result)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
visible: text
|
||||||
|
}
|
||||||
|
EmojiHash {
|
||||||
|
objectName: "ProfileDialog_userEmojiHash"
|
||||||
|
publicKey: root.publicKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredHeight: menuButton.visible ? menuButton.height : -1
|
||||||
|
sourceComponent: {
|
||||||
|
// current user
|
||||||
|
if (d.isCurrentUser)
|
||||||
|
return btnEditProfileComponent
|
||||||
|
|
||||||
|
// contact request, outgoing, rejected
|
||||||
|
if (!d.isContact && d.isContactRequestSent && d.outgoingVerificationStatus === Constants.verificationStatus.declined)
|
||||||
|
return txtRejectedContactRequestComponent
|
||||||
|
// contact request, outgoing, pending
|
||||||
|
if (!d.isContact && d.isContactRequestSent)
|
||||||
|
return txtPendingContactRequestComponent
|
||||||
|
|
||||||
|
// contact request, incoming, pending
|
||||||
|
if (!d.isContact && d.isContactRequestReceived)
|
||||||
|
return btnAcceptContactRequestComponent
|
||||||
|
|
||||||
|
// contact request, incoming, rejected
|
||||||
|
if (d.isContactRequestSent && d.incomingVerificationStatus === Constants.verificationStatus.declined)
|
||||||
|
return btnBlockUserComponent
|
||||||
|
|
||||||
|
// verified contact request, incoming, pending
|
||||||
|
if (d.isContact && !d.isTrusted && d.isVerificationRequestReceived)
|
||||||
|
return btnRespondToIdRequestComponent
|
||||||
|
|
||||||
|
// block user
|
||||||
|
if (!d.isContact && !d.isBlocked &&
|
||||||
|
(d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy || d.outgoingVerificationStatus === Constants.verificationStatus.declined))
|
||||||
|
return btnBlockUserComponent
|
||||||
|
|
||||||
|
// send contact request
|
||||||
|
if (!d.isContact && !d.isBlocked && !d.isContactRequestSent)
|
||||||
|
return btnSendContactRequestComponent
|
||||||
|
|
||||||
|
// blocked contact
|
||||||
|
if (d.isBlocked)
|
||||||
|
return btnUnblockUserComponent
|
||||||
|
|
||||||
|
// send message
|
||||||
|
if (d.isContact && !d.isBlocked)
|
||||||
|
return btnSendMessageComponent
|
||||||
|
|
||||||
|
console.warn("!!! UNHANDLED CONTACT ACTION BUTTON; PUBKEY", root.publicKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusFlatButton {
|
||||||
|
id: menuButton
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
|
||||||
|
visible: !d.isCurrentUser
|
||||||
|
size: StatusBaseButton.Size.Small
|
||||||
|
horizontalPadding: 6
|
||||||
|
verticalPadding: 6
|
||||||
|
icon.name: "more"
|
||||||
|
icon.color: Theme.palette.directColor1
|
||||||
|
highlighted: moreMenu.opened
|
||||||
|
onClicked: moreMenu.popup(-moreMenu.width + width, height + 4)
|
||||||
|
|
||||||
|
StatusPopupMenu {
|
||||||
|
id: moreMenu
|
||||||
|
width: 230
|
||||||
|
|
||||||
|
SendContactRequestMenuItem {
|
||||||
|
enabled: !d.isContact && !d.isBlocked && !d.isContactRequestSent && !d.contactDetails.removed &&
|
||||||
|
d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy // we have an action button otherwise
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
let contactRequestPopup = Global.openContactRequestPopup(root.publicKey)
|
||||||
|
contactRequestPopup.closed.connect(d.reload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Verify Identity")
|
||||||
|
icon.name: "checkmark-circle"
|
||||||
|
enabled: d.isContact && !d.isBlocked &&
|
||||||
|
d.outgoingVerificationStatus === Constants.verificationStatus.unverified &&
|
||||||
|
!d.isVerificationRequestReceived
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
let idRequestPopup = Global.openSendIDRequestPopup(root.publicKey)
|
||||||
|
idRequestPopup.accepted.connect(d.reload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("ID Request Pending...")
|
||||||
|
icon.name: "checkmark-circle"
|
||||||
|
enabled: d.isContact && !d.isBlocked && !d.isTrusted && d.isVerificationRequestSent
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
let idRequestPopup = Global.openOutgoingIDRequestPopup(root.publicKey)
|
||||||
|
idRequestPopup.closed.connect(d.reload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Rename")
|
||||||
|
icon.name: "edit_pencil"
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
Global.openNicknamePopupRequested(root.publicKey, d.userNickName,
|
||||||
|
"%1 (%2)".arg(d.userDisplayName).arg(Utils.getElidedCompressedPk(root.publicKey)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Reverse Contact Rejection")
|
||||||
|
icon.name: "refresh"
|
||||||
|
enabled: d.contactDetails.removed
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
root.contactsStore.removeContactRequestRejection(root.publicKey)
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Copy Link to Profile")
|
||||||
|
icon.name: "copy"
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
root.profileStore.copyToClipboard(d.linkToProfile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Unblock User")
|
||||||
|
icon.name: "remove-circle"
|
||||||
|
enabled: d.isBlocked
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
Global.unblockContactRequested(root.publicKey, d.userDisplayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuSeparator {}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Mark as Untrustworthy")
|
||||||
|
icon.name: "warning"
|
||||||
|
type: StatusMenuItem.Type.Danger
|
||||||
|
enabled: d.contactDetails.trustStatus === Constants.trustStatus.unknown
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
if (d.isContact && !d.isTrusted && d.isVerificationRequestReceived)
|
||||||
|
root.contactsStore.verifiedUntrustworthy(root.publicKey)
|
||||||
|
else
|
||||||
|
root.contactsStore.markUntrustworthy(root.publicKey)
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Remove Untrustworthy Mark")
|
||||||
|
icon.name: "warning"
|
||||||
|
enabled: d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
root.contactsStore.removeTrustStatus(root.publicKey)
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Remove Identity Verification")
|
||||||
|
icon.name: "warning"
|
||||||
|
type: StatusMenuItem.Type.Danger
|
||||||
|
enabled: d.isContact && d.isTrusted
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
removeVerificationConfirmationDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Remove Contact")
|
||||||
|
icon.name: "remove-contact"
|
||||||
|
type: StatusMenuItem.Type.Danger
|
||||||
|
enabled: d.isContact && !d.isBlocked
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
removeContactConfirmationDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Cancel Contact Request")
|
||||||
|
icon.name: "cancel"
|
||||||
|
type: StatusMenuItem.Type.Danger
|
||||||
|
enabled: !d.isContact && d.isContactRequestSent && !d.contactDetails.removed
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
root.contactsStore.removeContact(root.publicKey)
|
||||||
|
d.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusMenuItem {
|
||||||
|
text: qsTr("Block User")
|
||||||
|
icon.name: "cancel"
|
||||||
|
type: StatusMenuItem.Type.Danger
|
||||||
|
enabled: !d.isBlocked
|
||||||
|
onTriggered: {
|
||||||
|
moreMenu.close()
|
||||||
|
Global.blockContactRequested(root.publicKey, d.userDisplayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusDialogDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: -column.anchors.leftMargin
|
||||||
|
Layout.rightMargin: -column.anchors.rightMargin
|
||||||
|
Layout.topMargin: -column.spacing
|
||||||
|
Layout.bottomMargin: -column.spacing
|
||||||
|
opacity: scrollView.atYBeginning ? 0 : 1
|
||||||
|
Behavior on opacity { OpacityAnimator {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusScrollView {
|
||||||
|
id: scrollView
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.leftMargin: -column.anchors.leftMargin
|
||||||
|
Layout.rightMargin: -column.anchors.rightMargin
|
||||||
|
Layout.topMargin: -column.spacing
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
width: scrollView.width
|
||||||
|
spacing: 20
|
||||||
|
|
||||||
|
ProfileBioSocialsPanel {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: column.anchors.leftMargin + Style.current.halfPadding
|
||||||
|
Layout.rightMargin: column.anchors.rightMargin + Style.current.halfPadding
|
||||||
|
bio: d.contactDetails.bio
|
||||||
|
userSocialLinksJson: d.contactDetails.socialLinks
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: column.anchors.leftMargin
|
||||||
|
Layout.rightMargin: column.anchors.rightMargin
|
||||||
|
flow: GridLayout.TopToBottom
|
||||||
|
rowSpacing: Style.current.halfPadding
|
||||||
|
columnSpacing: Style.current.bigPadding
|
||||||
|
visible: d.isCurrentUser
|
||||||
|
enabled: visible
|
||||||
|
columns: 2
|
||||||
|
rows: 4
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Link to Profile")
|
||||||
|
font.pixelSize: 13
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBaseInput {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 56
|
||||||
|
leftPadding: 14
|
||||||
|
rightPadding: Style.current.halfPadding
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
placeholder.rightPadding: Style.current.halfPadding
|
||||||
|
placeholderText: d.linkToProfile
|
||||||
|
placeholderTextColor: Theme.palette.directColor1
|
||||||
|
edit.readOnly: true
|
||||||
|
rightComponent: StatusButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
borderColor: Theme.palette.primaryColor1
|
||||||
|
size: StatusBaseButton.Size.Tiny
|
||||||
|
text: qsTr("Copy")
|
||||||
|
onClicked: {
|
||||||
|
text = qsTr("Copied")
|
||||||
|
root.profileStore.copyToClipboard(d.linkToProfile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: Style.current.smallPadding
|
||||||
|
text: qsTr("Emoji Hash")
|
||||||
|
font.pixelSize: 13
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBaseInput {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 56
|
||||||
|
leftPadding: 14
|
||||||
|
rightPadding: Style.current.halfPadding
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
edit.readOnly: true
|
||||||
|
leftComponent: EmojiHash {
|
||||||
|
publicKey: root.publicKey
|
||||||
|
oneRow: !root.readOnly
|
||||||
|
}
|
||||||
|
rightComponent: StatusButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
borderColor: Theme.palette.primaryColor1
|
||||||
|
size: StatusBaseButton.Size.Tiny
|
||||||
|
text: qsTr("Copy")
|
||||||
|
onClicked: {
|
||||||
|
root.profileStore.copyToClipboard(Utils.getEmojiHashAsJson(root.publicKey).join("").toString())
|
||||||
|
text = qsTr("Copied")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.rowSpan: 4
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: Theme.palette.baseColor2
|
||||||
|
radius: Style.current.halfPadding
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
asynchronous: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
width: 170
|
||||||
|
height: width
|
||||||
|
mipmap: true
|
||||||
|
smooth: false
|
||||||
|
source: root.profileStore.getQrCodeSource(root.profileStore.pubkey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusTabBar {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: column.anchors.leftMargin
|
||||||
|
Layout.rightMargin: column.anchors.rightMargin
|
||||||
|
bottomPadding: -4
|
||||||
|
|
||||||
|
StatusTabButton {
|
||||||
|
leftPadding: 0
|
||||||
|
width: implicitWidth
|
||||||
|
text: qsTr("Tokens")
|
||||||
|
}
|
||||||
|
StatusTabButton {
|
||||||
|
width: implicitWidth
|
||||||
|
text: qsTr("NFTs")
|
||||||
|
}
|
||||||
|
StatusTabButton {
|
||||||
|
width: implicitWidth
|
||||||
|
text: qsTr("Communities")
|
||||||
|
}
|
||||||
|
StatusTabButton {
|
||||||
|
width: implicitWidth
|
||||||
|
text: qsTr("Accounts")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusDialogBackground {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: -column.spacing
|
||||||
|
Layout.preferredHeight: 300
|
||||||
|
color: Theme.palette.baseColor4
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
height: parent.radius
|
||||||
|
color: parent.color
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
text: qsTr("More content to appear here soon...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,484 +0,0 @@
|
||||||
import QtQuick 2.13
|
|
||||||
import QtQuick.Controls 2.13
|
|
||||||
import QtQuick.Layouts 1.13
|
|
||||||
import QtGraphicalEffects 1.13
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
import shared 1.0
|
|
||||||
import shared.popups 1.0
|
|
||||||
import shared.stores 1.0
|
|
||||||
import shared.views.chat 1.0
|
|
||||||
import shared.controls.chat 1.0
|
|
||||||
import shared.panels 1.0
|
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import StatusQ.Popups 0.1
|
|
||||||
|
|
||||||
import "../panels"
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property Popup parentPopup
|
|
||||||
|
|
||||||
property var profileStore
|
|
||||||
property var contactsStore
|
|
||||||
|
|
||||||
|
|
||||||
property string userPublicKey: profileStore.pubkey
|
|
||||||
property string userDisplayName: profileStore.displayName
|
|
||||||
property string userName: profileStore.username
|
|
||||||
property string userNickname: profileStore.details.localNickname
|
|
||||||
property string userEnsName: profileStore.ensName
|
|
||||||
property string userIcon: profileStore.profileLargeImage
|
|
||||||
property string userBio: profileStore.bio
|
|
||||||
property string userSocialLinks: profileStore.socialLinksJson
|
|
||||||
property string text: ""
|
|
||||||
|
|
||||||
property bool userIsEnsVerified: profileStore.details.ensVerified
|
|
||||||
property bool userIsBlocked: profileStore.details.isBlocked
|
|
||||||
property bool isCurrentUser: profileStore.pubkey === userPublicKey
|
|
||||||
property bool isAddedContact: false
|
|
||||||
|
|
||||||
property int userTrustStatus: Constants.trustStatus.unknown
|
|
||||||
property int outgoingVerificationStatus: Constants.verificationStatus.unverified
|
|
||||||
|
|
||||||
property string challenge: ""
|
|
||||||
property string response: ""
|
|
||||||
|
|
||||||
property bool userIsUntrustworthy: false
|
|
||||||
property bool userTrustIsUnknown: false
|
|
||||||
property bool isContact: false
|
|
||||||
property bool isVerificationSent: false
|
|
||||||
property bool isVerified: false
|
|
||||||
property bool isTrusted: false
|
|
||||||
property bool hasReceivedVerificationRequest: false
|
|
||||||
|
|
||||||
property bool showRemoveVerified: false
|
|
||||||
property bool showVerifyIdentitySection: false
|
|
||||||
property bool showVerificationPendingSection: false
|
|
||||||
property bool showIdentityVerified: false
|
|
||||||
property bool showIdentityVerifiedUntrustworthy: false
|
|
||||||
|
|
||||||
property string verificationChallenge: ""
|
|
||||||
property string verificationResponse: ""
|
|
||||||
property string verificationResponseDisplayName: ""
|
|
||||||
property string verificationResponseIcon: ""
|
|
||||||
property string verificationRequestedAt: ""
|
|
||||||
property string verificationRepliedAt: ""
|
|
||||||
|
|
||||||
readonly property alias qrCodePopup: qrCodePopup
|
|
||||||
readonly property alias unblockContactConfirmationDialog: unblockContactConfirmationDialog
|
|
||||||
readonly property alias blockContactConfirmationDialog: blockContactConfirmationDialog
|
|
||||||
readonly property alias removeContactConfirmationDialog: removeContactConfirmationDialog
|
|
||||||
readonly property alias wizardAnimation: wizardAnimation
|
|
||||||
readonly property alias challengeTxt: challengeTxt
|
|
||||||
readonly property alias stepsListModel: stepsListModel
|
|
||||||
readonly property alias nicknamePopup: nicknamePopup
|
|
||||||
|
|
||||||
readonly property int animationDuration: 500
|
|
||||||
|
|
||||||
signal contactUnblocked(publicKey: string)
|
|
||||||
signal contactBlocked(publicKey: string)
|
|
||||||
signal contactAdded(publicKey: string)
|
|
||||||
signal contactRemoved(publicKey: string)
|
|
||||||
signal nicknameEdited(publicKey: string)
|
|
||||||
|
|
||||||
objectName: "profileView"
|
|
||||||
implicitWidth: modalContent.implicitWidth
|
|
||||||
implicitHeight: modalContent.implicitHeight
|
|
||||||
|
|
||||||
color: Theme.palette.statusAppLayout.backgroundColor
|
|
||||||
radius: 8
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
readonly property string subTitle: root.userIsEnsVerified ? root.userName : Utils.getElidedCompressedPk(userPublicKey)
|
|
||||||
readonly property int subTitleElide: Text.ElideMiddle
|
|
||||||
}
|
|
||||||
|
|
||||||
SequentialAnimation {
|
|
||||||
id: wizardAnimation
|
|
||||||
ScriptAction {
|
|
||||||
id: step1
|
|
||||||
property int loadingTime: 0
|
|
||||||
Behavior on loadingTime { NumberAnimation { duration: animationDuration }}
|
|
||||||
onLoadingTimeChanged: {
|
|
||||||
if (isVerificationSent) {
|
|
||||||
stepsListModel.setProperty(1, "loadingTime", step1.loadingTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
script: {
|
|
||||||
step1.loadingTime = animationDuration;
|
|
||||||
stepsListModel.setProperty(0, "loadingTime", step1.loadingTime);
|
|
||||||
|
|
||||||
if (isVerificationSent) {
|
|
||||||
stepsListModel.setProperty(0, "stepCompleted", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PauseAnimation {
|
|
||||||
duration: animationDuration + 100
|
|
||||||
}
|
|
||||||
ScriptAction {
|
|
||||||
id: step2
|
|
||||||
property int loadingTime: 0
|
|
||||||
Behavior on loadingTime { NumberAnimation { duration: animationDuration } }
|
|
||||||
onLoadingTimeChanged: {
|
|
||||||
if (isVerificationSent && !!verificationResponse) {
|
|
||||||
stepsListModel.setProperty(2, "loadingTime", step2.loadingTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
script: {
|
|
||||||
if (isVerificationSent && !!verificationChallenge) {
|
|
||||||
step2.loadingTime = animationDuration;
|
|
||||||
if (isVerificationSent && !!verificationResponse) {
|
|
||||||
stepsListModel.setProperty(1, "stepCompleted", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PauseAnimation {
|
|
||||||
duration: animationDuration + 100
|
|
||||||
}
|
|
||||||
ScriptAction {
|
|
||||||
script: {
|
|
||||||
if (outgoingVerificationStatus === Constants.verificationStatus.trusted) {
|
|
||||||
stepsListModel.setProperty(2, "stepCompleted", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: modalContent
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: 32
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfileHeader {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
displayName: root.userDisplayName
|
|
||||||
pubkey: root.userPublicKey
|
|
||||||
icon: root.isCurrentUser ? root.profileStore.profileLargeImage : root.userIcon
|
|
||||||
trustStatus: root.userTrustStatus
|
|
||||||
isContact: root.isContact
|
|
||||||
store: root.profileStore
|
|
||||||
isCurrentUser: root.isCurrentUser
|
|
||||||
userIsEnsVerified: root.userIsEnsVerified
|
|
||||||
|
|
||||||
displayNameVisible: false
|
|
||||||
displayNamePlusIconsVisible: true
|
|
||||||
pubkeyVisibleWithCopy: true
|
|
||||||
pubkeyVisible: false
|
|
||||||
imageSize: ProfileHeader.ImageSize.Middle
|
|
||||||
editImageButtonVisible: root.isCurrentUser
|
|
||||||
onEditClicked: {
|
|
||||||
if(!isCurrentUser){
|
|
||||||
nicknamePopup.open()
|
|
||||||
} else {
|
|
||||||
Global.openEditDisplayNamePopup()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusBanner {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: root.userIsBlocked
|
|
||||||
type: StatusBanner.Type.Danger
|
|
||||||
statusText: qsTr("Blocked")
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfileBioSocialsPanel {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
bio: root.userBio
|
|
||||||
userSocialLinksJson: root.userSocialLinks
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusDescriptionListItem {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: !showVerifyIdentitySection && !showVerificationPendingSection && !showIdentityVerified
|
|
||||||
title: qsTr("Chat key")
|
|
||||||
subTitle: Utils.getCompressedPk(root.userPublicKey)
|
|
||||||
subTitleComponent.elide: Text.ElideMiddle
|
|
||||||
subTitleComponent.width: 320
|
|
||||||
subTitleComponent.font.family: Theme.palette.monoFont.name
|
|
||||||
tooltip.text: qsTr("Copied to clipboard")
|
|
||||||
tooltip.timeout: 1000
|
|
||||||
asset.name: "copy"
|
|
||||||
iconButton.onClicked: {
|
|
||||||
globalUtils.copyToClipboard(subTitle)
|
|
||||||
tooltip.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusDescriptionListItem {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: !showVerifyIdentitySection && !showVerificationPendingSection && !showIdentityVerified
|
|
||||||
title: qsTr("Share Profile URL")
|
|
||||||
subTitle: {
|
|
||||||
let user = ""
|
|
||||||
if (isCurrentUser) {
|
|
||||||
user = root.profileStore.ensName !== "" ? root.profileStore.ensName : StatusQUtils.Utils.elideText(root.profileStore.pubkey, 5)
|
|
||||||
} else if (userIsEnsVerified) {
|
|
||||||
user = userEnsName
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user === ""){
|
|
||||||
user = StatusQUtils.Utils.elideText(userPublicKey, 5)
|
|
||||||
}
|
|
||||||
return Constants.userLinkPrefix + user;
|
|
||||||
}
|
|
||||||
tooltip.text: qsTr("Copied to clipboard")
|
|
||||||
tooltip.timeout: 1000
|
|
||||||
asset.name: "copy"
|
|
||||||
iconButton.onClicked: {
|
|
||||||
let user = ""
|
|
||||||
if (isCurrentUser) {
|
|
||||||
user = root.profileStore.ensName !== "" ? root.profileStore.ensName : root.profileStore.pubkey
|
|
||||||
} else {
|
|
||||||
user = (userEnsName !== "" ? userEnsName : userPublicKey)
|
|
||||||
}
|
|
||||||
root.profileStore.copyToClipboard(Constants.userLinkPrefix + user)
|
|
||||||
tooltip.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: stepsListModel
|
|
||||||
ListElement {description: qsTr("Send Request"); loadingTime: 0; stepCompleted: false}
|
|
||||||
ListElement {description: qsTr("Receive Response"); loadingTime: 0; stepCompleted: false}
|
|
||||||
ListElement {description: qsTr("Confirm Identity"); loadingTime: 0; stepCompleted: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusWizardStepper {
|
|
||||||
id: wizardStepper
|
|
||||||
maxDuration: animationDuration
|
|
||||||
visible: showVerifyIdentitySection || showVerificationPendingSection || showIdentityVerified || showIdentityVerifiedUntrustworthy
|
|
||||||
width: parent.width
|
|
||||||
stepsModel: stepsListModel
|
|
||||||
}
|
|
||||||
|
|
||||||
Separator {
|
|
||||||
visible: wizardStepper.visible
|
|
||||||
implicitHeight: 32
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusBaseText {
|
|
||||||
id: confirmLbl
|
|
||||||
visible: showIdentityVerified
|
|
||||||
text: qsTr("You have confirmed %1's identity. From now on this verification emblem will always be displayed alongside %1's nickname.").arg(userDisplayName)
|
|
||||||
font.pixelSize: Style.current.additionalTextSize
|
|
||||||
horizontalAlignment : Text.AlignHCenter
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.preferredWidth: 363
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusBaseText {
|
|
||||||
id: confirmUntrustworthyLbl
|
|
||||||
visible: showIdentityVerifiedUntrustworthy
|
|
||||||
text: qsTr("You have marked %1 as Untrustworthy. From now on this Untrustworthy emblem will always be displayed alongside %1's nickname.").arg(userDisplayName)
|
|
||||||
font.pixelSize: Style.current.additionalTextSize
|
|
||||||
horizontalAlignment : Text.AlignHCenter
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.preferredWidth: 363
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
visible: checkboxIcon.visible || dangerIcon.visible
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: visible ? 16 : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusRoundIcon {
|
|
||||||
id: checkboxIcon
|
|
||||||
visible: confirmLbl.visible
|
|
||||||
asset.name: "checkbox"
|
|
||||||
asset.width: 16
|
|
||||||
asset.height: 16
|
|
||||||
asset.color: Theme.palette.white
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
color: Theme.palette.primaryColor1
|
|
||||||
width: 32
|
|
||||||
height: 32
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusDescriptionListItem {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: !showVerifyIdentitySection && !showVerificationPendingSection && !showIdentityVerified
|
|
||||||
title: root.userIsEnsVerified ? qsTr("ENS username") : qsTr("Username")
|
|
||||||
subTitle: root.userIsEnsVerified ? root.userEnsName : root.userName
|
|
||||||
tooltip.text: qsTr("Copied to clipboard")
|
|
||||||
tooltip.timeout: 1000
|
|
||||||
asset.name: "copy"
|
|
||||||
iconButton.onClicked: {
|
|
||||||
globalUtils.copyToClipboard(subTitle)
|
|
||||||
tooltip.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusRoundIcon {
|
|
||||||
id: dangerIcon
|
|
||||||
visible: confirmUntrustworthyLbl.visible
|
|
||||||
asset.name: "tiny/subtract"
|
|
||||||
asset.width: 5
|
|
||||||
asset.height: 21
|
|
||||||
asset.color: Theme.palette.white
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
color: Theme.palette.dangerColor1
|
|
||||||
width: 32
|
|
||||||
height: 32
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
visible: checkboxIcon.visible || dangerIcon.visible
|
|
||||||
height: visible ? 16 : 0
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusInput {
|
|
||||||
id: challengeTxt
|
|
||||||
visible: showVerifyIdentitySection
|
|
||||||
charLimit: 280
|
|
||||||
input.text: root.challenge
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.rightMargin: d.contentMargins
|
|
||||||
Layout.leftMargin: d.contentMargins
|
|
||||||
input.multiline: true
|
|
||||||
minimumHeight: 152
|
|
||||||
maximumHeight: 152
|
|
||||||
placeholderText: qsTr("Ask a question that only the real %1 will be able to answer e.g. a question about a shared experience, or ask %1 to enter a code or phrase you have sent to them via a different communication channel (phone, post, etc...).").arg(userDisplayName)
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageView {
|
|
||||||
id: challengeMessage
|
|
||||||
visible: root.showVerificationPendingSection
|
|
||||||
Layout.fillWidth: true
|
|
||||||
isMessage: true
|
|
||||||
shouldRepeatHeader: true
|
|
||||||
messageTimestamp: root.verificationRequestedAt
|
|
||||||
senderId: profileStore.pubkey
|
|
||||||
senderDisplayName: userProfile.name
|
|
||||||
senderIcon: userProfile.icon
|
|
||||||
messageText: root.verificationChallenge
|
|
||||||
messageContentType: Constants.messageContentType.messageType
|
|
||||||
placeholderMessage: true
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageView {
|
|
||||||
id: responseMessage
|
|
||||||
visible: root.showVerificationPendingSection && !!root.verificationResponse
|
|
||||||
Layout.fillWidth: true
|
|
||||||
isMessage: true
|
|
||||||
shouldRepeatHeader: true
|
|
||||||
messageTimestamp: root.verificationRepliedAt
|
|
||||||
senderId: root.userPublicKey
|
|
||||||
senderDisplayName: root.verificationResponseDisplayName
|
|
||||||
senderIcon: root.verificationResponseIcon
|
|
||||||
messageText: root.verificationResponse
|
|
||||||
messageContentType: Constants.messageContentType.messageType
|
|
||||||
placeholderMessage: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
visible: waitingForText.visible
|
|
||||||
height: 32
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusBaseText {
|
|
||||||
id: waitingForText
|
|
||||||
visible: showVerificationPendingSection && !verificationResponse
|
|
||||||
text: qsTr("Waiting for %1's response...").arg(userIsEnsVerified ? userEnsName : userDisplayName)
|
|
||||||
font.pixelSize: Style.current.additionalTextSize
|
|
||||||
horizontalAlignment : Text.AlignHCenter
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.preferredWidth: 363
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
height: 32
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: replace with StatusModal
|
|
||||||
ModalPopup {
|
|
||||||
id: qrCodePopup
|
|
||||||
width: 320
|
|
||||||
height: 320
|
|
||||||
Image {
|
|
||||||
asynchronous: true
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
source: globalUtils.qrCode(userPublicKey)
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
height: 212
|
|
||||||
width: 212
|
|
||||||
mipmap: true
|
|
||||||
smooth: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UnblockContactConfirmationDialog {
|
|
||||||
id: unblockContactConfirmationDialog
|
|
||||||
onUnblockButtonClicked: {
|
|
||||||
root.contactsStore.unblockContact(userPublicKey)
|
|
||||||
unblockContactConfirmationDialog.close();
|
|
||||||
root.contactUnblocked(userPublicKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockContactConfirmationDialog {
|
|
||||||
id: blockContactConfirmationDialog
|
|
||||||
onBlockButtonClicked: {
|
|
||||||
root.contactsStore.blockContact(userPublicKey)
|
|
||||||
blockContactConfirmationDialog.close();
|
|
||||||
root.contactBlocked(userPublicKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfirmationDialog {
|
|
||||||
id: removeContactConfirmationDialog
|
|
||||||
header.title: qsTr("Remove contact")
|
|
||||||
confirmationText: qsTr("Are you sure you want to remove this contact?")
|
|
||||||
onConfirmButtonClicked: {
|
|
||||||
if (isAddedContact) {
|
|
||||||
root.contactsStore.removeContact(userPublicKey);
|
|
||||||
}
|
|
||||||
removeContactConfirmationDialog.close();
|
|
||||||
root.contactRemoved(userPublicKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NicknamePopup {
|
|
||||||
id: nicknamePopup
|
|
||||||
nickname: root.userNickname
|
|
||||||
header.subTitle: d.subTitle
|
|
||||||
header.subTitleElide: d.subTitleElide
|
|
||||||
onEditDone: {
|
|
||||||
if (root.userNickname !== newNickname)
|
|
||||||
{
|
|
||||||
root.userNickname = newNickname;
|
|
||||||
root.contactsStore.changeContactNickname(userPublicKey, newNickname);
|
|
||||||
}
|
|
||||||
root.nicknameEdited(userPublicKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -106,7 +106,7 @@ StatusPopupMenu {
|
||||||
|
|
||||||
property var emojiReactionsReactedByUser: []
|
property var emojiReactionsReactedByUser: []
|
||||||
|
|
||||||
signal openProfileClicked(string publicKey, string state)
|
signal openProfileClicked(string publicKey)
|
||||||
signal pinMessage(string messageId)
|
signal pinMessage(string messageId)
|
||||||
signal unpinMessage(string messageId)
|
signal unpinMessage(string messageId)
|
||||||
signal pinnedMessagesLimitReached(string messageId)
|
signal pinnedMessagesLimitReached(string messageId)
|
||||||
|
@ -238,7 +238,7 @@ StatusPopupMenu {
|
||||||
id: viewProfileAction
|
id: viewProfileAction
|
||||||
enabled: root.isProfile && !root.pinnedPopup
|
enabled: root.isProfile && !root.pinnedPopup
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.openProfileClicked(root.selectedUserPublicKey, "")
|
root.openProfileClicked(root.selectedUserPublicKey)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,8 +256,7 @@ 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,
|
Global.openContactRequestPopup(root.selectedUserPublicKey)
|
||||||
Constants.profilePopupStates.contactRequest)
|
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,8 +269,7 @@ StatusPopupMenu {
|
||||||
&& root.outgoingVerificationStatus === Constants.verificationStatus.unverified
|
&& root.outgoingVerificationStatus === Constants.verificationStatus.unverified
|
||||||
&& !root.hasReceivedVerificationRequestFrom
|
&& !root.hasReceivedVerificationRequestFrom
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.openProfileClicked(root.selectedUserPublicKey,
|
Global.openSendIDRequestPopup(root.selectedUserPublicKey)
|
||||||
Constants.profilePopupStates.verifyIdentity)
|
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,11 +286,9 @@ StatusPopupMenu {
|
||||||
|| root.isVerificationRequestSent)
|
|| root.isVerificationRequestSent)
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (hasReceivedVerificationRequestFrom) {
|
if (hasReceivedVerificationRequestFrom) {
|
||||||
root.openProfileClicked(root.selectedUserPublicKey,
|
Global.openIncomingIDRequestPopup(root.selectedUserPublicKey)
|
||||||
Constants.profilePopupStates.respondToPendingRequest)
|
|
||||||
} else if (root.isVerificationRequestSent) {
|
} else if (root.isVerificationRequestSent) {
|
||||||
root.openProfileClicked(root.selectedUserPublicKey,
|
Global.openOutgoingIDRequestPopup(root.selectedUserPublicKey)
|
||||||
Constants.profilePopupStates.showVerificationPendingSection)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
root.close()
|
root.close()
|
||||||
|
@ -304,8 +300,8 @@ StatusPopupMenu {
|
||||||
icon.name: "edit_pencil"
|
icon.name: "edit_pencil"
|
||||||
enabled: root.isProfile && !root.isMe
|
enabled: root.isProfile && !root.isMe
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.openProfileClicked(root.selectedUserPublicKey,
|
Global.openNicknamePopupRequested(root.selectedUserPublicKey, d.contactDetails.localNickname,
|
||||||
Constants.profilePopupStates.openNickname)
|
"%1 (%2)".arg(root.selectedUserDisplayName).arg(Utils.getElidedCompressedPk(root.selectedUserPublicKey)))
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +310,7 @@ StatusPopupMenu {
|
||||||
text: qsTr("Unblock User")
|
text: qsTr("Unblock User")
|
||||||
icon.name: "remove-circle"
|
icon.name: "remove-circle"
|
||||||
enabled: root.isProfile && !root.isMe && root.isBlockedContact
|
enabled: root.isProfile && !root.isMe && root.isBlockedContact
|
||||||
onTriggered: root.store.contactsStore.unblockContact(root.selectedUserPublicKey)
|
onTriggered: Global.unblockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuSeparator {
|
StatusMenuSeparator {
|
||||||
|
@ -344,7 +340,7 @@ StatusPopupMenu {
|
||||||
icon.name: "cancel"
|
icon.name: "cancel"
|
||||||
type: StatusMenuItem.Type.Danger
|
type: StatusMenuItem.Type.Danger
|
||||||
enabled: root.isProfile && !root.isMe && !root.isBlockedContact
|
enabled: root.isProfile && !root.isMe && !root.isBlockedContact
|
||||||
onTriggered: root.store.contactsStore.blockContact(root.selectedUserPublicKey)
|
onTriggered: Global.blockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenuItem {
|
StatusMenuItem {
|
||||||
|
|
|
@ -7,7 +7,7 @@ TransactionPreview 1.0 TransactionPreview.qml
|
||||||
TransactionSigner 1.0 TransactionSigner.qml
|
TransactionSigner 1.0 TransactionSigner.qml
|
||||||
TransactionStackView 1.0 TransactionStackView.qml
|
TransactionStackView 1.0 TransactionStackView.qml
|
||||||
PasswordView 1.0 PasswordView.qml
|
PasswordView 1.0 PasswordView.qml
|
||||||
ProfileView 1.0 ProfileView.qml
|
ProfileDialogView 1.0 ProfileDialogView.qml
|
||||||
AssetsView 1.0 AssetsView.qml
|
AssetsView 1.0 AssetsView.qml
|
||||||
HistoryView 1.0 HistoryView.qml
|
HistoryView 1.0 HistoryView.qml
|
||||||
AssetsDetailView 1.0 AssetsDetailView.qml
|
AssetsDetailView 1.0 AssetsDetailView.qml
|
||||||
|
|
|
@ -280,16 +280,6 @@ 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 {
|
||||||
|
@ -567,7 +557,7 @@ QtObject {
|
||||||
readonly property int maxNumberOfPins: 3
|
readonly property int maxNumberOfPins: 3
|
||||||
|
|
||||||
readonly property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".svg", ".gif"]
|
readonly property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".svg", ".gif"]
|
||||||
readonly property var acceptedDragNDropImageExtensions: [".png", ".jpg", ".jpeg", ".heif", "tif", ".tiff"]
|
readonly property var acceptedDragNDropImageExtensions: [".png", ".jpg", ".jpeg", ".heif", ".tif", ".tiff"]
|
||||||
|
|
||||||
readonly property string mentionSpanTag: `<span style="background-color: ${Style.current.mentionBgColor};"><a style="color:${Style.current.mentionColor};text-decoration:none" href='http://'>`
|
readonly property string mentionSpanTag: `<span style="background-color: ${Style.current.mentionBgColor};"><a style="color:${Style.current.mentionColor};text-decoration:none" href='http://'>`
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,16 @@ Item {
|
||||||
signal openCreateChatView()
|
signal openCreateChatView()
|
||||||
signal closeCreateChatView()
|
signal closeCreateChatView()
|
||||||
|
|
||||||
signal openProfilePopupRequested(string publicKey, var parentPopup, string state)
|
signal openProfilePopupRequested(string publicKey, var parentPopup)
|
||||||
|
|
||||||
|
signal openNicknamePopupRequested(string publicKey, string nickname, string subtitle)
|
||||||
|
signal nickNameChanged(string publicKey, string nickname)
|
||||||
|
|
||||||
|
signal blockContactRequested(string publicKey, string contactName)
|
||||||
|
signal contactBlocked(string publicKey)
|
||||||
|
signal unblockContactRequested(string publicKey, string contactName)
|
||||||
|
signal contactUnblocked(string publicKey)
|
||||||
|
|
||||||
signal openChangeProfilePicPopup()
|
signal openChangeProfilePicPopup()
|
||||||
signal displayToastMessage(string title, string subTitle, string icon, bool loading, int ephNotifType, string url)
|
signal displayToastMessage(string title, string subTitle, string icon, bool loading, int ephNotifType, string url)
|
||||||
signal openEditDisplayNamePopup()
|
signal openEditDisplayNamePopup()
|
||||||
|
@ -50,7 +59,7 @@ Item {
|
||||||
userPublicKey: publicKey,
|
userPublicKey: publicKey,
|
||||||
userDisplayName: contactDetails.displayName,
|
userDisplayName: contactDetails.displayName,
|
||||||
userIcon: contactDetails.largeImage,
|
userIcon: contactDetails.largeImage,
|
||||||
userIsEnsVerified: contactDetails.ensVerified,
|
userIsEnsVerified: contactDetails.ensVerified
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +70,56 @@ Item {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function openProfilePopup(publicKey, parentPopup, state = "") {
|
function openSendIDRequestPopup(publicKey) {
|
||||||
openProfilePopupRequested(publicKey, parentPopup, state);
|
const contactDetails = Utils.getContactDetailsAsJson(publicKey);
|
||||||
|
return openPopup(sendIDRequestPopupComponent, {
|
||||||
|
userPublicKey: publicKey,
|
||||||
|
userDisplayName: contactDetails.displayName,
|
||||||
|
userIcon: contactDetails.largeImage,
|
||||||
|
userIsEnsVerified: contactDetails.ensVerified,
|
||||||
|
"header.title": qsTr("Verify %1's Identity").arg(contactDetails.displayName),
|
||||||
|
challengeText: qsTr("Ask a question that only the real %1 will be able to answer e.g. a question about a shared experience, or ask %1 to enter a code or phrase you have sent to them via a different communication channel (phone, post, etc...).").arg(contactDetails.displayName),
|
||||||
|
buttonText: qsTr("Send verification request")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function openIncomingIDRequestPopup(publicKey) {
|
||||||
|
try {
|
||||||
|
const request = appMain.rootStore.profileSectionStore.contactsStore.getVerificationDetailsFromAsJson(publicKey)
|
||||||
|
return 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openOutgoingIDRequestPopup(publicKey) {
|
||||||
|
try {
|
||||||
|
const verificationDetails = appMain.rootStore.profileSectionStore.contactsStore.getSentVerificationDetailsAsJson(publicKey)
|
||||||
|
return openPopup(contactOutgoingVerificationRequestPopupComponent, {
|
||||||
|
userPublicKey: publicKey,
|
||||||
|
verificationStatus: verificationDetails.requestStatus,
|
||||||
|
verificationChallenge: verificationDetails.challenge,
|
||||||
|
verificationResponse: verificationDetails.response,
|
||||||
|
verificationResponseDisplayName: verificationDetails.displayName,
|
||||||
|
verificationResponseIcon: verificationDetails.icon,
|
||||||
|
verificationRequestedAt: verificationDetails.requestedAt,
|
||||||
|
verificationRepliedAt: verificationDetails.repliedAt
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error getting or parsing verification data", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openProfilePopup(publicKey, parentPopup) {
|
||||||
|
openProfilePopupRequested(publicKey, parentPopup)
|
||||||
}
|
}
|
||||||
|
|
||||||
function openActivityCenterPopup() {
|
function openActivityCenterPopup() {
|
||||||
|
@ -145,9 +202,45 @@ Item {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
rootStore: appMain.rootStore
|
rootStore: appMain.rootStore
|
||||||
contactsStore: appMain.rootStore.contactStore
|
contactsStore: appMain.rootStore.contactStore
|
||||||
onClosed: {
|
onClosed: destroy()
|
||||||
destroy()
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: sendIDRequestPopupComponent
|
||||||
|
SendContactRequestModal {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
onAccepted: appMain.rootStore.profileSectionStore.contactsStore.sendVerificationRequest(userPublicKey, message)
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: contactVerificationRequestPopupComponent
|
||||||
|
ContactVerificationRequestPopup {
|
||||||
|
onResponseSent: {
|
||||||
|
appMain.rootStore.profileSectionStore.contactsStore.acceptVerificationRequest(senderPublicKey, response)
|
||||||
}
|
}
|
||||||
|
onVerificationRefused: {
|
||||||
|
appMain.rootStore.profileSectionStore.contactsStore.declineVerificationRequest(senderPublicKey)
|
||||||
|
}
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: contactOutgoingVerificationRequestPopupComponent
|
||||||
|
OutgoingContactVerificationRequestPopup {
|
||||||
|
onVerificationRequestCanceled: {
|
||||||
|
appMain.rootStore.profileSectionStore.contactsStore.cancelVerificationRequest(userPublicKey)
|
||||||
|
}
|
||||||
|
onUntrustworthyVerified: {
|
||||||
|
appMain.rootStore.profileSectionStore.contactsStore.verifiedUntrustworthy(userPublicKey)
|
||||||
|
}
|
||||||
|
onTrustedVerified: {
|
||||||
|
appMain.rootStore.profileSectionStore.contactsStore.verifiedTrusted(userPublicKey)
|
||||||
|
}
|
||||||
|
onClosed: destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -580,7 +580,7 @@ QtObject {
|
||||||
|
|
||||||
function isEnsVerified(publicKey, getVerificationRequest=true) {
|
function isEnsVerified(publicKey, getVerificationRequest=true) {
|
||||||
if (!publicKey)
|
if (!publicKey)
|
||||||
return false
|
return false
|
||||||
return getContactDetailsAsJson(publicKey, getVerificationRequest).ensVerified
|
return getContactDetailsAsJson(publicKey, getVerificationRequest).ensVerified
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|