From 272b41a6a06b748723e98c5a4d189b6f7467724a Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Thu, 1 Feb 2024 23:35:47 +0100 Subject: [PATCH] Retain ListState when reinitialising --- src/tui/app/selection.rs | 99 +++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/src/tui/app/selection.rs b/src/tui/app/selection.rs index 6926df8..189bcfe 100644 --- a/src/tui/app/selection.rs +++ b/src/tui/app/selection.rs @@ -62,7 +62,7 @@ impl Selection { } pub fn select(&mut self, artists: &[Artist], selected: ActiveSelection) { - self.artist = ArtistSelection::reinitialise(artists, selected.artist); + self.artist.reinitialise(artists, selected.artist); } pub fn increment_category(&mut self) { @@ -124,39 +124,44 @@ impl Selection { impl ArtistSelection { fn initialise(artists: &[Artist]) -> Self { - Self::reinitialise(artists, None) + let mut selection = ArtistSelection { + state: ListState::default(), + album: AlbumSelection::initialise(&[]), + }; + selection.reinitialise(artists, None); + selection } - fn reinitialise(artists: &[Artist], active: Option) -> Self { + fn reinitialise(&mut self, artists: &[Artist], active: Option) { if let Some(active) = active { let result = artists.binary_search_by(|a| a.get_sort_key().cmp(&active.artist_id)); match result { - Ok(index) => Self::reinitialise_with_index(artists, index, active.album), - Err(index) => Self::reinitialise_with_index(artists, index, None), + Ok(index) => self.reinitialise_with_index(artists, index, active.album), + Err(index) => self.reinitialise_with_index(artists, index, None), } } else { - Self::reinitialise_with_index(artists, 0, None) + self.reinitialise_with_index(artists, 0, None) } } fn reinitialise_with_index( + &mut self, artists: &[Artist], mut index: usize, mut active_album: Option, - ) -> Self { - let mut state = ListState::default(); - let album: AlbumSelection; + ) { if artists.is_empty() { - album = AlbumSelection::initialise(&[]); + self.state.select(None); + self.album.reinitialise(&[], None); } else { if index >= artists.len() { index = artists.len() - 1; active_album = None; } - state.select(Some(index)); - album = AlbumSelection::reinitialise(&artists[index].albums, active_album); + self.state.select(Some(index)); + self.album + .reinitialise(&artists[index].albums, active_album); } - ArtistSelection { state, album } } fn increment(&mut self, artists: &[Artist]) { @@ -206,39 +211,43 @@ impl ArtistSelection { impl AlbumSelection { fn initialise(albums: &[Album]) -> Self { - Self::reinitialise(albums, None) + let mut selection = AlbumSelection { + state: ListState::default(), + track: TrackSelection::initialise(&[]), + }; + selection.reinitialise(albums, None); + selection } - fn reinitialise(albums: &[Album], album: Option) -> Self { + fn reinitialise(&mut self, albums: &[Album], album: Option) { if let Some(album) = album { let result = albums.binary_search_by(|a| a.get_sort_key().cmp(&album.album_id)); match result { - Ok(index) => Self::reinitialise_with_index(albums, index, album.track), - Err(index) => Self::reinitialise_with_index(albums, index, None), + Ok(index) => self.reinitialise_with_index(albums, index, album.track), + Err(index) => self.reinitialise_with_index(albums, index, None), } } else { - Self::reinitialise_with_index(albums, 0, None) + self.reinitialise_with_index(albums, 0, None) } } fn reinitialise_with_index( + &mut self, albums: &[Album], mut index: usize, mut active_track: Option, - ) -> Self { - let mut state = ListState::default(); - let track: TrackSelection; + ) { if albums.is_empty() { - track = TrackSelection::initialise(&[]); + self.state.select(None); + self.track = TrackSelection::initialise(&[]); } else { if index >= albums.len() { index = albums.len() - 1; active_track = None; } - state.select(Some(index)); - track = TrackSelection::reinitialise(&albums[index].tracks, active_track); + self.state.select(Some(index)); + self.track.reinitialise(&albums[index].tracks, active_track); } - AlbumSelection { state, track } } fn increment(&mut self, albums: &[Album]) { @@ -276,29 +285,33 @@ impl AlbumSelection { impl TrackSelection { fn initialise(tracks: &[Track]) -> Self { - Self::reinitialise(tracks, None) + let mut selection = TrackSelection { + state: ListState::default(), + }; + selection.reinitialise(tracks, None); + selection } - fn reinitialise(tracks: &[Track], track: Option) -> Self { + fn reinitialise(&mut self, tracks: &[Track], track: Option) { if let Some(track) = track { let result = tracks.binary_search_by(|t| t.get_sort_key().cmp(&track.track_id)); match result { - Ok(index) | Err(index) => Self::reinitialise_with_index(tracks, index), + Ok(index) | Err(index) => self.reinitialise_with_index(tracks, index), } } else { - Self::reinitialise_with_index(tracks, 0) + self.reinitialise_with_index(tracks, 0) } } - fn reinitialise_with_index(tracks: &[Track], mut index: usize) -> Self { - let mut state = ListState::default(); - if !tracks.is_empty() { + fn reinitialise_with_index(&mut self, tracks: &[Track], mut index: usize) { + if tracks.is_empty() { + self.state.select(None); + } else { if index >= tracks.len() { index = tracks.len() - 1; } - state.select(Some(index)); + self.state.select(Some(index)); } - TrackSelection { state } } fn increment(&mut self, tracks: &[Track]) { @@ -415,20 +428,20 @@ mod tests { // Re-initialise. let previous = sel.clone(); let active_track = ActiveTrack::get(tracks, &sel); - sel = TrackSelection::reinitialise(tracks, active_track); + sel.reinitialise(tracks, active_track); assert_eq!(sel, previous); // Re-initialise out-of-bounds. let mut previous = sel.clone(); previous.decrement(tracks); let active_track = ActiveTrack::get(tracks, &sel); - sel = TrackSelection::reinitialise(&tracks[..(tracks.len() - 1)], active_track); + sel.reinitialise(&tracks[..(tracks.len() - 1)], active_track); assert_eq!(sel, previous); // Re-initialise empty. let previous = TrackSelection::initialise(&[]); let active_track = ActiveTrack::get(tracks, &sel); - sel = TrackSelection::reinitialise(&[], active_track); + sel.reinitialise(&[], active_track); assert_eq!(sel, previous); // Artifical test case to verify upper limit. @@ -486,20 +499,20 @@ mod tests { // Re-initialise. let previous = sel.clone(); let active_album = ActiveAlbum::get(albums, &sel); - sel = AlbumSelection::reinitialise(albums, active_album); + sel.reinitialise(albums, active_album); assert_eq!(sel, previous); // Re-initialise out-of-bounds. let mut previous = sel.clone(); previous.decrement(albums); let active_album = ActiveAlbum::get(albums, &sel); - sel = AlbumSelection::reinitialise(&albums[..(albums.len() - 1)], active_album); + sel.reinitialise(&albums[..(albums.len() - 1)], active_album); assert_eq!(sel, previous); // Re-initialise empty. let previous = AlbumSelection::initialise(&[]); let active_album = ActiveAlbum::get(albums, &sel); - sel = AlbumSelection::reinitialise(&[], active_album); + sel.reinitialise(&[], active_album); assert_eq!(sel, previous); // Artifical test case to verify upper limit. @@ -560,20 +573,20 @@ mod tests { // Re-initialise. let previous = sel.clone(); let active_artist = ActiveArtist::get(artists, &sel); - sel = ArtistSelection::reinitialise(artists, active_artist); + sel.reinitialise(artists, active_artist); assert_eq!(sel, previous); // Re-initialise out-of-bounds. let mut previous = sel.clone(); previous.decrement(artists); let active_artist = ActiveArtist::get(artists, &sel); - sel = ArtistSelection::reinitialise(&artists[..(artists.len() - 1)], active_artist); + sel.reinitialise(&artists[..(artists.len() - 1)], active_artist); assert_eq!(sel, previous); // Re-initialise empty. let previous = ArtistSelection::initialise(&[]); let active_artist = ActiveArtist::get(artists, &sel); - sel = ArtistSelection::reinitialise(&[], active_artist); + sel.reinitialise(&[], active_artist); assert_eq!(sel, previous); // Artifical test case to verify upper limit.