Implement modals for web

zio/stable
Paul Frazee 2023-01-26 22:25:38 -06:00
parent 24559599f3
commit 4b33cdb7ec
6 changed files with 102 additions and 9 deletions

View File

@ -7,7 +7,7 @@ import {
View, View,
} from 'react-native' } from 'react-native'
import LinearGradient from 'react-native-linear-gradient' import LinearGradient from 'react-native-linear-gradient'
import {BottomSheetScrollView, BottomSheetTextInput} from '@gorhom/bottom-sheet' import {ScrollView, TextInput} from './util'
import {Image as PickedImage} from '../util/images/ImageCropPicker' import {Image as PickedImage} from '../util/images/ImageCropPicker'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {ErrorMessage} from '../util/error/ErrorMessage' import {ErrorMessage} from '../util/error/ErrorMessage'
@ -102,7 +102,7 @@ export function Component({
return ( return (
<View style={s.flex1}> <View style={s.flex1}>
<BottomSheetScrollView style={styles.inner}> <ScrollView style={styles.inner}>
<Text style={styles.title}>Edit my profile</Text> <Text style={styles.title}>Edit my profile</Text>
<View style={styles.photos}> <View style={styles.photos}>
<UserBanner <UserBanner
@ -126,7 +126,7 @@ export function Component({
)} )}
<View> <View>
<Text style={styles.label}>Display Name</Text> <Text style={styles.label}>Display Name</Text>
<BottomSheetTextInput <TextInput
style={styles.textInput} style={styles.textInput}
placeholder="e.g. Alice Roberts" placeholder="e.g. Alice Roberts"
placeholderTextColor={colors.gray4} placeholderTextColor={colors.gray4}
@ -136,7 +136,7 @@ export function Component({
</View> </View>
<View style={s.pb10}> <View style={s.pb10}>
<Text style={styles.label}>Description</Text> <Text style={styles.label}>Description</Text>
<BottomSheetTextInput <TextInput
style={[styles.textArea]} style={[styles.textArea]}
placeholder="e.g. Artist, dog-lover, and memelord." placeholder="e.g. Artist, dog-lover, and memelord."
placeholderTextColor={colors.gray4} placeholderTextColor={colors.gray4}
@ -165,7 +165,7 @@ export function Component({
<Text style={[s.black, s.bold]}>Cancel</Text> <Text style={[s.black, s.bold]}>Cancel</Text>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
</BottomSheetScrollView> </ScrollView>
</View> </View>
) )
} }

View File

@ -0,0 +1,85 @@
import React from 'react'
import {TouchableWithoutFeedback, StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite'
import {useStores} from '../../../state'
import {usePalette} from '../../lib/hooks/usePalette'
import * as models from '../../../state/models/shell-ui'
import * as ConfirmModal from './Confirm'
import * as EditProfileModal from './EditProfile'
import * as ServerInputModal from './ServerInput'
import * as ReportPostModal from './ReportPost'
import * as ReportAccountModal from './ReportAccount'
export const Modal = observer(function Modal() {
const store = useStores()
const pal = usePalette('default')
if (!store.shell.isModalActive) {
return null
}
const onClose = () => {
store.shell.closeModal()
}
const onInnerPress = () => {
// do nothing, we just want to stop it from bubbling
}
let element
if (store.shell.activeModal?.name === 'confirm') {
element = (
<ConfirmModal.Component
{...(store.shell.activeModal as models.ConfirmModal)}
/>
)
} else if (store.shell.activeModal?.name === 'edit-profile') {
element = (
<EditProfileModal.Component
{...(store.shell.activeModal as models.EditProfileModal)}
/>
)
} else if (store.shell.activeModal?.name === 'server-input') {
element = (
<ServerInputModal.Component
{...(store.shell.activeModal as models.ServerInputModal)}
/>
)
} else if (store.shell.activeModal?.name === 'report-post') {
element = <ReportPostModal.Component />
} else if (store.shell.activeModal?.name === 'report-account') {
element = <ReportAccountModal.Component />
} else {
return null
}
return (
<TouchableWithoutFeedback onPress={onClose}>
<View style={styles.mask}>
<TouchableWithoutFeedback onPress={onInnerPress}>
<View style={[styles.container, pal.view]}>{element}</View>
</TouchableWithoutFeedback>
</View>
</TouchableWithoutFeedback>
)
})
const styles = StyleSheet.create({
mask: {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
backgroundColor: '#000c',
alignItems: 'center',
justifyContent: 'center',
},
container: {
width: 500,
paddingVertical: 20,
paddingHorizontal: 24,
borderRadius: 8,
},
})

View File

@ -4,7 +4,7 @@ import {
FontAwesomeIcon, FontAwesomeIcon,
FontAwesomeIconStyle, FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome' } from '@fortawesome/react-native-fontawesome'
import {BottomSheetScrollView, BottomSheetTextInput} from '@gorhom/bottom-sheet' import {ScrollView, TextInput} from './util'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {useStores} from '../../../state' import {useStores} from '../../../state'
import {s, colors} from '../../lib/styles' import {s, colors} from '../../lib/styles'
@ -32,7 +32,7 @@ export function Component({onSelect}: {onSelect: (url: string) => void}) {
return ( return (
<View style={s.flex1} testID="serverInputModal"> <View style={s.flex1} testID="serverInputModal">
<Text style={[s.textCenter, s.bold, s.f18]}>Choose Service</Text> <Text style={[s.textCenter, s.bold, s.f18]}>Choose Service</Text>
<BottomSheetScrollView style={styles.inner}> <ScrollView style={styles.inner}>
<View style={styles.group}> <View style={styles.group}>
{LOGIN_INCLUDE_DEV_SERVERS ? ( {LOGIN_INCLUDE_DEV_SERVERS ? (
<> <>
@ -69,7 +69,7 @@ export function Component({onSelect}: {onSelect: (url: string) => void}) {
<View style={styles.group}> <View style={styles.group}>
<Text style={styles.label}>Other service</Text> <Text style={styles.label}>Other service</Text>
<View style={s.flexRow}> <View style={s.flexRow}>
<BottomSheetTextInput <TextInput
testID="customServerTextInput" testID="customServerTextInput"
style={styles.textInput} style={styles.textInput}
placeholder="e.g. https://bsky.app" placeholder="e.g. https://bsky.app"
@ -92,7 +92,7 @@ export function Component({onSelect}: {onSelect: (url: string) => void}) {
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View> </View>
</BottomSheetScrollView> </ScrollView>
</View> </View>
) )
} }

View File

@ -0,0 +1,4 @@
export {
BottomSheetScrollView as ScrollView,
BottomSheetTextInput as TextInput,
} from '@gorhom/bottom-sheet'

View File

@ -0,0 +1 @@
export {ScrollView, TextInput} from 'react-native'

View File

@ -9,6 +9,7 @@ import {Onboard} from '../../screens/Onboard'
import {Login} from '../../screens/Login' import {Login} from '../../screens/Login'
import {ErrorBoundary} from '../../com/util/ErrorBoundary' import {ErrorBoundary} from '../../com/util/ErrorBoundary'
import {Lightbox} from '../../com/lightbox/Lightbox' import {Lightbox} from '../../com/lightbox/Lightbox'
import {Modal} from '../../com/modals/Modal'
import {usePalette} from '../../lib/hooks/usePalette' import {usePalette} from '../../lib/hooks/usePalette'
import {s} from '../../lib/styles' import {s} from '../../lib/styles'
@ -21,6 +22,7 @@ export const WebShell: React.FC = observer(() => {
return ( return (
<View style={styles.outerContainer}> <View style={styles.outerContainer}>
<Login /> <Login />
<Modal />
</View> </View>
) )
} }
@ -47,6 +49,7 @@ export const WebShell: React.FC = observer(() => {
))} ))}
<DesktopLeftColumn /> <DesktopLeftColumn />
<DesktopRightColumn /> <DesktopRightColumn />
<Modal />
<Lightbox /> <Lightbox />
</View> </View>
) )