mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-26 04:58:49 +03:00
Add DeviceVerificationFlow dummy and verification test button
This commit is contained in:
parent
488cc5e73b
commit
2088053d26
9 changed files with 163 additions and 33 deletions
|
@ -284,6 +284,7 @@ set(SRC_FILES
|
||||||
src/ColorImageProvider.cpp
|
src/ColorImageProvider.cpp
|
||||||
src/CommunitiesList.cpp
|
src/CommunitiesList.cpp
|
||||||
src/CommunitiesListItem.cpp
|
src/CommunitiesListItem.cpp
|
||||||
|
src/DeviceVerificationFlow.cpp
|
||||||
src/EventAccessors.cpp
|
src/EventAccessors.cpp
|
||||||
src/InviteeItem.cpp
|
src/InviteeItem.cpp
|
||||||
src/Logging.cpp
|
src/Logging.cpp
|
||||||
|
@ -488,6 +489,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
||||||
src/ChatPage.h
|
src/ChatPage.h
|
||||||
src/CommunitiesList.h
|
src/CommunitiesList.h
|
||||||
src/CommunitiesListItem.h
|
src/CommunitiesListItem.h
|
||||||
|
src/DeviceVerificationFlow.h
|
||||||
src/InviteeItem.h
|
src/InviteeItem.h
|
||||||
src/LoginPage.h
|
src/LoginPage.h
|
||||||
src/MainWindow.h
|
src/MainWindow.h
|
||||||
|
|
|
@ -9,6 +9,7 @@ import im.nheko.EmojiModel 1.0
|
||||||
|
|
||||||
import "./delegates"
|
import "./delegates"
|
||||||
import "./emoji"
|
import "./emoji"
|
||||||
|
import "./device-verification"
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
id: timelineRoot
|
id: timelineRoot
|
||||||
|
@ -98,6 +99,24 @@ Page {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: colors.window
|
color: colors.window
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: deviceVerificationDialog
|
||||||
|
DeviceVerification {}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: timelineManager
|
||||||
|
onDeviceVerificationRequest: {
|
||||||
|
var dialog = deviceVerificationDialog.createObject(timelineRoot, {flow: deviceVerificationFlow});
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "test device verification"
|
||||||
|
onClicked: timelineManager.startDummyVerification()
|
||||||
|
z: 5
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
visible: !timelineManager.timeline && !timelineManager.isInitialSync
|
visible: !timelineManager.timeline && !timelineManager.isInitialSync
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
|
@ -3,12 +3,15 @@ import QtQuick.Controls 2.10
|
||||||
import QtQuick.Window 2.2
|
import QtQuick.Window 2.2
|
||||||
import QtQuick.Layouts 1.10
|
import QtQuick.Layouts 1.10
|
||||||
|
|
||||||
Window {
|
import im.nheko 1.0
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
title: stack.currentItem.title
|
title: stack.currentItem.title
|
||||||
id: dialog
|
id: dialog
|
||||||
|
|
||||||
flags: Qt.Dialog
|
flags: Qt.Dialog
|
||||||
|
|
||||||
|
palette: colors
|
||||||
|
|
||||||
height: stack.implicitHeight
|
height: stack.implicitHeight
|
||||||
width: stack.implicitWidth
|
width: stack.implicitWidth
|
||||||
|
@ -21,6 +24,19 @@ Window {
|
||||||
|
|
||||||
onClosing: stack.replace(newVerificationRequest)
|
onClosing: stack.replace(newVerificationRequest)
|
||||||
|
|
||||||
|
property var flow
|
||||||
|
Connections {
|
||||||
|
target: flow
|
||||||
|
onVerificationCanceled: stack.replace(partnerAborted)
|
||||||
|
onTimedout: stack.replace(timedout)
|
||||||
|
onDeviceVerified: stack.replace(verificationSuccess)
|
||||||
|
|
||||||
|
onVerificationRequestAccepted: switch(method) {
|
||||||
|
case DeviceVerificationFlow.Decimal: stack.replace(digitVerification); break;
|
||||||
|
case DeviceVerificationFlow.Emoji: stack.replace(emojiVerification); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: newVerificationRequest
|
id: newVerificationRequest
|
||||||
Pane {
|
Pane {
|
||||||
|
@ -51,7 +67,7 @@ Window {
|
||||||
Button {
|
Button {
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
text: "Cancel"
|
text: "Cancel"
|
||||||
onClicked: dialog.close()
|
onClicked: { dialog.close(); flow.cancelVerification(); }
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -59,7 +75,7 @@ Window {
|
||||||
Button {
|
Button {
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
text: "Start verification"
|
text: "Start verification"
|
||||||
onClicked: stack.replace(awaitingVerificationRequestAccept)
|
onClicked: { stack.replace(awaitingVerificationRequestAccept); flow.acceptVerificationRequest(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,17 +106,12 @@ Window {
|
||||||
Button {
|
Button {
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
text: "Cancel"
|
text: "Cancel"
|
||||||
onClicked: dialog.close()
|
onClicked: { dialog.close(); flow.cancelVerification(); }
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Timer {
|
|
||||||
// temporary, until it is bound to a backend
|
|
||||||
interval: 5000; running: true;
|
|
||||||
onTriggered: if (Math.random() > 0.5) stack.replace(emojiVerification); else stack.replace(digitVerification);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +152,7 @@ Window {
|
||||||
Button {
|
Button {
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
text: "They do not match!"
|
text: "They do not match!"
|
||||||
onClicked: dialog.close()
|
onClicked: { dialog.close(); flow.cancelVerification(); }
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -149,7 +160,7 @@ Window {
|
||||||
Button {
|
Button {
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
text: "They match."
|
text: "They match."
|
||||||
onClicked: stack.replace(awaitingVerificationConfirmation)
|
onClicked: { stack.replace(awaitingVerificationConfirmation); flow.acceptDevice(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +259,7 @@ Window {
|
||||||
id: repeater
|
id: repeater
|
||||||
model: 7
|
model: 7
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
color: "red"
|
color: "transparent"
|
||||||
implicitHeight: Qt.application.font.pixelSize * 8
|
implicitHeight: Qt.application.font.pixelSize * 8
|
||||||
implicitWidth: col.width
|
implicitWidth: col.width
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
@ -274,7 +285,7 @@ Window {
|
||||||
Button {
|
Button {
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
text: "They do not match!"
|
text: "They do not match!"
|
||||||
onClicked: dialog.close()
|
onClicked: { dialog.close(); flow.cancelVerification(); }
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -282,7 +293,7 @@ Window {
|
||||||
Button {
|
Button {
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
text: "They match."
|
text: "They match."
|
||||||
onClicked: stack.replace(awaitingVerificationConfirmation)
|
onClicked: { stack.replace(awaitingVerificationConfirmation); flow.acceptDevice(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,17 +324,12 @@ Window {
|
||||||
Button {
|
Button {
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
text: "Cancel"
|
text: "Cancel"
|
||||||
onClicked: dialog.close()
|
onClicked: { dialog.close(); flow.cancelVerification(); }
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Timer {
|
|
||||||
// temporary, until it is bound to a backend
|
|
||||||
interval: 5000; running: true;
|
|
||||||
onTriggered: Math.random() > 0.5 ? stack.replace(verificationSuccess) : stack.replace(partnerAborted)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,4 +395,35 @@ Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: timedout
|
||||||
|
Pane {
|
||||||
|
property string title: "Verification timed out"
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
id: content
|
||||||
|
text: "Device verification timed out."
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: "Close"
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
import QtQuick 2.3
|
|
||||||
import QtQuick.Controls 1.2
|
|
||||||
|
|
||||||
Item {
|
|
||||||
DeviceVerification {
|
|
||||||
id: deviceVerification
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
text: "Test DeviceVerification"
|
|
||||||
onClicked: deviceVerification.show()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -135,5 +135,6 @@
|
||||||
<file>qml/delegates/Pill.qml</file>
|
<file>qml/delegates/Pill.qml</file>
|
||||||
<file>qml/delegates/Placeholder.qml</file>
|
<file>qml/delegates/Placeholder.qml</file>
|
||||||
<file>qml/delegates/Reply.qml</file>
|
<file>qml/delegates/Reply.qml</file>
|
||||||
|
<file>qml/device-verification/DeviceVerification.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
36
src/DeviceVerificationFlow.cpp
Normal file
36
src/DeviceVerificationFlow.cpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#include "DeviceVerificationFlow.h"
|
||||||
|
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
static constexpr int TIMEOUT = 2 * 60 * 1000; // 2 minutes
|
||||||
|
|
||||||
|
DeviceVerificationFlow::DeviceVerificationFlow(QObject *)
|
||||||
|
{
|
||||||
|
timeout = new QTimer(this);
|
||||||
|
timeout->setSingleShot(true);
|
||||||
|
connect(timeout, &QTimer::timeout, this, [this]() {
|
||||||
|
emit timedout();
|
||||||
|
this->deleteLater();
|
||||||
|
});
|
||||||
|
timeout->start(TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! accepts a verification and starts the verification flow
|
||||||
|
void
|
||||||
|
DeviceVerificationFlow::acceptVerificationRequest()
|
||||||
|
{
|
||||||
|
emit verificationRequestAccepted(rand() % 2 ? Emoji : Decimal);
|
||||||
|
}
|
||||||
|
//! cancels a verification flow
|
||||||
|
void
|
||||||
|
DeviceVerificationFlow::cancelVerification()
|
||||||
|
{
|
||||||
|
this->deleteLater();
|
||||||
|
}
|
||||||
|
//! Completes the verification flow
|
||||||
|
void
|
||||||
|
DeviceVerificationFlow::acceptDevice()
|
||||||
|
{
|
||||||
|
emit deviceVerified();
|
||||||
|
this->deleteLater();
|
||||||
|
}
|
38
src/DeviceVerificationFlow.h
Normal file
38
src/DeviceVerificationFlow.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
|
class DeviceVerificationFlow : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
// Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Method
|
||||||
|
{
|
||||||
|
Decimal,
|
||||||
|
Emoji
|
||||||
|
};
|
||||||
|
Q_ENUM(Method)
|
||||||
|
|
||||||
|
DeviceVerificationFlow(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
//! accepts a verification and starts the verification flow
|
||||||
|
void acceptVerificationRequest();
|
||||||
|
//! cancels a verification flow
|
||||||
|
void cancelVerification();
|
||||||
|
//! Completes the verification flow
|
||||||
|
void acceptDevice();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void verificationRequestAccepted(Method method);
|
||||||
|
void deviceVerified();
|
||||||
|
void timedout();
|
||||||
|
void verificationCanceled();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTimer *timeout = nullptr;
|
||||||
|
};
|
|
@ -85,6 +85,7 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
|
||||||
"Can't instantiate enum!");
|
"Can't instantiate enum!");
|
||||||
qmlRegisterType<DelegateChoice>("im.nheko", 1, 0, "DelegateChoice");
|
qmlRegisterType<DelegateChoice>("im.nheko", 1, 0, "DelegateChoice");
|
||||||
qmlRegisterType<DelegateChooser>("im.nheko", 1, 0, "DelegateChooser");
|
qmlRegisterType<DelegateChooser>("im.nheko", 1, 0, "DelegateChooser");
|
||||||
|
qmlRegisterType<DeviceVerificationFlow>("im.nheko", 1, 0, "DeviceVerificationFlow");
|
||||||
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
|
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
|
||||||
qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
|
qmlRegisterType<emoji::EmojiModel>("im.nheko.EmojiModel", 1, 0, "EmojiModel");
|
||||||
qmlRegisterType<emoji::EmojiProxyModel>("im.nheko.EmojiModel", 1, 0, "EmojiProxyModel");
|
qmlRegisterType<emoji::EmojiProxyModel>("im.nheko.EmojiModel", 1, 0, "EmojiProxyModel");
|
||||||
|
@ -460,3 +461,9 @@ TimelineViewManager::queueVideoMessage(const QString &roomid,
|
||||||
|
|
||||||
model->sendMessage(video);
|
model->sendMessage(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineViewManager::startDummyVerification()
|
||||||
|
{
|
||||||
|
emit deviceVerificationRequest(new DeviceVerificationFlow(this));
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <mtx/responses.hpp>
|
#include <mtx/responses.hpp>
|
||||||
|
|
||||||
#include "Cache.h"
|
#include "Cache.h"
|
||||||
|
#include "DeviceVerificationFlow.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
#include "TimelineModel.h"
|
#include "TimelineModel.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
@ -43,6 +44,7 @@ public:
|
||||||
Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; }
|
Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; }
|
||||||
Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const;
|
Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const;
|
||||||
Q_INVOKABLE QColor userColor(QString id, QColor background);
|
Q_INVOKABLE QColor userColor(QString id, QColor background);
|
||||||
|
Q_INVOKABLE void startDummyVerification();
|
||||||
|
|
||||||
Q_INVOKABLE QString userPresence(QString id) const;
|
Q_INVOKABLE QString userPresence(QString id) const;
|
||||||
Q_INVOKABLE QString userStatus(QString id) const;
|
Q_INVOKABLE QString userStatus(QString id) const;
|
||||||
|
@ -54,6 +56,7 @@ signals:
|
||||||
void initialSyncChanged(bool isInitialSync);
|
void initialSyncChanged(bool isInitialSync);
|
||||||
void replyingEventChanged(QString replyingEvent);
|
void replyingEventChanged(QString replyingEvent);
|
||||||
void replyClosed();
|
void replyClosed();
|
||||||
|
void deviceVerificationRequest(DeviceVerificationFlow *deviceVerificationFlow);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
|
void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
|
||||||
|
|
Loading…
Reference in a new issue