Keep screen awake when playing youtube video (#10479)

This commit is contained in:
Samuel Newman
2026-05-13 16:51:53 +01:00
committed by GitHub
parent e9ad74bb01
commit 34b3c52729
@@ -3,7 +3,6 @@ import {
ActivityIndicator, ActivityIndicator,
type GestureResponderEvent, type GestureResponderEvent,
Pressable, Pressable,
StyleSheet,
useWindowDimensions, useWindowDimensions,
View, View,
} from 'react-native' } from 'react-native'
@@ -32,6 +31,7 @@ import {atoms as a, useTheme} from '#/alf'
import {useDialogControl} from '#/components/Dialog' import {useDialogControl} from '#/components/Dialog'
import {EmbedConsentDialog} from '#/components/dialogs/EmbedConsent' import {EmbedConsentDialog} from '#/components/dialogs/EmbedConsent'
import {Fill} from '#/components/Fill' import {Fill} from '#/components/Fill'
import {KeepAwake} from '#/components/KeepAwake'
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon' import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
import {IS_NATIVE} from '#/env' import {IS_NATIVE} from '#/env'
@@ -55,13 +55,13 @@ function PlaceholderOverlay({
if (isPlayerActive && !isLoading) return null if (isPlayerActive && !isLoading) return null
return ( return (
<View style={[a.absolute, a.inset_0, styles.overlayLayer]}> <View style={[a.absolute, a.inset_0, {zIndex: 2}]}>
<Pressable <Pressable
accessibilityRole="button" accessibilityRole="button"
accessibilityLabel={_(msg`Play Video`)} accessibilityLabel={_(msg`Play Video`)}
accessibilityHint={_(msg`Plays the video`)} accessibilityHint={_(msg`Plays the video`)}
onPress={onPress} onPress={onPress}
style={[styles.overlayContainer]}> style={[a.flex_1, a.justify_center, a.align_center]}>
{!isPlayerActive ? ( {!isPlayerActive ? (
<PlayButtonIcon /> <PlayButtonIcon />
) : ( ) : (
@@ -96,21 +96,24 @@ function Player({
if (!isPlayerActive) return null if (!isPlayerActive) return null
return ( return (
<EventStopper style={[a.absolute, a.inset_0, styles.playerLayer]}> <>
<WebView <EventStopper style={[a.absolute, a.inset_0, {zIndex: 3}]}>
javaScriptEnabled={true} <WebView
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} javaScriptEnabled={true}
mediaPlaybackRequiresUserAction={false} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
allowsInlineMediaPlayback mediaPlaybackRequiresUserAction={false}
bounces={false} allowsInlineMediaPlayback
allowsFullscreenVideo bounces={false}
nestedScrollEnabled allowsFullscreenVideo
source={{uri: params.playerUri}} nestedScrollEnabled
onLoad={onLoad} source={{uri: params.playerUri}}
style={styles.webview} onLoad={onLoad}
setSupportMultipleWindows={false} // Prevent any redirects from opening a new window (ads) style={a.bg_transparent}
/> setSupportMultipleWindows={false} // Prevent any redirects from opening a new window (ads)
</EventStopper> />
</EventStopper>
<KeepAwake />
</>
) )
} }
@@ -129,7 +132,7 @@ export function ExternalPlayer({
const externalEmbedsPrefs = useExternalEmbedsPrefs() const externalEmbedsPrefs = useExternalEmbedsPrefs()
const consentDialogControl = useDialogControl() const consentDialogControl = useDialogControl()
const [isPlayerActive, setPlayerActive] = useState(false) const [isPlayerActive, setIsPlayerActive] = useState(false)
const [isLoading, setIsLoading] = useState(true) const [isLoading, setIsLoading] = useState(true)
const aspect = useMemo(() => { const aspect = useMemo(() => {
@@ -161,7 +164,7 @@ export function ExternalPlayer({
const isVisible = top <= realWinHeight - insets.bottom && bot >= insets.top const isVisible = top <= realWinHeight - insets.bottom && bot >= insets.top
if (!isVisible) { if (!isVisible) {
runOnJS(setPlayerActive)(false) runOnJS(setIsPlayerActive)(false)
} }
}, false) // False here disables autostarting the callback }, false) // False here disables autostarting the callback
@@ -173,7 +176,7 @@ export function ExternalPlayer({
// Interval for scrolling works in most cases, However, for twitch embeds, if we navigate away from the screen the webview will // Interval for scrolling works in most cases, However, for twitch embeds, if we navigate away from the screen the webview will
// continue playing. We need to watch for the blur event // continue playing. We need to watch for the blur event
const unsubscribe = navigation.addListener('blur', () => { const unsubscribe = navigation.addListener('blur', () => {
setPlayerActive(false) setIsPlayerActive(false)
}) })
// Start watching for changes // Start watching for changes
@@ -199,13 +202,13 @@ export function ExternalPlayer({
return return
} }
setPlayerActive(true) setIsPlayerActive(true)
}, },
[externalEmbedsPrefs, consentDialogControl, params.source], [externalEmbedsPrefs, consentDialogControl, params.source],
) )
const onAcceptConsent = useCallback(() => { const onAcceptConsent = useCallback(() => {
setPlayerActive(true) setIsPlayerActive(true)
}, []) }, [])
return ( return (
@@ -231,9 +234,7 @@ export function ExternalPlayer({
<Fill <Fill
style={[ style={[
t.name === 'light' ? t.atoms.bg_contrast_975 : t.atoms.bg, t.name === 'light' ? t.atoms.bg_contrast_975 : t.atoms.bg,
{ {opacity: 0.3},
opacity: 0.3,
},
]} ]}
/> />
</> </>
@@ -262,24 +263,3 @@ export function ExternalPlayer({
</> </>
) )
} }
const styles = StyleSheet.create({
overlayContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
overlayLayer: {
zIndex: 2,
},
playerLayer: {
zIndex: 3,
},
webview: {
backgroundColor: 'transparent',
},
gifContainer: {
width: '100%',
overflow: 'hidden',
},
})