···11# Changelog
2233## Next
44+- Sub-sort albums by track number when sorting by album
45- Add `Escape` shortcut for de-focusing the sidebar and filter
56- Fix rare error with updating artwork
67- 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
···111111 data.open_playlist_track_ids = page::get_track_ids(&data)?;
112112113113 let tracks = &data.library.tracks;
114114- let field = get_track_field_type(sort_key);
114114+ let field = match get_track_field_type(sort_key) {
115115+ Some(field) => field,
116116+ None => throw!("Field type not found for {sort_key}"),
117117+ };
118118+ let sort_2 = match sort_key {
119119+ "albumName" => Some(("trackNum", TrackField::U32, false)),
120120+ _ => None,
121121+ };
115122 data.open_playlist_track_ids.sort_by(|id_a, id_b| {
116123 let track_a = tracks.get(id_a).expect("Track ID non-existant (1)");
117124 let track_b = tracks.get(id_b).expect("Track ID non-existant (2)");
118118- match field {
119119- Some(TrackField::String) => {
120120- let empty_str = &"".to_string();
121121- let str_a = get_field_str(track_a, sort_key).unwrap_or(empty_str);
122122- let str_b = get_field_str(track_b, sort_key).unwrap_or(empty_str);
123123- if str_a == "" && str_b == "" {
124124- return Ordering::Equal;
125125+ match compare_track_field(track_a, track_b, sort_key, &field) {
126126+ Ordering::Equal => {}
127127+ order => {
128128+ return match desc {
129129+ true => order.reverse(),
130130+ false => order,
125131 }
126126- if str_a == "" {
127127- return Ordering::Greater;
128128- }
129129- if str_b == "" {
130130- return Ordering::Less;
131131- }
132132- return compare_str(str_a, str_b);
133133- }
134134- Some(TrackField::F64) => {
135135- let num_a = get_field_f64(track_a, sort_key).unwrap_or(0.0);
136136- let num_b = get_field_f64(track_b, sort_key).unwrap_or(0.0);
137137- match num_a.partial_cmp(&num_b) {
138138- Some(v) => v,
139139- None => panic!("Unable to compare f64 {} and {}", num_a, num_b),
140140- }
141141- }
142142- Some(TrackField::I64) => {
143143- let num_a = get_field_i64(track_a, sort_key).unwrap_or(0);
144144- let num_b = get_field_i64(track_b, sort_key).unwrap_or(0);
145145- return num_a.cmp(&num_b);
146146- }
147147- Some(TrackField::U32) => {
148148- let num_a = get_field_u32(track_a, sort_key).unwrap_or(0);
149149- let num_b = get_field_u32(track_b, sort_key).unwrap_or(0);
150150- return num_a.cmp(&num_b);
151151- }
152152- Some(TrackField::I8) => {
153153- let num_a = get_field_i8(track_a, sort_key).unwrap_or(0);
154154- let num_b = get_field_i8(track_b, sort_key).unwrap_or(0);
155155- return num_a.cmp(&num_b);
156156- }
157157- Some(TrackField::U8) => {
158158- let num_a = get_field_u8(track_a, sort_key).unwrap_or(0);
159159- let num_b = get_field_u8(track_b, sort_key).unwrap_or(0);
160160- return num_a.cmp(&num_b);
161161- }
162162- Some(TrackField::Bool) => {
163163- let bool_a = get_field_bool(track_a, sort_key).unwrap_or(false); //? look into this
164164- let bool_b = get_field_bool(track_b, sort_key).unwrap_or(false); //? look into this
165165- return bool_a.cmp(&bool_b);
166166- }
167167- None => {
168168- panic!("Field type not found for {}", sort_key)
169132 }
133133+ };
134134+ if let Some((sort_key, field, desc)) = &sort_2 {
135135+ let order = compare_track_field(track_a, track_b, sort_key, &field);
136136+ return match desc {
137137+ true => order.reverse(),
138138+ false => order,
139139+ };
140140+ } else {
141141+ Ordering::Equal
170142 }
171143 });
172172- if desc {
173173- data.open_playlist_track_ids.reverse();
174174- }
175144 data.sort_key = sort_key.to_string();
176145 data.sort_desc = desc;
177146 println!("Sort: {}ms", now.elapsed().as_millis());
178147 return Ok(());
179148}
149149+150150+pub fn compare_track_field(a: &Track, b: &Track, sort_key: &str, field: &TrackField) -> Ordering {
151151+ match field {
152152+ TrackField::String => {
153153+ let empty_str = &"".to_string();
154154+ let str_a = get_field_str(a, sort_key).unwrap_or(empty_str);
155155+ let str_b = get_field_str(b, sort_key).unwrap_or(empty_str);
156156+ if str_a == "" && str_b == "" {
157157+ return Ordering::Equal;
158158+ }
159159+ if str_a == "" {
160160+ return Ordering::Greater;
161161+ }
162162+ if str_b == "" {
163163+ return Ordering::Less;
164164+ }
165165+ return compare_str(str_a, str_b);
166166+ }
167167+ TrackField::F64 => {
168168+ let num_a = get_field_f64(a, sort_key).unwrap_or(0.0);
169169+ let num_b = get_field_f64(b, sort_key).unwrap_or(0.0);
170170+ match num_a.partial_cmp(&num_b) {
171171+ Some(v) => v,
172172+ None => panic!("Unable to compare f64 {} and {}", num_a, num_b),
173173+ }
174174+ }
175175+ TrackField::I64 => {
176176+ let num_a = get_field_i64(a, sort_key).unwrap_or(0);
177177+ let num_b = get_field_i64(b, sort_key).unwrap_or(0);
178178+ return num_a.cmp(&num_b);
179179+ }
180180+ TrackField::U32 => {
181181+ let num_a = get_field_u32(a, sort_key).unwrap_or(0);
182182+ let num_b = get_field_u32(b, sort_key).unwrap_or(0);
183183+ return num_a.cmp(&num_b);
184184+ }
185185+ TrackField::I8 => {
186186+ let num_a = get_field_i8(a, sort_key).unwrap_or(0);
187187+ let num_b = get_field_i8(b, sort_key).unwrap_or(0);
188188+ return num_a.cmp(&num_b);
189189+ }
190190+ TrackField::U8 => {
191191+ let num_a = get_field_u8(a, sort_key).unwrap_or(0);
192192+ let num_b = get_field_u8(b, sort_key).unwrap_or(0);
193193+ return num_a.cmp(&num_b);
194194+ }
195195+ TrackField::Bool => {
196196+ let bool_a = get_field_bool(a, sort_key).unwrap_or(false); //? look into this
197197+ let bool_b = get_field_bool(b, sort_key).unwrap_or(false); //? look into this
198198+ return bool_a.cmp(&bool_b);
199199+ }
200200+ }
201201+}