Bluesky app fork with some witchin' additions 馃挮
at main 110 lines 3.0 kB view raw
1import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' 2import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' 3import {RemoveScrollBar} from 'react-remove-scroll-bar' 4 5import {usePalette} from '#/lib/hooks/usePalette' 6import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 7import {type Modal as ModalIface} from '#/state/modals' 8import {useModalControls, useModals} from '#/state/modals' 9import * as DeleteAccountModal from './DeleteAccount' 10import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' 11import * as UserAddRemoveLists from './UserAddRemoveLists' 12 13export function ModalsContainer() { 14 const {isModalActive, activeModals} = useModals() 15 16 if (!isModalActive) { 17 return null 18 } 19 20 return ( 21 <> 22 <RemoveScrollBar /> 23 {activeModals.map((modal, i) => ( 24 <Modal key={`modal-${i}`} modal={modal} /> 25 ))} 26 </> 27 ) 28} 29 30function Modal({modal}: {modal: ModalIface}) { 31 const {isModalActive} = useModals() 32 const {closeModal} = useModalControls() 33 const pal = usePalette('default') 34 const {isMobile} = useWebMediaQueries() 35 36 if (!isModalActive) { 37 return null 38 } 39 40 const onPressMask = () => { 41 closeModal() 42 } 43 const onInnerPress = () => { 44 // TODO: can we use prevent default? 45 // do nothing, we just want to stop it from bubbling 46 } 47 48 let element 49 if (modal.name === 'user-add-remove-lists') { 50 element = <UserAddRemoveLists.Component {...modal} /> 51 } else if (modal.name === 'delete-account') { 52 element = <DeleteAccountModal.Component /> 53 } else if (modal.name === 'content-languages-settings') { 54 element = <ContentLanguagesSettingsModal.Component /> 55 } else { 56 return null 57 } 58 59 return ( 60 // eslint-disable-next-line react-native-a11y/has-valid-accessibility-descriptors 61 <TouchableWithoutFeedback onPress={onPressMask}> 62 <Animated.View 63 style={styles.mask} 64 entering={FadeIn.duration(150)} 65 exiting={FadeOut}> 66 {/* eslint-disable-next-line react-native-a11y/has-valid-accessibility-descriptors */} 67 <TouchableWithoutFeedback onPress={onInnerPress}> 68 <View 69 style={[ 70 styles.container, 71 isMobile && styles.containerMobile, 72 pal.view, 73 pal.border, 74 ]}> 75 {element} 76 </View> 77 </TouchableWithoutFeedback> 78 </Animated.View> 79 </TouchableWithoutFeedback> 80 ) 81} 82 83const styles = StyleSheet.create({ 84 mask: { 85 // @ts-ignore 86 position: 'fixed', 87 top: 0, 88 left: 0, 89 width: '100%', 90 height: '100%', 91 backgroundColor: '#000c', 92 alignItems: 'center', 93 justifyContent: 'center', 94 }, 95 container: { 96 width: 600, 97 // @ts-ignore web only 98 maxWidth: '100vw', 99 // @ts-ignore web only 100 maxHeight: '90vh', 101 paddingVertical: 20, 102 paddingHorizontal: 24, 103 borderRadius: 8, 104 borderWidth: 1, 105 }, 106 containerMobile: { 107 borderRadius: 0, 108 paddingHorizontal: 0, 109 }, 110})