Files
shotdeck/Sources/ShotdeckCore/Model/CaptureSession.swift
T

74 lines
2.2 KiB
Swift

import Foundation
public enum SessionState: String, Codable, Sendable {
case open // accepting captures
case archived // its PDF has been built and sent; kept forever, never deleted
}
/// The manifest persisted as session.json alongside the PNGs.
public struct CaptureSession: Codable, Sendable, Identifiable, Equatable {
public let id: UUID
public let createdAt: Date
public private(set) var state: SessionState
public private(set) var captures: [Capture]
/// Set when the PDF is built, so a re-send reuses the same file.
public private(set) var pdfFileName: String?
public init(
id: UUID,
createdAt: Date,
state: SessionState,
captures: [Capture],
pdfFileName: String?
) {
self.id = id
self.createdAt = createdAt
self.state = state
self.captures = captures
self.pdfFileName = pdfFileName
}
public var isEmpty: Bool {
captures.isEmpty
}
/// max(sequence)+1, or 1 when empty.
public var nextSequence: Int {
(captures.map(\.sequence).max() ?? 0) + 1
}
/// Value-semantic: returns a new session; does not mutate `self`.
public func appending(_ capture: Capture) -> CaptureSession {
CaptureSession(
id: id,
createdAt: createdAt,
state: state,
captures: captures + [capture],
pdfFileName: pdfFileName
)
}
/// Value-semantic: returns a new session; does not mutate `self`.
/// Sequence numbers of remaining captures are left unchanged.
public func removing(captureID: UUID) -> CaptureSession {
CaptureSession(
id: id,
createdAt: createdAt,
state: state,
captures: captures.filter { $0.id != captureID },
pdfFileName: pdfFileName
)
}
/// Value-semantic: returns a new session; does not mutate `self`.
public func markArchived(pdfFileName: String) -> CaptureSession {
CaptureSession(
id: id,
createdAt: createdAt,
state: .archived,
captures: captures,
pdfFileName: pdfFileName
)
}
}