import React from 'react' import { ActivityIndicator, type GestureResponderEvent, Pressable, } from 'react-native' import {Image} from 'expo-image' import {type AppBskyEmbedExternal} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {type EmbedPlayerParams} from '#/lib/strings/embed-player' import {isIOS, isNative, isWeb} from '#/platform/detection' import {useExternalEmbedsPrefs} from '#/state/preferences' import {atoms as a, useTheme} from '#/alf' import {useDialogControl} from '#/components/Dialog' import {EmbedConsentDialog} from '#/components/dialogs/EmbedConsent' import {Fill} from '#/components/Fill' import {PlayButtonIcon} from '#/components/video/PlayButtonIcon' export function ExternalGif({ link, params, }: { link: AppBskyEmbedExternal.ViewExternal params: EmbedPlayerParams }) { const t = useTheme() const externalEmbedsPrefs = useExternalEmbedsPrefs() const {_} = useLingui() const consentDialogControl = useDialogControl() // Tracking if the placer has been activated const [isPlayerActive, setIsPlayerActive] = React.useState(false) // Tracking whether the gif has been loaded yet const [isPrefetched, setIsPrefetched] = React.useState(false) // Tracking whether the image is animating const [isAnimating, setIsAnimating] = React.useState(true) // Used for controlling animation const imageRef = React.useRef(null) const load = React.useCallback(() => { setIsPlayerActive(true) Image.prefetch(params.playerUri).then(() => { // Replace the image once it's fetched setIsPrefetched(true) }) }, [params.playerUri]) const onPlayPress = React.useCallback( (event: GestureResponderEvent) => { // Don't propagate on web event.preventDefault() // Show consent if this is the first load if (externalEmbedsPrefs?.[params.source] === undefined) { consentDialogControl.open() return } // If the player isn't active, we want to activate it and prefetch the gif if (!isPlayerActive) { load() return } // Control animation on native setIsAnimating(prev => { if (prev) { if (isNative) { imageRef.current?.stopAnimating() } return false } else { if (isNative) { imageRef.current?.startAnimating() } return true } }) }, [ consentDialogControl, externalEmbedsPrefs, isPlayerActive, load, params.source, ], ) return ( <> {(!isPrefetched || !isAnimating) && ( {!isAnimating || !isPlayerActive ? ( // Play button when not animating or not active ) : ( // Activity indicator while gif loads )} )} ) }