Add support for PgUp and PgDn scrolling #121
@ -26,6 +26,11 @@ pub static DATABASE_JSON: &str = "[\
|
|||||||
\"id\":{\"number\":3,\"title\":\"track a.a.3\"},\
|
\"id\":{\"number\":3,\"title\":\"track a.a.3\"},\
|
||||||
\"artist\":[\"artist a.a.3\"],\
|
\"artist\":[\"artist a.a.3\"],\
|
||||||
\"quality\":{\"format\":\"Flac\",\"bitrate\":1061}\
|
\"quality\":{\"format\":\"Flac\",\"bitrate\":1061}\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":4,\"title\":\"track a.a.4\"},\
|
||||||
|
\"artist\":[\"artist a.a.4\"],\
|
||||||
|
\"quality\":{\"format\":\"Flac\",\"bitrate\":1042}\
|
||||||
}\
|
}\
|
||||||
]\
|
]\
|
||||||
},\
|
},\
|
||||||
@ -88,6 +93,36 @@ pub static DATABASE_JSON: &str = "[\
|
|||||||
\"quality\":{\"format\":\"Mp3\",\"bitrate\":320}\
|
\"quality\":{\"format\":\"Mp3\",\"bitrate\":320}\
|
||||||
}\
|
}\
|
||||||
]\
|
]\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"year\":2009,\"title\":\"album_title b.c\"},\
|
||||||
|
\"tracks\":[\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":1,\"title\":\"track b.c.1\"},\
|
||||||
|
\"artist\":[\"artist b.c.1\"],\
|
||||||
|
\"quality\":{\"format\":\"Mp3\",\"bitrate\":190}\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":2,\"title\":\"track b.c.2\"},\
|
||||||
|
\"artist\":[\"artist b.c.2.1\",\"artist b.c.2.2\"],\
|
||||||
|
\"quality\":{\"format\":\"Mp3\",\"bitrate\":120}\
|
||||||
|
}\
|
||||||
|
]\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"year\":2015,\"title\":\"album_title b.d\"},\
|
||||||
|
\"tracks\":[\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":1,\"title\":\"track b.d.1\"},\
|
||||||
|
\"artist\":[\"artist b.d.1\"],\
|
||||||
|
\"quality\":{\"format\":\"Mp3\",\"bitrate\":190}\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":2,\"title\":\"track b.d.2\"},\
|
||||||
|
\"artist\":[\"artist b.d.2.1\",\"artist b.d.2.2\"],\
|
||||||
|
\"quality\":{\"format\":\"Mp3\",\"bitrate\":120}\
|
||||||
|
}\
|
||||||
|
]\
|
||||||
}\
|
}\
|
||||||
]\
|
]\
|
||||||
},\
|
},\
|
||||||
@ -132,5 +167,47 @@ pub static DATABASE_JSON: &str = "[\
|
|||||||
]\
|
]\
|
||||||
}\
|
}\
|
||||||
]\
|
]\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"name\":\"album_artist d\"},\
|
||||||
|
\"sort\":null,\
|
||||||
|
\"properties\":{\
|
||||||
|
\"musicbrainz\":null,\
|
||||||
|
\"musicbutler\":[],\
|
||||||
|
\"bandcamp\":[],\
|
||||||
|
\"qobuz\":null\
|
||||||
|
},\
|
||||||
|
\"albums\":[\
|
||||||
|
{\
|
||||||
|
\"id\":{\"year\":1995,\"title\":\"album_title d.a\"},\
|
||||||
|
\"tracks\":[\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":1,\"title\":\"track d.a.1\"},\
|
||||||
|
\"artist\":[\"artist d.a.1\"],\
|
||||||
|
\"quality\":{\"format\":\"Mp3\",\"bitrate\":120}\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":2,\"title\":\"track d.a.2\"},\
|
||||||
|
\"artist\":[\"artist d.a.2.1\",\"artist d.a.2.2\"],\
|
||||||
|
\"quality\":{\"format\":\"Mp3\",\"bitrate\":120}\
|
||||||
|
}\
|
||||||
|
]\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"year\":2028,\"title\":\"album_title d.b\"},\
|
||||||
|
\"tracks\":[\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":1,\"title\":\"track d.b.1\"},\
|
||||||
|
\"artist\":[\"artist d.b.1\"],\
|
||||||
|
\"quality\":{\"format\":\"Flac\",\"bitrate\":841}\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
\"id\":{\"number\":2,\"title\":\"track d.b.2\"},\
|
||||||
|
\"artist\":[\"artist d.b.2.1\",\"artist d.b.2.2\"],\
|
||||||
|
\"quality\":{\"format\":\"Flac\",\"bitrate\":756}\
|
||||||
|
}\
|
||||||
|
]\
|
||||||
|
}\
|
||||||
|
]\
|
||||||
}\
|
}\
|
||||||
]";
|
]";
|
||||||
|
@ -5,15 +5,24 @@ pub static LIBRARY_BEETS: Lazy<Vec<String>> = Lazy::new(|| -> Vec<String> {
|
|||||||
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 1 -*^- track a.a.1 -*^- artist a.a.1 -*^- FLAC -*^- 992"),
|
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 1 -*^- track a.a.1 -*^- artist a.a.1 -*^- FLAC -*^- 992"),
|
||||||
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 2 -*^- track a.a.2 -*^- artist a.a.2.1; artist a.a.2.2 -*^- MP3 -*^- 320"),
|
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 2 -*^- track a.a.2 -*^- artist a.a.2.1; artist a.a.2.2 -*^- MP3 -*^- 320"),
|
||||||
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 3 -*^- track a.a.3 -*^- artist a.a.3 -*^- FLAC -*^- 1061"),
|
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 3 -*^- track a.a.3 -*^- artist a.a.3 -*^- FLAC -*^- 1061"),
|
||||||
|
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 4 -*^- track a.a.4 -*^- artist a.a.4 -*^- FLAC -*^- 1042"),
|
||||||
String::from("album_artist a -*^- -*^- 2015 -*^- album_title a.b -*^- 1 -*^- track a.b.1 -*^- artist a.b.1 -*^- FLAC -*^- 1004"),
|
String::from("album_artist a -*^- -*^- 2015 -*^- album_title a.b -*^- 1 -*^- track a.b.1 -*^- artist a.b.1 -*^- FLAC -*^- 1004"),
|
||||||
String::from("album_artist a -*^- -*^- 2015 -*^- album_title a.b -*^- 2 -*^- track a.b.2 -*^- artist a.b.2 -*^- FLAC -*^- 1077"),
|
String::from("album_artist a -*^- -*^- 2015 -*^- album_title a.b -*^- 2 -*^- track a.b.2 -*^- artist a.b.2 -*^- FLAC -*^- 1077"),
|
||||||
String::from("album_artist b -*^- -*^- 2003 -*^- album_title b.a -*^- 1 -*^- track b.a.1 -*^- artist b.a.1 -*^- MP3 -*^- 190"),
|
String::from("album_artist b -*^- -*^- 2003 -*^- album_title b.a -*^- 1 -*^- track b.a.1 -*^- artist b.a.1 -*^- MP3 -*^- 190"),
|
||||||
String::from("album_artist b -*^- -*^- 2003 -*^- album_title b.a -*^- 2 -*^- track b.a.2 -*^- artist b.a.2.1; artist b.a.2.2 -*^- MP3 -*^- 120"),
|
String::from("album_artist b -*^- -*^- 2003 -*^- album_title b.a -*^- 2 -*^- track b.a.2 -*^- artist b.a.2.1; artist b.a.2.2 -*^- MP3 -*^- 120"),
|
||||||
String::from("album_artist b -*^- -*^- 2008 -*^- album_title b.b -*^- 1 -*^- track b.b.1 -*^- artist b.b.1 -*^- FLAC -*^- 1077"),
|
String::from("album_artist b -*^- -*^- 2008 -*^- album_title b.b -*^- 1 -*^- track b.b.1 -*^- artist b.b.1 -*^- FLAC -*^- 1077"),
|
||||||
String::from("album_artist b -*^- -*^- 2008 -*^- album_title b.b -*^- 2 -*^- track b.b.2 -*^- artist b.b.2.1; artist b.b.2.2 -*^- MP3 -*^- 320"),
|
String::from("album_artist b -*^- -*^- 2008 -*^- album_title b.b -*^- 2 -*^- track b.b.2 -*^- artist b.b.2.1; artist b.b.2.2 -*^- MP3 -*^- 320"),
|
||||||
|
String::from("album_artist b -*^- -*^- 2009 -*^- album_title b.c -*^- 1 -*^- track b.c.1 -*^- artist b.c.1 -*^- MP3 -*^- 190"),
|
||||||
|
String::from("album_artist b -*^- -*^- 2009 -*^- album_title b.c -*^- 2 -*^- track b.c.2 -*^- artist b.c.2.1; artist b.c.2.2 -*^- MP3 -*^- 120"),
|
||||||
|
String::from("album_artist b -*^- -*^- 2015 -*^- album_title b.d -*^- 1 -*^- track b.d.1 -*^- artist b.d.1 -*^- MP3 -*^- 190"),
|
||||||
|
String::from("album_artist b -*^- -*^- 2015 -*^- album_title b.d -*^- 2 -*^- track b.d.2 -*^- artist b.d.2.1; artist b.d.2.2 -*^- MP3 -*^- 120"),
|
||||||
String::from("album_artist c -*^- -*^- 1985 -*^- album_title c.a -*^- 1 -*^- track c.a.1 -*^- artist c.a.1 -*^- MP3 -*^- 320"),
|
String::from("album_artist c -*^- -*^- 1985 -*^- album_title c.a -*^- 1 -*^- track c.a.1 -*^- artist c.a.1 -*^- MP3 -*^- 320"),
|
||||||
String::from("album_artist c -*^- -*^- 1985 -*^- album_title c.a -*^- 2 -*^- track c.a.2 -*^- artist c.a.2.1; artist c.a.2.2 -*^- MP3 -*^- 120"),
|
String::from("album_artist c -*^- -*^- 1985 -*^- album_title c.a -*^- 2 -*^- track c.a.2 -*^- artist c.a.2.1; artist c.a.2.2 -*^- MP3 -*^- 120"),
|
||||||
String::from("album_artist c -*^- -*^- 2018 -*^- album_title c.b -*^- 1 -*^- track c.b.1 -*^- artist c.b.1 -*^- FLAC -*^- 1041"),
|
String::from("album_artist c -*^- -*^- 2018 -*^- album_title c.b -*^- 1 -*^- track c.b.1 -*^- artist c.b.1 -*^- FLAC -*^- 1041"),
|
||||||
String::from("album_artist c -*^- -*^- 2018 -*^- album_title c.b -*^- 2 -*^- track c.b.2 -*^- artist c.b.2.1; artist c.b.2.2 -*^- FLAC -*^- 756")
|
String::from("album_artist c -*^- -*^- 2018 -*^- album_title c.b -*^- 2 -*^- track c.b.2 -*^- artist c.b.2.1; artist c.b.2.2 -*^- FLAC -*^- 756"),
|
||||||
|
String::from("album_artist d -*^- -*^- 1995 -*^- album_title d.a -*^- 1 -*^- track d.a.1 -*^- artist d.a.1 -*^- MP3 -*^- 120"),
|
||||||
|
String::from("album_artist d -*^- -*^- 1995 -*^- album_title d.a -*^- 2 -*^- track d.a.2 -*^- artist d.a.2.1; artist d.a.2.2 -*^- MP3 -*^- 120"),
|
||||||
|
String::from("album_artist d -*^- -*^- 2028 -*^- album_title d.b -*^- 1 -*^- track d.b.1 -*^- artist d.b.1 -*^- FLAC -*^- 841"),
|
||||||
|
String::from("album_artist d -*^- -*^- 2028 -*^- album_title d.b -*^- 2 -*^- track d.b.2 -*^- artist d.b.2.1; artist d.b.2.2 -*^- FLAC -*^- 756")
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -40,6 +40,17 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
|
|||||||
track_format: Format::Flac,
|
track_format: Format::Flac,
|
||||||
track_bitrate: 1061,
|
track_bitrate: 1061,
|
||||||
},
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist a"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 1998,
|
||||||
|
album_title: String::from("album_title a.a"),
|
||||||
|
track_number: 4,
|
||||||
|
track_title: String::from("track a.a.4"),
|
||||||
|
track_artist: vec![String::from("artist a.a.4")],
|
||||||
|
track_format: Format::Flac,
|
||||||
|
track_bitrate: 1042,
|
||||||
|
},
|
||||||
Item {
|
Item {
|
||||||
album_artist: String::from("album_artist a"),
|
album_artist: String::from("album_artist a"),
|
||||||
album_artist_sort: None,
|
album_artist_sort: None,
|
||||||
@ -112,6 +123,56 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
|
|||||||
track_format: Format::Mp3,
|
track_format: Format::Mp3,
|
||||||
track_bitrate: 320,
|
track_bitrate: 320,
|
||||||
},
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist b"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 2009,
|
||||||
|
album_title: String::from("album_title b.c"),
|
||||||
|
track_number: 1,
|
||||||
|
track_title: String::from("track b.c.1"),
|
||||||
|
track_artist: vec![String::from("artist b.c.1")],
|
||||||
|
track_format: Format::Mp3,
|
||||||
|
track_bitrate: 190,
|
||||||
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist b"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 2009,
|
||||||
|
album_title: String::from("album_title b.c"),
|
||||||
|
track_number: 2,
|
||||||
|
track_title: String::from("track b.c.2"),
|
||||||
|
track_artist: vec![
|
||||||
|
String::from("artist b.c.2.1"),
|
||||||
|
String::from("artist b.c.2.2"),
|
||||||
|
],
|
||||||
|
track_format: Format::Mp3,
|
||||||
|
track_bitrate: 120,
|
||||||
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist b"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 2015,
|
||||||
|
album_title: String::from("album_title b.d"),
|
||||||
|
track_number: 1,
|
||||||
|
track_title: String::from("track b.d.1"),
|
||||||
|
track_artist: vec![String::from("artist b.d.1")],
|
||||||
|
track_format: Format::Mp3,
|
||||||
|
track_bitrate: 190,
|
||||||
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist b"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 2015,
|
||||||
|
album_title: String::from("album_title b.d"),
|
||||||
|
track_number: 2,
|
||||||
|
track_title: String::from("track b.d.2"),
|
||||||
|
track_artist: vec![
|
||||||
|
String::from("artist b.d.2.1"),
|
||||||
|
String::from("artist b.d.2.2"),
|
||||||
|
],
|
||||||
|
track_format: Format::Mp3,
|
||||||
|
track_bitrate: 120,
|
||||||
|
},
|
||||||
Item {
|
Item {
|
||||||
album_artist: String::from("album_artist c"),
|
album_artist: String::from("album_artist c"),
|
||||||
album_artist_sort: None,
|
album_artist_sort: None,
|
||||||
@ -162,5 +223,55 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
|
|||||||
track_format: Format::Flac,
|
track_format: Format::Flac,
|
||||||
track_bitrate: 756,
|
track_bitrate: 756,
|
||||||
},
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist d"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 1995,
|
||||||
|
album_title: String::from("album_title d.a"),
|
||||||
|
track_number: 1,
|
||||||
|
track_title: String::from("track d.a.1"),
|
||||||
|
track_artist: vec![String::from("artist d.a.1")],
|
||||||
|
track_format: Format::Mp3,
|
||||||
|
track_bitrate: 120,
|
||||||
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist d"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 1995,
|
||||||
|
album_title: String::from("album_title d.a"),
|
||||||
|
track_number: 2,
|
||||||
|
track_title: String::from("track d.a.2"),
|
||||||
|
track_artist: vec![
|
||||||
|
String::from("artist d.a.2.1"),
|
||||||
|
String::from("artist d.a.2.2"),
|
||||||
|
],
|
||||||
|
track_format: Format::Mp3,
|
||||||
|
track_bitrate: 120,
|
||||||
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist d"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 2028,
|
||||||
|
album_title: String::from("album_title d.b"),
|
||||||
|
track_number: 1,
|
||||||
|
track_title: String::from("track d.b.1"),
|
||||||
|
track_artist: vec![String::from("artist d.b.1")],
|
||||||
|
track_format: Format::Flac,
|
||||||
|
track_bitrate: 841,
|
||||||
|
},
|
||||||
|
Item {
|
||||||
|
album_artist: String::from("album_artist d"),
|
||||||
|
album_artist_sort: None,
|
||||||
|
album_year: 2028,
|
||||||
|
album_title: String::from("album_title d.b"),
|
||||||
|
track_number: 2,
|
||||||
|
track_title: String::from("track d.b.2"),
|
||||||
|
track_artist: vec![
|
||||||
|
String::from("artist d.b.2.1"),
|
||||||
|
String::from("artist d.b.2.2"),
|
||||||
|
],
|
||||||
|
track_format: Format::Flac,
|
||||||
|
track_bitrate: 756,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
159
src/tests.rs
159
src/tests.rs
@ -55,6 +55,17 @@ macro_rules! library_collection {
|
|||||||
bitrate: 1061,
|
bitrate: 1061,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 4,
|
||||||
|
title: "track a.a.4".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec!["artist a.a.4".to_string()],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Flac,
|
||||||
|
bitrate: 1042,
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
Album {
|
Album {
|
||||||
@ -167,6 +178,72 @@ macro_rules! library_collection {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Album {
|
||||||
|
id: AlbumId {
|
||||||
|
year: 2009,
|
||||||
|
title: "album_title b.c".to_string(),
|
||||||
|
},
|
||||||
|
tracks: vec![
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 1,
|
||||||
|
title: "track b.c.1".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec!["artist b.c.1".to_string()],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Mp3,
|
||||||
|
bitrate: 190,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 2,
|
||||||
|
title: "track b.c.2".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec![
|
||||||
|
"artist b.c.2.1".to_string(),
|
||||||
|
"artist b.c.2.2".to_string(),
|
||||||
|
],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Mp3,
|
||||||
|
bitrate: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Album {
|
||||||
|
id: AlbumId {
|
||||||
|
year: 2015,
|
||||||
|
title: "album_title b.d".to_string(),
|
||||||
|
},
|
||||||
|
tracks: vec![
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 1,
|
||||||
|
title: "track b.d.1".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec!["artist b.d.1".to_string()],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Mp3,
|
||||||
|
bitrate: 190,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 2,
|
||||||
|
title: "track b.d.2".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec![
|
||||||
|
"artist b.d.2.1".to_string(),
|
||||||
|
"artist b.d.2.2".to_string(),
|
||||||
|
],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Mp3,
|
||||||
|
bitrate: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
Artist {
|
Artist {
|
||||||
@ -249,6 +326,86 @@ macro_rules! library_collection {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Artist {
|
||||||
|
id: ArtistId {
|
||||||
|
name: "album_artist d".to_string(),
|
||||||
|
},
|
||||||
|
sort: None,
|
||||||
|
properties: ArtistProperties {
|
||||||
|
musicbrainz: None,
|
||||||
|
musicbutler: vec![],
|
||||||
|
bandcamp: vec![],
|
||||||
|
qobuz: None,
|
||||||
|
},
|
||||||
|
albums: vec![
|
||||||
|
Album {
|
||||||
|
id: AlbumId {
|
||||||
|
year: 1995,
|
||||||
|
title: "album_title d.a".to_string(),
|
||||||
|
},
|
||||||
|
tracks: vec![
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 1,
|
||||||
|
title: "track d.a.1".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec!["artist d.a.1".to_string()],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Mp3,
|
||||||
|
bitrate: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 2,
|
||||||
|
title: "track d.a.2".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec![
|
||||||
|
"artist d.a.2.1".to_string(),
|
||||||
|
"artist d.a.2.2".to_string(),
|
||||||
|
],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Mp3,
|
||||||
|
bitrate: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Album {
|
||||||
|
id: AlbumId {
|
||||||
|
year: 2028,
|
||||||
|
title: "album_title d.b".to_string(),
|
||||||
|
},
|
||||||
|
tracks: vec![
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 1,
|
||||||
|
title: "track d.b.1".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec!["artist d.b.1".to_string()],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Flac,
|
||||||
|
bitrate: 841,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Track {
|
||||||
|
id: TrackId {
|
||||||
|
number: 2,
|
||||||
|
title: "track d.b.2".to_string(),
|
||||||
|
},
|
||||||
|
artist: vec![
|
||||||
|
"artist d.b.2.1".to_string(),
|
||||||
|
"artist d.b.2.2".to_string(),
|
||||||
|
],
|
||||||
|
quality: Quality {
|
||||||
|
format: Format::Flac,
|
||||||
|
bitrate: 756,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -318,6 +475,8 @@ macro_rules! full_collection {
|
|||||||
qobuz: None,
|
qobuz: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Nothing for artist_d
|
||||||
|
|
||||||
collection
|
collection
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use musichoard::collection::Collection;
|
use musichoard::collection::Collection;
|
||||||
|
|
||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
app::selection::{ActiveSelection, Selection},
|
app::selection::{ActiveSelection, Delta, Selection},
|
||||||
lib::IMusicHoard,
|
lib::IMusicHoard,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,8 +50,8 @@ pub trait IAppInteract {
|
|||||||
pub trait IAppInteractBrowse {
|
pub trait IAppInteractBrowse {
|
||||||
fn increment_category(&mut self);
|
fn increment_category(&mut self);
|
||||||
fn decrement_category(&mut self);
|
fn decrement_category(&mut self);
|
||||||
fn increment_selection(&mut self);
|
fn increment_selection(&mut self, delta: Delta);
|
||||||
fn decrement_selection(&mut self);
|
fn decrement_selection(&mut self, delta: Delta);
|
||||||
|
|
||||||
fn show_info_overlay(&mut self);
|
fn show_info_overlay(&mut self);
|
||||||
|
|
||||||
@ -160,14 +160,14 @@ impl<MH: IMusicHoard> IAppInteractBrowse for App<MH> {
|
|||||||
self.selection.decrement_category();
|
self.selection.decrement_category();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment_selection(&mut self) {
|
fn increment_selection(&mut self, delta: Delta) {
|
||||||
self.selection
|
self.selection
|
||||||
.increment_selection(self.music_hoard.get_collection());
|
.increment_selection(self.music_hoard.get_collection(), delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement_selection(&mut self) {
|
fn decrement_selection(&mut self, delta: Delta) {
|
||||||
self.selection
|
self.selection
|
||||||
.decrement_selection(self.music_hoard.get_collection());
|
.decrement_selection(self.music_hoard.get_collection(), delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_info_overlay(&mut self) {
|
fn show_info_overlay(&mut self) {
|
||||||
@ -362,87 +362,126 @@ mod tests {
|
|||||||
assert!(app.is_running());
|
assert!(app.is_running());
|
||||||
|
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
assert_eq!(app.selection.active, Category::Album);
|
assert_eq!(app.selection.active, Category::Album);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Album);
|
assert_eq!(app.selection.active, Category::Album);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(1));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(1)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(1));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(1)
|
||||||
|
);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
app.decrement_category();
|
app.decrement_category();
|
||||||
assert_eq!(app.selection.active, Category::Album);
|
assert_eq!(app.selection.active, Category::Album);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(1));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(1)
|
||||||
|
);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Album);
|
assert_eq!(app.selection.active, Category::Album);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
app.decrement_category();
|
app.decrement_category();
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
app.decrement_category();
|
app.decrement_category();
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
app.decrement_category();
|
app.decrement_category();
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(1));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(1));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), Some(0));
|
assert_eq!(
|
||||||
|
app.selection.artist.album.track.state.list.selected(),
|
||||||
|
Some(0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -454,24 +493,24 @@ mod tests {
|
|||||||
assert!(app.is_running());
|
assert!(app.is_running());
|
||||||
|
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.album.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -483,37 +522,37 @@ mod tests {
|
|||||||
assert!(app.is_running());
|
assert!(app.is_running());
|
||||||
|
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Album);
|
assert_eq!(app.selection.active, Category::Album);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Album);
|
assert_eq!(app.selection.active, Category::Album);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), Some(0));
|
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -522,49 +561,49 @@ mod tests {
|
|||||||
assert!(app.is_running());
|
assert!(app.is_running());
|
||||||
|
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), None);
|
assert_eq!(app.selection.artist.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), None);
|
assert_eq!(app.selection.artist.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Artist);
|
assert_eq!(app.selection.active, Category::Artist);
|
||||||
assert_eq!(app.selection.artist.state.selected(), None);
|
assert_eq!(app.selection.artist.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Album);
|
assert_eq!(app.selection.active, Category::Album);
|
||||||
assert_eq!(app.selection.artist.state.selected(), None);
|
assert_eq!(app.selection.artist.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Album);
|
assert_eq!(app.selection.active, Category::Album);
|
||||||
assert_eq!(app.selection.artist.state.selected(), None);
|
assert_eq!(app.selection.artist.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.increment_category();
|
app.increment_category();
|
||||||
|
|
||||||
app.increment_selection();
|
app.increment_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), None);
|
assert_eq!(app.selection.artist.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
|
|
||||||
app.decrement_selection();
|
app.decrement_selection(Delta::Line);
|
||||||
assert_eq!(app.selection.active, Category::Track);
|
assert_eq!(app.selection.active, Category::Track);
|
||||||
assert_eq!(app.selection.artist.state.selected(), None);
|
assert_eq!(app.selection.artist.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.state.selected(), None);
|
assert_eq!(app.selection.artist.album.state.list.selected(), None);
|
||||||
assert_eq!(app.selection.artist.album.track.state.selected(), None);
|
assert_eq!(app.selection.artist.album.track.state.list.selected(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -13,43 +13,51 @@ pub enum Category {
|
|||||||
Track,
|
Track,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct WidgetState {
|
||||||
|
pub list: ListState,
|
||||||
|
pub height: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for WidgetState {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.list.selected().eq(&other.list.selected()) && self.height.eq(&other.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Selection {
|
pub struct Selection {
|
||||||
pub active: Category,
|
pub active: Category,
|
||||||
pub artist: ArtistSelection,
|
pub artist: ArtistSelection,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct ArtistSelection {
|
pub struct ArtistSelection {
|
||||||
pub state: ListState,
|
pub state: WidgetState,
|
||||||
pub album: AlbumSelection,
|
pub album: AlbumSelection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for ArtistSelection {
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.state.selected().eq(&other.state.selected()) && self.album.eq(&other.album)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct AlbumSelection {
|
pub struct AlbumSelection {
|
||||||
pub state: ListState,
|
pub state: WidgetState,
|
||||||
pub track: TrackSelection,
|
pub track: TrackSelection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for AlbumSelection {
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.state.selected().eq(&other.state.selected()) && self.track.eq(&other.track)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct TrackSelection {
|
pub struct TrackSelection {
|
||||||
pub state: ListState,
|
pub state: WidgetState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for TrackSelection {
|
pub enum Delta {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
Line,
|
||||||
self.state.selected().eq(&other.state.selected())
|
Page,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Delta {
|
||||||
|
fn as_usize(&self, state: &WidgetState) -> usize {
|
||||||
|
match self {
|
||||||
|
Delta::Line => 1,
|
||||||
|
Delta::Page => state.height.saturating_sub(1),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,51 +89,51 @@ impl Selection {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn increment_selection(&mut self, collection: &Collection) {
|
pub fn increment_selection(&mut self, collection: &Collection, delta: Delta) {
|
||||||
match self.active {
|
match self.active {
|
||||||
Category::Artist => self.increment_artist(collection),
|
Category::Artist => self.increment_artist(collection, delta),
|
||||||
Category::Album => self.increment_album(collection),
|
Category::Album => self.increment_album(collection, delta),
|
||||||
Category::Track => self.increment_track(collection),
|
Category::Track => self.increment_track(collection, delta),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decrement_selection(&mut self, collection: &Collection) {
|
pub fn decrement_selection(&mut self, collection: &Collection, delta: Delta) {
|
||||||
match self.active {
|
match self.active {
|
||||||
Category::Artist => self.decrement_artist(collection),
|
Category::Artist => self.decrement_artist(collection, delta),
|
||||||
Category::Album => self.decrement_album(collection),
|
Category::Album => self.decrement_album(collection, delta),
|
||||||
Category::Track => self.decrement_track(collection),
|
Category::Track => self.decrement_track(collection, delta),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment_artist(&mut self, artists: &[Artist]) {
|
fn increment_artist(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
self.artist.increment(artists);
|
self.artist.increment(artists, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement_artist(&mut self, artists: &[Artist]) {
|
fn decrement_artist(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
self.artist.decrement(artists);
|
self.artist.decrement(artists, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment_album(&mut self, artists: &[Artist]) {
|
fn increment_album(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
self.artist.increment_album(artists);
|
self.artist.increment_album(artists, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement_album(&mut self, artists: &[Artist]) {
|
fn decrement_album(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
self.artist.decrement_album(artists);
|
self.artist.decrement_album(artists, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment_track(&mut self, artists: &[Artist]) {
|
fn increment_track(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
self.artist.increment_track(artists);
|
self.artist.increment_track(artists, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement_track(&mut self, artists: &[Artist]) {
|
fn decrement_track(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
self.artist.decrement_track(artists);
|
self.artist.decrement_track(artists, delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArtistSelection {
|
impl ArtistSelection {
|
||||||
fn initialise(artists: &[Artist]) -> Self {
|
fn initialise(artists: &[Artist]) -> Self {
|
||||||
let mut selection = ArtistSelection {
|
let mut selection = ArtistSelection {
|
||||||
state: ListState::default(),
|
state: WidgetState::default(),
|
||||||
album: AlbumSelection::initialise(&[]),
|
album: AlbumSelection::initialise(&[]),
|
||||||
};
|
};
|
||||||
selection.reinitialise(artists, None);
|
selection.reinitialise(artists, None);
|
||||||
@ -151,60 +159,71 @@ impl ArtistSelection {
|
|||||||
active_album: Option<ActiveAlbum>,
|
active_album: Option<ActiveAlbum>,
|
||||||
) {
|
) {
|
||||||
if artists.is_empty() {
|
if artists.is_empty() {
|
||||||
self.state.select(None);
|
self.state.list.select(None);
|
||||||
self.album = AlbumSelection::initialise(&[]);
|
self.album = AlbumSelection::initialise(&[]);
|
||||||
} else if index >= artists.len() {
|
} else if index >= artists.len() {
|
||||||
let end = artists.len() - 1;
|
let end = artists.len() - 1;
|
||||||
self.state.select(Some(end));
|
self.state.list.select(Some(end));
|
||||||
self.album = AlbumSelection::initialise(&artists[end].albums);
|
self.album = AlbumSelection::initialise(&artists[end].albums);
|
||||||
} else {
|
} else {
|
||||||
self.state.select(Some(index));
|
self.state.list.select(Some(index));
|
||||||
self.album
|
self.album
|
||||||
.reinitialise(&artists[index].albums, active_album);
|
.reinitialise(&artists[index].albums, active_album);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment(&mut self, artists: &[Artist]) {
|
fn increment_by(&mut self, artists: &[Artist], by: usize) {
|
||||||
if let Some(index) = self.state.selected() {
|
if let Some(index) = self.state.list.selected() {
|
||||||
if let Some(result) = index.checked_add(1) {
|
let mut result = index.saturating_add(by);
|
||||||
if result < artists.len() {
|
if result >= artists.len() {
|
||||||
self.state.select(Some(result));
|
result = artists.len() - 1;
|
||||||
self.album = AlbumSelection::initialise(&artists[result].albums);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if self.state.list.selected() != Some(result) {
|
||||||
}
|
self.state.list.select(Some(result));
|
||||||
|
|
||||||
fn increment_album(&mut self, artists: &[Artist]) {
|
|
||||||
if let Some(index) = self.state.selected() {
|
|
||||||
self.album.increment(&artists[index].albums);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn increment_track(&mut self, artists: &[Artist]) {
|
|
||||||
if let Some(index) = self.state.selected() {
|
|
||||||
self.album.increment_track(&artists[index].albums);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decrement(&mut self, artists: &[Artist]) {
|
|
||||||
if let Some(index) = self.state.selected() {
|
|
||||||
if let Some(result) = index.checked_sub(1) {
|
|
||||||
self.state.select(Some(result));
|
|
||||||
self.album = AlbumSelection::initialise(&artists[result].albums);
|
self.album = AlbumSelection::initialise(&artists[result].albums);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement_album(&mut self, artists: &[Artist]) {
|
fn increment(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
if let Some(index) = self.state.selected() {
|
self.increment_by(artists, delta.as_usize(&self.state));
|
||||||
self.album.decrement(&artists[index].albums);
|
}
|
||||||
|
|
||||||
|
fn increment_album(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
|
if let Some(index) = self.state.list.selected() {
|
||||||
|
self.album.increment(&artists[index].albums, delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement_track(&mut self, artists: &[Artist]) {
|
fn increment_track(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
if let Some(index) = self.state.selected() {
|
if let Some(index) = self.state.list.selected() {
|
||||||
self.album.decrement_track(&artists[index].albums);
|
self.album.increment_track(&artists[index].albums, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrement_by(&mut self, artists: &[Artist], by: usize) {
|
||||||
|
if let Some(index) = self.state.list.selected() {
|
||||||
|
let result = index.saturating_sub(by);
|
||||||
|
if self.state.list.selected() != Some(result) {
|
||||||
|
self.state.list.select(Some(result));
|
||||||
|
self.album = AlbumSelection::initialise(&artists[result].albums);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrement(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
|
self.decrement_by(artists, delta.as_usize(&self.state));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrement_album(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
|
if let Some(index) = self.state.list.selected() {
|
||||||
|
self.album.decrement(&artists[index].albums, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrement_track(&mut self, artists: &[Artist], delta: Delta) {
|
||||||
|
if let Some(index) = self.state.list.selected() {
|
||||||
|
self.album.decrement_track(&artists[index].albums, delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,7 +231,7 @@ impl ArtistSelection {
|
|||||||
impl AlbumSelection {
|
impl AlbumSelection {
|
||||||
fn initialise(albums: &[Album]) -> Self {
|
fn initialise(albums: &[Album]) -> Self {
|
||||||
let mut selection = AlbumSelection {
|
let mut selection = AlbumSelection {
|
||||||
state: ListState::default(),
|
state: WidgetState::default(),
|
||||||
track: TrackSelection::initialise(&[]),
|
track: TrackSelection::initialise(&[]),
|
||||||
};
|
};
|
||||||
selection.reinitialise(albums, None);
|
selection.reinitialise(albums, None);
|
||||||
@ -238,47 +257,58 @@ impl AlbumSelection {
|
|||||||
active_track: Option<ActiveTrack>,
|
active_track: Option<ActiveTrack>,
|
||||||
) {
|
) {
|
||||||
if albums.is_empty() {
|
if albums.is_empty() {
|
||||||
self.state.select(None);
|
self.state.list.select(None);
|
||||||
self.track = TrackSelection::initialise(&[]);
|
self.track = TrackSelection::initialise(&[]);
|
||||||
} else if index >= albums.len() {
|
} else if index >= albums.len() {
|
||||||
let end = albums.len() - 1;
|
let end = albums.len() - 1;
|
||||||
self.state.select(Some(end));
|
self.state.list.select(Some(end));
|
||||||
self.track = TrackSelection::initialise(&albums[end].tracks);
|
self.track = TrackSelection::initialise(&albums[end].tracks);
|
||||||
} else {
|
} else {
|
||||||
self.state.select(Some(index));
|
self.state.list.select(Some(index));
|
||||||
self.track.reinitialise(&albums[index].tracks, active_track);
|
self.track.reinitialise(&albums[index].tracks, active_track);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment(&mut self, albums: &[Album]) {
|
fn increment_by(&mut self, albums: &[Album], by: usize) {
|
||||||
if let Some(index) = self.state.selected() {
|
if let Some(index) = self.state.list.selected() {
|
||||||
if let Some(result) = index.checked_add(1) {
|
let mut result = index.saturating_add(by);
|
||||||
if result < albums.len() {
|
if result >= albums.len() {
|
||||||
self.state.select(Some(result));
|
result = albums.len() - 1;
|
||||||
self.track = TrackSelection::initialise(&albums[result].tracks);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if self.state.list.selected() != Some(result) {
|
||||||
}
|
self.state.list.select(Some(result));
|
||||||
|
|
||||||
fn increment_track(&mut self, albums: &[Album]) {
|
|
||||||
if let Some(index) = self.state.selected() {
|
|
||||||
self.track.increment(&albums[index].tracks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decrement(&mut self, albums: &[Album]) {
|
|
||||||
if let Some(index) = self.state.selected() {
|
|
||||||
if let Some(result) = index.checked_sub(1) {
|
|
||||||
self.state.select(Some(result));
|
|
||||||
self.track = TrackSelection::initialise(&albums[result].tracks);
|
self.track = TrackSelection::initialise(&albums[result].tracks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement_track(&mut self, albums: &[Album]) {
|
fn increment(&mut self, albums: &[Album], delta: Delta) {
|
||||||
if let Some(index) = self.state.selected() {
|
self.increment_by(albums, delta.as_usize(&self.state));
|
||||||
self.track.decrement(&albums[index].tracks);
|
}
|
||||||
|
|
||||||
|
fn increment_track(&mut self, albums: &[Album], delta: Delta) {
|
||||||
|
if let Some(index) = self.state.list.selected() {
|
||||||
|
self.track.increment(&albums[index].tracks, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrement_by(&mut self, albums: &[Album], by: usize) {
|
||||||
|
if let Some(index) = self.state.list.selected() {
|
||||||
|
let result = index.saturating_sub(by);
|
||||||
|
if self.state.list.selected() != Some(result) {
|
||||||
|
self.state.list.select(Some(result));
|
||||||
|
self.track = TrackSelection::initialise(&albums[result].tracks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrement(&mut self, albums: &[Album], delta: Delta) {
|
||||||
|
self.decrement_by(albums, delta.as_usize(&self.state));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrement_track(&mut self, albums: &[Album], delta: Delta) {
|
||||||
|
if let Some(index) = self.state.list.selected() {
|
||||||
|
self.track.decrement(&albums[index].tracks, delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,7 +316,7 @@ impl AlbumSelection {
|
|||||||
impl TrackSelection {
|
impl TrackSelection {
|
||||||
fn initialise(tracks: &[Track]) -> Self {
|
fn initialise(tracks: &[Track]) -> Self {
|
||||||
let mut selection = TrackSelection {
|
let mut selection = TrackSelection {
|
||||||
state: ListState::default(),
|
state: WidgetState::default(),
|
||||||
};
|
};
|
||||||
selection.reinitialise(tracks, None);
|
selection.reinitialise(tracks, None);
|
||||||
selection
|
selection
|
||||||
@ -305,31 +335,42 @@ impl TrackSelection {
|
|||||||
|
|
||||||
fn reinitialise_with_index(&mut self, tracks: &[Track], index: usize) {
|
fn reinitialise_with_index(&mut self, tracks: &[Track], index: usize) {
|
||||||
if tracks.is_empty() {
|
if tracks.is_empty() {
|
||||||
self.state.select(None);
|
self.state.list.select(None);
|
||||||
} else if index >= tracks.len() {
|
} else if index >= tracks.len() {
|
||||||
self.state.select(Some(tracks.len() - 1));
|
self.state.list.select(Some(tracks.len() - 1));
|
||||||
} else {
|
} else {
|
||||||
self.state.select(Some(index));
|
self.state.list.select(Some(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment(&mut self, tracks: &[Track]) {
|
fn increment_by(&mut self, tracks: &[Track], by: usize) {
|
||||||
if let Some(index) = self.state.selected() {
|
if let Some(index) = self.state.list.selected() {
|
||||||
if let Some(result) = index.checked_add(1) {
|
let mut result = index.saturating_add(by);
|
||||||
if result < tracks.len() {
|
if result >= tracks.len() {
|
||||||
self.state.select(Some(result));
|
result = tracks.len() - 1;
|
||||||
}
|
}
|
||||||
|
if self.state.list.selected() != Some(result) {
|
||||||
|
self.state.list.select(Some(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement(&mut self, _tracks: &[Track]) {
|
fn increment(&mut self, tracks: &[Track], delta: Delta) {
|
||||||
if let Some(index) = self.state.selected() {
|
self.increment_by(tracks, delta.as_usize(&self.state));
|
||||||
if let Some(result) = index.checked_sub(1) {
|
}
|
||||||
self.state.select(Some(result));
|
|
||||||
|
fn decrement_by(&mut self, _tracks: &[Track], by: usize) {
|
||||||
|
if let Some(index) = self.state.list.selected() {
|
||||||
|
let result = index.saturating_sub(by);
|
||||||
|
if self.state.list.selected() != Some(result) {
|
||||||
|
self.state.list.select(Some(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn decrement(&mut self, tracks: &[Track], delta: Delta) {
|
||||||
|
self.decrement_by(tracks, delta.as_usize(&self.state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ActiveSelection {
|
pub struct ActiveSelection {
|
||||||
@ -360,7 +401,7 @@ impl ActiveSelection {
|
|||||||
|
|
||||||
impl ActiveArtist {
|
impl ActiveArtist {
|
||||||
fn get(artists: &[Artist], selection: &ArtistSelection) -> Option<Self> {
|
fn get(artists: &[Artist], selection: &ArtistSelection) -> Option<Self> {
|
||||||
selection.state.selected().map(|index| {
|
selection.state.list.selected().map(|index| {
|
||||||
let artist = &artists[index];
|
let artist = &artists[index];
|
||||||
ActiveArtist {
|
ActiveArtist {
|
||||||
artist_id: artist.get_sort_key().clone(),
|
artist_id: artist.get_sort_key().clone(),
|
||||||
@ -372,7 +413,7 @@ impl ActiveArtist {
|
|||||||
|
|
||||||
impl ActiveAlbum {
|
impl ActiveAlbum {
|
||||||
fn get(albums: &[Album], selection: &AlbumSelection) -> Option<Self> {
|
fn get(albums: &[Album], selection: &AlbumSelection) -> Option<Self> {
|
||||||
selection.state.selected().map(|index| {
|
selection.state.list.selected().map(|index| {
|
||||||
let album = &albums[index];
|
let album = &albums[index];
|
||||||
ActiveAlbum {
|
ActiveAlbum {
|
||||||
album_id: album.get_sort_key().clone(),
|
album_id: album.get_sort_key().clone(),
|
||||||
@ -384,7 +425,7 @@ impl ActiveAlbum {
|
|||||||
|
|
||||||
impl ActiveTrack {
|
impl ActiveTrack {
|
||||||
fn get(tracks: &[Track], selection: &TrackSelection) -> Option<Self> {
|
fn get(tracks: &[Track], selection: &TrackSelection) -> Option<Self> {
|
||||||
selection.state.selected().map(|index| {
|
selection.state.list.selected().map(|index| {
|
||||||
let track = &tracks[index];
|
let track = &tracks[index];
|
||||||
ActiveTrack {
|
ActiveTrack {
|
||||||
track_id: track.get_sort_key().clone(),
|
track_id: track.get_sort_key().clone(),
|
||||||
@ -405,24 +446,62 @@ mod tests {
|
|||||||
assert!(tracks.len() > 1);
|
assert!(tracks.len() > 1);
|
||||||
|
|
||||||
let empty = TrackSelection::initialise(&[]);
|
let empty = TrackSelection::initialise(&[]);
|
||||||
assert_eq!(empty.state.selected(), None);
|
assert_eq!(empty.state.list.selected(), None);
|
||||||
|
|
||||||
let mut sel = TrackSelection::initialise(tracks);
|
let mut sel = TrackSelection::initialise(tracks);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
|
||||||
sel.decrement(tracks);
|
sel.decrement(tracks, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
|
||||||
sel.increment(tracks);
|
sel.increment(tracks, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(1));
|
assert_eq!(sel.state.list.selected(), Some(1));
|
||||||
|
|
||||||
sel.decrement(tracks);
|
sel.decrement(tracks, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
|
||||||
for _ in 0..(tracks.len() + 5) {
|
for _ in 0..(tracks.len() + 5) {
|
||||||
sel.increment(tracks);
|
sel.increment(tracks, Delta::Line);
|
||||||
}
|
}
|
||||||
assert_eq!(sel.state.selected(), Some(tracks.len() - 1));
|
assert_eq!(sel.state.list.selected(), Some(tracks.len() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn track_delta_page() {
|
||||||
|
let tracks = &COLLECTION[0].albums[0].tracks;
|
||||||
|
assert!(tracks.len() > 1);
|
||||||
|
|
||||||
|
let empty = TrackSelection::initialise(&[]);
|
||||||
|
assert_eq!(empty.state.list.selected(), None);
|
||||||
|
|
||||||
|
let mut sel = TrackSelection::initialise(tracks);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
assert!(tracks.len() >= 4);
|
||||||
|
sel.state.height = 3;
|
||||||
|
|
||||||
|
sel.decrement(tracks, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
sel.increment(tracks, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(2));
|
||||||
|
|
||||||
|
sel.decrement(tracks, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
for _ in 0..(tracks.len() + 5) {
|
||||||
|
sel.increment(tracks, Delta::Page);
|
||||||
|
}
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(tracks.len() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn track_reinitialise() {
|
||||||
|
let tracks = &COLLECTION[0].albums[0].tracks;
|
||||||
|
assert!(tracks.len() > 1);
|
||||||
|
|
||||||
|
let mut sel = TrackSelection::initialise(tracks);
|
||||||
|
sel.state.list.select(Some(tracks.len() - 1));
|
||||||
|
|
||||||
// Re-initialise.
|
// Re-initialise.
|
||||||
let expected = sel.clone();
|
let expected = sel.clone();
|
||||||
@ -432,7 +511,7 @@ mod tests {
|
|||||||
|
|
||||||
// Re-initialise out-of-bounds.
|
// Re-initialise out-of-bounds.
|
||||||
let mut expected = sel.clone();
|
let mut expected = sel.clone();
|
||||||
expected.decrement(tracks);
|
expected.decrement(tracks, Delta::Line);
|
||||||
let active_track = ActiveTrack::get(tracks, &sel);
|
let active_track = ActiveTrack::get(tracks, &sel);
|
||||||
sel.reinitialise(&tracks[..(tracks.len() - 1)], active_track);
|
sel.reinitialise(&tracks[..(tracks.len() - 1)], active_track);
|
||||||
assert_eq!(sel, expected);
|
assert_eq!(sel, expected);
|
||||||
@ -442,13 +521,6 @@ mod tests {
|
|||||||
let active_track = ActiveTrack::get(tracks, &sel);
|
let active_track = ActiveTrack::get(tracks, &sel);
|
||||||
sel.reinitialise(&[], active_track);
|
sel.reinitialise(&[], active_track);
|
||||||
assert_eq!(sel, expected);
|
assert_eq!(sel, expected);
|
||||||
|
|
||||||
// Artifical test case to verify upper limit.
|
|
||||||
sel.state.select(Some(std::usize::MAX));
|
|
||||||
assert_eq!(sel.state.selected(), Some(std::usize::MAX));
|
|
||||||
|
|
||||||
sel.increment(&[]);
|
|
||||||
assert_eq!(sel.state.selected(), Some(std::usize::MAX));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -457,43 +529,101 @@ mod tests {
|
|||||||
assert!(albums.len() > 1);
|
assert!(albums.len() > 1);
|
||||||
|
|
||||||
let empty = AlbumSelection::initialise(&[]);
|
let empty = AlbumSelection::initialise(&[]);
|
||||||
assert_eq!(empty.state.selected(), None);
|
assert_eq!(empty.state.list.selected(), None);
|
||||||
|
|
||||||
let mut sel = AlbumSelection::initialise(albums);
|
let mut sel = AlbumSelection::initialise(albums);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
assert_eq!(sel.track.state.selected(), Some(0));
|
assert_eq!(sel.track.state.list.selected(), Some(0));
|
||||||
|
|
||||||
sel.increment_track(albums);
|
sel.increment_track(albums, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
assert_eq!(sel.track.state.selected(), Some(1));
|
assert_eq!(sel.track.state.list.selected(), Some(1));
|
||||||
|
|
||||||
// Verify that decrement that doesn't change index does not reset track.
|
// Verify that decrement that doesn't change index does not reset track.
|
||||||
sel.decrement(albums);
|
sel.decrement(albums, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
assert_eq!(sel.track.state.selected(), Some(1));
|
assert_eq!(sel.track.state.list.selected(), Some(1));
|
||||||
|
|
||||||
sel.increment(albums);
|
sel.increment(albums, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(1));
|
assert_eq!(sel.state.list.selected(), Some(1));
|
||||||
assert_eq!(sel.track.state.selected(), Some(0));
|
assert_eq!(sel.track.state.list.selected(), Some(0));
|
||||||
|
|
||||||
sel.decrement(albums);
|
sel.decrement(albums, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
assert_eq!(sel.track.state.selected(), Some(0));
|
assert_eq!(sel.track.state.list.selected(), Some(0));
|
||||||
|
|
||||||
for _ in 0..(albums.len() + 5) {
|
for _ in 0..(albums.len() + 5) {
|
||||||
sel.increment(albums);
|
sel.increment(albums, Delta::Line);
|
||||||
}
|
}
|
||||||
assert_eq!(sel.state.selected(), Some(albums.len() - 1));
|
assert_eq!(sel.state.list.selected(), Some(albums.len() - 1));
|
||||||
assert_eq!(sel.track.state.selected(), Some(0));
|
assert_eq!(sel.track.state.list.selected(), Some(0));
|
||||||
|
|
||||||
sel.increment_track(albums);
|
sel.increment_track(albums, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(albums.len() - 1));
|
assert_eq!(sel.state.list.selected(), Some(albums.len() - 1));
|
||||||
assert_eq!(sel.track.state.selected(), Some(1));
|
assert_eq!(sel.track.state.list.selected(), Some(1));
|
||||||
|
|
||||||
// Verify that increment that doesn't change index does not reset track.
|
// Verify that increment that doesn't change index does not reset track.
|
||||||
sel.increment(albums);
|
sel.increment(albums, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(albums.len() - 1));
|
assert_eq!(sel.state.list.selected(), Some(albums.len() - 1));
|
||||||
assert_eq!(sel.track.state.selected(), Some(1));
|
assert_eq!(sel.track.state.list.selected(), Some(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn album_delta_page() {
|
||||||
|
let albums = &COLLECTION[1].albums;
|
||||||
|
assert!(albums.len() > 1);
|
||||||
|
|
||||||
|
let empty = AlbumSelection::initialise(&[]);
|
||||||
|
assert_eq!(empty.state.list.selected(), None);
|
||||||
|
|
||||||
|
let mut sel = AlbumSelection::initialise(albums);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
assert_eq!(sel.track.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
assert!(albums.len() >= 4);
|
||||||
|
sel.state.height = 3;
|
||||||
|
|
||||||
|
sel.increment_track(albums, Delta::Line);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
assert_eq!(sel.track.state.list.selected(), Some(1));
|
||||||
|
|
||||||
|
// Verify that decrement that doesn't change index does not reset track.
|
||||||
|
sel.decrement(albums, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
assert_eq!(sel.track.state.list.selected(), Some(1));
|
||||||
|
|
||||||
|
sel.increment(albums, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(2));
|
||||||
|
assert_eq!(sel.track.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
sel.decrement(albums, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
assert_eq!(sel.track.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
for _ in 0..(albums.len() + 5) {
|
||||||
|
sel.increment(albums, Delta::Page);
|
||||||
|
}
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(albums.len() - 1));
|
||||||
|
assert_eq!(sel.track.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
sel.increment_track(albums, Delta::Line);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(albums.len() - 1));
|
||||||
|
assert_eq!(sel.track.state.list.selected(), Some(1));
|
||||||
|
|
||||||
|
// Verify that increment that doesn't change index does not reset track.
|
||||||
|
sel.increment(albums, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(albums.len() - 1));
|
||||||
|
assert_eq!(sel.track.state.list.selected(), Some(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn album_reinitialise() {
|
||||||
|
let albums = &COLLECTION[0].albums;
|
||||||
|
assert!(albums.len() > 1);
|
||||||
|
|
||||||
|
let mut sel = AlbumSelection::initialise(albums);
|
||||||
|
sel.state.list.select(Some(albums.len() - 1));
|
||||||
|
sel.track.state.list.select(Some(1));
|
||||||
|
|
||||||
// Re-initialise.
|
// Re-initialise.
|
||||||
let expected = sel.clone();
|
let expected = sel.clone();
|
||||||
@ -503,7 +633,7 @@ mod tests {
|
|||||||
|
|
||||||
// Re-initialise out-of-bounds.
|
// Re-initialise out-of-bounds.
|
||||||
let mut expected = sel.clone();
|
let mut expected = sel.clone();
|
||||||
expected.decrement(albums);
|
expected.decrement(albums, Delta::Line);
|
||||||
let active_album = ActiveAlbum::get(albums, &sel);
|
let active_album = ActiveAlbum::get(albums, &sel);
|
||||||
sel.reinitialise(&albums[..(albums.len() - 1)], active_album);
|
sel.reinitialise(&albums[..(albums.len() - 1)], active_album);
|
||||||
assert_eq!(sel, expected);
|
assert_eq!(sel, expected);
|
||||||
@ -513,16 +643,6 @@ mod tests {
|
|||||||
let active_album = ActiveAlbum::get(albums, &sel);
|
let active_album = ActiveAlbum::get(albums, &sel);
|
||||||
sel.reinitialise(&[], active_album);
|
sel.reinitialise(&[], active_album);
|
||||||
assert_eq!(sel, expected);
|
assert_eq!(sel, expected);
|
||||||
|
|
||||||
// Artifical test case to verify upper limit.
|
|
||||||
sel.state.select(Some(std::usize::MAX));
|
|
||||||
sel.track.state.select(Some(1));
|
|
||||||
assert_eq!(sel.state.selected(), Some(std::usize::MAX));
|
|
||||||
assert_eq!(sel.track.state.selected(), Some(1));
|
|
||||||
|
|
||||||
sel.increment(&[]);
|
|
||||||
assert_eq!(sel.state.selected(), Some(std::usize::MAX));
|
|
||||||
assert_eq!(sel.track.state.selected(), Some(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -531,43 +651,101 @@ mod tests {
|
|||||||
assert!(artists.len() > 1);
|
assert!(artists.len() > 1);
|
||||||
|
|
||||||
let empty = ArtistSelection::initialise(&[]);
|
let empty = ArtistSelection::initialise(&[]);
|
||||||
assert_eq!(empty.state.selected(), None);
|
assert_eq!(empty.state.list.selected(), None);
|
||||||
|
|
||||||
let mut sel = ArtistSelection::initialise(artists);
|
let mut sel = ArtistSelection::initialise(artists);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
assert_eq!(sel.album.state.selected(), Some(0));
|
assert_eq!(sel.album.state.list.selected(), Some(0));
|
||||||
|
|
||||||
sel.increment_album(artists);
|
sel.increment_album(artists, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
assert_eq!(sel.album.state.selected(), Some(1));
|
assert_eq!(sel.album.state.list.selected(), Some(1));
|
||||||
|
|
||||||
// Verify that decrement that doesn't change index does not reset album.
|
// Verify that decrement that doesn't change index does not reset album.
|
||||||
sel.decrement(artists);
|
sel.decrement(artists, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
assert_eq!(sel.album.state.selected(), Some(1));
|
assert_eq!(sel.album.state.list.selected(), Some(1));
|
||||||
|
|
||||||
sel.increment(artists);
|
sel.increment(artists, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(1));
|
assert_eq!(sel.state.list.selected(), Some(1));
|
||||||
assert_eq!(sel.album.state.selected(), Some(0));
|
assert_eq!(sel.album.state.list.selected(), Some(0));
|
||||||
|
|
||||||
sel.decrement(artists);
|
sel.decrement(artists, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(0));
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
assert_eq!(sel.album.state.selected(), Some(0));
|
assert_eq!(sel.album.state.list.selected(), Some(0));
|
||||||
|
|
||||||
for _ in 0..(artists.len() + 5) {
|
for _ in 0..(artists.len() + 5) {
|
||||||
sel.increment(artists);
|
sel.increment(artists, Delta::Line);
|
||||||
}
|
}
|
||||||
assert_eq!(sel.state.selected(), Some(artists.len() - 1));
|
assert_eq!(sel.state.list.selected(), Some(artists.len() - 1));
|
||||||
assert_eq!(sel.album.state.selected(), Some(0));
|
assert_eq!(sel.album.state.list.selected(), Some(0));
|
||||||
|
|
||||||
sel.increment_album(artists);
|
sel.increment_album(artists, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(artists.len() - 1));
|
assert_eq!(sel.state.list.selected(), Some(artists.len() - 1));
|
||||||
assert_eq!(sel.album.state.selected(), Some(1));
|
assert_eq!(sel.album.state.list.selected(), Some(1));
|
||||||
|
|
||||||
// Verify that increment that doesn't change index does not reset album.
|
// Verify that increment that doesn't change index does not reset album.
|
||||||
sel.increment(artists);
|
sel.increment(artists, Delta::Line);
|
||||||
assert_eq!(sel.state.selected(), Some(artists.len() - 1));
|
assert_eq!(sel.state.list.selected(), Some(artists.len() - 1));
|
||||||
assert_eq!(sel.album.state.selected(), Some(1));
|
assert_eq!(sel.album.state.list.selected(), Some(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn artist_delta_page() {
|
||||||
|
let artists = &COLLECTION;
|
||||||
|
assert!(artists.len() > 1);
|
||||||
|
|
||||||
|
let empty = ArtistSelection::initialise(&[]);
|
||||||
|
assert_eq!(empty.state.list.selected(), None);
|
||||||
|
|
||||||
|
let mut sel = ArtistSelection::initialise(artists);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
assert_eq!(sel.album.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
assert!(artists.len() >= 4);
|
||||||
|
sel.state.height = 3;
|
||||||
|
|
||||||
|
sel.increment_album(artists, Delta::Line);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
assert_eq!(sel.album.state.list.selected(), Some(1));
|
||||||
|
|
||||||
|
// Verify that decrement that doesn't change index does not reset album.
|
||||||
|
sel.decrement(artists, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
assert_eq!(sel.album.state.list.selected(), Some(1));
|
||||||
|
|
||||||
|
sel.increment(artists, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(2));
|
||||||
|
assert_eq!(sel.album.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
sel.decrement(artists, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(0));
|
||||||
|
assert_eq!(sel.album.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
for _ in 0..(artists.len() + 5) {
|
||||||
|
sel.increment(artists, Delta::Page);
|
||||||
|
}
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(artists.len() - 1));
|
||||||
|
assert_eq!(sel.album.state.list.selected(), Some(0));
|
||||||
|
|
||||||
|
sel.increment_album(artists, Delta::Line);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(artists.len() - 1));
|
||||||
|
assert_eq!(sel.album.state.list.selected(), Some(1));
|
||||||
|
|
||||||
|
// Verify that increment that doesn't change index does not reset album.
|
||||||
|
sel.increment(artists, Delta::Page);
|
||||||
|
assert_eq!(sel.state.list.selected(), Some(artists.len() - 1));
|
||||||
|
assert_eq!(sel.album.state.list.selected(), Some(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn artist_reinitialise() {
|
||||||
|
let artists = &COLLECTION;
|
||||||
|
assert!(artists.len() > 1);
|
||||||
|
|
||||||
|
let mut sel = ArtistSelection::initialise(artists);
|
||||||
|
sel.state.list.select(Some(artists.len() - 1));
|
||||||
|
sel.album.state.list.select(Some(1));
|
||||||
|
|
||||||
// Re-initialise.
|
// Re-initialise.
|
||||||
let expected = sel.clone();
|
let expected = sel.clone();
|
||||||
@ -577,7 +755,7 @@ mod tests {
|
|||||||
|
|
||||||
// Re-initialise out-of-bounds.
|
// Re-initialise out-of-bounds.
|
||||||
let mut expected = sel.clone();
|
let mut expected = sel.clone();
|
||||||
expected.decrement(artists);
|
expected.decrement(artists, Delta::Line);
|
||||||
let active_artist = ActiveArtist::get(artists, &sel);
|
let active_artist = ActiveArtist::get(artists, &sel);
|
||||||
sel.reinitialise(&artists[..(artists.len() - 1)], active_artist);
|
sel.reinitialise(&artists[..(artists.len() - 1)], active_artist);
|
||||||
assert_eq!(sel, expected);
|
assert_eq!(sel, expected);
|
||||||
@ -587,15 +765,5 @@ mod tests {
|
|||||||
let active_artist = ActiveArtist::get(artists, &sel);
|
let active_artist = ActiveArtist::get(artists, &sel);
|
||||||
sel.reinitialise(&[], active_artist);
|
sel.reinitialise(&[], active_artist);
|
||||||
assert_eq!(sel, expected);
|
assert_eq!(sel, expected);
|
||||||
|
|
||||||
// Artifical test case to verify upper limit.
|
|
||||||
sel.state.select(Some(std::usize::MAX));
|
|
||||||
sel.album.state.select(Some(1));
|
|
||||||
assert_eq!(sel.state.selected(), Some(std::usize::MAX));
|
|
||||||
assert_eq!(sel.album.state.selected(), Some(1));
|
|
||||||
|
|
||||||
sel.increment(&[]);
|
|
||||||
assert_eq!(sel.state.selected(), Some(std::usize::MAX));
|
|
||||||
assert_eq!(sel.album.state.selected(), Some(1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,12 @@ use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
|||||||
use mockall::automock;
|
use mockall::automock;
|
||||||
|
|
||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
app::app::{
|
app::{
|
||||||
AppState, IAppInteract, IAppInteractBrowse, IAppInteractError, IAppInteractInfo,
|
app::{
|
||||||
IAppInteractReload,
|
AppState, IAppInteract, IAppInteractBrowse, IAppInteractError, IAppInteractInfo,
|
||||||
|
IAppInteractReload,
|
||||||
|
},
|
||||||
|
selection::Delta,
|
||||||
},
|
},
|
||||||
event::{Event, EventError, EventReceiver},
|
event::{Event, EventError, EventReceiver},
|
||||||
};
|
};
|
||||||
@ -83,8 +86,10 @@ impl<APP: IAppInteract> IEventHandlerPrivate<APP> for EventHandler {
|
|||||||
KeyCode::Left => app.decrement_category(),
|
KeyCode::Left => app.decrement_category(),
|
||||||
KeyCode::Right => app.increment_category(),
|
KeyCode::Right => app.increment_category(),
|
||||||
// Selection change.
|
// Selection change.
|
||||||
KeyCode::Up => app.decrement_selection(),
|
KeyCode::Up => app.decrement_selection(Delta::Line),
|
||||||
KeyCode::Down => app.increment_selection(),
|
KeyCode::Down => app.increment_selection(Delta::Line),
|
||||||
|
KeyCode::PageUp => app.decrement_selection(Delta::Page),
|
||||||
|
KeyCode::PageDown => app.increment_selection(Delta::Page),
|
||||||
// Toggle overlay.
|
// Toggle overlay.
|
||||||
KeyCode::Char('m') | KeyCode::Char('M') => app.show_info_overlay(),
|
KeyCode::Char('m') | KeyCode::Char('M') => app.show_info_overlay(),
|
||||||
// Toggle Reload
|
// Toggle Reload
|
||||||
|
@ -14,7 +14,7 @@ use ratatui::{
|
|||||||
|
|
||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
app::{AppState, IAppAccess},
|
app::{AppState, IAppAccess},
|
||||||
selection::{Category, Selection},
|
selection::{Category, Selection, WidgetState},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait IUi {
|
pub trait IUi {
|
||||||
@ -159,11 +159,11 @@ impl OverlayBuilder {
|
|||||||
struct ArtistState<'a, 'b> {
|
struct ArtistState<'a, 'b> {
|
||||||
active: bool,
|
active: bool,
|
||||||
list: List<'a>,
|
list: List<'a>,
|
||||||
state: &'b mut ListState,
|
state: &'b mut WidgetState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> ArtistState<'a, 'b> {
|
impl<'a, 'b> ArtistState<'a, 'b> {
|
||||||
fn new(active: bool, artists: &'a [Artist], state: &'b mut ListState) -> ArtistState<'a, 'b> {
|
fn new(active: bool, artists: &'a [Artist], state: &'b mut WidgetState) -> ArtistState<'a, 'b> {
|
||||||
let list = List::new(
|
let list = List::new(
|
||||||
artists
|
artists
|
||||||
.iter()
|
.iter()
|
||||||
@ -234,12 +234,12 @@ impl<'a> ArtistOverlay<'a> {
|
|||||||
struct AlbumState<'a, 'b> {
|
struct AlbumState<'a, 'b> {
|
||||||
active: bool,
|
active: bool,
|
||||||
list: List<'a>,
|
list: List<'a>,
|
||||||
state: &'b mut ListState,
|
state: &'b mut WidgetState,
|
||||||
info: Paragraph<'a>,
|
info: Paragraph<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> AlbumState<'a, 'b> {
|
impl<'a, 'b> AlbumState<'a, 'b> {
|
||||||
fn new(active: bool, albums: &'a [Album], state: &'b mut ListState) -> AlbumState<'a, 'b> {
|
fn new(active: bool, albums: &'a [Album], state: &'b mut WidgetState) -> AlbumState<'a, 'b> {
|
||||||
let list = List::new(
|
let list = List::new(
|
||||||
albums
|
albums
|
||||||
.iter()
|
.iter()
|
||||||
@ -247,7 +247,7 @@ impl<'a, 'b> AlbumState<'a, 'b> {
|
|||||||
.collect::<Vec<ListItem>>(),
|
.collect::<Vec<ListItem>>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let album = state.selected().map(|i| &albums[i]);
|
let album = state.list.selected().map(|i| &albums[i]);
|
||||||
let info = Paragraph::new(format!(
|
let info = Paragraph::new(format!(
|
||||||
"Title: {}\n\
|
"Title: {}\n\
|
||||||
Year: {}",
|
Year: {}",
|
||||||
@ -267,12 +267,12 @@ impl<'a, 'b> AlbumState<'a, 'b> {
|
|||||||
struct TrackState<'a, 'b> {
|
struct TrackState<'a, 'b> {
|
||||||
active: bool,
|
active: bool,
|
||||||
list: List<'a>,
|
list: List<'a>,
|
||||||
state: &'b mut ListState,
|
state: &'b mut WidgetState,
|
||||||
info: Paragraph<'a>,
|
info: Paragraph<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> TrackState<'a, 'b> {
|
impl<'a, 'b> TrackState<'a, 'b> {
|
||||||
fn new(active: bool, tracks: &'a [Track], state: &'b mut ListState) -> TrackState<'a, 'b> {
|
fn new(active: bool, tracks: &'a [Track], state: &'b mut WidgetState) -> TrackState<'a, 'b> {
|
||||||
let list = List::new(
|
let list = List::new(
|
||||||
tracks
|
tracks
|
||||||
.iter()
|
.iter()
|
||||||
@ -280,7 +280,7 @@ impl<'a, 'b> TrackState<'a, 'b> {
|
|||||||
.collect::<Vec<ListItem>>(),
|
.collect::<Vec<ListItem>>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let track = state.selected().map(|i| &tracks[i]);
|
let track = state.list.selected().map(|i| &tracks[i]);
|
||||||
let info = Paragraph::new(format!(
|
let info = Paragraph::new(format!(
|
||||||
"Track: {}\n\
|
"Track: {}\n\
|
||||||
Title: {}\n\
|
Title: {}\n\
|
||||||
@ -342,7 +342,7 @@ impl Ui {
|
|||||||
fn render_list_widget<B: Backend>(
|
fn render_list_widget<B: Backend>(
|
||||||
title: &str,
|
title: &str,
|
||||||
list: List,
|
list: List,
|
||||||
list_state: &mut ListState,
|
state: &mut WidgetState,
|
||||||
active: bool,
|
active: bool,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
frame: &mut Frame<'_, B>,
|
frame: &mut Frame<'_, B>,
|
||||||
@ -353,8 +353,9 @@ impl Ui {
|
|||||||
.style(Self::style(active, false))
|
.style(Self::style(active, false))
|
||||||
.block(Self::block(title, active, false)),
|
.block(Self::block(title, active, false)),
|
||||||
area,
|
area,
|
||||||
list_state,
|
&mut state.list,
|
||||||
);
|
);
|
||||||
|
state.height = area.height.saturating_sub(2) as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_info_widget<B: Backend>(
|
fn render_info_widget<B: Backend>(
|
||||||
@ -422,6 +423,7 @@ impl Ui {
|
|||||||
let no_albums: Vec<Album> = vec![];
|
let no_albums: Vec<Album> = vec![];
|
||||||
let albums = artist_selection
|
let albums = artist_selection
|
||||||
.state
|
.state
|
||||||
|
.list
|
||||||
.selected()
|
.selected()
|
||||||
.map(|i| &artists[i].albums)
|
.map(|i| &artists[i].albums)
|
||||||
.unwrap_or_else(|| &no_albums);
|
.unwrap_or_else(|| &no_albums);
|
||||||
@ -437,6 +439,7 @@ impl Ui {
|
|||||||
let no_tracks: Vec<Track> = vec![];
|
let no_tracks: Vec<Track> = vec![];
|
||||||
let tracks = album_selection
|
let tracks = album_selection
|
||||||
.state
|
.state
|
||||||
|
.list
|
||||||
.selected()
|
.selected()
|
||||||
.map(|i| &albums[i].tracks)
|
.map(|i| &albums[i].tracks)
|
||||||
.unwrap_or_else(|| &no_tracks);
|
.unwrap_or_else(|| &no_tracks);
|
||||||
@ -458,7 +461,7 @@ impl Ui {
|
|||||||
let area = OverlayBuilder::default().build(frame.size());
|
let area = OverlayBuilder::default().build(frame.size());
|
||||||
|
|
||||||
let artist_selection = &mut selection.artist;
|
let artist_selection = &mut selection.artist;
|
||||||
let artist_overlay = ArtistOverlay::new(artists, &artist_selection.state);
|
let artist_overlay = ArtistOverlay::new(artists, &artist_selection.state.list);
|
||||||
|
|
||||||
Self::render_overlay_widget("Artist", artist_overlay.properties, area, false, frame);
|
Self::render_overlay_widget("Artist", artist_overlay.properties, area, false, frame);
|
||||||
}
|
}
|
||||||
@ -510,7 +513,11 @@ impl IUi for Ui {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::tui::{app::app::AppPublic, testmod::COLLECTION, tests::terminal};
|
use crate::tui::{
|
||||||
|
app::{app::AppPublic, selection::Delta},
|
||||||
|
testmod::COLLECTION,
|
||||||
|
tests::terminal,
|
||||||
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -564,14 +571,14 @@ mod tests {
|
|||||||
// Change the track (which has a different track format).
|
// Change the track (which has a different track format).
|
||||||
selection.increment_category();
|
selection.increment_category();
|
||||||
selection.increment_category();
|
selection.increment_category();
|
||||||
selection.increment_selection(artists);
|
selection.increment_selection(artists, Delta::Line);
|
||||||
|
|
||||||
draw_test_suite(artists, &mut selection);
|
draw_test_suite(artists, &mut selection);
|
||||||
|
|
||||||
// Change the artist (which has a multi-link entry).
|
// Change the artist (which has a multi-link entry).
|
||||||
selection.decrement_category();
|
selection.decrement_category();
|
||||||
selection.decrement_category();
|
selection.decrement_category();
|
||||||
selection.increment_selection(artists);
|
selection.increment_selection(artists, Delta::Line);
|
||||||
|
|
||||||
draw_test_suite(artists, &mut selection);
|
draw_test_suite(artists, &mut selection);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user