desktop: custom bookmark names
Bookmark names can now be changed by the user, defaults to the URL file.
This commit is contained in:
parent
231fbb7d66
commit
5cb9988183
|
@ -316,6 +316,7 @@ impl RuffleGui {
|
||||||
// FIXME: if spoof url is used, the URL here is incorrect (fun fact, its also incorrect in the debug tools).
|
// FIXME: if spoof url is used, the URL here is incorrect (fun fact, its also incorrect in the debug tools).
|
||||||
match Url::from_str(player.swf().url()) {
|
match Url::from_str(player.swf().url()) {
|
||||||
Ok(url) => writer.add(crate::preferences::Bookmark {
|
Ok(url) => writer.add(crate::preferences::Bookmark {
|
||||||
|
name: crate::util::url_to_readable_name(&url).into_owned(),
|
||||||
url,
|
url,
|
||||||
}),
|
}),
|
||||||
Err(e) => tracing::warn!("Failed to parse SWF url for bookmark: {e}"),
|
Err(e) => tracing::warn!("Failed to parse SWF url for bookmark: {e}"),
|
||||||
|
@ -336,7 +337,7 @@ impl RuffleGui {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
self.preferences.bookmarks(|bookmarks| {
|
self.preferences.bookmarks(|bookmarks| {
|
||||||
for bookmark in bookmarks.iter().filter(|x| !x.is_invalid()) {
|
for bookmark in bookmarks.iter().filter(|x| !x.is_invalid()) {
|
||||||
if Button::new(crate::util::url_to_readable_name(&bookmark.url)).ui(ui).clicked() {
|
if Button::new(&bookmark.name).ui(ui).clicked() {
|
||||||
ui.close_menu();
|
ui.close_menu();
|
||||||
let _ = self.event_loop.send_event(RuffleEvent::OpenURL(bookmark.url.clone(), Box::new(self.default_player_options.clone())));
|
let _ = self.event_loop.send_event(RuffleEvent::OpenURL(bookmark.url.clone(), Box::new(self.default_player_options.clone())));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use crate::gui::text;
|
use crate::gui::text;
|
||||||
use crate::gui::widgets::PathOrUrlField;
|
use crate::gui::widgets::PathOrUrlField;
|
||||||
use crate::preferences::GlobalPreferences;
|
use crate::preferences::GlobalPreferences;
|
||||||
use crate::util::url_to_readable_name;
|
|
||||||
use egui::{Align2, Grid, Label, Sense, Ui, Window};
|
use egui::{Align2, Grid, Label, Sense, Ui, Window};
|
||||||
use egui_extras::{Column, TableBuilder};
|
use egui_extras::{Column, TableBuilder};
|
||||||
use unic_langid::LanguageIdentifier;
|
use unic_langid::LanguageIdentifier;
|
||||||
|
|
||||||
struct SelectedBookmark {
|
struct SelectedBookmark {
|
||||||
index: usize,
|
index: usize,
|
||||||
|
name: String,
|
||||||
url: PathOrUrlField,
|
url: PathOrUrlField,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,11 +94,7 @@ impl BookmarksDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
row.col(|ui| {
|
row.col(|ui| {
|
||||||
ui.add(
|
ui.add(Label::new(&bookmark.name).selectable(false).wrap(false));
|
||||||
Label::new(url_to_readable_name(&bookmark.url))
|
|
||||||
.selectable(false)
|
|
||||||
.wrap(false),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
row.col(|ui| {
|
row.col(|ui| {
|
||||||
ui.add(
|
ui.add(
|
||||||
|
@ -119,6 +115,7 @@ impl BookmarksDialog {
|
||||||
self.selected_bookmark = Some(SelectedBookmark {
|
self.selected_bookmark = Some(SelectedBookmark {
|
||||||
index,
|
index,
|
||||||
// TODO: set hint
|
// TODO: set hint
|
||||||
|
name: bookmark.name.clone(),
|
||||||
url: PathOrUrlField::new(Some(bookmark.url.clone()), ""),
|
url: PathOrUrlField::new(Some(bookmark.url.clone()), ""),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -145,11 +142,22 @@ impl BookmarksDialog {
|
||||||
Grid::new("bookmarks-dialog-panel-grid")
|
Grid::new("bookmarks-dialog-panel-grid")
|
||||||
.num_columns(2)
|
.num_columns(2)
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
|
ui.label(text(locale, "bookmarks-dialog-name"));
|
||||||
|
if ui.text_edit_singleline(&mut bookmark.name).lost_focus() {
|
||||||
|
if let Err(e) = self.preferences.write_bookmarks(|writer| {
|
||||||
|
writer.set_name(bookmark.index, bookmark.name.clone());
|
||||||
|
}) {
|
||||||
|
tracing::warn!("Couldn't update bookmarks: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
let previous_url = bookmark.url.value().cloned();
|
let previous_url = bookmark.url.value().cloned();
|
||||||
|
|
||||||
ui.label(text(locale, "bookmarks-dialog-url"));
|
ui.label(text(locale, "bookmarks-dialog-url"));
|
||||||
let current_url = bookmark.url.ui(locale, ui).value();
|
let current_url = bookmark.url.ui(locale, ui).value();
|
||||||
|
|
||||||
|
// TOOD: Change the UrlOrPathField widget to return a response instead, so we can update when we lose the focus, removes the need to clone every redraw.
|
||||||
if previous_url.as_ref() != current_url {
|
if previous_url.as_ref() != current_url {
|
||||||
if let Some(url) = current_url {
|
if let Some(url) = current_url {
|
||||||
if let Err(e) = self.preferences.write_bookmarks(|writer| {
|
if let Err(e) = self.preferences.write_bookmarks(|writer| {
|
||||||
|
@ -159,7 +167,6 @@ impl BookmarksDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -256,6 +256,7 @@ pub static INVALID_URL: &str = "invalid:///";
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Bookmark {
|
pub struct Bookmark {
|
||||||
pub url: Url,
|
pub url: Url,
|
||||||
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bookmark {
|
impl Bookmark {
|
||||||
|
|
|
@ -271,7 +271,13 @@ pub fn read_bookmarks(input: &str) -> (ParseResult<Vec<Bookmark>>, DocumentMut)
|
||||||
.expect("Url is constant and valid"),
|
.expect("Url is constant and valid"),
|
||||||
};
|
};
|
||||||
|
|
||||||
result.result.push(Bookmark { url });
|
let name = match bookmark.parse_from_str(cx, "name") {
|
||||||
|
Some(value) => value,
|
||||||
|
// Fallback to using the URL as the name.
|
||||||
|
None => crate::util::url_to_readable_name(&url).into_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
result.result.push(Bookmark { url, name });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -603,6 +609,7 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ParseResult {
|
ParseResult {
|
||||||
result: vec![],
|
result: vec![],
|
||||||
|
|
||||||
warnings: vec![
|
warnings: vec![
|
||||||
"Invalid bookmark: expected array of tables but found table".to_string()
|
"Invalid bookmark: expected array of tables but found table".to_string()
|
||||||
]
|
]
|
||||||
|
@ -614,6 +621,7 @@ mod tests {
|
||||||
ParseResult {
|
ParseResult {
|
||||||
result: vec![Bookmark {
|
result: vec![Bookmark {
|
||||||
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
||||||
|
name: "".to_string(),
|
||||||
}],
|
}],
|
||||||
warnings: vec![],
|
warnings: vec![],
|
||||||
},
|
},
|
||||||
|
@ -624,11 +632,26 @@ mod tests {
|
||||||
ParseResult {
|
ParseResult {
|
||||||
result: vec![Bookmark {
|
result: vec![Bookmark {
|
||||||
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
||||||
|
name: "".to_string(),
|
||||||
}],
|
}],
|
||||||
warnings: vec!["Invalid bookmark.url: unsupported value \"invalid\"".to_string()],
|
warnings: vec!["Invalid bookmark.url: unsupported value \"invalid\"".to_string()],
|
||||||
},
|
},
|
||||||
read_bookmarks("[[bookmark]]\nurl = \"invalid\"").0,
|
read_bookmarks("[[bookmark]]\nurl = \"invalid\"").0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
ParseResult {
|
||||||
|
result: vec![Bookmark {
|
||||||
|
url: Url::parse("https://ruffle.rs/logo-anim.swf").unwrap(),
|
||||||
|
name: "Logo SWF".to_string(),
|
||||||
|
}],
|
||||||
|
warnings: vec![],
|
||||||
|
},
|
||||||
|
read_bookmarks(
|
||||||
|
"[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\nname = \"Logo SWF\""
|
||||||
|
)
|
||||||
|
.0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -638,9 +661,11 @@ mod tests {
|
||||||
result: vec![
|
result: vec![
|
||||||
Bookmark {
|
Bookmark {
|
||||||
url: Url::from_str("file:///home/user/example.swf").unwrap(),
|
url: Url::from_str("file:///home/user/example.swf").unwrap(),
|
||||||
|
name: "example.swf".to_string(),
|
||||||
},
|
},
|
||||||
Bookmark {
|
Bookmark {
|
||||||
url: Url::from_str("https://ruffle.rs/logo-anim.swf").unwrap(),
|
url: Url::from_str("https://ruffle.rs/logo-anim.swf").unwrap(),
|
||||||
|
name: "logo-anim.swf".to_string(),
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
warnings: vec![],
|
warnings: vec![],
|
||||||
|
@ -662,15 +687,19 @@ mod tests {
|
||||||
result: vec![
|
result: vec![
|
||||||
Bookmark {
|
Bookmark {
|
||||||
url: Url::from_str("file:///home/user/example.swf").unwrap(),
|
url: Url::from_str("file:///home/user/example.swf").unwrap(),
|
||||||
|
name: "example.swf".to_string(),
|
||||||
},
|
},
|
||||||
Bookmark {
|
Bookmark {
|
||||||
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
||||||
|
name: "".to_string(),
|
||||||
},
|
},
|
||||||
Bookmark {
|
Bookmark {
|
||||||
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
url: Url::parse(crate::preferences::INVALID_URL).unwrap(),
|
||||||
|
name: "".to_string(),
|
||||||
},
|
},
|
||||||
Bookmark {
|
Bookmark {
|
||||||
url: Url::from_str("https://ruffle.rs/logo-anim.swf").unwrap(),
|
url: Url::from_str("https://ruffle.rs/logo-anim.swf").unwrap(),
|
||||||
|
name: "logo-anim.swf".to_string(),
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ impl<'a> BookmarksWriter<'a> {
|
||||||
let table = self.get_underlying_table();
|
let table = self.get_underlying_table();
|
||||||
let mut bookmark_table = Table::new();
|
let mut bookmark_table = Table::new();
|
||||||
bookmark_table["url"] = value(bookmark.url.to_string());
|
bookmark_table["url"] = value(bookmark.url.to_string());
|
||||||
|
bookmark_table["name"] = value(&bookmark.name);
|
||||||
table.push(bookmark_table);
|
table.push(bookmark_table);
|
||||||
self.0.values.push(bookmark);
|
self.0.values.push(bookmark);
|
||||||
}
|
}
|
||||||
|
@ -92,6 +93,12 @@ impl<'a> BookmarksWriter<'a> {
|
||||||
self.0.values[index].url = url;
|
self.0.values[index].url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_name(&mut self, index: usize, name: String) {
|
||||||
|
let table = self.bookmark_table(index);
|
||||||
|
table["name"] = value(&name);
|
||||||
|
self.0.values[index].name = name;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, index: usize) {
|
pub fn remove(&mut self, index: usize) {
|
||||||
let table = self.get_underlying_table();
|
let table = self.get_underlying_table();
|
||||||
table.remove(index);
|
table.remove(index);
|
||||||
|
@ -242,6 +249,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::preferences::read::read_bookmarks;
|
use crate::preferences::read::read_bookmarks;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
define_serialization_test_helpers!(read_bookmarks, BookmarksAndDocument, BookmarksWriter);
|
define_serialization_test_helpers!(read_bookmarks, BookmarksAndDocument, BookmarksWriter);
|
||||||
|
|
||||||
|
@ -251,14 +259,30 @@ mod tests {
|
||||||
"",
|
"",
|
||||||
|writer| {
|
|writer| {
|
||||||
writer.add(Bookmark {
|
writer.add(Bookmark {
|
||||||
url: url::Url::from_str("file:///home/user/example.swf").unwrap(),
|
url: Url::from_str("file:///home/user/example.swf").unwrap(),
|
||||||
|
name: "example.swf".to_string(),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
"[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n",
|
"[[bookmark]]\nurl = \"file:///home/user/example.swf\"\nname = \"example.swf\"\n",
|
||||||
);
|
);
|
||||||
test("[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n", |writer| writer.add(Bookmark {
|
test("[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n", |writer| writer.add(Bookmark {
|
||||||
url: url::Url::from_str("file:///home/user/another_file.swf").unwrap()
|
url: Url::from_str("file:///home/user/another_file.swf").unwrap(),
|
||||||
}), "[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n\n[[bookmark]]\nurl = \"file:///home/user/another_file.swf\"\n");
|
name: "another_file.swf".to_string(),
|
||||||
|
}), "[[bookmark]]\nurl = \"file:///home/user/example.swf\"\n\n[[bookmark]]\nurl = \"file:///home/user/another_file.swf\"\nname = \"another_file.swf\"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn modify_bookmark() {
|
||||||
|
test(
|
||||||
|
"[[bookmark]]\nurl = \"file:///example.swf\"\n",
|
||||||
|
|writer| writer.set_name(0, "Custom Name".to_string()),
|
||||||
|
"[[bookmark]]\nurl = \"file:///example.swf\"\nname = \"Custom Name\"\n",
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
"[[bookmark]]\nurl = \"file:///example.swf\"\nname = \"example.swf\"",
|
||||||
|
|writer| writer.set_url(0, Url::parse("https://ruffle.rs/logo-anim.swf").unwrap()),
|
||||||
|
"[[bookmark]]\nurl = \"https://ruffle.rs/logo-anim.swf\"\nname = \"example.swf\"\n",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -284,20 +308,22 @@ mod tests {
|
||||||
"[bookmark]",
|
"[bookmark]",
|
||||||
|writer| {
|
|writer| {
|
||||||
writer.add(Bookmark {
|
writer.add(Bookmark {
|
||||||
url: url::Url::from_str("file:///test.swf").unwrap(),
|
url: Url::from_str("file:///test.swf").unwrap(),
|
||||||
|
name: "test.swf".to_string(),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
"[[bookmark]]\nurl = \"file:///test.swf\"\n",
|
"[[bookmark]]\nurl = \"file:///test.swf\"\nname = \"test.swf\"\n",
|
||||||
);
|
);
|
||||||
|
|
||||||
test(
|
test(
|
||||||
"bookmark = 1010",
|
"bookmark = 1010",
|
||||||
|writer| {
|
|writer| {
|
||||||
writer.add(Bookmark {
|
writer.add(Bookmark {
|
||||||
url: url::Url::from_str("file:///test.swf").unwrap(),
|
url: Url::from_str("file:///test.swf").unwrap(),
|
||||||
|
name: "test.swf".to_string(),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
"[[bookmark]]\nurl = \"file:///test.swf\"\n",
|
"[[bookmark]]\nurl = \"file:///test.swf\"\nname = \"test.swf\"\n",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue