diff --git a/internal/frontend/bridge-gui/bridge-gui/Resources.qrc b/internal/frontend/bridge-gui/bridge-gui/Resources.qrc
index e7521f98..a3d0ec7b 100644
--- a/internal/frontend/bridge-gui/bridge-gui/Resources.qrc
+++ b/internal/frontend/bridge-gui/bridge-gui/Resources.qrc
@@ -6,7 +6,11 @@
qml/Banner.qml
qml/Bridge.qml
qml/bridgeqml.qmlproject
+ qml/BugCategoryView.qml
+ qml/BugQuestionView.qml
+ qml/BugReportFlow.qml
qml/BugReportView.qml
+ qml/CategoryItem.qml
qml/Configuration.qml
qml/ConfigurationItem.qml
qml/ContentWrapper.qml
@@ -95,6 +99,7 @@
qml/Proton/TextArea.qml
qml/Proton/TextField.qml
qml/Proton/Toggle.qml
+ qml/QuestionItem.qml
qml/SettingsItem.qml
qml/SettingsView.qml
qml/SetupGuide.qml
@@ -104,4 +109,4 @@
qml/Status.qml
qml/WelcomeGuide.qml
-
+
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/BugCategoryView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/BugCategoryView.qml
new file mode 100644
index 00000000..343aaea1
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/BugCategoryView.qml
@@ -0,0 +1,51 @@
+// Copyright (c) 2023 Proton AG
+// This file is part of Proton Mail Bridge.
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import Proton
+
+SettingsView {
+ id: root
+
+ signal categorySelected(int categoryId)
+
+ fillHeight: true
+
+ property var categories: ["category 1", "category 2"]
+
+ Label {
+ Layout.fillWidth: true
+ colorScheme: root.colorScheme
+ text: qsTr("What's the issue?")
+ type: Label.Heading
+ }
+
+ Repeater {
+ model: root.categories
+
+ CategoryItem {
+ Layout.fillWidth: true
+ actionIcon: "/qml/icons/ic-chevron-right.svg"
+ colorScheme: root.colorScheme
+ text: modelData
+
+ onClicked: root.categorySelected(index)
+ }
+ }
+
+ // fill height so the footer label will always be attached to the bottom
+ Item {
+ Layout.fillHeight: true
+ }
+}
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/BugQuestionView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/BugQuestionView.qml
new file mode 100644
index 00000000..3a18f03b
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/BugQuestionView.qml
@@ -0,0 +1,127 @@
+// Copyright (c) 2023 Proton AG
+// This file is part of Proton Mail Bridge.
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import Proton
+
+SettingsView {
+ id: root
+
+ signal resume
+ signal questionAnswered
+
+ function setDefaultValue() {
+ }
+
+ function next() {
+
+ if (stackLayout.currentIndex >=(stackLayout.count - 1)) {
+ root.questionAnswered();
+ }
+ else
+ {
+ ++stackLayout.currentIndex
+ root.setDefaultValue();
+ }
+ }
+
+ function previous() {
+ if (stackLayout.currentIndex === 0) {
+ root.resume()
+ }
+ else {
+ --stackLayout.currentIndex
+ root.setDefaultValue();
+ }
+ }
+
+ fillHeight: true
+
+ onBack: {
+ root.previous();
+ }
+
+ onVisibleChanged: {
+ root.setDefaultValue();
+ }
+
+ Label {
+ Layout.fillWidth: true
+ colorScheme: root.colorScheme
+ text: qsTr("Give us more details")
+ type: Label.Heading
+ }
+
+ Label {
+ Layout.fillWidth: true
+ colorScheme: root.colorScheme
+ text: qsTr("Step " + (stackLayout.currentIndex + 1) + " of " + stackLayout.count )
+ type: Label.Caption
+ }
+
+ StackLayout {
+ id: stackLayout
+ QuestionItem {
+ Layout.fillWidth: true
+ colorScheme: root.colorScheme
+
+ text: "question 1"
+ type: QuestionItem.InputType.TextInput
+ mandatory: true
+ tips: ""
+ errorString: "please answer the question"
+ }
+
+ QuestionItem {
+ Layout.fillWidth: true
+ colorScheme: root.colorScheme
+
+ text: "question 2"
+ type: QuestionItem.InputType.Radio
+ mandatory: true
+ answerList: ["answer A", "answer B", "answer C","answer D"]
+ tips: ""
+ errorString: "please answer the question"
+ }
+
+ QuestionItem {
+ Layout.fillWidth: true
+ colorScheme: root.colorScheme
+
+ text: "question 3"
+ type: QuestionItem.InputType.Checkbox
+ mandatory: true
+ answerList: ["answer 1", "answer 2", "answer 3","answer 4"]
+ tips: ""
+ errorString: "please answer the question"
+ }
+ }
+ // fill height so the footer label will always be attached to the bottom
+ Item {
+ Layout.fillHeight: true
+ }
+ Button {
+ id: continueButton
+ colorScheme: root.colorScheme
+ enabled: !loading
+ text: qsTr("Continue")
+
+ onClicked: {
+ if (stackLayout.children[stackLayout.currentIndex].validate()) {
+ next();
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/BugReportFlow.qml b/internal/frontend/bridge-gui/bridge-gui/qml/BugReportFlow.qml
new file mode 100644
index 00000000..21f0b911
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/BugReportFlow.qml
@@ -0,0 +1,98 @@
+// Copyright (c) 2023 Proton AG
+// This file is part of Proton Mail Bridge.
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import Proton
+import Notifications
+
+Item {
+ id: root
+
+ property ColorScheme colorScheme
+ property string selectedAddress
+ property var titles: ["Category", "Description", "Confirmation"]
+ property int categoryId: -1
+
+ signal back
+ signal bugReportWasSent
+
+ Rectangle {
+ anchors.fill: parent
+
+ Layout.fillHeight: true // right content background
+ Layout.fillWidth: true
+ color: colorScheme.background_norm
+
+ StackLayout {
+ id: bugReportFlow
+
+ function showBugCategory() {
+ bugReportFlow.currentIndex = 0;
+ }
+ function showBugQuestion() {
+ bugReportFlow.currentIndex = 1;
+ }
+ function showBugReport() {
+ bugReportFlow.currentIndex = 2;
+ }
+
+ anchors.fill: parent
+
+ BugCategoryView {
+ // 0
+ id: bugCategory
+ colorScheme: root.colorScheme
+ path: root.titles
+ currPath: 0
+
+ onBack: {
+ root.back()
+ }
+ onCategorySelected: function(categoryId){
+ root.categoryId = categoryId
+ bugReportFlow.showBugQuestion();
+ }
+ }
+ BugQuestionView {
+ // 1
+ id: bugQuestion
+ colorScheme: root.colorScheme
+ path: root.titles
+ currPath: 1
+
+ onResume: {
+ bugReportFlow.showBugCategory();
+ }
+ onQuestionAnswered: {
+ bugReportFlow.showBugReport();
+ }
+ }
+ BugReportView {
+ // 2
+ id: bugReport
+ colorScheme: root.colorScheme
+ selectedAddress: root.selectedAddress
+ path: root.titles
+ currPath: 2
+
+ onBack: {
+ bugReportFlow.showBugQuestion();
+ }
+ onBugReportWasSent: {
+ root.bugReportWasSent();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/BugReportView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/BugReportView.qml
index 1f7abc73..dbeaeabf 100644
--- a/internal/frontend/bridge-gui/bridge-gui/qml/BugReportView.qml
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/BugReportView.qml
@@ -48,7 +48,7 @@ SettingsView {
Label {
colorScheme: root.colorScheme
- text: qsTr("Report a problem")
+ text: qsTr("Send report")
type: Label.Heading
}
TextArea {
@@ -172,4 +172,4 @@ SettingsView {
target: Backend
}
}
-}
+}
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/CategoryItem.qml b/internal/frontend/bridge-gui/bridge-gui/qml/CategoryItem.qml
new file mode 100644
index 00000000..059c77ea
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/CategoryItem.qml
@@ -0,0 +1,72 @@
+// Copyright (c) 2023 Proton AG
+// This file is part of Proton Mail Bridge.
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import Proton
+
+Item {
+ id: root
+
+ property var _bottomMargin: 20
+ property var _lineHeight: 1
+ property string actionIcon: ""
+ property var colorScheme
+ property bool showSeparator: true
+ property string text: "Text"
+
+ signal clicked
+
+ implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin
+
+ RowLayout {
+ anchors.fill: parent
+ spacing: 16
+
+ Label {
+ id: mainLabel
+ colorScheme: root.colorScheme
+ text: root.text
+ type: Label.Body
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.preferredWidth: parent.width
+ Layout.alignment: Qt.AlignVCenter
+ Layout.bottomMargin: root._bottomMargin
+ wrapMode: Text.WordWrap
+ }
+ Button {
+ id: button
+ Layout.alignment: Qt.AlignVCenter
+ Layout.bottomMargin: root._bottomMargin
+ colorScheme: root.colorScheme
+ icon.source: root.actionIcon
+ text: ""
+ secondary: true
+ visible: root.actionIcon !== ""
+
+ onClicked: {
+ if (!root.loading)
+ root.clicked();
+ }
+ }
+ }
+ Rectangle {
+ anchors.bottom: root.bottom
+ anchors.left: root.left
+ anchors.right: root.right
+ color: colorScheme.border_weak
+ height: root._lineHeight
+ visible: root.showSeparator
+ }
+}
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/ContentWrapper.qml b/internal/frontend/bridge-gui/bridge-gui/qml/ContentWrapper.qml
index eca31c53..b5224262 100644
--- a/internal/frontend/bridge-gui/bridge-gui/qml/ContentWrapper.qml
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/ContentWrapper.qml
@@ -40,10 +40,6 @@ Item {
}
console.error("User with ID ", userID, " was not found in the account list");
}
- function showBugReportAndPrefill(description) {
- rightContent.showBugReport();
- bugReport.setDescription(description);
- }
function showHelp() {
rightContent.showHelpView();
}
@@ -437,7 +433,7 @@ Item {
rightContent.showAccount();
}
}
- BugReportView {
+ BugReportFlow {
// 8
id: bugReport
colorScheme: root.colorScheme
@@ -472,4 +468,4 @@ Item {
}
}
}
-}
+}
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml
index 969567ba..b0277748 100644
--- a/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml
@@ -76,7 +76,7 @@ SettingsView {
SettingsItem {
id: reportBug
Layout.fillWidth: true
- actionText: qsTr("Report a problem")
+ actionText: qsTr("Report problem")
colorScheme: root.colorScheme
description: qsTr("Something not working as expected? Let us know.")
text: qsTr("Report a problem")
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml b/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml
index a76c1a6a..a16ebc52 100644
--- a/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml
@@ -35,9 +35,6 @@ ApplicationWindow {
root.requestActivate();
}
}
- function showBugReportAndPrefill(message) {
- contentWrapper.showBugReportAndPrefill(message);
- }
function showHelp() {
contentWrapper.showHelp();
}
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/QuestionItem.qml b/internal/frontend/bridge-gui/bridge-gui/qml/QuestionItem.qml
new file mode 100644
index 00000000..712284f9
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/QuestionItem.qml
@@ -0,0 +1,153 @@
+// Copyright (c) 2023 Proton AG
+// This file is part of Proton Mail Bridge.
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import Proton
+
+Item {
+ id: root
+ enum InputType {
+ TextInput = 1,
+ Radio,
+ Checkbox
+ }
+
+ property var colorScheme
+ property string text: ""
+ property string tips: ""
+ property string errorString: ""
+ property bool error: false
+ property var type: QuestionItem.InputType.TextInput
+ property bool mandatory: true
+ property var answerList: ListModel{}
+ property string answer:{
+ if (type === QuestionItem.InputType.TextInput) {
+ return textInput.text
+ } else if (type === QuestionItem.InputType.Radio) {
+ return selectionRadio.text
+ } else if (type === QuestionItem.InputType.Checkbox) {
+ return selectionCheckBox.text
+ }
+ return ""
+ }
+
+ function validate() {
+ if (type === QuestionItem.InputType.TextInput) {
+ textInput.validate()
+ root.error = textInput.error
+ } else if (type === QuestionItem.InputType.Radio) {
+ selectionRadio.validate()
+ } else if (type === QuestionItem.InputType.Checkbox) {
+ selectionCheckBox.validate()
+ }
+ return !root.error
+ }
+
+ implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: 16
+
+ Label {
+ id: mainLabel
+ colorScheme: root.colorScheme
+ text: qsTr(root.text)
+ type: Label.Body
+ }
+ ColumnLayout {
+ spacing: 16
+ TextArea {
+ id: textInput
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.minimumHeight: root.type === QuestionItem.InputType.TextInput ? heightForLinesVisible(2) : 0
+ colorScheme: root.colorScheme
+
+ label: qsTr("Your answer")
+ placeholderText: qsTr(root.tips)
+
+ validator: function (str) {
+ if (root.mandatory && str.length === 0) {
+ return root.errorStr;
+ }
+ return;
+ }
+
+ visible: root.type === QuestionItem.InputType.TextInput
+ }
+
+ ButtonGroup {
+ id: selectionRadio
+ property string text: {
+ return checkedButton ? checkedButton.text : "";
+ }
+
+ function validate() {
+ root.error = false
+ }
+ }
+ Repeater {
+ model: root.answerList
+
+ RadioButton {
+ ButtonGroup.group: selectionRadio
+ colorScheme: root.colorScheme
+ text: modelData
+ visible: root.type === QuestionItem.InputType.Radio
+ }
+ }
+ ButtonGroup {
+ id: selectionCheckBox
+ exclusive: false
+ property string text: {
+ var str = "";
+ for (var i = 0; i < buttons.length; ++i) {
+ if (buttons[i].checked) {
+ str += buttons[i].text + " ";
+ }
+ }
+ return str;
+ }
+
+ function validate() {
+ root.error = false
+ }
+ }
+ Repeater {
+ model: root.answerList
+
+ CheckBox {
+ ButtonGroup.group: selectionCheckBox
+ colorScheme: root.colorScheme
+ text: modelData
+ visible: root.type === QuestionItem.InputType.Checkbox
+ }
+ }
+ }
+ }
+ Label {
+ id: errorText
+ Layout.fillWidth: true
+ visible: root.error
+ color: root.colorScheme.signal_danger
+ colorScheme: root.colorScheme
+ text: root.errorString
+ type: Label.LabelType.Caption_semibold
+ }
+ // fill height so the footer label will always be attached to the bottom
+ Item {
+ Layout.fillHeight: true
+ }
+}
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/SettingsView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/SettingsView.qml
index e4619052..06718b3a 100644
--- a/internal/frontend/bridge-gui/bridge-gui/qml/SettingsView.qml
+++ b/internal/frontend/bridge-gui/bridge-gui/qml/SettingsView.qml
@@ -29,6 +29,8 @@ Item {
// fillHeight indicates whether the SettingsView should fill all available explicit height set
property bool fillHeight: false
default property alias items: content.children
+ property var path: ListModel{}
+ property var currPath: 0
signal back
@@ -61,6 +63,37 @@ Item {
Layout.rightMargin: root._rightMargin
Layout.topMargin: root._topMargin
spacing: root._spacing
+ ListView {
+ id: trackPath
+ Layout.fillWidth: true
+ Layout.topMargin: root._topMargin
+ Layout.bottomMargin: root._spacing
+
+ interactive: false
+ orientation: ListView.Horizontal
+ model: path
+
+ delegate: Item{
+ width: children[0].width + children[0].spacing
+ RowLayout {
+ Label {
+ colorScheme: root.colorScheme
+ text: qsTr(modelData)
+ type: Label.Caption
+ color: index === currPath ? colorScheme.interaction_norm : colorScheme.text_hint
+ }
+ Label {
+ colorScheme: root.colorScheme
+ text: "/"
+ color: colorScheme.text_hint
+ type: Label.Caption
+ visible: index < (root.path.length - 1)
+ }
+ }
+ }
+
+ visible: model.length > 0
+ }
}
Item {
id: filler