Add basic project state and book listing
This commit is contained in:
parent
f874cef96d
commit
136684ed74
|
@ -2368,6 +2368,7 @@ dependencies = [
|
|||
"iced",
|
||||
"rfd",
|
||||
"tokio",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -9,3 +9,4 @@ edition = "2021"
|
|||
iced = { git = "https://github.com/iced-rs/iced.git", version = "0.12.0", features = ["tokio"] }
|
||||
rfd = "0.13.0"
|
||||
tokio = { version = "1.35.1", features = ["fs"] }
|
||||
walkdir = "2.4.0"
|
||||
|
|
|
@ -2,12 +2,13 @@ use std::{path::PathBuf, sync::Arc};
|
|||
|
||||
use iced::{
|
||||
executor,
|
||||
widget::{button, column, row, text, text_editor},
|
||||
Application, Command, Element, Theme,
|
||||
widget::{button, column, row, scrollable, text, text_editor, vertical_rule, Column},
|
||||
Application, Command, Element, Length, Theme,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
file::{default_file, load_file, pick_file},
|
||||
file::{default_file, load_file, load_folder},
|
||||
project::ProjectState,
|
||||
Error,
|
||||
};
|
||||
|
||||
|
@ -16,9 +17,11 @@ pub enum Message {
|
|||
Open,
|
||||
Edit(text_editor::Action),
|
||||
FileOpened(Result<(PathBuf, Arc<String>), Error>),
|
||||
FolderSelected(Result<PathBuf, Error>),
|
||||
}
|
||||
|
||||
pub struct BookManagerApp {
|
||||
project: Option<ProjectState>,
|
||||
book_path: Option<PathBuf>,
|
||||
book_content: text_editor::Content,
|
||||
io_error: Option<Error>,
|
||||
|
@ -33,6 +36,7 @@ impl Application for BookManagerApp {
|
|||
fn new(_flags: Self::Flags) -> (Self, Command<Self::Message>) {
|
||||
(
|
||||
Self {
|
||||
project: None,
|
||||
book_path: None,
|
||||
book_content: text_editor::Content::new(),
|
||||
io_error: None,
|
||||
|
@ -55,8 +59,12 @@ impl Application for BookManagerApp {
|
|||
}
|
||||
Err(error) => self.io_error = Some(error),
|
||||
},
|
||||
Message::FolderSelected(result) => match result {
|
||||
Ok(path) => self.project = Some(ProjectState::new(path)),
|
||||
Err(error) => self.io_error = Some(error),
|
||||
},
|
||||
Message::Open => {
|
||||
return Command::perform(pick_file(), Message::FileOpened);
|
||||
return Command::perform(load_folder(), Message::FolderSelected);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,10 +76,19 @@ impl Application for BookManagerApp {
|
|||
let controls = row![button("Open").on_press(Message::Open)];
|
||||
let active_editor = text_editor(&self.book_content).on_action(Message::Edit);
|
||||
|
||||
column![hello_world, controls, active_editor]
|
||||
let mut books: Vec<Element<'_, Self::Message>> = vec![];
|
||||
if let Some(project) = &self.project {
|
||||
for book in project.books.iter() {
|
||||
books.push(text(book.file_name.clone()).into());
|
||||
}
|
||||
}
|
||||
|
||||
let left_panel = scrollable(Column::with_children(books)).width(Length::Fixed(256.0));
|
||||
let right_panel = column![hello_world, controls, active_editor]
|
||||
.spacing(10)
|
||||
.padding(10)
|
||||
.into()
|
||||
.padding(10);
|
||||
|
||||
row![left_panel, vertical_rule(2), right_panel].into()
|
||||
}
|
||||
|
||||
fn theme(&self) -> Theme {
|
||||
|
|
|
@ -23,3 +23,12 @@ pub async fn pick_file() -> Result<(PathBuf, Arc<String>), Error> {
|
|||
pub fn default_file() -> PathBuf {
|
||||
PathBuf::from(format!("{}/src/main.rs", env!("CARGO_MANIFEST_DIR")))
|
||||
}
|
||||
|
||||
pub async fn load_folder() -> Result<PathBuf, Error> {
|
||||
let file_handle = rfd::AsyncFileDialog::new()
|
||||
.set_title("Choose project folder...")
|
||||
.pick_folder()
|
||||
.await
|
||||
.ok_or(Error::DialogClosed)?;
|
||||
Ok(file_handle.path().to_owned())
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
mod application;
|
||||
mod file;
|
||||
mod project;
|
||||
|
||||
use std::io;
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
use std::{ffi::OsStr, path::PathBuf};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Book {
|
||||
pub path: PathBuf,
|
||||
pub file_name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ProjectState {
|
||||
pub path: PathBuf,
|
||||
pub books: Vec<Book>,
|
||||
}
|
||||
|
||||
impl ProjectState {
|
||||
pub fn new(path: PathBuf) -> Self {
|
||||
let mut books = vec![];
|
||||
let book_walker = WalkDir::new(path.join("books")).into_iter();
|
||||
for entry in book_walker.flatten() {
|
||||
if entry.metadata().is_ok_and(|md| md.is_dir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let extension = entry.path().extension().and_then(OsStr::to_str);
|
||||
if extension.is_some_and(|ext| ext.to_lowercase() == "str") {
|
||||
books.push(Book {
|
||||
path: entry.path().to_owned(),
|
||||
file_name: entry.file_name().to_str().unwrap().to_owned(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Self { path, books }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue