157 lines
5.1 KiB
Rust
157 lines
5.1 KiB
Rust
use super::*;
|
|
use anyhow::Context;
|
|
use std::time::Duration;
|
|
|
|
const RECONNECT_POLL_TIME: Duration = Duration::from_secs(5);
|
|
|
|
pub struct App {
|
|
daemon_client: Arc<Mutex<Option<DaemonClient>>>,
|
|
settings_screen: Controller<settings_screen::SettingsScreen>,
|
|
switch_screen: AsyncController<switch_screen::SwitchScreen>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum AppMsg {
|
|
None,
|
|
PostInit,
|
|
}
|
|
|
|
impl App {
|
|
pub fn run() {
|
|
let app = RelmApp::new(config::ID);
|
|
Self::setup_gresources().unwrap();
|
|
Self::setup_i18n().unwrap();
|
|
|
|
app.run_async::<App>(());
|
|
}
|
|
|
|
fn setup_i18n() -> Result<()> {
|
|
gettextrs::setlocale(gettextrs::LocaleCategory::LcAll, "");
|
|
gettextrs::bindtextdomain(config::GETTEXT_PACKAGE, config::LOCALEDIR)?;
|
|
gettextrs::bind_textdomain_codeset(config::GETTEXT_PACKAGE, "UTF-8")?;
|
|
gettextrs::textdomain(config::GETTEXT_PACKAGE)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn setup_gresources() -> Result<()> {
|
|
gtk::gio::resources_register_include!("compiled.gresource")
|
|
.context("Failed to register and include compiled gresource.")
|
|
}
|
|
}
|
|
|
|
#[relm4::component(pub, async)]
|
|
impl AsyncComponent for App {
|
|
type Init = ();
|
|
type Input = AppMsg;
|
|
type Output = ();
|
|
type CommandOutput = ();
|
|
|
|
view! {
|
|
adw::Window {
|
|
set_title: Some("Burrow"),
|
|
set_default_size: (640, 480),
|
|
}
|
|
}
|
|
|
|
async fn init(
|
|
_: Self::Init,
|
|
root: Self::Root,
|
|
sender: AsyncComponentSender<Self>,
|
|
) -> AsyncComponentParts<Self> {
|
|
let daemon_client = Arc::new(Mutex::new(DaemonClient::new().await.ok()));
|
|
|
|
let switch_screen = switch_screen::SwitchScreen::builder()
|
|
.launch(switch_screen::SwitchScreenInit {
|
|
daemon_client: Arc::clone(&daemon_client),
|
|
})
|
|
.forward(sender.input_sender(), |_| AppMsg::None);
|
|
|
|
let settings_screen = settings_screen::SettingsScreen::builder()
|
|
.launch(settings_screen::SettingsScreenInit {
|
|
daemon_client: Arc::clone(&daemon_client),
|
|
})
|
|
.forward(sender.input_sender(), |_| AppMsg::None);
|
|
|
|
let widgets = view_output!();
|
|
|
|
let view_stack = adw::ViewStack::new();
|
|
view_stack.add_titled(switch_screen.widget(), None, "Switch");
|
|
view_stack.add_titled(settings_screen.widget(), None, "Settings");
|
|
|
|
let view_switcher_bar = adw::ViewSwitcherBar::builder().stack(&view_stack).build();
|
|
view_switcher_bar.set_reveal(true);
|
|
|
|
// When libadwaita 1.4 support becomes more avaliable, this approach is more appropriate
|
|
//
|
|
// let toolbar = adw::ToolbarView::new();
|
|
// toolbar.add_top_bar(
|
|
// &adw::HeaderBar::builder()
|
|
// .title_widget(>k::Label::new(Some("Burrow")))
|
|
// .build(),
|
|
// );
|
|
// toolbar.add_bottom_bar(&view_switcher_bar);
|
|
// toolbar.set_content(Some(&view_stack));
|
|
// root.set_content(Some(&toolbar));
|
|
|
|
let content = gtk::Box::new(gtk::Orientation::Vertical, 0);
|
|
content.append(
|
|
&adw::HeaderBar::builder()
|
|
.title_widget(>k::Label::new(Some("Burrow")))
|
|
.build(),
|
|
);
|
|
content.append(&view_stack);
|
|
content.append(&view_switcher_bar);
|
|
|
|
root.set_content(Some(&content));
|
|
|
|
sender.input(AppMsg::PostInit);
|
|
|
|
let model = App {
|
|
daemon_client,
|
|
switch_screen,
|
|
settings_screen,
|
|
};
|
|
|
|
AsyncComponentParts { model, widgets }
|
|
}
|
|
|
|
async fn update(
|
|
&mut self,
|
|
_msg: Self::Input,
|
|
_sender: AsyncComponentSender<Self>,
|
|
_root: &Self::Root,
|
|
) {
|
|
loop {
|
|
tokio::time::sleep(RECONNECT_POLL_TIME).await;
|
|
{
|
|
let mut daemon_client = self.daemon_client.lock().await;
|
|
let mut disconnected_daemon_client = false;
|
|
|
|
if let Some(daemon_client) = daemon_client.as_mut() {
|
|
if let Err(_e) = daemon_client.send_command(DaemonCommand::ServerInfo).await {
|
|
disconnected_daemon_client = true;
|
|
self.switch_screen
|
|
.emit(switch_screen::SwitchScreenMsg::DaemonDisconnect);
|
|
self.settings_screen
|
|
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
|
}
|
|
}
|
|
|
|
if disconnected_daemon_client || daemon_client.is_none() {
|
|
match DaemonClient::new().await {
|
|
Ok(new_daemon_client) => {
|
|
*daemon_client = Some(new_daemon_client);
|
|
self.switch_screen
|
|
.emit(switch_screen::SwitchScreenMsg::DaemonReconnect);
|
|
self.settings_screen
|
|
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
|
}
|
|
Err(_e) => {
|
|
// TODO: Handle Error
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|