mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
fork

Configure Feed

Select the types of activity you want to include in your feed.

at schema-errors 223 lines 5.3 kB view raw
1import React from 'react' 2import {Pressable, StyleProp, View, ViewStyle} from 'react-native' 3import {msg, Trans} from '@lingui/macro' 4import {useLingui} from '@lingui/react' 5import flattenReactChildren from 'react-keyed-flatten-children' 6 7import {isNative} from 'platform/detection' 8import {atoms as a, useTheme} from '#/alf' 9import {Button, ButtonText} from '#/components/Button' 10import * as Dialog from '#/components/Dialog' 11import {useInteractionState} from '#/components/hooks/useInteractionState' 12import {Context} from '#/components/Menu/context' 13import { 14 ContextType, 15 GroupProps, 16 ItemIconProps, 17 ItemProps, 18 ItemTextProps, 19 TriggerProps, 20} from '#/components/Menu/types' 21import {Text} from '#/components/Typography' 22 23export { 24 type DialogControlProps as MenuControlProps, 25 useDialogControl as useMenuControl, 26} from '#/components/Dialog' 27 28export function useMemoControlContext() { 29 return React.useContext(Context) 30} 31 32export function Root({ 33 children, 34 control, 35}: React.PropsWithChildren<{ 36 control?: Dialog.DialogOuterProps['control'] 37}>) { 38 const defaultControl = Dialog.useDialogControl() 39 const context = React.useMemo<ContextType>( 40 () => ({ 41 control: control || defaultControl, 42 }), 43 [control, defaultControl], 44 ) 45 46 return <Context.Provider value={context}>{children}</Context.Provider> 47} 48 49export function Trigger({children, label}: TriggerProps) { 50 const {control} = React.useContext(Context) 51 const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() 52 const { 53 state: pressed, 54 onIn: onPressIn, 55 onOut: onPressOut, 56 } = useInteractionState() 57 58 return children({ 59 isNative: true, 60 control, 61 state: { 62 hovered: false, 63 focused, 64 pressed, 65 }, 66 props: { 67 onPress: control.open, 68 onFocus, 69 onBlur, 70 onPressIn, 71 onPressOut, 72 accessibilityLabel: label, 73 }, 74 }) 75} 76 77export function Outer({ 78 children, 79 showCancel, 80}: React.PropsWithChildren<{ 81 showCancel?: boolean 82 style?: StyleProp<ViewStyle> 83}>) { 84 const context = React.useContext(Context) 85 86 return ( 87 <Dialog.Outer control={context.control}> 88 <Dialog.Handle /> 89 90 {/* Re-wrap with context since Dialogs are portal-ed to root */} 91 <Context.Provider value={context}> 92 <Dialog.ScrollableInner label="Menu TODO"> 93 <View style={[a.gap_lg]}> 94 {children} 95 {isNative && showCancel && <Cancel />} 96 </View> 97 <View style={{height: a.gap_lg.gap}} /> 98 </Dialog.ScrollableInner> 99 </Context.Provider> 100 </Dialog.Outer> 101 ) 102} 103 104export function Item({children, label, style, onPress, ...rest}: ItemProps) { 105 const t = useTheme() 106 const {control} = React.useContext(Context) 107 const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() 108 const { 109 state: pressed, 110 onIn: onPressIn, 111 onOut: onPressOut, 112 } = useInteractionState() 113 114 return ( 115 <Pressable 116 {...rest} 117 accessibilityHint="" 118 accessibilityLabel={label} 119 onPress={e => { 120 onPress(e) 121 122 if (!e.defaultPrevented) { 123 control?.close() 124 } 125 }} 126 onFocus={onFocus} 127 onBlur={onBlur} 128 onPressIn={onPressIn} 129 onPressOut={onPressOut} 130 style={[ 131 a.flex_row, 132 a.align_center, 133 a.gap_sm, 134 a.px_md, 135 a.rounded_md, 136 a.border, 137 t.atoms.bg_contrast_25, 138 t.atoms.border_contrast_low, 139 {minHeight: 44, paddingVertical: 10}, 140 style, 141 (focused || pressed) && [t.atoms.bg_contrast_50], 142 ]}> 143 {children} 144 </Pressable> 145 ) 146} 147 148export function ItemText({children, style}: ItemTextProps) { 149 const t = useTheme() 150 return ( 151 <Text 152 numberOfLines={1} 153 ellipsizeMode="middle" 154 style={[ 155 a.flex_1, 156 a.text_md, 157 a.font_bold, 158 t.atoms.text_contrast_medium, 159 {paddingTop: 3}, 160 style, 161 ]}> 162 {children} 163 </Text> 164 ) 165} 166 167export function ItemIcon({icon: Comp}: ItemIconProps) { 168 const t = useTheme() 169 return <Comp size="lg" fill={t.atoms.text_contrast_medium.color} /> 170} 171 172export function Group({children, style}: GroupProps) { 173 const t = useTheme() 174 return ( 175 <View 176 style={[ 177 a.rounded_md, 178 a.overflow_hidden, 179 a.border, 180 t.atoms.border_contrast_low, 181 style, 182 ]}> 183 {flattenReactChildren(children).map((child, i) => { 184 return React.isValidElement(child) && child.type === Item ? ( 185 <React.Fragment key={i}> 186 {i > 0 ? ( 187 <View style={[a.border_b, t.atoms.border_contrast_low]} /> 188 ) : null} 189 {React.cloneElement(child, { 190 // @ts-ignore 191 style: { 192 borderRadius: 0, 193 borderWidth: 0, 194 }, 195 })} 196 </React.Fragment> 197 ) : null 198 })} 199 </View> 200 ) 201} 202 203function Cancel() { 204 const {_} = useLingui() 205 const {control} = React.useContext(Context) 206 207 return ( 208 <Button 209 label={_(msg`Close this dialog`)} 210 size="small" 211 variant="ghost" 212 color="secondary" 213 onPress={() => control.close()}> 214 <ButtonText> 215 <Trans>Cancel</Trans> 216 </ButtonText> 217 </Button> 218 ) 219} 220 221export function Divider() { 222 return null 223}