summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamilskyy <alive6863@gmail.com>2025-12-06 23:13:31 +0300
committerNamilskyy <alive6863@gmail.com>2025-12-06 23:13:31 +0300
commitfb5455ae891c30cdf55fca393b70eb8dd907dd16 (patch)
tree9538e4be14c02bb7aefbb1c5476c4a126f0230f5
parent9c0167f5f65947391a30ca8304d9db2bc450fb2d (diff)
Implemented bookmarks and some fixesmain
-rw-r--r--src/bookmarks.rs163
-rw-r--r--src/main.rs60
2 files changed, 222 insertions, 1 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
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 287ec42..48fb653 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,9 +1,10 @@
mod redirecting_i2p;
mod settings_window;
+mod bookmarks;
use gtk4::prelude::*;
use gtk4::{
- Application, ApplicationWindow, Box, Button, CheckButton, Entry, HeaderBar, Image, Orientation,
+ Application, ApplicationWindow, Box, Button, CheckButton, Entry, HeaderBar, Orientation,
ScrolledWindow,
};
use webkit6::prelude::*;
@@ -50,6 +51,7 @@ fn build_ui(app: &Application) {
let settings_button = Button::with_label("Settings");
let i2p_proxy = CheckButton::with_label("Enable i2p proxy");
let i2p_panel = Button::with_label("Panel");
+ let bookmark_button = Button::with_label("Bookmark");
header_bar.pack_start(&button_back);
header_bar.pack_start(&button_forward);
@@ -58,10 +60,19 @@ fn build_ui(app: &Application) {
header_bar.pack_end(&settings_button);
header_bar.pack_end(&i2p_proxy);
header_bar.pack_end(&i2p_panel);
+ header_bar.pack_end(&bookmark_button);
let main_box = Box::new(Orientation::Vertical, 0);
window.set_child(Some(&main_box));
+ // Create bookmarks bar
+ let bookmarks_bar = bookmarks::BookmarksBar::new();
+
+ // Use Rc<RefCell> for shared mutable access
+ use std::rc::Rc;
+ use std::cell::RefCell;
+ let bookmarks_bar_shared = Rc::new(RefCell::new(bookmarks_bar));
+
if let Some(enabled) = settings_window::load_i2p_proxy_enabled() {
i2p_proxy.set_active(enabled);
configure_i2p_proxy(enabled);
@@ -80,7 +91,11 @@ fn build_ui(app: &Application) {
web_view.set_vexpand(true);
web_view.set_hexpand(true);
+ // Set webview for bookmarks bar
+ bookmarks_bar_shared.borrow_mut().set_webview(&web_view);
+
main_box.append(&url_entry);
+ main_box.append(bookmarks_bar_shared.borrow().get_container());
if let Some(enable_js) = settings_window::load_js_enabled()
&& let Some(web_settings) = webkit6::prelude::WebViewExt::settings(&web_view) {
@@ -162,6 +177,49 @@ fn build_ui(app: &Application) {
let i2p_panel_url = format!("http://127.0.0.1:{}/", panel_port);
web_view_for_panel.load_uri(&i2p_panel_url);
});
+
+ let web_view_for_bookmark = web_view.clone();
+ let bookmarks_bar_for_bookmark = bookmarks_bar_shared.clone();
+ bookmark_button.connect_clicked(move |_| {
+ if let Some(uri) = web_view_for_bookmark.uri() {
+ let dialog = gtk4::Dialog::builder()
+ .title("Add Bookmark")
+ .modal(true)
+ .default_width(300)
+ .build();
+
+ let content_area = dialog.content_area();
+ let entry_box = gtk4::Box::new(Orientation::Vertical, 5);
+ entry_box.set_margin_top(10);
+ entry_box.set_margin_bottom(10);
+ entry_box.set_margin_start(10);
+ entry_box.set_margin_end(10);
+
+ let label = gtk4::Label::new(Some("Bookmark name:"));
+ let name_entry = gtk4::Entry::new();
+ name_entry.set_text(&uri);
+
+ entry_box.append(&label);
+ entry_box.append(&name_entry);
+ content_area.append(&entry_box);
+
+ dialog.add_button("Cancel", gtk4::ResponseType::Cancel);
+ dialog.add_button("Add", gtk4::ResponseType::Accept);
+
+ let name_entry_for_response = name_entry.clone();
+ let uri_for_response = uri.clone();
+ let bookmarks_bar_clone = bookmarks_bar_for_bookmark.clone();
+ dialog.connect_response(move |dialog, response| {
+ if response == gtk4::ResponseType::Accept {
+ let name = name_entry_for_response.text().to_string();
+ bookmarks_bar_clone.borrow_mut().add_current_page(name, uri_for_response.to_string());
+ }
+ dialog.close();
+ });
+
+ dialog.present();
+ }
+ });
web_view.load_uri("http://legwork.i2p/");
window.present();
}