diff --git a/src/core/utils.rs b/src/core/utils.rs index ed4f2ef..b7e0dfe 100644 --- a/src/core/utils.rs +++ b/src/core/utils.rs @@ -9,6 +9,7 @@ use std::collections::HashMap; use std::fs; use std::io::{self, prelude::*, BufReader}; use std::path::PathBuf; +use std::process::Command; pub fn fetch_packages( uad_lists: &'static HashMap, @@ -146,3 +147,27 @@ pub fn setup_uad_dir(dir: Option) -> PathBuf { fs::create_dir_all(&dir).expect("Can't create cache directory"); dir } + +pub fn open_url(dir: PathBuf) { + #[cfg(target_os = "windows")] + Command::new("explorer") + .args([dir]) + .creation_flags(0x08000000) + .output(); + + #[cfg(target_os = "macos")] + Command::new("open").args([dir]).output(); + + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + let output = Command::new("xdg-open").args([dir]).output(); + + match output { + Ok(o) => { + if !o.status.success() { + let stderr = String::from_utf8(o.stderr).unwrap().trim_end().to_string(); + error!("Can't open the following URL: {}", stderr) + } + } + Err(e) => error!("Failed to run command to open the file explorer: {}", e), + } +} diff --git a/src/gui/mod.rs b/src/gui/mod.rs index ccd1039..d51a4a6 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -6,7 +6,7 @@ pub use crate::core::sync::{get_device_list, Phone}; pub use crate::core::uad_lists::Package; use crate::core::utils::icon; use std::env; -pub use views::about::About as AboutView; +pub use views::about::{About as AboutView, Message as AboutMessage}; pub use views::list::{List as AppsView, Message as AppsMessage}; pub use views::settings::{ Message as SettingsMessage, Phone as SettingsPhone, Settings as SettingsView, @@ -57,8 +57,8 @@ pub enum Message { SettingsPressed, LoadDevices(usize), AppsPress, - DeviceSelected(Phone), + AboutAction(AboutMessage), AppsAction(AppsMessage), SettingsAction(SettingsMessage), RefreshButtonPressed, @@ -155,6 +155,10 @@ impl Application for UadGui { self.settings_view.update(msg); Command::none() } + Message::AboutAction(msg) => { + self.about_view.update(msg); + Command::none() + } Message::DeviceSelected(device) => { self.selected_device = Some(device); self.apps_view = AppsView::default(); @@ -236,7 +240,10 @@ impl Application for UadGui { &self.selected_device.clone().unwrap_or_default(), ) .map(Message::AppsAction), - View::About => self.about_view.view(&self.settings_view), + View::About => self + .about_view + .view(&self.settings_view) + .map(Message::AboutAction), View::Settings => self.settings_view.view().map(Message::SettingsAction), }; diff --git a/src/gui/views/about.rs b/src/gui/views/about.rs index de55cc5..337f44c 100644 --- a/src/gui/views/about.rs +++ b/src/gui/views/about.rs @@ -1,22 +1,82 @@ +use crate::core::utils::open_url; use crate::gui::style; use crate::gui::views::settings::Settings; -use crate::gui::Message; -use iced::{Alignment, Column, Container, Element, Length, Text}; +use crate::CACHE_DIR; +use iced::{button, Alignment, Button, Column, Container, Element, Length, Row, Space, Text}; +use std::path::PathBuf; #[derive(Default, Debug, Clone)] -pub struct About {} +pub struct About { + website_btn: button::State, + issue_btn: button::State, + wiki_btn: button::State, + log_btn: button::State, +} + +#[derive(Debug, Clone)] +pub enum Message { + UrlPressed(PathBuf), +} impl About { - pub fn view(&self, settings: &Settings) -> Element { + pub fn update(&mut self, msg: Message) { + match msg { + Message::UrlPressed(url) => { + open_url(url); + } + } + } + pub fn view(&mut self, settings: &Settings) -> Element { let about_text = Text::new( - "Welcome to UadGui, a completely free project that helps you remove pre-installed apps on your Android device.", + "Universal Android Debloater (UAD) is a Free and Open-Source community project aiming at simplifying \ + the removal of pre-installed apps on any Android device.", ); + let container = Container::new(about_text) + .width(Length::Fill) + .padding(25) + .style(style::NavigationContainer(settings.theme.palette)); + + let website_btn = Button::new(&mut self.website_btn, Text::new("Github page")) + .on_press(Message::UrlPressed(PathBuf::from( + "https://github.com/0x192/universal-android-debloater", + ))) + .padding(5) + .style(style::PrimaryButton(settings.theme.palette)); + + let issue_btn = Button::new(&mut self.issue_btn, Text::new("Have an issue?")) + .on_press(Message::UrlPressed(PathBuf::from( + "https://github.com/0x192/universal-android-debloater/issues", + ))) + .padding(5) + .style(style::PrimaryButton(settings.theme.palette)); + + let log_btn = Button::new(&mut self.log_btn, Text::new("Locate the logfiles")) + .on_press(Message::UrlPressed(CACHE_DIR.to_path_buf())) + .padding(5) + .style(style::PrimaryButton(settings.theme.palette)); + + let wiki_btn = Button::new(&mut self.wiki_btn, Text::new("Wiki")) + .on_press(Message::UrlPressed(PathBuf::from( + "https://github.com/0x192/universal-android-debloater/wiki", + ))) + .padding(5) + .style(style::PrimaryButton(settings.theme.palette)); + + let row = Row::new() + .spacing(20) + .push(website_btn) + .push(wiki_btn) + .push(issue_btn) + .push(log_btn); + let content = Column::new() .width(Length::Fill) - .spacing(10) + .spacing(20) .align_items(Alignment::Center) - .push(about_text); + .push(Space::new(Length::Fill, Length::Shrink)) + .push(container) + .push(row); Container::new(content) .width(Length::Fill)