// #![allow(dead_code, unused)] extern crate dotenv; use fltk::{prelude::*, app, text::SimpleTerminal, enums::Color, frame, window, /*button,*/ image}; use fltk_theme::{/*ColorTheme, color_themes, widget_themes, */WidgetTheme, ThemeType, WidgetScheme, SchemeType}; use tokio::io::{self, BufReader, AsyncBufReadExt}; use tokio::process::Command; use std::env; use std::process::Stdio; use std::path::Path; async fn run_process() -> tokio::process::Child { #[cfg(not(debug_assertions))] let env_path = Path::new("/etc/arch-linux-updater/.env"); #[cfg(debug_assertions)] let env_path = Path::new(".env_debug"); dotenv::from_path(env_path).unwrap(); let cmd_line = env::var("RUN").unwrap(); let par = env::var("PARAM").unwrap(); let v = par.split_whitespace(); println!("{cmd_line} {par}"); let child: tokio::process::Child = Command::new(cmd_line) .args(v) .stderr(Stdio::piped()) // don't care about stderr .stdout(Stdio::piped()) // set up stdout so we can read it .stdin(Stdio::piped()) // set up stdin so we can write on it .spawn() .expect("Could not run the command"); // finally run the command child } async fn get_stdout() -> tokio::process::ChildStdout { let mut child: tokio::process::Child = run_process().await; let stdout: tokio::process::ChildStdout = child.stdout.take() .expect("child did not have a handle to stdout"); stdout } async fn get_buffer() -> BufReader { let buffer: BufReader = BufReader::new(get_stdout().await); buffer } async fn get_lines() -> io::Lines> { let lines: io::Lines> = get_buffer().await.lines(); lines } async fn get_line(lines: &mut io::Lines>) -> io::Result> { let line: Result, io::Error> = lines.next_line().await; line } async fn gui() -> io::Result<()> { let width = 1100; let height = 700; let app = app::App::default(); // let app = app::App::default().with_scheme(app::Scheme::Gtk); // Base, Gleam, Gtk, Oxy, Plastic let widget_theme = WidgetTheme::new(ThemeType::Dark); widget_theme.apply(); let widget_scheme = WidgetScheme::new(SchemeType::Fluent); widget_scheme.apply(); let mut wind: fltk::window::DoubleWindow = window::Window::default() .with_size(width, height) .center_screen() .with_label("Arch Linux Updater"); // let image = image::PngImage::load("assets/icons/Melawy.png").unwrap(); let image = image::PngImage::load("/usr/share/arch-linux-updater/assets/icons/Melawy.png").unwrap(); // let image = image::PngImage::load(&std::path::Path::new("assets/icons/Melawy.png")).unwrap(); wind.set_icon(Some(image)); let frame = frame::Frame::default_fill() .with_size(width, height) .center_of(&wind); let mut terminal: SimpleTerminal = SimpleTerminal::default_fill() .with_size(width, height) .center_of(&frame); terminal.set_color(Color::Background2); terminal.set_text_color(Color::Light2); wind.make_resizable(true); wind.end(); wind.show(); let mut printed_close_msg = false; let mut lines: io::Lines> = get_lines().await; // app.run().unwrap(); while app.wait() { if let Some(line) = get_line(&mut lines).await? { terminal.append(format!("{}\n", line).as_str()); } else { if printed_close_msg == false { let lang_key = "LANG"; let get_lang = match env::var(lang_key) { Ok(val) => val, Err(_) => "".to_string(), }; let text_to_close = if get_lang == "ru_RU.UTF-8" { "Теперь это окно можно закрыть" } else { "Now this window may close" }; terminal.append(format!("\n{}\n", text_to_close).as_str()); printed_close_msg = true; } } } Ok(()) } #[tokio::main] async fn main() -> io::Result<()> { gui().await }