Files
Termind/Frameworks/TermindApplication/FeatureModels/SnippetLibraryModel.swift
T
Kaede Akino b3066afe77 feat(snippets): share cards and add color selection
Reuse card content across macOS and iOS with platform-sized icons and matching card heights. Add the shared Color field below Package and preserve selection, drag, and execution behavior.

Migrate stored snippets to V51 and write color in Vault V2 while retaining V1 decoding and guarding against lossy V1 writes.

Validation: macOS focused snippet, migration, architecture, and localization tests pass; 30 iOS focused tests pass; Swift format and localization checks pass. Full macOS testing also reports failures in unchanged KeyExport, MCP, and Agent suites.
2026-10-04 12:25:52 +08:00

67 lines
2.9 KiB
Swift

import Foundation
import TermindDomain
import struct TermindDomain.Host
/// The Snippets feature's deliberately narrow view of the shared vault.
@Observable
public final class SnippetLibraryModel {
private let library: HostLibraryModel
public init(library: HostLibraryModel) {
self.library = library
}
public var hosts: [Host] { library.hosts }
public var snippets: [Snippet] { library.snippets }
public var snippetPackages: [SnippetPackage] { library.snippetPackages }
public var rootSnippetPackages: [SnippetPackage] { library.rootSnippetPackages }
public var isSnippetsUngroupedExpanded: Bool { library.isSnippetsUngroupedExpanded }
public func snippetPackage(_ id: SnippetPackage.ID) -> SnippetPackage? {
library.snippetPackage(id)
}
public func isSnippetPackageExpanded(_ id: SnippetPackage.ID) -> Bool {
library.isSnippetPackageExpanded(id)
}
public func childSnippetPackages(of parent: SnippetPackage.ID) -> [SnippetPackage] {
library.childSnippetPackages(of: parent)
}
public func descendantSnippetPackages(of parent: SnippetPackage.ID) -> [SnippetPackage] {
library.descendantSnippetPackages(of: parent)
}
public func snippets(in package: SnippetPackage.ID?) -> [Snippet] { library.snippets(in: package) }
public func snippetPackagePath(_ packageID: SnippetPackage.ID?) -> String? {
library.snippetPackagePath(packageID)
}
public func modifiedAt(for snippetID: Snippet.ID) -> Date? {
library.snippetModifiedAt(snippetID)
}
public func searchSnippets(_ query: String) -> [Snippet] { library.searchSnippets(query) }
public func searchHosts(_ query: String) -> [Host] { library.hosts(matching: query, for: .snippetExecution) }
public func validTargetIDs(for snippet: Snippet) -> [Host.ID] {
let wanted = Set(snippet.targetHostIDs)
return searchHosts("").filter { wanted.contains($0.id) }.map(\.id)
}
public func loginAddress(for host: Host) -> String { library.loginAddress(for: host) }
public func setSnippetPackageExpanded(_ expanded: Bool, for packageID: SnippetPackage.ID) {
library.setSnippetPackageExpanded(expanded, for: packageID)
}
public func setSnippetsUngroupedExpanded(_ expanded: Bool) {
library.setSnippetsUngroupedExpanded(expanded)
}
public func upsert(_ snippet: Snippet) { library.upsert(snippet) }
public func upsert(_ package: SnippetPackage) { library.upsert(package) }
public func delete(snippetIDs: [Snippet.ID]) { library.delete(snippetIDs: snippetIDs) }
public func delete(snippetPackageID: SnippetPackage.ID, keepSnippets: Bool) {
library.delete(snippetPackageID: snippetPackageID, keepSnippets: keepSnippets)
}
public func move(
snippetIDs: [Snippet.ID], into packageID: SnippetPackage.ID?,
before next: Snippet.ID? = nil
) {
library.move(snippetIDs: snippetIDs, into: packageID, before: next)
}
}