diff --git a/Cargo.lock b/Cargo.lock index 8004943..d713f0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,6 +18,16 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" +[[package]] +name = "accesskit" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74a4b14f3d99c1255dcba8f45621ab1a2e7540a0009652d33989005a4d0bfc6b" +dependencies = [ + "enumn", + "serde", +] + [[package]] name = "addr2line" version = "0.24.1" @@ -69,6 +79,7 @@ dependencies = [ "cfg-if", "getrandom", "once_cell", + "serde", "version_check", "zerocopy", ] @@ -1058,6 +1069,7 @@ source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410 dependencies = [ "bytemuck", "emath", + "serde", ] [[package]] @@ -1098,12 +1110,14 @@ name = "egui" version = "0.27.2" source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" dependencies = [ + "accesskit", "ahash", "emath", "epaint", "log", "nohash-hasher", "puffin", + "serde", ] [[package]] @@ -1241,6 +1255,7 @@ version = "0.27.2" source = "git+https://github.com/emilk/egui?rev=fcb7764e48ce00f8f8e58da10f937410d65b0bfb#fcb7764e48ce00f8f8e58da10f937410d65b0bfb" dependencies = [ "bytemuck", + "serde", ] [[package]] @@ -1279,6 +1294,17 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "enumn" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "env_filter" version = "0.1.2" @@ -1329,6 +1355,7 @@ dependencies = [ "nohash-hasher", "parking_lot", "puffin", + "serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 18f107f..213b754 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["lib", "cdylib"] [dependencies] #egui-android = { git = "https://github.com/jb55/egui-android.git" } -egui = { git = "https://github.com/emilk/egui", rev = "fcb7764e48ce00f8f8e58da10f937410d65b0bfb" } +egui = { git = "https://github.com/emilk/egui", rev = "fcb7764e48ce00f8f8e58da10f937410d65b0bfb", features = ["serde"] } eframe = { git = "https://github.com/emilk/egui", rev = "fcb7764e48ce00f8f8e58da10f937410d65b0bfb", package = "eframe", default-features = false, features = [ "wgpu", "wayland", "x11", "android-native-activity" ] } egui_extras = { git = "https://github.com/emilk/egui", rev = "fcb7764e48ce00f8f8e58da10f937410d65b0bfb", package = "egui_extras", features = ["all_loaders"] } ehttp = "0.2.0" diff --git a/src/account_manager.rs b/src/account_manager.rs index 6ae2521..7551d1a 100644 --- a/src/account_manager.rs +++ b/src/account_manager.rs @@ -208,7 +208,7 @@ fn get_selected_index(accounts: &[UserAccount], keystore: &KeyStorageType) -> Op } KeyStorageResponse::ReceivedResult(Err(e)) => error!("Error getting selected key: {}", e), - _ => (), + KeyStorageResponse::Waiting | KeyStorageResponse::ReceivedResult(Ok(None)) => {} }; None diff --git a/src/app.rs b/src/app.rs index ce7382a..ba3ec6c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,7 @@ use crate::{ account_manager::AccountManager, app_creation::setup_cc, + app_size_handler::AppSizeHandler, app_style::user_requested_visuals_change, args::Args, column::Columns, @@ -60,6 +61,7 @@ pub struct Damus { pub img_cache: ImageCache, pub accounts: AccountManager, pub subscriptions: Subscriptions, + pub app_rect_handler: AppSizeHandler, frame_history: crate::frame_history::FrameHistory, @@ -507,6 +509,8 @@ fn update_damus(damus: &mut Damus, ctx: &egui::Context) { error!("error processing event: {}", err); } + damus.app_rect_handler.try_save_app_size(ctx); + damus.columns.attempt_perform_deletion_request(); } @@ -746,6 +750,7 @@ impl Damus { accounts, frame_history: FrameHistory::default(), view_state: ViewState::default(), + app_rect_handler: AppSizeHandler::default(), } } @@ -829,6 +834,7 @@ impl Damus { accounts: AccountManager::new(KeyStorageType::None), frame_history: FrameHistory::default(), view_state: ViewState::default(), + app_rect_handler: AppSizeHandler::default(), } } diff --git a/src/app_creation.rs b/src/app_creation.rs index d824339..f8f28f3 100644 --- a/src/app_creation.rs +++ b/src/app_creation.rs @@ -1,3 +1,4 @@ +use crate::app_size_handler::AppSizeHandler; use crate::app_style::{ create_custom_style, dark_mode, desktop_font_size, light_mode, mobile_font_size, }; @@ -8,10 +9,16 @@ use eframe::NativeOptions; pub fn generate_native_options() -> NativeOptions { generate_native_options_with_builder_modifiers(|builder| { - builder + let builder = builder .with_fullsize_content_view(true) .with_titlebar_shown(false) - .with_title_shown(false) + .with_title_shown(false); + + if let Some(window_size) = AppSizeHandler::default().get_app_size() { + builder.with_inner_size(window_size) + } else { + builder + } }) } diff --git a/src/app_size_handler.rs b/src/app_size_handler.rs new file mode 100644 index 0000000..f1140bb --- /dev/null +++ b/src/app_size_handler.rs @@ -0,0 +1,100 @@ +use std::time::{Duration, Instant}; + +use egui::Context; +use tracing::{error, info}; + +use crate::{ + storage::{write_file, Directory}, + DataPaths, +}; + +pub struct AppSizeHandler { + directory: Option, + saved_size: Option, + last_saved: Instant, +} + +static FILE_NAME: &str = "app_size.json"; +static DELAY: Duration = Duration::from_millis(500); + +impl Default for AppSizeHandler { + fn default() -> Self { + let directory = match DataPaths::Setting.get_path() { + Ok(path) => Some(Directory::new(path)), + Err(e) => { + error!("Could not load settings path: {}", e); + None + } + }; + + Self { + directory, + saved_size: None, + last_saved: Instant::now() - DELAY, + } + } +} + +impl AppSizeHandler { + pub fn try_save_app_size(&mut self, ctx: &Context) { + if let Some(interactor) = &self.directory { + // There doesn't seem to be a way to check if user is resizing window, so if the rect is different than last saved, we'll wait DELAY before saving again to avoid spamming io + if self.last_saved.elapsed() >= DELAY { + internal_try_save_app_size(interactor, &mut self.saved_size, ctx); + self.last_saved = Instant::now(); + } + } + } + + pub fn get_app_size(&self) -> Option { + if self.saved_size.is_some() { + return self.saved_size; + } + + if let Some(directory) = &self.directory { + if let Ok(file_contents) = directory.get_file(FILE_NAME.to_owned()) { + if let Ok(rect) = serde_json::from_str::(&file_contents) { + return Some(rect); + } + } else { + info!("Could not find {}", FILE_NAME); + } + } + + None + } +} + +fn internal_try_save_app_size( + interactor: &Directory, + maybe_saved_size: &mut Option, + ctx: &Context, +) { + let cur_size = ctx.input(|i| i.screen_rect.size()); + if let Some(saved_size) = maybe_saved_size { + if cur_size != *saved_size { + try_save_size(interactor, cur_size, maybe_saved_size); + } + } else { + try_save_size(interactor, cur_size, maybe_saved_size); + } +} + +fn try_save_size( + interactor: &Directory, + cur_size: egui::Vec2, + maybe_saved_size: &mut Option, +) { + if let Ok(serialized_rect) = serde_json::to_string(&cur_size) { + if write_file( + &interactor.file_path, + FILE_NAME.to_owned(), + &serialized_rect, + ) + .is_ok() + { + info!("wrote size {}", cur_size,); + *maybe_saved_size = Some(cur_size); + } + } +}