Bluesky app fork with some witchin' additions 💫

Implement modals for web

+102 -9
+5 -5
src/view/com/modals/EditProfile.tsx
··· 7 7 View, 8 8 } from 'react-native' 9 9 import LinearGradient from 'react-native-linear-gradient' 10 - import {BottomSheetScrollView, BottomSheetTextInput} from '@gorhom/bottom-sheet' 10 + import {ScrollView, TextInput} from './util' 11 11 import {Image as PickedImage} from '../util/images/ImageCropPicker' 12 12 import {Text} from '../util/text/Text' 13 13 import {ErrorMessage} from '../util/error/ErrorMessage' ··· 102 102 103 103 return ( 104 104 <View style={s.flex1}> 105 - <BottomSheetScrollView style={styles.inner}> 105 + <ScrollView style={styles.inner}> 106 106 <Text style={styles.title}>Edit my profile</Text> 107 107 <View style={styles.photos}> 108 108 <UserBanner ··· 126 126 )} 127 127 <View> 128 128 <Text style={styles.label}>Display Name</Text> 129 - <BottomSheetTextInput 129 + <TextInput 130 130 style={styles.textInput} 131 131 placeholder="e.g. Alice Roberts" 132 132 placeholderTextColor={colors.gray4} ··· 136 136 </View> 137 137 <View style={s.pb10}> 138 138 <Text style={styles.label}>Description</Text> 139 - <BottomSheetTextInput 139 + <TextInput 140 140 style={[styles.textArea]} 141 141 placeholder="e.g. Artist, dog-lover, and memelord." 142 142 placeholderTextColor={colors.gray4} ··· 165 165 <Text style={[s.black, s.bold]}>Cancel</Text> 166 166 </View> 167 167 </TouchableOpacity> 168 - </BottomSheetScrollView> 168 + </ScrollView> 169 169 </View> 170 170 ) 171 171 }
+85
src/view/com/modals/Modal.web.tsx
··· 1 + import React from 'react' 2 + import {TouchableWithoutFeedback, StyleSheet, View} from 'react-native' 3 + import {observer} from 'mobx-react-lite' 4 + import {useStores} from '../../../state' 5 + import {usePalette} from '../../lib/hooks/usePalette' 6 + 7 + import * as models from '../../../state/models/shell-ui' 8 + 9 + import * as ConfirmModal from './Confirm' 10 + import * as EditProfileModal from './EditProfile' 11 + import * as ServerInputModal from './ServerInput' 12 + import * as ReportPostModal from './ReportPost' 13 + import * as ReportAccountModal from './ReportAccount' 14 + 15 + export const Modal = observer(function Modal() { 16 + const store = useStores() 17 + const pal = usePalette('default') 18 + 19 + if (!store.shell.isModalActive) { 20 + return null 21 + } 22 + 23 + const onClose = () => { 24 + store.shell.closeModal() 25 + } 26 + const onInnerPress = () => { 27 + // do nothing, we just want to stop it from bubbling 28 + } 29 + 30 + let element 31 + if (store.shell.activeModal?.name === 'confirm') { 32 + element = ( 33 + <ConfirmModal.Component 34 + {...(store.shell.activeModal as models.ConfirmModal)} 35 + /> 36 + ) 37 + } else if (store.shell.activeModal?.name === 'edit-profile') { 38 + element = ( 39 + <EditProfileModal.Component 40 + {...(store.shell.activeModal as models.EditProfileModal)} 41 + /> 42 + ) 43 + } else if (store.shell.activeModal?.name === 'server-input') { 44 + element = ( 45 + <ServerInputModal.Component 46 + {...(store.shell.activeModal as models.ServerInputModal)} 47 + /> 48 + ) 49 + } else if (store.shell.activeModal?.name === 'report-post') { 50 + element = <ReportPostModal.Component /> 51 + } else if (store.shell.activeModal?.name === 'report-account') { 52 + element = <ReportAccountModal.Component /> 53 + } else { 54 + return null 55 + } 56 + 57 + return ( 58 + <TouchableWithoutFeedback onPress={onClose}> 59 + <View style={styles.mask}> 60 + <TouchableWithoutFeedback onPress={onInnerPress}> 61 + <View style={[styles.container, pal.view]}>{element}</View> 62 + </TouchableWithoutFeedback> 63 + </View> 64 + </TouchableWithoutFeedback> 65 + ) 66 + }) 67 + 68 + const styles = StyleSheet.create({ 69 + mask: { 70 + position: 'absolute', 71 + top: 0, 72 + left: 0, 73 + width: '100%', 74 + height: '100%', 75 + backgroundColor: '#000c', 76 + alignItems: 'center', 77 + justifyContent: 'center', 78 + }, 79 + container: { 80 + width: 500, 81 + paddingVertical: 20, 82 + paddingHorizontal: 24, 83 + borderRadius: 8, 84 + }, 85 + })
+4 -4
src/view/com/modals/ServerInput.tsx
··· 4 4 FontAwesomeIcon, 5 5 FontAwesomeIconStyle, 6 6 } from '@fortawesome/react-native-fontawesome' 7 - import {BottomSheetScrollView, BottomSheetTextInput} from '@gorhom/bottom-sheet' 7 + import {ScrollView, TextInput} from './util' 8 8 import {Text} from '../util/text/Text' 9 9 import {useStores} from '../../../state' 10 10 import {s, colors} from '../../lib/styles' ··· 32 32 return ( 33 33 <View style={s.flex1} testID="serverInputModal"> 34 34 <Text style={[s.textCenter, s.bold, s.f18]}>Choose Service</Text> 35 - <BottomSheetScrollView style={styles.inner}> 35 + <ScrollView style={styles.inner}> 36 36 <View style={styles.group}> 37 37 {LOGIN_INCLUDE_DEV_SERVERS ? ( 38 38 <> ··· 69 69 <View style={styles.group}> 70 70 <Text style={styles.label}>Other service</Text> 71 71 <View style={s.flexRow}> 72 - <BottomSheetTextInput 72 + <TextInput 73 73 testID="customServerTextInput" 74 74 style={styles.textInput} 75 75 placeholder="e.g. https://bsky.app" ··· 92 92 </TouchableOpacity> 93 93 </View> 94 94 </View> 95 - </BottomSheetScrollView> 95 + </ScrollView> 96 96 </View> 97 97 ) 98 98 }
+4
src/view/com/modals/util.tsx
··· 1 + export { 2 + BottomSheetScrollView as ScrollView, 3 + BottomSheetTextInput as TextInput, 4 + } from '@gorhom/bottom-sheet'
+1
src/view/com/modals/util.web.tsx
··· 1 + export {ScrollView, TextInput} from 'react-native'
+3
src/view/shell/web/index.tsx
··· 9 9 import {Login} from '../../screens/Login' 10 10 import {ErrorBoundary} from '../../com/util/ErrorBoundary' 11 11 import {Lightbox} from '../../com/lightbox/Lightbox' 12 + import {Modal} from '../../com/modals/Modal' 12 13 import {usePalette} from '../../lib/hooks/usePalette' 13 14 import {s} from '../../lib/styles' 14 15 ··· 21 22 return ( 22 23 <View style={styles.outerContainer}> 23 24 <Login /> 25 + <Modal /> 24 26 </View> 25 27 ) 26 28 } ··· 47 49 ))} 48 50 <DesktopLeftColumn /> 49 51 <DesktopRightColumn /> 52 + <Modal /> 50 53 <Lightbox /> 51 54 </View> 52 55 )