- API, Mac client
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import Foundation
|
||||
|
||||
struct DraftRecord: Codable, Identifiable {
|
||||
var id: String { item.slug.isEmpty ? item.title : item.slug }
|
||||
var serverURL: String
|
||||
var savedAt: Date
|
||||
var item: ContentItem
|
||||
var markdown: String
|
||||
}
|
||||
|
||||
final class DraftStore {
|
||||
private let folder: URL
|
||||
|
||||
init() {
|
||||
let base = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first
|
||||
?? URL(fileURLWithPath: NSTemporaryDirectory())
|
||||
folder = base.appendingPathComponent("TCMS Mac Client", isDirectory: true)
|
||||
try? FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
|
||||
}
|
||||
|
||||
func save(item: ContentItem, markdown: String, serverURL: String) throws {
|
||||
let record = DraftRecord(serverURL: serverURL, savedAt: Date(), item: item, markdown: markdown)
|
||||
let data = try JSONEncoder.tcms.encode(record)
|
||||
try data.write(to: fileURL(for: record.id), options: .atomic)
|
||||
}
|
||||
|
||||
func remove(id: String) {
|
||||
try? FileManager.default.removeItem(at: fileURL(for: id))
|
||||
}
|
||||
|
||||
func loadAll(serverURL: String) -> [DraftRecord] {
|
||||
let urls = (try? FileManager.default.contentsOfDirectory(at: folder, includingPropertiesForKeys: nil)) ?? []
|
||||
return urls.compactMap { url in
|
||||
guard let data = try? Data(contentsOf: url),
|
||||
let record = try? JSONDecoder.tcms.decode(DraftRecord.self, from: data),
|
||||
record.serverURL == serverURL else {
|
||||
return nil
|
||||
}
|
||||
return record
|
||||
}
|
||||
.sorted { $0.savedAt > $1.savedAt }
|
||||
}
|
||||
|
||||
private func fileURL(for id: String) -> URL {
|
||||
let safe = id.replacingOccurrences(of: "[^A-Za-z0-9._-]+", with: "-", options: .regularExpression)
|
||||
return folder.appendingPathComponent(safe.isEmpty ? "untitled" : safe).appendingPathExtension("json")
|
||||
}
|
||||
}
|
||||
|
||||
private extension JSONEncoder {
|
||||
static var tcms: JSONEncoder {
|
||||
let encoder = JSONEncoder()
|
||||
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
|
||||
encoder.dateEncodingStrategy = .iso8601
|
||||
return encoder
|
||||
}
|
||||
}
|
||||
|
||||
private extension JSONDecoder {
|
||||
static var tcms: JSONDecoder {
|
||||
let decoder = JSONDecoder()
|
||||
decoder.dateDecodingStrategy = .iso8601
|
||||
return decoder
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user