Rename EditAccount to AccountSettings

This commit is contained in:
miruka
2019-11-10 09:07:35 -04:00
parent e3165d0a7c
commit 484e9e595d
10 changed files with 15 additions and 16 deletions

View File

@@ -0,0 +1,62 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import "../../Base"
import "../../utils.js" as Utils
HPage {
id: accountSettings
property int avatarPreferredSize: 256
property string userId: ""
readonly property bool ready:
accountInfo !== "waiting" && Boolean(accountInfo.profile_updated)
readonly property var accountInfo: Utils.getItem(
modelSources["Account"] || [], "user_id", userId
) || "waiting"
property string headerName: ready ? accountInfo.display_name : userId
hideHeaderUnderHeight: avatarPreferredSize
headerLabel.text: qsTr("Account settings for %1").arg(
Utils.coloredNameHtml(headerName, userId)
)
HSpacer {}
Repeater {
id: repeater
model: ["Profile.qml", "Encryption.qml"]
Rectangle {
color: ready ? theme.controls.box.background : "transparent"
Behavior on color { HColorAnimation {} }
Layout.alignment: Qt.AlignCenter
Layout.topMargin: header.visible || index > 0 ? theme.spacing : 0
Layout.bottomMargin:
header.visible || index < repeater.count - 1? theme.spacing : 0
Layout.maximumWidth: Math.min(parent.width, 640)
Layout.preferredWidth:
pageLoader.isWide ? parent.width : avatarPreferredSize
Layout.preferredHeight: childrenRect.height
HLoader {
anchors.centerIn: parent
width: ready ? parent.width : 96
source: ready ?
modelData :
(modelData == "Profile.qml" ?
"../../Base/HBusyIndicator.qml" : "")
}
}
}
HSpacer {}
}

View File

@@ -0,0 +1,23 @@
import QtQuick 2.12
import "../../Base"
HLoader {
id: encryptionUI
source:
accountInfo.import_error[0] ? "ImportError.qml" :
accountInfo.total_keys_to_import ? "ImportingKeys.qml" :
"ImportExportKeys.qml"
onSourceChanged: animation.running = true
SequentialAnimation {
id: animation
HNumberAnimation {
target: encryptionUI; property: "scale"; to: 0;
}
HNumberAnimation {
target: encryptionUI; property: "scale"; to: 1; overshoot: 3;
}
}
}

View File

@@ -0,0 +1,36 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import "../../Base"
import "../../utils.js" as Utils
HBox {
horizontalSpacing: currentSpacing
verticalSpacing: currentSpacing
buttonModel: [
{ name: "retry", text: qsTr("Retry"), iconName: "retry" },
{ name: "cancel", text: qsTr("Cancel"), iconName: "cancel" },
]
buttonCallbacks: ({
retry: button => {
encryptionUI.importKeys(
accountInfo.import_error[0],
accountInfo.import_error[1],
button,
)
},
cancel: button => { py.callClientCoro(userId, "clear_import_error") },
})
HLabel {
color: theme.colors.errorText
wrapMode: Text.Wrap
text: qsTr("Couldn't import decryption keys file: %1")
.arg(qsTr(accountInfo.import_error[2]))
Layout.fillWidth: true
}
}

View File

@@ -0,0 +1,50 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../../Base"
import "../../utils.js" as Utils
HBox {
horizontalSpacing: currentSpacing
verticalSpacing: currentSpacing
buttonModel: [
{ name: "export", text: qsTr("Export"), iconName: "export-keys"},
{ name: "import", text: qsTr("Import"), iconName: "import-keys"},
]
buttonCallbacks: ({
export: button => {
Utils.makeObject(
"Dialogs/ExportKeys.qml",
accountSettings,
{ userId: accountSettings.userId },
obj => {
button.loading = Qt.binding(() => obj.exporting)
obj.dialog.open()
}
)
},
import: button => {
Utils.makeObject(
"Dialogs/ImportKeys.qml",
accountSettings,
{ userId: accountSettings.userId },
obj => { obj.dialog.open() }
)
},
})
HLabel {
wrapMode: Text.Wrap
text: qsTr(
"The decryption keys for messages you received in encrypted " +
"rooms can be exported to a passphrase-protected file.\n\n" +
"You can then import this file on any Matrix account or " +
"client, to be able to decrypt these messages again."
)
Layout.fillWidth: true
}
}

View File

@@ -0,0 +1,57 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../../Base"
HColumnLayout {
readonly property int progress: accountInfo.importing_key
onProgressChanged: iconAnimation.restart()
HRowLayout {
HIcon {
id: icon
svgName: "import-keys"
Layout.margins: currentSpacing
SequentialAnimation {
id: iconAnimation
HNumberAnimation { target: icon; property: "opacity"; to: 0.6 }
HNumberAnimation { target: icon; property: "opacity"; to: 1 }
}
}
HLabel {
text: qsTr("Importing decryption keys...")
elide: Text.ElideRight
Layout.fillWidth: true
Layout.margins: currentSpacing
Layout.leftMargin: 0
Layout.rightMargin: 0
}
HLabel {
text: progressBar.indeterminate ?
qsTr("Preparing...") :
qsTr("%1/%2")
.arg(Math.ceil(progressBar.value)).arg(progressBar.to)
Layout.margins: currentSpacing
}
}
HProgressBar {
id: progressBar
from: 0
value: progress
to: accountInfo.total_keys_to_import
indeterminate: accountInfo.total_keys_to_import < 0
Behavior on value { HNumberAnimation { factor: 5 } }
Layout.fillWidth: true
}
}

View File

@@ -0,0 +1,221 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import "../../Base"
import "../../Dialogs"
import "../../utils.js" as Utils
HGridLayout {
function applyChanges() {
if (nameField.changed) {
saveButton.nameChangeRunning = true
py.callClientCoro(
userId, "set_displayname", [nameField.field.text], () => {
saveButton.nameChangeRunning = false
accountSettings.headerName =
Qt.binding(() => accountInfo.display_name)
}
)
}
if (aliasField.changed) {
window.settings.writeAliases[userId] = aliasField.field.text
window.settingsChanged()
}
if (avatar.changed) {
saveButton.avatarChangeRunning = true
let path =
Qt.resolvedUrl(avatar.sourceOverride).replace(/^file:/, "")
py.callClientCoro(userId, "set_avatar_from_file", [path], () => {
saveButton.avatarChangeRunning = false
}, (errType, [httpCode]) => {
console.error("Avatar upload failed:", httpCode, errType)
saveButton.avatarChangeRunning = false
})
}
}
function cancelChanges() {
nameField.field.text = accountInfo.display_name
aliasField.field.text = aliasField.currentAlias
fileDialog.selectedFile = ""
fileDialog.file = ""
accountSettings.headerName = Qt.binding(() => accountInfo.display_name)
}
columns: 2
flow: pageLoader.isWide ? GridLayout.LeftToRight : GridLayout.TopToBottom
rowSpacing: currentSpacing
Component.onCompleted: nameField.field.forceActiveFocus()
HUserAvatar {
property bool changed: Boolean(sourceOverride)
id: avatar
clientUserId: accountSettings.userId
userId: accountSettings.userId
displayName: nameField.field.text
mxc: accountInfo.avatar_url
toolTipMxc: ""
sourceOverride: fileDialog.selectedFile || fileDialog.file
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Math.min(flickable.height, avatarPreferredSize)
Layout.preferredHeight: Layout.preferredWidth
Rectangle {
z: 10
visible: opacity > 0
opacity: ! fileDialog.dialog.visible &&
((! avatar.mxc && ! avatar.changed) || avatar.hovered) ?
1 : 0
anchors.fill: parent
color: Utils.hsluv(0, 0, 0,
(! avatar.mxc && overlayHover.hovered) ? 0.8 : 0.7
)
Behavior on opacity { HNumberAnimation {} }
Behavior on color { HColorAnimation {} }
HoverHandler { id: overlayHover }
HColumnLayout {
anchors.centerIn: parent
spacing: currentSpacing
width: parent.width
HIcon {
svgName: "upload-avatar"
colorize: (! avatar.mxc && overlayHover.hovered) ?
theme.colors.accentText : theme.icons.colorize
dimension: 64
Layout.alignment: Qt.AlignCenter
}
Item { Layout.preferredHeight: theme.spacing }
HLabel {
text: avatar.mxc ?
qsTr("Change profile picture") :
qsTr("Upload profile picture")
color: (! avatar.mxc && overlayHover.hovered) ?
theme.colors.accentText : theme.colors.brightText
Behavior on color { HColorAnimation {} }
font.pixelSize: theme.fontSize.big *
avatar.height / avatarPreferredSize
wrapMode: Text.WordWrap
horizontalAlignment: Qt.AlignHCenter
Layout.fillWidth: true
}
}
}
HFileDialogOpener {
id: fileDialog
fileType: HFileDialogOpener.FileType.Images
dialog.title: qsTr("Select profile picture for %1")
.arg(accountInfo.display_name)
}
}
HColumnLayout {
id: profileInfo
spacing: theme.spacing
HColumnLayout {
spacing: theme.spacing
Layout.margins: currentSpacing
HLabel {
text: qsTr("User ID:<br>%1")
.arg(Utils.coloredNameHtml(userId, userId, userId))
textFormat: Text.StyledText
wrapMode: Text.Wrap
Layout.fillWidth: true
}
HLabeledTextField {
property bool changed: field.text != accountInfo.display_name
readonly property string fText: field.text
onFTextChanged: accountSettings.headerName = field.text
id: nameField
label.text: qsTr("Display name:")
field.onAccepted: applyChanges()
Component.onCompleted: field.text = accountInfo.display_name
Keys.onEscapePressed: cancelChanges()
Layout.fillWidth: true
Layout.maximumWidth: 480
}
HLabeledTextField {
property string currentAlias:
window.settings.writeAliases[userId] || ""
property bool changed: field.text != currentAlias
id: aliasField
label.text: qsTr("Write alias:")
field.onAccepted: applyChanges()
Component.onCompleted: field.text = currentAlias
Layout.fillWidth: true
Layout.maximumWidth: 480
Keys.onEscapePressed: cancelChanges()
}
}
HSpacer {}
HRowLayout {
Layout.alignment: Qt.AlignBottom
HButton {
property bool nameChangeRunning: false
property bool avatarChangeRunning: false
id: saveButton
icon.name: "apply"
icon.color: theme.colors.positiveBackground
text: qsTr("Save")
loading: nameChangeRunning || avatarChangeRunning
enabled:
nameField.changed || aliasField.changed || avatar.changed
onClicked: applyChanges()
Layout.fillWidth: true
Layout.alignment: Qt.AlignBottom
}
HButton {
icon.name: "cancel"
icon.color: theme.colors.negativeBackground
text: qsTr("Cancel")
enabled: saveButton.enabled && ! saveButton.loading
onClicked: cancelChanges()
Layout.fillWidth: true
Layout.alignment: Qt.AlignBottom
}
}
}
}