Skip to content

Commit 0582034

Browse files
committed
Fix - Video file loads infinitely and stop playing when open using arrows
1 parent 90d39ec commit 0582034

2 files changed

Lines changed: 62 additions & 23 deletions

File tree

src/components/VideoPlayerPreview/index.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import VideoPlayer from '@components/VideoPlayer';
99
import IconButton from '@components/VideoPlayer/IconButton';
1010
import {usePlaybackContext} from '@components/VideoPlayerContexts/PlaybackContext';
1111
import useCheckIfRouteHasRemainedUnchanged from '@hooks/useCheckIfRouteHasRemainedUnchanged';
12-
import useFirstRenderRoute from '@hooks/useFirstRenderRoute';
1312
import useLocalize from '@hooks/useLocalize';
1413
import useResponsiveLayout from '@hooks/useResponsiveLayout';
1514
import useThemeStyles from '@hooks/useThemeStyles';
@@ -66,9 +65,8 @@ function VideoPlayerPreview({videoUrl, thumbnailUrl, reportID, fileName, videoDi
6665
const {isOnSearch} = useSearchContext();
6766
const navigation = useNavigation();
6867

69-
const didUserNavigateOutOfReportScreen = useCheckIfRouteHasRemainedUnchanged();
7068
// We want to play the video only when the user is on the page where it was rendered
71-
const firstRenderRoute = useFirstRenderRoute(didUserNavigateOutOfReportScreen);
69+
const isUserRemainOnFirstRenderRoute = useCheckIfRouteHasRemainedUnchanged(videoUrl);
7270

7371
// `onVideoLoaded` is passed to VideoPlayerPreview's `Video` element which is displayed only on web.
7472
// VideoReadyForDisplayEvent type is lacking srcElement, that's why it's added here
@@ -85,14 +83,15 @@ function VideoPlayerPreview({videoUrl, thumbnailUrl, reportID, fileName, videoDi
8583

8684
useEffect(() => {
8785
return navigation.addListener('blur', () => !isOnAttachmentRoute() && setIsThumbnail(true));
88-
}, [navigation, firstRenderRoute]);
86+
}, [navigation]);
8987

9088
useEffect(() => {
91-
if (videoUrl !== currentlyPlayingURL || reportID !== currentRouteReportID || !firstRenderRoute.isFocused) {
89+
const isFocused = isUserRemainOnFirstRenderRoute();
90+
if (videoUrl !== currentlyPlayingURL || reportID !== currentRouteReportID || !isFocused) {
9291
return;
9392
}
9493
setIsThumbnail(false);
95-
}, [currentlyPlayingURL, currentRouteReportID, updateCurrentURLAndReportID, videoUrl, reportID, firstRenderRoute, isOnSearch]);
94+
}, [currentlyPlayingURL, currentRouteReportID, updateCurrentURLAndReportID, videoUrl, reportID, isUserRemainOnFirstRenderRoute, isOnSearch]);
9695

9796
return (
9897
<View style={[styles.webViewStyles.tagStyles.video, thumbnailDimensionsStyles]}>

src/hooks/useCheckIfRouteHasRemainedUnchanged.ts

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,85 @@
11
import {useNavigation} from '@react-navigation/native';
22
import {useCallback, useEffect, useRef} from 'react';
3-
import Navigation from '@navigation/Navigation';
4-
import ROUTES from '@src/ROUTES';
3+
import Navigation, {navigationRef} from '@navigation/Navigation';
4+
import SCREENS from '@src/SCREENS';
5+
import useResponsiveLayout from './useResponsiveLayout';
56

67
/**
7-
* Hook that returns a function to check if the currently active route remains the same as the last known route.
8-
* The last known route reference is updated every time the component experiences a 'blur' event,
8+
* Hook that returns a function to check if the currently active route remains the same as the route on which the component was initially rendered.
9+
* The `isFocused` is set to `false` every time the component experiences a 'blur' event,
910
* except when opening an attachments modal, which is treated as an exception and does not trigger a reference update.
1011
*
11-
* @return Function that checks if the last known route matches the currently active route.
12+
* @return Function that checks if the route where the component was rendered matches the currently active route.
1213
*/
13-
function useCheckIfRouteHasRemainedUnchanged(): () => boolean {
14-
const lastKnownRouteRef = useRef<string | undefined>(undefined);
14+
function useCheckIfRouteHasRemainedUnchanged(videoUrl: string) {
15+
// Ref stores a value determining whether the component is still rendered on the route.
16+
// If the value is false, it immediately returns false; if true, it checks whether it is in the attachment modal.
17+
const hasOnRenderedRouteRef = useRef<boolean | undefined>(undefined);
1518
const navigation = useNavigation();
19+
const {shouldUseNarrowLayout, isInNarrowPaneModal} = useResponsiveLayout();
1620

17-
// Function to compare the last known route with the current active route
1821
const hasRouteRemainedUnchanged = useCallback(() => {
19-
return lastKnownRouteRef.current === Navigation.getActiveRouteWithoutParams();
20-
}, []);
22+
if (navigation.isFocused()) {
23+
return true;
24+
}
25+
26+
// If navigating outside the rendered route and attachment modal route
27+
if (!hasOnRenderedRouteRef.current) {
28+
return false;
29+
}
30+
31+
// If on AttachmentModal, only play when the source parameters match videoUrl
32+
const currentRoute = navigationRef.getCurrentRoute();
33+
if (
34+
currentRoute?.name === SCREENS.ATTACHMENTS &&
35+
currentRoute?.params &&
36+
'source' in currentRoute.params &&
37+
currentRoute.params.source === videoUrl &&
38+
// Because the video player is shared only on desktop
39+
// Allow in RHP
40+
(!shouldUseNarrowLayout || isInNarrowPaneModal)
41+
) {
42+
return true;
43+
}
2144

22-
// Initialize the initial route when navigation is ready
45+
return false;
46+
}, [shouldUseNarrowLayout, isInNarrowPaneModal, videoUrl, navigation]);
47+
48+
// Initialize and check if starting with the attachment modal
2349
useEffect(() => {
2450
Navigation.isNavigationReady().then(() => {
25-
if (lastKnownRouteRef.current !== undefined) {
51+
if (hasOnRenderedRouteRef.current !== undefined) {
2652
return;
2753
}
2854

29-
lastKnownRouteRef.current = Navigation.getActiveRouteWithoutParams();
55+
const route = navigationRef.getCurrentRoute();
56+
// If the app is opened via the attachment route, it will always remain on the report screen.
57+
// Thus, it can be considered as still being on the rendered route.
58+
hasOnRenderedRouteRef.current = route?.name === SCREENS.ATTACHMENTS;
3059
});
3160
}, []);
3261

3362
// Update the route reference on 'blur' events, except when opening attachments modal
3463
useEffect(() => {
35-
return navigation.addListener('blur', () => {
36-
const currentRoute = Navigation.getActiveRouteWithoutParams();
37-
if (currentRoute === `/${ROUTES.ATTACHMENTS.route}`) {
64+
const unsubscribeFocus = navigation.addListener('focus', () => {
65+
hasOnRenderedRouteRef.current = true;
66+
});
67+
68+
const unsubscribeBlur = navigation.addListener('blur', () => {
69+
const route = navigationRef.getCurrentRoute();
70+
71+
if (route?.name === SCREENS.ATTACHMENTS) {
3872
// Skip route update when attachment modal is opened
3973
return;
4074
}
41-
lastKnownRouteRef.current = currentRoute;
75+
76+
hasOnRenderedRouteRef.current = false;
4277
});
78+
79+
return () => {
80+
unsubscribeFocus();
81+
unsubscribeBlur();
82+
};
4383
}, [navigation]);
4484

4585
return hasRouteRemainedUnchanged;

0 commit comments

Comments
 (0)