mod actions; mod ui; use client_shared::{LOGO, LOGO_DURATION}; use cursive::align::Align; use cursive::view::Resizable as _; use cursive::views::TextView; use cursive::{event, Cursive}; use cursive::CursiveExt as _; use std::ffi::OsString; use std::str::FromStr; use std::thread; use std::time::Duration; use ui::INPUT_FIELD_ID; use client_shared::persistence::{Appdata, load_appdata, save_appdata}; pub fn get_appdata(siv: &mut Cursive) -> Appdata { siv.with_user_data(|appdata: &mut Appdata| appdata.clone()) .expect("Failed to retrieve appdata.") } fn main() { if cfg!(debug_assertions) { logging::set_global_log_level(logging::LogLevel::Trace); } else { logging::set_global_log_level(logging::LogLevel::Debug); } logging::set_global_log_path(Some(OsString::from_str("./client-log.txt").unwrap())); utils::rng::shuffle_rng(); let mut siv = Cursive::default(); // TODO (low): Add a notice when the file is corrupted. let appdata = match load_appdata() { Ok(Some(x)) => x, _ => Appdata::new(), }; siv.set_user_data(appdata); // Global hotkeys siv.add_global_callback(event::Key::Backspace, |siv| { let _ = siv.focus_name(INPUT_FIELD_ID); }); // Logo intro screen siv.add_fullscreen_layer(TextView::new(LOGO).align(Align::center()).full_screen()); // Background thread { let cb_sink = siv.cb_sink().clone(); thread::spawn(move || { let mut timer = 0; loop { cb_sink .send(Box::new(move |siv| { let appdata = get_appdata(siv); if appdata.intro_screen_shown_until > utils::time::time_millis() { thread::sleep(Duration::from_millis( appdata .intro_screen_shown_until .saturating_sub(utils::time::time_millis()) as u64, )); // Main layout let main_layout = ui::setup_ui(siv); siv.pop_layer(); siv.add_fullscreen_layer(main_layout); } ui::visual_update(siv); if timer % appdata.persistent_data.api_refresh_rate == 0 { // TODO (low): Add a notice when automatic refresh fails. let _ = actions::load_messages(siv); } save_appdata(get_appdata(siv)); })) .expect("Failed to send callback from background thread."); timer += 1; thread::sleep(Duration::from_secs(1)); } }); } siv.with_user_data(|appdata: &mut Appdata| { appdata.intro_screen_shown_until = utils::time::time_millis() + LOGO_DURATION; }); siv.run(); }