This repository has been archived on 2021-06-24. You can view files and clone it, but cannot push or open issues or pull requests.
ui/qml/panes/ProfileAddEditPane.qml

505 lines
16 KiB
QML

import QtGraphicalEffects 1.0
import QtQuick 2.7
import QtQuick.Controls 2.13
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
import QtQuick.Window 2.11
import "../opaque" as Opaque
import "../opaque/theme"
import "../opaque/fonts"
// import "../styles"
Opaque.Flickable {
id: flickRoot
Layout.fillHeight: true
Layout.fillWidth: true
contentWidth: rc.width
contentHeight: rc.height
readonly property string mode_add: "add"
readonly property string mode_edit: "edit"
property string mode // edit or add
property string onion
property string tag
property bool deleting
property bool changingPassword
function reset() {
flickRoot.contentY = 0
mode = mode_add
reset_errors()
txtProfileName.text = ""
changingPassword = false
txtPassword1.text = ""
txtPassword2.text = ""
deleting = false
deleteConfirmLabel.color = Theme.mainTextColor
txtCurrentPassword.text = ""
nameLabel.text = ""
portrait.performTransform = true
portrait.source = "core/account_circle-24px_negative_space.webp"
tag = ""
confirmDeleteTxt.text = ""
radioUsePassword.checked = true
}
function reset_errors() {
txtPassword1.error = false
txtPassword2.error = false
txtCurrentPassword.error = false
passwordErrorLabel.visible = false
passwordChangeErrorLabel.visible = false
confirmDeleteTxt.error = false
}
function load(userOnion, name, userTag, image) {
reset()
mode = mode_edit
tag = userTag
onion = userOnion
txtPassword1.text = ""
txtPassword2.text = ""
onionLabel.text = onion
txtProfileName.text = name
nameLabel.text = name
portrait.performTransform = false
portrait.source = image
if (tag == "v1-defaultPassword" || tag == "v1-default-password") {
radioNoPassword.checked = true
} else {
radioUsePassword.checked = true
}
}
Opaque.ResponsiveContainer {
id: rc
width: flickRoot.width
Rectangle {
id: leftCol
color: Theme.backgroundPaneColor
//height:
implicitHeight: leftContents.height
height: implicitHeight
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
Column {
id: leftContents
anchors.horizontalCenter: parent.horizontalCenter
Layout.alignment : Qt.AlignHCenter + Qt.AlignTop
width: 400 * gcd.themeScale
spacing: 10 * gcd.themeScale
Opaque.ScalingLabel {
anchors.horizontalCenter: parent.horizontalCenter
size: Theme.primaryTextSize
//: New Profile || Edit Profile
text: mode == mode_add ? qsTr("new-profile") : qsTr("edit-profile")
bold: true
}
// spacing
Rectangle {
height: 30 * gcd.themeScale
width: 100
color: Theme.backgroundPaneColor
}
Opaque.Portrait {
id: portrait
size: 250
Layout.preferredHeight: size
anchors.horizontalCenter: parent.horizontalCenter
portraitBorderColor: Theme.portraitOnlineBorderColor
portraitColor: Theme.portraitOnlineBackgroundColor
badgeColor: Theme.portraitProfileBadgeColor
performTransform: true
overlayColor: Theme.portraitProfileBadgeTextColor
badgeContent: Image {// Profle Type
id: profiletype
source: radioUsePassword.checked ? gcd.assetPath + "core/lock-24px.webp" : gcd.assetPath + "core/lock-open-24px.webp"
height: 40 * gcd.themeScale
width: height
}
}
Opaque.ScalingLabel {
id: nameLabel
visible: mode == mode_edit
anchors.horizontalCenter: parent.horizontalCenter
size: Theme.primaryTextSize
bold: true
}
// spacing
Rectangle {
visible: mode == mode_edit
height: 10 * gcd.themeScale
width: 100
color: Theme.backgroundPaneColor
}
Opaque.ScalingLabel {
visible: mode == mode_edit
anchors.horizontalCenter: parent.horizontalCenter
size: Theme.secondaryTextSize
//: Send this address to peers you want to connect with
text: qsTr("profile-oniblon-label")
}
Opaque.ButtonTextField {
id: onionLabel
anchors.horizontalCenter: parent.horizontalCenter
visible: mode == mode_edit
readOnly: true
width: leftCol.width - (40*gcd.themeScale)
button_text: qsTr("copy-btn")
dropShadowColor: Theme.dropShadowPaneColor
onClicked: {
//: notification: copied to clipboard
gcd.popup(qsTr("copied-to-clipboard-notification"))
onionLabel.selectAll()
onionLabel.copy()
}
}
// spacing
Rectangle {
visible: radioNoPassword.checked
height: 30 * gcd.themeScale
width: 100
color: Theme.backgroundPaneColor
}
Rectangle {
width: parent.width
height: noPasswordLabel.visible ? noPasswordLabel.height : 0
color: leftCol.color
anchors.horizontalCenter: parent.horizontalCenter
Opaque.ScalingLabel {
id: noPasswordLabel
width: parent.width
size: Theme.secondaryTextSize
anchors.horizontalCenter: parent.horizontalCenter
//: Not using a password on this account means that all data stored locally will not be encrypted
text: qsTr("no-password-warning")
visible: radioNoPassword.checked
}
}
// spacing
Rectangle {
height: 30 * gcd.themeScale
width: 100
color: Theme.backgroundPaneColor
}
}
}
Rectangle {
id: rightCol
color: Theme.backgroundPaneColor
anchors.topMargin: 80 * gcd.themeScale
height: rightContents.height
implicitHeight: height
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
Column {
id: rightContents
anchors.horizontalCenter: parent.horizontalCenter
Layout.alignment : Qt.AlignHCenter + Qt.AlignTop
width: 400 * gcd.themeScale
spacing: 40 * gcd.themeScale
Opaque.UnderlineTextField {
id: txtProfileName
backgroundColor: Theme.backgroundPaneColor
width: parent.width - (40*gcd.themeScale)
anchors.horizontalCenter: parent.horizontalCenter
//: Your Display Name
placeholderText: qsTr("your-display-name")
}
RowLayout {
visible: (mode == mode_add) || (tag == "v1-defaultPassword")
width: parent.width - (40*gcd.themeScale)
anchors.horizontalCenter: parent.horizontalCenter
//id: radioButtons
Opaque.RadioButton {
id: radioUsePassword
checked: true
//: Password
text: qsTr("radio-use-password")
onClicked: {
changingPassword = true
}
}
Opaque.RadioButton {
id: radioNoPassword
//: Unencrypted (No password)
text: qsTr("radio-no-password")
onClicked: {
changingPassword = true
}
}
}
Opaque.UnderlineTextField {
id: txtCurrentPassword
visible: radioUsePassword.checked && (mode == mode_edit) && tag != "v1-defaultPassword"
backgroundColor: Theme.backgroundPaneColor
width: parent.width - (40*gcd.themeScale)
anchors.horizontalCenter: parent.horizontalCenter
//: Current Password
placeholderText: qsTr("current-password-label") + ":"
echoMode: TextInput.Password
}
Opaque.UnderlineTextField {
id: txtPassword1
visible: radioUsePassword.checked
backgroundColor: Theme.backgroundPaneColor
width: parent.width - (40*gcd.themeScale)
anchors.horizontalCenter: parent.horizontalCenter
echoMode: TextInput.Password
//: Password
placeholderText: qsTr("password1-label")
onTextEdited: {
changingPassword = true
}
}
Opaque.UnderlineTextField {
id: txtPassword2
visible: radioUsePassword.checked
backgroundColor: Theme.backgroundPaneColor
width: parent.width - (40*gcd.themeScale)
anchors.horizontalCenter: parent.horizontalCenter
//: Reenter password
placeholderText: qsTr("password2-label")
echoMode: TextInput.Password
}
Opaque.ScalingLabel {
id: passwordErrorLabel
anchors.horizontalCenter: parent.horizontalCenter
size: Theme.secondaryTextSize
//: Passwords do not match
text: qsTr("password-error-match")
visible: false
color: Theme.textfieldErrorColor
}
Opaque.ScalingLabel {
id: passwordChangeErrorLabel
anchors.horizontalCenter: parent.horizontalCenter
size: Theme.secondaryTextSize
//: Error changing password: Supplied password rejected
text: qsTr("password-change-error")
visible: false
color: Theme.textfieldErrorColor
}
Opaque.Button { // ADD or SAVE button
height: Theme.primaryTextSize * 1.5
anchors.horizontalCenter: parent.horizontalCenter
//: Create || Save
text: mode == mode_add ? qsTr("create-profile-btn") : qsTr("save-profile-btn")
onClicked: {
reset_errors()
if (mode == mode_add) {
if (txtPassword1.text != txtPassword2.text) {
passwordErrorLabel.visible = true
txtPassword1.error = true
txtPassword2.error = true
} else {
gcd.createProfile(txtProfileName.text, radioNoPassword.checked, txtPassword1.text)
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
}
} else {
console.log("Save clicked")
gcd.updateNick(onion, txtProfileName.text)
if (changingPassword) {
console.log("changingPassword")
if (txtPassword1.text != txtPassword2.text) {
passwordErrorLabel.visible = true
txtPassword1.error = true
txtPassword2.error = true
} else {
console.log("gcd.changePassword")
gcd.changePassword(onion, txtCurrentPassword.text, txtPassword1.text, radioNoPassword.checked)
}
} else {
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
}
}
}
}
// ***** Delete button and confirm flow *****
Opaque.Button {
anchors.right: parent.right
anchors.rightMargin: 20 * gcd.themeScale
//: Delete Profile
text: qsTr("delete-profile-btn")
//icon: "regular/trash-alt"
visible: mode == mode_edit
height: Theme.primaryTextSize * 1.5
onClicked: {
deleting = true
}
}
Opaque.ScalingLabel {
id: deleteConfirmLabel
size: Theme.secondaryTextSize
anchors.right: parent.right
anchors.rightMargin: 20 * gcd.themeScale
//: Type DELETE to confirm
text: qsTr("delete-confirm-label")+ ":"
visible: deleting
}
Opaque.UnderlineTextField {
id: confirmDeleteTxt
visible: deleting
backgroundColor: Theme.backgroundPaneColor
width: 300 * gcd.themeScale
anchors.right: parent.right
anchors.rightMargin: 20 * gcd.themeScale
placeholderText: qsTr("delete-confirm-label")
}
Opaque.Button {
id: confirmDeleteBtn
height: Theme.primaryTextSize * 1.5
anchors.right: parent.right
anchors.rightMargin: 20 * gcd.themeScale
//: Really Delete Profile
text: qsTr("delete-profile-confirm-btn")
visible: deleting
onClicked: {
//: DELETE
if (confirmDeleteTxt.text == qsTr("delete-confirm-text")) {
deleteConfirmLabel.color = Theme.mainTextColor
gcd.deleteProfile(onion)
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
} else {
confirmDeleteTxt.error = true
deleteConfirmLabel.color = Theme.textfieldErrorColor
}
}
}
// spacing
Rectangle {
height: 30 * gcd.themeScale
width: 100
color: Theme.backgroundPaneColor
}
}
}
Connections {
target: gcd
onChangePasswordResponse: function(error) {
if (!error) {
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
} else {
passwordChangeErrorLabel.visible = true
txtCurrentPassword.error = true
}
}
}
}
}