From 15a0d18b16a6e04e24368ee8866c3f7dcf466235 Mon Sep 17 00:00:00 2001 From: sleepycatcoding <131554884+sleepycatcoding@users.noreply.github.com> Date: Tue, 9 Apr 2024 22:42:50 +0300 Subject: [PATCH] desktop: Filter out invalid and unavailable recent entries --- desktop/src/gui/menu_bar.rs | 57 +++++++++++++++++++++++++++-------- desktop/src/preferences.rs | 2 +- frontend-utils/src/recents.rs | 2 +- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/desktop/src/gui/menu_bar.rs b/desktop/src/gui/menu_bar.rs index 84f5a847a..025de9da4 100644 --- a/desktop/src/gui/menu_bar.rs +++ b/desktop/src/gui/menu_bar.rs @@ -5,6 +5,7 @@ use crate::player::PlayerOptions; use crate::preferences::GlobalPreferences; use egui::{menu, Button, Key, KeyboardShortcut, Modifiers, Widget}; use ruffle_core::Player; +use ruffle_frontend_utils::recents::Recent; use unic_langid::LanguageIdentifier; use url::Url; use winit::event_loop::EventLoopProxy; @@ -14,6 +15,7 @@ pub struct MenuBar { default_player_options: PlayerOptions, preferences: GlobalPreferences, + cached_recents: Option>, pub currently_opened: Option<(Url, PlayerOptions)>, } @@ -26,6 +28,7 @@ impl MenuBar { Self { event_loop, default_player_options, + cached_recents: None, currently_opened: None, preferences, } @@ -65,6 +68,7 @@ impl MenuBar { menu::bar(ui, |ui| { self.file_menu(locale, ui, dialogs, player.is_some()); + menu::menu_button(ui, text(locale, "controls-menu"), |ui| { ui.add_enabled_ui(player.is_some(), |ui| { let playing = player.as_ref().map(|p| p.is_playing()).unwrap_or_default(); @@ -208,20 +212,47 @@ impl MenuBar { } ui.separator(); - ui.menu_button("Recents", |ui| { - // Since we store recents from oldest to newest iterate backwards. - self.preferences.recents(|recents| { - for recent in recents.iter().rev() { - if ui.button(recent.url.as_str()).clicked() { - ui.close_menu(); - let _ = self.event_loop.send_event(RuffleEvent::OpenURL( - recent.url.clone(), - Box::new(self.default_player_options.clone()), - )); - } + let recent_menu_response = ui + .menu_button("Recents", |ui| { + if self + .cached_recents + .as_ref() + .map(|x| x.is_empty()) + .unwrap_or(true) + { + ui.label("No recent entries"); } - }); - }); + + if let Some(recents) = &self.cached_recents { + for recent in recents { + if ui.button(recent.url.as_str()).clicked() { + ui.close_menu(); + let _ = self.event_loop.send_event(RuffleEvent::OpenURL( + recent.url.clone(), + Box::new(self.default_player_options.clone()), + )); + } + } + }; + }) + .inner; + + match recent_menu_response { + // recreate the cache on the first draw. + Some(_) if self.cached_recents.is_none() => { + self.cached_recents = Some(self.preferences.recents(|recents| { + recents + .iter() + .rev() + .filter(|x| !x.is_invalid() && x.is_available()) + .cloned() + .collect::>() + })) + } + // clear cache, since menu was closed. + None if self.cached_recents.is_some() => self.cached_recents = None, + _ => {} + } ui.separator(); if Button::new(text(locale, "file-menu-preferences")) diff --git a/desktop/src/preferences.rs b/desktop/src/preferences.rs index ae9da2f12..7ae59be5c 100644 --- a/desktop/src/preferences.rs +++ b/desktop/src/preferences.rs @@ -180,7 +180,7 @@ impl GlobalPreferences { .recent_limit } - pub fn recents(&self, fun: impl FnOnce(&Recents)) { + pub fn recents(&self, fun: impl FnOnce(&Recents) -> R) -> R { fun(&self.recents.lock().expect("Recents is not reentrant")) } diff --git a/frontend-utils/src/recents.rs b/frontend-utils/src/recents.rs index fe6780f63..2f423a0ed 100644 --- a/frontend-utils/src/recents.rs +++ b/frontend-utils/src/recents.rs @@ -6,7 +6,7 @@ pub use write::RecentsWriter; use url::Url; -#[derive(Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct Recent { pub url: Url, }