desktop/frontend-utils: Show filename or bundle name in recent list

This should lead to shorter recent entries in the GUI by only showing the filename or bundle name (depending on which was opened).

If name field is missing from `recents.toml`, which would be the case with files created by previous Ruffle versions, it falls back to the filename from the URL.
This commit is contained in:
sleepycatcoding 2024-05-26 00:10:13 +03:00
parent f712c9212c
commit 3c944e35c7
6 changed files with 81 additions and 26 deletions

View File

@ -7,7 +7,6 @@ mod widgets;
pub use controller::GuiController; pub use controller::GuiController;
pub use movie::MovieView; pub use movie::MovieView;
use ruffle_frontend_utils::recents::Recent;
use std::borrow::Cow; use std::borrow::Cow;
use url::Url; use url::Url;
@ -185,17 +184,6 @@ impl RuffleGui {
mut player: MutexGuard<Player>, mut player: MutexGuard<Player>,
) { ) {
self.menu_bar.currently_opened = Some((movie_url.clone(), opt.clone())); self.menu_bar.currently_opened = Some((movie_url.clone(), opt.clone()));
let recent_limit = self.preferences.recent_limit();
if let Err(e) = self.preferences.write_recents(|writer| {
writer.push(
Recent {
url: movie_url.clone(),
},
recent_limit,
)
}) {
tracing::warn!("Couldn't update recents: {e}");
}
// Update dialog state to reflect the newly-opened movie's options. // Update dialog state to reflect the newly-opened movie's options.
self.dialogs self.dialogs

View File

@ -225,7 +225,7 @@ impl MenuBar {
if let Some(recents) = &self.cached_recents { if let Some(recents) = &self.cached_recents {
for recent in recents { for recent in recents {
if ui.button(recent.url.as_str()).clicked() { if ui.button(&recent.name).clicked() {
ui.close_menu(); ui.close_menu();
let _ = self.event_loop.send_event(RuffleEvent::OpenURL( let _ = self.event_loop.send_event(RuffleEvent::OpenURL(
recent.url.clone(), recent.url.clone(),

View File

@ -17,6 +17,7 @@ use ruffle_frontend_utils::bundle::source::BundleSourceError;
use ruffle_frontend_utils::bundle::{Bundle, BundleError}; use ruffle_frontend_utils::bundle::{Bundle, BundleError};
use ruffle_frontend_utils::content::PlayingContent; use ruffle_frontend_utils::content::PlayingContent;
use ruffle_frontend_utils::player_options::PlayerOptions; use ruffle_frontend_utils::player_options::PlayerOptions;
use ruffle_frontend_utils::recents::Recent;
use ruffle_render::backend::RenderBackend; use ruffle_render::backend::RenderBackend;
use ruffle_render::quality::StageQuality; use ruffle_render::quality::StageQuality;
use ruffle_render_wgpu::backend::WgpuRenderBackend; use ruffle_render_wgpu::backend::WgpuRenderBackend;
@ -167,6 +168,19 @@ impl ActivePlayer {
} }
} }
let recent_limit = preferences.recent_limit();
if let Err(e) = preferences.write_recents(|writer| {
writer.push(
Recent {
url: movie_url.clone(),
name: content.name(),
},
recent_limit,
)
}) {
tracing::warn!("Couldn't update recents: {e}");
}
let opt = match &content { let opt = match &content {
PlayingContent::DirectFile(_) => Cow::Borrowed(opt), PlayingContent::DirectFile(_) => Cow::Borrowed(opt),
PlayingContent::Bundle(_, bundle) => { PlayingContent::Bundle(_, bundle) => {

View File

@ -9,6 +9,7 @@ use url::Url;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Recent { pub struct Recent {
pub url: Url, pub url: Url,
pub name: String,
} }
impl Recent { impl Recent {

View File

@ -24,7 +24,11 @@ pub fn read_recents(input: &str) -> ParseDetails<Recents> {
None => Url::parse(crate::INVALID_URL).expect("Url is constant and valid"), None => Url::parse(crate::INVALID_URL).expect("Url is constant and valid"),
}; };
result.push(Recent { url }); let name = recent
.parse_from_str(cx, "name")
.unwrap_or_else(|| crate::url_to_readable_name(&url).into_owned());
result.push(Recent { url, name });
} }
}); });
@ -65,6 +69,7 @@ mod tests {
assert_eq!( assert_eq!(
&vec![Recent { &vec![Recent {
url: Url::parse(crate::INVALID_URL).unwrap(), url: Url::parse(crate::INVALID_URL).unwrap(),
name: "".to_string(),
}], }],
result.values() result.values()
); );
@ -77,6 +82,7 @@ mod tests {
assert_eq!( assert_eq!(
&vec![Recent { &vec![Recent {
url: Url::parse(crate::INVALID_URL).unwrap(), url: Url::parse(crate::INVALID_URL).unwrap(),
name: "".to_string()
}], }],
result.values() result.values()
); );
@ -95,6 +101,23 @@ mod tests {
assert_eq!( assert_eq!(
&vec![Recent { &vec![Recent {
url: Url::parse("https://ruffle.rs/logo-anim.swf").unwrap(), url: Url::parse("https://ruffle.rs/logo-anim.swf").unwrap(),
name: "logo-anim.swf".to_string()
}],
result.values()
);
assert_eq!(Vec::<ParseWarning>::new(), result.warnings);
}
#[test]
fn name() {
let result = read_recents(
"[[recent]]\nurl = \"file:///name_test.swf\"\nname = \"This is not a test!\"",
);
assert_eq!(
&vec![Recent {
url: Url::parse("file:///name_test.swf").unwrap(),
name: "This is not a test!".to_string(),
}], }],
result.values() result.values()
); );
@ -116,9 +139,11 @@ mod tests {
&vec![ &vec![
Recent { Recent {
url: Url::parse("file:///first.swf").unwrap(), url: Url::parse("file:///first.swf").unwrap(),
name: "first.swf".to_string()
}, },
Recent { Recent {
url: Url::parse("file:///second.swf").unwrap(), url: Url::parse("file:///second.swf").unwrap(),
name: "second.swf".to_string(),
} }
], ],
result.values() result.values()
@ -149,18 +174,23 @@ mod tests {
&vec![ &vec![
Recent { Recent {
url: Url::parse("file:///first.swf").unwrap(), url: Url::parse("file:///first.swf").unwrap(),
name: "first.swf".to_string()
}, },
Recent { Recent {
url: Url::parse(crate::INVALID_URL).unwrap(), url: Url::parse(crate::INVALID_URL).unwrap(),
name: "".to_string()
}, },
Recent { Recent {
url: Url::parse(crate::INVALID_URL).unwrap(), url: Url::parse(crate::INVALID_URL).unwrap(),
name: "".to_string()
}, },
Recent { Recent {
url: Url::parse(crate::INVALID_URL).unwrap(), url: Url::parse(crate::INVALID_URL).unwrap(),
name: "".to_string()
}, },
Recent { Recent {
url: Url::parse("file:///second.swf").unwrap(), url: Url::parse("file:///second.swf").unwrap(),
name: "second.swf".to_string(),
}, },
], ],
result.values() result.values()

View File

@ -39,14 +39,10 @@ impl<'a> RecentsWriter<'a> {
// Existing entry, just move it to the top. // Existing entry, just move it to the top.
// Update TOML first, then internal values. // Update TOML first, then internal values.
// TODO: Unfortunately, ArrayOfTables does not return the removed entry, so we need to recreate it.
// https://github.com/toml-rs/toml/issues/712
array.remove(index); array.remove(index);
let mut table = Table::new(); array.push(Self::create_recent_table(&recent));
table["url"] = value(recent.url.as_str());
array.push(table);
let recent = values.remove(index); values.remove(index);
values.push(recent); values.push(recent);
} else { } else {
// New entry. // New entry.
@ -63,13 +59,18 @@ impl<'a> RecentsWriter<'a> {
} }
// Create a new table and push it. // Create a new table and push it.
let mut table = Table::new(); array.push(Self::create_recent_table(&recent));
table["url"] = value(recent.url.as_str());
array.push(table);
values.push(recent); values.push(recent);
} }
}); });
} }
fn create_recent_table(recent: &Recent) -> Table {
let mut table = Table::new();
table["url"] = value(recent.url.as_str());
table["name"] = value(&recent.name);
table
}
} }
#[cfg(test)] #[cfg(test)]
@ -88,11 +89,12 @@ mod tests {
writer.push( writer.push(
Recent { Recent {
url: Url::parse("file:///1.swf").unwrap(), url: Url::parse("file:///1.swf").unwrap(),
name: "Test 1".to_string(),
}, },
10, 10,
) )
}, },
"[[recent]]\nurl = \"file:///1.swf\"\n", "[[recent]]\nurl = \"file:///1.swf\"\nname = \"Test 1\"\n",
); );
} }
@ -100,14 +102,16 @@ mod tests {
fn test_limit() { fn test_limit() {
test("[[recent]]\nurl = \"file:///1.swf\"\n[[recent]]\nurl = \"file:///2.swf\"\n[[recent]]\nurl = \"file:///3.swf\"\n", |writer| writer.push(Recent { test("[[recent]]\nurl = \"file:///1.swf\"\n[[recent]]\nurl = \"file:///2.swf\"\n[[recent]]\nurl = \"file:///3.swf\"\n", |writer| writer.push(Recent {
url: Url::parse("file:///very_important_file.swf").unwrap(), url: Url::parse("file:///very_important_file.swf").unwrap(),
}, 2), "[[recent]]\nurl = \"file:///3.swf\"\n\n[[recent]]\nurl = \"file:///very_important_file.swf\"\n"); name: "Important File".to_string(),
}, 2), "[[recent]]\nurl = \"file:///3.swf\"\n\n[[recent]]\nurl = \"file:///very_important_file.swf\"\nname = \"Important File\"\n");
} }
#[test] #[test]
fn test_move_to_top() { fn test_move_to_top() {
test("[[recent]]\nurl = \"file:///very_important_file.swf\"\n[[recent]]\nurl = \"file:///2.swf\"\n[[recent]]\nurl = \"file:///3.swf\"\n", |writer| writer.push(Recent { test("[[recent]]\nurl = \"file:///very_important_file.swf\"\n[[recent]]\nurl = \"file:///2.swf\"\n[[recent]]\nurl = \"file:///3.swf\"\n", |writer| writer.push(Recent {
url: Url::parse("file:///very_important_file.swf").unwrap(), url: Url::parse("file:///very_important_file.swf").unwrap(),
}, 3), "[[recent]]\nurl = \"file:///2.swf\"\n[[recent]]\nurl = \"file:///3.swf\"\n\n[[recent]]\nurl = \"file:///very_important_file.swf\"\n"); name: "Important File".to_string()
}, 3), "[[recent]]\nurl = \"file:///2.swf\"\n[[recent]]\nurl = \"file:///3.swf\"\n\n[[recent]]\nurl = \"file:///very_important_file.swf\"\nname = \"Important File\"\n");
} }
#[test] #[test]
@ -123,6 +127,7 @@ mod tests {
writer.push( writer.push(
Recent { Recent {
url: Url::parse("file:///no_crash.swf").unwrap(), url: Url::parse("file:///no_crash.swf").unwrap(),
name: "".to_string(),
}, },
0, 0,
) )
@ -130,4 +135,21 @@ mod tests {
"", "",
); );
} }
#[test]
fn name() {
test(
"",
|writer| {
writer.push(
Recent {
url: Url::parse("file:///cake.swf").unwrap(),
name: "The cake is a lie!".to_string(),
},
10,
)
},
"[[recent]]\nurl = \"file:///cake.swf\"\nname = \"The cake is a lie!\"\n",
);
}
} }