From cf986694eba41b4cc6db9b7139d8be1ad3cde02b Mon Sep 17 00:00:00 2001 From: jane400 Date: Thu, 19 Sep 2024 21:43:35 +0200 Subject: [PATCH] feat: paket: logout --- paket/src/account.rs | 76 +++++++++++++++++++++++++++++++------------ paket/src/advice.rs | 2 +- paket/src/advices.rs | 7 ++++ paket/src/login.rs | 29 +++++++++++++++-- paket/src/ready.rs | 3 +- paket/src/tracking.rs | 4 +++ 6 files changed, 95 insertions(+), 26 deletions(-) diff --git a/paket/src/account.rs b/paket/src/account.rs index 4ebdf6b..d314bb6 100644 --- a/paket/src/account.rs +++ b/paket/src/account.rs @@ -1,9 +1,8 @@ use adw::prelude::*; -use gtk::gdk; use libpaket::{stammdaten::CustomerDataFull, LibraryError, LibraryResult}; use relm4::{Component, ComponentParts}; -use crate::LoginSharedState; +use crate::{send_log_out, LoginSharedState}; #[tracker::track] pub struct AccountView { @@ -31,6 +30,7 @@ pub enum CopyTargets { #[derive(Debug)] pub enum AccountInput { Copy(CopyTargets), + LogOut, } #[derive(Debug)] @@ -66,31 +66,62 @@ impl Component for AccountView { #[root] adw::Bin { #[wrap(Some)] - set_child = >k::ListBox { - // General infos - append = &adw::PreferencesGroup { - #[track(model.changed_customer_data_full() && model.get_customer_data_full().is_some())] - set_title?: get_str_from_customer_data!(model, display_name).as_ref(), + set_child = >k::ScrolledWindow { + set_propagate_natural_width: true, - // Postnumber - add = &adw::ActionRow { - #[track(model.changed_customer_data_full() && model.get_customer_data_full().is_some())] - set_title?: get_str_from_customer_data!(model, post_number).as_ref(), + #[wrap(Some)] + set_child = &adw::Clamp { + #[wrap(Some)] + set_child = >k::Box { + set_orientation: gtk::Orientation::Vertical, + set_margin_start: 12, + set_margin_end: 12, - set_subtitle: "Postnummer", + set_margin_top: 24, + set_margin_bottom: 24, + + // General infos + append = &adw::PreferencesGroup { + #[track(model.changed_customer_data_full() && model.get_customer_data_full().is_some())] + set_title?: get_str_from_customer_data!(model, display_name).as_ref(), - add_suffix = >k::Button { #[wrap(Some)] - set_child = &adw::ButtonContent { - set_icon_name: relm4_icons::icon_names::COPY, - set_label: "Copy", + set_header_suffix = >k::Box { + add_css_class: relm4::css::LINKED, + + append = >k::Button { + add_css_class: relm4::css::DESTRUCTIVE_ACTION, + set_label: "Log out", + + connect_clicked => AccountInput::LogOut, + }, }, - connect_clicked => AccountInput::Copy(CopyTargets::PostNumber), - }, - } - } - }, + // Postnumber + add = &adw::ActionRow { + add_css_class: relm4::css::NUMERIC, + set_subtitle: "Postnummer", + + #[track(model.changed_customer_data_full() && model.get_customer_data_full().is_some())] + set_title?: get_str_from_customer_data!(model, post_number).as_ref(), + + add_suffix = >k::Button { + set_vexpand: false, + set_valign: gtk::Align::Center, + + #[wrap(Some)] + set_child = &adw::ButtonContent { + set_icon_name: relm4_icons::icon_names::COPY, + set_label: "Copy", + }, + + connect_clicked => AccountInput::Copy(CopyTargets::PostNumber), + }, + } + } + }, + }, + } } } @@ -152,6 +183,9 @@ impl Component for AccountView { clipboard.set_text(value.as_str()); } } + AccountInput::LogOut => { + send_log_out(); + } }; } diff --git a/paket/src/advice.rs b/paket/src/advice.rs index 00eeee6..161b20a 100644 --- a/paket/src/advice.rs +++ b/paket/src/advice.rs @@ -1,5 +1,5 @@ use libpaket::LibraryError; -use relm4::{adw, gtk, gtk::gdk, gtk::gio, gtk::glib}; +use relm4::{adw, gtk, gtk::gdk, gtk::gio}; use adw::prelude::*; use relm4::prelude::*; diff --git a/paket/src/advices.rs b/paket/src/advices.rs index 43eee1c..23e1c0f 100644 --- a/paket/src/advices.rs +++ b/paket/src/advices.rs @@ -117,6 +117,7 @@ pub struct AdvicesView { #[derive(Debug)] pub enum AdvicesViewInput { Fetch, + Reset, } #[derive(Debug)] @@ -197,7 +198,13 @@ impl AsyncComponent for AdvicesView { sender: AsyncComponentSender, root: &Self::Root, ) { + self.reset(); + match message { + AdvicesViewInput::Reset => { + self.set_state(AdvicesViewState::Loading); + self.factory.guard().clear(); + }, AdvicesViewInput::Fetch => { self.set_state(AdvicesViewState::Loading); diff --git a/paket/src/login.rs b/paket/src/login.rs index c9d791a..36e43ea 100644 --- a/paket/src/login.rs +++ b/paket/src/login.rs @@ -196,12 +196,35 @@ impl AsyncComponent for Login { match message { LoginInput::LogOut => { - self.refresh_token = None; - sender.output(LoginOutput::RequiresLogin).unwrap(); + sender.input(LoginInput::NeedsLogin); + { + let token = get_id_token(&self.shared_id_token).await; + if let Some(token) = token { + sender.command(|_, shutdown| { + shutdown + .register(async move { + let client = OpenIdClient::new(); + let _ = client.logout(&token).await; + }) + .drop_on_shutdown() + }); + } + } { let token = self.shared_id_token.lock().await; *token.write() = None; } + if let Some(refresh_token) = self.refresh_token.clone() { + sender.command(|out, shutdown| { + shutdown + .register(async move { + let client = OpenIdClient::new(); + let _ = client.revoke(&refresh_token).await; + }) + .drop_on_shutdown() + }); + } + self.refresh_token = None; let keyring = KEYRING.get().unwrap(); let _ = keyring .delete(&HashMap::from([("app", crate::constants::APP_ID)])) @@ -356,7 +379,7 @@ macro_rules! received { async fn $func_name$args -> LoginCommand { let client = OpenIdClient::new(); let mut err = LibraryError::NetworkFetch; - for _ in 0..6 { + while err == LibraryError::NetworkFetch { let result: Result = client .$calling$calling_args .await; diff --git a/paket/src/ready.rs b/paket/src/ready.rs index 6486eaa..fecb19a 100644 --- a/paket/src/ready.rs +++ b/paket/src/ready.rs @@ -222,7 +222,8 @@ impl Component for Ready { if self.logged_in { sender.output(ReadyOutput::Ready).unwrap(); } else { - todo!(); + self.advices_component.emit(AdvicesViewInput::Reset); + self.tracking_component.emit(TrackingInput::Reset); } } } diff --git a/paket/src/tracking.rs b/paket/src/tracking.rs index d306486..1996a13 100644 --- a/paket/src/tracking.rs +++ b/paket/src/tracking.rs @@ -16,6 +16,7 @@ pub struct TrackingView { pub enum TrackingInput { Search(Option), Notification(String), + Reset, } #[derive(Debug)] @@ -108,6 +109,9 @@ impl Component for TrackingView { fn update(&mut self, message: Self::Input, sender: ComponentSender, root: &Self::Root) { match message { + TrackingInput::Reset => { + self.factory.clear(); + } TrackingInput::Search(value) => { // Some input validation if let Some(value) = &value {