diff --git a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift index 76be4d0..381932f 100644 --- a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift +++ b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift @@ -86,6 +86,11 @@ final class RemoteStore: ObservableObject { /// `RootView` switches to the Sessions tab; `SessionsView` pushes it and clears. @Published var pendingRoute: SessionID? + /// A request to surface the sessions list itself, no specific session โ€” the Live Activity's + /// "work running, nothing waiting" tap. Compact jumps to the Sessions tab; the iPad split + /// reveals its sidebar (which always lists sessions). One-shot: the shell clears it. + @Published var pendingSessionsList = false + /// Whether the app is foreground-active (scene phase), mirrored here so the store can /// decide which transitions deserve a notification. private(set) var isActive = true @@ -95,6 +100,19 @@ final class RemoteStore: ObservableObject { /// Route to a session from a notification tap (deep link). func route(to sessionID: SessionID) { pendingRoute = sessionID } + /// Ask the shell to show the sessions list (no specific session opened). + func showSessionsList() { pendingSessionsList = true } + + /// Follow a `nucleic://` deep link โ€” the Live Activity tap. A session waiting on the user + /// opens straight into that session; the plain sessions link just surfaces the list. + func handleDeepLink(_ url: URL) { + switch NucleicDeepLink.route(for: url) { + case .session(let id): route(to: SessionID(rawValue: id)) + case .sessionsList: showSessionsList() + case .none: break + } + } + /// An Allow/Deny straight from a notification action (UX_IOS ยง5.1). Requires a live /// channel; if the socket dropped while backgrounded, reconnect and send once ready โ€” /// but only briefly (a stale queued approval must never fire minutes later; see