This commit is contained in:
2025-11-26 00:08:41 -06:00
parent 0ca341ff18
commit 726b919163
2 changed files with 43 additions and 48 deletions
+17 -32
View File
@@ -1,13 +1,11 @@
use std::cell::RefCell;
use std::{fs, io, time};
use std::path::{Path, PathBuf};
use std::process::Command;
use std::sync::RwLock;
use clipboard_rs::Clipboard;
use clipboard_rs::common::RustImage;
use tempfile::TempDir;
use thiserror::Error;
use tinyrand::{Rand, Seeded};
use tokio::task::JoinHandle;
use crate::fleen_app::FleenError::{RootDirNonexistence, RootDirPopulated, TargetDir};
use crate::fleen_app::TreeEntry::{CloseDir, Dir};
use crate::renderer;
@@ -55,13 +53,13 @@ pub enum FileType {
pub struct FleenApp {
root: PathBuf,
files_cache: RefCell<Option<Vec<TreeEntry>>>
files_cache: RwLock<Option<Vec<TreeEntry>>>
}
impl FleenApp {
pub fn open(root: PathBuf) -> Result<Self, FleenError> {
match root.try_exists() {
Ok(true) => Ok(Self { root, files_cache: RefCell::new(None) }),
Ok(true) => Ok(Self { root, files_cache: RwLock::new(None) }),
_ => Err(RootDirNonexistence(root))
}
}
@@ -73,7 +71,7 @@ impl FleenApp {
Err(RootDirPopulated(root))
} else {
Self::initialize_site(root.clone()).map_err(|e| FleenError::FileIo(String::from("creating site"), e.to_string()))?;
Ok(Self { root, files_cache: RefCell::new(None) })
Ok(Self { root, files_cache: RwLock::new(None) })
}
}
Err(_) => {
@@ -96,7 +94,7 @@ impl FleenApp {
// TODO: This is panicky as hell, make it return a Result
fn refresh_file_cache(&self, force: bool) {
if self.files_cache.borrow().is_none() || force {
if self.files_cache.read().unwrap().is_none() || force {
let mut entries = vec![];
fn visit_dir(dir: &Path, entries: &mut Vec<TreeEntry>) {
@@ -117,13 +115,14 @@ impl FleenApp {
visit_dir(&self.root, &mut entries);
entries.push(CloseDir);
self.files_cache.replace(Some(entries));
self.files_cache.write().unwrap().replace(entries);
}
}
pub fn file_tree_entries(&self) -> impl IntoIterator<Item=TreeEntry> {
self.refresh_file_cache(false);
self.files_cache.borrow().clone().expect("Can't happen because we just refreshed the cache")
// We need to clone these because the rwlock owns them
self.files_cache.read().unwrap().clone().expect("Can't happen because we just refreshed the cache")
}
pub fn open_filename(&self, filename: &str) -> Result<(), FleenError> {
@@ -289,7 +288,7 @@ impl FleenApp {
Ok(())
}
pub fn build_and_deploy(&self) -> Result<JoinHandle<Result<String, FleenError>>, FleenError> {
pub async fn build_and_deploy(&self) -> Result<String, FleenError> {
let output_dir = tempfile::tempdir().map_err(|_| TargetDir)?;
self.build_site(&output_dir.path())?; // Attempt to build the site somewhere
@@ -299,30 +298,16 @@ impl FleenApp {
} else {
let mut command = Command::new(deploy_script_path);
command.current_dir(output_dir.path()); // don't consume dir!
Ok(self.build_and_deploy_inner(output_dir, command))
}
}
let output = command.output().map_err(|e| FleenError::DeployError(e.to_string()))?;
let status = command.status()?;
fn build_and_deploy_inner(&self, output_dir: TempDir, mut command: Command) -> JoinHandle<Result<String, FleenError>> {
tokio::spawn(async move {
let output = command.output();
let status = command.status().unwrap();
output_dir.close().map_err(|e| FleenError::Io(e))?;
match output {
Ok(output) => {
let output = String::from_utf8(output.stdout).unwrap_or("Error reading deploy script output".to_string());
if status.success() {
Ok(output)
} else {
Err(FleenError::DeployError(output))
}
},
Err(e) => {
Err(FleenError::DeployError(e.to_string()))
}
let output = String::from_utf8(output.stdout).unwrap_or("Error reading deploy script output".to_string());
if status.success() {
Ok(output)
} else {
Err(FleenError::DeployError(output))
}
})
}
}
}
+26 -16
View File
@@ -4,7 +4,7 @@ mod server;
mod ui_ext;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::sync::{Arc, Mutex, MutexGuard};
use std::task::Waker;
use std::time::{Duration, Instant};
use eframe::egui::{Button, Context, Id, RichText};
@@ -46,7 +46,8 @@ struct FleenUi {
dialog_mode: Option<DialogMode>,
server_handle: Option<JoinHandle<()>>,
server_port: String,
deploy_handle: Option<JoinHandle<Result<String, FleenError>>>,
deploy_response: Arc<Mutex<Option<Result<String, FleenError>>>>,
deploying: bool,
image_message: Option<TempMessage>,
}
@@ -59,7 +60,8 @@ impl Default for FleenUi {
selected_file: None,
dialog_mode: None,
server_handle: None,
deploy_handle: None,
deploy_response: Mutex::new(None).into(),
deploying: false,
image_message: None,
server_port: "3000".to_string(),
}
@@ -109,8 +111,13 @@ impl FleenUi {
});
ui.column(width, |ui| self.server_controls(ui));
ui.column(width, |ui| {
ui.add_enabled_ui(self.deploy_handle.is_none(), |ui| {
if ui.add_fill_width(Button::green("Build and deploy")).clicked() {
ui.add_enabled_ui(!self.deploying, |ui| {
let label = if self.deploying {
"Deploying..."
} else {
"Build and Deploy"
};
if ui.add_fill_width(Button::green(label)).clicked() {
self.build_and_deploy();
}
});
@@ -135,10 +142,15 @@ impl FleenUi {
}
fn build_and_deploy(&mut self) {
match self.app.as_ref().unwrap().build_and_deploy() {
Ok(handle) => { self.deploy_handle = Some(handle) },
Err(err) => { self.error = Some(err) }
}
self.deploying = true;
let mutex = self.deploy_response.clone();
let app = self.app.as_ref().unwrap().clone();
tokio::spawn(async move {
let result = app.build_and_deploy().await;
if let Ok(mut m) = mutex.lock() {
*m = Some(result);
}
});
}
fn tree_view(&mut self, ui: &mut egui::Ui) {
@@ -361,15 +373,13 @@ impl FleenUi {
impl eframe::App for FleenUi {
fn update(&mut self, ctx: &Context, _frame: &mut Frame) {
if let Some(handle) = self.deploy_handle.as_ref() {
if handle.is_finished() {
let handle = self.deploy_handle.take().unwrap();
let result = futures::executor::block_on(async move { handle.await });
if self.deploying && let Ok(mut m) = self.deploy_response.lock() {
if let Some(result) = m.take() {
match result {
Err(e) => { self.error = Some(FleenError::DeployError(e.to_string())) }
Ok(Err(e)) => { self.error = Some(e) }
Ok(Ok(s)) => { self.message = Some(s) }
Err(e) => { self.error = Some(e) }
Ok(s) => { self.message = Some(s) }
}
self.deploying = false;
}
ctx.request_repaint_after(Duration::from_millis(100));
}