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
|
- When qml syntax highlighting supports string interpolation, use them
|
||||||
|
|
||||||
- Fixes
|
- 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
|
- Don't linkify images for outgoing html
|
||||||
- state: If last page is a room and the account for it is no longer present,
|
- state: If last page is a room and the account for it is no longer present,
|
||||||
load Default.qml instead
|
load Default.qml instead
|
||||||
|
@ -29,6 +32,13 @@
|
||||||
- [hr not working](https://bugreports.qt.io/browse/QTBUG-74342)
|
- [hr not working](https://bugreports.qt.io/browse/QTBUG-74342)
|
||||||
|
|
||||||
- UI
|
- 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
|
- Make invite/left banners look better in column mode
|
||||||
- Messages editing
|
- Messages editing
|
||||||
- Code highlighting
|
- 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: ""
|
property string file: ""
|
||||||
|
|
||||||
enum FileType { All, Images }
|
enum FileType { All, Images }
|
||||||
property int fileType: FileType.All
|
property int fileType: HFileDialogOpener.FileType.All
|
||||||
|
|
||||||
TapHandler { onTapped: fileDialog.open() }
|
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)
|
Utils.coloredNameHtml(headerName, userId)
|
||||||
)
|
)
|
||||||
|
|
||||||
HRectangle {
|
HSpacer {}
|
||||||
color: ready ? theme.controls.box.background : "transparent"
|
|
||||||
Behavior on color { HColorAnimation {} }
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
Repeater {
|
||||||
|
model: ["Profile.qml", "Encryption.qml"]
|
||||||
|
|
||||||
Layout.maximumWidth: Math.min(parent.width, 640)
|
HRectangle {
|
||||||
Layout.preferredWidth:
|
color: ready ? theme.controls.box.background : "transparent"
|
||||||
pageStack.isWide ? parent.width : avatarPreferredSize
|
Behavior on color { HColorAnimation {} }
|
||||||
|
|
||||||
Layout.preferredHeight: childrenRect.height
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
|
||||||
Loader {
|
Layout.maximumWidth: Math.min(parent.width, 640)
|
||||||
width: parent.width
|
Layout.preferredWidth:
|
||||||
source: ready ? "Profile.qml" : "../../Base/HBusyIndicator.qml"
|
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
|
color background: colors.strongBackground
|
||||||
int radius: theme.radius
|
int radius: theme.radius
|
||||||
|
|
||||||
|
popup:
|
||||||
|
color background: colors.strongBackground
|
||||||
|
|
||||||
header:
|
header:
|
||||||
color background: colors.strongBackground
|
color background: colors.strongBackground
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user