Feat: UI / UX
This commit is contained in:
@@ -3,7 +3,7 @@ use std::sync::atomic::Ordering;
|
||||
|
||||
use super::{InputContext, InputResult};
|
||||
use crate::commands::AppCommand;
|
||||
use crate::state::{ConfirmAction, DictFocus, HelpFocus, Modal};
|
||||
use crate::state::{ConfirmAction, DictFocus, FlashKind, HelpFocus, Modal};
|
||||
|
||||
pub(super) fn handle_help_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
|
||||
let ctrl = key.modifiers.contains(KeyModifiers::CONTROL);
|
||||
@@ -26,7 +26,22 @@ pub(super) fn handle_help_page(ctx: &mut InputContext, key: KeyEvent) -> InputRe
|
||||
KeyCode::Esc if !ctx.app.ui.help_search_query.is_empty() => {
|
||||
ctx.dispatch(AppCommand::HelpClearSearch);
|
||||
}
|
||||
KeyCode::Esc if ctx.app.ui.help_focused_block.is_some() => {
|
||||
ctx.app.ui.help_focused_block = None;
|
||||
}
|
||||
KeyCode::Tab => ctx.dispatch(AppCommand::HelpToggleFocus),
|
||||
KeyCode::Char('n') if ctx.app.ui.help_focus == HelpFocus::Content => {
|
||||
navigate_code_block(ctx, true);
|
||||
}
|
||||
KeyCode::Char('p') if ctx.app.ui.help_focus == HelpFocus::Content => {
|
||||
navigate_code_block(ctx, false);
|
||||
}
|
||||
KeyCode::Enter
|
||||
if ctx.app.ui.help_focus == HelpFocus::Content
|
||||
&& ctx.app.ui.help_focused_block.is_some() =>
|
||||
{
|
||||
execute_focused_block(ctx);
|
||||
}
|
||||
KeyCode::Char('j') | KeyCode::Down if ctrl => {
|
||||
ctx.dispatch(AppCommand::HelpNextTopic(5));
|
||||
}
|
||||
@@ -49,6 +64,8 @@ pub(super) fn handle_help_page(ctx: &mut InputContext, key: KeyEvent) -> InputRe
|
||||
selected: false,
|
||||
}));
|
||||
}
|
||||
KeyCode::Char('s') => super::open_save(ctx),
|
||||
KeyCode::Char('l') => super::open_load(ctx),
|
||||
KeyCode::Char('?') => {
|
||||
ctx.dispatch(AppCommand::OpenModal(Modal::KeybindingsHelp { scroll: 0 }));
|
||||
}
|
||||
@@ -62,6 +79,57 @@ pub(super) fn handle_help_page(ctx: &mut InputContext, key: KeyEvent) -> InputRe
|
||||
InputResult::Continue
|
||||
}
|
||||
|
||||
fn navigate_code_block(ctx: &mut InputContext, forward: bool) {
|
||||
let cache = ctx.app.ui.help_parsed.borrow();
|
||||
let Some(parsed) = cache[ctx.app.ui.help_topic].as_ref() else {
|
||||
return;
|
||||
};
|
||||
let count = parsed.code_blocks.len();
|
||||
if count == 0 {
|
||||
return;
|
||||
}
|
||||
let next = match ctx.app.ui.help_focused_block {
|
||||
Some(cur) if forward => (cur + 1) % count,
|
||||
Some(0) if !forward => count - 1,
|
||||
Some(cur) if !forward => cur - 1,
|
||||
_ if forward => 0,
|
||||
_ => count - 1,
|
||||
};
|
||||
let scroll_to = parsed.code_blocks[next].start_line.saturating_sub(2);
|
||||
drop(cache);
|
||||
ctx.app.ui.help_focused_block = Some(next);
|
||||
*ctx.app.ui.help_scroll_mut() = scroll_to;
|
||||
}
|
||||
|
||||
fn execute_focused_block(ctx: &mut InputContext) {
|
||||
let source = {
|
||||
let cache = ctx.app.ui.help_parsed.borrow();
|
||||
let Some(parsed) = cache[ctx.app.ui.help_topic].as_ref() else {
|
||||
return;
|
||||
};
|
||||
let idx = ctx.app.ui.help_focused_block.unwrap();
|
||||
let Some(block) = parsed.code_blocks.get(idx) else {
|
||||
return;
|
||||
};
|
||||
block.source.clone()
|
||||
};
|
||||
let cleaned: String = source
|
||||
.lines()
|
||||
.map(|l| l.split(" => ").next().unwrap_or(l))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
match ctx
|
||||
.app
|
||||
.execute_script_oneshot(&cleaned, ctx.link, ctx.audio_tx)
|
||||
{
|
||||
Ok(()) => ctx.app.ui.flash("Executed", 100, FlashKind::Info),
|
||||
Err(e) => ctx
|
||||
.app
|
||||
.ui
|
||||
.flash(&format!("Error: {e}"), 200, FlashKind::Error),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn handle_dict_page(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
|
||||
let ctrl = key.modifiers.contains(KeyModifiers::CONTROL);
|
||||
|
||||
@@ -100,6 +168,8 @@ pub(super) fn handle_dict_page(ctx: &mut InputContext, key: KeyEvent) -> InputRe
|
||||
selected: false,
|
||||
}));
|
||||
}
|
||||
KeyCode::Char('s') => super::open_save(ctx),
|
||||
KeyCode::Char('l') => super::open_load(ctx),
|
||||
KeyCode::Char('?') => {
|
||||
ctx.dispatch(AppCommand::OpenModal(Modal::KeybindingsHelp { scroll: 0 }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user