Add basic project state and book listing
This commit is contained in:
parent
f874cef96d
commit
136684ed74
|
@ -2368,6 +2368,7 @@ dependencies = [
|
||||||
"iced",
|
"iced",
|
||||||
"rfd",
|
"rfd",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -9,3 +9,4 @@ edition = "2021"
|
||||||
iced = { git = "https://github.com/iced-rs/iced.git", version = "0.12.0", features = ["tokio"] }
|
iced = { git = "https://github.com/iced-rs/iced.git", version = "0.12.0", features = ["tokio"] }
|
||||||
rfd = "0.13.0"
|
rfd = "0.13.0"
|
||||||
tokio = { version = "1.35.1", features = ["fs"] }
|
tokio = { version = "1.35.1", features = ["fs"] }
|
||||||
|
walkdir = "2.4.0"
|
||||||
|
|
|
@ -2,12 +2,13 @@ use std::{path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
use iced::{
|
use iced::{
|
||||||
executor,
|
executor,
|
||||||
widget::{button, column, row, text, text_editor},
|
widget::{button, column, row, scrollable, text, text_editor, vertical_rule, Column},
|
||||||
Application, Command, Element, Theme,
|
Application, Command, Element, Length, Theme,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
file::{default_file, load_file, pick_file},
|
file::{default_file, load_file, load_folder},
|
||||||
|
project::ProjectState,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,9 +17,11 @@ pub enum Message {
|
||||||
Open,
|
Open,
|
||||||
Edit(text_editor::Action),
|
Edit(text_editor::Action),
|
||||||
FileOpened(Result<(PathBuf, Arc<String>), Error>),
|
FileOpened(Result<(PathBuf, Arc<String>), Error>),
|
||||||
|
FolderSelected(Result<PathBuf, Error>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BookManagerApp {
|
pub struct BookManagerApp {
|
||||||
|
project: Option<ProjectState>,
|
||||||
book_path: Option<PathBuf>,
|
book_path: Option<PathBuf>,
|
||||||
book_content: text_editor::Content,
|
book_content: text_editor::Content,
|
||||||
io_error: Option<Error>,
|
io_error: Option<Error>,
|
||||||
|
@ -33,6 +36,7 @@ impl Application for BookManagerApp {
|
||||||
fn new(_flags: Self::Flags) -> (Self, Command<Self::Message>) {
|
fn new(_flags: Self::Flags) -> (Self, Command<Self::Message>) {
|
||||||
(
|
(
|
||||||
Self {
|
Self {
|
||||||
|
project: None,
|
||||||
book_path: None,
|
book_path: None,
|
||||||
book_content: text_editor::Content::new(),
|
book_content: text_editor::Content::new(),
|
||||||
io_error: None,
|
io_error: None,
|
||||||
|
@ -55,8 +59,12 @@ impl Application for BookManagerApp {
|
||||||
}
|
}
|
||||||
Err(error) => self.io_error = Some(error),
|
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 => {
|
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 controls = row![button("Open").on_press(Message::Open)];
|
||||||
let active_editor = text_editor(&self.book_content).on_action(Message::Edit);
|
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)
|
.spacing(10)
|
||||||
.padding(10)
|
.padding(10);
|
||||||
.into()
|
|
||||||
|
row![left_panel, vertical_rule(2), right_panel].into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn theme(&self) -> Theme {
|
fn theme(&self) -> Theme {
|
||||||
|
|
|
@ -23,3 +23,12 @@ pub async fn pick_file() -> Result<(PathBuf, Arc<String>), Error> {
|
||||||
pub fn default_file() -> PathBuf {
|
pub fn default_file() -> PathBuf {
|
||||||
PathBuf::from(format!("{}/src/main.rs", env!("CARGO_MANIFEST_DIR")))
|
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 application;
|
||||||
mod file;
|
mod file;
|
||||||
|
mod project;
|
||||||
|
|
||||||
use std::io;
|
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