Files
luma/Luma/LumaProject.swift
Ole André Vadla Ravnås f75755911e macos: Autosave open documents in place
Mark the document edited on every working-copy commit so
AppKit autosave-in-place writes the file. Drop
ProjectAutosaver and its onDisappear flush, which lost edits
made after reopening a saved document.
2026-06-02 15:23:12 +02:00

68 lines
2.8 KiB
Swift

import Foundation
import LumaCore
import SwiftUI
import UniformTypeIdentifiers
struct LumaProject: FileDocument {
static let readableContentTypes: [UTType] = [UTType(exportedAs: "re.frida.luma")]
static let writableContentTypes: [UTType] = readableContentTypes
var workingProjectURL: URL
/// Bumped whenever the working-copy database commits. The value is
/// never read back; mutating it is what tells SwiftUI the document is
/// edited so autosave-in-place writes a fresh snapshot.
var unsavedChangeCount = 0
init() {
let doc = (try? LumaDocumentLoader.makeUntitled(in: LumaAppPaths.shared.untitledDirectory))
?? LumaDocument(storage: .untitled(
LumaAppPaths.shared.untitledDirectory
.appendingPathComponent("Untitled-\(UUID().uuidString).luma")
))
self.workingProjectURL = doc.url
Self.ensureProjectExists(at: workingProjectURL)
}
init(configuration: ReadConfiguration) throws {
guard configuration.file.isDirectory,
configuration.file.fileWrappers?["db.sqlite"] != nil
else {
throw CocoaError(.fileReadCorruptFile)
}
self.workingProjectURL = Self.uniqueWorkingCopyURL()
try copyFileWrapper(configuration.file, to: workingProjectURL)
Self.ensureProjectExists(at: workingProjectURL)
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let staging = FileManager.default.temporaryDirectory
.appendingPathComponent("luma-save-\(UUID().uuidString).luma", isDirectory: true)
defer { try? FileManager.default.removeItem(at: staging) }
try ProjectSnapshot.snapshot(from: workingProjectURL, to: staging)
return try FileWrapper(url: staging, options: .immediate)
}
private func copyFileWrapper(_ wrapper: FileWrapper, to destination: URL) throws {
let fm = FileManager.default
if fm.fileExists(atPath: destination.path) {
try fm.removeItem(at: destination)
}
try fm.createDirectory(at: destination, withIntermediateDirectories: true)
try wrapper.write(to: destination, options: [.atomic, .withNameUpdating], originalContentsURL: nil)
}
private static func ensureProjectExists(at url: URL) {
let fm = FileManager.default
try? fm.createDirectory(at: url, withIntermediateDirectories: true)
try? fm.createDirectory(at: url.appendingPathComponent("traces", isDirectory: true), withIntermediateDirectories: true)
}
private static func uniqueWorkingCopyURL() -> URL {
let dir = LumaAppPaths.shared.workingDirectory
try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
return dir.appendingPathComponent("Working-\(UUID().uuidString).luma")
}
}