From 976bb0e066f9fbe78c785b73ddb8b621e0e93514 Mon Sep 17 00:00:00 2001 From: Andrew Blakeslee Moore Date: Thu, 2 Jul 2026 19:18:09 -0700 Subject: [PATCH] Review Feature Access Nucleic-Session: 85A6233A-F3F6-44B2-AD0B-261D49EE9C35 Co-authored-by: Nucleic --- .../NucleicRemote/Models/RemoteStore.swift | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift index 4a5536e..f4b17c7 100644 --- a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift +++ b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift @@ -326,6 +326,40 @@ final class RemoteStore: ObservableObject { NotificationRouter.shared.updateBadge(0) } + /// Enter the in-app demo (the "Explore a demo" button): drop any live connection, persist the + /// flag so it survives relaunch (a reviewer may relaunch), and seed the mock world. `isPaired` + /// then returns true, so `RootView` shows the full TabView. + func enterDemo() { + teardown() + demoMode = true + UserDefaults.standard.set(true, forKey: Self.demoModeKey) + reconnectAttempts = 0 + seedDemo() + } + + /// Leave the demo (Settings ▸ Leave demo): cancel any simulated runs, clear the mock world, + /// and return to the real state — reconnect if a Mac is actually paired, else the pairing intro. + func exitDemo() { + demoMode = false + UserDefaults.standard.set(false, forKey: Self.demoModeKey) + demoTasks.forEach { $0.cancel() } + demoTasks.removeAll() + openSessionID = nil + openEvents = [] + openApprovals = [] + openDiff = nil + diffLoading = false + sessions = [] + dashboard = .empty + LiveActivityManager.shared.end() + NotificationRouter.shared.updateBadge(0) + if IdentityStore.loadPairedHost() != nil { + reconnect() + } else { + connectivity = .unpaired + } + } + // MARK: - Intents (UX_IOS §9) func open(_ sessionID: SessionID) {