feat: paket: account page
This commit is contained in:
parent
b9fb7fcea4
commit
31698154e0
7 changed files with 283 additions and 94 deletions
|
@ -1,3 +1,3 @@
|
||||||
app_id = "de.j4ne.Paket"
|
app_id = "de.j4ne.Paket"
|
||||||
|
|
||||||
icons = ["plus", "minus", "package-x-generic", "mail", "loupe-large"]
|
icons = ["plus", "minus", "package-x-generic", "mail", "loupe-large", "person", "copy"]
|
214
paket/src/account.rs
Normal file
214
paket/src/account.rs
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
use adw::prelude::*;
|
||||||
|
use gtk::gdk;
|
||||||
|
use libpaket::{stammdaten::CustomerDataFull, LibraryError, LibraryResult};
|
||||||
|
use relm4::{Component, ComponentParts};
|
||||||
|
|
||||||
|
use crate::LoginSharedState;
|
||||||
|
|
||||||
|
#[tracker::track]
|
||||||
|
pub struct AccountView {
|
||||||
|
logged_in: bool,
|
||||||
|
|
||||||
|
#[do_not_track]
|
||||||
|
login: LoginSharedState,
|
||||||
|
#[no_eq]
|
||||||
|
customer_data_full: Option<CustomerDataFull>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have to handle both events, as we want to reset everything, if we log out.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum AccountCmd {
|
||||||
|
LoggedIn,
|
||||||
|
LoggedOut,
|
||||||
|
GotCustomerDataFull(LibraryResult<CustomerDataFull>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum CopyTargets {
|
||||||
|
PostNumber,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum AccountInput {
|
||||||
|
Copy(CopyTargets),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum AccountServices {
|
||||||
|
Advices,
|
||||||
|
SendungVerfolgung,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum AccountOutput {
|
||||||
|
LoggedOut,
|
||||||
|
LoggedIn,
|
||||||
|
HaveService(AccountServices),
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! get_str_from_customer_data {
|
||||||
|
($model: ident, $id: ident) => {{
|
||||||
|
|| -> Option<String> {
|
||||||
|
let data = $model.customer_data_full.as_ref()?;
|
||||||
|
Some(data.common.$id.clone())
|
||||||
|
}()
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component(pub)]
|
||||||
|
impl Component for AccountView {
|
||||||
|
type Input = AccountInput;
|
||||||
|
type Output = AccountOutput;
|
||||||
|
type Init = LoginSharedState;
|
||||||
|
type CommandOutput = AccountCmd;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
#[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(),
|
||||||
|
|
||||||
|
// 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(),
|
||||||
|
|
||||||
|
set_subtitle: "Postnummer",
|
||||||
|
|
||||||
|
add_suffix = >k::Button {
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_child = &adw::ButtonContent {
|
||||||
|
set_icon_name: relm4_icons::icon_names::COPY,
|
||||||
|
set_label: "Copy",
|
||||||
|
},
|
||||||
|
|
||||||
|
connect_clicked => AccountInput::Copy(CopyTargets::PostNumber),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: relm4::ComponentSender<Self>,
|
||||||
|
) -> relm4::ComponentParts<Self> {
|
||||||
|
let model = AccountView {
|
||||||
|
logged_in: false,
|
||||||
|
login: init,
|
||||||
|
tracker: 0,
|
||||||
|
customer_data_full: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let login = model.login.clone();
|
||||||
|
sender.command(move |out, shutdown| {
|
||||||
|
shutdown
|
||||||
|
.register(async move {
|
||||||
|
let login = { login.clone().as_ref().lock().await.clone() };
|
||||||
|
let (sender, receiver) = relm4::channel::<AccountCmd>();
|
||||||
|
login.subscribe(&sender, |model| match model {
|
||||||
|
Some(_) => AccountCmd::LoggedIn,
|
||||||
|
None => AccountCmd::LoggedOut,
|
||||||
|
});
|
||||||
|
loop {
|
||||||
|
out.send(receiver.recv().await.unwrap()).unwrap();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.drop_on_shutdown()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
ComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
message: Self::Input,
|
||||||
|
sender: relm4::ComponentSender<Self>,
|
||||||
|
root: &Self::Root,
|
||||||
|
) {
|
||||||
|
self.reset();
|
||||||
|
|
||||||
|
match message {
|
||||||
|
AccountInput::Copy(target) => {
|
||||||
|
let value = match target {
|
||||||
|
CopyTargets::PostNumber => {
|
||||||
|
get_str_from_customer_data!(self, post_number)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(value) = value {
|
||||||
|
let display = root.display();
|
||||||
|
let clipboard = display.clipboard();
|
||||||
|
clipboard.set_text(value.as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_cmd(
|
||||||
|
&mut self,
|
||||||
|
message: Self::CommandOutput,
|
||||||
|
sender: relm4::ComponentSender<Self>,
|
||||||
|
root: &Self::Root,
|
||||||
|
) {
|
||||||
|
self.reset();
|
||||||
|
|
||||||
|
match message {
|
||||||
|
AccountCmd::LoggedIn => {
|
||||||
|
self.set_logged_in(true);
|
||||||
|
}
|
||||||
|
AccountCmd::LoggedOut => {
|
||||||
|
self.set_logged_in(false);
|
||||||
|
}
|
||||||
|
AccountCmd::GotCustomerDataFull(data) => match data {
|
||||||
|
Ok(data) => {
|
||||||
|
for service in &data.common.services {
|
||||||
|
match service {
|
||||||
|
libpaket::stammdaten::CustomerDataService::Packstation => (),
|
||||||
|
libpaket::stammdaten::CustomerDataService::Paketankuendigung => sender
|
||||||
|
.output(AccountOutput::HaveService(
|
||||||
|
AccountServices::SendungVerfolgung,
|
||||||
|
))
|
||||||
|
.unwrap(),
|
||||||
|
libpaket::stammdaten::CustomerDataService::Briefankuendigung => sender
|
||||||
|
.output(AccountOutput::HaveService(AccountServices::Advices))
|
||||||
|
.unwrap(),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.set_customer_data_full(Some(data));
|
||||||
|
}
|
||||||
|
Err(err) => todo!(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.changed_logged_in() {
|
||||||
|
if self.logged_in {
|
||||||
|
sender.output(AccountOutput::LoggedIn).unwrap();
|
||||||
|
let token = self.login.clone();
|
||||||
|
sender.oneshot_command(async move {
|
||||||
|
let token = crate::login::get_id_token(&token).await.unwrap();
|
||||||
|
let client = libpaket::StammdatenClient::new();
|
||||||
|
let mut res: LibraryResult<CustomerDataFull> = Err(LibraryError::NetworkFetch);
|
||||||
|
while res.is_err() && *res.as_ref().err().unwrap() == LibraryError::NetworkFetch
|
||||||
|
{
|
||||||
|
res = client.customer_data_full(&token).await;
|
||||||
|
}
|
||||||
|
AccountCmd::GotCustomerDataFull(res)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
sender.output(AccountOutput::LoggedOut).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,7 +101,7 @@ impl AsyncComponent for App {
|
||||||
.forward(sender.input_sender(), convert_ready_response);
|
.forward(sender.input_sender(), convert_ready_response);
|
||||||
|
|
||||||
let login = Login::builder()
|
let login = Login::builder()
|
||||||
.launch(login_shared_state.clone())
|
.launch_with_broker(login_shared_state.clone(), &paket::LOGIN_BROKER)
|
||||||
.forward(sender.input_sender(), convert_login_response);
|
.forward(sender.input_sender(), convert_login_response);
|
||||||
|
|
||||||
let model = App {
|
let model = App {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod account;
|
||||||
pub mod advice;
|
pub mod advice;
|
||||||
pub mod advices;
|
pub mod advices;
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
|
@ -6,3 +7,8 @@ pub mod ready;
|
||||||
pub mod tracking;
|
pub mod tracking;
|
||||||
|
|
||||||
pub use login::LoginSharedState;
|
pub use login::LoginSharedState;
|
||||||
|
|
||||||
|
pub static LOGIN_BROKER: relm4::MessageBroker<login::LoginInput> = relm4::MessageBroker::new();
|
||||||
|
pub fn send_log_out() {
|
||||||
|
LOGIN_BROKER.send(login::LoginInput::LogOut);
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ static KEYRING: OnceLock<oo7::Keyring> = OnceLock::new();
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LoginInput {
|
pub enum LoginInput {
|
||||||
|
LogOut,
|
||||||
NeedsLogin,
|
NeedsLogin,
|
||||||
NeedsRefresh,
|
NeedsRefresh,
|
||||||
ReceivedAuthCode(String),
|
ReceivedAuthCode(String),
|
||||||
|
@ -194,6 +195,18 @@ impl AsyncComponent for Login {
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
|
LoginInput::LogOut => {
|
||||||
|
self.refresh_token = None;
|
||||||
|
sender.output(LoginOutput::RequiresLogin).unwrap();
|
||||||
|
{
|
||||||
|
let token = self.shared_id_token.lock().await;
|
||||||
|
*token.write() = None;
|
||||||
|
}
|
||||||
|
let keyring = KEYRING.get().unwrap();
|
||||||
|
let _ = keyring
|
||||||
|
.delete(&HashMap::from([("app", crate::constants::APP_ID)]))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
LoginInput::NeedsRefresh => {
|
LoginInput::NeedsRefresh => {
|
||||||
let refresh_token = self.refresh_token.as_ref().unwrap().clone();
|
let refresh_token = self.refresh_token.as_ref().unwrap().clone();
|
||||||
sender.oneshot_command(async {
|
sender.oneshot_command(async {
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use libpaket::{stammdaten::CustomerDataFull, LibraryError, LibraryResult};
|
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
account::{AccountOutput, AccountServices, AccountView},
|
||||||
advices::{AdvicesView, AdvicesViewInput},
|
advices::{AdvicesView, AdvicesViewInput},
|
||||||
tracking::{TrackingInput, TrackingOutput, TrackingView},
|
tracking::{TrackingInput, TrackingOutput, TrackingView},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
pub struct Ready {
|
pub struct Ready {
|
||||||
#[do_not_track]
|
logged_in: bool,
|
||||||
login: crate::LoginSharedState,
|
|
||||||
activate: bool,
|
|
||||||
have_service_advices: bool,
|
have_service_advices: bool,
|
||||||
have_service_tracking: bool,
|
have_service_tracking: bool,
|
||||||
|
|
||||||
|
#[do_not_track]
|
||||||
|
account_component: Controller<AccountView>,
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
advices_component: AsyncController<AdvicesView>,
|
advices_component: AsyncController<AdvicesView>,
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
|
@ -33,21 +33,14 @@ pub enum ReadyOutput {
|
||||||
pub enum ReadyCmds {
|
pub enum ReadyCmds {
|
||||||
LoggedIn,
|
LoggedIn,
|
||||||
LoggedOut,
|
LoggedOut,
|
||||||
GotCustomerDataFull(LibraryResult<libpaket::stammdaten::CustomerDataFull>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Services {
|
|
||||||
Advices,
|
|
||||||
SendungVerfolgung,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ReadyInput {
|
pub enum ReadyInput {
|
||||||
Activate,
|
LoggedIn,
|
||||||
Deactivate,
|
LoggedOut,
|
||||||
HaveService(Services),
|
HaveService(AccountServices),
|
||||||
ServiceBorked(Services),
|
ServiceBorked(AccountServices),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
|
@ -106,6 +99,13 @@ impl Component for Ready {
|
||||||
#[track(model.changed_have_service_tracking())]
|
#[track(model.changed_have_service_tracking())]
|
||||||
set_visible: model.have_service_tracking,
|
set_visible: model.have_service_tracking,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
add = &model.account_component.widget().clone() -> adw::Bin {
|
||||||
|
} -> page_account: adw::ViewStackPage {
|
||||||
|
set_title: Some("Account"),
|
||||||
|
set_name: Some("page_account"),
|
||||||
|
set_icon_name: Some(relm4_icons::icon_names::PERSON)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -132,41 +132,28 @@ impl Component for Ready {
|
||||||
.launch(init.clone())
|
.launch(init.clone())
|
||||||
.forward(&sender.input_sender(), convert_tracking_output);
|
.forward(&sender.input_sender(), convert_tracking_output);
|
||||||
|
|
||||||
|
let account_component = AccountView::builder()
|
||||||
|
.launch(init.clone())
|
||||||
|
.forward(&sender.input_sender(), convert_account_output);
|
||||||
|
|
||||||
let toast_overlay = adw::ToastOverlay::new();
|
let toast_overlay = adw::ToastOverlay::new();
|
||||||
|
|
||||||
let model = Ready {
|
let model = Ready {
|
||||||
have_service_advices: false,
|
have_service_advices: false,
|
||||||
have_service_tracking: true,
|
have_service_tracking: true,
|
||||||
login: init.clone(),
|
logged_in: false,
|
||||||
activate: false,
|
|
||||||
|
account_component,
|
||||||
advices_component,
|
advices_component,
|
||||||
tracking_component,
|
tracking_component,
|
||||||
toast_overlay,
|
toast_overlay,
|
||||||
|
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
|
||||||
let login = model.login.clone();
|
|
||||||
sender.command(move |out, shutdown| {
|
|
||||||
shutdown
|
|
||||||
.register(async move {
|
|
||||||
let login = { login.clone().as_ref().lock().await.clone() };
|
|
||||||
let (sender, receiver) = relm4::channel::<ReadyCmds>();
|
|
||||||
login.subscribe(&sender, |model| match model {
|
|
||||||
Some(_) => ReadyCmds::LoggedIn,
|
|
||||||
None => ReadyCmds::LoggedOut,
|
|
||||||
});
|
|
||||||
loop {
|
|
||||||
out.send(receiver.recv().await.unwrap()).unwrap();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.drop_on_shutdown()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let breakpoint = adw::Breakpoint::new(adw::BreakpointCondition::new_length(
|
let breakpoint = adw::Breakpoint::new(adw::BreakpointCondition::new_length(
|
||||||
adw::BreakpointConditionLengthType::MaxWidth,
|
adw::BreakpointConditionLengthType::MaxWidth,
|
||||||
450.0,
|
550.0,
|
||||||
adw::LengthUnit::Sp,
|
adw::LengthUnit::Sp,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -193,39 +180,24 @@ impl Component for Ready {
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
ReadyInput::Activate => {
|
ReadyInput::LoggedIn => {
|
||||||
self.set_activate(true);
|
self.set_logged_in(true);
|
||||||
if self.changed_activate() {
|
|
||||||
let token = self.login.clone();
|
|
||||||
sender.oneshot_command(async move {
|
|
||||||
let token = crate::login::get_id_token(&token).await.unwrap();
|
|
||||||
let client = libpaket::StammdatenClient::new();
|
|
||||||
let mut res: LibraryResult<CustomerDataFull> =
|
|
||||||
Err(LibraryError::NetworkFetch);
|
|
||||||
while res.is_err()
|
|
||||||
&& *res.as_ref().err().unwrap() == LibraryError::NetworkFetch
|
|
||||||
{
|
|
||||||
res = client.customer_data_full(&token).await;
|
|
||||||
}
|
}
|
||||||
ReadyCmds::GotCustomerDataFull(res)
|
ReadyInput::LoggedOut => {
|
||||||
});
|
self.set_logged_in(false);
|
||||||
}
|
|
||||||
}
|
|
||||||
ReadyInput::Deactivate => {
|
|
||||||
self.set_activate(false);
|
|
||||||
}
|
}
|
||||||
ReadyInput::HaveService(service) => match service {
|
ReadyInput::HaveService(service) => match service {
|
||||||
Services::Advices => {
|
AccountServices::Advices => {
|
||||||
self.set_have_service_advices(true);
|
self.set_have_service_advices(true);
|
||||||
self.advices_component.emit(AdvicesViewInput::Fetch);
|
self.advices_component.emit(AdvicesViewInput::Fetch);
|
||||||
}
|
}
|
||||||
Services::SendungVerfolgung => {
|
AccountServices::SendungVerfolgung => {
|
||||||
self.set_have_service_tracking(true);
|
self.set_have_service_tracking(true);
|
||||||
self.tracking_component.emit(TrackingInput::Search(None))
|
self.tracking_component.emit(TrackingInput::Search(None))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ReadyInput::ServiceBorked(service) => match service {
|
ReadyInput::ServiceBorked(service) => match service {
|
||||||
Services::Advices => {
|
AccountServices::Advices => {
|
||||||
self.toast_overlay.add_toast(
|
self.toast_overlay.add_toast(
|
||||||
adw::Toast::builder()
|
adw::Toast::builder()
|
||||||
.title("Service borked: Mail notifications")
|
.title("Service borked: Mail notifications")
|
||||||
|
@ -234,7 +206,7 @@ impl Component for Ready {
|
||||||
);
|
);
|
||||||
self.set_have_service_advices(false);
|
self.set_have_service_advices(false);
|
||||||
}
|
}
|
||||||
Services::SendungVerfolgung => {
|
AccountServices::SendungVerfolgung => {
|
||||||
self.toast_overlay.add_toast(
|
self.toast_overlay.add_toast(
|
||||||
adw::Toast::builder()
|
adw::Toast::builder()
|
||||||
.title("Service borked: Shipment tracking")
|
.title("Service borked: Shipment tracking")
|
||||||
|
@ -244,43 +216,28 @@ impl Component for Ready {
|
||||||
self.set_have_service_tracking(false);
|
self.set_have_service_tracking(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
fn update_cmd(
|
if self.changed_logged_in() {
|
||||||
&mut self,
|
if self.logged_in {
|
||||||
message: Self::CommandOutput,
|
sender.output(ReadyOutput::Ready).unwrap();
|
||||||
sender: ComponentSender<Self>,
|
} else {
|
||||||
_: &Self::Root,
|
todo!();
|
||||||
) {
|
|
||||||
match message {
|
|
||||||
ReadyCmds::LoggedIn => sender.input(ReadyInput::Activate),
|
|
||||||
ReadyCmds::LoggedOut => sender.input(ReadyInput::Deactivate),
|
|
||||||
ReadyCmds::GotCustomerDataFull(res) => match res {
|
|
||||||
Ok(res) => {
|
|
||||||
for service in &res.common.services {
|
|
||||||
match service {
|
|
||||||
libpaket::stammdaten::CustomerDataService::Packstation => (),
|
|
||||||
libpaket::stammdaten::CustomerDataService::Paketankuendigung => {
|
|
||||||
sender.input(ReadyInput::HaveService(Services::SendungVerfolgung))
|
|
||||||
}
|
}
|
||||||
libpaket::stammdaten::CustomerDataService::Briefankuendigung => {
|
|
||||||
sender.input(ReadyInput::HaveService(Services::Advices))
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.output(ReadyOutput::Ready).unwrap()
|
|
||||||
}
|
|
||||||
Err(err) => todo!(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tracking_output(value: TrackingOutput) -> ReadyInput {
|
fn convert_tracking_output(value: TrackingOutput) -> ReadyInput {
|
||||||
match value {
|
match value {
|
||||||
TrackingOutput::Borked => ReadyInput::ServiceBorked(Services::SendungVerfolgung),
|
TrackingOutput::Borked => ReadyInput::ServiceBorked(AccountServices::SendungVerfolgung),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_account_output(value: AccountOutput) -> ReadyInput {
|
||||||
|
match value {
|
||||||
|
AccountOutput::LoggedOut => ReadyInput::LoggedOut,
|
||||||
|
AccountOutput::LoggedIn => ReadyInput::LoggedIn,
|
||||||
|
AccountOutput::HaveService(service) => ReadyInput::HaveService(service),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ use libpaket::tracking::{Shipment, TrackingParams};
|
||||||
use libpaket::{LibraryError, LibraryResult};
|
use libpaket::{LibraryError, LibraryResult};
|
||||||
use relm4::factory::{FactoryComponent, FactoryHashMap};
|
use relm4::factory::{FactoryComponent, FactoryHashMap};
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
use relm4::{adw, gtk};
|
|
||||||
|
|
||||||
use crate::login::get_id_token;
|
use crate::login::get_id_token;
|
||||||
use crate::LoginSharedState;
|
use crate::LoginSharedState;
|
||||||
|
|
Loading…
Reference in a new issue