Add decryption keys import in account settings
This commit is contained in:
parent
93a6867735
commit
858c9f337d
10
TODO.md
10
TODO.md
|
@ -16,6 +16,9 @@
|
|||
- When qml syntax highlighting supports string interpolation, use them
|
||||
|
||||
- Fixes
|
||||
- Run import in thread ? Does it blocks the async loop?
|
||||
- Handle import errors
|
||||
- Update the room subtitle when a message is decrypted/edited
|
||||
- Don't linkify images for outgoing html
|
||||
- state: If last page is a room and the account for it is no longer present,
|
||||
load Default.qml instead
|
||||
|
@ -29,6 +32,13 @@
|
|||
- [hr not working](https://bugreports.qt.io/browse/QTBUG-74342)
|
||||
|
||||
- UI
|
||||
- Popup:
|
||||
- label size
|
||||
- Accept/cancel buttons
|
||||
- Transitions
|
||||
|
||||
- When starting a long task, e.g. importing keys, quitting the page,
|
||||
and coming back, show the buttons as still loading until operation is done
|
||||
- Make invite/left banners look better in column mode
|
||||
- Messages editing
|
||||
- Code highlighting
|
||||
|
|
1
src/icons/dark-filled/export-keys.svg
Normal file
1
src/icons/dark-filled/export-keys.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M9 16h-8v6h22v-6h-8v-1h9v8h-24v-8h9v1zm11 2c.552 0 1 .448 1 1s-.448 1-1 1-1-.448-1-1 .448-1 1-1zm-7.5 0h-1v-14.883l-4.735 5.732-.765-.644 6.021-7.205 5.979 7.195-.764.645-4.736-5.724v14.884z"/></svg>
|
After Width: | Height: | Size: 311 B |
1
src/icons/dark-filled/import-keys.svg
Normal file
1
src/icons/dark-filled/import-keys.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M6 16h-5v6h22v-6h-5v-1h6v8h-24v-8h6v1zm14 2c.552 0 1 .448 1 1s-.448 1-1 1-1-.448-1-1 .448-1 1-1zm-7.5-17v14.884l4.736-5.724.764.645-5.979 7.195-6.021-7.205.765-.644 4.735 5.732v-14.883h1z"/></svg>
|
After Width: | Height: | Size: 308 B |
32
src/icons/light-thin/export-keys.svg
Normal file
32
src/icons/light-thin/export-keys.svg
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg4"
|
||||
version="1.1"
|
||||
clip-rule="evenodd"
|
||||
fill-rule="evenodd"
|
||||
height="24"
|
||||
width="24">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<path
|
||||
style="fill:#c8c8c8;fill-opacity:1"
|
||||
id="path2"
|
||||
d="M9 16h-8v6h22v-6h-8v-1h9v8h-24v-8h9v1zm11 2c.552 0 1 .448 1 1s-.448 1-1 1-1-.448-1-1 .448-1 1-1zm-7.5 0h-1v-14.883l-4.735 5.732-.765-.644 6.021-7.205 5.979 7.195-.764.645-4.736-5.724v14.884z" />
|
||||
</svg>
|
After Width: | Height: | Size: 991 B |
32
src/icons/light-thin/import-keys.svg
Normal file
32
src/icons/light-thin/import-keys.svg
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg4"
|
||||
version="1.1"
|
||||
clip-rule="evenodd"
|
||||
fill-rule="evenodd"
|
||||
height="24"
|
||||
width="24">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<path
|
||||
style="fill:#c8c8c8;fill-opacity:1"
|
||||
id="path2"
|
||||
d="M6 16h-5v6h22v-6h-5v-1h6v8h-24v-8h6v1zm14 2c.552 0 1 .448 1 1s-.448 1-1 1-1-.448-1-1 .448-1 1-1zm-7.5-17v14.884l4.736-5.724.764.645-5.979 7.195-6.021-7.205.765-.644 4.735 5.732v-14.883h1z" />
|
||||
</svg>
|
After Width: | Height: | Size: 988 B |
|
@ -13,7 +13,7 @@ Item {
|
|||
property string file: ""
|
||||
|
||||
enum FileType { All, Images }
|
||||
property int fileType: FileType.All
|
||||
property int fileType: HFileDialogOpener.FileType.All
|
||||
|
||||
TapHandler { onTapped: fileDialog.open() }
|
||||
|
||||
|
|
55
src/qml/Base/HPasswordPopup.qml
Normal file
55
src/qml/Base/HPasswordPopup.qml
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2019 miruka
|
||||
// This file is part of harmonyqml, licensed under LGPLv3.
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../SidePane"
|
||||
|
||||
Popup {
|
||||
id: popup
|
||||
width: window.width
|
||||
anchors.centerIn: Overlay.overlay
|
||||
modal: true
|
||||
|
||||
onOpened: passwordField.forceActiveFocus()
|
||||
|
||||
property alias label: popupLabel
|
||||
property alias field: passwordField
|
||||
property string password: ""
|
||||
|
||||
background: HRectangle {
|
||||
color: theme.controls.popup.background
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
width: parent.width
|
||||
spacing: theme.spacing
|
||||
|
||||
HLabel {
|
||||
id: popupLabel
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.minimumWidth: theme.minimumSupportedWidth
|
||||
Layout.maximumWidth:
|
||||
Math.min(480, window.width - theme.spacing * 2)
|
||||
}
|
||||
|
||||
HTextField {
|
||||
id: passwordField
|
||||
echoMode: TextInput.Password
|
||||
focus: true
|
||||
onAccepted: {
|
||||
popup.password = text
|
||||
popup.close()
|
||||
}
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
Layout.preferredWidth: popupLabel.width
|
||||
Layout.maximumWidth: popupLabel.width
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright 2019 miruka
|
||||
// This file is part of harmonyqml, licensed under LGPLv3.
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../../Base"
|
||||
import "../../utils.js" as Utils
|
||||
|
||||
HLabel {
|
||||
text: "Client - TODO"
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright 2019 miruka
|
||||
// This file is part of harmonyqml, licensed under LGPLv3.
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../../Base"
|
||||
import "../../utils.js" as Utils
|
||||
|
||||
HLabel {
|
||||
text: "Devices - TODO"
|
||||
}
|
|
@ -24,21 +24,32 @@ HPage {
|
|||
Utils.coloredNameHtml(headerName, userId)
|
||||
)
|
||||
|
||||
HRectangle {
|
||||
color: ready ? theme.controls.box.background : "transparent"
|
||||
Behavior on color { HColorAnimation {} }
|
||||
HSpacer {}
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Repeater {
|
||||
model: ["Profile.qml", "Encryption.qml"]
|
||||
|
||||
Layout.maximumWidth: Math.min(parent.width, 640)
|
||||
Layout.preferredWidth:
|
||||
pageStack.isWide ? parent.width : avatarPreferredSize
|
||||
HRectangle {
|
||||
color: ready ? theme.controls.box.background : "transparent"
|
||||
Behavior on color { HColorAnimation {} }
|
||||
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
Loader {
|
||||
width: parent.width
|
||||
source: ready ? "Profile.qml" : "../../Base/HBusyIndicator.qml"
|
||||
Layout.maximumWidth: Math.min(parent.width, 640)
|
||||
Layout.preferredWidth:
|
||||
pageStack.isWide ? parent.width : avatarPreferredSize
|
||||
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
|
||||
Loader {
|
||||
width: parent.width
|
||||
source: ready ?
|
||||
modelData :
|
||||
(modelData == "Profile.qml" ?
|
||||
"../../Base/HBusyIndicator.qml" : "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HSpacer {}
|
||||
}
|
||||
|
|
79
src/qml/Pages/EditAccount/Encryption.qml
Normal file
79
src/qml/Pages/EditAccount/Encryption.qml
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Copyright 2019 miruka
|
||||
// This file is part of harmonyqml, licensed under LGPLv3.
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../../Base"
|
||||
import "../../utils.js" as Utils
|
||||
|
||||
HColumnLayout {
|
||||
function importKeys(file, passphrase) {
|
||||
importButton.loading = true
|
||||
|
||||
let path = Qt.resolvedUrl(file).replace(/^file:\/\//, "")
|
||||
|
||||
py.callClientCoro(
|
||||
editAccount.userId, "import_keys", [path, passphrase], () => {
|
||||
importButton.loading = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
HLabel {
|
||||
wrapMode: Text.Wrap
|
||||
text: qsTr(
|
||||
"The decryption keys for the messages you received in " +
|
||||
"encrypted rooms can be exported to a file.%1" +
|
||||
"You will then be able to import this file in another " +
|
||||
"Matrix client."
|
||||
).arg(pageStack.isWide ? "\n" :"\n\n")
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: currentSpacing
|
||||
}
|
||||
|
||||
HRowLayout {
|
||||
HUIButton {
|
||||
id: exportButton
|
||||
iconName: "export-keys"
|
||||
text: qsTr("Export")
|
||||
enabled: false
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
|
||||
HUIButton {
|
||||
id: importButton
|
||||
iconName: "import-keys"
|
||||
text: qsTr("Import")
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
|
||||
HFileDialogOpener {
|
||||
id: fileDialog
|
||||
dialog.title: qsTr("Select a decryption key file to import")
|
||||
onFileChanged: {
|
||||
importPasswordPopup.file = file
|
||||
importPasswordPopup.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HPasswordPopup {
|
||||
property url file: ""
|
||||
|
||||
id: importPasswordPopup
|
||||
label.text: qsTr(
|
||||
"Please enter the passphrase that was used to protect this " +
|
||||
"file.\n\n" +
|
||||
"The import can take a few minutes. " +
|
||||
"You can leave the account settings page while it is running. " +
|
||||
"Messages may not be sent or received until the operation is done."
|
||||
)
|
||||
onPasswordChanged: importKeys(file, password)
|
||||
}
|
||||
}
|
|
@ -72,6 +72,9 @@ controls:
|
|||
color background: colors.strongBackground
|
||||
int radius: theme.radius
|
||||
|
||||
popup:
|
||||
color background: colors.strongBackground
|
||||
|
||||
header:
|
||||
color background: colors.strongBackground
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user