its whats on the tin; culls raw photos
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: redo import menu

+40
+40
cull/CullApp.swift
··· 4 4 struct CullApp: App { 5 5 @State private var session = CullSession() 6 6 @State private var thumbnailCache = ThumbnailCache() 7 + @AppStorage("recentFolders") private var recentFoldersData: Data = Data() 8 + 9 + private var recentFolders: [URL] { 10 + (try? JSONDecoder().decode([String].self, from: recentFoldersData))?.compactMap { URL(fileURLWithPath: $0) } ?? [] 11 + } 12 + 13 + private func addRecentFolder(_ url: URL) { 14 + var paths = (try? JSONDecoder().decode([String].self, from: recentFoldersData)) ?? [] 15 + paths.removeAll { $0 == url.path } 16 + paths.insert(url.path, at: 0) 17 + if paths.count > 10 { paths = Array(paths.prefix(10)) } 18 + recentFoldersData = (try? JSONEncoder().encode(paths)) ?? Data() 19 + } 7 20 8 21 var body: some Scene { 9 22 WindowGroup("Cull") { 10 23 ContentView() 11 24 .environment(session) 12 25 .environment(thumbnailCache) 26 + .onReceive(NotificationCenter.default.publisher(for: .openFolder)) { notification in 27 + if let url = notification.object as? URL { 28 + addRecentFolder(url) 29 + } 30 + } 13 31 } 14 32 .windowStyle(.automatic) 15 33 .commands { ··· 19 37 openFolder() 20 38 } 21 39 .keyboardShortcut("o") 40 + 41 + Toggle("Include Subfolders", isOn: Binding( 42 + get: { session.importRecursive }, 43 + set: { session.importRecursive = $0 } 44 + )) 45 + 46 + Menu("Open Recent") { 47 + ForEach(recentFolders, id: \.path) { url in 48 + Button(url.lastPathComponent) { 49 + addRecentFolder(url) 50 + NotificationCenter.default.post(name: .openFolder, object: url) 51 + } 52 + } 53 + 54 + if !recentFolders.isEmpty { 55 + Divider() 56 + Button("Clear Menu") { 57 + recentFoldersData = Data() 58 + } 59 + } 60 + } 61 + .disabled(recentFolders.isEmpty) 22 62 23 63 Divider() 24 64