diff --git a/app/data/resources/welcome_dialog.blp b/app/data/resources/welcome_dialog.blp index fa5b67b..e53e279 100644 --- a/app/data/resources/welcome_dialog.blp +++ b/app/data/resources/welcome_dialog.blp @@ -1,187 +1,267 @@ using Gtk 4.0; using Adw 1; -template $WelcomeDialog : Dialog { - height-request: 800; - width-request: 800; +template $WelcomeDialog : Adw.Window { + default-width: 800; + default-height: 800; modal: true; - Adw.Clamp { - maximum-size: 400; - tightening-threshold: 200; - - Stack stack { - StackPage { - name: "welcome-screen"; - - child: Box welcome-screen { - orientation: vertical; - valign: center; - halign: center; - - Label { - label: "Welcome!"; - halign: start; - styles ["title-1"] - } - Label { - label: "Let's get you set up using the app. Enter your information below:"; - wrap: true; - halign: start; - margin-bottom: 20; - } - - Grid { - halign: start; + Adw.NavigationView navigation_view { + Adw.NavigationPage { + tag: "welcome-screen"; + title: "Setup"; + + child: Adw.ToolbarView { + + [top] + Adw.HeaderBar {} + + content: Adw.Clamp { + maximum-size: 400; + margin-top: 12; + margin-bottom: 12; + margin-start: 12; + margin-end: 12; + + Box { + orientation: vertical; + halign: center; valign: center; - row-spacing: 5; - column-spacing: 20; Label { - label: "Email address"; + label: "Welcome!"; halign: start; + styles ["title-1"] } - Entry { - layout { - row: 0; - column: 2; - } - } - Label { - label: "Account name"; + label: "Let's get you set up using the app. Enter your information below:"; + wrap: true; halign: start; + margin-bottom: 20; + } - layout { - row: 1; - column: 0; + Adw.PreferencesGroup { + Adw.EntryRow email_address_entry { + title: "Email address"; } - } - - Entry { - width-request: 270; - - layout { - row: 1; - column: 2; + + Adw.EntryRow account_name_entry { + title: "Account name"; + } + + Adw.EntryRow full_name_entry { + title: "Full name"; + + Image { + pixel-size: 15; + tooltip-text: "Publicly visible. Used in the sender field of your e-mails."; + icon-name: "dialog-information-symbolic"; + } } } + Button { + label: "Next"; + halign: end; + margin-top: 30; + styles ["suggested-action", "pill"] + + clicked => $welcome_screen_next_clicked() swapped; + } + } + }; + }; + } + Adw.NavigationPage { + tag: "connection-details"; + title: "Connection details"; + + child: Adw.ToolbarView { + + [top] + Adw.HeaderBar {} + + content: Adw.Clamp { + maximum-size: 400; + margin-top: 12; + margin-bottom: 12; + margin-start: 12; + margin-end: 12; + + Box { + orientation: vertical; + valign: center; + halign: center; + Label { - label: "Full name"; + label: "We were unable to automatically detect your account connectivity settings. Enter the information below:"; + wrap: true; + hexpand: true; halign: start; - - layout { - row: 2; - column: 0; - } + margin-bottom: 20; } - - Image { - pixel-size: 15; - tooltip-text: "Publicly visible. Used in the sender field of your e-mails."; - icon-name: "dialog-information-symbolic"; - - layout { - row: 2; - column: 1; + + Adw.PreferencesGroup { + Adw.EntryRow imap_server_hostname_entry { + title: "IMAP server hostname"; + } + + Adw.EntryRow imap_server_port_entry { + title: "IMAP server port"; + } + + Adw.PasswordEntryRow imap_password_entry { + title: "IMAP account password"; + } + + Adw.SwitchRow imap_use_tls_switch { + title: "Use TLS"; + active: true; + } + + Adw.SwitchRow imap_use_starttls_switch { + title: "Use StartTLS"; + active: true; } } - - Entry { - layout { - row: 2; - column: 2; - } + Button { + label: "Next"; + halign: end; + margin-top: 30; + styles ["suggested-action", "pill"] + + clicked => $connection_details_next_clicked() swapped; } } - - Button { - label: "Next"; - halign: end; - margin-top: 30; - clicked => $next_clicked() swapped; - } }; - } - StackPage { - name: "authorization-screen"; - - child: Box authorization-screen { - orientation: vertical; - valign: center; - halign: center; - - Label { - label: "Authorization"; - halign: start; - styles ["title-1"] - } - - Label { - label: "Clicking the button will open a browser window requesting you to authorize Envoyer to read your e-mails."; - wrap: true; - halign: start; - } + }; + } + Adw.NavigationPage { + tag: "authorization-screen"; + title: "Authorization"; + + child: Adw.ToolbarView { + + [top] + Adw.HeaderBar {} + + content: Adw.Clamp { + maximum-size: 400; + margin-top: 12; + margin-bottom: 12; + margin-start: 12; + margin-end: 12; - Button { - label: "Authorize"; - halign: end; - margin-top: 30; - clicked => $authorize_clicked() swapped; + Box { + orientation: vertical; + valign: center; + halign: center; + + + Label { + label: "Authorization"; + halign: start; + styles ["title-1"] + } + + Label { + label: "Clicking the button will open a browser window requesting you to authorize Envoyer to read your e-mails."; + wrap: true; + halign: start; + } + + Button { + label: "Authorize"; + halign: end; + margin-top: 30; + styles ["suggested-action", "pill"] + clicked => $authorize_clicked() swapped; + } } }; - } - StackPage { - name: "check-browser"; - - child: Box check-browser { - orientation: vertical; - valign: center; - halign: center; - - Label { - label: "Check your Internet browser"; - halign: start; - styles ["title-1"] - } + }; + } + Adw.NavigationPage { + tag: "check-browser"; + + child: Adw.ToolbarView { + + [top] + Adw.HeaderBar { + show-title: false; + } + + content: Adw.Clamp { + maximum-size: 400; + margin-top: 12; + margin-bottom: 12; + margin-start: 12; + margin-end: 12; - Label { - label: "A browser window was opened to authenticate with your e-mail provider. Please continue there."; - wrap: true; - halign: start; + Box { + orientation: vertical; + valign: center; + halign: center; + + Label { + label: "Check your Internet browser"; + halign: start; + styles ["title-1"] + } + + Label { + label: "A browser window was opened to authenticate with your e-mail provider. Please continue there."; + wrap: true; + halign: start; + } } - }; - } - StackPage { - name: "please-wait"; - - child: Box please-wait { - orientation: vertical; - valign: center; - halign: center; - - Label { - label: "Please wait"; - halign: start; - styles ["title-1"] - } - - Label { - label: "Synchronizing with the server. It may take a while."; - wrap: true; - halign: start; - } + }; + } + Adw.NavigationPage { + tag: "please-wait"; + + child: Adw.ToolbarView { + + [top] + Adw.HeaderBar { + show-title: false; + } + + content: Adw.Clamp { + maximum-size: 400; + margin-top: 12; + margin-bottom: 12; + margin-start: 12; + margin-end: 12; - Spinner spinner { - width-request: 40; - height-request: 40; + Box { + orientation: vertical; + valign: center; + halign: center; + + Label { + label: "Please wait"; + halign: start; + styles ["title-1"] + } + + Label { + label: "Synchronizing with the server. It may take a while."; + wrap: true; + halign: start; + } + + Spinner spinner { + width-request: 40; + height-request: 40; + margin-top: 30; + } } }; - } + }; } } } \ No newline at end of file diff --git a/app/src/ui/welcome_dialog.rs b/app/src/ui/welcome_dialog.rs index 1eb2895..2910719 100644 --- a/app/src/ui/welcome_dialog.rs +++ b/app/src/ui/welcome_dialog.rs @@ -2,39 +2,53 @@ use gtk::glib; use gtk::prelude::*; use gtk::subclass::prelude::*; +use adw; +use adw::subclass::prelude::*; + use std::cell::RefCell; use std::rc::Rc; use crate::controllers::ApplicationMessage; -use crate::ui; +use crate::models; mod imp { + use chrono::{DateTime, Utc}; use gtk::{glib::Properties, CompositeTemplate}; + use log::error; use super::*; - #[derive(Properties, CompositeTemplate, Default)] - #[properties(wrapper_type = super::WelcomeDialog)] + #[derive(CompositeTemplate, Default)] #[template(resource = "/com/github/matzipan/envoyer/welcome_dialog.ui")] pub struct WelcomeDialog { pub sender: Rc>>>, #[template_child] - pub spinner: TemplateChild, + spinner: TemplateChild, + #[template_child] + email_address_entry: TemplateChild, + #[template_child] + full_name_entry: TemplateChild, + #[template_child] + account_name_entry: TemplateChild, + #[template_child] + imap_server_hostname_entry: TemplateChild, + #[template_child] + imap_server_port_entry: TemplateChild, + #[template_child] + imap_password_entry: TemplateChild, + #[template_child] + imap_use_tls_switch: TemplateChild, + #[template_child] + imap_use_starttls_switch: TemplateChild, #[template_child] - pub stack: TemplateChild, - #[property(get, set)] - pub email_address: RefCell>, - #[property(get, set)] - pub full_name: RefCell>, - #[property(get, set)] - pub account_name: RefCell>, + navigation_view: TemplateChild, } #[glib::object_subclass] impl ObjectSubclass for WelcomeDialog { const NAME: &'static str = "WelcomeDialog"; type Type = super::WelcomeDialog; - type ParentType = gtk::Dialog; + type ParentType = adw::Window; fn class_init(klass: &mut Self::Class) { klass.bind_template(); @@ -46,26 +60,71 @@ mod imp { } } - #[glib::derived_properties] impl ObjectImpl for WelcomeDialog {} impl WidgetImpl for WelcomeDialog {} - impl DialogImpl for WelcomeDialog {} impl WindowImpl for WelcomeDialog {} + impl AdwWindowImpl for WelcomeDialog {} #[gtk::template_callbacks] impl WelcomeDialog { #[template_callback] - fn next_clicked(&self) { + fn welcome_screen_next_clicked(&self) { //@TODO check the values - self.stack.get().set_visible_child_name("authorization-screen"); + let email_address = self.email_address_entry.get().text().to_string(); + + if email_address.ends_with("gmail.com") { + self.navigation_view.get().push_by_tag("authorization-screen"); + } else { + self.navigation_view.get().push_by_tag("connection-details"); + } + } + + #[template_callback] + fn connection_details_next_clicked(&self) { + //@TODO check the values + + let email_address = self.email_address_entry.get().text().to_string(); + let full_name = self.full_name_entry.get().text().to_string(); + let account_name = self.account_name_entry.get().text().to_string(); + let imap_server_hostname = self.imap_server_hostname_entry.get().text().to_string(); + let imap_password = self.imap_password_entry.get().text().to_string(); + let imap_use_tls = self.imap_use_tls_switch.get().is_active(); + let imap_use_starttls = self.imap_use_starttls_switch.get().is_active(); + + let imap_server_port = self.imap_server_port_entry.get().text().trim().parse::(); + + if let Ok(imap_server_port) = imap_server_port { + self.sender + .borrow() + .as_ref() + .expect("Message sender not available") + .send(ApplicationMessage::SaveIdentity { + email_address, + full_name, + identity_type: models::IdentityType::Imap, + account_name, + expires_at: DateTime::::MIN_UTC, + imap_server_hostname, + imap_server_port, + imap_password, + imap_use_tls, + imap_use_starttls, + gmail_access_token: String::new(), + gmail_refresh_token: String::new(), + }) + .map_err(|e| e.to_string()) + .map_err(|x| error!("{}", x)); //@TODO + + self.show_please_wait(); + } } #[template_callback] fn authorize_clicked(&self) { - let email_address = self.email_address.borrow().clone().unwrap_or_default(); - let full_name = self.full_name.borrow().clone().unwrap_or_default(); - let account_name = self.account_name.borrow().clone().unwrap_or_default(); + let email_address = self.email_address_entry.get().text().to_string(); + let full_name = self.full_name_entry.get().text().to_string(); + let account_name = self.account_name_entry.get().text().to_string(); self.sender .borrow() @@ -78,14 +137,19 @@ mod imp { }) .expect("Unable to send application message"); - self.stack.set_visible_child_name("check-browser"); + self.navigation_view.get().push_by_tag("check-browser"); + } + + pub fn show_please_wait(&self) { + self.spinner.start(); + self.navigation_view.get().push_by_tag("please-wait"); } } } glib::wrapper! { pub struct WelcomeDialog(ObjectSubclass) - @extends gtk::Widget, gtk::Dialog, gtk::Window; + @extends gtk::Widget, adw::Window, gtk::Window; } impl WelcomeDialog { @@ -102,7 +166,6 @@ impl WelcomeDialog { pub fn show_please_wait(&self) { let imp = self.imp(); - imp.spinner.start(); - imp.stack.set_visible_child_name("please-wait"); + imp.show_please_wait(); } }