73 lines
2.1 KiB
Swift
73 lines
2.1 KiB
Swift
|
|
import Foundation
|
||
|
|
import SaplingCore
|
||
|
|
|
||
|
|
@MainActor
|
||
|
|
public final class MarkdownDocumentSession: Identifiable, ObservableObject {
|
||
|
|
public let id: UUID
|
||
|
|
public let documentURL: URL
|
||
|
|
public let viewModel: HybridMarkdownEditorViewModel
|
||
|
|
|
||
|
|
public init(
|
||
|
|
id: UUID = UUID(),
|
||
|
|
documentURL: URL,
|
||
|
|
viewModel: HybridMarkdownEditorViewModel
|
||
|
|
) {
|
||
|
|
self.id = id
|
||
|
|
self.documentURL = documentURL
|
||
|
|
self.viewModel = viewModel
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@MainActor
|
||
|
|
public final class DocumentSessionStore: ObservableObject {
|
||
|
|
@Published public private(set) var sessions: [MarkdownDocumentSession]
|
||
|
|
@Published public private(set) var activeSession: MarkdownDocumentSession?
|
||
|
|
|
||
|
|
public init(sessions: [MarkdownDocumentSession] = []) {
|
||
|
|
self.sessions = sessions
|
||
|
|
self.activeSession = sessions.first
|
||
|
|
}
|
||
|
|
|
||
|
|
@discardableResult
|
||
|
|
public func openDocument(
|
||
|
|
at url: URL,
|
||
|
|
loadDocument: @MainActor (URL) throws -> MarkdownDocument = HybridMarkdownEditorViewModel.loadDocument(at:)
|
||
|
|
) throws -> MarkdownDocumentSession {
|
||
|
|
let key = sessionKey(for: url)
|
||
|
|
if let existingSession = sessions.first(where: { sessionKey(for: $0.documentURL) == key }) {
|
||
|
|
activeSession = existingSession
|
||
|
|
return existingSession
|
||
|
|
}
|
||
|
|
|
||
|
|
let document = try loadDocument(url)
|
||
|
|
let session = MarkdownDocumentSession(
|
||
|
|
documentURL: url,
|
||
|
|
viewModel: HybridMarkdownEditorViewModel(document: document)
|
||
|
|
)
|
||
|
|
sessions.append(session)
|
||
|
|
activeSession = session
|
||
|
|
return session
|
||
|
|
}
|
||
|
|
|
||
|
|
@discardableResult
|
||
|
|
public func activateDocument(at url: URL) -> Bool {
|
||
|
|
let key = sessionKey(for: url)
|
||
|
|
guard let session = sessions.first(where: { sessionKey(for: $0.documentURL) == key }) else {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
activeSession = session
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
|
||
|
|
public func updateActiveSessionFromViewModel() {
|
||
|
|
guard let activeSession else { return }
|
||
|
|
objectWillChange.send()
|
||
|
|
activeSession.objectWillChange.send()
|
||
|
|
}
|
||
|
|
|
||
|
|
private func sessionKey(for url: URL) -> String {
|
||
|
|
url.standardizedFileURL.path
|
||
|
|
}
|
||
|
|
}
|