From d2bcf5d7166cf287258d6df40f557dbe9ff824bc Mon Sep 17 00:00:00 2001 From: Yaros Date: Fri, 28 Mar 2025 16:32:25 +0100 Subject: [PATCH] fix(mobile): pause background video play (#17032) * fix(mobile): prevent background video playback * fix: logic for tracking app state * chore: move lifecycle handler in separate file * chore: replace useState with useRef * chore: useOnAppLifecycleStateChange * fix: removed print statement --- .../pages/common/native_video_viewer.page.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mobile/lib/pages/common/native_video_viewer.page.dart b/mobile/lib/pages/common/native_video_viewer.page.dart index 23685db274..957a119f66 100644 --- a/mobile/lib/pages/common/native_video_viewer.page.dart +++ b/mobile/lib/pages/common/native_video_viewer.page.dart @@ -44,6 +44,10 @@ class NativeVideoViewerPage extends HookConsumerWidget { final lastVideoPosition = useRef(-1); final isBuffering = useRef(false); + // Used to track whether the video should play when the app + // is brought back to the foreground + final shouldPlayOnForeground = useRef(true); + // When a video is opened through the timeline, `isCurrent` will immediately be true. // When swiping from video A to video B, `isCurrent` will initially be true for video A and false for video B. // If the swipe is completed, `isCurrent` will be true for video B after a delay. @@ -368,6 +372,20 @@ class NativeVideoViewerPage extends HookConsumerWidget { const [], ); + useOnAppLifecycleStateChange((_, state) async { + if (state == AppLifecycleState.resumed && shouldPlayOnForeground.value) { + controller.value?.play(); + } else if (state == AppLifecycleState.paused) { + final videoPlaying = await controller.value?.isPlaying(); + if (videoPlaying ?? true) { + shouldPlayOnForeground.value = true; + controller.value?.pause(); + } else { + shouldPlayOnForeground.value = false; + } + } + }); + return Stack( children: [ // This remains under the video to avoid flickering