Split qml part of Device Verification

This commit is contained in:
CH Chethan Reddy 2020-09-14 17:27:49 +05:30
parent 94e1b52ddd
commit 8eb74daf76
18 changed files with 758 additions and 711 deletions

View File

@ -70,8 +70,8 @@ ApplicationWindow{
id: verifyUserButton
text: "Verify"
Layout.alignment: Qt.AlignHCenter
enabled: profile.isUserVerified
visible: profile.isUserVerified
enabled: !profile.isUserVerified
visible: !profile.isUserVerified
onClicked: {
var newFlow = profile.createFlow(true);

View File

@ -0,0 +1,65 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
import im.nheko 1.0
Pane {
property string title: qsTr("Recieving Device Verification Request")
Component {
id: awaitingVerificationRequestAccept
AwaitingVerificationRequest {}
}
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("The device was requested to be verified")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("Deny")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.User);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("Accept")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
stack.replace(awaitingVerificationRequestAccept);
isRequest?flow.sendVerificationReady():flow.acceptVerificationRequest();
}
}
}
}
}

View File

@ -0,0 +1,48 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
import im.nheko 1.0
Pane {
property string title: qsTr("Awaiting Confirmation")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Waiting for other side to complete verification.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
BusyIndicator {
Layout.alignment: Qt.AlignHCenter
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("Cancel")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.User);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
}
}
}

View File

@ -0,0 +1,48 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
import im.nheko 1.0
Pane {
property string title: qsTr("Waiting for other party")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Waiting for other side to accept the verification request.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
BusyIndicator {
Layout.alignment: Qt.AlignHCenter
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("Cancel")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.User);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
}
}
}

View File

@ -1,11 +1,14 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Window 2.2
import QtQuick.Layouts 1.10
import im.nheko 1.0
ApplicationWindow {
property var flow
property bool isRequest
property var tran_id
title: stack.currentItem.title
id: dialog
@ -15,6 +18,17 @@ ApplicationWindow {
height: stack.implicitHeight
width: stack.implicitWidth
Component{
id: newVerificationRequest
NewVerificationRequest {}
}
Component{
id: acceptNewVerificationRequest
AcceptNewVerificationRequest {}
}
StackView {
id: stack
initialItem: flow.sender == true?newVerificationRequest:acceptNewVerificationRequest
@ -22,9 +36,30 @@ ApplicationWindow {
implicitHeight: currentItem.implicitHeight
}
property var flow
property bool isRequest
property var tran_id
Component {
id: partnerAborted
PartnerAborted {}
}
Component {
id: timedout
TimedOut {}
}
Component {
id: verificationSuccess
VerificationSuccess {}
}
Component {
id: digitVerification
DigitVerification {}
}
Component {
id: emojiVerification
EmojiVerification {}
}
Connections {
target: flow
@ -41,594 +76,4 @@ ApplicationWindow {
deviceVerificationList.updateProfile(flow.userId);
}
}
Component {
id: newVerificationRequest
Pane {
property string title: qsTr("Sending Device Verification Request")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("A new device was added.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("The device may have been added by you signing in from another client or physical device. To ensure that no malicious user can eavesdrop on your encrypted communications, you should verify the new device.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("Cancel")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
deviceVerificationList.remove(tran_id);
flow.deleteFlow();
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("Start verification")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
stack.replace(awaitingVerificationRequestAccept);
isRequest?flow.sendVerificationRequest():flow.startVerificationRequest(); }
}
}
}
}
}
Component {
id: acceptNewVerificationRequest
Pane {
property string title: qsTr("Recieving Device Verification Request")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("The device was requested to be verified")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("Deny")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.User);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("Accept")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
stack.replace(awaitingVerificationRequestAccept);
isRequest?flow.sendVerificationReady():flow.acceptVerificationRequest();
}
}
}
}
}
}
Component {
id: awaitingVerificationRequestAccept
Pane {
property string title: qsTr("Waiting for other party")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Waiting for other side to accept the verification request.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
BusyIndicator {
Layout.alignment: Qt.AlignHCenter
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("Cancel")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.User);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
}
}
}
}
Component {
id: digitVerification
Pane {
property string title: qsTr("Verification Code")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("Please verify the following digits. You should see the same numbers on both sides. If they differ, please press 'They do not match!' to abort verification!")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
Label {
font.pixelSize: Qt.application.font.pixelSize * 2
text: flow.sasList[0]
color:colors.text
}
Label {
font.pixelSize: Qt.application.font.pixelSize * 2
text: flow.sasList[1]
color:colors.text
}
Label {
font.pixelSize: Qt.application.font.pixelSize * 2
text: flow.sasList[2]
color:colors.text
}
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("They do not match!")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.MismatchedSAS);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("They match!")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: { stack.replace(awaitingVerificationConfirmation); flow.sendVerificationMac(); }
}
}
}
}
}
Component {
id: emojiVerification
Pane {
property string title: qsTr("Verification Code")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("Please verify the following emoji. You should see the same emoji on both sides. If they differ, please press 'They do not match!' to abort verification!")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
id: emojis
property var mapping: [
{"number": 0, "emoji": "🐶", "description": "Dog", "unicode": "U+1F436"},
{"number": 1, "emoji": "🐱", "description": "Cat", "unicode": "U+1F431"},
{"number": 2, "emoji": "🦁", "description": "Lion", "unicode": "U+1F981"},
{"number": 3, "emoji": "🐎", "description": "Horse", "unicode": "U+1F40E"},
{"number": 4, "emoji": "🦄", "description": "Unicorn", "unicode": "U+1F984"},
{"number": 5, "emoji": "🐷", "description": "Pig", "unicode": "U+1F437"},
{"number": 6, "emoji": "🐘", "description": "Elephant", "unicode": "U+1F418"},
{"number": 7, "emoji": "🐰", "description": "Rabbit", "unicode": "U+1F430"},
{"number": 8, "emoji": "🐼", "description": "Panda", "unicode": "U+1F43C"},
{"number": 9, "emoji": "🐓", "description": "Rooster", "unicode": "U+1F413"},
{"number": 10, "emoji": "🐧", "description": "Penguin", "unicode": "U+1F427"},
{"number": 11, "emoji": "🐢", "description": "Turtle", "unicode": "U+1F422"},
{"number": 12, "emoji": "🐟", "description": "Fish", "unicode": "U+1F41F"},
{"number": 13, "emoji": "🐙", "description": "Octopus", "unicode": "U+1F419"},
{"number": 14, "emoji": "🦋", "description": "Butterfly", "unicode": "U+1F98B"},
{"number": 15, "emoji": "🌷", "description": "Flower", "unicode": "U+1F337"},
{"number": 16, "emoji": "🌳", "description": "Tree", "unicode": "U+1F333"},
{"number": 17, "emoji": "🌵", "description": "Cactus", "unicode": "U+1F335"},
{"number": 18, "emoji": "🍄", "description": "Mushroom", "unicode": "U+1F344"},
{"number": 19, "emoji": "🌏", "description": "Globe", "unicode": "U+1F30F"},
{"number": 20, "emoji": "🌙", "description": "Moon", "unicode": "U+1F319"},
{"number": 21, "emoji": "☁️", "description": "Cloud", "unicode": "U+2601U+FE0F"},
{"number": 22, "emoji": "🔥", "description": "Fire", "unicode": "U+1F525"},
{"number": 23, "emoji": "🍌", "description": "Banana", "unicode": "U+1F34C"},
{"number": 24, "emoji": "🍎", "description": "Apple", "unicode": "U+1F34E"},
{"number": 25, "emoji": "🍓", "description": "Strawberry", "unicode": "U+1F353"},
{"number": 26, "emoji": "🌽", "description": "Corn", "unicode": "U+1F33D"},
{"number": 27, "emoji": "🍕", "description": "Pizza", "unicode": "U+1F355"},
{"number": 28, "emoji": "🎂", "description": "Cake", "unicode": "U+1F382"},
{"number": 29, "emoji": "❤️", "description": "Heart", "unicode": "U+2764U+FE0F"},
{"number": 30, "emoji": "😀", "description": "Smiley", "unicode": "U+1F600"},
{"number": 31, "emoji": "🤖", "description": "Robot", "unicode": "U+1F916"},
{"number": 32, "emoji": "🎩", "description": "Hat", "unicode": "U+1F3A9"},
{"number": 33, "emoji": "👓", "description": "Glasses", "unicode": "U+1F453"},
{"number": 34, "emoji": "🔧", "description": "Spanner", "unicode": "U+1F527"},
{"number": 35, "emoji": "🎅", "description": "Santa", "unicode": "U+1F385"},
{"number": 36, "emoji": "👍", "description": "Thumbs Up", "unicode": "U+1F44D"},
{"number": 37, "emoji": "☂️", "description": "Umbrella", "unicode": "U+2602U+FE0F"},
{"number": 38, "emoji": "⌛", "description": "Hourglass", "unicode": "U+231B"},
{"number": 39, "emoji": "⏰", "description": "Clock", "unicode": "U+23F0"},
{"number": 40, "emoji": "🎁", "description": "Gift", "unicode": "U+1F381"},
{"number": 41, "emoji": "💡", "description": "Light Bulb", "unicode": "U+1F4A1"},
{"number": 42, "emoji": "📕", "description": "Book", "unicode": "U+1F4D5"},
{"number": 43, "emoji": "✏️", "description": "Pencil", "unicode": "U+270FU+FE0F"},
{"number": 44, "emoji": "📎", "description": "Paperclip", "unicode": "U+1F4CE"},
{"number": 45, "emoji": "✂️", "description": "Scissors", "unicode": "U+2702U+FE0F"},
{"number": 46, "emoji": "🔒", "description": "Lock", "unicode": "U+1F512"},
{"number": 47, "emoji": "🔑", "description": "Key", "unicode": "U+1F511"},
{"number": 48, "emoji": "🔨", "description": "Hammer", "unicode": "U+1F528"},
{"number": 49, "emoji": "☎️", "description": "Telephone", "unicode": "U+260EU+FE0F"},
{"number": 50, "emoji": "🏁", "description": "Flag", "unicode": "U+1F3C1"},
{"number": 51, "emoji": "🚂", "description": "Train", "unicode": "U+1F682"},
{"number": 52, "emoji": "🚲", "description": "Bicycle", "unicode": "U+1F6B2"},
{"number": 53, "emoji": "✈️", "description": "Aeroplane", "unicode": "U+2708U+FE0F"},
{"number": 54, "emoji": "🚀", "description": "Rocket", "unicode": "U+1F680"},
{"number": 55, "emoji": "🏆", "description": "Trophy", "unicode": "U+1F3C6"},
{"number": 56, "emoji": "⚽", "description": "Ball", "unicode": "U+26BD"},
{"number": 57, "emoji": "🎸", "description": "Guitar", "unicode": "U+1F3B8"},
{"number": 58, "emoji": "🎺", "description": "Trumpet", "unicode": "U+1F3BA"},
{"number": 59, "emoji": "🔔", "description": "Bell", "unicode": "U+1F514"},
{"number": 60, "emoji": "⚓", "description": "Anchor", "unicode": "U+2693"},
{"number": 61, "emoji": "🎧", "description": "Headphones", "unicode": "U+1F3A7"},
{"number": 62, "emoji": "📁", "description": "Folder", "unicode": "U+1F4C1"},
{"number": 63, "emoji": "📌", "description": "Pin", "unicode": "U+1F4CC"}
]
Repeater {
id: repeater
model: 7
delegate: Rectangle {
color: "transparent"
implicitHeight: Qt.application.font.pixelSize * 8
implicitWidth: col.width
ColumnLayout {
id: col
Layout.fillWidth: true
anchors.bottom: parent.bottom
property var emoji: emojis.mapping[flow.sasList[index]]
Label {
//height: font.pixelSize * 2
Layout.alignment: Qt.AlignHCenter
text: col.emoji.emoji
font.pixelSize: Qt.application.font.pixelSize * 2
font.family: Settings.emojiFont
color:colors.text
}
Label {
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
text: col.emoji.description
color:colors.text
}
}
}
}
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("They do not match!")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.MismatchedSAS);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("They match!")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: { stack.replace(awaitingVerificationConfirmation); flow.sendVerificationMac(); }
}
}
}
}
}
Component {
id: awaitingVerificationConfirmation
Pane {
property string title: qsTr("Awaiting Confirmation")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Waiting for other side to complete verification.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
BusyIndicator {
Layout.alignment: Qt.AlignHCenter
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("Cancel")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.User);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
}
}
}
}
Component {
id: verificationSuccess
Pane {
property string title: qsTr("Successful Verification")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Verification successful! Both sides verified their devices!")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("Close")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
deviceVerificationList.remove(tran_id);
flow.deleteFlow();
dialog.destroy();
}
}
}
}
}
}
Component {
id: partnerAborted
Pane {
property string title: qsTr("Verification aborted!")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Verification canceled by the other party!")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("Close")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
}
}
}
}
Component {
id: timedout
Pane {
property string title: qsTr("Verification timed out")
ColumnLayout {
spacing: 16
Text {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Device verification timed out.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Item {
Layout.fillWidth: true
}
Button {
id: timedOutCancel
Layout.alignment: Qt.AlignRight
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
text: qsTr("Close")
onClicked: {
deviceVerificationList.remove(tran_id);
flow.deleteFlow();
dialog.destroy()
}
}
}
}
}
}
}

View File

@ -0,0 +1,80 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
import im.nheko 1.0
Pane {
property string title: qsTr("Verification Code")
Component {
id: awaitingVerificationConfirmation
AwaitingVerificationConfirmation {}
}
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("Please verify the following digits. You should see the same numbers on both sides. If they differ, please press 'They do not match!' to abort verification!")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
Label {
font.pixelSize: Qt.application.font.pixelSize * 2
text: flow.sasList[0]
color:colors.text
}
Label {
font.pixelSize: Qt.application.font.pixelSize * 2
text: flow.sasList[1]
color:colors.text
}
Label {
font.pixelSize: Qt.application.font.pixelSize * 2
text: flow.sasList[2]
color:colors.text
}
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("They do not match!")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.MismatchedSAS);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("They match!")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: { stack.replace(awaitingVerificationConfirmation); flow.sendVerificationMac(); }
}
}
}
}

View File

@ -1,4 +1,5 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
Rectangle {

View File

@ -0,0 +1,160 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
import im.nheko 1.0
Pane {
property string title: qsTr("Verification Code")
Component {
id: awaitingVerificationConfirmation
AwaitingVerificationConfirmation{}
}
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("Please verify the following emoji. You should see the same emoji on both sides. If they differ, please press 'They do not match!' to abort verification!")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
id: emojis
property var mapping: [
{"number": 0, "emoji": "🐶", "description": "Dog", "unicode": "U+1F436"},
{"number": 1, "emoji": "🐱", "description": "Cat", "unicode": "U+1F431"},
{"number": 2, "emoji": "🦁", "description": "Lion", "unicode": "U+1F981"},
{"number": 3, "emoji": "🐎", "description": "Horse", "unicode": "U+1F40E"},
{"number": 4, "emoji": "🦄", "description": "Unicorn", "unicode": "U+1F984"},
{"number": 5, "emoji": "🐷", "description": "Pig", "unicode": "U+1F437"},
{"number": 6, "emoji": "🐘", "description": "Elephant", "unicode": "U+1F418"},
{"number": 7, "emoji": "🐰", "description": "Rabbit", "unicode": "U+1F430"},
{"number": 8, "emoji": "🐼", "description": "Panda", "unicode": "U+1F43C"},
{"number": 9, "emoji": "🐓", "description": "Rooster", "unicode": "U+1F413"},
{"number": 10, "emoji": "🐧", "description": "Penguin", "unicode": "U+1F427"},
{"number": 11, "emoji": "🐢", "description": "Turtle", "unicode": "U+1F422"},
{"number": 12, "emoji": "🐟", "description": "Fish", "unicode": "U+1F41F"},
{"number": 13, "emoji": "🐙", "description": "Octopus", "unicode": "U+1F419"},
{"number": 14, "emoji": "🦋", "description": "Butterfly", "unicode": "U+1F98B"},
{"number": 15, "emoji": "🌷", "description": "Flower", "unicode": "U+1F337"},
{"number": 16, "emoji": "🌳", "description": "Tree", "unicode": "U+1F333"},
{"number": 17, "emoji": "🌵", "description": "Cactus", "unicode": "U+1F335"},
{"number": 18, "emoji": "🍄", "description": "Mushroom", "unicode": "U+1F344"},
{"number": 19, "emoji": "🌏", "description": "Globe", "unicode": "U+1F30F"},
{"number": 20, "emoji": "🌙", "description": "Moon", "unicode": "U+1F319"},
{"number": 21, "emoji": "☁️", "description": "Cloud", "unicode": "U+2601U+FE0F"},
{"number": 22, "emoji": "🔥", "description": "Fire", "unicode": "U+1F525"},
{"number": 23, "emoji": "🍌", "description": "Banana", "unicode": "U+1F34C"},
{"number": 24, "emoji": "🍎", "description": "Apple", "unicode": "U+1F34E"},
{"number": 25, "emoji": "🍓", "description": "Strawberry", "unicode": "U+1F353"},
{"number": 26, "emoji": "🌽", "description": "Corn", "unicode": "U+1F33D"},
{"number": 27, "emoji": "🍕", "description": "Pizza", "unicode": "U+1F355"},
{"number": 28, "emoji": "🎂", "description": "Cake", "unicode": "U+1F382"},
{"number": 29, "emoji": "❤️", "description": "Heart", "unicode": "U+2764U+FE0F"},
{"number": 30, "emoji": "😀", "description": "Smiley", "unicode": "U+1F600"},
{"number": 31, "emoji": "🤖", "description": "Robot", "unicode": "U+1F916"},
{"number": 32, "emoji": "🎩", "description": "Hat", "unicode": "U+1F3A9"},
{"number": 33, "emoji": "👓", "description": "Glasses", "unicode": "U+1F453"},
{"number": 34, "emoji": "🔧", "description": "Spanner", "unicode": "U+1F527"},
{"number": 35, "emoji": "🎅", "description": "Santa", "unicode": "U+1F385"},
{"number": 36, "emoji": "👍", "description": "Thumbs Up", "unicode": "U+1F44D"},
{"number": 37, "emoji": "☂️", "description": "Umbrella", "unicode": "U+2602U+FE0F"},
{"number": 38, "emoji": "⌛", "description": "Hourglass", "unicode": "U+231B"},
{"number": 39, "emoji": "⏰", "description": "Clock", "unicode": "U+23F0"},
{"number": 40, "emoji": "🎁", "description": "Gift", "unicode": "U+1F381"},
{"number": 41, "emoji": "💡", "description": "Light Bulb", "unicode": "U+1F4A1"},
{"number": 42, "emoji": "📕", "description": "Book", "unicode": "U+1F4D5"},
{"number": 43, "emoji": "✏️", "description": "Pencil", "unicode": "U+270FU+FE0F"},
{"number": 44, "emoji": "📎", "description": "Paperclip", "unicode": "U+1F4CE"},
{"number": 45, "emoji": "✂️", "description": "Scissors", "unicode": "U+2702U+FE0F"},
{"number": 46, "emoji": "🔒", "description": "Lock", "unicode": "U+1F512"},
{"number": 47, "emoji": "🔑", "description": "Key", "unicode": "U+1F511"},
{"number": 48, "emoji": "🔨", "description": "Hammer", "unicode": "U+1F528"},
{"number": 49, "emoji": "☎️", "description": "Telephone", "unicode": "U+260EU+FE0F"},
{"number": 50, "emoji": "🏁", "description": "Flag", "unicode": "U+1F3C1"},
{"number": 51, "emoji": "🚂", "description": "Train", "unicode": "U+1F682"},
{"number": 52, "emoji": "🚲", "description": "Bicycle", "unicode": "U+1F6B2"},
{"number": 53, "emoji": "✈️", "description": "Aeroplane", "unicode": "U+2708U+FE0F"},
{"number": 54, "emoji": "🚀", "description": "Rocket", "unicode": "U+1F680"},
{"number": 55, "emoji": "🏆", "description": "Trophy", "unicode": "U+1F3C6"},
{"number": 56, "emoji": "⚽", "description": "Ball", "unicode": "U+26BD"},
{"number": 57, "emoji": "🎸", "description": "Guitar", "unicode": "U+1F3B8"},
{"number": 58, "emoji": "🎺", "description": "Trumpet", "unicode": "U+1F3BA"},
{"number": 59, "emoji": "🔔", "description": "Bell", "unicode": "U+1F514"},
{"number": 60, "emoji": "⚓", "description": "Anchor", "unicode": "U+2693"},
{"number": 61, "emoji": "🎧", "description": "Headphones", "unicode": "U+1F3A7"},
{"number": 62, "emoji": "📁", "description": "Folder", "unicode": "U+1F4C1"},
{"number": 63, "emoji": "📌", "description": "Pin", "unicode": "U+1F4CC"}
]
Repeater {
id: repeater
model: 7
delegate: Rectangle {
color: "transparent"
implicitHeight: Qt.application.font.pixelSize * 8
implicitWidth: col.width
ColumnLayout {
id: col
Layout.fillWidth: true
anchors.bottom: parent.bottom
property var emoji: emojis.mapping[flow.sasList[index]]
Label {
//height: font.pixelSize * 2
Layout.alignment: Qt.AlignHCenter
text: col.emoji.emoji
font.pixelSize: Qt.application.font.pixelSize * 2
font.family: Settings.emojiFont
color:colors.text
}
Label {
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
text: col.emoji.description
color:colors.text
}
}
}
}
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("They do not match!")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
flow.cancelVerification(DeviceVerificationFlow.MismatchedSAS);
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("They match!")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: { stack.replace(awaitingVerificationConfirmation); flow.sendVerificationMac(); }
}
}
}
}

View File

@ -0,0 +1,71 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
Pane {
property string title: qsTr("Sending Device Verification Request")
Component {
id: awaitingVerificationRequestAccept
AwaitingVerificationRequest {}
}
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("A new device was added.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
text: qsTr("The device may have been added by you signing in from another client or physical device. To ensure that no malicious user can eavesdrop on your encrypted communications, you should verify the new device.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Button {
Layout.alignment: Qt.AlignLeft
text: qsTr("Cancel")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
deviceVerificationList.remove(tran_id);
flow.deleteFlow();
dialog.destroy();
}
}
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("Start verification")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
stack.replace(awaitingVerificationRequestAccept);
isRequest?flow.sendVerificationRequest():flow.startVerificationRequest(); }
}
}
}
}

View File

@ -0,0 +1,42 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
Pane {
property string title: qsTr("Verification aborted!")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Verification canceled by the other party!")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("Close")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
deviceVerificationList.remove(tran_id);
dialog.destroy();
}
}
}
}
}

View File

@ -0,0 +1,44 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
Pane {
property string title: qsTr("Verification timed out")
ColumnLayout {
spacing: 16
Text {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Device verification timed out.")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Item {
Layout.fillWidth: true
}
Button {
id: timedOutCancel
Layout.alignment: Qt.AlignRight
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
text: qsTr("Close")
onClicked: {
deviceVerificationList.remove(tran_id);
flow.deleteFlow();
dialog.destroy()
}
}
}
}
}

View File

@ -0,0 +1,43 @@
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.10
Pane {
property string title: qsTr("Successful Verification")
ColumnLayout {
spacing: 16
Label {
Layout.maximumWidth: 400
Layout.fillHeight: true
Layout.fillWidth: true
wrapMode: Text.Wrap
id: content
text: qsTr("Verification successful! Both sides verified their devices!")
color:colors.text
verticalAlignment: Text.AlignVCenter
}
RowLayout {
Item {
Layout.fillWidth: true
}
Button {
Layout.alignment: Qt.AlignRight
text: qsTr("Close")
palette {
button: "white"
}
contentItem: Text {
text: parent.text
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: {
deviceVerificationList.remove(tran_id);
if(flow) flow.deleteFlow();
dialog.destroy();
}
}
}
}
}

View File

@ -141,7 +141,16 @@
<file>qml/delegates/Pill.qml</file>
<file>qml/delegates/Placeholder.qml</file>
<file>qml/delegates/Reply.qml</file>
<file>qml/device-verification/AcceptNewVerificationRequest.qml</file>
<file>qml/device-verification/AwaitingVerificationConfirmation.qml</file>
<file>qml/device-verification/AwaitingVerificationRequest.qml</file>
<file>qml/device-verification/DeviceVerification.qml</file>
<file>qml/device-verification/DigitVerification.qml</file>
<file>qml/device-verification/EmojiVerification.qml</file>
<file>qml/device-verification/NewVerificationRequest.qml</file>
<file>qml/device-verification/PartnerAborted.qml</file>
<file>qml/device-verification/TimedOut.qml</file>
<file>qml/device-verification/VerificationSuccess.qml</file>
</qresource>
<qresource prefix="/media">
<file>media/ring.ogg</file>

View File

@ -139,26 +139,24 @@ Cache::Cache(const QString &userId, QObject *parent)
, localUserId_{userId}
{
setup();
connect(
this,
&Cache::updateUserCacheFlag,
this,
[this](const std::string &user_id) {
std::optional<UserCache> cache_ = getUserCache(user_id);
if (cache_.has_value()) {
cache_.value().isUpdated = false;
setUserCache(user_id, cache_.value());
} else {
setUserCache(user_id, UserCache{});
}
},
Qt::QueuedConnection);
connect(
this,
&Cache::deleteLeftUsers,
this,
[this](const std::string &user_id) { deleteUserCache(user_id); },
Qt::QueuedConnection);
connect(this,
&Cache::updateUserCacheFlag,
this,
[this](const std::string &user_id) {
std::optional<UserCache> cache_ = getUserCache(user_id);
if (cache_.has_value()) {
cache_.value().isUpdated = false;
setUserCache(user_id, cache_.value());
} else {
setUserCache(user_id, UserCache{});
}
},
Qt::QueuedConnection);
connect(this,
&Cache::deleteLeftUsers,
this,
[this](const std::string &user_id) { deleteUserCache(user_id); },
Qt::QueuedConnection);
}
void

View File

@ -606,12 +606,11 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
connect(
this, &ChatPage::tryInitialSyncCb, this, &ChatPage::tryInitialSync, Qt::QueuedConnection);
connect(this, &ChatPage::trySyncCb, this, &ChatPage::trySync, Qt::QueuedConnection);
connect(
this,
&ChatPage::tryDelayedSyncCb,
this,
[this]() { QTimer::singleShot(RETRY_TIMEOUT, this, &ChatPage::trySync); },
Qt::QueuedConnection);
connect(this,
&ChatPage::tryDelayedSyncCb,
this,
[this]() { QTimer::singleShot(RETRY_TIMEOUT, this, &ChatPage::trySync); },
Qt::QueuedConnection);
connect(this,
&ChatPage::newSyncResponse,

View File

@ -33,5 +33,4 @@ private:
return shortname.replace(" ", "-").replace(":", "-").replace("--", "-").toLower();
}
};
}

View File

@ -32,40 +32,38 @@ EventStore::EventStore(std::string room_id, QObject *)
this->last = range->last;
}
connect(
this,
&EventStore::eventFetched,
this,
[this](std::string id,
std::string relatedTo,
mtx::events::collections::TimelineEvents timeline) {
cache::client()->storeEvent(room_id_, id, {timeline});
connect(this,
&EventStore::eventFetched,
this,
[this](std::string id,
std::string relatedTo,
mtx::events::collections::TimelineEvents timeline) {
cache::client()->storeEvent(room_id_, id, {timeline});
if (!relatedTo.empty()) {
auto idx = idToIndex(relatedTo);
if (idx)
emit dataChanged(*idx, *idx);
}
},
Qt::QueuedConnection);
if (!relatedTo.empty()) {
auto idx = idToIndex(relatedTo);
if (idx)
emit dataChanged(*idx, *idx);
}
},
Qt::QueuedConnection);
connect(
this,
&EventStore::oldMessagesRetrieved,
this,
[this](const mtx::responses::Messages &res) {
uint64_t newFirst = cache::client()->saveOldMessages(room_id_, res);
if (newFirst == first)
fetchMore();
else {
emit beginInsertRows(toExternalIdx(newFirst),
toExternalIdx(this->first - 1));
this->first = newFirst;
emit endInsertRows();
emit fetchedMore();
}
},
Qt::QueuedConnection);
connect(this,
&EventStore::oldMessagesRetrieved,
this,
[this](const mtx::responses::Messages &res) {
uint64_t newFirst = cache::client()->saveOldMessages(room_id_, res);
if (newFirst == first)
fetchMore();
else {
emit beginInsertRows(toExternalIdx(newFirst),
toExternalIdx(this->first - 1));
this->first = newFirst;
emit endInsertRows();
emit fetchedMore();
}
},
Qt::QueuedConnection);
connect(this, &EventStore::processPending, this, [this]() {
if (!current_txn.empty()) {
@ -130,48 +128,46 @@ EventStore::EventStore(std::string room_id, QObject *)
event->data);
});
connect(
this,
&EventStore::messageFailed,
this,
[this](std::string txn_id) {
if (current_txn == txn_id) {
current_txn_error_count++;
if (current_txn_error_count > 10) {
nhlog::ui()->debug("failing txn id '{}'", txn_id);
cache::client()->removePendingStatus(room_id_, txn_id);
current_txn_error_count = 0;
}
}
QTimer::singleShot(1000, this, [this]() {
nhlog::ui()->debug("timeout");
this->current_txn = "";
emit processPending();
});
},
Qt::QueuedConnection);
connect(this,
&EventStore::messageFailed,
this,
[this](std::string txn_id) {
if (current_txn == txn_id) {
current_txn_error_count++;
if (current_txn_error_count > 10) {
nhlog::ui()->debug("failing txn id '{}'", txn_id);
cache::client()->removePendingStatus(room_id_, txn_id);
current_txn_error_count = 0;
}
}
QTimer::singleShot(1000, this, [this]() {
nhlog::ui()->debug("timeout");
this->current_txn = "";
emit processPending();
});
},
Qt::QueuedConnection);
connect(
this,
&EventStore::messageSent,
this,
[this](std::string txn_id, std::string event_id) {
nhlog::ui()->debug("sent {}", txn_id);
connect(this,
&EventStore::messageSent,
this,
[this](std::string txn_id, std::string event_id) {
nhlog::ui()->debug("sent {}", txn_id);
http::client()->read_event(
room_id_, event_id, [this, event_id](mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn(
"failed to read_event ({}, {})", room_id_, event_id);
}
});
http::client()->read_event(
room_id_, event_id, [this, event_id](mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn(
"failed to read_event ({}, {})", room_id_, event_id);
}
});
cache::client()->removePendingStatus(room_id_, txn_id);
this->current_txn = "";
this->current_txn_error_count = 0;
emit processPending();
},
Qt::QueuedConnection);
cache::client()->removePendingStatus(room_id_, txn_id);
this->current_txn = "";
this->current_txn_error_count = 0;
emit processPending();
},
Qt::QueuedConnection);
}
void

View File

@ -204,12 +204,11 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
, room_id_(room_id)
, manager_(manager)
{
connect(
this,
&TimelineModel::redactionFailed,
this,
[](const QString &msg) { emit ChatPage::instance()->showNotification(msg); },
Qt::QueuedConnection);
connect(this,
&TimelineModel::redactionFailed,
this,
[](const QString &msg) { emit ChatPage::instance()->showNotification(msg); },
Qt::QueuedConnection);
connect(this,
&TimelineModel::newMessageToSend,
@ -218,17 +217,17 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
Qt::QueuedConnection);
connect(this, &TimelineModel::addPendingMessageToStore, &events, &EventStore::addPending);
connect(
&events,
&EventStore::dataChanged,
this,
[this](int from, int to) {
nhlog::ui()->debug(
"data changed {} to {}", events.size() - to - 1, events.size() - from - 1);
emit dataChanged(index(events.size() - to - 1, 0),
index(events.size() - from - 1, 0));
},
Qt::QueuedConnection);
connect(&events,
&EventStore::dataChanged,
this,
[this](int from, int to) {
nhlog::ui()->debug("data changed {} to {}",
events.size() - to - 1,
events.size() - from - 1);
emit dataChanged(index(events.size() - to - 1, 0),
index(events.size() - from - 1, 0));
},
Qt::QueuedConnection);
connect(&events, &EventStore::beginInsertRows, this, [this](int from, int to) {
int first = events.size() - to;