diff --git a/js/mobile/package.json b/js/mobile/package.json index 4ded7b7..84547c4 100644 --- a/js/mobile/package.json +++ b/js/mobile/package.json @@ -4,7 +4,7 @@ "private": true, "main": "index.ts", "scripts": { - "start": "expo start", + "start": "expo start -c", "ios": "expo run:ios --device", "publish:ios": "eas build --platform ios --auto-submit && echo 'Go to App Store Connect and submit the testflight build for app review. Visit for more information: https://docs.expo.dev/submit/introduction/'", "android": "expo run:android", diff --git a/js/mobile/src/features/stream-view/StreamView.tsx b/js/mobile/src/features/stream-view/StreamView.tsx index c348478..d4cf69d 100644 --- a/js/mobile/src/features/stream-view/StreamView.tsx +++ b/js/mobile/src/features/stream-view/StreamView.tsx @@ -118,6 +118,13 @@ function StreamViewInner({ streamParticle, path, onExit }: StreamViewProps) { const [holdActive, setHoldActive] = useState(false); useSuspendPlayback(holdActive, "touch-hold"); + // Suspend playback whenever another screen (Huddle, NewStream, modals + // routed as screens) is on top. Native stack keeps StreamView mounted, so + // without this the stream would keep advancing — and the exit countdown + // would fire — behind the huddle. + const isFocused = useIsFocused(); + useSuspendPlayback(!isFocused, "screen-unfocused"); + // Reaction sheet — opens via swipe-up on the canvas. const [reactionsOpen, setReactionsOpen] = useState(false); @@ -386,11 +393,9 @@ function StreamViewInner({ streamParticle, path, onExit }: StreamViewProps) { }); // --- End-of-stream countdown --- - // Pause the countdown when this screen isn't focused (e.g. a Huddle screen - // is mounted on top). Otherwise the timer keeps ticking under the huddle - // and goBack() pops the huddle out from under the user. - const isFocused = useIsFocused(); - const exitRemainingMs = useExitCountdown(status, paused || !isFocused, exit); + // `paused` already reflects unfocused state via the "screen-unfocused" + // suspender registered above, so the countdown freezes under the huddle. + const exitRemainingMs = useExitCountdown(status, paused, exit); // Chrome reservations: top = safe-area + segmented bar (3) + gap (12) + // metadata row (~38) + breathing room (12). Bottom = safe-area + compose