feat(GODT-2769): Setup Wizard QML foundations.

This commit is contained in:
Xavier Michelon
2023-08-11 11:28:54 +02:00
parent 7355c7dfd6
commit 0a51c7a6b0
10 changed files with 158 additions and 183 deletions

View File

@ -28,8 +28,8 @@ Item {
property var notifications property var notifications
property var user property var user
signal showSetupGuide(var user, string address) signal showClientConfigurator(var user, string address)
signal showSignIn(var username) signal showLogin(var username)
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
@ -93,7 +93,7 @@ Item {
onClicked: { onClicked: {
if (user) { if (user) {
root.showSignIn(user.primaryEmailOrUsername()); root.showLogin(user.primaryEmailOrUsername());
} }
} }
} }
@ -129,7 +129,7 @@ Item {
onClicked: { onClicked: {
if (!root.user) if (!root.user)
return; return;
root.showSetupGuide(root.user, user.addresses[0]); root.showClientConfigurator(root.user, user.addresses[0]);
} }
} }
SettingsItem { SettingsItem {
@ -171,7 +171,7 @@ Item {
onClicked: { onClicked: {
if (!root.user) if (!root.user)
return; return;
root.showSetupGuide(root.user, addressSelector.displayText); root.showClientConfigurator(root.user, addressSelector.displayText);
} }
} }
} }

View File

@ -24,9 +24,8 @@ Item {
signal closeWindow signal closeWindow
signal quitBridge signal quitBridge
signal showSetupGuide(var user, string address) signal showClientConfigurator(var user, string address)
signal showSignIn(var username) signal showLogin(var username)
signal showSetupWizard()
function selectUser(userID) { function selectUser(userID) {
const users = Backend.users; const users = Backend.users;
@ -37,7 +36,7 @@ Item {
} }
accounts.currentIndex = i; accounts.currentIndex = i;
if (user.state === EUserState.SignedOut) if (user.state === EUserState.SignedOut)
showSignIn(user.primaryEmailOrUsername()); showLogin(user.primaryEmailOrUsername());
return; return;
} }
console.error("User with ID ", userID, " was not found in the account list"); console.error("User with ID ", userID, " was not found in the account list");
@ -55,7 +54,6 @@ Item {
rightContent.showGeneralSettings(); rightContent.showGeneralSettings();
} }
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
@ -235,7 +233,7 @@ Item {
if (user.state !== EUserState.SignedOut) { if (user.state !== EUserState.SignedOut) {
rightContent.showAccount(); rightContent.showAccount();
} else { } else {
showSignIn(user.primaryEmailOrUsername()); showLogin(user.primaryEmailOrUsername());
} }
} }
} }
@ -283,7 +281,7 @@ Item {
width: 36 width: 36
onClicked: { onClicked: {
root.showSignIn("") root.showLogin("");
} }
} }
} }
@ -338,16 +336,16 @@ Item {
return Backend.users.get(accounts.currentIndex); return Backend.users.get(accounts.currentIndex);
} }
onShowSetupGuide: function (user, address) { onShowClientConfigurator: function (user, address) {
root.showSetupGuide(user, address); root.showClientConfigurator(user, address);
} }
onShowSignIn: function (username) { onShowLogin: function (username) {
root.showSignIn(username) root.showLogin(username);
} }
} }
Rectangle { Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true
color: "#ff9900" color: "#ff9900"
} }
GeneralSettings { GeneralSettings {

View File

@ -26,6 +26,22 @@ ApplicationWindow {
property int _defaultWidth: 1080 property int _defaultWidth: 1080
property var notifications property var notifications
function layoutForUserCount(userCount) {
if (userCount === 0) {
showLogin();
return;
}
const u = Backend.users.get(0);
if (!u) {
console.trace();
console.log("empty user");
setupWizard.showOnboarding();
return;
}
if ((userCount === 1) && (u.state === EUserState.SignedOut)) {
setupWizard.showLogin(u.primaryEmailOrUsername());
}
}
function selectUser(userID) { function selectUser(userID) {
contentWrapper.selectUser(userID); contentWrapper.selectUser(userID);
} }
@ -36,54 +52,38 @@ ApplicationWindow {
root.requestActivate(); root.requestActivate();
} }
} }
function showClientConfigurator(user, address) {
contentLayout.currentIndex = 1;
setupWizard.showClientConfig(user, address);
}
function showHelp() { function showHelp() {
showWebViewOverlay("https://proton.me/support/bridge"); showWebViewOverlay("https://proton.me/support/bridge");
} }
function showLocalCacheSettings() { function showLocalCacheSettings() {
contentWrapper.showLocalCacheSettings(); contentWrapper.showLocalCacheSettings();
} }
function showLogin(username = "") {
contentLayout.currentIndex = 1;
setupWizard.showLogin(username);
}
function showSettings() { function showSettings() {
contentWrapper.showSettings(); contentWrapper.showSettings();
} }
function showSetup(user, address) {
contentLayout.currentIndex = 1;
setupWizard.showClientConfig(user, address)
}
function showSignIn(username) {
contentLayout.currentIndex = 1;
setupWizard.showLogin(username)
}
function showWebViewOverlay(url) { function showWebViewOverlay(url) {
webViewOverlay.visible = true; webViewOverlay.visible = true;
webViewOverlay.url = url; webViewOverlay.url = url;
} }
function layoutForUserCount(userCount) {
if (userCount === 0) {
showSignIn("");
return;
}
const u = Backend.users.get(0);
if (!u) {
console.trace();
console.log("empty user");
setupWizard.showOnboarding();
return;
}
if ((userCount === 1) && (u.state === EUserState.SignedOut)) {
setupWizard.showLogin(u.primaryEmailOrUsername());
}
}
colorScheme: ProtonStyle.currentStyle colorScheme: ProtonStyle.currentStyle
height: _defaultHeight height: _defaultHeight
minimumWidth: _defaultWidth minimumWidth: _defaultWidth
visible: true visible: true
width: _defaultWidth width: _defaultWidth
Component.onCompleted: {
layoutForUserCount(Backend.users.count);
}
// show Setup Guide on every new user // show Setup Guide on every new user
Connections { Connections {
function onRowsAboutToBeRemoved(parent, first, last) { function onRowsAboutToBeRemoved(parent, first, last) {
@ -103,7 +103,7 @@ ApplicationWindow {
if (user.setupGuideSeen) { if (user.setupGuideSeen) {
return; return;
} }
root.showSetup(user, user.addresses[0]); root.showClientConfigurator(user, user.addresses[0]);
} }
target: Backend.users target: Backend.users
@ -129,17 +129,15 @@ ApplicationWindow {
target: Backend target: Backend
} }
Connections { Connections {
function onCountChanged(count) { function onCountChanged(count) {
layoutForUserCount(count) layoutForUserCount(count);
} }
target: Backend.users target: Backend.users
} }
StackLayout { StackLayout {
id: contentLayout id: contentLayout
anchors.fill: parent anchors.fill: parent
currentIndex: 0 currentIndex: 0
@ -160,29 +158,27 @@ ApplicationWindow {
root.close(); root.close();
Backend.quit(); Backend.quit();
} }
onShowSetupGuide: function (user, address) { onShowClientConfigurator: function (user, address) {
root.showSetup(user, address); root.showClientConfigurator(user, address);
} }
onShowSignIn: function(username) { onShowLogin: function (username) {
root.showSignIn(username) root.showLogin(username);
} }
} }
SetupWizard { SetupWizard {
id: setupWizard id: setupWizard
Layout.fillWidth: true; Layout.fillHeight: true
Layout.fillHeight: true; Layout.fillWidth: true
colorScheme: root.colorScheme colorScheme: root.colorScheme
onWizardEnded: {
contentLayout.currentIndex = 0
}
onShowBugReport: { onShowBugReport: {
contentWrapper.showBugReport(); contentWrapper.showBugReport();
} }
onWizardEnded: {
contentLayout.currentIndex = 0;
}
} }
} }
WebView { WebView {
id: webViewOverlay id: webViewOverlay
anchors.fill: parent anchors.fill: parent
@ -200,8 +196,4 @@ ApplicationWindow {
id: splashScreen id: splashScreen
colorScheme: root.colorScheme colorScheme: root.colorScheme
} }
Component.onCompleted: {
layoutForUserCount(Backend.users.count)
}
} }

View File

@ -238,12 +238,12 @@ FocusScope {
bottomPadding: 8 bottomPadding: 8
color: { color: {
if (!control.enabled) { if (!control.enabled) {
return root.colorScheme.text_disabled return root.colorScheme.text_disabled;
} }
if (control.readOnly) { if (control.readOnly) {
return root.colorScheme.text_hint return root.colorScheme.text_hint;
} }
return root.colorScheme.text_norm return root.colorScheme.text_norm;
} }
// enforcing default focus here within component // enforcing default focus here within component

View File

@ -20,24 +20,27 @@ import ".."
Rectangle { Rectangle {
id: root id: root
property var wizard
color: colorScheme.background_weak
readonly property bool genericClient: SetupWizard.Client.Generic === wizard.client readonly property bool genericClient: SetupWizard.Client.Generic === wizard.client
property var wizard
color: colorScheme.background_weak
Item { Item {
id: centeredContainer id: centeredContainer
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom
width: 800 width: 800
ColumnLayout { ColumnLayout {
anchors.bottomMargin: 96
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.bottomMargin: 96
anchors.topMargin: 32 anchors.topMargin: 32
spacing: 0 spacing: 0
Label { Label {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true Layout.fillWidth: true
@ -55,18 +58,17 @@ Rectangle {
color: colorScheme.text_weak color: colorScheme.text_weak
colorScheme: wizard.colorScheme colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: genericClient ? qsTr("Here are the IMAP and SMTP configuration parameters for your email client") : text: genericClient ? qsTr("Here are the IMAP and SMTP configuration parameters for your email client") : qsTr("Here are your email configuration parameters for %1. \nWe have prepared an easy to follow configuration guide to help you setup your account in %1.").arg(wizard.clientName())
qsTr("Here are your email configuration parameters for %1. \nWe have prepared an easy to follow configuration guide to help you setup your account in %1.").arg(wizard.clientName())
type: Label.LabelType.Body type: Label.LabelType.Body
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
} }
RowLayout { RowLayout {
id: configuration id: configuration
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 32 Layout.topMargin: 32
spacing: 64 spacing: 64
Configuration { Configuration {
Layout.fillWidth: true Layout.fillWidth: true
colorScheme: wizard.colorScheme colorScheme: wizard.colorScheme
@ -88,7 +90,6 @@ Rectangle {
username: wizard.address username: wizard.address
} }
} }
Button { Button {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: 444 Layout.preferredWidth: 444
@ -97,17 +98,16 @@ Rectangle {
text: qsTr("Open configuration guide") text: qsTr("Open configuration guide")
visible: !genericClient visible: !genericClient
} }
Button { Button {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: 444 Layout.preferredWidth: 444
Layout.topMargin: 32 Layout.topMargin: 32
colorScheme: wizard.colorScheme colorScheme: wizard.colorScheme
text: qsTr("Done") text: qsTr("Done")
onClicked: wizard.closeWizard() onClicked: wizard.closeWizard()
} }
} }
LinkLabel { LinkLabel {
id: reportProblemLink id: reportProblemLink
anchors.bottom: parent.bottom anchors.bottom: parent.bottom

View File

@ -61,8 +61,8 @@ Item {
Label { Label {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
colorScheme: wizard.colorScheme colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter
text: qsTr("Do not enter your Proton account password in you email application.") text: qsTr("Do not enter your Proton account password in you email application.")
type: Label.LabelType.Body type: Label.LabelType.Body
wrapMode: Text.WordWrap wrapMode: Text.WordWrap

View File

@ -20,15 +20,8 @@ import ".."
Item { Item {
id: root id: root
property var wizard
function showClientSelector() { property var wizard
titleLabel.text = qsTr("Configure your email client");
descriptionLabel.text = qsTr("Bridge is now connected to Proton, and has already started downloading your messages. Lets now connect your email client to Bridge.");
linkLabel1.clear();
linkLabel2.clear();
icon.source = "/qml/icons/img-mail-clients.svg";
}
function showClientConfigCommon() { function showClientConfigCommon() {
const clientName = wizard.clientName(); const clientName = wizard.clientName();
@ -40,26 +33,29 @@ Item {
Layout.preferredHeight = 72; Layout.preferredHeight = 72;
Layout.preferredWidth = 72; Layout.preferredWidth = 72;
} }
function showClientConfigWarning() { function showClientConfigWarning() {
showClientConfigCommon(); showClientConfigCommon();
linkLabel1.setLink("https://proton.me/support/bridge", qsTr("Why can't I use my Proton password in my email client?")); linkLabel1.setLink("https://proton.me/support/bridge", qsTr("Why can't I use my Proton password in my email client?"));
} }
function showClientSelector() {
titleLabel.text = qsTr("Configure your email client");
descriptionLabel.text = qsTr("Bridge is now connected to Proton, and has already started downloading your messages. Lets now connect your email client to Bridge.");
linkLabel1.clear();
linkLabel2.clear();
icon.source = "/qml/icons/img-mail-clients.svg";
}
function showLogin() { function showLogin() {
descriptionLabel.text = qsTr("Let's start by signing in to your Proton account."); descriptionLabel.text = qsTr("Let's start by signing in to your Proton account.");
linkLabel1.setLink("https://proton.me/mail/pricing", qsTr("Create or upgrade your account")); linkLabel1.setLink("https://proton.me/mail/pricing", qsTr("Create or upgrade your account"));
linkLabel2.clear(); linkLabel2.clear();
showLoginCommon(); showLoginCommon();
} }
function showLogin2FA() { function showLogin2FA() {
descriptionLabel.text = qsTr("You have enabled two-factor authentication. Please enter the 6-digit code provided by your authenticator application."); descriptionLabel.text = qsTr("You have enabled two-factor authentication. Please enter the 6-digit code provided by your authenticator application.");
linkLabel1.clear(); linkLabel1.clear();
linkLabel2.clear(); linkLabel2.clear();
showLoginCommon(); showLoginCommon();
} }
function showLoginCommon() { function showLoginCommon() {
titleLabel.text = qsTr("Sign in to your Proton Account"); titleLabel.text = qsTr("Sign in to your Proton Account");
icon.Layout.preferredHeight = 72; icon.Layout.preferredHeight = 72;
@ -68,14 +64,12 @@ Item {
icon.sourceSize.height = 128; icon.sourceSize.height = 128;
icon.sourceSize.width = 128; icon.sourceSize.width = 128;
} }
function showLoginMailboxPassword() { function showLoginMailboxPassword() {
descriptionLabel.text = qsTr("You have secured your account with a separate mailbox password."); descriptionLabel.text = qsTr("You have secured your account with a separate mailbox password.");
linkLabel1.clear(); linkLabel1.clear();
linkLabel2.clear(); linkLabel2.clear();
showLoginCommon(); showLoginCommon();
} }
function showOnboarding() { function showOnboarding() {
titleLabel.text = qsTr("Welcome to\nProton Mail Bridge"); titleLabel.text = qsTr("Welcome to\nProton Mail Bridge");
descriptionLabel.text = qsTr("Bridge is the gateway between your Proton account and your email client. It runs in the background and encrypts and decrypts your messages seamlessly. "); descriptionLabel.text = qsTr("Bridge is the gateway between your Proton account and your email client. It runs in the background and encrypts and decrypts your messages seamlessly. ");
@ -87,7 +81,6 @@ Item {
icon.sourceSize.height = 148; icon.sourceSize.height = 148;
icon.sourceSize.width = 265; icon.sourceSize.width = 265;
} }
function showOutlookSelector() { function showOutlookSelector() {
showClientConfigCommon(); showClientConfigCommon();
linkLabel1.setLink("https://proton.me/support/bridge", qsTr("My version of Outlook is not listed")); linkLabel1.setLink("https://proton.me/support/bridge", qsTr("My version of Outlook is not listed"));
@ -98,7 +91,6 @@ Item {
function onLogin2FARequested() { function onLogin2FARequested() {
showLogin2FA(); showLogin2FA();
} }
function onLogin2PasswordRequested() { function onLogin2PasswordRequested() {
showLoginMailboxPassword(); showLoginMailboxPassword();
} }

View File

@ -19,10 +19,15 @@ import Proton
FocusScope { FocusScope {
id: root id: root
enum RootStack {
Login,
TOTP,
MailboxPassword
}
property var wizard
property alias currentIndex: stackLayout.currentIndex property alias currentIndex: stackLayout.currentIndex
property alias username: usernameTextField.text property alias username: usernameTextField.text
property var wizard
signal loginAbort(string username, bool wasSignedOut) signal loginAbort(string username, bool wasSignedOut)
@ -32,10 +37,10 @@ FocusScope {
Backend.loginAbort(usernameTextField.text); Backend.loginAbort(usernameTextField.text);
} }
function reset(clearUsername = false) { function reset(clearUsername = false) {
stackLayout.currentIndex = 0; stackLayout.currentIndex = Login.RootStack.Login;
loginNormalLayout.reset(clearUsername); loginLayout.reset(clearUsername);
login2FALayout.reset(); totpLayout.reset();
login2PasswordLayout.reset(); mailboxPasswordLayout.reset();
} }
implicitHeight: children[0].implicitHeight implicitHeight: children[0].implicitHeight
@ -55,7 +60,7 @@ FocusScope {
Connections { Connections {
function onLogin2FAError(_) { function onLogin2FAError(_) {
console.assert(stackLayout.currentIndex === 1, "Unexpected login2FAError"); console.assert(stackLayout.currentIndex === Login.RootStack.TOTP, "Unexpected login2FAError");
twoFAButton.loading = false; twoFAButton.loading = false;
twoFactorPasswordTextField.enabled = true; twoFactorPasswordTextField.enabled = true;
twoFactorPasswordTextField.error = true; twoFactorPasswordTextField.error = true;
@ -63,18 +68,18 @@ FocusScope {
twoFactorPasswordTextField.focus = true; twoFactorPasswordTextField.focus = true;
} }
function onLogin2FAErrorAbort(_) { function onLogin2FAErrorAbort(_) {
console.assert(stackLayout.currentIndex === 1, "Unexpected login2FAErrorAbort"); console.assert(stackLayout.currentIndex === Login.RootStack.TOTP, "Unexpected login2FAErrorAbort");
root.reset(); root.reset();
errorLabel.text = qsTr("Incorrect login credentials. Please try again."); errorLabel.text = qsTr("Incorrect login credentials. Please try again.");
} }
function onLogin2FARequested(username) { function onLogin2FARequested(username) {
console.assert(stackLayout.currentIndex === 0, "Unexpected login2FARequested"); console.assert(stackLayout.currentIndex === Login.RootStack.Login, "Unexpected login2FARequested");
twoFactorUsernameLabel.text = username; twoFactorUsernameLabel.text = username;
stackLayout.currentIndex = 1; stackLayout.currentIndex = Login.RootStack.TOTP;
twoFactorPasswordTextField.focus = true; twoFactorPasswordTextField.focus = true;
} }
function onLogin2PasswordError(_) { function onLogin2PasswordError(_) {
console.assert(stackLayout.currentIndex === 2, "Unexpected login2PasswordError"); console.assert(stackLayout.currentIndex === Login.RootStack.MailboxPassword, "Unexpected login2PasswordError");
secondPasswordButton.loading = false; secondPasswordButton.loading = false;
secondPasswordTextField.enabled = true; secondPasswordTextField.enabled = true;
secondPasswordTextField.error = true; secondPasswordTextField.error = true;
@ -82,34 +87,34 @@ FocusScope {
secondPasswordTextField.focus = true; secondPasswordTextField.focus = true;
} }
function onLogin2PasswordErrorAbort(_) { function onLogin2PasswordErrorAbort(_) {
console.assert(stackLayout.currentIndex === 2, "Unexpected login2PasswordErrorAbort"); console.assert(stackLayout.currentIndex === Login.RootStack.MailboxPassword, "Unexpected login2PasswordErrorAbort");
root.reset(); root.reset();
errorLabel.text = qsTr("Incorrect login credentials. Please try again."); errorLabel.text = qsTr("Incorrect login credentials. Please try again.");
} }
function onLogin2PasswordRequested() { function onLogin2PasswordRequested() {
console.assert(stackLayout.currentIndex === 0 || stackLayout.currentIndex === 1, "Unexpected login2PasswordRequested"); console.assert(stackLayout.currentIndex === Login.RootStack.Login || stackLayout.currentIndex === Login.RootStack.TOTP, "Unexpected login2PasswordRequested");
stackLayout.currentIndex = 2; stackLayout.currentIndex = Login.RootStack.MailboxPassword;
secondPasswordTextField.focus = true; secondPasswordTextField.focus = true;
} }
function onLoginAlreadyLoggedIn(_) { function onLoginAlreadyLoggedIn(_) {
stackLayout.currentIndex = 0; stackLayout.currentIndex = Login.RootStack.Login;
root.reset(); root.reset();
} }
function onLoginConnectionError(_) { function onLoginConnectionError(_) {
if (stackLayout.currentIndex === 0) { if (stackLayout.currentIndex === Login.RootStack.Login) {
stackLayout.loginFailed(); stackLayout.loginFailed();
} }
} }
function onLoginFinished(_) { function onLoginFinished(_) {
stackLayout.currentIndex = 0; stackLayout.currentIndex = Login.RootStack.Login;
root.reset(); root.reset();
} }
function onLoginFreeUserError() { function onLoginFreeUserError() {
console.assert(stackLayout.currentIndex === 0, "Unexpected loginFreeUserError"); console.assert(stackLayout.currentIndex === Login.RootStack.Login, "Unexpected loginFreeUserError");
stackLayout.loginFailed(); stackLayout.loginFailed();
} }
function onLoginUsernamePasswordError(errorMsg) { function onLoginUsernamePasswordError(errorMsg) {
console.assert(stackLayout.currentIndex === 0, "Unexpected loginUsernamePasswordError"); console.assert(stackLayout.currentIndex === Login.RootStack.Login, "Unexpected loginUsernamePasswordError");
stackLayout.loginFailed(); stackLayout.loginFailed();
if (errorMsg !== "") if (errorMsg !== "")
errorLabel.text = errorMsg; errorLabel.text = errorMsg;
@ -120,7 +125,7 @@ FocusScope {
target: Backend target: Backend
} }
ColumnLayout { ColumnLayout {
id: loginNormalLayout id: loginLayout
function reset(clearUsername = false) { function reset(clearUsername = false) {
signInButton.loading = false; signInButton.loading = false;
errorLabel.text = ""; errorLabel.text = "";
@ -262,7 +267,7 @@ FocusScope {
} }
} }
ColumnLayout { ColumnLayout {
id: login2FALayout id: totpLayout
function reset() { function reset() {
twoFAButton.loading = false; twoFAButton.loading = false;
twoFactorPasswordTextField.enabled = true; twoFactorPasswordTextField.enabled = true;
@ -342,7 +347,7 @@ FocusScope {
} }
} }
ColumnLayout { ColumnLayout {
id: login2PasswordLayout id: mailboxPasswordLayout
function reset() { function reset() {
secondPasswordButton.loading = false; secondPasswordButton.loading = false;
secondPasswordTextField.enabled = true; secondPasswordTextField.enabled = true;

View File

@ -19,6 +19,7 @@ import "." as Proton
Item { Item {
id: root id: root
property var wizard property var wizard
ColumnLayout { ColumnLayout {
@ -55,7 +56,7 @@ Item {
colorScheme: wizard.colorScheme colorScheme: wizard.colorScheme
text: qsTr("Let's start") text: qsTr("Let's start")
onClicked: wizard.showLogin(); onClicked: wizard.showLogin()
} }
} }
} }

View File

@ -26,28 +26,26 @@ Item {
MozillaThunderbird, MozillaThunderbird,
Generic Generic
} }
enum RootStack {
TwoPanesView = 0,
ClientConfigParameters = 1
}
enum ContentStack { enum ContentStack {
Onboarding = 0, Onboarding,
Login = 1, Login,
ClientConfigSelector = 2, ClientConfigSelector,
ClientConfigOutlookSelector = 3, ClientConfigOutlookSelector,
ClientConfigWarning = 4 ClientConfigWarning
}
enum RootStack {
TwoPanesView,
ClientConfigParameters
} }
property string address
property int client property int client
property string clientVersion property string clientVersion
property ColorScheme colorScheme property ColorScheme colorScheme
property var user property var user
property string address
signal wizardEnded() signal showBugReport
signal showBugReport() signal wizardEnded
function clientIconSource() { function clientIconSource() {
switch (client) { switch (client) {
@ -60,11 +58,10 @@ Item {
case SetupWizard.Client.Generic: case SetupWizard.Client.Generic:
return "/qml/icons/ic-other-mail-clients.svg"; return "/qml/icons/ic-other-mail-clients.svg";
default: default:
console.error("Unknown mail client " + client) console.error("Unknown mail client " + client);
return "/qml/icons/ic-other-mail-clients.svg"; return "/qml/icons/ic-other-mail-clients.svg";
} }
} }
function clientName() { function clientName() {
switch (client) { switch (client) {
case SetupWizard.Client.AppleMail: case SetupWizard.Client.AppleMail:
@ -76,35 +73,28 @@ Item {
case SetupWizard.Client.Generic: case SetupWizard.Client.Generic:
return "your email client"; return "your email client";
default: default:
console.error("Unknown mail client " + client) console.error("Unknown mail client " + client);
return "your email client"; return "your email client";
} }
} }
function closeWizard() { function closeWizard() {
wizardEnded() wizardEnded();
} }
function showOutlookSelector() {
rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
leftContent.showOutlookSelector();
rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigOutlookSelector;
}
function showOnboarding() {
rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
leftContent.showOnboarding();
rightContent.currentIndex = SetupWizard.ContentStack.Onboarding;
}
function showClientConfig(user, address) { function showClientConfig(user, address) {
root.user = user root.user = user;
root.address = address root.address = address;
rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView; rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
leftContent.showClientSelector(); leftContent.showClientSelector();
rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigSelector; rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigSelector;
} }
function showClientParams() {
rootStackLayout.currentIndex = SetupWizard.RootStack.ClientConfigParameters;
}
function showClientWarning() {
rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
leftContent.showClientConfigWarning();
rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigWarning;
}
function showLogin(username = "") { function showLogin(username = "") {
rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView; rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
root.address = ""; root.address = "";
@ -113,16 +103,15 @@ Item {
login.reset(true); login.reset(true);
login.username = username; login.username = username;
} }
function showOnboarding() {
function showClientWarning() {
rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView; rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
leftContent.showClientConfigWarning(); leftContent.showOnboarding();
rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigWarning rightContent.currentIndex = SetupWizard.ContentStack.Onboarding;
} }
function showOutlookSelector() {
function showClientParams() { rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
rootStackLayout.currentIndex = SetupWizard.RootStack.ClientConfigParameters; leftContent.showOutlookSelector();
rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigOutlookSelector;
} }
Connections { Connections {
@ -131,14 +120,13 @@ Item {
closeWizard(); closeWizard();
return; return;
} }
let user = Backend.users.get(userIndex) let user = Backend.users.get(userIndex);
let address = user ? user.addresses[0] : "" let address = user ? user.addresses[0] : "";
showClientConfig(user, address); showClientConfig(user, address);
} }
target: Backend target: Backend
} }
StackLayout { StackLayout {
id: rootStackLayout id: rootStackLayout
anchors.fill: parent anchors.fill: parent
@ -157,7 +145,6 @@ Item {
LeftPane { LeftPane {
id: leftContent id: leftContent
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: 96 anchors.bottomMargin: 96
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter