use crate::core::*; use std::path::{Path, PathBuf}; use std::fs::{File, create_dir_all}; const CONFIG_FILE_NAME: &'static str = "tek.toml"; const PROJECT_FILE_NAME: &'static str = "project.toml"; pub struct AppPaths { config_dir: PathBuf, config_file: PathBuf, data_dir: PathBuf, project_file: PathBuf, } impl AppPaths { pub fn new (xdg: &XdgApp) -> Usually { let config_dir = PathBuf::from(xdg.app_config()?); let config_file = PathBuf::from(config_dir.join(CONFIG_FILE_NAME)); let data_dir = PathBuf::from(xdg.app_data()?); let project_file = PathBuf::from(data_dir.join(PROJECT_FILE_NAME)); Ok(Self { config_dir, config_file, data_dir, project_file }) } pub fn should_create (&self) -> bool { for path in [ &self.config_dir, &self.config_file, &self.data_dir, &self.project_file, ].iter() { if !Path::new(path).exists() { return true } } false } pub fn create (&self) -> Usually<()> { for dir in [&self.config_dir, &self.data_dir].iter() { if !Path::new(dir).exists() { create_dir_all(&dir)?; } } for file in [&self.config_file, &self.project_file].iter() { if !Path::new(file).exists() { File::create_new(&file)?; } } Ok(()) } } pub struct SetupModal(pub Option>); render!(SetupModal |self, buf, area| { for cell in buf.content.iter_mut() { cell.fg = ratatui::style::Color::Gray; cell.modifier = ratatui::style::Modifier::DIM; } let lines = [ (" ", Style::default().white().on_black().not_dim().bold()), (" Welcome to TEK! ", Style::default().white().on_black().not_dim().bold()), (" ", Style::default().white().on_black().not_dim().bold()), (" Press ENTER to create the ", Style::default().white().on_black().not_dim()), (" following directories: ", Style::default().white().on_black().not_dim()), (" ", Style::default().white().on_black().not_dim().bold()), (" Configuration directory: ", Style::default().white().on_black().not_dim()), (" ~/.config/tek ", Style::default().white().on_black().not_dim().bold()), (" ", Style::default().white().on_black().not_dim()), (" Data directory: ", Style::default().white().on_black().not_dim()), (" ~/.local/share/tek ", Style::default().white().on_black().not_dim().bold()), (" ", Style::default().white().on_black().not_dim().bold()), (" Or press CTRL-C to exit. ", Style::default().white().on_black().not_dim()), (" ", Style::default().white().on_black().not_dim()), ]; let width = lines[0].0.len() as u16; let x = area.x + (area.width - width) / 2; for (i, (line, style)) in lines.iter().enumerate() { line.blit(buf, x, area.y + area.height / 2 - (lines.len() / 2) as u16 + i as u16, Some(*style)); } Ok(area) }); handle!(SetupModal |self, e| { if let AppEvent::Input(::crossterm::event::Event::Key(KeyEvent { code: KeyCode::Enter, .. })) = e { AppPaths::new(&self.0.as_ref().unwrap())?.create()?; self.0 = None; Ok(true) } else { Ok(false) } });