fix(profile-settings): Add usage dirty values for preview and load image profile on save

Closes: #7920 #7917
This commit is contained in:
Boris Melnik 2022-11-08 21:30:50 +03:00
parent 7e7daa56e1
commit 13acb5730d
12 changed files with 90 additions and 12 deletions

View File

@ -73,30 +73,44 @@ QtObject:
proc getSocialLinksJson(self: View): string {.slot.} =
$(%*self.socialLinksModel.items)
proc temporarySocialLinksJsonChanged*(self: View) {.signal.}
proc getTemporarySocialLinksJson(self: View): string {.slot.} =
$(%*self.temporarySocialLinksModel.items)
QtProperty[string] socialLinksJson:
read = getSocialLinksJson
notify = socialLinksJsonChanged
QtProperty[string] temporarySocialLinksJson:
read = getTemporarySocialLinksJson
notify = temporarySocialLinksJsonChanged
QtProperty[bool] socialLinksDirty:
read = areSocialLinksDirty
notify = socialLinksDirtyChanged
proc createCustomLink(self: View, text: string, url: string) {.slot.} =
self.temporarySocialLinksModel.appendItem(initSocialLinkItem(text, url, LinkType.Custom))
self.temporarySocialLinksJsonChanged()
self.socialLinksDirtyChanged()
proc removeCustomLink(self: View, uuid: string) {.slot.} =
if (self.temporarySocialLinksModel.removeItem(uuid)):
self.temporarySocialLinksJsonChanged()
self.socialLinksDirtyChanged()
proc updateLink(self: View, uuid: string, text: string, url: string): bool {.slot.} =
if (self.temporarySocialLinksModel.updateItem(uuid, text, url)):
self.temporarySocialLinksJsonChanged()
self.socialLinksDirtyChanged()
proc resetSocialLinks(self: View): bool {.slot.} =
if (self.areSocialLinksDirty()):
self.temporarySocialLinksModel.setItems(self.socialLinksModel.items)
self.socialLinksDirtyChanged()
self.temporarySocialLinksJsonChanged()
proc saveSocialLinks(self: View): bool {.slot.} =
result = self.delegate.saveSocialLinks()
@ -104,6 +118,7 @@ QtObject:
self.socialLinksModel.setItems(self.temporarySocialLinksModel.items)
self.socialLinksDirtyChanged()
self.socialLinksJsonChanged()
self.temporarySocialLinksJsonChanged()
proc bioChanged*(self: View) {.signal.}
proc getBio(self: View): string {.slot.} =

View File

@ -42,6 +42,13 @@ Loader {
color: root.asset.imgIsIdenticon ?
Theme.palette.statusRoundedImage.backgroundColor :
root.asset.bgColor
image.fillMode: root.asset.cropRect ? Image.PreserveAspectCrop
: Image.PreserveAspectFit
image.scale: root.asset.scale
image.x: root.asset.cropRectangle ? -root.asset.cropRectangle.x
: 0
image.y: root.asset.cropRectangle ? -root.asset.cropRectangle.y
: 0
}
Loader {
anchors.centerIn: parent

View File

@ -34,4 +34,7 @@ QtObject {
property bool isImage: false
property int imgStatus
property bool imgIsIdenticon: false
// crop
property rect cropRect
}

View File

@ -79,6 +79,8 @@ SettingsContentBase {
Layout.fillWidth: true
profileStore: root.profileStore
contactsStore: root.contactsStore
dirtyValues: settingsView.dirtyValues
dirty: settingsView.dirty
}
}

View File

@ -8,6 +8,8 @@ import StatusQ.Core.Theme 0.1
Item {
property alias profileStore: profilePreview.profileStore
property alias contactsStore: profilePreview.contactsStore
property alias dirtyValues: profilePreview.dirtyValues
property alias dirty: profilePreview.dirty
implicitHeight: profilePreview.implicitHeight
+ profilePreview.anchors.topMargin

View File

@ -28,10 +28,18 @@ ColumnLayout {
property ProfileStore profileStore
property WalletStore walletStore
property QtObject dirtyValues: QtObject {
property string displayName: descriptionPanel.displayName.text
property string bio: descriptionPanel.bio.text
property bool biomentricValue: biometricsSwitch.checked
property url profileLargeImage: profileHeader.icon
}
readonly property bool dirty: descriptionPanel.displayName.text !== profileStore.displayName ||
descriptionPanel.bio.text !== profileStore.bio ||
profileStore.socialLinksDirty ||
biometricsSwitch.checked != biometricsSwitch.currentStoredValue
biometricsSwitch.checked != biometricsSwitch.currentStoredValue ||
profileHeader.icon !== profileStore.profileLargeImage
readonly property bool valid: !!descriptionPanel.displayName.text && descriptionPanel.displayName.valid
@ -41,17 +49,28 @@ ColumnLayout {
profileStore.resetSocialLinks()
descriptionPanel.reevaluateSocialLinkInputs()
biometricsSwitch.checked = Qt.binding(() => { return biometricsSwitch.currentStoredValue })
profileHeader.icon = Qt.binding(() => { return profileStore.profileLargeImage })
}
function save() {
profileStore.setDisplayName(descriptionPanel.displayName.text)
profileStore.setBio(descriptionPanel.bio.text)
profileStore.saveSocialLinks()
if (profileHeader.icon === "") {
root.profileStore.removeImage()
} else {
profileStore.uploadImage(profileHeader.icon,
profileHeader.cropRect.x.toFixed(),
profileHeader.cropRect.y.toFixed(),
(profileHeader.cropRect.x + profileHeader.cropRect.width).toFixed(),
(profileHeader.cropRect.y + profileHeader.cropRect.height).toFixed());
}
if (biometricsSwitch.checked)
Global.openPopup(storePasswordModal)
else
localAccountSettings.storeToKeychainValue = Constants.keychain.storedValue.never;
reset()
}
function offerToStorePassword(password, runStoreToKeyChainPopup)
@ -64,6 +83,7 @@ ColumnLayout {
}
ProfileHeader {
id: profileHeader
Layout.fillWidth: true
Layout.leftMargin: Style.current.padding
Layout.rightMargin: Style.current.padding

View File

@ -145,7 +145,7 @@ Item {
}
onOpenChangeProfilePicPopup: {
var popup = changeProfilePicComponent.createObject(appMain);
var popup = changeProfilePicComponent.createObject(appMain, {callback: cb});
popup.chooseImageToCrop();
}
onOpenBackUpSeedPopup: Global.openPopup(backupSeedModalComponent)
@ -236,6 +236,15 @@ Item {
title: qsTr("Profile Picture")
acceptButtonText: qsTr("Make this my Profile Pic")
onImageCropped: {
if (callback) {
callback(image,
cropRect.x.toFixed(),
cropRect.y.toFixed(),
(cropRect.x + cropRect.width).toFixed(),
(cropRect.y + cropRect.height).toFixed())
return
}
appMain.rootStore.profileSectionStore.profileStore.uploadImage(image,
cropRect.x.toFixed(),
cropRect.y.toFixed(),

View File

@ -27,6 +27,7 @@ Item {
property bool isContact: false
property bool isCurrentUser
property bool userIsEnsVerified
property rect cropRect: undefined
property int imageSize: ProfileHeader.ImageSize.Compact
property bool displayNameVisible: true
@ -82,9 +83,11 @@ Item {
imageWidth: d.getSize(36, 64, 160)
imageHeight: imageWidth
showRing: !root.userIsEnsVerified
cropRect: root.cropRect
}
StatusRoundButton {
id: editButton
visible: root.editImageButtonVisible
anchors.bottom: userImage.bottom
anchors.right: userImage.right
@ -102,7 +105,12 @@ Item {
if (!!root.store.profileLargeImage)
imageEditMenu.popup(this, mouse.x, mouse.y);
else
Global.openChangeProfilePicPopup();
Global.openChangeProfilePicPopup(tempIcon);
}
function tempIcon(image, aX, aY, bX, bY) {
root.icon = image
root.cropRect = Qt.rect(aX, aY, bX - aX, bY - aY)
}
}
}
@ -211,14 +219,14 @@ Item {
text: qsTr("Upload a file")
icon.name: "download"
iconRotation: 180
onTriggered: Global.openChangeProfilePicPopup()
onTriggered: Global.openChangeProfilePicPopup(editButton.tempIcon)
}
StatusMenuItem {
text: qsTr("Remove image")
type: StatusMenuItem.Danger
icon.name: "delete"
onTriggered: root.store.removeImage()
onTriggered: root.icon = ""
}
}
}

View File

@ -20,6 +20,8 @@ Loader {
property bool interactive: true
property bool disabled: false
property rect cropRect: undefined
property int colorId: Utils.colorIdForPubkey(pubkey)
property var colorHash: Utils.getColorHashAsJson(pubkey)
@ -34,6 +36,7 @@ Loader {
name: root.image
charactersLen: 2
isImage: true
cropRect: root.cropRect
}
ringSettings {
ringSpecModel: root.showRing ? root.colorHash : undefined

View File

@ -14,6 +14,7 @@ Item {
id: root
objectName: "imageCropWorkflow"
property var callback: null
property alias aspectRatio: imageCropper.aspectRatio
property alias windowStyle: imageCropper.windowStyle
/*required*/ property string imageFileDialogTitle: ""

View File

@ -27,6 +27,9 @@ Pane {
property var profileStore
property var contactsStore
property QtObject dirtyValues: null
property bool dirty: false
signal closeRequested()
padding: 0
@ -249,9 +252,11 @@ Pane {
UserImage {
Layout.alignment: Qt.AlignTop
objectName: "ProfileDialog_userImage"
name: d.userDisplayName
name: root.dirty ? root.dirtyValues.displayName
: d.userDisplayName
pubkey: root.publicKey
image: d.contactDetails.largeImage
image: root.dirty ? root.dirtyValues.profileLargeImage
: d.contactDetails.largeImage
interactive: false
imageWidth: 80
imageHeight: imageWidth
@ -275,7 +280,8 @@ Pane {
font.bold: true
font.pixelSize: 22
elide: Text.ElideRight
text: d.userDisplayName
text: root.dirty ? root.dirtyValues.displayName
: d.userDisplayName
}
StatusContactVerificationIcons {
id: verificationIcons
@ -543,8 +549,10 @@ Pane {
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
bio: root.dirty ? root.dirtyValues.bio
: d.contactDetails.bio
userSocialLinksJson: root.dirty ? root.profileStore.temporarySocialLinksJson
: d.contactDetails.socialLinks
}
GridLayout {

View File

@ -44,7 +44,7 @@ QtObject {
signal unblockContactRequested(string publicKey, string contactName)
signal contactUnblocked(string publicKey)
signal openChangeProfilePicPopup()
signal openChangeProfilePicPopup(var cb)
signal displayToastMessage(string title, string subTitle, string icon, bool loading, int ephNotifType, string url)
signal openEditDisplayNamePopup()
signal openActivityCenterPopupRequested