From 45f0f7eefecae1922c2f30d4e7760d2b93b1ae56 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 13 Jun 2025 12:05:41 -0500 Subject: Port post embeds to new arch (#7408) * Direct port of embeds to new arch (cherry picked from commit cc3fa1f6cea396dd9222486c633a508bfee1ecd6) * Re-org * Split out ListEmbed and FeedEmbed * Split out ImageEmbed * DRY up a bit * Port over ExternalLinkEmbed * Port over Player and Gif embeds * Migrate ComposerReplyTo * Replace other usages of old post-embeds * Migrate view contexts * Copy pasta VideoEmbed * Copy pasta GifEmbed * Swap in new file location * Clean up * Fix up native * Add back in correct moderation on List and Feed embeds * Format * Prettier * delete old video utils * move bandwidth-estimate.ts * Remove log * Add LazyQuoteEmbed for composer use * Clean up unused things * Remove remaining items * Prettier * Fix imports * Handle nested quotes same as prod * Add back silenced error handling * Fix lint --------- Co-authored-by: Samuel Newman --- src/components/Post/Embed/ExternalEmbed/Gif.tsx | 224 ++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 src/components/Post/Embed/ExternalEmbed/Gif.tsx (limited to 'src/components/Post/Embed/ExternalEmbed/Gif.tsx') diff --git a/src/components/Post/Embed/ExternalEmbed/Gif.tsx b/src/components/Post/Embed/ExternalEmbed/Gif.tsx new file mode 100644 index 000000000..a839294f1 --- /dev/null +++ b/src/components/Post/Embed/ExternalEmbed/Gif.tsx @@ -0,0 +1,224 @@ +import React from 'react' +import { + Pressable, + StyleProp, + StyleSheet, + TouchableOpacity, + View, + ViewStyle, +} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {HITSLOP_20} from '#/lib/constants' +import {EmbedPlayerParams} from '#/lib/strings/embed-player' +import {isWeb} from '#/platform/detection' +import {useAutoplayDisabled} from '#/state/preferences' +import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' +import {atoms as a, useTheme} from '#/alf' +import {Fill} from '#/components/Fill' +import {Loader} from '#/components/Loader' +import * as Prompt from '#/components/Prompt' +import {Text} from '#/components/Typography' +import {PlayButtonIcon} from '#/components/video/PlayButtonIcon' +import {GifView} from '../../../../../modules/expo-bluesky-gif-view' +import {GifViewStateChangeEvent} from '../../../../../modules/expo-bluesky-gif-view/src/GifView.types' + +function PlaybackControls({ + onPress, + isPlaying, + isLoaded, +}: { + onPress: () => void + isPlaying: boolean + isLoaded: boolean +}) { + const {_} = useLingui() + const t = useTheme() + + return ( + + {!isLoaded ? ( + + + + + + ) : !isPlaying ? ( + + ) : undefined} + + ) +} + +export function GifEmbed({ + params, + thumb, + altText, + isPreferredAltText, + hideAlt, + style = {width: '100%'}, +}: { + params: EmbedPlayerParams + thumb: string | undefined + altText: string + isPreferredAltText: boolean + hideAlt?: boolean + style?: StyleProp +}) { + const t = useTheme() + const {_} = useLingui() + const autoplayDisabled = useAutoplayDisabled() + + const playerRef = React.useRef(null) + + const [playerState, setPlayerState] = React.useState<{ + isPlaying: boolean + isLoaded: boolean + }>({ + isPlaying: !autoplayDisabled, + isLoaded: false, + }) + + const onPlayerStateChange = React.useCallback( + (e: GifViewStateChangeEvent) => { + setPlayerState(e.nativeEvent) + }, + [], + ) + + const onPress = React.useCallback(() => { + playerRef.current?.toggleAsync() + }, []) + + return ( + + + + + {!playerState.isPlaying && ( + + )} + {!hideAlt && isPreferredAltText && } + + + ) +} + +function AltText({text}: {text: string}) { + const control = Prompt.usePromptControl() + const largeAltBadge = useLargeAltBadgeEnabled() + + const {_} = useLingui() + return ( + <> + + + ALT + + + + + Alt Text + + {text} + + control.close()} + cta={_(msg`Close`)} + color="secondary" + /> + + + + ) +} + +const styles = StyleSheet.create({ + altContainer: { + backgroundColor: 'rgba(0, 0, 0, 0.75)', + borderRadius: 6, + paddingHorizontal: isWeb ? 8 : 6, + paddingVertical: isWeb ? 6 : 3, + position: 'absolute', + // Related to margin/gap hack. This keeps the alt label in the same position + // on all platforms + right: isWeb ? 8 : 5, + bottom: isWeb ? 8 : 5, + zIndex: 2, + }, + alt: { + color: 'white', + fontSize: isWeb ? 10 : 7, + fontWeight: '600', + }, +}) -- cgit 1.4.1