Add DeviceVerificationFlow dummy and verification test button

This commit is contained in:
Nicolas Werner 2020-03-13 21:05:18 +01:00 committed by CH Chethan Reddy
parent 488cc5e73b
commit 2088053d26
9 changed files with 163 additions and 33 deletions

View file

@ -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

View file

@ -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

View file

@ -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()
}
}
}
}
}
} }

View file

@ -1,13 +0,0 @@
import QtQuick 2.3
import QtQuick.Controls 1.2
Item {
DeviceVerification {
id: deviceVerification
}
Button {
text: "Test DeviceVerification"
onClicked: deviceVerification.show()
}
}

View file

@ -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>

View 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();
}

View 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;
};

View file

@ -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));
}

View file

@ -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);