Bluesky app fork with some witchin' additions 馃挮
at main 149 lines 4.2 kB view raw
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}