forked from
jollywhoppers.com/witchsky.app
fork
Configure Feed
Select the types of activity you want to include in your feed.
Bluesky app fork with some witchin' additions 馃挮
fork
Configure Feed
Select the types of activity you want to include in your feed.
1import {type ReactNode} from 'react'
2import {ScrollView, View} from 'react-native'
3import {
4 useSafeAreaFrame,
5 useSafeAreaInsets,
6} from 'react-native-safe-area-context'
7import {LinearGradient} from 'expo-linear-gradient'
8import {utils} from '@bsky.app/alf'
9
10import {useA11y} from '#/state/a11y'
11import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
12import {FocusScope} from '#/components/FocusScope'
13import {LockScroll} from '#/components/LockScroll'
14import {IS_ANDROID, IS_NATIVE} from '#/env'
15
16const GUTTER = 24
17
18export function Overlay({
19 children,
20 label,
21}: {
22 children: ReactNode
23 label: string
24}) {
25 const t = useTheme()
26 const {gtPhone} = useBreakpoints()
27 const {reduceMotionEnabled} = useA11y()
28 const insets = useSafeAreaInsets()
29 const frame = useSafeAreaFrame()
30
31 return (
32 <>
33 <LockScroll />
34
35 <View style={[a.fixed, a.inset_0, !reduceMotionEnabled && a.fade_in]}>
36 {gtPhone ? (
37 <View style={[a.absolute, a.inset_0, {opacity: 0.8}]}>
38 <View
39 style={[
40 a.fixed,
41 a.inset_0,
42 {backgroundColor: t.palette.black},
43 !reduceMotionEnabled && a.fade_in,
44 ]}
45 />
46 </View>
47 ) : (
48 <LinearGradient
49 colors={[
50 utils.alpha(t.atoms.bg.backgroundColor, 0),
51 t.atoms.bg.backgroundColor,
52 t.atoms.bg.backgroundColor,
53 ]}
54 start={[0.5, 0]}
55 end={[0.5, 1]}
56 style={[a.absolute, a.inset_0]}
57 />
58 )}
59 </View>
60
61 <ScrollView
62 showsVerticalScrollIndicator={false}
63 style={[
64 a.z_10,
65 gtPhone &&
66 web({
67 paddingHorizontal: GUTTER,
68 paddingVertical: '10vh',
69 }),
70 ]}
71 contentContainerStyle={[a.align_center]}>
72 {/**
73 * This is needed to prevent centered dialogs from overflowing
74 * above the screen, and provides a "natural" centering so that
75 * stacked dialogs appear relatively aligned.
76 */}
77 <View
78 style={[
79 a.w_full,
80 a.z_20,
81 a.align_center,
82 !gtPhone && [a.justify_end, {minHeight: frame.height}],
83 IS_NATIVE && [
84 {
85 paddingBottom: Math.max(insets.bottom, a.p_2xl.padding),
86 },
87 ],
88 ]}>
89 {!gtPhone && (
90 <View
91 style={[
92 a.flex_1,
93 a.w_full,
94 {
95 minHeight: Math.max(insets.top, a.p_2xl.padding),
96 },
97 ]}>
98 <LinearGradient
99 colors={[
100 utils.alpha(t.atoms.bg.backgroundColor, 0),
101 t.atoms.bg.backgroundColor,
102 ]}
103 start={[0.5, 0]}
104 end={[0.5, 1]}
105 style={[a.absolute, a.inset_0]}
106 />
107 </View>
108 )}
109
110 <FocusScope>
111 <View
112 accessible={IS_ANDROID}
113 role="dialog"
114 aria-role="dialog"
115 aria-label={label}
116 style={[
117 a.relative,
118 a.w_full,
119 a.p_2xl,
120 t.atoms.bg,
121 !reduceMotionEnabled && a.zoom_fade_in,
122 gtPhone && [
123 a.rounded_md,
124 a.border,
125 t.atoms.shadow_lg,
126 t.atoms.border_contrast_low,
127 web({
128 maxWidth: 420,
129 }),
130 ],
131 ]}>
132 {children}
133 </View>
134 </FocusScope>
135 </View>
136 </ScrollView>
137 </>
138 )
139}