diff options
Diffstat (limited to 'src/bookmarks.rs')
| -rw-r--r-- | src/bookmarks.rs | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/bookmarks.rs b/src/bookmarks.rs new file mode 100644 index 0000000..82edd33 --- /dev/null +++ b/src/bookmarks.rs @@ -0,0 +1,163 @@ +use gtk4::prelude::*; +use gtk4::{Box, Button, Orientation}; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::PathBuf; +use webkit6::prelude::*; +use webkit6::WebView; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Bookmark { + pub name: String, + pub url: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Bookmarks { + pub items: Vec<Bookmark>, +} + +impl Bookmarks { + fn default_config_path() -> PathBuf { + let home = std::env::var("HOME").unwrap_or_else(|_| String::from(".")); + let mut path = PathBuf::from(home); + path.push(".config"); + path.push("i2p-browser"); + let _ = fs::create_dir_all(&path); + path.push("bookmarks.toml"); + path + } + + pub fn load_from_file() -> Bookmarks { + let path = Self::default_config_path(); + if let Ok(content) = fs::read_to_string(path) { + toml::from_str(&content).unwrap_or_else(|_| Bookmarks { + items: vec![ + Bookmark { + name: "Reg.i2p".to_string(), + url: "http://reg.i2p".to_string(), + }, + Bookmark { + name: "Kislitsa forum".to_string(), + url: "http://kislitsa.i2p/".to_string(), + }, + Bookmark { + name: "Soundcloack".to_string(), + url: "http://maidzones5taqt3g2boaepkxdi6f2etznqbfebludsl4i2ydrcjq.b32.i2p/".to_string(), + }, + ], + }) + } else { + Bookmarks { + items: vec![ + Bookmark { + name: "Reg.i2p".to_string(), + url: "http://reg.i2p".to_string(), + }, + Bookmark { + name: "Kislitsa forum".to_string(), + url: "http://kislitsa.i2p/".to_string(), + }, + Bookmark { + name: "Soundcloack".to_string(), + url: "http://maidzones5taqt3g2boaepkxdi6f2etznqbfebludsl4i2ydrcjq.b32.i2p/".to_string(), + }, + ], + } + } + } + + pub fn save_to_file(&self) -> Result<(), toml::ser::Error> { + let path = Self::default_config_path(); + let toml: String = toml::to_string(self)?; + fs::write(path, toml) + .expect("Failed to write bookmarks file"); + Ok(()) + } + + pub fn add_bookmark(&mut self, name: String, url: String) { + self.items.push(Bookmark { name, url }); + let _ = self.save_to_file(); + } + + pub fn remove_bookmark(&mut self, index: usize) { + if index < self.items.len() { + self.items.remove(index); + let _ = self.save_to_file(); + } + } +} + +pub struct BookmarksBar { + pub container: Box, + bookmarks: Bookmarks, + webview: Option<WebView>, +} + +impl BookmarksBar { + pub fn new() -> Self { + let container = Box::builder() + .orientation(Orientation::Horizontal) + .spacing(5) + .margin_start(10) + .margin_end(10) + .margin_top(5) + .margin_bottom(5) + .build(); + + let mut bookmarks_bar = BookmarksBar { + container, + bookmarks: Bookmarks::load_from_file(), + webview: None, + }; + + bookmarks_bar.refresh_bookmarks(); + bookmarks_bar + } + + pub fn set_webview(&mut self, webview: &WebView) { + self.webview = Some(webview.clone()); + self.refresh_bookmarks(); + } + + fn refresh_bookmarks(&mut self) { + while let Some(child) = self.container.first_child() { + self.container.remove(&child); + } + + for bookmark in self.bookmarks.items.iter() { + let button = Button::with_label(&bookmark.name); + let url = bookmark.url.clone(); + + if let Some(ref webview) = self.webview { + let webview_clone = webview.clone(); + button.connect_clicked(move |_| { + webview_clone.load_uri(&url); + }); + } + + self.container.append(&button); + } + + let add_button = Button::with_label("+"); + let webview_ref = self.webview.clone(); + add_button.connect_clicked(move |_| { + // TODO: Show dialog to add bookmark + if let Some(ref webview) = webview_ref { + if let Some(uri) = webview.uri() { + println!("Add bookmark for current URL: {}", uri); + } + } + }); + self.container.append(&add_button); + } + + pub fn add_current_page(&mut self, name: String, url: String) { + self.bookmarks.add_bookmark(name, url); + self.refresh_bookmarks(); + } + + pub fn get_container(&self) -> &Box { + &self.container + } +} |
