Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix various issues with screen dimension detection in external player (#2349)

* various dimension fixes

* use reactive hook for dimensions

* remove debug

* accurate dismissing of player

authored by

Hailey and committed by
GitHub
d4bb64c1 db3bf784

+45 -19
+45 -19
src/view/com/util/post-embeds/ExternalPlayerEmbed.tsx
··· 1 1 import React from 'react' 2 2 import { 3 3 ActivityIndicator, 4 - Dimensions, 5 4 GestureResponderEvent, 6 5 Pressable, 7 6 StyleSheet, 7 + useWindowDimensions, 8 8 View, 9 9 } from 'react-native' 10 + import Animated, { 11 + measure, 12 + runOnJS, 13 + useAnimatedRef, 14 + useFrameCallback, 15 + } from 'react-native-reanimated' 10 16 import {Image} from 'expo-image' 11 17 import {WebView} from 'react-native-webview' 18 + import {useSafeAreaInsets} from 'react-native-safe-area-context' 12 19 import YoutubePlayer from 'react-native-youtube-iframe' 13 20 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 14 21 import {EmbedPlayerParams, getPlayerHeight} from 'lib/strings/embed-player' ··· 116 123 params: EmbedPlayerParams 117 124 }) { 118 125 const navigation = useNavigation<NavigationProp>() 126 + const insets = useSafeAreaInsets() 127 + const windowDims = useWindowDimensions() 119 128 120 129 const [isPlayerActive, setPlayerActive] = React.useState(false) 121 130 const [isLoading, setIsLoading] = React.useState(true) ··· 124 133 height: 0, 125 134 }) 126 135 127 - const viewRef = React.useRef<View>(null) 136 + const viewRef = useAnimatedRef() 137 + 138 + const frameCallback = useFrameCallback(() => { 139 + const measurement = measure(viewRef) 140 + if (!measurement) return 141 + 142 + const {height: winHeight, width: winWidth} = windowDims 143 + 144 + // Get the proper screen height depending on what is going on 145 + const realWinHeight = isNative // If it is native, we always want the larger number 146 + ? winHeight > winWidth 147 + ? winHeight 148 + : winWidth 149 + : winHeight // On web, we always want the actual screen height 150 + 151 + const top = measurement.pageY 152 + const bot = measurement.pageY + measurement.height 153 + 154 + // We can use the same logic on all platforms against the screenHeight that we get above 155 + const isVisible = top <= realWinHeight - insets.bottom && bot >= insets.top 156 + 157 + if (!isVisible) { 158 + runOnJS(setPlayerActive)(false) 159 + } 160 + }, false) // False here disables autostarting the callback 128 161 129 162 // watch for leaving the viewport due to scrolling 130 163 React.useEffect(() => { 164 + // We don't want to do anything if the player isn't active 165 + if (!isPlayerActive) return 166 + 131 167 // Interval for scrolling works in most cases, However, for twitch embeds, if we navigate away from the screen the webview will 132 168 // continue playing. We need to watch for the blur event 133 169 const unsubscribe = navigation.addListener('blur', () => { 134 170 setPlayerActive(false) 135 171 }) 136 172 137 - const interval = setInterval(() => { 138 - viewRef.current?.measure((x, y, w, h, pageX, pageY) => { 139 - const window = Dimensions.get('window') 140 - const top = pageY 141 - const bot = pageY + h 142 - const isVisible = isNative 143 - ? top >= 0 && bot <= window.height 144 - : !(top >= window.height || bot <= 0) 145 - if (!isVisible) { 146 - setPlayerActive(false) 147 - } 148 - }) 149 - }, 1e3) 173 + // Start watching for changes 174 + frameCallback.setActive(true) 175 + 150 176 return () => { 151 177 unsubscribe() 152 - clearInterval(interval) 178 + frameCallback.setActive(false) 153 179 } 154 - }, [viewRef, navigation]) 180 + }, [navigation, isPlayerActive, frameCallback]) 155 181 156 182 // calculate height for the player and the screen size 157 183 const height = React.useMemo( ··· 187 213 ) 188 214 189 215 return ( 190 - <View 216 + <Animated.View 191 217 ref={viewRef} 192 218 style={{height}} 193 219 collapsable={false} ··· 217 243 height={height} 218 244 onLoad={onLoad} 219 245 /> 220 - </View> 246 + </Animated.View> 221 247 ) 222 248 } 223 249