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