fix(@desktop): Send contact request from profile

Close #6125
This commit is contained in:
MishkaRogachev 2022-06-20 14:54:17 +03:00 committed by Iuri Matias
parent 58eff9adf2
commit 95326620c3
3 changed files with 276 additions and 200 deletions

View File

@ -182,6 +182,7 @@ Item {
property Component profilePopupComponent: ProfilePopup { property Component profilePopupComponent: ProfilePopup {
id: profilePopup id: profilePopup
anchors.centerIn: parent
profileStore: appMain.rootStore.profileSectionStore.profileStore profileStore: appMain.rootStore.profileSectionStore.profileStore
contactsStore: appMain.rootStore.profileSectionStore.contactsStore contactsStore: appMain.rootStore.profileSectionStore.contactsStore
onClosed: { onClosed: {

View File

@ -17,7 +17,6 @@ import StatusQ.Popups 0.1
StatusModal { StatusModal {
id: popup id: popup
anchors.centerIn: parent
property Popup parentPopup property Popup parentPopup
@ -32,8 +31,6 @@ StatusModal {
property string userIcon: "" property string userIcon: ""
property string text: "" property string text: ""
readonly property int innerMargin: 20
property bool userIsEnsVerified: false property bool userIsEnsVerified: false
property bool userIsBlocked: false property bool userIsBlocked: false
property bool isCurrentUser: false property bool isCurrentUser: false
@ -45,7 +42,6 @@ StatusModal {
signal contactUnblocked(publicKey: string) signal contactUnblocked(publicKey: string)
signal contactBlocked(publicKey: string) signal contactBlocked(publicKey: string)
signal contactAdded(publicKey: string)
function openPopup(publicKey, openNicknamePopup) { function openPopup(publicKey, openNicknamePopup) {
// All this should be improved more, but for now we leave it like this. // All this should be improved more, but for now we leave it like this.
@ -70,10 +66,17 @@ StatusModal {
} }
} }
header.title: userDisplayName header.title: userDisplayName + qsTr("'s Profile")
header.subTitle: userIsEnsVerified ? userName : Utils.getElidedCompressedPk(userPublicKey) header.subTitle: userIsEnsVerified ? userName : Utils.getElidedCompressedPk(userPublicKey)
header.subTitleElide: Text.ElideMiddle header.subTitleElide: Text.ElideMiddle
QtObject {
id: d
readonly property int contentSpacing: 5
readonly property int contentMargins: 16
}
headerActionButton: StatusFlatRoundButton { headerActionButton: StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary type: StatusFlatRoundButton.Type.Secondary
width: 32 width: 32
@ -85,219 +88,227 @@ StatusModal {
onClicked: contentItem.qrCodePopup.open() onClicked: contentItem.qrCodePopup.open()
} }
contentItem: Item { Component {
width: popup.width id: contactTopComponent
height: modalContent.height
ProfileHeader {
displayName: popup.userDisplayName
pubkey: popup.userPublicKey
icon: popup.isCurrentUser ? popup.profileStore.icon : popup.userIcon
displayNameVisible: false
pubkeyVisible: false
compact: false
imageOverlay: Item {
visible: popup.isCurrentUser
StatusFlatRoundButton {
width: 24
height: 24
anchors {
right: parent.right
bottom: parent.bottom
rightMargin: -8
}
type: StatusFlatRoundButton.Type.Secondary
icon.name: "pencil"
icon.color: Theme.palette.directColor1
icon.width: 12.5
icon.height: 12.5
onClicked: Global.openChangeProfilePicPopup()
}
}
}
}
contentItem: ColumnLayout {
id: modalContent
property alias qrCodePopup: qrCodePopup property alias qrCodePopup: qrCodePopup
property alias unblockContactConfirmationDialog: unblockContactConfirmationDialog property alias unblockContactConfirmationDialog: unblockContactConfirmationDialog
property alias blockContactConfirmationDialog: blockContactConfirmationDialog property alias blockContactConfirmationDialog: blockContactConfirmationDialog
property alias removeContactConfirmationDialog: removeContactConfirmationDialog property alias removeContactConfirmationDialog: removeContactConfirmationDialog
Column { anchors.left: parent.left
id: modalContent anchors.right: parent.right
anchors.top: parent.top anchors.margins: d.contentMargins
width: parent.width spacing: d.contentSpacing
clip: true
Item { Item {
height: 16 implicitHeight: d.contentSpacing
width: parent.width Layout.fillWidth: true
}
ProfileHeader {
width: parent.width
displayName: popup.userDisplayName
pubkey: popup.userPublicKey
icon: popup.isCurrentUser ? popup.profileStore.icon : popup.userIcon
displayNameVisible: false
pubkeyVisible: false
compact: false
imageOverlay: Item {
visible: popup.isCurrentUser
StatusFlatRoundButton {
width: 24
height: 24
anchors {
right: parent.right
bottom: parent.bottom
rightMargin: -8
}
type: StatusFlatRoundButton.Type.Secondary
icon.name: "pencil"
icon.color: Theme.palette.directColor1
icon.width: 12.5
icon.height: 12.5
onClicked: Global.openChangeProfilePicPopup()
}
}
}
StatusBanner {
width: parent.width
visible: popup.userIsBlocked
type: StatusBanner.Type.Danger
statusText: qsTr("Blocked")
}
Item {
height: 16
width: parent.width
}
StatusDescriptionListItem {
title: userIsEnsVerified ?
qsTr("ENS username") :
qsTr("Username")
subTitle: userIsEnsVerified ? userEnsName : userName
tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
globalUtils.copyToClipboard(subTitle)
tooltip.visible = !tooltip.visible
}
width: parent.width
}
StatusDescriptionListItem {
title: qsTr("Chat key")
subTitle: Utils.getCompressedPk(userPublicKey)
subTitleComponent.elide: Text.ElideMiddle
subTitleComponent.width: 320
subTitleComponent.font.family: Theme.palette.monoFont.name
tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
globalUtils.copyToClipboard(subTitle)
tooltip.visible = !tooltip.visible
}
width: parent.width
}
StatusDescriptionListItem {
title: qsTr("Share Profile URL")
subTitle: {
let user = ""
if (isCurrentUser) {
user = popup.profileStore.ensName !== "" ? popup.profileStore.ensName :
(popup.profileStore.pubkey.substring(0, 5) + "..." + popup.profileStore.pubkey.substring(popup.profileStore.pubkey.length - 5))
} else if (userIsEnsVerified) {
user = userEnsName
}
if (user === ""){
user = userPublicKey.substr(0, 4) + "..." + userPublicKey.substr(userPublicKey.length - 5)
}
return Constants.userLinkPrefix + user;
}
tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
let user = ""
if (isCurrentUser) {
user = popup.profileStore.ensName !== "" ? popup.profileStore.ensName : popup.profileStore.pubkey
} else {
user = (userEnsName !== "" ? userEnsName : userPublicKey)
}
popup.profileStore.copyToClipboard(Constants.userLinkPrefix + user)
tooltip.visible = !tooltip.visible
}
width: parent.width
}
StatusDescriptionListItem {
visible: !isCurrentUser
title: qsTr("Chat settings")
subTitle: qsTr("Nickname")
value: userNickname ? userNickname : qsTr("None")
sensor.enabled: true
sensor.onClicked: {
nicknamePopup.open()
}
width: parent.width
}
Item {
visible: !isCurrentUser
width: parent.width
height: 16
}
} }
// TODO: replace with StatusModal Loader {
ModalPopup { sourceComponent: contactTopComponent
id: qrCodePopup Layout.fillWidth: true
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 { StatusBanner {
id: unblockContactConfirmationDialog visible: popup.userIsBlocked
onUnblockButtonClicked: { type: StatusBanner.Type.Danger
popup.contactsStore.unblockContact(userPublicKey) statusText: qsTr("Blocked")
unblockContactConfirmationDialog.close(); Layout.fillWidth: true
popup.close()
popup.contactUnblocked(userPublicKey)
}
} }
BlockContactConfirmationDialog { StatusDescriptionListItem {
id: blockContactConfirmationDialog title: userIsEnsVerified ?
onBlockButtonClicked: { qsTr("ENS username") :
popup.contactsStore.blockContact(userPublicKey) qsTr("Username")
blockContactConfirmationDialog.close(); subTitle: userIsEnsVerified ? userEnsName : userName
popup.close() tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
popup.contactBlocked(userPublicKey) iconButton.onClicked: {
globalUtils.copyToClipboard(subTitle)
tooltip.visible = !tooltip.visible
} }
Layout.fillWidth: true
} }
ConfirmationDialog { StatusDescriptionListItem {
id: removeContactConfirmationDialog title: qsTr("Chat key")
header.title: qsTr("Remove contact") subTitle: Utils.getCompressedPk(userPublicKey)
confirmationText: qsTr("Are you sure you want to remove this contact?") subTitleComponent.elide: Text.ElideMiddle
onConfirmButtonClicked: { subTitleComponent.width: 320
if (isAddedContact) { subTitleComponent.font.family: Theme.palette.monoFont.name
popup.contactsStore.removeContact(userPublicKey); tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
globalUtils.copyToClipboard(subTitle)
tooltip.visible = !tooltip.visible
}
Layout.fillWidth: true
}
StatusDescriptionListItem {
title: qsTr("Share Profile URL")
subTitle: {
let user = ""
if (isCurrentUser) {
user = popup.profileStore.ensName !== "" ? popup.profileStore.ensName :
(popup.profileStore.pubkey.substring(0, 5) + "..." + popup.profileStore.pubkey.substring(popup.profileStore.pubkey.length - 5))
} else if (userIsEnsVerified) {
user = userEnsName
} }
removeContactConfirmationDialog.close();
popup.close(); if (user === ""){
user = userPublicKey.substr(0, 4) + "..." + userPublicKey.substr(userPublicKey.length - 5)
}
return Constants.userLinkPrefix + user;
} }
tooltip.text: qsTr("Copy to clipboard")
icon.name: "copy"
iconButton.onClicked: {
let user = ""
if (isCurrentUser) {
user = popup.profileStore.ensName !== "" ? popup.profileStore.ensName : popup.profileStore.pubkey
} else {
user = (userEnsName !== "" ? userEnsName : userPublicKey)
}
popup.profileStore.copyToClipboard(Constants.userLinkPrefix + user)
tooltip.visible = !tooltip.visible
}
Layout.fillWidth: true
} }
NicknamePopup { StatusDescriptionListItem {
id: nicknamePopup visible: !isCurrentUser
nickname: popup.userNickname title: qsTr("Chat settings")
header.subTitle: popup.header.subTitle subTitle: qsTr("Nickname")
header.subTitleElide: popup.header.subTitleElide value: userNickname ? userNickname : qsTr("None")
onEditDone: { sensor.enabled: true
if(popup.userNickname !== newNickname) sensor.onClicked: {
{ nicknamePopup.open()
popup.userNickname = newNickname;
popup.contactsStore.changeContactNickname(userPublicKey, newNickname);
}
popup.close()
} }
Layout.fillWidth: true
} }
} }
// TODO: replace with StatusStackModal
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: {
popup.contactsStore.unblockContact(userPublicKey)
unblockContactConfirmationDialog.close();
popup.close()
popup.contactUnblocked(userPublicKey)
}
}
BlockContactConfirmationDialog {
id: blockContactConfirmationDialog
onBlockButtonClicked: {
popup.contactsStore.blockContact(userPublicKey)
blockContactConfirmationDialog.close();
popup.close()
popup.contactBlocked(userPublicKey)
}
}
ConfirmationDialog {
id: removeContactConfirmationDialog
header.title: qsTr("Remove contact")
confirmationText: qsTr("Are you sure you want to remove this contact?")
onConfirmButtonClicked: {
if (isAddedContact) {
popup.contactsStore.removeContact(userPublicKey);
}
removeContactConfirmationDialog.close();
popup.close();
}
}
NicknamePopup {
id: nicknamePopup
nickname: popup.userNickname
header.subTitle: popup.header.subTitle
header.subTitleElide: popup.header.subTitleElide
onEditDone: {
if(popup.userNickname !== newNickname)
{
popup.userNickname = newNickname;
popup.contactsStore.changeContactNickname(userPublicKey, newNickname);
}
popup.close()
}
}
// TODO: replace with StatusStackModal
SendContactRequestModal {
id: sendContactRequestModal
anchors.centerIn: parent
width: popup.width
height: popup.height
visible: false
header.title: qsTr("Send Contact Request to") + " " + userDisplayName
topComponent: contactTopComponent
onAccepted: popup.contactsStore.sendContactRequest(userPublicKey, message)
onClosed: popup.close()
}
rightButtons: [ rightButtons: [
StatusFlatButton { StatusFlatButton {
text: userIsBlocked ? text: userIsBlocked ?
@ -328,13 +339,9 @@ StatusModal {
}, },
StatusButton { StatusButton {
text: qsTr("Add to contacts") text: qsTr("Send Contact Request")
visible: !userIsBlocked && !isAddedContact visible: !userIsBlocked && !isAddedContact
onClicked: { onClicked: sendContactRequestModal.open()
popup.contactsStore.sendContactRequest(userPublicKey);
popup.contactAdded(userPublicKey);
popup.close();
}
} }
] ]
} }

View File

@ -0,0 +1,68 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import utils 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1
import StatusQ.Popups 0.1
StatusModal {
id: root
signal accepted(string message)
property alias topComponent: topComponentLoader.sourceComponent
QtObject {
id: d
readonly property int maxMsgLength: 280
readonly property int minMsgLength: 1
readonly property int msgHeight: 152
readonly property int contentSpacing: 5
readonly property int contentMargins: 16
}
contentItem: ColumnLayout {
id: content
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: d.contentMargins
spacing: d.contentSpacing
Loader {
id: topComponentLoader
Layout.fillWidth: true
}
StatusInput {
id: messageInput
charLimit: d.maxMsgLength
input.placeholderText: qsTr("Say who you are / why you want to become a contact...")
input.multiline: true
input.implicitHeight: d.msgHeight
input.verticalAlignment: TextEdit.AlignTop
validators: StatusMinLengthValidator {
minLength: d.minMsgLength
errorMessage: Utils.getErrorMessage(messageInput.errors, qsTr("who are you"))
}
validationMode: StatusInput.ValidationMode.Always
Layout.fillWidth: true
}
}
rightButtons: StatusButton {
enabled: messageInput.valid
text: qsTr("Send Contact Request")
onClicked: {
root.accepted(messageInput.text);
root.close();
}
}
}