mod redirecting_i2p; mod settings_window; use gtk4::prelude::*; use gtk4::{ Application, ApplicationWindow, Box, Button, CheckButton, Entry, HeaderBar, Image, Orientation, ScrolledWindow, }; use webkit6::prelude::*; use webkit6::{NetworkProxyMode, NetworkProxySettings, NetworkSession, WebView}; const APP_ID: &str = "com.namilsk.i2p-browser"; fn configure_i2p_proxy(enabled: bool) { if let Some(session) = NetworkSession::default() { if enabled { let settings = NetworkProxySettings::new(Some("http://127.0.0.1:4444"), &[]); session.set_proxy_settings(NetworkProxyMode::Custom, Some(&settings)); } else { session.set_proxy_settings(NetworkProxyMode::Default, None); } } } fn main() -> glib::ExitCode { let app = Application::builder().application_id(APP_ID).build(); app.connect_activate(build_ui); app.run() } fn build_ui(app: &Application) { let window = ApplicationWindow::builder() .application(app) .title("I2P Browser") .default_width(1024) .default_height(768) .build(); let header_bar = HeaderBar::new(); window.set_titlebar(Some(&header_bar)); let url_entry = Entry::builder() .placeholder_text("Enter I2P URL (e.g., http://example.i2p)") .build(); let button_back = Button::with_label("<"); let button_forward = Button::with_label(">"); let button_reload = Button::with_label("Restart"); let button_home = Button::with_label("Home"); let settings_button = Button::with_label("Settings"); let i2p_proxy = CheckButton::with_label("Enable i2p proxy"); let i2p_panel = Button::with_label("Panel"); header_bar.pack_start(&button_back); header_bar.pack_start(&button_forward); header_bar.pack_start(&button_reload); header_bar.pack_start(&button_home); header_bar.pack_end(&settings_button); header_bar.pack_end(&i2p_proxy); header_bar.pack_end(&i2p_panel); let main_box = Box::new(Orientation::Vertical, 0); window.set_child(Some(&main_box)); if let Some(enabled) = settings_window::load_i2p_proxy_enabled() { i2p_proxy.set_active(enabled); configure_i2p_proxy(enabled); } i2p_proxy.connect_toggled(|btn| { let enabled = btn.is_active(); settings_window::save_i2p_proxy_enabled(enabled); configure_i2p_proxy(enabled); }); let web_view = WebView::new(); let scrolled_window = ScrolledWindow::builder().child(&web_view).build(); scrolled_window.set_vexpand(true); scrolled_window.set_hexpand(true); web_view.set_vexpand(true); web_view.set_hexpand(true); main_box.append(&url_entry); if let Some(enable_js) = settings_window::load_js_enabled() && let Some(web_settings) = webkit6::prelude::WebViewExt::settings(&web_view) { web_settings.set_enable_javascript(enable_js); } main_box.append(&scrolled_window); let web_view_for_entry = web_view.clone(); let url_entry_for_entry = url_entry.clone(); url_entry.connect_activate(move |entry| { let url = entry.text().to_string(); let url_to_use = if !url.starts_with("http://") && !url.starts_with("https://") { format!("http://{}", url) } else { url }; let final_url = url_to_use; if glib::Uri::parse(&final_url, glib::UriFlags::NONE).is_ok() { web_view_for_entry.load_uri(&final_url); println!("Loading: {}", final_url); } else { eprintln!("Invalid URI: {}", final_url); } url_entry_for_entry.set_text(&final_url); }); let web_view_for_back = web_view.clone(); button_back.connect_clicked(move |_| { if web_view_for_back.can_go_back() { web_view_for_back.go_back(); } }); let web_view_for_forward = web_view.clone(); button_forward.connect_clicked(move |_| { if web_view_for_forward.can_go_forward() { web_view_for_forward.go_forward(); } }); let web_view_for_reload = web_view.clone(); button_reload.connect_clicked(move |_| { web_view_for_reload.reload(); }); let web_view_for_home = web_view.clone(); let url_entry_for_home = url_entry.clone(); button_home.connect_clicked(move |_| { let home_url = "http://reg.i2p/"; web_view_for_home.load_uri(home_url); url_entry_for_home.set_text(home_url); }); settings_button.connect_clicked(move |_| { settings_window::settings_window(); }); let url_entry_for_notify = url_entry.clone(); web_view.connect_notify_local(Some("uri"), move |web_view, _| { if let Some(uri) = web_view.uri() { url_entry_for_notify.set_text(&uri); } }); let web_view_for_panel = web_view.clone(); let _i2p_panel_for_open = i2p_panel.clone(); i2p_panel.connect_clicked(move |_| { let panel_port = redirecting_i2p::I2ProxySettings::from_i2pd_config(None) .ok() .and_then(|cfg| cfg.panel_port) .unwrap_or(7070); let i2p_panel_url = format!("http://127.0.0.1:{}/", panel_port); web_view_for_panel.load_uri(&i2p_panel_url); }); web_view.load_uri("http://legwork.i2p/"); window.present(); }