about summary refs log tree commit diff
path: root/src/view/com/modals
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/modals')
-rw-r--r--src/view/com/modals/EditProfile.tsx4
-rw-r--r--src/view/com/modals/Modal.tsx53
-rw-r--r--src/view/com/modals/Modal.web.tsx78
-rw-r--r--src/view/com/modals/crop-image/CropImage.web.tsx24
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,