[READ-ONLY] Mirror of https://github.com/probablykasper/ferrum. Music library app for Mac, Linux and Windows ferrum.kasper.space
electron linux macos music music-library music-player napi windows
0

Configure Feed

Select the types of activity you want to include in your feed.

Sub-sort album by track number

Kasper (Apr 30, 2024, 6:40 AM +0200) 47ec3e5c 331b4ebb

+77 -54
+1
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 3 ## Next 4 + - Sub-sort albums by track number when sorting by album 4 5 - Add `Escape` shortcut for de-focusing the sidebar and filter 5 6 - Fix rare error with updating artwork 6 7 - Fix importing of iTunes playlist likes. These aren't visible in the app, but they do get imported. If you previously imported playlists, the likes got lost in Ferrum.
+76 -54
src-native/sort.rs
··· 111 111 data.open_playlist_track_ids = page::get_track_ids(&data)?; 112 112 113 113 let tracks = &data.library.tracks; 114 - let field = get_track_field_type(sort_key); 114 + let field = match get_track_field_type(sort_key) { 115 + Some(field) => field, 116 + None => throw!("Field type not found for {sort_key}"), 117 + }; 118 + let sort_2 = match sort_key { 119 + "albumName" => Some(("trackNum", TrackField::U32, false)), 120 + _ => None, 121 + }; 115 122 data.open_playlist_track_ids.sort_by(|id_a, id_b| { 116 123 let track_a = tracks.get(id_a).expect("Track ID non-existant (1)"); 117 124 let track_b = tracks.get(id_b).expect("Track ID non-existant (2)"); 118 - match field { 119 - Some(TrackField::String) => { 120 - let empty_str = &"".to_string(); 121 - let str_a = get_field_str(track_a, sort_key).unwrap_or(empty_str); 122 - let str_b = get_field_str(track_b, sort_key).unwrap_or(empty_str); 123 - if str_a == "" && str_b == "" { 124 - return Ordering::Equal; 125 + match compare_track_field(track_a, track_b, sort_key, &field) { 126 + Ordering::Equal => {} 127 + order => { 128 + return match desc { 129 + true => order.reverse(), 130 + false => order, 125 131 } 126 - if str_a == "" { 127 - return Ordering::Greater; 128 - } 129 - if str_b == "" { 130 - return Ordering::Less; 131 - } 132 - return compare_str(str_a, str_b); 133 - } 134 - Some(TrackField::F64) => { 135 - let num_a = get_field_f64(track_a, sort_key).unwrap_or(0.0); 136 - let num_b = get_field_f64(track_b, sort_key).unwrap_or(0.0); 137 - match num_a.partial_cmp(&num_b) { 138 - Some(v) => v, 139 - None => panic!("Unable to compare f64 {} and {}", num_a, num_b), 140 - } 141 - } 142 - Some(TrackField::I64) => { 143 - let num_a = get_field_i64(track_a, sort_key).unwrap_or(0); 144 - let num_b = get_field_i64(track_b, sort_key).unwrap_or(0); 145 - return num_a.cmp(&num_b); 146 - } 147 - Some(TrackField::U32) => { 148 - let num_a = get_field_u32(track_a, sort_key).unwrap_or(0); 149 - let num_b = get_field_u32(track_b, sort_key).unwrap_or(0); 150 - return num_a.cmp(&num_b); 151 - } 152 - Some(TrackField::I8) => { 153 - let num_a = get_field_i8(track_a, sort_key).unwrap_or(0); 154 - let num_b = get_field_i8(track_b, sort_key).unwrap_or(0); 155 - return num_a.cmp(&num_b); 156 - } 157 - Some(TrackField::U8) => { 158 - let num_a = get_field_u8(track_a, sort_key).unwrap_or(0); 159 - let num_b = get_field_u8(track_b, sort_key).unwrap_or(0); 160 - return num_a.cmp(&num_b); 161 - } 162 - Some(TrackField::Bool) => { 163 - let bool_a = get_field_bool(track_a, sort_key).unwrap_or(false); //? look into this 164 - let bool_b = get_field_bool(track_b, sort_key).unwrap_or(false); //? look into this 165 - return bool_a.cmp(&bool_b); 166 - } 167 - None => { 168 - panic!("Field type not found for {}", sort_key) 169 132 } 133 + }; 134 + if let Some((sort_key, field, desc)) = &sort_2 { 135 + let order = compare_track_field(track_a, track_b, sort_key, &field); 136 + return match desc { 137 + true => order.reverse(), 138 + false => order, 139 + }; 140 + } else { 141 + Ordering::Equal 170 142 } 171 143 }); 172 - if desc { 173 - data.open_playlist_track_ids.reverse(); 174 - } 175 144 data.sort_key = sort_key.to_string(); 176 145 data.sort_desc = desc; 177 146 println!("Sort: {}ms", now.elapsed().as_millis()); 178 147 return Ok(()); 179 148 } 149 + 150 + pub fn compare_track_field(a: &Track, b: &Track, sort_key: &str, field: &TrackField) -> Ordering { 151 + match field { 152 + TrackField::String => { 153 + let empty_str = &"".to_string(); 154 + let str_a = get_field_str(a, sort_key).unwrap_or(empty_str); 155 + let str_b = get_field_str(b, sort_key).unwrap_or(empty_str); 156 + if str_a == "" && str_b == "" { 157 + return Ordering::Equal; 158 + } 159 + if str_a == "" { 160 + return Ordering::Greater; 161 + } 162 + if str_b == "" { 163 + return Ordering::Less; 164 + } 165 + return compare_str(str_a, str_b); 166 + } 167 + TrackField::F64 => { 168 + let num_a = get_field_f64(a, sort_key).unwrap_or(0.0); 169 + let num_b = get_field_f64(b, sort_key).unwrap_or(0.0); 170 + match num_a.partial_cmp(&num_b) { 171 + Some(v) => v, 172 + None => panic!("Unable to compare f64 {} and {}", num_a, num_b), 173 + } 174 + } 175 + TrackField::I64 => { 176 + let num_a = get_field_i64(a, sort_key).unwrap_or(0); 177 + let num_b = get_field_i64(b, sort_key).unwrap_or(0); 178 + return num_a.cmp(&num_b); 179 + } 180 + TrackField::U32 => { 181 + let num_a = get_field_u32(a, sort_key).unwrap_or(0); 182 + let num_b = get_field_u32(b, sort_key).unwrap_or(0); 183 + return num_a.cmp(&num_b); 184 + } 185 + TrackField::I8 => { 186 + let num_a = get_field_i8(a, sort_key).unwrap_or(0); 187 + let num_b = get_field_i8(b, sort_key).unwrap_or(0); 188 + return num_a.cmp(&num_b); 189 + } 190 + TrackField::U8 => { 191 + let num_a = get_field_u8(a, sort_key).unwrap_or(0); 192 + let num_b = get_field_u8(b, sort_key).unwrap_or(0); 193 + return num_a.cmp(&num_b); 194 + } 195 + TrackField::Bool => { 196 + let bool_a = get_field_bool(a, sort_key).unwrap_or(false); //? look into this 197 + let bool_b = get_field_bool(b, sort_key).unwrap_or(false); //? look into this 198 + return bool_a.cmp(&bool_b); 199 + } 200 + } 201 + }