forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 💫
1import {useCallback, useMemo} from 'react'
2import {View} from 'react-native'
3import {Image} from 'expo-image'
4import {LinearGradient} from 'expo-linear-gradient'
5import {msg, Trans} from '@lingui/macro'
6import {useLingui} from '@lingui/react'
7
8import {atoms as a, select, useTheme, utils, web} from '#/alf'
9import {Button, ButtonText} from '#/components/Button'
10import * as Dialog from '#/components/Dialog'
11import {useNuxDialogContext} from '#/components/dialogs/nuxs'
12import {
13 createIsEnabledCheck,
14 isExistingUserAsOf,
15} from '#/components/dialogs/nuxs/utils'
16import {Beaker_Stroke2_Corner2_Rounded as BeakerIcon} from '#/components/icons/Beaker'
17import {Text} from '#/components/Typography'
18import {IS_E2E, IS_WEB} from '#/env'
19
20export const enabled = createIsEnabledCheck(props => {
21 return (
22 !IS_E2E &&
23 isExistingUserAsOf(
24 '2026-01-16T00:00:00.000Z',
25 props.currentProfile.createdAt,
26 ) &&
27 !props.features.enabled(props.features.LiveNowBetaDisable)
28 )
29})
30
31export function LiveNowBetaDialog() {
32 const t = useTheme()
33 const {_} = useLingui()
34 const nuxDialogs = useNuxDialogContext()
35 const control = Dialog.useDialogControl()
36
37 Dialog.useAutoOpen(control)
38
39 const onClose = useCallback(() => {
40 nuxDialogs.dismissActiveNux()
41 }, [nuxDialogs])
42
43 const shadowColor = useMemo(() => {
44 return select(t.name, {
45 light: utils.alpha(t.palette.primary_900, 0.4),
46 dark: utils.alpha(t.palette.primary_25, 0.4),
47 dim: utils.alpha(t.palette.primary_25, 0.4),
48 })
49 }, [t])
50
51 return (
52 <Dialog.Outer
53 control={control}
54 onClose={onClose}
55 nativeOptions={{preventExpansion: true}}>
56 <Dialog.Handle fill={t.palette.primary_700} />
57
58 <Dialog.ScrollableInner
59 label={_(msg`Show when you’re live`)}
60 style={[web({maxWidth: 440})]}
61 contentContainerStyle={[
62 {
63 paddingTop: 0,
64 paddingLeft: 0,
65 paddingRight: 0,
66 },
67 ]}>
68 <View
69 style={[
70 a.align_center,
71 a.overflow_hidden,
72 {
73 gap: 16,
74 paddingTop: IS_WEB ? 24 : 40,
75 borderTopLeftRadius: a.rounded_md.borderRadius,
76 borderTopRightRadius: a.rounded_md.borderRadius,
77 },
78 ]}>
79 <LinearGradient
80 colors={[
81 t.palette.primary_100,
82 utils.alpha(t.palette.primary_100, 0),
83 ]}
84 locations={[0, 1]}
85 start={{x: 0, y: 0}}
86 end={{x: 0, y: 1}}
87 style={[a.absolute, a.inset_0]}
88 />
89 <View style={[a.flex_row, a.align_center, a.gap_xs]}>
90 <BeakerIcon fill={t.palette.primary_700} size="sm" />
91 <Text
92 style={[
93 a.font_semi_bold,
94 {
95 color: t.palette.primary_700,
96 },
97 ]}>
98 <Trans>Beta Feature</Trans>
99 </Text>
100 </View>
101
102 <View
103 style={[
104 a.relative,
105 a.w_full,
106 {
107 paddingTop: 8,
108 paddingHorizontal: 32,
109 paddingBottom: 32,
110 },
111 ]}>
112 <View
113 style={[
114 {
115 borderRadius: 24,
116 aspectRatio: 652 / 211,
117 },
118 IS_WEB
119 ? [
120 {
121 boxShadow: `0px 10px 15px -3px ${shadowColor}`,
122 },
123 ]
124 : [
125 t.atoms.shadow_md,
126 {
127 shadowColor,
128 shadowOpacity: 0.2,
129 shadowOffset: {
130 width: 0,
131 height: 10,
132 },
133 },
134 ],
135 ]}>
136 <Image
137 accessibilityIgnoresInvertColors
138 source={require('../../../../assets/images/live_now_beta.webp')}
139 style={[
140 a.w_full,
141 {
142 aspectRatio: 652 / 211,
143 },
144 ]}
145 alt={_(
146 msg({
147 message: `A screenshot of a post from @esb.lol, showing the user is currently livestreaming content on Twitch. The post reads: "Hello! I'm live on Twitch, and I'm testing Bluesky's latest feature too!"`,
148 comment:
149 'Contains a post that originally appeared in English. Consider translating the post text if it makes sense in your language, and noting that the post was translated from English.',
150 }),
151 )}
152 />
153 </View>
154 </View>
155 </View>
156 <View style={[a.align_center, a.px_xl, a.gap_2xl, a.pb_sm]}>
157 <View style={[a.gap_sm, a.align_center]}>
158 <Text
159 style={[
160 a.text_3xl,
161 a.leading_tight,
162 a.font_bold,
163 a.text_center,
164 {
165 fontSize: IS_WEB ? 28 : 32,
166 maxWidth: 360,
167 },
168 ]}>
169 <Trans>Show when you’re live</Trans>
170 </Text>
171 <Text
172 style={[
173 a.text_md,
174 a.leading_snug,
175 a.text_center,
176 {
177 maxWidth: 340,
178 },
179 ]}>
180 <Trans>
181 Streaming on Twitch? Set your live status on Bluesky to add a
182 badge to your avatar. Tapping it takes people straight to your
183 stream.
184 </Trans>
185 </Text>
186 </View>
187
188 {!IS_WEB && (
189 <Button
190 label={_(msg`Close`)}
191 size="large"
192 color="primary"
193 onPress={() => {
194 control.close()
195 }}
196 style={[a.w_full]}>
197 <ButtonText>
198 <Trans>Close</Trans>
199 </ButtonText>
200 </Button>
201 )}
202 </View>
203
204 <Dialog.Close />
205 </Dialog.ScrollableInner>
206 </Dialog.Outer>
207 )
208}