Show import keys error in the UI
This commit is contained in:
parent
7d2cbae26f
commit
ce3404a516
8
TODO.md
8
TODO.md
|
@ -22,9 +22,7 @@ translated arg for avatar upload and login
|
|||
- Fixes
|
||||
- Restore previous focus after closing right click context menu
|
||||
|
||||
- Run import in thread and AsyncClient.olm functions, they block async loop
|
||||
- Handle import keys errors
|
||||
- Show error box if uploading avatar fails
|
||||
- Show error if uploading avatar fails
|
||||
|
||||
- Don't strip user spacing in html
|
||||
- Do something when access token is invalid
|
||||
|
@ -35,9 +33,7 @@ translated arg for avatar upload and login
|
|||
- Terrible performance using `QT_QPA_PLATFORM=wayland-egl`, must use `xcb`
|
||||
|
||||
- UI
|
||||
- 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
|
||||
|
||||
- Decrypt messages again after importing keys
|
||||
- Choose a better default easing type for animations
|
||||
- Make invite icon blink if there's no one but ourself in the room,
|
||||
but never do it again once the user hovered it long enough to show tooltip
|
||||
|
|
1
src/icons/light-thin/retry.svg
Normal file
1
src/icons/light-thin/retry.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13.5 2c-5.629 0-10.212 4.436-10.475 10h-3.025l4.537 5.917 4.463-5.917h-2.975c.26-3.902 3.508-7 7.475-7 4.136 0 7.5 3.364 7.5 7.5s-3.364 7.5-7.5 7.5c-2.381 0-4.502-1.119-5.876-2.854l-1.847 2.449c1.919 2.088 4.664 3.405 7.723 3.405 5.798 0 10.5-4.702 10.5-10.5s-4.702-10.5-10.5-10.5z"/></svg>
|
After Width: | Height: | Size: 383 B |
|
@ -304,17 +304,21 @@ class MatrixClient(nio.AsyncClient):
|
|||
return True
|
||||
|
||||
|
||||
async def import_keys(self, infile: str, passphrase: str) -> Optional[str]:
|
||||
async def import_keys(self, infile: str, passphrase: str) -> None:
|
||||
# Reimplemented until better solutions are worked on in nio
|
||||
await self.clear_import_error()
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
account = self.models[Account][self.user_id]
|
||||
import_keys = partial(self.olm.import_keys_static, infile, passphrase)
|
||||
|
||||
try:
|
||||
sessions = await loop.run_in_executor(None, import_keys)
|
||||
except nio.EncryptionError as err:
|
||||
return str(err)
|
||||
account.import_error = (infile, passphrase, str(err))
|
||||
return
|
||||
|
||||
account = self.models[Account][self.user_id]
|
||||
account.importing_key = 0
|
||||
account.total_keys_to_import = len(sessions)
|
||||
|
||||
|
@ -330,6 +334,10 @@ class MatrixClient(nio.AsyncClient):
|
|||
return None
|
||||
|
||||
|
||||
async def clear_import_error(self) -> None:
|
||||
self.models[Account][self.user_id].import_error = ("", "", "")
|
||||
|
||||
|
||||
# Functions to register data into models
|
||||
|
||||
async def event_is_past(self, ev: Union[nio.Event, Event]) -> bool:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import re
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from ..html_filter import HTML_FILTER
|
||||
from ..utils import AutoStrEnum, auto
|
||||
|
@ -18,6 +18,7 @@ class Account(ModelItem):
|
|||
|
||||
importing_key: int = 0
|
||||
total_keys_to_import: int = 0
|
||||
import_error: Tuple[str, str, str] = ("", "", "") # path,pw,err
|
||||
|
||||
def __lt__(self, other: "Account") -> bool:
|
||||
name = self.display_name or self.user_id[1:]
|
||||
|
|
|
@ -10,7 +10,7 @@ Item {
|
|||
rotation: 45 * 3
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: Qt.hsla(0.73, 0.25, 0.25, 1) }
|
||||
GradientStop { position: 1.0; color: Qt.hsla(0.52, 1, 0.08, 1) }
|
||||
GradientStop { position: 1.0; color: Qt.hsla(0.52, 1, 0.06, 1) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,39 @@ import QtQuick 2.12
|
|||
import "../../Base"
|
||||
|
||||
HLoader {
|
||||
id: loader
|
||||
source: accountInfo.total_keys_to_import ?
|
||||
"ImportingKeys.qml" : "ImportExportKeys.qml"
|
||||
property bool importing: false
|
||||
|
||||
|
||||
function importKeys(file, passphrase, button=null) {
|
||||
if (button) button.loading = true
|
||||
importing = true
|
||||
|
||||
let path = file.toString().replace(/^file:\/\//, "")
|
||||
|
||||
py.callClientCoro(
|
||||
editAccount.userId, "import_keys", [path, passphrase], () => {
|
||||
importing = false
|
||||
if (button) button.loading = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
id: encryptionUI
|
||||
source:
|
||||
accountInfo.import_error[0] ? "ImportError.qml" :
|
||||
importing || accountInfo.total_keys_to_import ? "ImportingKeys.qml" :
|
||||
"ImportExportKeys.qml"
|
||||
|
||||
onSourceChanged: animation.running = true
|
||||
|
||||
HNumberAnimation {
|
||||
SequentialAnimation {
|
||||
id: animation
|
||||
target: loader.item
|
||||
property: "scale"
|
||||
from: 0
|
||||
to: 1
|
||||
overshoot: 3
|
||||
HNumberAnimation {
|
||||
target: encryptionUI; property: "scale"; to: 0;
|
||||
}
|
||||
HNumberAnimation {
|
||||
target: encryptionUI; property: "scale"; to: 1; overshoot: 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
33
src/qml/Pages/EditAccount/ImportError.qml
Normal file
33
src/qml/Pages/EditAccount/ImportError.qml
Normal file
|
@ -0,0 +1,33 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../../Base"
|
||||
import "../../utils.js" as Utils
|
||||
|
||||
HInterfaceBox {
|
||||
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
|
||||
}
|
||||
}
|
|
@ -5,18 +5,6 @@ import "../../Base"
|
|||
import "../../utils.js" as Utils
|
||||
|
||||
HColumnLayout {
|
||||
function importKeys(file, passphrase) {
|
||||
importButton.loading = true
|
||||
|
||||
let path = file.toString().replace(/^file:\/\//, "")
|
||||
|
||||
py.callClientCoro(
|
||||
editAccount.userId, "import_keys", [path, passphrase], () => {
|
||||
if (importButton) importButton.loading = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
HLabel {
|
||||
wrapMode: Text.Wrap
|
||||
text: qsTr(
|
||||
|
@ -75,6 +63,7 @@ HColumnLayout {
|
|||
label.text: qsTr(
|
||||
"Please enter the passphrase that was used to protect this file:"
|
||||
)
|
||||
onAcceptedPasswordChanged: importKeys(file, acceptedPassword)
|
||||
onAcceptedPasswordChanged:
|
||||
encryptionUI.importKeys(file, acceptedPassword, importButton)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user