Add adaptive drill intro, refactor key hints
This commit is contained in:
@@ -6,6 +6,7 @@ use ratatui::widgets::{Block, Paragraph, Widget};
|
||||
|
||||
use crate::i18n::t;
|
||||
use crate::session::result::DrillResult;
|
||||
use crate::ui::hint;
|
||||
use crate::ui::layout::pack_hint_lines;
|
||||
use crate::ui::theme::Theme;
|
||||
|
||||
@@ -44,17 +45,17 @@ impl Widget for Dashboard<'_> {
|
||||
let footer_line_count = if self.input_lock_remaining_ms.is_some() {
|
||||
1u16
|
||||
} else {
|
||||
let hint_continue = t!("dashboard.hint_continue");
|
||||
let hint_retry = t!("dashboard.hint_retry");
|
||||
let hint_menu = t!("dashboard.hint_menu");
|
||||
let hint_stats = t!("dashboard.hint_stats");
|
||||
let hint_delete = t!("dashboard.hint_delete");
|
||||
let hint_continue = hint::hint(hint::K_C_ENTER_SPACE, t!("dashboard.hint_continue").as_ref());
|
||||
let hint_retry = hint::hint(hint::K_R, t!("dashboard.hint_retry").as_ref());
|
||||
let hint_menu = hint::hint(hint::K_Q, t!("dashboard.hint_menu").as_ref());
|
||||
let hint_stats = hint::hint(hint::K_S, t!("dashboard.hint_stats").as_ref());
|
||||
let hint_delete = hint::hint(hint::K_X, t!("dashboard.hint_delete").as_ref());
|
||||
let hints = [
|
||||
hint_continue.as_ref(),
|
||||
hint_retry.as_ref(),
|
||||
hint_menu.as_ref(),
|
||||
hint_stats.as_ref(),
|
||||
hint_delete.as_ref(),
|
||||
hint_continue.as_str(),
|
||||
hint_retry.as_str(),
|
||||
hint_menu.as_str(),
|
||||
hint_stats.as_str(),
|
||||
hint_delete.as_str(),
|
||||
];
|
||||
pack_hint_lines(&hints, inner.width as usize).len().max(1) as u16
|
||||
};
|
||||
@@ -167,17 +168,17 @@ impl Widget for Dashboard<'_> {
|
||||
),
|
||||
]))
|
||||
} else {
|
||||
let hint_continue = t!("dashboard.hint_continue");
|
||||
let hint_retry = t!("dashboard.hint_retry");
|
||||
let hint_menu = t!("dashboard.hint_menu");
|
||||
let hint_stats = t!("dashboard.hint_stats");
|
||||
let hint_delete = t!("dashboard.hint_delete");
|
||||
let hint_continue = hint::hint(hint::K_C_ENTER_SPACE, t!("dashboard.hint_continue").as_ref());
|
||||
let hint_retry = hint::hint(hint::K_R, t!("dashboard.hint_retry").as_ref());
|
||||
let hint_menu = hint::hint(hint::K_Q, t!("dashboard.hint_menu").as_ref());
|
||||
let hint_stats = hint::hint(hint::K_S, t!("dashboard.hint_stats").as_ref());
|
||||
let hint_delete = hint::hint(hint::K_X, t!("dashboard.hint_delete").as_ref());
|
||||
let hints = [
|
||||
hint_continue.as_ref(),
|
||||
hint_retry.as_ref(),
|
||||
hint_menu.as_ref(),
|
||||
hint_stats.as_ref(),
|
||||
hint_delete.as_ref(),
|
||||
hint_continue.as_str(),
|
||||
hint_retry.as_str(),
|
||||
hint_menu.as_str(),
|
||||
hint_stats.as_str(),
|
||||
hint_delete.as_str(),
|
||||
];
|
||||
let lines: Vec<Line> = pack_hint_lines(&hints, inner.width as usize)
|
||||
.into_iter()
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::engine::key_stats::KeyStatsStore;
|
||||
use crate::engine::skill_tree::{
|
||||
BranchId, BranchStatus, DrillScope, SkillTree as SkillTreeEngine, get_branch_definition,
|
||||
};
|
||||
use crate::ui::hint;
|
||||
use crate::ui::layout::{pack_hint_lines, wrapped_line_count};
|
||||
use crate::ui::theme::Theme;
|
||||
|
||||
@@ -137,11 +138,11 @@ impl Widget for SkillTreeWidget<'_> {
|
||||
|
||||
// Layout: main split (branch list + detail) and footer (adaptive height)
|
||||
let branches = selectable_branches();
|
||||
let h_navigate = t!("skill_tree.hint_navigate").to_string();
|
||||
let h_scroll = t!("skill_tree.hint_scroll").to_string();
|
||||
let h_back = t!("skill_tree.hint_back").to_string();
|
||||
let h_unlock = t!("skill_tree.hint_unlock").to_string();
|
||||
let h_start_drill = t!("skill_tree.hint_start_drill").to_string();
|
||||
let h_navigate = hint::hint(hint::K_UD_JK, t!("skill_tree.hint_navigate").as_ref());
|
||||
let h_scroll = hint::hint(hint::K_SCROLL_KEYS, t!("skill_tree.hint_scroll").as_ref());
|
||||
let h_back = hint::hint(hint::K_Q_ESC, t!("skill_tree.hint_back").as_ref());
|
||||
let h_unlock = hint::hint(hint::K_ENTER, t!("skill_tree.hint_unlock").as_ref());
|
||||
let h_start_drill = hint::hint(hint::K_ENTER, t!("skill_tree.hint_start_drill").as_ref());
|
||||
let (footer_hints, footer_notice): (Vec<&str>, Option<String>) =
|
||||
if self.selected < branches.len() {
|
||||
let bp = self.skill_tree.branch_progress(branches[self.selected]);
|
||||
|
||||
@@ -13,6 +13,7 @@ use crate::keyboard::model::KeyboardModel;
|
||||
use crate::session::result::DrillResult;
|
||||
use crate::ui::components::activity_heatmap::ActivityHeatmap;
|
||||
use crate::i18n::t;
|
||||
use crate::ui::hint;
|
||||
use crate::ui::layout::pack_hint_lines;
|
||||
use crate::ui::theme::Theme;
|
||||
|
||||
@@ -1673,20 +1674,20 @@ const TAB_SEPARATOR: &str = " ";
|
||||
|
||||
fn footer_hints_default() -> Vec<String> {
|
||||
vec![
|
||||
t!("stats.hint_back").to_string(),
|
||||
t!("stats.hint_next_tab").to_string(),
|
||||
t!("stats.hint_switch_tab").to_string(),
|
||||
hint::hint(hint::K_Q_ESC, t!("stats.hint_back").as_ref()),
|
||||
hint::hint(hint::K_TAB, t!("stats.hint_next_tab").as_ref()),
|
||||
hint::hint(hint::K_1_6, t!("stats.hint_switch_tab").as_ref()),
|
||||
]
|
||||
}
|
||||
|
||||
fn footer_hints_history() -> Vec<String> {
|
||||
vec![
|
||||
t!("stats.hint_back").to_string(),
|
||||
t!("stats.hint_next_tab").to_string(),
|
||||
t!("stats.hint_switch_tab").to_string(),
|
||||
t!("stats.hint_navigate").to_string(),
|
||||
t!("stats.hint_page").to_string(),
|
||||
t!("stats.hint_delete").to_string(),
|
||||
hint::hint(hint::K_Q_ESC, t!("stats.hint_back").as_ref()),
|
||||
hint::hint(hint::K_TAB, t!("stats.hint_next_tab").as_ref()),
|
||||
hint::hint(hint::K_1_6, t!("stats.hint_switch_tab").as_ref()),
|
||||
hint::hint(hint::K_J_K, t!("stats.hint_navigate").as_ref()),
|
||||
hint::hint(hint::K_PGUP_PGDN, t!("stats.hint_page").as_ref()),
|
||||
hint::hint(hint::K_X, t!("stats.hint_delete").as_ref()),
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user