pageta-native/Sources/Core/Theme/ThemePassStore.swift
Till JS 99967b5531 Theme-Pass Pilot: pageta verdrahtet (Unlock-Gating live)
appSlug "pageta" + ThemePassStore (@Observable): markiert beim Start die
eigene App als besucht (Keychain cross-app + Server best-effort) und holt
die triedApps-Union. PagetaThemeGallery reicht unlocked = allCases.filter{
isUnlocked(triedApps:)} + onLockedTap (öffnet mana-ev.ch/apps/<slug>) in die
geteilte Galerie. Baseline + paper(=pageta-Signatur) sofort frei, Rest gesperrt
bis die jeweilige App ausprobiert wird. Keychain-Pfad sofort aktiv; cross-device
nach mana-auth-Deploy. Build grün, on-device verifiziert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 15:32:26 +02:00

44 lines
1.3 KiB
Swift

import ManaCore
import ManaTokens
import Observation
import SwiftUI
/// Hält den Theme-Pass-Stand (ausprobierte App-Slugs) für die UI und
/// leitet die freigeschalteten Variants ab. Beim Start markiert es die
/// eigene App als besucht (Keychain + Server) und holt die
/// Server↔Keychain-Vereinigungsmenge (``ManaCore/ThemePass``).
///
/// Die **eigene** App ist immer sofort enthalten — man ist ja drin, also
/// ist die Signatur-Variant der App von Anfang an frei (kein Flash).
@MainActor
@Observable
final class ThemePassStore {
private(set) var triedApps: Set<String>
private let pass: ThemePass
private let ownApp: String
init(auth: AuthClient, config: ManaAppConfig) {
ownApp = config.appSlug ?? ""
triedApps = config.appSlug.map { [$0] } ?? []
pass = ThemePass(
auth: auth,
authBaseURL: config.authBaseURL,
keychainAccessGroup: config.keychainAccessGroup
)
}
/// Freigeschaltete Variants — für `ManaThemeGallery(unlocked:)`.
var unlocked: Set<ManaTheme> {
Set(ManaTheme.allCases.filter { $0.isUnlocked(triedApps: triedApps) })
}
/// Beim App-Start aufrufen: eigene App besucht-markieren + syncen.
func bootstrap() async {
if !ownApp.isEmpty {
triedApps = await pass.recordVisit(app: ownApp)
}
var merged = await pass.sync()
if !ownApp.isEmpty { merged.insert(ownApp) }
triedApps = merged
}
}