fix(Profile): Added menu to remove profile image

This commit is contained in:
Igor Sirotin 2022-08-08 00:05:25 +03:00 committed by Igor Sirotin
parent e0cd28d5f4
commit f60dacc45d
6 changed files with 27 additions and 446 deletions

View File

@ -1,115 +0,0 @@
import QtQuick 2.13
import QtQuick.Dialogs 1.3
import utils 1.0
import StatusQ.Controls 0.1
import shared 1.0
import shared.panels 1.0
import shared.popups 1.0
// TODO: replace with StatusModal
ModalPopup {
id: popup
title: qsTr("Profile picture")
property var profileStore
property string selectedImage // selectedImage is for us to be able to analyze it before setting it as current
property string uploadError
property url largeImage: popup.profileStore.profileLargeImage
property bool hasIdentityImage: !!popup.profileStore.profileLargeImage
onClosed: {
destroy()
}
onSelectedImageChanged: {
if (!selectedImage) {
return
}
cropImageModal.open()
}
Item {
anchors.fill: parent
RoundedImage {
id: profilePic
source: popup.largeImage
width: 160
height: 160
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
border.width: 1
border.color: Style.current.border
onClicked: imageDialog.open()
}
StyledText {
visible: !!uploadError
text: uploadError
anchors.left: parent.left
anchors.right: parent.right
anchors.top: profilePic.bottom
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 13
wrapMode: Text.WordWrap
anchors.topMargin: 13
font.weight: Font.Thin
color: Style.current.danger
}
ImageCropperModal {
id: cropImageModal
selectedImage: popup.selectedImage
ratio: "1:1"
onCropFinished: {
popup.uploadError = popup.profileStore.uploadImage(selectedImage, aX, aY, bX, bY)
}
}
}
footer: Item {
width: parent.width
height: uploadBtn.height
StatusFlatButton {
visible: popup.hasIdentityImage
type: StatusBaseButton.Type.Danger
text: qsTr("Remove")
anchors.right: uploadBtn.left
anchors.rightMargin: Style.current.padding
anchors.bottom: parent.bottom
onClicked: {
popup.uploadError = popup.profileStore.removeImage()
}
}
StatusButton {
id: uploadBtn
text: qsTr("Upload")
anchors.right: parent.right
anchors.bottom: parent.bottom
onClicked: {
imageDialog.open()
}
FileDialog {
id: imageDialog
title: qsTr("Please choose an image")
folder: shortcuts.pictures
nameFilters: [
qsTr("Image files (*.jpg *.jpeg *.png)")
]
onAccepted: {
selectedImage = imageDialog.fileUrls[0]
}
}
}
}
}

View File

@ -58,6 +58,8 @@ ColumnLayout {
Layout.leftMargin: Style.current.padding Layout.leftMargin: Style.current.padding
Layout.rightMargin: Style.current.padding Layout.rightMargin: Style.current.padding
store: root.profileStore
displayName: profileStore.name displayName: profileStore.name
pubkey: profileStore.pubkey pubkey: profileStore.pubkey
icon: profileStore.profileLargeImage icon: profileStore.profileLargeImage

View File

@ -1,213 +0,0 @@
import QtQuick 2.13
import "../panels"
import utils 1.0
Item {
id: root
property Image image
property alias selectorRectangle: selectorRectangle
property string ratio: ""
property var splitRatio: !!ratio ? ratio.split(":") : null
property int widthRatio: !!ratio ? parseInt(splitRatio[0]) : -1
property int heightRatio: !!ratio ? parseInt(splitRatio[1]) : -1
property bool settingCorners: false
property int draggedCorner: 0
property bool ready: false
readonly property int topLeft: 0
readonly property int topRight: 1
readonly property int bottomLeft: 2
readonly property int bottomRight: 3
width: image.width
height: image.height
Rectangle {
id: selectorRectangle
visible: false
x: 0
y: 0
border.width: 2
border.color: Style.current.orange
color: Style.current.transparent
function fitRatio(makeBigger) {
if (!!ratio) {
if ((makeBigger && selectorRectangle.width < selectorRectangle.height) || (!makeBigger && selectorRectangle.width > selectorRectangle.height)) {
selectorRectangle.width = (selectorRectangle.height/heightRatio) * widthRatio
} else {
selectorRectangle.height = (selectorRectangle.width/widthRatio) * heightRatio
}
}
}
function initialSetup() {
selectorRectangle.width = image.width
selectorRectangle.height = image.height
fitRatio()
topLeftCorner.x = 0
topLeftCorner.y = 0
topRightCorner.x = selectorRectangle.width - topRightCorner.width
topRightCorner.y = 0
bottomLeftCorner.x = 0
bottomLeftCorner.y = selectorRectangle.height - topRightCorner.height
bottomRightCorner.x = selectorRectangle.width - topRightCorner.width
bottomRightCorner.y = selectorRectangle.height - topRightCorner.height
}
function adjustRectangleSize() {
if (!selectorRectangle.visible) {
return
}
selectorRectangle.width = bottomRightCorner.x + bottomRightCorner.width - topLeftCorner.x
selectorRectangle.height = bottomRightCorner.y + bottomRightCorner.height - topLeftCorner.y
selectorRectangle.x = topLeftCorner.x
selectorRectangle.y = topLeftCorner.y
if (!!ratio) {
// FIXME with a ratio that is not 1:1, the rectangle can go out of bounds
fitRatio()
switch(draggedCorner) {
case topLeft:
selectorRectangle.x = topLeftCorner.x
selectorRectangle.y = topLeftCorner.y
break
case topRight:
selectorRectangle.x = topRightCorner.x - selectorRectangle.width + topRightCorner.width
selectorRectangle.y = topRightCorner.y
break
case bottomLeft:
selectorRectangle.x = bottomLeftCorner.x
selectorRectangle.y = bottomLeftCorner.y - selectorRectangle.height + bottomLeftCorner.height
break
case bottomRight:
selectorRectangle.x = bottomRightCorner.x - selectorRectangle.width + bottomRightCorner.width
selectorRectangle.y = bottomRightCorner.y - selectorRectangle.height + bottomRightCorner.height
break
}
}
}
Connections {
target: image
onStatusChanged: {
if (image.status === Image.Ready) {
selectorRectangle.initialSetup()
selectorRectangle.visible = true
root.ready = true
}
}
}
}
function putCorners() {
settingCorners = true
topLeftCorner.x = selectorRectangle.x
topLeftCorner.y = selectorRectangle.y
topRightCorner.x = selectorRectangle.x + selectorRectangle.width - topRightCorner.width
topRightCorner.y = selectorRectangle.y
bottomLeftCorner.x = selectorRectangle.x
bottomLeftCorner.y = selectorRectangle.y + selectorRectangle.height - topRightCorner.height
bottomRightCorner.x = selectorRectangle.x + selectorRectangle.width - topRightCorner.width
bottomRightCorner.y = selectorRectangle.y + selectorRectangle.height - topRightCorner.height
settingCorners = false
}
// Size calculations are only done on top-left and bottom-right, because the other two corners follow them
CropCornerRectangle {
id: topLeftCorner
onXChanged: {
if (settingCorners) return
if (x < 0) x = 0
if (x > topRightCorner.x - width) x = topRightCorner.x - width
bottomLeftCorner.x = x
selectorRectangle.adjustRectangleSize()
}
onYChanged: {
if (settingCorners) return
if (y < 0) y = 0
if (y > bottomRightCorner.y - height) y = bottomRightCorner.y - height
topRightCorner.y = y
selectorRectangle.adjustRectangleSize()
}
onPressed: {
draggedCorner = topLeft
}
onReleased: {
putCorners()
}
}
CropCornerRectangle {
id: topRightCorner
onXChanged: {
if (settingCorners) return
bottomRightCorner.x = x
}
onYChanged: {
if (settingCorners) return
topLeftCorner.y = y
}
onPressed: {
draggedCorner = topRight
}
onReleased: {
putCorners()
}
}
CropCornerRectangle {
id: bottomLeftCorner
onXChanged: {
if (settingCorners) return
topLeftCorner.x = x
}
onYChanged: {
if (settingCorners) return
bottomRightCorner.y = y
}
onPressed: {
draggedCorner = bottomLeft
}
onReleased: {
putCorners()
}
}
CropCornerRectangle {
id: bottomRightCorner
onXChanged: {
if (settingCorners) return
if (x < topLeftCorner.x + topLeftCorner.width) x = topLeftCorner.x + topLeftCorner.width
if (x > image.width - width) x = image.width - width
topRightCorner.x = x
selectorRectangle.adjustRectangleSize()
}
onYChanged: {
if (settingCorners) return
if (y < topRightCorner.y + topRightCorner.height) y = topRightCorner.y + topRightCorner.height
if (y > image.height - height) y = image.height - height
bottomLeftCorner.y = y
selectorRectangle.adjustRectangleSize()
}
onPressed: {
draggedCorner = bottomRight
}
onReleased: {
putCorners()
}
}
}

View File

@ -7,6 +7,7 @@ import shared.controls 1.0
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils import StatusQ.Core.Utils 0.1 as StatusQUtils
Item { Item {
@ -94,7 +95,12 @@ Item {
icon.width: d.getSize(8, 12, 20) icon.width: d.getSize(8, 12, 20)
icon.height: d.getSize(8, 12, 20) icon.height: d.getSize(8, 12, 20)
onClicked: Global.openChangeProfilePicPopup() onClicked: {
if (!!root.store.profileLargeImage)
imageEditMenu.popup(this, mouse.x, mouse.y);
else
Global.openChangeProfilePicPopup();
}
} }
} }
@ -210,4 +216,22 @@ Item {
publicKey: root.pubkey publicKey: root.pubkey
} }
} }
StatusPopupMenu {
id: imageEditMenu
StatusMenuItem {
text: qsTr("Upload a file")
icon.name: "download"
iconRotation: 180
onTriggered: Global.openChangeProfilePicPopup()
}
StatusMenuItem {
text: qsTr("Remove image")
type: StatusMenuItem.Danger
icon.name: "delete"
onTriggered: root.store.removeImage()
}
}
} }

View File

@ -1,29 +0,0 @@
import QtQuick 2.13
import utils 1.0
Rectangle {
signal released()
signal pressed()
id: root
width: 25
height: 25
border.width: 2
border.color: Style.current.orange
color: Utils.setColorAlpha(Style.current.orange, 0.5)
Drag.active: dragArea.drag.active
MouseArea {
id: dragArea
property int oldX
property int oldY
anchors.fill: parent
drag.target: parent
cursorShape: Qt.PointingHandCursor
onReleased: root.released()
onPressed: root.pressed()
}
}

View File

@ -1,88 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import utils 1.0
import StatusQ.Controls 0.1
import "../controls"
import "."
// TODO: replace with StatusModal
ModalPopup {
property string selectedImage
property string ratio: "1:1"
property int aX: 0
property int aY: 0
property int bX: 0
property int bY: 0
signal cropFinished(aX: int, aY: int, bX: int, bY: int)
id: cropImageModal
width: image.width + 50
height: image.height + 170
title: qsTr("Crop your image (optional)")
Image {
id: image
width: 400
source: cropImageModal.selectedImage
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
}
ImageCropper {
id: imageCropper
x: image.x
y: image.y
image: image
ratio: cropImageModal.ratio
onReadyChanged: {
if (ready) {
// cropImageModal.calculateCrop()
cropImageModal.aX = Qt.binding(function() {
const aXPercent = imageCropper.selectorRectangle.x / image.width
return Math.round(aXPercent * image.sourceSize.width)
})
cropImageModal.aY = Qt.binding(function() {
const aYPercent = imageCropper.selectorRectangle.y / image.height
return Math.round(aYPercent * image.sourceSize.height)
})
cropImageModal.bX = Qt.binding(function() {
const bXPercent = (imageCropper.selectorRectangle.x + imageCropper.selectorRectangle.width) / image.width
return Math.round(bXPercent * image.sourceSize.width)
})
cropImageModal.bY = Qt.binding(function() {
const bYPercent = (imageCropper.selectorRectangle.y + imageCropper.selectorRectangle.height) / image.height
return Math.round(bYPercent * image.sourceSize.height)
})
}
}
}
footer: StatusButton {
id: doneBtn
text: qsTr("Finish")
anchors.right: parent.right
anchors.bottom: parent.bottom
onClicked: {
const aXPercent = imageCropper.selectorRectangle.x / image.width
const aYPercent = imageCropper.selectorRectangle.y / image.height
const bXPercent = (imageCropper.selectorRectangle.x + imageCropper.selectorRectangle.width) / image.width
const bYPercent = (imageCropper.selectorRectangle.y + imageCropper.selectorRectangle.height) / image.height
const aX = Math.round(aXPercent * image.sourceSize.width)
const aY = Math.round(aYPercent * image.sourceSize.height)
const bX = Math.round(bXPercent * image.sourceSize.width)
const bY = Math.round(bYPercent * image.sourceSize.height)
cropImageModal.cropFinished(aX, aY, bX, bY)
cropImageModal.close()
}
}
}