diff --git a/World Manager for Minecraft/Services/AppSupport/Scanning/ContentItemFileFacts.swift b/World Manager for Minecraft/Services/AppSupport/Scanning/ContentItemFileFacts.swift new file mode 100644 index 0000000..981d497 --- /dev/null +++ b/World Manager for Minecraft/Services/AppSupport/Scanning/ContentItemFileFacts.swift @@ -0,0 +1,35 @@ +import Foundation + +struct ContentItemFileFacts: Sendable { + let storageFormatLabel: String + let createdDateText: String + let approximateAgeText: String? + + nonisolated init(item: MinecraftContentItem, now: Date = .now, fileManager: FileManager = .default) { + let createdDate = try? item.folderURL.resourceValues(forKeys: [.creationDateKey]).creationDate + self.createdDateText = createdDate?.formatted(date: .abbreviated, time: .omitted) ?? "Unknown" + + if let createdDate { + let components = Calendar.current.dateComponents([.year, .month], from: createdDate, to: now) + if let year = components.year, year > 0 { + self.approximateAgeText = year == 1 ? "About 1 year old" : "About \(year) years old" + } else if let month = components.month, month > 0 { + self.approximateAgeText = month == 1 ? "About 1 month old" : "About \(month) months old" + } else { + self.approximateAgeText = "Recently created" + } + } else { + self.approximateAgeText = nil + } + + switch item.contentType { + case .world: + let levelDBURL = item.folderURL.appendingPathComponent("db", isDirectory: true) + self.storageFormatLabel = fileManager.fileExists(atPath: levelDBURL.path) + ? "LevelDB world storage" + : "Flat-file world storage" + case .behaviorPack, .resourcePack, .skinPack, .worldTemplate: + self.storageFormatLabel = "Manifest-based package" + } + } +} diff --git a/World Manager for Minecraft/UI/Detail/ItemDetailView.swift b/World Manager for Minecraft/UI/Detail/ItemDetailView.swift index 16257ce..ee53a9f 100644 --- a/World Manager for Minecraft/UI/Detail/ItemDetailView.swift +++ b/World Manager for Minecraft/UI/Detail/ItemDetailView.swift @@ -218,7 +218,7 @@ struct ItemDetailView: View { detailRow(title: "Name", value: item.displayName) detailValueRow(title: "Size", value: sizeText) detailValueRow(title: item.displayDateLabel, value: displayDateText) - detailValueRow(title: "Created", value: createdDateText) + detailValueRow(title: "Created", value: fileFacts.createdDateText) if let gameMode = item.worldMetadata?.gameMode { detailValueRow(title: "Game Mode", value: gameMode) @@ -339,8 +339,8 @@ struct ItemDetailView: View { } private var storageHighlights: [String] { - var highlights = [storageFormatLabel] - if let approximateAgeText { + var highlights = [fileFacts.storageFormatLabel] + if let approximateAgeText = fileFacts.approximateAgeText { highlights.append(approximateAgeText) } return highlights @@ -416,35 +416,8 @@ struct ItemDetailView: View { } } - private var storageFormatLabel: String { - switch item.contentType { - case .world: - return FileManager.default.fileExists(atPath: item.folderURL.appendingPathComponent("db", isDirectory: true).path) - ? "LevelDB world storage" - : "Flat-file world storage" - case .behaviorPack, .resourcePack, .skinPack, .worldTemplate: - return "Manifest-based package" - } - } - - private var createdDateText: String { - (try? item.folderURL.resourceValues(forKeys: [.creationDateKey]).creationDate)? - .formatted(date: .abbreviated, time: .omitted) ?? "Unknown" - } - - private var approximateAgeText: String? { - guard let createdDate = try? item.folderURL.resourceValues(forKeys: [.creationDateKey]).creationDate else { - return nil - } - - let components = Calendar.current.dateComponents([.year, .month], from: createdDate, to: .now) - if let year = components.year, year > 0 { - return year == 1 ? "About 1 year old" : "About \(year) years old" - } - if let month = components.month, month > 0 { - return month == 1 ? "About 1 month old" : "About \(month) months old" - } - return "Recently created" + private var fileFacts: ContentItemFileFacts { + ContentItemFileFacts(item: item) } private var visibleContentsCountText: String {