From c9d526d6dc5d2c31abe689999497b00237a0bc12 Mon Sep 17 00:00:00 2001 From: Namilskyy Date: Thu, 4 Dec 2025 23:37:33 +0300 Subject: Implemented full functional. Release v0.0.1 --- src/settings_window.rs | 270 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 233 insertions(+), 37 deletions(-) (limited to 'src/settings_window.rs') diff --git a/src/settings_window.rs b/src/settings_window.rs index fbab489..105ff22 100644 --- a/src/settings_window.rs +++ b/src/settings_window.rs @@ -1,30 +1,23 @@ - use gtk4::prelude::*; -use gtk4::{ - ApplicationWindow, - Box, - Entry, - Label, - Orientation, - HeaderBar, - CheckButton -}; -use toml; -use serde::Serialize; +use gtk4::{ApplicationWindow, Box, Button, CheckButton, Entry, HeaderBar, Label, Orientation}; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::PathBuf; +use crate::redirecting_i2p::I2ProxySettings; #[allow(dead_code)] -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] struct Settings { - js: bool, - outproxy: bool, - i2p_proxy: bool, + js: bool, + outproxy: bool, + i2p_proxy: bool, web_rtc: bool, - home_addr: str, - -} + home_addr: String, + proxy_port: Option, + panel_port: Option, +} -#[allow(dead_code, unused_variables)] -pub fn window() -> ApplicationWindow { +pub fn settings_window() { let app = ApplicationWindow::builder() .title("Settings") .default_width(400) @@ -32,30 +25,233 @@ pub fn window() -> ApplicationWindow { .build(); let header_bar = HeaderBar::new(); - window().set_titlebar(Some(&header_bar)); + app.set_titlebar(Some(&header_bar)); let main_box = Box::new(Orientation::Vertical, 0); - window().set_child(Some(&main_box)); - - Label::new(Some("Settings")).set_markup("Settings"); - - let javascript = CheckButton::new().set_label(Some("Enable JS")); - let outproxy = CheckButton::new().set_label(Some("Enable outproxy")); - let i2pproxy = CheckButton::new().set_label(Some("Enable i2p proxy")); - let webrtc = CheckButton::new().set_label(Some("Enable WebRTC")); + app.set_child(Some(&main_box)); + + let label = Label::new(Some("Most wanted features")); + main_box.append(&label); + + let javascript = CheckButton::with_label("Enable JS"); + let outproxy = CheckButton::with_label("Enable outproxy"); + let i2pproxy = CheckButton::with_label("Enable i2p proxy"); + let webrtc = CheckButton::with_label("Enable WebRTC"); + let load = Button::with_label("Load"); + let load_i2pd_conf = Button::with_label("Load from i2pd conf"); + + main_box.append(&javascript); + main_box.append(&outproxy); + main_box.append(&i2pproxy); + main_box.append(&webrtc); + let homeaddr = Entry::new(); + homeaddr.set_placeholder_text(Some("Enter home address")); + main_box.append(&homeaddr); + + let proxy_port_entry = Entry::new(); + proxy_port_entry.set_placeholder_text(Some("Proxy port")); + main_box.append(&proxy_port_entry); + + let panel_port_entry = Entry::new(); + panel_port_entry.set_placeholder_text(Some("Panel port")); + main_box.append(&panel_port_entry); + + main_box.append(&load); + main_box.append(&load_i2pd_conf); + let save = Button::with_label("Save"); + main_box.append(&save); - app + if let Some(settings) = Settings::load_from_default_file() { + settings.apply_to_widgets( + &javascript, + &outproxy, + &i2pproxy, + &webrtc, + &homeaddr, + &proxy_port_entry, + &panel_port_entry, + ); + } + + let javascript_for_save = javascript.clone(); + let outproxy_for_save = outproxy.clone(); + let i2pproxy_for_save = i2pproxy.clone(); + let webrtc_for_save = webrtc.clone(); + let homeaddr_for_save = homeaddr.clone(); + let proxy_port_for_save = proxy_port_entry.clone(); + let panel_port_for_save = panel_port_entry.clone(); + save.connect_clicked(move |_| { + let settings = Settings::from_widgets( + &javascript_for_save, + &outproxy_for_save, + &i2pproxy_for_save, + &webrtc_for_save, + &homeaddr_for_save, + &proxy_port_for_save, + &panel_port_for_save, + ); + + if let Err(err) = Settings::serialize_write(&Settings::default_config_path(), &settings) { + eprintln!("Failed to save settings: {err}"); + } + }); + + let javascript_for_load = javascript.clone(); + let outproxy_for_load = outproxy.clone(); + let i2pproxy_for_load = i2pproxy.clone(); + let webrtc_for_load = webrtc.clone(); + let homeaddr_for_load = homeaddr.clone(); + let proxy_port_for_load = proxy_port_entry.clone(); + let panel_port_for_load = panel_port_entry.clone(); + load.connect_clicked(move |_| { + if let Some(settings) = Settings::load_from_default_file() { + settings.apply_to_widgets( + &javascript_for_load, + &outproxy_for_load, + &i2pproxy_for_load, + &webrtc_for_load, + &homeaddr_for_load, + &proxy_port_for_load, + &panel_port_for_load, + ); + } + }); + + let proxy_port_for_i2pd = proxy_port_entry.clone(); + let panel_port_for_i2pd = panel_port_entry.clone(); + let i2pproxy_for_i2pd = i2pproxy.clone(); + load_i2pd_conf.connect_clicked(move |_| { + match I2ProxySettings::from_i2pd_config(None) { + Ok(cfg) => { + if let Some(port) = cfg.i2p_port { + proxy_port_for_i2pd.set_text(&port.to_string()); + i2pproxy_for_i2pd.set_active(true); + } + if let Some(port) = cfg.panel_port { + panel_port_for_i2pd.set_text(&port.to_string()); + } + } + Err(err) => { + eprintln!("Failed to load i2pd config: {err}"); + } + } + }); + + app.present(); } #[allow(dead_code)] impl Settings { - pub fn serialize_write(path: &std::path::Path, - setts: &Settings) -> Result<(), toml::ser::Error> { - - let toml: String = toml::to_string(setts)?; - std::fs::write(path, toml).expect("Some error occured, is permission granted to ~/.config?"); + 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"); + // Best effort to ensure directory exists + let _ = fs::create_dir_all(&path); + + path.push("settings.toml"); + path + } + + fn from_widgets( + javascript: &CheckButton, + outproxy: &CheckButton, + i2p_proxy: &CheckButton, + web_rtc: &CheckButton, + home_addr: &Entry, + proxy_port_entry: &Entry, + panel_port_entry: &Entry, + ) -> Settings { + let proxy_port = proxy_port_entry + .text() + .trim() + .parse::() + .ok(); + let panel_port = panel_port_entry + .text() + .trim() + .parse::() + .ok(); + Settings { + js: javascript.is_active(), + outproxy: outproxy.is_active(), + i2p_proxy: i2p_proxy.is_active(), + web_rtc: web_rtc.is_active(), + home_addr: home_addr.text().to_string(), + proxy_port, + panel_port, + } + } + + fn apply_to_widgets( + &self, + javascript: &CheckButton, + outproxy: &CheckButton, + i2p_proxy: &CheckButton, + web_rtc: &CheckButton, + home_addr: &Entry, + proxy_port_entry: &Entry, + panel_port_entry: &Entry, + ) { + javascript.set_active(self.js); + outproxy.set_active(self.outproxy); + i2p_proxy.set_active(self.i2p_proxy); + web_rtc.set_active(self.web_rtc); + home_addr.set_text(&self.home_addr); + if let Some(port) = self.proxy_port { + proxy_port_entry.set_text(&port.to_string()); + } else { + proxy_port_entry.set_text(""); + } + if let Some(port) = self.panel_port { + panel_port_entry.set_text(&port.to_string()); + } else { + panel_port_entry.set_text(""); + } + } + + fn load_from_default_file() -> Option { + let path = Self::default_config_path(); + let content = fs::read_to_string(path).ok()?; + toml::from_str(&content).ok() + } + + pub fn serialize_write( + path: &std::path::Path, + setts: &Settings, + ) -> Result<(), toml::ser::Error> { + let toml: String = toml::to_string(setts)?; + std::fs::write(path, toml) + .expect("Some error occurred, is permission granted to ~/.config?"); Ok(()) } -} \ No newline at end of file +} + +pub fn load_js_enabled() -> Option { + Settings::load_from_default_file().map(|s| s.js) +} + +pub fn load_i2p_proxy_enabled() -> Option { + Settings::load_from_default_file().map(|s| s.i2p_proxy) +} + +pub fn save_i2p_proxy_enabled(enabled: bool) { + let mut settings = Settings::load_from_default_file().unwrap_or(Settings { + js: true, + outproxy: false, + i2p_proxy: enabled, + web_rtc: false, + home_addr: String::new(), + panel_port: Some(7070), + proxy_port: Some(4444), + }); + + settings.i2p_proxy = enabled; + + if let Err(err) = Settings::serialize_write(&Settings::default_config_path(), &settings) { + eprintln!("Failed to save i2p proxy setting: {err}"); + } +} -- cgit v1.2.3