diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-03-28 21:13:41 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-03-28 21:13:41 +0300 |
| commit | fa1adf1a26033fc50a2920d96045e76aba93bddb (patch) | |
| tree | 383bd48d0c6bcad7ccf1d5c907f78fd7eee1797f /src/app/input.rs | |
| parent | d05ba2ea9f1ab2379f5be5ef7fc3898a03f5dce1 (diff) | |
feat: add onboarding and toast notification preferences
Diffstat (limited to 'src/app/input.rs')
| -rw-r--r-- | src/app/input.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/app/input.rs b/src/app/input.rs index 590e9548..7d2e709e 100644 --- a/src/app/input.rs +++ b/src/app/input.rs @@ -18,6 +18,7 @@ use super::App; impl App { pub(super) async fn handle_key(&mut self, key: KeyEvent) { match self.state.mode { + Mode::Onboarding => self.handle_onboarding_key(key), Mode::Navigate => handle_navigate_key(&mut self.state, key), Mode::Terminal => self.handle_terminal_key(key).await, Mode::RenameSession => handle_rename_key(&mut self.state, key), @@ -49,6 +50,39 @@ impl App { } } + fn handle_onboarding_key(&mut self, key: KeyEvent) { + match self.state.onboarding_step { + 0 => match key.code { + KeyCode::Enter | KeyCode::Right | KeyCode::Char('l') => { + self.state.onboarding_step = 1; + } + KeyCode::Char('q') => self.state.should_quit = true, + _ => {} + }, + _ => match key.code { + KeyCode::Up | KeyCode::Char('k') => { + if self.state.onboarding_selected > 0 { + self.state.onboarding_selected -= 1; + } + } + KeyCode::Down | KeyCode::Char('j') => { + if self.state.onboarding_selected < 3 { + self.state.onboarding_selected += 1; + } + } + KeyCode::Left | KeyCode::Esc | KeyCode::Char('h') => { + self.state.onboarding_step = 0; + } + KeyCode::Char(c) if ('1'..='4').contains(&c) => { + self.state.onboarding_selected = (c as usize) - ('1' as usize); + } + KeyCode::Enter => self.complete_onboarding(), + KeyCode::Char('q') => self.state.should_quit = true, + _ => {} + }, + } + } + async fn handle_terminal_key(&mut self, key: KeyEvent) { self.state.clear_selection(); self.state.update_dismissed = true; @@ -338,7 +372,76 @@ fn handle_context_menu_key(state: &mut AppState, key: KeyEvent) { // --------------------------------------------------------------------------- impl AppState { + fn onboarding_full_area(&self) -> ratatui::layout::Rect { + self.view.sidebar_rect.union(self.view.terminal_area) + } + + fn onboarding_modal_inner(&self, popup_w: u16, popup_h: u16) -> Option<ratatui::layout::Rect> { + let area = self.onboarding_full_area(); + let popup_w = popup_w.min(area.width.saturating_sub(4)); + let popup_h = popup_h.min(area.height.saturating_sub(2)); + if popup_w < 4 || popup_h < 4 { + return None; + } + let popup_x = area.x + (area.width.saturating_sub(popup_w)) / 2; + let popup_y = area.y + (area.height.saturating_sub(popup_h)) / 2; + let popup = ratatui::layout::Rect::new(popup_x, popup_y, popup_w, popup_h); + let block = ratatui::widgets::Block::default().borders(ratatui::widgets::Borders::ALL); + Some(block.inner(popup)) + } + + fn handle_onboarding_mouse(&mut self, mouse: MouseEvent) { + if mouse.kind != MouseEventKind::Down(MouseButton::Left) { + return; + } + + match self.onboarding_step { + 0 => { + let Some(inner) = self.onboarding_modal_inner(64, 15) else { + return; + }; + let footer_y = inner.y + 9; + let button_x = inner.x; + let button_w = 14; + if mouse.row == footer_y + && mouse.column >= button_x + && mouse.column < button_x + button_w + { + self.onboarding_step = 1; + } + } + _ => { + let Some(inner) = self.onboarding_modal_inner(52, 10) else { + return; + }; + let options_start_y = inner.y + 2; + if mouse.row >= options_start_y && mouse.row < options_start_y + 4 { + self.onboarding_selected = (mouse.row - options_start_y) as usize; + return; + } + + let footer_y = inner.y + 6; + let back_x = inner.x; + let back_w = 10; + let save_x = inner.x + 12; + let save_w = 10; + if mouse.row == footer_y { + if mouse.column >= back_x && mouse.column < back_x + back_w { + self.onboarding_step = 0; + } else if mouse.column >= save_x && mouse.column < save_x + save_w { + self.request_complete_onboarding = true; + } + } + } + } + } + pub(crate) fn handle_mouse(&mut self, mouse: MouseEvent) { + if self.mode == Mode::Onboarding { + self.handle_onboarding_mouse(mouse); + return; + } + let sidebar = self.view.sidebar_rect; let in_sidebar = mouse.column >= sidebar.x && mouse.column < sidebar.x + sidebar.width |
