diff options
Diffstat (limited to 'src/view/com/modals')
-rw-r--r-- | src/view/com/modals/EditProfile.tsx | 4 | ||||
-rw-r--r-- | src/view/com/modals/Modal.tsx | 53 | ||||
-rw-r--r-- | src/view/com/modals/Modal.web.tsx | 78 | ||||
-rw-r--r-- | src/view/com/modals/crop-image/CropImage.web.tsx | 24 |
4 files changed, 77 insertions, 82 deletions
diff --git a/src/view/com/modals/EditProfile.tsx b/src/view/com/modals/EditProfile.tsx index add75e89e..f822fcfd9 100644 --- a/src/view/com/modals/EditProfile.tsx +++ b/src/view/com/modals/EditProfile.tsx @@ -8,7 +8,7 @@ import { } from 'react-native' import LinearGradient from 'react-native-linear-gradient' import {ScrollView, TextInput} from './util' -import {PickedMedia} from '../util/images/image-crop-picker/ImageCropPicker' +import {PickedMedia} from '../../../lib/media/picker' import {Text} from '../util/text/Text' import {ErrorMessage} from '../util/error/ErrorMessage' import {useStores} from 'state/index' @@ -16,7 +16,7 @@ import {ProfileViewModel} from 'state/models/profile-view' import {s, colors, gradients} from 'lib/styles' import {enforceLen} from 'lib/strings/helpers' import {MAX_DISPLAY_NAME, MAX_DESCRIPTION} from 'lib/constants' -import {compressIfNeeded} from 'lib/images' +import {compressIfNeeded} from 'lib/media/manip' import {UserBanner} from '../util/UserBanner' import {UserAvatar} from '../util/UserAvatar' import {usePalette} from 'lib/hooks/usePalette' diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index 2529d0d5b..58dd12e61 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -5,8 +5,6 @@ import BottomSheet from '@gorhom/bottom-sheet' import {useStores} from 'state/index' import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop' -import * as models from 'state/models/shell-ui' - import * as ConfirmModal from './Confirm' import * as EditProfileModal from './EditProfile' import * as ServerInputModal from './ServerInput' @@ -18,7 +16,7 @@ import {StyleSheet} from 'react-native' const CLOSED_SNAPPOINTS = ['10%'] -export const Modal = observer(function Modal() { +export const ModalsContainer = observer(function ModalsContainer() { const store = useStores() const bottomSheetRef = useRef<BottomSheet>(null) const pal = usePalette('default') @@ -32,52 +30,37 @@ export const Modal = observer(function Modal() { store.shell.closeModal() } + const activeModal = React.useMemo( + () => store.shell.activeModals.at(-1), + [store.shell.activeModals], + ) + useEffect(() => { if (store.shell.isModalActive) { bottomSheetRef.current?.expand() } else { bottomSheetRef.current?.close() } - }, [store.shell.isModalActive, bottomSheetRef, store.shell.activeModal?.name]) + }, [store.shell.isModalActive, bottomSheetRef, activeModal?.name]) let snapPoints: (string | number)[] = CLOSED_SNAPPOINTS let element - if (store.shell.activeModal?.name === 'confirm') { + if (activeModal?.name === 'confirm') { snapPoints = ConfirmModal.snapPoints - element = ( - <ConfirmModal.Component - {...(store.shell.activeModal as models.ConfirmModal)} - /> - ) - } else if (store.shell.activeModal?.name === 'edit-profile') { + element = <ConfirmModal.Component {...activeModal} /> + } else if (activeModal?.name === 'edit-profile') { snapPoints = EditProfileModal.snapPoints - element = ( - <EditProfileModal.Component - {...(store.shell.activeModal as models.EditProfileModal)} - /> - ) - } else if (store.shell.activeModal?.name === 'server-input') { + element = <EditProfileModal.Component {...activeModal} /> + } else if (activeModal?.name === 'server-input') { snapPoints = ServerInputModal.snapPoints - element = ( - <ServerInputModal.Component - {...(store.shell.activeModal as models.ServerInputModal)} - /> - ) - } else if (store.shell.activeModal?.name === 'report-post') { + element = <ServerInputModal.Component {...activeModal} /> + } else if (activeModal?.name === 'report-post') { snapPoints = ReportPostModal.snapPoints - element = ( - <ReportPostModal.Component - {...(store.shell.activeModal as models.ReportPostModal)} - /> - ) - } else if (store.shell.activeModal?.name === 'report-account') { + element = <ReportPostModal.Component {...activeModal} /> + } else if (activeModal?.name === 'report-account') { snapPoints = ReportAccountModal.snapPoints - element = ( - <ReportAccountModal.Component - {...(store.shell.activeModal as models.ReportAccountModal)} - /> - ) - } else if (store.shell.activeModal?.name === 'delete-account') { + element = <ReportAccountModal.Component {...activeModal} /> + } else if (activeModal?.name === 'delete-account') { snapPoints = DeleteAccountModal.snapPoints element = <DeleteAccountModal.Component /> } else { diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index 3c6551093..38b526d29 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -3,8 +3,7 @@ import {TouchableWithoutFeedback, StyleSheet, View} from 'react-native' import {observer} from 'mobx-react-lite' import {useStores} from 'state/index' import {usePalette} from 'lib/hooks/usePalette' - -import * as models from 'state/models/shell-ui' +import type {Modal as ModalIface} from 'state/models/shell-ui' import * as ConfirmModal from './Confirm' import * as EditProfileModal from './EditProfile' @@ -13,7 +12,23 @@ import * as ReportPostModal from './ReportPost' import * as ReportAccountModal from './ReportAccount' import * as CropImageModal from './crop-image/CropImage.web' -export const Modal = observer(function Modal() { +export const ModalsContainer = observer(function ModalsContainer() { + const store = useStores() + + if (!store.shell.isModalActive) { + return null + } + + return ( + <> + {store.shell.activeModals.map((modal, i) => ( + <Modal key={`modal-${i}`} modal={modal} /> + ))} + </> + ) +}) + +function Modal({modal}: {modal: ModalIface}) { const store = useStores() const pal = usePalette('default') @@ -21,7 +36,10 @@ export const Modal = observer(function Modal() { return null } - const onClose = () => { + const onPressMask = () => { + if (modal.name === 'crop-image') { + return // dont close on mask presses during crop + } store.shell.closeModal() } const onInnerPress = () => { @@ -29,48 +47,24 @@ export const Modal = observer(function Modal() { } 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 - {...(store.shell.activeModal as models.ReportPostModal)} - /> - ) - } else if (store.shell.activeModal?.name === 'report-account') { - element = ( - <ReportAccountModal.Component - {...(store.shell.activeModal as models.ReportAccountModal)} - /> - ) - } else if (store.shell.activeModal?.name === 'crop-image') { - element = ( - <CropImageModal.Component - {...(store.shell.activeModal as models.CropImageModal)} - /> - ) + if (modal.name === 'confirm') { + element = <ConfirmModal.Component {...modal} /> + } else if (modal.name === 'edit-profile') { + element = <EditProfileModal.Component {...modal} /> + } else if (modal.name === 'server-input') { + element = <ServerInputModal.Component {...modal} /> + } else if (modal.name === 'report-post') { + element = <ReportPostModal.Component {...modal} /> + } else if (modal.name === 'report-account') { + element = <ReportAccountModal.Component {...modal} /> + } else if (modal.name === 'crop-image') { + element = <CropImageModal.Component {...modal} /> } else { return null } return ( - <TouchableWithoutFeedback onPress={onClose}> + <TouchableWithoutFeedback onPress={onPressMask}> <View style={styles.mask}> <TouchableWithoutFeedback onPress={onInnerPress}> <View style={[styles.container, pal.view]}>{element}</View> @@ -78,7 +72,7 @@ export const Modal = observer(function Modal() { </View> </TouchableWithoutFeedback> ) -}) +} const styles = StyleSheet.create({ mask: { diff --git a/src/view/com/modals/crop-image/CropImage.web.tsx b/src/view/com/modals/crop-image/CropImage.web.tsx index e43f37397..c774b94e1 100644 --- a/src/view/com/modals/crop-image/CropImage.web.tsx +++ b/src/view/com/modals/crop-image/CropImage.web.tsx @@ -38,6 +38,7 @@ export function Component({ const pal = usePalette('default') const [as, setAs] = React.useState<AspectRatio>(AspectRatio.Square) const [scale, setScale] = React.useState<number>(1) + const editorRef = React.useRef<ImageEditor>(null) const doSetAs = (v: AspectRatio) => () => setAs(v) @@ -46,8 +47,20 @@ export function Component({ store.shell.closeModal() } const onPressDone = () => { - console.log('TODO') - onSelect(undefined) // TODO + const canvas = editorRef.current?.getImageScaledToCanvas() + if (canvas) { + const dataUri = canvas.toDataURL('image/jpeg') + onSelect({ + mediaType: 'photo', + path: dataUri, + mime: 'image/jpeg', + size: Math.round((dataUri.length * 3) / 4), // very rough estimate + width: DIMS[as].width, + height: DIMS[as].height, + }) + } else { + onSelect(undefined) + } store.shell.closeModal() } @@ -61,13 +74,15 @@ export function Component({ } return ( <View> - <View style={[styles.cropper, cropperStyle]}> + <View style={[styles.cropper, pal.borderDark, cropperStyle]}> <ImageEditor + ref={editorRef} style={styles.imageEditor} image={uri} width={DIMS[as].width} height={DIMS[as].height} scale={scale} + border={0} /> </View> <View style={styles.ctrls}> @@ -126,6 +141,9 @@ const styles = StyleSheet.create({ cropper: { marginLeft: 'auto', marginRight: 'auto', + borderWidth: 1, + borderRadius: 4, + overflow: 'hidden', }, cropperSquare: { width: 400, |