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