diff options
Diffstat (limited to 'src/app/input')
| -rw-r--r-- | src/app/input/mod.rs | 3 | ||||
| -rw-r--r-- | src/app/input/settings.rs | 126 |
2 files changed, 125 insertions, 4 deletions
diff --git a/src/app/input/mod.rs b/src/app/input/mod.rs index 44491631..0f2f575d 100644 --- a/src/app/input/mod.rs +++ b/src/app/input/mod.rs @@ -204,6 +204,9 @@ impl App { SettingsAction::SaveAgentBorderLabels(enabled) => { self.save_agent_border_labels(enabled) } + SettingsAction::SavePaneHistory(enabled) => { + self.save_pane_history_persistence(enabled) + } SettingsAction::InstallRecommendedIntegrations => { self.install_recommended_integrations() } diff --git a/src/app/input/settings.rs b/src/app/input/settings.rs index 6caccb0e..986f59e2 100644 --- a/src/app/input/settings.rs +++ b/src/app/input/settings.rs @@ -17,6 +17,7 @@ pub(super) enum SettingsAction { SaveSound(bool), SaveToastDelivery(ToastDelivery), SaveAgentBorderLabels(bool), + SavePaneHistory(bool), InstallRecommendedIntegrations, } @@ -31,6 +32,9 @@ impl App { SettingsAction::SaveAgentBorderLabels(enabled) => { self.save_agent_border_labels(enabled) } + SettingsAction::SavePaneHistory(enabled) => { + self.save_pane_history_persistence(enabled) + } SettingsAction::InstallRecommendedIntegrations => { self.install_recommended_integrations() } @@ -142,6 +146,10 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti state.settings.section = SettingsSection::Sound; state.settings.list.selected = usize::from(!state.sound_enabled()); } + KeyCode::BackTab | KeyCode::Left | KeyCode::Char('h') => { + state.settings.section = SettingsSection::Experiments; + state.settings.list.selected = 0; + } _ => match super::modal::modal_action_from_key(&key, super::modal::SETTINGS_ACTIONS) { Some(super::modal::ModalAction::Apply) => return apply_settings(state), Some(super::modal::ModalAction::Close) => cancel_settings(state), @@ -219,6 +227,28 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti } } }, + SettingsSection::Experiments => match key.code { + KeyCode::Enter | KeyCode::Char(' ') => { + return Some(SettingsAction::SavePaneHistory( + !state.pane_history_persistence_enabled(), + )); + } + KeyCode::BackTab | KeyCode::Left | KeyCode::Char('h') => { + state.settings.section = SettingsSection::Integrations; + state.settings.list.selected = 0; + } + KeyCode::Tab | KeyCode::Right | KeyCode::Char('l') => { + state.settings.section = SettingsSection::Theme; + state.settings.list.selected = current_theme_index(&state.theme_name); + } + _ => { + if let Some(super::modal::ModalAction::Close) = + super::modal::modal_action_from_key(&key, super::modal::SETTINGS_ACTIONS) + { + cancel_settings(state); + } + } + }, SettingsSection::Integrations => match key.code { KeyCode::Enter | KeyCode::Char(' ') if integrations_need_install(state) => { return Some(SettingsAction::InstallRecommendedIntegrations); @@ -228,8 +258,8 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti state.settings.list.selected = usize::from(!state.agent_border_labels_enabled()); } KeyCode::Tab | KeyCode::Right | KeyCode::Char('l') => { - state.settings.section = SettingsSection::Theme; - state.settings.list.selected = current_theme_index(&state.theme_name); + state.settings.section = SettingsSection::Experiments; + state.settings.list.selected = 0; } _ => match super::modal::modal_action_from_key(&key, super::modal::SETTINGS_ACTIONS) { Some(super::modal::ModalAction::Apply) => return apply_settings(state), @@ -255,6 +285,7 @@ pub(crate) fn open_settings_at(state: &mut AppState, section: SettingsSection) { SettingsSection::Sound => usize::from(!state.sound_enabled()), SettingsSection::Toast => toast_delivery_index(state.toast_delivery()), SettingsSection::PaneLabels => usize::from(!state.agent_border_labels_enabled()), + SettingsSection::Experiments => 0, SettingsSection::Integrations => 0, }; state.mode = Mode::Settings; @@ -344,6 +375,10 @@ impl AppState { None } } + SettingsSection::Experiments => { + let list_y = area.y + 3; + (row == list_y).then_some(0) + } SettingsSection::Integrations => None, } } @@ -360,6 +395,7 @@ impl AppState { SettingsSection::PaneLabels => { usize::from(!self.agent_border_labels_enabled()) } + SettingsSection::Experiments => 0, SettingsSection::Integrations => 0, }); return None; @@ -383,6 +419,9 @@ impl AppState { let enabled = idx == 0; Some(SettingsAction::SaveAgentBorderLabels(enabled)) } + SettingsSection::Experiments => Some(SettingsAction::SavePaneHistory( + !self.pane_history_persistence_enabled(), + )), SettingsSection::Integrations => None, }; } @@ -470,6 +509,57 @@ mod tests { } #[test] + fn settings_experiments_toggles_pane_history() { + let mut state = state_with_workspaces(&["test"]); + state.pane_history_persistence = false; + open_settings_at(&mut state, SettingsSection::Experiments); + + let action = update_settings_state( + &mut state, + KeyEvent::new(KeyCode::Enter, KeyModifiers::empty()), + ); + + assert_eq!(action, Some(SettingsAction::SavePaneHistory(true))); + assert_eq!(state.mode, Mode::Settings); + } + + #[test] + fn settings_tab_cycle_places_experiments_last() { + let mut state = state_with_workspaces(&["test"]); + open_settings_at(&mut state, SettingsSection::PaneLabels); + + update_settings_state( + &mut state, + KeyEvent::new(KeyCode::Tab, KeyModifiers::empty()), + ); + assert_eq!(state.settings.section, SettingsSection::Integrations); + + update_settings_state( + &mut state, + KeyEvent::new(KeyCode::Tab, KeyModifiers::empty()), + ); + assert_eq!(state.settings.section, SettingsSection::Experiments); + + update_settings_state( + &mut state, + KeyEvent::new(KeyCode::Tab, KeyModifiers::empty()), + ); + assert_eq!(state.settings.section, SettingsSection::Theme); + + update_settings_state( + &mut state, + KeyEvent::new(KeyCode::BackTab, KeyModifiers::empty()), + ); + assert_eq!(state.settings.section, SettingsSection::Experiments); + + update_settings_state( + &mut state, + KeyEvent::new(KeyCode::BackTab, KeyModifiers::empty()), + ); + assert_eq!(state.settings.section, SettingsSection::Integrations); + } + + #[test] fn integrations_enter_does_nothing_when_nothing_needs_install() { let mut state = state_with_workspaces(&["test"]); open_settings_at(&mut state, SettingsSection::Integrations); @@ -500,6 +590,23 @@ mod tests { } #[test] + fn settings_mouse_click_toggles_pane_history() { + let mut app = app_for_mouse_test(); + app.state.pane_history_persistence = false; + open_settings_at(&mut app.state, SettingsSection::Experiments); + + let area = app.state.settings_content_rect(); + let action = app.state.handle_settings_mouse(mouse( + MouseEventKind::Down(crossterm::event::MouseButton::Left), + area.x + 2, + area.y + 3, + )); + + assert_eq!(action, Some(SettingsAction::SavePaneHistory(true))); + assert_eq!(app.state.settings.list.selected, 0); + } + + #[test] fn integration_update_badge_only_tracks_outdated_recommendations() { let mut state = state_with_workspaces(&["test"]); state.integration_recommendations = vec![integration_recommendation( @@ -538,10 +645,21 @@ mod tests { let inner = state.settings_inner_rect(); let tab_y = inner.y + 1; + let integrations_idx = SettingsSection::ALL + .iter() + .position(|section| *section == SettingsSection::Integrations) + .expect("integrations section should be present"); let integrations_x = inner.x - + SettingsSection::ALL[..SettingsSection::ALL.len() - 1] + + SettingsSection::ALL[..integrations_idx] .iter() - .map(|section| section.label().len() as u16 + 3) + .map(|section| { + let badge_width = if state.settings_section_has_badge(*section) { + 2 + } else { + 0 + }; + section.label().len() as u16 + 3 + badge_width + }) .sum::<u16>(); let dotted_width = SettingsSection::Integrations.label().len() as u16 + 4; |
