Add tag overview, improve assets

This commit is contained in:
Christoph Hagen
2024-12-15 21:20:12 +01:00
parent 8a3a0f1797
commit 1e67a99866
59 changed files with 1301 additions and 480 deletions

View File

@ -306,6 +306,18 @@ final class Storage {
try writeIfChanged(fileDescriptions, to: fileDescriptionFilename)
}
// MARK: Tag overview
private let tagOverviewFileName = "tag-overview.json"
func loadTagOverview() throws -> TagOverviewFile? {
try read(at: tagOverviewFileName)
}
func save(tagOverview: TagOverviewFile?) throws {
try writeIfChanged(tagOverview, to: tagOverviewFileName)
}
// MARK: Files
private let filesFolderName = "files"
@ -499,6 +511,19 @@ final class Storage {
}
}
/**
Write the data of an encodable value to a relative path in the content folder,
or delete the file if nil is passed.
- Note: This function requires a security scope for the content path
*/
private func writeIfChanged<T>(_ value: T?, to relativePath: String) throws where T: Encodable {
guard let value else {
try deleteFile(at: relativePath)
return
}
return try writeIfChanged(value, to: relativePath)
}
/**
Write the data of an encodable value to a relative path in the content folder
- Note: This function requires a security scope for the content path
@ -547,6 +572,16 @@ final class Storage {
}
}
/**
Read an object from a file, if the file exists
*/
private func read<T>(at relativePath: String) throws -> T? where T: Decodable {
guard let data = try readData(at: relativePath) else {
return nil
}
return try decoder.decode(T.self, from: data)
}
/**
- Note: This function requires a security scope for the content path
@ -632,4 +667,13 @@ final class Storage {
try fm.copyItem(at: file, to: destination)
}
}
private func deleteFile(at relativePath: String) throws {
try withScopedContent(file: relativePath) { destination in
guard fm.fileExists(atPath: destination.path()) else {
return
}
try fm.removeItem(at: destination)
}
}
}