Extract handle_artists_click and handle_playlists_click into mouse_artists.rs and mouse_playlists.rs respectively, reducing mouse.rs from ~530 to ~247 lines. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
90 lines
3.9 KiB
Rust
90 lines
3.9 KiB
Rust
use crate::error::Error;
|
|
|
|
use super::*;
|
|
|
|
impl App {
|
|
/// Handle click on playlists page
|
|
pub(super) async fn handle_playlists_click(
|
|
&mut self,
|
|
x: u16,
|
|
y: u16,
|
|
layout: &LayoutAreas,
|
|
) -> Result<(), Error> {
|
|
let mut state = self.state.write().await;
|
|
let left = layout.content_left.unwrap_or(layout.content);
|
|
let right = layout.content_right.unwrap_or(layout.content);
|
|
|
|
if x >= left.x && x < left.x + left.width && y >= left.y && y < left.y + left.height {
|
|
// Playlists pane
|
|
let row_in_viewport = y.saturating_sub(left.y + 1) as usize;
|
|
let item_index = state.playlists.playlist_scroll_offset + row_in_viewport;
|
|
|
|
if item_index < state.playlists.playlists.len() {
|
|
let was_selected = state.playlists.selected_playlist == Some(item_index);
|
|
state.playlists.focus = 0;
|
|
state.playlists.selected_playlist = Some(item_index);
|
|
|
|
let is_second_click = was_selected
|
|
&& self.last_click.is_some_and(|(lx, ly, t)| {
|
|
lx == x && ly == y && t.elapsed().as_millis() < 500
|
|
});
|
|
|
|
if is_second_click {
|
|
// Load playlist songs (same as Enter)
|
|
let playlist = state.playlists.playlists[item_index].clone();
|
|
let playlist_id = playlist.id.clone();
|
|
let playlist_name = playlist.name.clone();
|
|
drop(state);
|
|
|
|
if let Some(ref client) = self.subsonic {
|
|
match client.get_playlist(&playlist_id).await {
|
|
Ok((_playlist, songs)) => {
|
|
let mut state = self.state.write().await;
|
|
let count = songs.len();
|
|
state.playlists.songs = songs;
|
|
state.playlists.selected_song = if count > 0 { Some(0) } else { None };
|
|
state.playlists.focus = 1;
|
|
state.notify(format!("Loaded playlist: {} ({} songs)", playlist_name, count));
|
|
}
|
|
Err(e) => {
|
|
let mut state = self.state.write().await;
|
|
state.notify_error(format!("Failed to load playlist: {}", e));
|
|
}
|
|
}
|
|
}
|
|
self.last_click = Some((x, y, std::time::Instant::now()));
|
|
return Ok(());
|
|
}
|
|
}
|
|
} else if x >= right.x && x < right.x + right.width && y >= right.y && y < right.y + right.height {
|
|
// Songs pane
|
|
let row_in_viewport = y.saturating_sub(right.y + 1) as usize;
|
|
let item_index = state.playlists.song_scroll_offset + row_in_viewport;
|
|
|
|
if item_index < state.playlists.songs.len() {
|
|
let was_selected = state.playlists.selected_song == Some(item_index);
|
|
state.playlists.focus = 1;
|
|
state.playlists.selected_song = Some(item_index);
|
|
|
|
let is_second_click = was_selected
|
|
&& self.last_click.is_some_and(|(lx, ly, t)| {
|
|
lx == x && ly == y && t.elapsed().as_millis() < 500
|
|
});
|
|
|
|
if is_second_click {
|
|
// Play selected song from playlist
|
|
let songs = state.playlists.songs.clone();
|
|
state.queue.clear();
|
|
state.queue.extend(songs);
|
|
drop(state);
|
|
self.last_click = Some((x, y, std::time::Instant::now()));
|
|
return self.play_queue_position(item_index).await;
|
|
}
|
|
}
|
|
}
|
|
|
|
self.last_click = Some((x, y, std::time::Instant::now()));
|
|
Ok(())
|
|
}
|
|
}
|