diff --git a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift index 419fdde..fbc55a8 100644 --- a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift +++ b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift @@ -929,6 +929,26 @@ final class RemoteStore: ObservableObject { connection(owningSession: sessionID)?.fetchFullTranscript(sessionID) } + /// Bind the open session to its owning Mac once that Mac is live — the deferred half of `open()` + /// for a session opened before any connection existed (a Live Activity / notification cold-launch + /// deep link). Because `open()` ran while the app was still dialing, `connection(owningSession:)` + /// found nothing: the host binding stayed nil, no `subscribe` went out, and the transcript + /// callbacks — all gated on `openSessionHostID` — dropped everything the host later sent, leaving + /// the detail stuck on "Disconnected" with an empty transcript and a dead composer. Once a host + /// connects and lists its sessions, `didUpdate` calls this: it finds the owner and finishes the + /// subscription so the transcript loads and connectivity/scope follow the bound host. Idempotent + /// and cheap — a no-op on the common path where `open()` already bound a live connection. + private func bindOpenSessionIfNeeded() { + guard !demoMode, let sessionID = openSessionID, + let conn = connection(owningSession: sessionID), conn.connectivity.isLive else { return } + // Already bound to this live host with its subscription in place — nothing to redo. + guard openSessionHostID != conn.hostID || conn.openSessionID != sessionID else { return } + openSessionHostID = conn.hostID + conn.openSessionID = sessionID + conn.send(.subscribe(Subscribe(sessionID: sessionID, sinceSeq: nil, verbosity: .full))) + conn.fetchFullTranscript(sessionID) + } + /// Ask the host for the open session's full patch (Diff tab). No-op when the host /// doesn't advertise the capability — the view falls back to the diffstat summary. func fetchDiff(_ sessionID: SessionID) {