Skip to content

Commit

Permalink
refactor: Track identifiers in the grid view and inject the scene mod…
Browse files Browse the repository at this point in the history
…el (#66)
  • Loading branch information
jbmorley authored Feb 24, 2024
1 parent 7c3be78 commit 0f3b32b
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 30 deletions.
4 changes: 2 additions & 2 deletions Folders/Models/ApplicationModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,11 @@ extension ApplicationModel: StoreViewDelegate {
}
}

func storeView(_ storeView: StoreView, didInsertURL url: URL, atIndex: Int) {
func storeView(_ storeView: StoreView, didInsertFile file: Details, atIndex: Int) {
self.lookup = sidebarItems(for: storeView.files)
}

func storeView(_ storeView: StoreView, didRemoveURL url: URL, atIndex: Int) {
func storeView(_ storeView: StoreView, didRemoveFileWithIdentifier identifier: Details.Identifier, atIndex: Int) {
self.lookup = sidebarItems(for: storeView.files)
}

Expand Down
4 changes: 4 additions & 0 deletions Folders/Models/Details.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ struct Details: Hashable {
struct Identifier: Equatable, Hashable {
let ownerURL: URL
let url: URL

var parent: Identifier {
return Identifier(ownerURL: ownerURL, url: url.deletingLastPathComponent())
}
}

let identifier: Identifier
Expand Down
8 changes: 4 additions & 4 deletions Folders/Utilities/StoreView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ protocol StoreViewDelegate: NSObject {

func storeViewDidUpdate(_ storeView: StoreView)
// TODO: Expose the details directly in the update.
func storeView(_ storeView: StoreView, didInsertURL url: URL, atIndex: Int)
func storeView(_ storeView: StoreView, didRemoveURL url: URL, atIndex: Int)
func storeView(_ storeView: StoreView, didInsertFile file: Details, atIndex: Int)
func storeView(_ storeView: StoreView, didRemoveFileWithIdentifier identifier: Details.Identifier, atIndex: Int)

}

Expand Down Expand Up @@ -95,7 +95,7 @@ class StoreView: NSObject, StoreObserver {
return self.sort.compare(file, $0)
}
self.files.insert(file, at: index)
self.delegate?.storeView(self, didInsertURL: file.url, atIndex: index)
self.delegate?.storeView(self, didInsertFile: file, atIndex: index)
}
} else {
for file in files {
Expand All @@ -122,7 +122,7 @@ class StoreView: NSObject, StoreObserver {
continue
}
self.files.remove(at: index)
self.delegate?.storeView(self, didRemoveURL: identifier.url, atIndex: index)
self.delegate?.storeView(self, didRemoveFileWithIdentifier: identifier, atIndex: index)
}
} else {
for identifier in identifiers {
Expand Down
3 changes: 2 additions & 1 deletion Folders/Views/FolderView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import SwiftUI
struct FolderView: View {

@EnvironmentObject var applicationModel: ApplicationModel
@EnvironmentObject var sceneModel: SceneModel

@Environment(\.openURL) var openURL

Expand All @@ -41,7 +42,7 @@ struct FolderView: View {

var body: some View {
VStack(alignment: .leading, spacing: 0) {
GridView(store: applicationModel.store, ownerURL: ownerURL, directoryURL: url)
GridView(sceneModel: sceneModel, store: applicationModel.store, ownerURL: ownerURL, directoryURL: url)
if let url = folderModel.settings?.url {
Divider()
HStack {
Expand Down
51 changes: 28 additions & 23 deletions Folders/Views/GridView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ import QuickLookUI

struct GridView: NSViewRepresentable {

let sceneModel: SceneModel
let store: Store
let ownerURL: URL
let directoryURL: URL

func makeNSView(context: Context) -> InnerGridView {
return InnerGridView(store: store, ownerURL: ownerURL, directoryURL: directoryURL)
return InnerGridView(sceneModel: sceneModel, store: store, ownerURL: ownerURL, directoryURL: directoryURL)
}

func updateNSView(_ nsView: NSViewType, context: Context) {
Expand All @@ -42,15 +43,16 @@ struct GridView: NSViewRepresentable {

class InnerGridView: NSView {

let sceneModel: SceneModel
let storeView: StoreView
var previewPanel: QLPreviewPanel?

enum Section {
case none
}

typealias Snapshot = NSDiffableDataSourceSnapshot<Section, URL>
typealias DataSource = NSCollectionViewDiffableDataSource<Section, URL>
typealias Snapshot = NSDiffableDataSourceSnapshot<Section, Details.Identifier>
typealias DataSource = NSCollectionViewDiffableDataSource<Section, Details.Identifier>
typealias Cell = ShortcutItemView

private let scrollView: NSScrollView
Expand All @@ -63,7 +65,8 @@ class InnerGridView: NSView {
}
}

init(store: Store, ownerURL: URL, directoryURL: URL) {
init(sceneModel: SceneModel, store: Store, ownerURL: URL, directoryURL: URL) {
self.sceneModel = sceneModel
let filter: Filter = .owner(ownerURL) && .parent(directoryURL) && (.conforms(to: .pdf) || .conforms(to: .jpeg) || .conforms(to: .gif) || .conforms(to: .png) || .conforms(to: .video) || .conforms(to: .mpeg4Movie) || .conforms(to: .cbz) || .conforms(to: .stl) || .conforms(to: .mp3) || .conforms(to: .tap))
self.storeView = StoreView(store: store, filter: filter, sort: .displayNameDescending)

Expand Down Expand Up @@ -94,7 +97,7 @@ class InnerGridView: NSView {
for: indexPath) as? ShortcutItemView else {
return ShortcutItemView()
}
view.configure(url: item)
view.configure(url: item.url)
return view
}

Expand Down Expand Up @@ -151,8 +154,8 @@ extension InnerGridView: QLPreviewPanelDataSource, QLPreviewPanelDelegate {
}

func previewPanel(_ panel: QLPreviewPanel!, previewItemAt index: Int) -> QLPreviewItem! {
let url = dataSource.itemIdentifier(for: activeSelectionIndexPath!)!
return PreviewItem(url: url)
let identifier = dataSource.itemIdentifier(for: activeSelectionIndexPath!)!
return PreviewItem(url: identifier.url)
}

func previewPanel(_ panel: QLPreviewPanel!, handle event: NSEvent!) -> Bool {
Expand All @@ -173,12 +176,12 @@ extension InnerGridView: StoreViewDelegate {
func storeViewDidUpdate(_ storeView: StoreView) {
var snapshot = Snapshot()
snapshot.appendSections([.none])
snapshot.appendItems(storeView.files.map({ $0.url }), toSection: Section.none)
snapshot.appendItems(storeView.files.map({ $0.identifier }), toSection: Section.none)
dataSource.apply(snapshot, animatingDifferences: false)
}

// TODO: Insert details.
func storeView(_ storeView: StoreView, didInsertURL url: URL, atIndex index: Int) {
func storeView(_ storeView: StoreView, didInsertFile file: Details, atIndex index: Int) {
// TODO: Insert in the correct place.
// TODO: We may need to rate-limit these updates.
var snapshot = dataSource.snapshot()
Expand All @@ -188,18 +191,18 @@ extension InnerGridView: StoreViewDelegate {
}

if index >= snapshot.itemIdentifiers.count {
snapshot.appendItems([url])
snapshot.appendItems([file.identifier])
} else {
let beforeItem = snapshot.itemIdentifiers[index]
snapshot.insertItems([url], beforeItem: beforeItem)
snapshot.insertItems([file.identifier], beforeItem: beforeItem)
}

dataSource.apply(snapshot, animatingDifferences: true)
}

func storeView(_ storeView: StoreView, didRemoveURL url: URL, atIndex: Int) {
func storeView(_ storeView: StoreView, didRemoveFileWithIdentifier identifier: Details.Identifier, atIndex: Int) {
var snapshot = dataSource.snapshot()
snapshot.deleteItems([url])
snapshot.deleteItems([identifier])
dataSource.apply(snapshot, animatingDifferences: true)
}

Expand All @@ -208,28 +211,30 @@ extension InnerGridView: StoreViewDelegate {
extension InnerGridView: InteractiveCollectionViewDelegate {

@objc func reveal(sender: NSMenuItem) {
guard let urls = sender.representedObject as? [URL] else {
guard let identifiers = sender.representedObject as? [Details.Identifier] else {
return
}
for url in urls {
NSWorkspace.shared.reveal(url)
// TODO: Scene.
for identifier in identifiers {
NSWorkspace.shared.reveal(identifier.url)
}
}

@objc func setWallpaper(sender: NSMenuItem) {
guard let urls = sender.representedObject as? [URL] else {
guard let identifiers = sender.representedObject as? [Details.Identifier] else {
return
}
guard let screen = window?.screen else {
return
}
for url in urls {
try? NSWorkspace.shared.setDesktopImageURL(url, for: screen)
// TODO: SceneModel or ApplicationModel?
for identifier in identifiers {
try? NSWorkspace.shared.setDesktopImageURL(identifier.url, for: screen)
}
}

@objc func preview(sender: NSMenuItem) {
guard let urls = sender.representedObject as? [URL] else {
guard let urls = sender.representedObject as? [Details.Identifier] else {
return
}
showPreview()
Expand Down Expand Up @@ -287,9 +292,9 @@ extension InnerGridView: InteractiveCollectionViewDelegate {
}

func customCollectionView(_ customCollectionView: InteractiveCollectionView, didDoubleClickSelection selection: Set<IndexPath>) {
let urls = dataSource.itemIdentifiers(for: selection)
for url in urls {
NSWorkspace.shared.open(url)
let identifiers = dataSource.itemIdentifiers(for: selection)
for identifier in identifiers {
NSWorkspace.shared.open(identifier.url)
}
}

Expand Down
1 change: 1 addition & 0 deletions Folders/Views/LibraryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct LibraryView: View {
}
}
}
.environmentObject(sceneModel)
}

}

0 comments on commit 0f3b32b

Please sign in to comment.