Skip to content

Commit

Permalink
Finagle the sort order a little
Browse files Browse the repository at this point in the history
Navidrome at least has an [Unknown] index with an [Unknown Artist]
artist entry below it, but the Foundation sorting puts it in a clumsy
place with the index and artist flipped. Provide a custom sort order
that deals with it. Ugly and Navidrome specific, but does work.

I'm considering preserving the order the server gives us, but that has
its own problems (is it actually desirable?). Might need to rethink the
schema with index vs. artist a little.
  • Loading branch information
NattyNarwhal committed May 15, 2024
1 parent 8674038 commit b6d1c4a
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Submariner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
3E70B2E12A2D52A1002C0B93 /* SBPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E70B2E02A2D52A1002C0B93 /* SBPlayer.swift */; };
3E7491972B6A1AE00052CBCE /* SBTracklistController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E7491962B6A1AE00052CBCE /* SBTracklistController.swift */; };
3E8124272BEFF4F80060DDAF /* SBToggleNameTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E8124262BEFF4F80060DDAF /* SBToggleNameTransformer.swift */; };
3E8124292BF408110060DDAF /* NSString+Comparison.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E8124282BF408110060DDAF /* NSString+Comparison.swift */; };
3E82701827E653F0007E5695 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E82701727E653F0007E5695 /* MediaPlayer.framework */; };
3E87E90E2B43557400E85000 /* SBServerSearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E87E90D2B43557400E85000 /* SBServerSearchController.swift */; };
3E87E9102B4364CF00E85000 /* Collection+IndexSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E87E90F2B4364CF00E85000 /* Collection+IndexSet.swift */; };
Expand Down Expand Up @@ -209,6 +210,7 @@
3E70B2E02A2D52A1002C0B93 /* SBPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SBPlayer.swift; sourceTree = "<group>"; };
3E7491962B6A1AE00052CBCE /* SBTracklistController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SBTracklistController.swift; sourceTree = "<group>"; };
3E8124262BEFF4F80060DDAF /* SBToggleNameTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SBToggleNameTransformer.swift; sourceTree = "<group>"; };
3E8124282BF408110060DDAF /* NSString+Comparison.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSString+Comparison.swift"; sourceTree = "<group>"; };
3E82701727E653F0007E5695 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
3E87E90D2B43557400E85000 /* SBServerSearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SBServerSearchController.swift; sourceTree = "<group>"; };
3E87E90F2B4364CF00E85000 /* Collection+IndexSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+IndexSet.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -592,6 +594,7 @@
4CFB3E05139CEA76008DC01A /* NSOutlineView+Expand.h */,
4CFB3E06139CEA76008DC01A /* NSOutlineView+Expand.m */,
3E32BE542B8E500500E77CF0 /* NSPasteboard+Library.swift */,
3E8124282BF408110060DDAF /* NSString+Comparison.swift */,
3E2F86D728E8F5BD00C5CE23 /* NSTreeController+IndexPath.swift */,
3EC03AC229F33C68001FDE50 /* OperationQueue+Shared.swift */,
3E87E9112B436B4500E85000 /* PasteboardType+Submariner.swift */,
Expand Down Expand Up @@ -876,6 +879,7 @@
3EC039C929EFC259001FDE50 /* View+Modify.swift in Sources */,
3EC03B3A29F4F2E0001FDE50 /* SBAlbum.swift in Sources */,
3EB2BCD12992FD5A00DC5056 /* SBTracklistButton.swift in Sources */,
3E8124292BF408110060DDAF /* NSString+Comparison.swift in Sources */,
4CFB3E14139D028D008DC01A /* SBSheetController.m in Sources */,
4CFB3E15139D028D008DC01A /* SBServerViewController.m in Sources */,
3E189E4028EF5BAB0062ACA0 /* SBAudioMetadata.swift in Sources */,
Expand Down
40 changes: 40 additions & 0 deletions Submariner/NSString+Comparison.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// NSString+Comparison.swift
// Submariner
//
// Created by Calvin Buckley on 2024-05-14.
//
// Copyright (c) 2024 Calvin Buckley
// SPDX-License-Identifier: BSD-3-Clause
//

import Foundation

extension NSString {
private func isUnknownValue(_ string: String) -> Bool {
return string.starts(with: "[Unknown") && string.last == "]"
}

@objc func artistListCompare(_ rhs: String) -> ComparisonResult {
let lhs = self as String
// Our goal with this is to kick the special unknown values to the bottom.
// For example in Navidrome, there is the [Unknown] index group as well as
// [Unknown Artist] and [Unknown Album]. The default sorting behaviours from
// Foundation are unpleasant and put the group after the artist, or put them
// in the middle of the list.
// This is Navidrome specific unfortunately.
// In the future other comparison changes could be made.
let lhsUnknown = isUnknownValue(lhs)
let rhsUnknown = isUnknownValue(rhs)
if lhsUnknown && !rhsUnknown {
return .orderedDescending
} else if !lhsUnknown && rhsUnknown {
return .orderedAscending
} else if lhsUnknown && rhsUnknown {
// we won't see special items of the same length
return lhs.count < rhs.count ? .orderedAscending : .orderedDescending
}

return self.caseInsensitiveCompare(rhs)
}
}
2 changes: 1 addition & 1 deletion Submariner/SBMusicController.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ - (NSString*)title {
- (id)initWithManagedObjectContext:(NSManagedObjectContext *)context {
self = [super initWithManagedObjectContext:context];
if (self) {
NSSortDescriptor *artistDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"itemName" ascending:YES selector: @selector(caseInsensitiveCompare:)];
NSSortDescriptor *artistDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"itemName" ascending:YES selector: @selector(artistListCompare:)];
artistSortDescriptor = [NSArray arrayWithObject:artistDescriptor];

NSSortDescriptor *albumYearDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"year" ascending:YES];
Expand Down
2 changes: 1 addition & 1 deletion Submariner/SBServerLibraryController.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ - (id)initWithManagedObjectContext:(NSManagedObjectContext *)context {
if (self) {
groupEntity = [NSEntityDescription entityForName: @"Group" inManagedObjectContext: managedObjectContext];

NSSortDescriptor *artistDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"itemName" ascending:YES selector: @selector(caseInsensitiveCompare:)];
NSSortDescriptor *artistDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"itemName" ascending:YES selector: @selector(artistListCompare:)];
artistSortDescriptor = [NSArray arrayWithObject:artistDescriptor];

NSSortDescriptor *albumYearDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"year" ascending:YES];
Expand Down

0 comments on commit b6d1c4a

Please sign in to comment.