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