diff --git a/Memola.xcodeproj/project.pbxproj b/Memola.xcodeproj/project.pbxproj index e57b134..131c62d 100644 --- a/Memola.xcodeproj/project.pbxproj +++ b/Memola.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ EC0D14242BF79C98009BFE5F /* MemolaModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = EC0D14222BF79C98009BFE5F /* MemolaModel.xcdatamodeld */; }; EC0D14262BF7A8C9009BFE5F /* PenObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0D14252BF7A8C9009BFE5F /* PenObject.swift */; }; EC0D14282BF7BF20009BFE5F /* ContextMenuViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC0D14272BF7BF20009BFE5F /* ContextMenuViewModifier.swift */; }; + EC1815082C2D980B00541369 /* Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815072C2D980B00541369 /* Sort.swift */; }; EC1B783D2BFA0AC9005A34E2 /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */; }; EC2106AD2C10C2A700FBE27C /* AnyStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */; }; EC2BEBF42C0F5FF7005DB0AF /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */; }; @@ -117,6 +118,7 @@ EC0D14232BF79C98009BFE5F /* MemolaModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MemolaModel.xcdatamodel; sourceTree = ""; }; EC0D14252BF7A8C9009BFE5F /* PenObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenObject.swift; sourceTree = ""; }; EC0D14272BF7BF20009BFE5F /* ContextMenuViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuViewModifier.swift; sourceTree = ""; }; + EC1815072C2D980B00541369 /* Sort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sort.swift; sourceTree = ""; }; EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toolbar.swift; sourceTree = ""; }; EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyStroke.swift; sourceTree = ""; }; EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RTree.swift; sourceTree = ""; }; @@ -411,6 +413,7 @@ isa = PBXGroup; children = ( ECA738792BE5EF0400A4542E /* MemosView.swift */, + EC1815072C2D980B00541369 /* Sort.swift */, ); path = Memos; sourceTree = ""; @@ -887,6 +890,7 @@ EC3565522BEFC65F00A4E0BF /* NSManagedObjectContext++.swift in Sources */, ECFA15222BEF21F500455818 /* CanvasObject.swift in Sources */, ECA738AA2BE6026D00A4542E /* Uniforms.swift in Sources */, + EC1815082C2D980B00541369 /* Sort.swift in Sources */, ECA7387D2BE5EF4B00A4542E /* MemoView.swift in Sources */, ECA738DA2BE60FF100A4542E /* CacheRenderPass.swift in Sources */, ECA738CD2BE60F2F00A4542E /* PointGridContext.swift in Sources */, diff --git a/Memola/Features/Memos/MemosView.swift b/Memola/Features/Memos/MemosView.swift index bdf4e07..1c292a1 100644 --- a/Memola/Features/Memos/MemosView.swift +++ b/Memola/Features/Memos/MemosView.swift @@ -10,23 +10,43 @@ import SwiftUI struct MemosView: View { @Environment(\.managedObjectContext) var managedObjectContext - @FetchRequest(sortDescriptors: []) var memoObjects: FetchedResults + @FetchRequest var memoObjects: FetchedResults @State var memo: MemoObject? + @AppStorage("memola.memo-objects.sort") var sort: Sort = .recent + let cellWidth: CGFloat = 250 let cellHeight: CGFloat = 150 + init() { + let standard = UserDefaults.standard + var descriptors: [SortDescriptor] = [] + let sort = Sort(rawValue: standard.value(forKey: "memola.memo-objects.sort") as? String ?? "") ?? .recent + descriptors = sort.memoSortDescriptors + _memoObjects = FetchRequest(sortDescriptors: descriptors) + } + var body: some View { NavigationStack { memoGrid .navigationTitle("Memos") .toolbar { - ToolbarItem(placement: .primaryAction) { + ToolbarItemGroup(placement: .primaryAction) { + Menu { + Picker("", selection: $sort) { + ForEach(Sort.all) { sort in + Text(sort.name) + .tag(sort) + } + } + } label: { + Image(systemName: "arrow.up.arrow.down.circle") + } Button { createMemo(title: "Untitled") } label: { - Image(systemName: "plus") + Image(systemName: "square.and.pencil") } .hoverEffect() } @@ -41,6 +61,9 @@ struct MemosView: View { } } } + .onChange(of: sort) { oldValue, newValue in + memoObjects.sortDescriptors = newValue.memoSortDescriptors + } } var memoGrid: some View { diff --git a/Memola/Features/Memos/Sort.swift b/Memola/Features/Memos/Sort.swift new file mode 100644 index 0000000..aa9f4b0 --- /dev/null +++ b/Memola/Features/Memos/Sort.swift @@ -0,0 +1,49 @@ +// +// Sort.swift +// Memola +// +// Created by Dscyre Scotti on 6/27/24. +// + +import Foundation + +enum Sort: String, Identifiable, Hashable, Equatable { + var id: String { + rawValue + } + + case recent + case aToZ + case zToA + case newest + case oldest + + var name: String { + switch self { + case .recent: return "Recent" + case .aToZ: return "A to Z" + case .zToA: return "Z to A" + case .newest: return "Newest" + case .oldest: return "Oldest" + } + } + + static let all: [Sort] = [.recent, .aToZ, .zToA, .newest, .oldest] +} + +extension Sort { + var memoSortDescriptors: [SortDescriptor] { + switch self { + case .recent: + return [SortDescriptor(\.updatedAt, order: .reverse)] + case .aToZ: + return [SortDescriptor(\.title), SortDescriptor(\.updatedAt, order: .reverse)] + case .zToA: + return [SortDescriptor(\.title, order: .reverse), SortDescriptor(\.updatedAt, order: .reverse)] + case .newest: + return [SortDescriptor(\.createdAt, order: .reverse)] + case .oldest: + return [SortDescriptor(\.createdAt)] + } + } +}