desktop: allow multiple bookmarks with the same URL
This commit is contained in:
parent
e1f9b5e5df
commit
fb93ef9cb6
|
@ -333,7 +333,7 @@ impl RuffleGui {
|
|||
|
||||
if have_bookmarks {
|
||||
ui.separator();
|
||||
for bookmark in bookmarks {
|
||||
for bookmark in bookmarks.iter().filter(|x| !x.is_invalid()) {
|
||||
if Button::new(crate::util::url_to_readable_name(&bookmark.url)).ui(ui).clicked() {
|
||||
ui.close_menu();
|
||||
let _ = self.event_loop.send_event(RuffleEvent::OpenURL(bookmark.url.clone(), Box::new(self.default_player_options.clone())));
|
||||
|
|
|
@ -36,7 +36,9 @@ impl BookmarksDialog {
|
|||
// Close the dialog if we have no bookmarks to show.
|
||||
should_close = bookmarks.is_empty();
|
||||
|
||||
for (index, bookmark) in bookmarks.iter().enumerate() {
|
||||
for (index, bookmark) in
|
||||
bookmarks.iter().filter(|x| !x.is_invalid()).enumerate()
|
||||
{
|
||||
ui.label(bookmark.url.as_str());
|
||||
|
||||
if Button::new(text(locale, "remove")).ui(ui).clicked() {
|
||||
|
|
|
@ -241,7 +241,15 @@ pub struct LogPreferences {
|
|||
pub filename_pattern: FilenamePattern,
|
||||
}
|
||||
|
||||
pub static INVALID_URL: &str = "invalid:///";
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Bookmark {
|
||||
pub url: Url,
|
||||
}
|
||||
|
||||
impl Bookmark {
|
||||
pub fn is_invalid(&self) -> bool {
|
||||
self.url.as_str() == INVALID_URL
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,10 +267,8 @@ pub fn read_bookmarks(input: &str) -> (ParseResult<Vec<Bookmark>>, DocumentMut)
|
|||
for bookmark in bookmarks.iter() {
|
||||
let url = match bookmark.parse_from_str(cx, "url") {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
cx.add_warning("Missing bookmark.url".to_string());
|
||||
continue;
|
||||
}
|
||||
None => url::Url::parse(crate::preferences::INVALID_URL)
|
||||
.expect("Url is constant and valid"),
|
||||
};
|
||||
|
||||
result.result.push(Bookmark { url });
|
||||
|
@ -614,15 +612,19 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
ParseResult {
|
||||
result: vec![],
|
||||
warnings: vec!["Missing bookmark.url".to_string()],
|
||||
result: vec![Bookmark {
|
||||
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
||||
}],
|
||||
warnings: vec![],
|
||||
},
|
||||
read_bookmarks("[[bookmark]]").0
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ParseResult {
|
||||
result: vec![],
|
||||
result: vec![Bookmark {
|
||||
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
||||
}],
|
||||
warnings: vec!["Invalid bookmark.url: unsupported value \"invalid\"".to_string()],
|
||||
},
|
||||
read_bookmarks("[[bookmark]]\nurl = \"invalid\"").0,
|
||||
|
@ -661,15 +663,18 @@ mod tests {
|
|||
Bookmark {
|
||||
url: Url::from_str("file:///home/user/example.swf").unwrap(),
|
||||
},
|
||||
Bookmark {
|
||||
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
||||
},
|
||||
Bookmark {
|
||||
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
||||
},
|
||||
Bookmark {
|
||||
url: Url::from_str("https://ruffle.rs/logo-anim.swf").unwrap(),
|
||||
}
|
||||
],
|
||||
|
||||
warnings: vec![
|
||||
"Invalid bookmark.url: unsupported value \"invalid\"".to_string(),
|
||||
"Missing bookmark.url".to_string()
|
||||
],
|
||||
warnings: vec!["Invalid bookmark.url: unsupported value \"invalid\"".to_string(),],
|
||||
},
|
||||
read_bookmarks(
|
||||
r#"
|
||||
|
|
|
@ -59,42 +59,29 @@ impl<'a> BookmarksWriter<'a> {
|
|||
}
|
||||
|
||||
pub fn add(&mut self, bookmark: Bookmark) {
|
||||
// TODO: if more fields are added, this should use URL matching (e.g. other properties are ignored)
|
||||
if !self.0.values.contains(&bookmark) {
|
||||
if let Some(array) = self.0.toml_document["bookmark"]
|
||||
.or_insert(array())
|
||||
.as_array_of_tables_mut()
|
||||
{
|
||||
// TODO: If we add a BookmarkWriter use this here instead rather than duplicating the table write code.
|
||||
let mut table = Table::new();
|
||||
table["url"] = value(bookmark.url.to_string());
|
||||
array.push(table);
|
||||
self.0.values.push(bookmark);
|
||||
} else {
|
||||
// TODO: There is definitely a better way to handle this, then just logging a warning.
|
||||
tracing::warn!("bookmark is not an array of tables, bookmarks will NOT be saved.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index: usize) {
|
||||
// We need to get the URL to find the bookmark in the TOML file, since index may not correspond to
|
||||
// the same table entry (i.e. invalid tables and such that we want to keep intact for compatibility purposes)
|
||||
let bookmark = self.0.values.remove(index);
|
||||
|
||||
// Remove the bookmark from the TOML file.
|
||||
if let Some(array) = self.0.toml_document["bookmark"]
|
||||
.or_insert(array())
|
||||
.as_array_of_tables_mut()
|
||||
{
|
||||
let bookmark_url = bookmark.url.to_string();
|
||||
array.retain(|x| {
|
||||
if let Some(url) = x.get("url").and_then(|x| x.as_str()) {
|
||||
return url != bookmark_url;
|
||||
}
|
||||
// TODO: If we add a BookmarkWriter use this here instead rather than duplicating the table write code.
|
||||
let mut table = Table::new();
|
||||
table["url"] = value(bookmark.url.to_string());
|
||||
array.push(table);
|
||||
self.0.values.push(bookmark);
|
||||
} else {
|
||||
// TODO: There is definitely a better way to handle this, then just logging a warning.
|
||||
tracing::warn!("bookmark is not an array of tables, bookmarks will NOT be saved.");
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
});
|
||||
pub fn remove(&mut self, index: usize) {
|
||||
self.0.values.remove(index);
|
||||
|
||||
if let Some(array) = self.0.toml_document["bookmark"]
|
||||
.or_insert(array())
|
||||
.as_array_of_tables_mut()
|
||||
{
|
||||
array.remove(index);
|
||||
} else {
|
||||
// TODO: We should add a way to return an error from write methods.
|
||||
tracing::warn!("bookmark is not an array of tables, bookmarks will NOT be saved.");
|
||||
|
@ -273,11 +260,12 @@ mod tests {
|
|||
},
|
||||
"[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\nurl = \"file:///another_file.swf\"\n",
|
||||
);
|
||||
|
||||
// Test that we leave invalid bookmark tables intact when removing a bookmark.
|
||||
test("[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\n\n[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\n\n[[bookmark]]\nurl = \"invalid\"\n", |writer| {
|
||||
writer.remove(1);
|
||||
}, "[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\n\n[[bookmark]]\nurl = \"invalid\"\n")
|
||||
writer.remove(2);
|
||||
}, "[[bookmark]]\nurl = \"file://home/user/example.swf\"\n\n[[bookmark]]\n\n[[bookmark]]\nurl = \"invalid\"\n");
|
||||
|
||||
// check if we can remove invalid entries.
|
||||
test("[[bookmark]]", |writer| writer.remove(0), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue