505 lines
16 KiB
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|