Sort review clips by active setting

This commit is contained in:
Mikei386
2026-06-04 09:46:07 +02:00
parent 7cb4c5e86a
commit 7c0eb7b0d4
2 changed files with 73 additions and 3 deletions
+28 -2
View File
@@ -253,6 +253,9 @@ struct ContentView: View {
selectedClipID = project?.clips.first?.id
}
}
.onChange(of: settings.sortMode) { sortMode in
processor.reorderProject(sortMode: sortMode)
}
}
private var statusHeader: some View {
@@ -307,7 +310,8 @@ struct ContentView: View {
}
private func projectReviewPanel(_ project: GrowthLapseProject) -> some View {
let selectedClip = project.clips.first { $0.id == selectedClipID } ?? project.clips.first
let orderedClips = orderedProjectClips(project.clips)
let selectedClip = orderedClips.first { $0.id == selectedClipID } ?? orderedClips.first
return VStack(alignment: .leading, spacing: 10) {
HStack {
@@ -328,7 +332,7 @@ struct ContentView: View {
}
HStack(alignment: .top, spacing: 12) {
List(project.clips, selection: $selectedClipID) { clip in
List(orderedClips, selection: $selectedClipID) { clip in
VStack(alignment: .leading, spacing: 2) {
HStack {
Text(String(format: "%03d", clip.index))
@@ -429,6 +433,28 @@ struct ContentView: View {
processor.project?.clips.first { $0.id == id }
}
private func orderedProjectClips(_ clips: [GrowthLapseProjectClip]) -> [GrowthLapseProjectClip] {
clips.sorted { left, right in
switch settings.sortMode {
case .filenameAscending:
return left.displayName.localizedStandardCompare(right.displayName) == .orderedAscending
case .ageWeeksAscending:
if left.ageWeeks != right.ageWeeks {
return (left.ageWeeks ?? Int.max) < (right.ageWeeks ?? Int.max)
}
return left.displayName.localizedStandardCompare(right.displayName) == .orderedAscending
case .modificationDateAscending:
return left.index < right.index
}
}
.enumerated()
.map { offset, clip in
var updated = clip
updated.index = offset + 1
return updated
}
}
private var errorBinding: Binding<Bool> {
Binding(
get: {
+45 -1
View File
@@ -69,7 +69,7 @@ final class VideoProcessor: ObservableObject {
state = .running
let settingsCopy = settings
let projectCopy = project
let projectCopy = reorderedProject(project, sortMode: settings.sortMode)
renderTask = Task {
do {
let outcome = try await render(settings: settingsCopy, existingProject: projectCopy)
@@ -106,6 +106,15 @@ final class VideoProcessor: ObservableObject {
saveProject(project)
}
func reorderProject(sortMode: SortMode) {
guard let project else {
return
}
let reordered = reorderedProject(project, sortMode: sortMode)
self.project = reordered
saveProject(reordered)
}
func confirmProjectAndDeleteCache() {
guard let project else {
return
@@ -1039,6 +1048,41 @@ final class VideoProcessor: ObservableObject {
)
}
private func reorderedProject(_ project: GrowthLapseProject, sortMode: SortMode) -> GrowthLapseProject {
var copy = project
copy.clips = sortedProjectClips(project.clips, sortMode: sortMode).enumerated().map { offset, clip in
var updated = clip
updated.index = offset + 1
return updated
}
return copy
}
private func sortedProjectClips(_ clips: [GrowthLapseProjectClip], sortMode: SortMode) -> [GrowthLapseProjectClip] {
clips.sorted { left, right in
switch sortMode {
case .filenameAscending:
return left.displayName.localizedStandardCompare(right.displayName) == .orderedAscending
case .ageWeeksAscending:
if left.ageWeeks != right.ageWeeks {
return (left.ageWeeks ?? Int.max) < (right.ageWeeks ?? Int.max)
}
return left.displayName.localizedStandardCompare(right.displayName) == .orderedAscending
case .modificationDateAscending:
let leftDate = modificationDate(for: left.sourceURL)
let rightDate = modificationDate(for: right.sourceURL)
if leftDate != rightDate {
return leftDate < rightDate
}
return left.displayName.localizedStandardCompare(right.displayName) == .orderedAscending
}
}
}
private func modificationDate(for url: URL) -> Date {
(try? url.resourceValues(forKeys: [.contentModificationDateKey]).contentModificationDate) ?? .distantPast
}
private func saveProject(_ project: GrowthLapseProject) {
let url = GrowthLapseProject.url(for: project.outputFileURL)
do {