Decouple source access from detail view types

This commit is contained in:
John Burwell 2026-05-29 13:44:25 -05:00
parent 3e7e3016e5
commit dce5af8a89
9 changed files with 23 additions and 22 deletions

View File

@ -0,0 +1,7 @@
import Foundation
struct DirectoryEntry: Identifiable, Hashable, Sendable {
let id = UUID()
let name: String
let isDirectory: Bool
}

View File

@ -187,7 +187,7 @@ final class SourceLibrary: ObservableObject, SourceScanSessionHosting, SourcePer
startScan(for: sourceID, mode: .fullScan)
}
func listContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryPreviewEntry] {
func listContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryEntry] {
try await sourceAccessMethod.listItemContents(for: item, in: source)
}

View File

@ -307,7 +307,7 @@ struct AppleMobileDeviceSourceAccess: ConnectedDeviceSourceAccessMethod {
}
}
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryPreviewEntry] {
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryEntry] {
guard case .connectedDevice(_, let container) = source.origin else {
return []
}
@ -325,7 +325,7 @@ struct AppleMobileDeviceSourceAccess: ConnectedDeviceSourceAccessMethod {
return entries
.map { entry in
let isDirectory = !NSString(string: entry).pathExtension.isEmpty ? false : true
return DirectoryPreviewEntry(name: entry, isDirectory: isDirectory)
return DirectoryEntry(name: entry, isDirectory: isDirectory)
}
.sorted { lhs, rhs in
if lhs.isDirectory != rhs.isDirectory {

View File

@ -26,7 +26,7 @@ protocol SourceAccessMethod: Sendable {
nonisolated func loadPreviewAssets(for items: [MinecraftContentItem], in source: MinecraftSource) async -> [MinecraftContentItem]
nonisolated func loadSize(for item: MinecraftContentItem, in source: MinecraftSource) async -> MinecraftContentItem
nonisolated func loadSizeAssets(for items: [MinecraftContentItem], in source: MinecraftSource) async -> [MinecraftContentItem]
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryPreviewEntry]
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryEntry]
nonisolated func materializeItem(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> URL
nonisolated func purgeCachedArtifacts(for source: MinecraftSource) async
}
@ -96,7 +96,7 @@ extension SourceAccessMethod {
return sizedItems
}
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryPreviewEntry] {
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryEntry] {
_ = source
_ = item
return []
@ -191,7 +191,7 @@ struct SourceAccessCoordinator: SourceAccessMethod {
return await accessMethod(for: source).loadSizeAssets(for: items, in: source)
}
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryPreviewEntry] {
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryEntry] {
return try await accessMethod(for: source).listItemContents(for: item, in: source)
}

View File

@ -104,7 +104,7 @@ struct LocalFolderSourceAccess: SourceAccessMethod {
return WorldScanner.loadSize(for: item)
}
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryPreviewEntry] {
nonisolated func listItemContents(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> [DirectoryEntry] {
_ = source
let fileManager = FileManager.default
let urls = try fileManager.contentsOfDirectory(
@ -116,7 +116,7 @@ struct LocalFolderSourceAccess: SourceAccessMethod {
return urls
.map { url in
let isDirectory = (try? url.resourceValues(forKeys: [.isDirectoryKey]).isDirectory) == true
return DirectoryPreviewEntry(name: url.lastPathComponent, isDirectory: isDirectory)
return DirectoryEntry(name: url.lastPathComponent, isDirectory: isDirectory)
}
.sorted { lhs, rhs in
if lhs.isDirectory != rhs.isDirectory {

View File

@ -1,12 +1,6 @@
import AppKit
import SwiftUI
struct DirectoryPreviewEntry: Identifiable {
let id = UUID()
let name: String
let isDirectory: Bool
}
struct ItemDetailColumnView: View {
let item: MinecraftContentItem?
let source: MinecraftSource?
@ -16,7 +10,7 @@ struct ItemDetailColumnView: View {
let worldsUsingPack: [MinecraftContentItem]
let backingPackInstances: [MinecraftContentItem]
let isSuspiciousPack: Bool
let contents: [DirectoryPreviewEntry]
let contents: [DirectoryEntry]
let directoryPreviewLimit: Int
let isEmpty: Bool
let isPerformingItemAction: Bool

View File

@ -12,7 +12,7 @@ struct ItemDetailView: View {
let worldsUsingPack: [MinecraftContentItem]
let backingPackInstances: [MinecraftContentItem]
let isSuspiciousPack: Bool
let contents: [DirectoryPreviewEntry]
let contents: [DirectoryEntry]
let directoryPreviewLimit: Int
let isPerformingItemAction: Bool
let areFileActionsEnabled: Bool

View File

@ -230,11 +230,11 @@ enum PreviewFixtures {
static let allSources = [primarySource, secondarySource]
static let directoryEntries = [
DirectoryPreviewEntry(name: "db", isDirectory: true),
DirectoryPreviewEntry(name: "level.dat", isDirectory: false),
DirectoryPreviewEntry(name: "levelname.txt", isDirectory: false),
DirectoryPreviewEntry(name: "world_icon.jpeg", isDirectory: false),
DirectoryPreviewEntry(name: "resource_packs", isDirectory: true)
DirectoryEntry(name: "db", isDirectory: true),
DirectoryEntry(name: "level.dat", isDirectory: false),
DirectoryEntry(name: "levelname.txt", isDirectory: false),
DirectoryEntry(name: "world_icon.jpeg", isDirectory: false),
DirectoryEntry(name: "resource_packs", isDirectory: true)
]
}

View File

@ -19,7 +19,7 @@ struct ContentView: View {
@State private var isPerformingItemAction = false
@State private var isShowingDeviceSourceSheet = false
@State private var sortMode: ItemSortMode = .name
@State private var directoryPreviewContents: [DirectoryPreviewEntry] = []
@State private var directoryPreviewContents: [DirectoryEntry] = []
private let connectedDeviceAccess: AppleMobileDeviceSourceAccess
private let deviceSourceFactory: ConnectedDeviceSourceFactory