Decouple source access from detail view types
This commit is contained in:
parent
3e7e3016e5
commit
dce5af8a89
@ -0,0 +1,7 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct DirectoryEntry: Identifiable, Hashable, Sendable {
|
||||||
|
let id = UUID()
|
||||||
|
let name: String
|
||||||
|
let isDirectory: Bool
|
||||||
|
}
|
||||||
@ -187,7 +187,7 @@ final class SourceLibrary: ObservableObject, SourceScanSessionHosting, SourcePer
|
|||||||
startScan(for: sourceID, mode: .fullScan)
|
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)
|
try await sourceAccessMethod.listItemContents(for: item, in: source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 {
|
guard case .connectedDevice(_, let container) = source.origin else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@ -325,7 +325,7 @@ struct AppleMobileDeviceSourceAccess: ConnectedDeviceSourceAccessMethod {
|
|||||||
return entries
|
return entries
|
||||||
.map { entry in
|
.map { entry in
|
||||||
let isDirectory = !NSString(string: entry).pathExtension.isEmpty ? false : true
|
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
|
.sorted { lhs, rhs in
|
||||||
if lhs.isDirectory != rhs.isDirectory {
|
if lhs.isDirectory != rhs.isDirectory {
|
||||||
|
|||||||
@ -26,7 +26,7 @@ protocol SourceAccessMethod: Sendable {
|
|||||||
nonisolated func loadPreviewAssets(for items: [MinecraftContentItem], in source: MinecraftSource) async -> [MinecraftContentItem]
|
nonisolated func loadPreviewAssets(for items: [MinecraftContentItem], in source: MinecraftSource) async -> [MinecraftContentItem]
|
||||||
nonisolated func loadSize(for item: 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 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 materializeItem(for item: MinecraftContentItem, in source: MinecraftSource) async throws -> URL
|
||||||
nonisolated func purgeCachedArtifacts(for source: MinecraftSource) async
|
nonisolated func purgeCachedArtifacts(for source: MinecraftSource) async
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ extension SourceAccessMethod {
|
|||||||
return sizedItems
|
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
|
_ = source
|
||||||
_ = item
|
_ = item
|
||||||
return []
|
return []
|
||||||
@ -191,7 +191,7 @@ struct SourceAccessCoordinator: SourceAccessMethod {
|
|||||||
return await accessMethod(for: source).loadSizeAssets(for: items, in: source)
|
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)
|
return try await accessMethod(for: source).listItemContents(for: item, in: source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -104,7 +104,7 @@ struct LocalFolderSourceAccess: SourceAccessMethod {
|
|||||||
return WorldScanner.loadSize(for: item)
|
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
|
_ = source
|
||||||
let fileManager = FileManager.default
|
let fileManager = FileManager.default
|
||||||
let urls = try fileManager.contentsOfDirectory(
|
let urls = try fileManager.contentsOfDirectory(
|
||||||
@ -116,7 +116,7 @@ struct LocalFolderSourceAccess: SourceAccessMethod {
|
|||||||
return urls
|
return urls
|
||||||
.map { url in
|
.map { url in
|
||||||
let isDirectory = (try? url.resourceValues(forKeys: [.isDirectoryKey]).isDirectory) == true
|
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
|
.sorted { lhs, rhs in
|
||||||
if lhs.isDirectory != rhs.isDirectory {
|
if lhs.isDirectory != rhs.isDirectory {
|
||||||
|
|||||||
@ -1,12 +1,6 @@
|
|||||||
import AppKit
|
import AppKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct DirectoryPreviewEntry: Identifiable {
|
|
||||||
let id = UUID()
|
|
||||||
let name: String
|
|
||||||
let isDirectory: Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ItemDetailColumnView: View {
|
struct ItemDetailColumnView: View {
|
||||||
let item: MinecraftContentItem?
|
let item: MinecraftContentItem?
|
||||||
let source: MinecraftSource?
|
let source: MinecraftSource?
|
||||||
@ -16,7 +10,7 @@ struct ItemDetailColumnView: View {
|
|||||||
let worldsUsingPack: [MinecraftContentItem]
|
let worldsUsingPack: [MinecraftContentItem]
|
||||||
let backingPackInstances: [MinecraftContentItem]
|
let backingPackInstances: [MinecraftContentItem]
|
||||||
let isSuspiciousPack: Bool
|
let isSuspiciousPack: Bool
|
||||||
let contents: [DirectoryPreviewEntry]
|
let contents: [DirectoryEntry]
|
||||||
let directoryPreviewLimit: Int
|
let directoryPreviewLimit: Int
|
||||||
let isEmpty: Bool
|
let isEmpty: Bool
|
||||||
let isPerformingItemAction: Bool
|
let isPerformingItemAction: Bool
|
||||||
|
|||||||
@ -12,7 +12,7 @@ struct ItemDetailView: View {
|
|||||||
let worldsUsingPack: [MinecraftContentItem]
|
let worldsUsingPack: [MinecraftContentItem]
|
||||||
let backingPackInstances: [MinecraftContentItem]
|
let backingPackInstances: [MinecraftContentItem]
|
||||||
let isSuspiciousPack: Bool
|
let isSuspiciousPack: Bool
|
||||||
let contents: [DirectoryPreviewEntry]
|
let contents: [DirectoryEntry]
|
||||||
let directoryPreviewLimit: Int
|
let directoryPreviewLimit: Int
|
||||||
let isPerformingItemAction: Bool
|
let isPerformingItemAction: Bool
|
||||||
let areFileActionsEnabled: Bool
|
let areFileActionsEnabled: Bool
|
||||||
|
|||||||
@ -230,11 +230,11 @@ enum PreviewFixtures {
|
|||||||
static let allSources = [primarySource, secondarySource]
|
static let allSources = [primarySource, secondarySource]
|
||||||
|
|
||||||
static let directoryEntries = [
|
static let directoryEntries = [
|
||||||
DirectoryPreviewEntry(name: "db", isDirectory: true),
|
DirectoryEntry(name: "db", isDirectory: true),
|
||||||
DirectoryPreviewEntry(name: "level.dat", isDirectory: false),
|
DirectoryEntry(name: "level.dat", isDirectory: false),
|
||||||
DirectoryPreviewEntry(name: "levelname.txt", isDirectory: false),
|
DirectoryEntry(name: "levelname.txt", isDirectory: false),
|
||||||
DirectoryPreviewEntry(name: "world_icon.jpeg", isDirectory: false),
|
DirectoryEntry(name: "world_icon.jpeg", isDirectory: false),
|
||||||
DirectoryPreviewEntry(name: "resource_packs", isDirectory: true)
|
DirectoryEntry(name: "resource_packs", isDirectory: true)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ struct ContentView: View {
|
|||||||
@State private var isPerformingItemAction = false
|
@State private var isPerformingItemAction = false
|
||||||
@State private var isShowingDeviceSourceSheet = false
|
@State private var isShowingDeviceSourceSheet = false
|
||||||
@State private var sortMode: ItemSortMode = .name
|
@State private var sortMode: ItemSortMode = .name
|
||||||
@State private var directoryPreviewContents: [DirectoryPreviewEntry] = []
|
@State private var directoryPreviewContents: [DirectoryEntry] = []
|
||||||
|
|
||||||
private let connectedDeviceAccess: AppleMobileDeviceSourceAccess
|
private let connectedDeviceAccess: AppleMobileDeviceSourceAccess
|
||||||
private let deviceSourceFactory: ConnectedDeviceSourceFactory
|
private let deviceSourceFactory: ConnectedDeviceSourceFactory
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user