import {useMemo, useState} from 'react' import {type ImageStyle, useWindowDimensions, View} from 'react-native' import {Image} from 'expo-image' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' import {Plural, Trans} from '@lingui/react/macro' import {MAX_ALT_TEXT} from '#/lib/constants' import {enforceLen} from '#/lib/strings/helpers' import {type ComposerImage} from '#/state/gallery' import {AltTextCounterWrapper} from '#/view/com/composer/AltTextCounterWrapper' import {atoms as a, tokens, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {type DialogControlProps} from '#/components/Dialog' import * as TextField from '#/components/forms/TextField' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' import {Text} from '#/components/Typography' import {IS_LIQUID_GLASS, IS_WEB} from '#/env' type Props = { control: Dialog.DialogOuterProps['control'] image: ComposerImage onChange: (next: ComposerImage) => void sourceViewTag?: number } export const ImageAltTextDialog = ({ control, image, onChange, sourceViewTag, }: Props): React.ReactNode => { const [altText, setAltText] = useState(image.alt) return ( { onChange({ ...image, alt: enforceLen(altText, MAX_ALT_TEXT, true), }) }} nativeOptions={{fullHeight: true, sourceViewTag}}> ) } const ImageAltTextInner = ({ altText, setAltText, control, image, }: { altText: string setAltText: (text: string) => void control: DialogControlProps image: Props['image'] }): React.ReactNode => { const {_, i18n} = useLingui() const t = useTheme() const {width: screenWidth} = useWindowDimensions() const imageStyle = useMemo(() => { const maxWidth = IS_WEB ? 450 : screenWidth - // account for dialog padding 2 * (IS_LIQUID_GLASS ? tokens.space._2xl : tokens.space.xl) const source = image.transformed ?? image.source if (source.height > source.width) { return { resizeMode: 'contain', width: '100%', aspectRatio: 1, borderRadius: 8, } } return { width: '100%', height: (maxWidth / source.width) * source.height, borderRadius: 8, } }, [image, screenWidth]) return ( {/* vertical space is too precious - gets scrolled out of the way anyway */} {IS_WEB && ( Add alt text )} Descriptive alt text { setAltText(text) }} defaultValue={altText} multiline numberOfLines={3} autoFocus /> {altText.length > MAX_ALT_TEXT && ( Alt text will be truncated.{' '} )} ) }