forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {useRef} from 'react'
2import {type ListRenderItemInfo} from 'react-native'
3import {View} from 'react-native'
4import {
5 type AppBskyActorDefs,
6 type AppBskyFeedDefs,
7 type ModerationOpts,
8} from '@atproto/api'
9import {msg, Trans} from '@lingui/macro'
10import {useLingui} from '@lingui/react'
11
12import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
13import {type ListMethods} from '#/view/com/util/List'
14import {
15 type WizardAction,
16 type WizardState,
17} from '#/screens/StarterPack/Wizard/State'
18import {atoms as a, native, useTheme, web} from '#/alf'
19import {Button, ButtonText} from '#/components/Button'
20import * as Dialog from '#/components/Dialog'
21import {
22 WizardFeedCard,
23 WizardProfileCard,
24} from '#/components/StarterPack/Wizard/WizardListCard'
25import {Text} from '#/components/Typography'
26import {IS_WEB} from '#/env'
27
28function keyExtractor(
29 item: AppBskyActorDefs.ProfileViewBasic | AppBskyFeedDefs.GeneratorView,
30 index: number,
31) {
32 return `${item.did}-${index}`
33}
34
35export function WizardEditListDialog({
36 control,
37 state,
38 dispatch,
39 moderationOpts,
40 profile,
41}: {
42 control: Dialog.DialogControlProps
43 state: WizardState
44 dispatch: (action: WizardAction) => void
45 moderationOpts: ModerationOpts
46 profile: AppBskyActorDefs.ProfileViewDetailed
47}) {
48 const {_} = useLingui()
49 const t = useTheme()
50 const initialNumToRender = useInitialNumToRender()
51
52 const listRef = useRef<ListMethods>(null)
53
54 const getData = () => {
55 if (state.currentStep === 'Feeds') return state.feeds
56
57 return [profile, ...state.profiles.filter(p => p.did !== profile.did)]
58 }
59
60 const renderItem = ({item}: ListRenderItemInfo<any>) =>
61 state.currentStep === 'Profiles' ? (
62 <WizardProfileCard
63 profile={item}
64 btnType="remove"
65 state={state}
66 dispatch={dispatch}
67 moderationOpts={moderationOpts}
68 />
69 ) : (
70 <WizardFeedCard
71 generator={item}
72 btnType="remove"
73 state={state}
74 dispatch={dispatch}
75 moderationOpts={moderationOpts}
76 />
77 )
78
79 return (
80 <Dialog.Outer control={control} testID="newChatDialog">
81 <Dialog.Handle />
82 <Dialog.InnerFlatList
83 ref={listRef}
84 data={getData()}
85 renderItem={renderItem}
86 keyExtractor={keyExtractor}
87 ListHeaderComponent={
88 <View
89 style={[
90 native(a.pt_4xl),
91 a.flex_row,
92 a.justify_between,
93 a.border_b,
94 a.px_sm,
95 a.mb_sm,
96 t.atoms.bg,
97 t.atoms.border_contrast_medium,
98 IS_WEB
99 ? [
100 a.align_center,
101 {
102 height: 48,
103 },
104 ]
105 : [a.pb_sm, a.align_end],
106 ]}>
107 <View style={{width: 60}} />
108 <Text style={[a.font_semi_bold, a.text_xl]}>
109 {state.currentStep === 'Profiles' ? (
110 <Trans>Edit People</Trans>
111 ) : (
112 <Trans>Edit Feeds</Trans>
113 )}
114 </Text>
115 <View style={{width: 60}}>
116 {IS_WEB && (
117 <Button
118 label={_(msg`Close`)}
119 variant="ghost"
120 color="primary"
121 size="small"
122 onPress={() => control.close()}>
123 <ButtonText>
124 <Trans>Close</Trans>
125 </ButtonText>
126 </Button>
127 )}
128 </View>
129 </View>
130 }
131 stickyHeaderIndices={[0]}
132 style={[
133 web([a.py_0, {height: '100vh', maxHeight: 600}, a.px_0]),
134 native({
135 height: '100%',
136 paddingHorizontal: 0,
137 marginTop: 0,
138 paddingTop: 0,
139 }),
140 ]}
141 webInnerStyle={[a.py_0, {maxWidth: 500, minWidth: 200}]}
142 keyboardDismissMode="on-drag"
143 removeClippedSubviews={true}
144 initialNumToRender={initialNumToRender}
145 />
146 </Dialog.Outer>
147 )
148}