Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
at main 137 lines 3.4 kB view raw
1import { 2 ActivityIndicator, 3 StyleSheet, 4 TouchableOpacity, 5 View, 6} from 'react-native' 7import {msg} from '@lingui/core/macro' 8import {useLingui} from '@lingui/react' 9import {Trans} from '@lingui/react/macro' 10 11import {HITSLOP_20} from '#/lib/constants' 12import {atoms as a, useTheme} from '#/alf' 13import {Button} from '#/components/Button' 14import {Fill} from '#/components/Fill' 15import * as Prompt from '#/components/Prompt' 16import {Text} from '#/components/Typography' 17import {PlayButtonIcon} from '#/components/video/PlayButtonIcon' 18 19export function GifPresentationControls({ 20 onPress, 21 isPlaying, 22 isLoading, 23 altText, 24}: { 25 onPress: () => void 26 isPlaying: boolean 27 isLoading?: boolean 28 altText?: string 29}) { 30 const {_} = useLingui() 31 const t = useTheme() 32 33 return ( 34 <> 35 <Button 36 label={isPlaying ? _(msg`Pause GIF`) : _(msg`Play GIF`)} 37 accessibilityHint={_(msg`Plays or pauses the GIF`)} 38 style={[ 39 a.absolute, 40 a.align_center, 41 a.justify_center, 42 a.inset_0, 43 {zIndex: 2}, 44 ]} 45 onPress={onPress}> 46 {isLoading ? ( 47 <View style={[a.align_center, a.justify_center]}> 48 <ActivityIndicator size="large" color="white" /> 49 </View> 50 ) : !isPlaying ? ( 51 <PlayButtonIcon /> 52 ) : ( 53 <></> 54 )} 55 </Button> 56 {!isPlaying && ( 57 <Fill 58 style={[ 59 t.name === 'light' ? t.atoms.bg_contrast_975 : t.atoms.bg, 60 { 61 opacity: 0.2, 62 zIndex: 1, 63 }, 64 ]} 65 /> 66 )} 67 <View style={styles.gifBadgeContainer}> 68 <Text style={[{color: 'white'}, a.font_bold, a.text_xs]}> 69 <Trans>GIF</Trans> 70 </Text> 71 </View> 72 {altText && <AltBadge text={altText} />} 73 </> 74 ) 75} 76 77function AltBadge({text}: {text: string}) { 78 const control = Prompt.usePromptControl() 79 const {_} = useLingui() 80 81 return ( 82 <> 83 <TouchableOpacity 84 testID="altTextButton" 85 accessibilityRole="button" 86 accessibilityLabel={_(msg`Show alt text`)} 87 accessibilityHint="" 88 hitSlop={HITSLOP_20} 89 onPress={control.open} 90 style={styles.altBadgeContainer}> 91 <Text 92 style={[{color: 'white'}, a.font_bold, a.text_xs]} 93 accessible={false}> 94 <Trans>ALT</Trans> 95 </Text> 96 </TouchableOpacity> 97 <Prompt.Outer control={control}> 98 <Prompt.Content> 99 <Prompt.TitleText> 100 <Trans>Alt Text</Trans> 101 </Prompt.TitleText> 102 <Prompt.DescriptionText selectable>{text}</Prompt.DescriptionText> 103 </Prompt.Content> 104 <Prompt.Actions> 105 <Prompt.Action 106 onPress={() => control.close()} 107 cta={_(msg`Close`)} 108 color="secondary" 109 /> 110 </Prompt.Actions> 111 </Prompt.Outer> 112 </> 113 ) 114} 115 116const styles = StyleSheet.create({ 117 gifBadgeContainer: { 118 backgroundColor: 'rgba(0, 0, 0, 0.75)', 119 borderRadius: 6, 120 paddingHorizontal: 4, 121 paddingVertical: 3, 122 position: 'absolute', 123 left: 6, 124 bottom: 6, 125 zIndex: 2, 126 }, 127 altBadgeContainer: { 128 backgroundColor: 'rgba(0, 0, 0, 0.75)', 129 borderRadius: 6, 130 paddingHorizontal: 4, 131 paddingVertical: 3, 132 position: 'absolute', 133 right: 6, 134 bottom: 6, 135 zIndex: 2, 136 }, 137})