Add tag overview, improve assets
This commit is contained in:
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user