From e6c4a539ca2b67e7ecbf3876eefcb9d9fc71d07c Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 4 Feb 2026 22:34:14 +0200 Subject: [PATCH] align alt text behaviour between gif types (#9822) --- .../Post/Embed/ExternalEmbed/Gif.tsx | 77 +------------------ .../VideoEmbed/GifPresentationControls.tsx | 56 +++++++++++++- .../VideoEmbedInner/VideoEmbedInnerNative.tsx | 1 + .../VideoEmbedInner/VideoEmbedInnerWeb.tsx | 1 + .../web-controls/VideoControls.tsx | 3 + 5 files changed, 63 insertions(+), 75 deletions(-) diff --git a/src/components/Post/Embed/ExternalEmbed/Gif.tsx b/src/components/Post/Embed/ExternalEmbed/Gif.tsx index 21211e3b33..cc53192c78 100644 --- a/src/components/Post/Embed/ExternalEmbed/Gif.tsx +++ b/src/components/Post/Embed/ExternalEmbed/Gif.tsx @@ -1,25 +1,14 @@ import {useRef, useState} from 'react' -import { - type StyleProp, - StyleSheet, - TouchableOpacity, - View, - type ViewStyle, -} from 'react-native' -import {msg, Trans} from '@lingui/macro' +import {type StyleProp, View, type ViewStyle} from 'react-native' +import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {HITSLOP_20} from '#/lib/constants' import {clamp} from '#/lib/numbers' import {type EmbedPlayerParams} from '#/lib/strings/embed-player' 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 {MediaInsetBorder} from '#/components/MediaInsetBorder' -import * as Prompt from '#/components/Prompt' -import {Text} from '#/components/Typography' -import {IS_WEB} from '#/env' import {GifView} from '../../../../../modules/expo-bluesky-gif-view' import {type GifViewStateChangeEvent} from '../../../../../modules/expo-bluesky-gif-view/src/GifView.types' import {GifPresentationControls} from '../VideoEmbed/GifPresentationControls' @@ -94,6 +83,7 @@ export function GifEmbed({ onPress={onPress} isPlaying={playerState.isPlaying} isLoading={!playerState.isLoaded} + altText={!hideAlt && isPreferredAltText ? altText : undefined} /> )} - {!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: IS_WEB ? 8 : 6, - paddingVertical: IS_WEB ? 6 : 3, - position: 'absolute', - // Related to margin/gap hack. This keeps the alt label in the same position - // on all platforms - right: IS_WEB ? 8 : 5, - bottom: IS_WEB ? 8 : 5, - zIndex: 2, - }, - alt: { - color: 'white', - fontSize: IS_WEB ? 10 : 7, - fontWeight: '600', - }, -}) diff --git a/src/components/Post/Embed/VideoEmbed/GifPresentationControls.tsx b/src/components/Post/Embed/VideoEmbed/GifPresentationControls.tsx index aaeaf742d5..42098a7e9c 100644 --- a/src/components/Post/Embed/VideoEmbed/GifPresentationControls.tsx +++ b/src/components/Post/Embed/VideoEmbed/GifPresentationControls.tsx @@ -1,10 +1,12 @@ -import {Pressable, StyleSheet, View} from 'react-native' +import {Pressable, StyleSheet, TouchableOpacity, View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {HITSLOP_20} from '#/lib/constants' 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' @@ -12,10 +14,12 @@ export function GifPresentationControls({ onPress, isPlaying, isLoading, + altText, }: { onPress: () => void isPlaying: boolean isLoading?: boolean + altText?: string }) { const {_} = useLingui() const t = useTheme() @@ -60,6 +64,46 @@ export function GifPresentationControls({ GIF + {altText && } + + ) +} + +function AltBadge({text}: {text: string}) { + const control = Prompt.usePromptControl() + const {_} = useLingui() + + return ( + <> + + + ALT + + + + + + Alt Text + + {text} + + + control.close()} + cta={_(msg`Close`)} + color="secondary" + /> + + ) } @@ -75,4 +119,14 @@ const styles = StyleSheet.create({ bottom: 6, zIndex: 2, }, + altBadgeContainer: { + backgroundColor: 'rgba(0, 0, 0, 0.75)', + borderRadius: 6, + paddingHorizontal: 4, + paddingVertical: 3, + position: 'absolute', + right: 6, + bottom: 6, + zIndex: 2, + }, }) diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx index bb72a6c687..9cad63e9a8 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/VideoEmbedInnerNative.tsx @@ -92,6 +92,7 @@ export function VideoEmbedInnerNative({ }} isPlaying={isPlaying} isLoading={false} + altText={embed.alt} /> ) : ( diff --git a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx index e7c7514a7f..5a23e595a9 100644 --- a/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx +++ b/src/components/Post/Embed/VideoEmbed/VideoEmbedInner/web-controls/VideoControls.tsx @@ -46,6 +46,7 @@ export function Controls({ hlsLoading, hasSubtitleTrack, isGif, + altText, }: { videoRef: React.RefObject hlsRef: React.RefObject @@ -58,6 +59,7 @@ export function Controls({ hlsLoading: boolean hasSubtitleTrack: boolean isGif: boolean + altText?: string }) { const { play, @@ -296,6 +298,7 @@ export function Controls({ isPlaying={playing} isLoading={showSpinner} onPress={onPressPlayPause} + altText={altText} /> ) }