Files
unshell/unshell-gui/src/interface/mod.rs
T

229 lines
6.7 KiB
Rust
Raw Normal View History

2025-12-21 17:58:04 -07:00
mod interface;
2025-12-17 16:40:34 -07:00
use std::{
path::PathBuf,
sync::{Arc, Mutex},
};
2025-12-21 17:58:04 -07:00
use egui_async::Bind;
use log::debug;
2025-12-21 00:35:28 -07:00
use unshell_lib::config::TreeMessage;
2025-12-21 17:58:04 -07:00
use unshell_lib::{ModuleError, Result};
2025-12-21 00:35:28 -07:00
use crate::auth::Auth;
2025-12-17 16:40:34 -07:00
#[derive(serde::Deserialize, serde::Serialize)]
pub struct InterfaceWindow {
path: PathBuf,
2025-12-21 17:58:04 -07:00
// #[serde(skip)]
// data_bind: Bind<String, ModuleError>,
2025-12-17 16:40:34 -07:00
#[serde(skip)]
state: Arc<Mutex<InterfaceWindowState>>,
2025-12-21 17:58:04 -07:00
// #[serde(skip)]
// promise: Option<PromiseWrapper<Result<TreeMessage>>>,
2025-12-17 16:40:34 -07:00
}
pub struct InterfaceWindowState {
is_request: bool,
is_error: bool,
2025-12-21 00:35:28 -07:00
branch: Option<TreeMessage>,
2025-12-17 16:40:34 -07:00
}
impl InterfaceWindow {
pub fn update(&mut self, auth: &mut Auth, ui: &mut egui::Ui) {
2025-12-21 17:58:04 -07:00
// let data_bind = Bind::<InterfaceWindowState, ModuleError>::new(false);
2025-12-17 16:40:34 -07:00
ui.heading("Interface");
ui.label(self.path.to_string_lossy());
{
if !self.path.eq("/") && ui.button("Go up").clicked() {
self.go_up();
self.state.lock().unwrap().branch = None;
}
let state_lock = self.state.lock().unwrap();
let (is_request, is_error, is_some) = (
state_lock.is_request,
state_lock.is_error,
state_lock.branch.is_some(),
);
drop(state_lock);
if is_request {
ui.spinner();
} else if is_error {
self.reset_path();
let mut state_lock = self.state.lock().unwrap();
state_lock.is_error = false;
state_lock.is_request = false;
state_lock.branch = None;
drop(state_lock)
} else if !is_some {
{
let mut state_lock = self.state.lock().unwrap();
state_lock.is_request = true;
}
let state_clone = self.state.clone();
auth.get(
&format!("/api/interface{}", self.path.display()),
2025-12-21 00:35:28 -07:00
move |response: Result<TreeMessage>| {
2025-12-17 16:40:34 -07:00
let mut state_lock = state_clone.lock().unwrap();
match response {
Ok(item) => {
state_lock.branch = Some(item);
}
2025-12-21 17:58:04 -07:00
Err(err) => {
crate::log(&format!("Got error {err:?}"));
2025-12-17 16:40:34 -07:00
state_lock.is_error = true;
}
}
state_lock.is_request = false;
drop(state_lock);
},
2025-12-21 00:35:28 -07:00
)
.unwrap();
2025-12-17 16:40:34 -07:00
} else {
let state_clone = self.state.clone();
let mut state_lock = state_clone.lock().unwrap();
2025-12-21 12:04:53 -07:00
let branch = (state_lock.branch).as_mut().unwrap();
2025-12-17 16:40:34 -07:00
let clear = match branch {
2025-12-21 00:35:28 -07:00
TreeMessage::InterfaceAndValue(interface_struct, interface_data) => {
2025-12-21 17:58:04 -07:00
interface::render(ui, interface_struct, interface_data);
2025-12-21 12:04:53 -07:00
if ui.button("Save").clicked() {
auth.post(
&format!("/api/interface{}", self.path.display()),
&TreeMessage::State(interface_data.clone()),
move |response: Result<TreeMessage>| {
2025-12-21 17:58:04 -07:00
debug!("{response:?}");
2025-12-21 12:04:53 -07:00
},
)
.unwrap();
}
2025-12-17 16:40:34 -07:00
false
}
2025-12-21 00:35:28 -07:00
TreeMessage::Folder(items) => {
2025-12-17 16:40:34 -07:00
let mut clear = false;
for item in items {
if ui.button(&format!("Item {}", item)).clicked() {
self.go_down(item.clone());
clear = true;
break;
}
}
clear
}
_ => false,
};
if clear {
state_lock.branch = None;
}
drop(state_lock)
}
}
2025-12-21 17:58:04 -07:00
// if ui.button("Go Up").clicked() {
// self.go_up();
// // self.data_bind.clear();
// }
// match self.promise.as_mut() {
// Some(promise) => {
// if let Some(result) = promise.poll() {
// crate::log(&format!("{result:?}"));
// } else {
// crate::log("Poll failed");
// }
// }
// None => {
// self.promise =
// Some(auth.get_async(&format!("/api/interface{}", self.path.to_str().unwrap())));
// }
// }
// let future = Auth::get_async::<String>("/api/test").await;
// future.;
// if let Some(res) = self.data_bind.read_or_request(async || {
// // self.go_up();
// // auth.get("", |e: String| {});
// reqwest::get("https://icanhazip.com/")
// .await
// .map_err(|e| ModuleError::Error(e.to_string()))?
// .text()
// .await
// .map_err(|e| ModuleError::Error(e.to_string()))
// }) {
// match res {
// Ok(ip) => {
// ui.label(format!("OK {ip}"));
// }
// Err(err) => {
// ui.label(format!("ERR {err}"));
// }
// }
// } else {
// ui.spinner();
// };
// if ui.button("Refresh").clicked() {
// Auth::get_async_callback::<String>("/api/interface");
// // self.data_bind.clear();
// }
2025-12-17 16:40:34 -07:00
}
fn reset_path(&mut self) {
self.path = PathBuf::from("/");
}
fn go_up(&mut self) {
2025-12-21 17:58:04 -07:00
if let Some(parent) = self.path.parent() {
self.path = PathBuf::from(parent);
}
2025-12-17 16:40:34 -07:00
}
fn go_down(&mut self, path: String) {
self.path = self.path.join(path);
}
2025-12-21 17:58:04 -07:00
async fn get() {}
2025-12-17 16:40:34 -07:00
}
impl Default for InterfaceWindow {
fn default() -> Self {
Self {
path: "/".into(),
2025-12-21 17:58:04 -07:00
// promise: None,
2025-12-17 16:40:34 -07:00
state: Arc::new(Mutex::new(InterfaceWindowState::default())),
2025-12-21 17:58:04 -07:00
// data_bind: Bind::new(false),
2025-12-17 16:40:34 -07:00
}
}
}
impl Default for InterfaceWindowState {
fn default() -> Self {
Self {
is_request: false,
branch: None,
is_error: false,
}
}
}