feat: paket: logout

This commit is contained in:
jane400 2024-09-19 21:43:35 +02:00 committed by jane400
parent 4d0f8f57ce
commit cf986694eb
6 changed files with 95 additions and 26 deletions

View file

@ -1,9 +1,8 @@
use adw::prelude::*; use adw::prelude::*;
use gtk::gdk;
use libpaket::{stammdaten::CustomerDataFull, LibraryError, LibraryResult}; use libpaket::{stammdaten::CustomerDataFull, LibraryError, LibraryResult};
use relm4::{Component, ComponentParts}; use relm4::{Component, ComponentParts};
use crate::LoginSharedState; use crate::{send_log_out, LoginSharedState};
#[tracker::track] #[tracker::track]
pub struct AccountView { pub struct AccountView {
@ -31,6 +30,7 @@ pub enum CopyTargets {
#[derive(Debug)] #[derive(Debug)]
pub enum AccountInput { pub enum AccountInput {
Copy(CopyTargets), Copy(CopyTargets),
LogOut,
} }
#[derive(Debug)] #[derive(Debug)]
@ -66,31 +66,62 @@ impl Component for AccountView {
#[root] #[root]
adw::Bin { adw::Bin {
#[wrap(Some)] #[wrap(Some)]
set_child = &gtk::ListBox { set_child = &gtk::ScrolledWindow {
// General infos set_propagate_natural_width: true,
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(),
// Postnumber #[wrap(Some)]
add = &adw::ActionRow { set_child = &adw::Clamp {
#[track(model.changed_customer_data_full() && model.get_customer_data_full().is_some())] #[wrap(Some)]
set_title?: get_str_from_customer_data!(model, post_number).as_ref(), set_child = &gtk::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 = &gtk::Button {
#[wrap(Some)] #[wrap(Some)]
set_child = &adw::ButtonContent { set_header_suffix = &gtk::Box {
set_icon_name: relm4_icons::icon_names::COPY, add_css_class: relm4::css::LINKED,
set_label: "Copy",
append = &gtk::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 = &gtk::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()); clipboard.set_text(value.as_str());
} }
} }
AccountInput::LogOut => {
send_log_out();
}
}; };
} }

View file

@ -1,5 +1,5 @@
use libpaket::LibraryError; 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 adw::prelude::*;
use relm4::prelude::*; use relm4::prelude::*;

View file

@ -117,6 +117,7 @@ pub struct AdvicesView {
#[derive(Debug)] #[derive(Debug)]
pub enum AdvicesViewInput { pub enum AdvicesViewInput {
Fetch, Fetch,
Reset,
} }
#[derive(Debug)] #[derive(Debug)]
@ -197,7 +198,13 @@ impl AsyncComponent for AdvicesView {
sender: AsyncComponentSender<Self>, sender: AsyncComponentSender<Self>,
root: &Self::Root, root: &Self::Root,
) { ) {
self.reset();
match message { match message {
AdvicesViewInput::Reset => {
self.set_state(AdvicesViewState::Loading);
self.factory.guard().clear();
},
AdvicesViewInput::Fetch => { AdvicesViewInput::Fetch => {
self.set_state(AdvicesViewState::Loading); self.set_state(AdvicesViewState::Loading);

View file

@ -196,12 +196,35 @@ impl AsyncComponent for Login {
match message { match message {
LoginInput::LogOut => { LoginInput::LogOut => {
self.refresh_token = None; sender.input(LoginInput::NeedsLogin);
sender.output(LoginOutput::RequiresLogin).unwrap(); {
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; let token = self.shared_id_token.lock().await;
*token.write() = None; *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 = KEYRING.get().unwrap();
let _ = keyring let _ = keyring
.delete(&HashMap::from([("app", crate::constants::APP_ID)])) .delete(&HashMap::from([("app", crate::constants::APP_ID)]))
@ -356,7 +379,7 @@ macro_rules! received {
async fn $func_name$args -> LoginCommand { async fn $func_name$args -> LoginCommand {
let client = OpenIdClient::new(); let client = OpenIdClient::new();
let mut err = LibraryError::NetworkFetch; let mut err = LibraryError::NetworkFetch;
for _ in 0..6 { while err == LibraryError::NetworkFetch {
let result: Result<TokenResponse, LibraryError> = client let result: Result<TokenResponse, LibraryError> = client
.$calling$calling_args .$calling$calling_args
.await; .await;

View file

@ -222,7 +222,8 @@ impl Component for Ready {
if self.logged_in { if self.logged_in {
sender.output(ReadyOutput::Ready).unwrap(); sender.output(ReadyOutput::Ready).unwrap();
} else { } else {
todo!(); self.advices_component.emit(AdvicesViewInput::Reset);
self.tracking_component.emit(TrackingInput::Reset);
} }
} }
} }

View file

@ -16,6 +16,7 @@ pub struct TrackingView {
pub enum TrackingInput { pub enum TrackingInput {
Search(Option<String>), Search(Option<String>),
Notification(String), Notification(String),
Reset,
} }
#[derive(Debug)] #[derive(Debug)]
@ -108,6 +109,9 @@ impl Component for TrackingView {
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>, root: &Self::Root) { fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>, root: &Self::Root) {
match message { match message {
TrackingInput::Reset => {
self.factory.clear();
}
TrackingInput::Search(value) => { TrackingInput::Search(value) => {
// Some input validation // Some input validation
if let Some(value) = &value { if let Some(value) = &value {