use gtk4::prelude::GtkWindowExt; use libadwaita::ApplicationWindow; use libadwaita::prelude::AdwApplicationWindowExt; use relm4::{ Component, ComponentController, ComponentParts, ComponentSender, Controller, component, }; use crate::persist::data_manager::{DataManager, DataManagerError}; use crate::ui::components::media_type_switcher::MediaTypeSwitcher; pub struct App { media_type_switcher: Option>, } #[derive(Debug)] pub enum AppCmdOutput { DataManagerReady, DataManagerFailed(DataManagerError), } #[component(pub)] impl Component for App { type Input = (); type Output = (); type Init = (); type CommandOutput = AppCmdOutput; view! { ApplicationWindow { set_title: Some("Zoƶdex"), #[watch] set_content: model.media_type_switcher.as_ref().map(Controller::widget), } } fn init(_init: (), root: ApplicationWindow, sender: ComponentSender) -> ComponentParts { sender.oneshot_command(async { match DataManager::init().await { Ok(_) => AppCmdOutput::DataManagerReady, Err(error) => AppCmdOutput::DataManagerFailed(error), } }); let model = App { media_type_switcher: None, }; let widgets = view_output!(); ComponentParts { model, widgets } } fn update_cmd( &mut self, message: AppCmdOutput, _sender: ComponentSender, _root: &ApplicationWindow, ) { match message { AppCmdOutput::DataManagerReady => { // Only launch child component after data manager is ready. self.media_type_switcher = Some(MediaTypeSwitcher::builder().launch(()).detach()); } AppCmdOutput::DataManagerFailed(error) => { // TODO: Show error in GUI. println!("Error occurred in data manager initialization: {:?}", error); } } } }