Had AI add code documentation/comments
This commit is contained in:
		
							
								
								
									
										132
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -16,19 +16,38 @@ use ratatui::{ | ||||
| use ratatui::backend::CrosstermBackend; | ||||
| use std::{io, time::Duration}; | ||||
|  | ||||
| /// Application state | ||||
| /// Main application state holding all the data needed for the TUI | ||||
| struct App { | ||||
|     /// MPD client connection for interacting with the music player daemon | ||||
|     client: Client, | ||||
|     /// Currently playing song, if any | ||||
|     current_song: Option<Song>, | ||||
|     /// List of songs in the current playlist, deduplicated by file path | ||||
|     playlist: Vec<Song>, | ||||
|     /// Current MPD server status including playback state, volume, etc. | ||||
|     status: mpd::Status, | ||||
|     selected_index: usize,  // Currently selected song in the playlist | ||||
|     scroll_offset: usize,   // Offset for playlist scrolling | ||||
|     show_help: bool,       // Whether to show the help panel | ||||
|     /// Index of the currently selected song in the playlist (for UI highlighting) | ||||
|     selected_index: usize, | ||||
|     /// Number of items to skip from the start of playlist (for scrolling) | ||||
|     scroll_offset: usize, | ||||
|     /// Whether to display the help overlay | ||||
|     show_help: bool, | ||||
| } | ||||
|  | ||||
| impl App { | ||||
|     /// Create a new App instance, connecting to MPD | ||||
|     /// Creates a new application instance and initializes the MPD connection | ||||
|     ///  | ||||
|     /// This function: | ||||
|     /// 1. Connects to the MPD server at localhost:6600 | ||||
|     /// 2. Retrieves initial server status | ||||
|     /// 3. Gets the current playlist | ||||
|     /// 4. Gets the currently playing song | ||||
|     ///  | ||||
|     /// # Errors | ||||
|     ///  | ||||
|     /// Returns an error if: | ||||
|     /// - Cannot connect to MPD server | ||||
|     /// - Failed to retrieve initial state from server | ||||
|     fn new() -> Result<Self, anyhow::Error> { | ||||
|         let mut client = Client::connect("127.0.0.1:6600")?; | ||||
|         let status = client.status()?; | ||||
| @@ -46,7 +65,22 @@ impl App { | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     /// Refresh the application state from MPD | ||||
|     /// Updates the application state by fetching fresh data from the MPD server | ||||
|     ///  | ||||
|     /// This function: | ||||
|     /// 1. Updates the server status (play state, volume, etc) | ||||
|     /// 2. Updates the currently playing song | ||||
|     /// 3. Refreshes the playlist, removing any duplicates | ||||
|     /// 4. Adjusts scroll position to keep selected item visible | ||||
|     ///  | ||||
|     /// # Arguments | ||||
|     ///  | ||||
|     /// * `playlist_height` - The number of playlist items that can be displayed at once | ||||
|     ///                      Used to adjust scrolling to keep selected item visible | ||||
|     ///  | ||||
|     /// # Errors | ||||
|     ///  | ||||
|     /// Returns an error if communication with MPD server fails | ||||
|     fn refresh(&mut self, playlist_height: usize) -> Result<(), anyhow::Error> { | ||||
|         self.status = self.client.status()?; | ||||
|         self.current_song = self.client.currentsong()?; | ||||
| @@ -79,21 +113,33 @@ impl App { | ||||
|         Ok(()) | ||||
|     } | ||||
|      | ||||
|     /// Move selection up, adjusting scroll if necessary | ||||
|     /// Moves the selection cursor up one item in the playlist | ||||
|     ///  | ||||
|     /// Will not move past the first item (index 0) | ||||
|     fn move_up(&mut self) { | ||||
|         if self.selected_index > 0 { | ||||
|             self.selected_index -= 1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Move selection down, adjusting scroll if necessary | ||||
|     /// Moves the selection cursor down one item in the playlist | ||||
|     ///  | ||||
|     /// Will not move past the last item in the playlist | ||||
|     fn move_down(&mut self) { | ||||
|         if self.selected_index + 1 < self.playlist.len() { | ||||
|             self.selected_index += 1; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     /// Update scroll offset to ensure selected item is visible | ||||
|     /// Adjusts the scroll offset to ensure the selected item remains visible | ||||
|     ///  | ||||
|     /// This function handles two cases: | ||||
|     /// 1. Selected item is below visible area -> Scroll down to show it | ||||
|     /// 2. Selected item is above visible area -> Scroll up to show it | ||||
|     ///  | ||||
|     /// # Arguments | ||||
|     ///  | ||||
|     /// * `height` - Number of items that can be displayed at once | ||||
|     fn update_scroll(&mut self, height: usize) { | ||||
|         if self.selected_index >= self.scroll_offset + height { | ||||
|             self.scroll_offset = self.selected_index.saturating_sub(height) + 1; | ||||
| @@ -103,8 +149,19 @@ impl App { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Main entry point for the Sonnet MPD client | ||||
| ///  | ||||
| /// Sets up the terminal UI environment and runs the main application loop. | ||||
| /// Handles cleanup when the application exits. | ||||
| ///  | ||||
| /// # Error | ||||
| ///  | ||||
| /// Returns an error if: | ||||
| /// - Terminal setup fails | ||||
| /// - MPD connection fails | ||||
| /// - Terminal restoration fails | ||||
| fn main() -> anyhow::Result<()> { | ||||
|     // Setup terminal | ||||
|     // Setup terminal in raw mode and alternate screen | ||||
|     enable_raw_mode()?; | ||||
|     let mut stdout = io::stdout(); | ||||
|     execute!(stdout, EnterAlternateScreen)?; | ||||
| @@ -127,9 +184,25 @@ fn main() -> anyhow::Result<()> { | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| /// Main application loop handling user input and UI updates | ||||
| ///  | ||||
| /// This function: | ||||
| /// 1. Continuously updates the application state | ||||
| /// 2. Redraws the terminal UI | ||||
| /// 3. Handles keyboard input events | ||||
| /// 4. Controls MPD playback based on user commands | ||||
| ///  | ||||
| /// # Arguments | ||||
| ///  | ||||
| /// * `terminal` - The terminal interface for rendering | ||||
| /// * `app` - The application state | ||||
| ///  | ||||
| /// # Type Parameters | ||||
| ///  | ||||
| /// * `B` - The terminal backend type (allows for different terminal implementations) | ||||
| fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: &mut App) -> anyhow::Result<()> { | ||||
|     loop { | ||||
|         // Get the available height for the playlist | ||||
|         // Calculate available height for playlist display | ||||
|         let height = terminal.size()?.height.saturating_sub(12) as usize; | ||||
|         app.refresh(height)?; | ||||
|          | ||||
| @@ -182,7 +255,20 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: &mut App) -> anyhow::Res | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Helper function to create a centered rect using up certain percentage of the available rect | ||||
| /// Creates a centered rectangle for modal overlays like the help panel | ||||
| ///  | ||||
| /// This function creates a rectangle that is centered both horizontally and vertically | ||||
| /// within the given space. The size is specified as percentages of the available space. | ||||
| ///  | ||||
| /// # Arguments | ||||
| ///  | ||||
| /// * `percent_x` - Width of the rectangle as a percentage of parent width | ||||
| /// * `percent_y` - Height of the rectangle as a percentage of parent height | ||||
| /// * `r` - The parent rectangle within which to center the new rectangle | ||||
| ///  | ||||
| /// # Returns | ||||
| ///  | ||||
| /// A new rectangle centered within the parent, with the specified size | ||||
| fn centered_rect(percent_x: u16, percent_y: u16, r: ratatui::layout::Rect) -> ratatui::layout::Rect { | ||||
|     // Calculate the width and height of the popup | ||||
|     let popup_layout = Layout::default() | ||||
| @@ -204,13 +290,29 @@ fn centered_rect(percent_x: u16, percent_y: u16, r: ratatui::layout::Rect) -> ra | ||||
|         .split(popup_layout[1])[1] | ||||
| } | ||||
|  | ||||
| /// Renders the terminal user interface | ||||
| ///  | ||||
| /// The UI is composed of several sections: | ||||
| /// - Header: Shows the application title | ||||
| /// - Status: Displays current playback status and song info | ||||
| /// - Playlist: Shows the list of songs with selection highlight | ||||
| /// - Help Panel: Optional overlay showing keyboard shortcuts | ||||
| ///  | ||||
| /// The layout is organized vertically with fixed heights for header and status, | ||||
| /// and the playlist taking the remaining space. | ||||
| ///  | ||||
| /// # Arguments | ||||
| ///  | ||||
| /// * `f` - Frame for rendering UI elements | ||||
| /// * `app` - Application state containing all the data to display | ||||
| pub(crate) fn ui(f: &mut Frame, app: &App) { | ||||
|     // Create the main vertical layout | ||||
|     let chunks = Layout::default() | ||||
|         .direction(Direction::Vertical) | ||||
|         .constraints([ | ||||
|             Constraint::Length(3),  // Header | ||||
|             Constraint::Length(10), // Status | ||||
|             Constraint::Min(0)      // Playlist | ||||
|             Constraint::Length(3),  // Header: Fixed 3 lines | ||||
|             Constraint::Length(10), // Status: Fixed 10 lines | ||||
|             Constraint::Min(0)      // Playlist: All remaining space | ||||
|         ].as_ref()) | ||||
|         .split(f.size()); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user