Skip to content

Commit ece7807

Browse files
committed
ux: sort files and subdirectories by numeric components in name (fixes #272)
1 parent 20f67b5 commit ece7807

File tree

4 files changed

+98
-95
lines changed

4 files changed

+98
-95
lines changed

Sushitrain/BrowserTableView.swift

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -428,94 +428,3 @@ private struct EntryNameView: View {
428428
}
429429
}
430430
}
431-
432-
extension ComparisonResult {
433-
var flipped: ComparisonResult {
434-
switch self {
435-
case .orderedSame: return .orderedSame
436-
case .orderedAscending: return .orderedDescending
437-
case .orderedDescending: return .orderedAscending
438-
}
439-
}
440-
}
441-
442-
private struct EntryComparator: SortComparator {
443-
typealias Compared = SushitrainEntry
444-
445-
enum SortBy {
446-
case size
447-
case name
448-
case lastModifiedDate
449-
case fileExtension
450-
}
451-
452-
var order: SortOrder
453-
var sortBy: SortBy
454-
455-
private func compareDates(_ lhs: Date?, _ rhs: Date?) -> ComparisonResult {
456-
switch (lhs, rhs) {
457-
case (nil, nil): return .orderedSame
458-
case (nil, _): return .orderedAscending
459-
case (_, nil): return .orderedDescending
460-
case (let a, let b): return a!.compare(b!)
461-
}
462-
}
463-
464-
func compare(_ lhs: SushitrainEntry, _ rhs: SushitrainEntry) -> ComparisonResult {
465-
let ascending: ComparisonResult = order == .forward ? .orderedAscending : .orderedDescending
466-
let descending: ComparisonResult = order == .forward ? .orderedDescending : .orderedAscending
467-
468-
switch (lhs.isDirectory(), rhs.isDirectory()) {
469-
// Compare directories among themselves
470-
case (true, true):
471-
switch self.sortBy {
472-
case .size:
473-
return .orderedSame // Directories all have zero size
474-
case .lastModifiedDate:
475-
let r = compareDates(lhs.modifiedAt()?.date(), rhs.modifiedAt()?.date())
476-
return order == .forward ? r : r.flipped
477-
case .name:
478-
return order == .forward
479-
? lhs.name().compare(rhs.name()) : rhs.name().compare(lhs.name())
480-
case .fileExtension:
481-
return order == .forward
482-
? lhs.extension().compare(rhs.extension())
483-
: rhs.extension().compare(lhs.extension())
484-
}
485-
486-
// Compare directory with file or vice versa
487-
case (true, false): return .orderedAscending // This doesn't change when order is swapped
488-
case (false, true): return .orderedDescending // This doesn't change when order is swapped
489-
490-
// Compare entries among themselves
491-
case (false, false):
492-
switch self.sortBy {
493-
case .lastModifiedDate:
494-
let r = compareDates(lhs.modifiedAt()?.date(), rhs.modifiedAt()?.date())
495-
return order == .forward ? r : r.flipped
496-
497-
case .name:
498-
return order == .forward
499-
? lhs.name().compare(rhs.name()) : rhs.name().compare(lhs.name())
500-
501-
case .fileExtension:
502-
return order == .forward
503-
? lhs.extension().compare(rhs.extension())
504-
: rhs.extension().compare(lhs.extension())
505-
506-
case .size:
507-
let sa = lhs.size()
508-
let sb = rhs.size()
509-
if sa == sb {
510-
return .orderedSame
511-
}
512-
else if sa < sb {
513-
return ascending
514-
}
515-
else {
516-
return descending
517-
}
518-
}
519-
}
520-
}
521-
}

Sushitrain/BrowserView.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ private struct BrowserItemsView: View {
732732
}
733733
do {
734734
var dirNames = try folder.list(prefix, directories: true, recurse: false).asArray()
735-
.sorted()
735+
.sorted(by: { $0.compare($1, options: .numeric) == .orderedAscending })
736736
if dotFilesHidden {
737737
dirNames = dirNames.filter({ !$0.starts(with: ".") })
738738
}
@@ -752,8 +752,9 @@ private struct BrowserItemsView: View {
752752
return []
753753
}
754754
do {
755-
return try folder.listEntries(
756-
prefix: self.prefix, directories: false, hideDotFiles: dotFilesHidden)
755+
var entries = try folder.listEntries(prefix: self.prefix, directories: false, hideDotFiles: dotFilesHidden)
756+
entries.sort(by: { $0.fileName().compare($1.fileName(), options: .numeric) == .orderedAscending })
757+
return entries
757758
}
758759
catch let error {
759760
Log.warn("Error listing: \(error.localizedDescription)")

Sushitrain/FoldersView.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ struct FoldersSections: View {
215215
}
216216

217217
private func update() async {
218-
folders = await appState.folders().sorted()
218+
folders = await appState.folders().sorted(by: {
219+
$0.displayName.compare($1.displayName, options: .numeric) == .orderedAscending
220+
})
219221

220222
let addedFolders = Set(folders.map({ f in f.folderID }))
221223
self.pendingFolderIds = ((try? self.appState.client.pendingFolderIDs())?.asArray() ?? []).filter({

Sushitrain/Utils.swift

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,3 +1013,94 @@ extension SecCertificate {
10131013
return Data(digest)
10141014
}
10151015
}
1016+
1017+
extension ComparisonResult {
1018+
var flipped: ComparisonResult {
1019+
switch self {
1020+
case .orderedSame: return .orderedSame
1021+
case .orderedAscending: return .orderedDescending
1022+
case .orderedDescending: return .orderedAscending
1023+
}
1024+
}
1025+
}
1026+
1027+
struct EntryComparator: SortComparator {
1028+
typealias Compared = SushitrainEntry
1029+
1030+
enum SortBy {
1031+
case size
1032+
case name
1033+
case lastModifiedDate
1034+
case fileExtension
1035+
}
1036+
1037+
var order: SortOrder
1038+
var sortBy: SortBy
1039+
1040+
private func compareDates(_ lhs: Date?, _ rhs: Date?) -> ComparisonResult {
1041+
switch (lhs, rhs) {
1042+
case (nil, nil): return .orderedSame
1043+
case (nil, _): return .orderedAscending
1044+
case (_, nil): return .orderedDescending
1045+
case (let a, let b): return a!.compare(b!)
1046+
}
1047+
}
1048+
1049+
func compare(_ lhs: SushitrainEntry, _ rhs: SushitrainEntry) -> ComparisonResult {
1050+
let ascending: ComparisonResult = order == .forward ? .orderedAscending : .orderedDescending
1051+
let descending: ComparisonResult = order == .forward ? .orderedDescending : .orderedAscending
1052+
1053+
switch (lhs.isDirectory(), rhs.isDirectory()) {
1054+
// Compare directories among themselves
1055+
case (true, true):
1056+
switch self.sortBy {
1057+
case .size:
1058+
return .orderedSame // Directories all have zero size
1059+
case .lastModifiedDate:
1060+
let r = compareDates(lhs.modifiedAt()?.date(), rhs.modifiedAt()?.date())
1061+
return order == .forward ? r : r.flipped
1062+
case .name:
1063+
return order == .forward
1064+
? lhs.name().compare(rhs.name(), options: .numeric) : rhs.name().compare(lhs.name(), options: .numeric)
1065+
case .fileExtension:
1066+
return order == .forward
1067+
? lhs.extension().compare(rhs.extension(), options: .numeric)
1068+
: rhs.extension().compare(lhs.extension(), options: .numeric)
1069+
}
1070+
1071+
// Compare directory with file or vice versa
1072+
case (true, false): return .orderedAscending // This doesn't change when order is swapped
1073+
case (false, true): return .orderedDescending // This doesn't change when order is swapped
1074+
1075+
// Compare entries among themselves
1076+
case (false, false):
1077+
switch self.sortBy {
1078+
case .lastModifiedDate:
1079+
let r = compareDates(lhs.modifiedAt()?.date(), rhs.modifiedAt()?.date())
1080+
return order == .forward ? r : r.flipped
1081+
1082+
case .name:
1083+
return order == .forward
1084+
? lhs.name().compare(rhs.name(), options: .numeric) : rhs.name().compare(lhs.name(), options: .numeric)
1085+
1086+
case .fileExtension:
1087+
return order == .forward
1088+
? lhs.extension().compare(rhs.extension(), options: .numeric)
1089+
: rhs.extension().compare(lhs.extension(), options: .numeric)
1090+
1091+
case .size:
1092+
let sa = lhs.size()
1093+
let sb = rhs.size()
1094+
if sa == sb {
1095+
return .orderedSame
1096+
}
1097+
else if sa < sb {
1098+
return ascending
1099+
}
1100+
else {
1101+
return descending
1102+
}
1103+
}
1104+
}
1105+
}
1106+
}

0 commit comments

Comments
 (0)