Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split NotebookState::consume into sub modules based on InnerState #12

Merged
merged 1 commit into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 6 additions & 193 deletions core/src/state/notebook.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
mod consume;
mod directory_item;
mod inner_state;

use {
crate::{
data::{Directory, Note},
event::KeyEvent,
state::{EntryState, GetInner},
state::GetInner,
types::DirectoryId,
Error, Event, Glues, NotebookEvent, NotebookTransition, Result,
Error, Event, Glues, NotebookTransition, Result,
},
consume::{directory, note, traverse},
inner_state::InnerState::{self, *},
};

pub use directory_item::{DirectoryItem, DirectoryItemChildren, TreeItem};
Expand All @@ -28,19 +29,6 @@ pub enum SelectedItem {
None,
}

#[derive(Clone)]
pub enum InnerState {
NoteSelected,
NoteMoreActions,
DirectorySelected,
DirectoryMoreActions,
NoteTreeNumber(usize),
EditingViewMode,
EditingEditMode,
EntryDialog(Box<InnerState>),
}
use InnerState::*;

impl NotebookState {
pub async fn new(glues: &mut Glues) -> Result<Self> {
let db = glues
Expand Down Expand Up @@ -111,7 +99,6 @@ impl NotebookState {

format!("Note '{name}' edit mode")
}
EntryDialog(_) => "Global menu dialog".to_owned(),
})
}

Expand Down Expand Up @@ -162,7 +149,7 @@ impl NotebookState {
"[Ctrl+h] Show editor keymap".to_owned(),
]
}
DirectoryMoreActions | NoteMoreActions | EntryDialog(_) => {
DirectoryMoreActions | NoteMoreActions => {
vec![
"[j] Next".to_owned(),
"[k] Previous".to_owned(),
Expand Down Expand Up @@ -195,185 +182,11 @@ impl NotebookState {
}

pub async fn consume(glues: &mut Glues, event: Event) -> Result<NotebookTransition> {
use Event::*;
use NotebookEvent::*;

let db = glues
.db
.as_mut()
.ok_or(Error::Wip("[consume] empty db".to_owned()))?;
let state: &mut NotebookState = glues.state.get_inner_mut()?;

match (event, &state.inner_state) {
(Notebook(CloseEntryDialog), EntryDialog(inner_state)) => {
state.inner_state = *inner_state.clone();

Ok(NotebookTransition::None)
}
(event, EntryDialog(_)) => EntryState::consume(glues, event)
.await
.map(NotebookTransition::Entry),
(Key(KeyEvent::Esc), DirectorySelected | NoteSelected | EditingViewMode) => {
state.inner_state = EntryDialog(Box::new(state.inner_state.clone()));

Ok(NotebookTransition::ShowEntryDialog)
}
(Notebook(OpenDirectory(directory_id)), DirectorySelected | NoteSelected) => {
directory::open(db, state, directory_id).await
}
(Key(KeyEvent::L) | Key(KeyEvent::Right), DirectorySelected) => {
let directory = state.get_selected_directory()?.clone();
let directory_item = state.root.find(&directory.id).ok_or(Error::Wip(
"[Key::L] failed to find the target directory".to_owned(),
))?;

if directory_item.children.is_none() {
directory::open(db, state, directory.id.clone()).await
} else {
directory::close(state, directory)
}
}
(Notebook(CloseDirectory(directory_id)), DirectorySelected | NoteSelected) => {
let directory = state
.root
.find(&directory_id)
.ok_or(Error::Wip(
"[CloseDirectory] failed to find target directory".to_owned(),
))?
.directory
.clone();

directory::close(state, directory)
}
(Key(KeyEvent::H) | Key(KeyEvent::Left), DirectorySelected) => {
let directory = state.get_selected_directory()?;
if state.root.directory.id == directory.id {
return Ok(NotebookTransition::None);
}

let parent_item = state.root.find(&directory.parent_id).ok_or(Error::Wip(
"[Key::H] failed to find parent directory".to_owned(),
))?;
let parent = parent_item.directory.clone();

directory::close(state, parent)
}
(Key(KeyEvent::H) | Key(KeyEvent::Left), NoteSelected) => {
let directory_id = &state.get_selected_note()?.directory_id;
let directory_item = state.root.find(directory_id).ok_or(Error::Wip(
"[Key::H] failed to find parent directory".to_owned(),
))?;
let directory = directory_item.directory.clone();

directory::close(state, directory)
}
(Key(KeyEvent::J), DirectorySelected | NoteSelected) => traverse::select_next(state),
(Key(KeyEvent::K), DirectorySelected | NoteSelected) => traverse::select_prev(state),
(Key(KeyEvent::M), NoteSelected) => {
let note = state.get_selected_note()?.clone();

note::show_actions_dialog(state, note)
}
(Key(KeyEvent::M), DirectorySelected) => {
let directory = state.get_selected_directory()?.clone();

directory::show_actions_dialog(state, directory)
}
(Notebook(CloseNoteActionsDialog), NoteMoreActions) => {
let note = state.get_selected_note()?.clone();

note::select(state, note)
}
(Notebook(CloseDirectoryActionsDialog), DirectoryMoreActions) => {
let directory = state.get_selected_directory()?.clone();

directory::select(state, directory)
}
(
Notebook(SelectNote(note)),
DirectorySelected | NoteSelected | NoteTreeNumber(_) | EditingViewMode,
) => note::select(state, note),
(
Notebook(SelectDirectory(directory)),
DirectorySelected | NoteSelected | NoteTreeNumber(_) | EditingViewMode,
) => directory::select(state, directory),
(Notebook(RenameNote(new_name)), NoteMoreActions) => {
let note = state.get_selected_note()?.clone();

note::rename(db, state, note, new_name).await
}
(Notebook(RemoveNote), NoteMoreActions) => {
let note = state.get_selected_note()?.clone();

note::remove(db, state, note).await
}
(Notebook(RenameDirectory(new_name)), DirectoryMoreActions) => {
let directory = state.get_selected_directory()?.clone();

directory::rename(db, state, directory, new_name).await
}
(Notebook(RemoveDirectory), DirectoryMoreActions) => {
let directory = state.get_selected_directory()?.clone();

directory::remove(db, state, directory).await
}
(Notebook(AddNote(note_name)), DirectoryMoreActions) => {
let directory = state.get_selected_directory()?.clone();

note::add(db, state, directory, note_name).await
}
(Notebook(AddDirectory(directory_name)), DirectoryMoreActions) => {
let directory = state.get_selected_directory()?.clone();

directory::add(db, state, directory, directory_name).await
}
(Key(KeyEvent::O) | Notebook(OpenNote), NoteSelected) => {
let note = state.get_selected_note()?.clone();

note::open(db, state, note).await
}
(Notebook(UpdateNoteContent(content)), EditingViewMode) => {
note::update_content(db, state, content).await
}
(Key(KeyEvent::E) | Notebook(EditNote), EditingViewMode) => note::edit(state).await,
(Key(KeyEvent::B) | Notebook(BrowseNoteTree), EditingViewMode) => note::browse(state).await,
(Key(KeyEvent::Esc) | Notebook(ViewNote), EditingEditMode) => note::view(state).await,
(Cancel, NoteMoreActions) => {
let note = state.get_selected_note()?.clone();

note::select(state, note.clone())
}
(Cancel, DirectoryMoreActions) => {
let directory = state.get_selected_directory()?.clone();

directory::select(state, directory)
}
(Key(KeyEvent::Num(n)), NoteSelected | DirectorySelected) => {
state.inner_state = NoteTreeNumber(n.into());

Ok(NotebookTransition::None)
}
(Key(KeyEvent::Num(n2)), NoteTreeNumber(n)) => {
state.inner_state = NoteTreeNumber(n2 + n * 10);

Ok(NotebookTransition::None)
}
(Key(KeyEvent::Esc), NoteTreeNumber(_)) => {
match state.selected {
SelectedItem::Note { .. } => {
state.inner_state = NoteSelected;
}
SelectedItem::Directory { .. } => {
state.inner_state = DirectorySelected;
}
SelectedItem::None => {}
};

Ok(NotebookTransition::None)
}
(Key(KeyEvent::J), NoteTreeNumber(n)) => Ok(NotebookTransition::SelectNext(*n)),
(Key(KeyEvent::K), NoteTreeNumber(n)) => Ok(NotebookTransition::SelectPrev(*n)),
(event @ Key(_), _) => Ok(NotebookTransition::Inedible(event)),
_ => Err(Error::Wip("todo: Notebook::consume".to_owned())),
}
inner_state::consume(db, state, event).await
}
38 changes: 38 additions & 0 deletions core/src/state/notebook/inner_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
mod directory_more_actions;
mod directory_selected;
mod editing_edit_mode;
mod editing_view_mode;
mod note_more_actions;
mod note_selected;
mod note_tree_number;

use crate::{db::Db, state::notebook::NotebookState, Event, NotebookTransition, Result};

#[derive(Clone)]
pub enum InnerState {
NoteSelected,
NoteMoreActions,
DirectorySelected,
DirectoryMoreActions,
NoteTreeNumber(usize),
EditingViewMode,
EditingEditMode,
}

pub async fn consume(
db: &mut Db,
state: &mut NotebookState,
event: Event,
) -> Result<NotebookTransition> {
use InnerState::*;

match &state.inner_state {
NoteSelected => note_selected::consume(db, state, event).await,
DirectorySelected => directory_selected::consume(db, state, event).await,
NoteMoreActions => note_more_actions::consume(db, state, event).await,
DirectoryMoreActions => directory_more_actions::consume(db, state, event).await,
NoteTreeNumber(n) => note_tree_number::consume(db, state, *n, event).await,
EditingViewMode => editing_view_mode::consume(db, state, event).await,
EditingEditMode => editing_edit_mode::consume(db, state, event).await,
}
}
49 changes: 49 additions & 0 deletions core/src/state/notebook/inner_state/directory_more_actions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use crate::{
db::Db,
state::notebook::{directory, note, NotebookState},
Error, Event, NotebookEvent, NotebookTransition, Result,
};

pub async fn consume(
db: &mut Db,
state: &mut NotebookState,
event: Event,
) -> Result<NotebookTransition> {
use Event::*;
use NotebookEvent::*;

match event {
Notebook(CloseDirectoryActionsDialog) => {
let directory = state.get_selected_directory()?.clone();

directory::select(state, directory)
}
Notebook(RenameDirectory(new_name)) => {
let directory = state.get_selected_directory()?.clone();

directory::rename(db, state, directory, new_name).await
}
Notebook(RemoveDirectory) => {
let directory = state.get_selected_directory()?.clone();

directory::remove(db, state, directory).await
}
Notebook(AddNote(note_name)) => {
let directory = state.get_selected_directory()?.clone();

note::add(db, state, directory, note_name).await
}
Notebook(AddDirectory(directory_name)) => {
let directory = state.get_selected_directory()?.clone();

directory::add(db, state, directory, directory_name).await
}
Cancel => {
let directory = state.get_selected_directory()?.clone();

directory::select(state, directory)
}
event @ Key(_) => Ok(NotebookTransition::Inedible(event)),
_ => Err(Error::Wip("todo: Notebook::consume".to_owned())),
}
}
Loading