From 6bcb1d6579f6d574fd36db021a4f3db890cbd711 Mon Sep 17 00:00:00 2001 From: lalvarezt Date: Thu, 24 Jul 2025 15:44:27 +0200 Subject: [PATCH] refactor(actions): centralize action descriptions --- television/action.rs | 118 ++++++++++++++++++++++++++++++++ television/screen/help_panel.rs | 42 ++---------- 2 files changed, 122 insertions(+), 38 deletions(-) diff --git a/television/action.rs b/television/action.rs index 8ce4d2a..6f051ae 100644 --- a/television/action.rs +++ b/television/action.rs @@ -367,6 +367,101 @@ impl Display for Action { } } +impl Action { + /// Returns a user-friendly description of the action for help panels and UI display. + /// + /// This method provides human-readable descriptions of actions that are suitable + /// for display in help panels, tooltips, and other user interfaces. Unlike the + /// `Display` implementation which returns `snake_case` configuration names, this + /// method returns descriptive text. + /// + /// # Returns + /// + /// A static string slice containing the user-friendly description. + /// + /// # Examples + /// + /// ```rust + /// use television::action::Action; + /// + /// assert_eq!(Action::Quit.description(), "Quit"); + /// assert_eq!(Action::SelectNextEntry.description(), "Navigate down"); + /// assert_eq!(Action::TogglePreview.description(), "Toggle preview"); + /// ``` + pub fn description(&self) -> &'static str { + match self { + // Input actions + Action::AddInputChar(_) => "Add character", + Action::DeletePrevChar => "Delete previous char", + Action::DeletePrevWord => "Delete previous word", + Action::DeleteNextChar => "Delete next char", + Action::DeleteLine => "Delete line", + Action::GoToPrevChar => "Move cursor left", + Action::GoToNextChar => "Move cursor right", + Action::GoToInputStart => "Move to start", + Action::GoToInputEnd => "Move to end", + + // Rendering actions (typically not shown in help) + Action::Render => "Render", + Action::Resize(_, _) => "Resize", + Action::ClearScreen => "Clear screen", + + // Selection actions + Action::ToggleSelectionDown => "Toggle selection down", + Action::ToggleSelectionUp => "Toggle selection up", + Action::ConfirmSelection => "Select entry", + Action::SelectAndExit => "Select and exit", + + // Navigation actions + Action::SelectNextEntry => "Navigate down", + Action::SelectPrevEntry => "Navigate up", + Action::SelectNextPage => "Page down", + Action::SelectPrevPage => "Page up", + Action::CopyEntryToClipboard => "Copy to clipboard", + + // Preview actions + Action::ScrollPreviewUp => "Preview scroll up", + Action::ScrollPreviewDown => "Preview scroll down", + Action::ScrollPreviewHalfPageUp => "Preview scroll half page up", + Action::ScrollPreviewHalfPageDown => { + "Preview scroll half page down" + } + Action::OpenEntry => "Open entry", + + // Application actions + Action::Tick => "Tick", + Action::Suspend => "Suspend", + Action::Resume => "Resume", + Action::Quit => "Quit", + + // Toggle actions + Action::ToggleRemoteControl => "Toggle remote control", + Action::ToggleHelp => "Toggle help", + Action::ToggleStatusBar => "Toggle status bar", + Action::TogglePreview => "Toggle preview", + + // Error and no-op + Action::Error(_) => "Error", + Action::NoOp => "No operation", + + // Channel actions + Action::ToggleSendToChannel => "Toggle send to channel", + Action::CycleSources => "Cycle sources", + Action::ReloadSource => "Reload source", + Action::SwitchToChannel(_) => "Switch to channel", + Action::WatchTimer => "Watch timer", + + // History actions + Action::SelectPrevHistory => "Previous history", + Action::SelectNextHistory => "Next history", + + // Mouse actions + Action::SelectEntryAtPosition(_, _) => "Select at position", + Action::MouseClickAt(_, _) => "Mouse click", + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -448,4 +543,27 @@ mod tests { assert_eq!(map.get(&actions2), Some(&"single")); assert_eq!(map.get(&actions4), Some(&"multiple")); } + + #[test] + fn test_action_description() { + // Test that description() returns user-friendly text + assert_eq!(Action::Quit.description(), "Quit"); + assert_eq!(Action::SelectNextEntry.description(), "Navigate down"); + assert_eq!(Action::SelectPrevEntry.description(), "Navigate up"); + assert_eq!(Action::TogglePreview.description(), "Toggle preview"); + assert_eq!(Action::ToggleHelp.description(), "Toggle help"); + assert_eq!(Action::ConfirmSelection.description(), "Select entry"); + assert_eq!( + Action::CopyEntryToClipboard.description(), + "Copy to clipboard" + ); + + // Test that description() differs from Display (snake_case) + assert_ne!( + Action::SelectNextEntry.description(), + Action::SelectNextEntry.to_string() + ); + assert_eq!(Action::SelectNextEntry.to_string(), "select_next_entry"); + assert_eq!(Action::SelectNextEntry.description(), "Navigate down"); + } } diff --git a/television/screen/help_panel.rs b/television/screen/help_panel.rs index 8f8db39..531a8ba 100644 --- a/television/screen/help_panel.rs +++ b/television/screen/help_panel.rs @@ -81,9 +81,9 @@ fn add_keybinding_lines_for_keys( continue; } - let description = get_action_description(action); + let description = action.description(); let key_string = key.to_string(); - entries.push((description.clone(), key_string.clone())); + entries.push((description.to_string(), key_string.clone())); trace!( "Added keybinding: {} -> {} ({})", key_string, description, category_name @@ -112,40 +112,6 @@ fn add_keybinding_lines_for_keys( } } -/// Get human-readable description for an action -fn get_action_description(action: &Action) -> String { - match action { - Action::Quit => "Quit".to_string(), - Action::TogglePreview => "Toggle preview".to_string(), - Action::ToggleHelp => "Toggle help".to_string(), - Action::ToggleStatusBar => "Toggle status bar".to_string(), - Action::ToggleRemoteControl => "Toggle remote control".to_string(), - Action::SelectPrevEntry => "Navigate up".to_string(), - Action::SelectNextEntry => "Navigate down".to_string(), - Action::SelectPrevPage => "Page up".to_string(), - Action::SelectNextPage => "Page down".to_string(), - Action::SelectPrevHistory => "Previous history".to_string(), - Action::SelectNextHistory => "Next history".to_string(), - Action::ScrollPreviewHalfPageUp => "Preview scroll up".to_string(), - Action::ScrollPreviewHalfPageDown => "Preview scroll down".to_string(), - Action::ConfirmSelection => "Select entry".to_string(), - Action::ToggleSelectionDown => "Toggle selection down".to_string(), - Action::ToggleSelectionUp => "Toggle selection up".to_string(), - Action::CopyEntryToClipboard => "Copy to clipboard".to_string(), - Action::CycleSources => "Cycle sources".to_string(), - Action::ReloadSource => "Reload source".to_string(), - Action::DeletePrevChar => "Delete previous char".to_string(), - Action::DeletePrevWord => "Delete previous word".to_string(), - Action::DeleteNextChar => "Delete next char".to_string(), - Action::DeleteLine => "Delete line".to_string(), - Action::GoToPrevChar => "Move cursor left".to_string(), - Action::GoToNextChar => "Move cursor right".to_string(), - Action::GoToInputStart => "Move to start".to_string(), - Action::GoToInputEnd => "Move to end".to_string(), - _ => action.to_string(), - } -} - /// Generates the help content organized into global and channel-specific groups fn generate_help_content( config: &Config, @@ -280,9 +246,9 @@ pub fn calculate_help_panel_size( .unwrap_or(25); // Calculate dimensions with proper padding: - // - Width: content + 3 (2 borders + 1 padding) + // - Width: content + 4 (2 borders + 2 padding) // - Height: content lines + 2 (2 borders, no title or padding) - let required_width = (max_content_width + 3).max(25) as u16; + let required_width = (max_content_width + 4).max(25) as u16; let required_height = (content.len() + 2).max(8) as u16; trace!(