use crate::{database::add_file, get_basepath}; use futures::future::{BoxFuture, FutureExt}; use html_tag::HtmlTag; use shellexpand; use std::{ fs::{self, DirEntry}, ops::Deref, path::{Path, PathBuf}, }; #[tauri::command] pub async fn dir_tree_html(app_handle: tauri::AppHandle, filter: Vec) -> String { if let Some(basepath) = get_basepath(app_handle.clone()) { add_dir_tree_node( &app_handle, &Path::new(&basepath), &filter, &Path::new(&basepath).parent().unwrap_or(Path::new("/")), ) .await .to_html() } else { String::new() } } async fn add_dir_tree_node( app_handle: &tauri::AppHandle, path: &Path, filter: &Vec, parent_path: &Path, ) -> HtmlTag { let mut html = HtmlTag::new("div") .with_class("filetree-node") .with_id(&format!( "{}", Path::new(path) .file_name() .unwrap_or_default() .to_string_lossy() )) .with_attribute("expanded", "false") .with_child( HtmlTag::new("button") .with_class("filetree-directory-button") .with_child( HtmlTag::new("img") .with_class("filetree-icon") .with_attribute("src", "images/directory.svg"), ) .with_child( HtmlTag::new("a").with_body( &Path::new(path) .file_name() .unwrap_or_default() .to_string_lossy(), ), ), ); if let Ok(entries) = fs::read_dir(path) { for dir_entry_res in entries { if let Ok(dir_entry) = dir_entry_res { if let Ok(metadata) = fs::metadata(dir_entry.path()) { let absolute_path = dir_entry.path(); let relative_path = absolute_path.strip_prefix(parent_path).unwrap_or_else(|_| { log::error!("{:?}:{:?}", path, parent_path); Path::new("/") }); if metadata.is_file() { add_file( app_handle, relative_path.to_string_lossy().as_ref(), dir_entry.file_name().to_string_lossy().as_ref(), ) .await; html.add_child(div_from_dir_entry(&absolute_path, &relative_path)) } else if metadata.is_dir() { html.add_child( Box::pin(add_dir_tree_node( app_handle, &dir_entry.path(), &filter, parent_path, )) .await .with_attribute("style", "visibility: hidden; height: 0px;"), // .with_style("visibility", "hidden") // .with_style("height", "0px"), ); } } } } } return html; } fn div_from_dir_entry(absolute_path: &Path, relative_path: &Path) -> HtmlTag { let mut file_div = HtmlTag::new("div") .with_class("filetree-node") .with_id(&format!("{}", absolute_path.to_string_lossy())) .with_attribute("style", "visibility: hidden; height: 0px;"); let mut file_button = HtmlTag::new("button").with_class("filetree-file-button"); match relative_path .extension() .unwrap_or_default() .to_string_lossy() .to_string() .as_str() { "md" => file_button.add_child( HtmlTag::new("img") .with_class("filetree-icon") .with_attribute("src", "images/markdown.svg"), ), _ => file_button.add_child( HtmlTag::new("img") .with_class("filetree-icon") .with_attribute("src", "images/file.svg"), ), }; file_button.add_child( HtmlTag::new("a").with_body( &relative_path .file_name() .unwrap_or_default() .to_string_lossy(), ), ); file_div.add_child(file_button); return file_div; }