diff options
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/com/composer/ComposePost.tsx | 49 | ||||
-rw-r--r-- | src/view/com/composer/photos/PhotoCarouselPicker.tsx | 91 | ||||
-rw-r--r-- | src/view/com/composer/photos/PhotoCarouselPicker.web.tsx | 156 | ||||
-rw-r--r-- | src/view/com/lightbox/Lightbox.tsx | 2 | ||||
-rw-r--r-- | src/view/com/modals/EditProfile.tsx | 4 | ||||
-rw-r--r-- | src/view/com/modals/Modal.web.tsx | 7 | ||||
-rw-r--r-- | src/view/com/modals/crop-image/CropImage.web.tsx | 24 | ||||
-rw-r--r-- | src/view/com/util/PostEmbeds/index.tsx | 2 | ||||
-rw-r--r-- | src/view/com/util/UserAvatar.tsx | 2 | ||||
-rw-r--r-- | src/view/com/util/UserBanner.tsx | 2 | ||||
-rw-r--r-- | src/view/com/util/images/image-crop-picker/ImageCropPicker.tsx | 92 | ||||
-rw-r--r-- | src/view/com/util/images/image-crop-picker/ImageCropPicker.web.tsx | 75 | ||||
-rw-r--r-- | src/view/com/util/images/image-crop-picker/types.ts | 31 |
13 files changed, 104 insertions, 433 deletions
diff --git a/src/view/com/composer/ComposePost.tsx b/src/view/com/composer/ComposePost.tsx index 6431a11aa..6f8fe460d 100644 --- a/src/view/com/composer/ComposePost.tsx +++ b/src/view/com/composer/ComposePost.tsx @@ -36,11 +36,18 @@ import {s, colors, gradients} from 'lib/styles' import {cleanError} from 'lib/strings/errors' import {detectLinkables, extractEntities} from 'lib/strings/rich-text-detection' import {getLinkMeta} from 'lib/link-meta/link-meta' -import {downloadAndResize} from 'lib/images' -import {PhotoCarouselPicker, cropPhoto} from './photos/PhotoCarouselPicker' +import {getImageDim, downloadAndResize} from 'lib/media/manip' +import {PhotoCarouselPicker} from './photos/PhotoCarouselPicker' +import {cropAndCompressFlow, pickImagesFlow} from '../../../lib/media/picker' import {getMentionAt, insertMentionAt} from 'lib/strings/mention-manip' import {SelectedPhoto} from './SelectedPhoto' import {usePalette} from 'lib/hooks/usePalette' +import { + POST_IMG_MAX_WIDTH, + POST_IMG_MAX_HEIGHT, + POST_IMG_MAX_SIZE, +} from 'lib/constants' +import {isWeb} from 'platform/detection' const MAX_TEXT_LENGTH = 256 const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10} @@ -61,7 +68,7 @@ export const ComposePost = observer(function ComposePost({ onPost?: ComposerOpts['onPost'] onClose: () => void }) { - const {track, screen} = useAnalytics() + const {track} = useAnalytics() const pal = usePalette('default') const store = useStores() const textInput = useRef<TextInputRef>(null) @@ -174,12 +181,24 @@ export const ComposePost = observer(function ComposePost({ const onPressContainer = () => { textInput.current?.focus() } - const onPressSelectPhotos = () => { + const onPressSelectPhotos = async () => { track('ComposePost:SelectPhotos') - if (isSelectingPhotos) { - setIsSelectingPhotos(false) - } else if (selectedPhotos.length < 4) { - setIsSelectingPhotos(true) + if (isWeb) { + if (selectedPhotos.length < 4) { + const images = await pickImagesFlow( + store, + 4 - selectedPhotos.length, + {width: POST_IMG_MAX_WIDTH, height: POST_IMG_MAX_HEIGHT}, + POST_IMG_MAX_SIZE, + ) + setSelectedPhotos([...selectedPhotos, ...images]) + } + } else { + if (isSelectingPhotos) { + setIsSelectingPhotos(false) + } else if (selectedPhotos.length < 4) { + setIsSelectingPhotos(true) + } } } const onSelectPhotos = (photos: string[]) => { @@ -220,7 +239,19 @@ export const ComposePost = observer(function ComposePost({ } const imgUri = uris.find(uri => /\.(jpe?g|png)$/.test(uri)) if (imgUri) { - const finalImgPath = await cropPhoto(store, imgUri) + let imgDim + try { + imgDim = await getImageDim(imgUri) + } catch (e) { + imgDim = {width: POST_IMG_MAX_WIDTH, height: POST_IMG_MAX_HEIGHT} + } + const finalImgPath = await cropAndCompressFlow( + store, + imgUri, + imgDim, + {width: POST_IMG_MAX_WIDTH, height: POST_IMG_MAX_HEIGHT}, + POST_IMG_MAX_SIZE, + ) onSelectPhotos([...selectedPhotos, finalImgPath]) } } diff --git a/src/view/com/composer/photos/PhotoCarouselPicker.tsx b/src/view/com/composer/photos/PhotoCarouselPicker.tsx index 406f8b04c..ab2fdc478 100644 --- a/src/view/com/composer/photos/PhotoCarouselPicker.tsx +++ b/src/view/com/composer/photos/PhotoCarouselPicker.tsx @@ -9,57 +9,24 @@ import { openPicker, openCamera, openCropper, -} from '../../util/images/image-crop-picker/ImageCropPicker' + cropAndCompressFlow, +} from '../../../../lib/media/picker' import { UserLocalPhotosModel, PhotoIdentifier, } from 'state/models/user-local-photos' -import { - compressIfNeeded, - moveToPremanantPath, - scaleDownDimensions, -} from 'lib/images' +import {compressIfNeeded} from 'lib/media/manip' import {usePalette} from 'lib/hooks/usePalette' -import {useStores, RootStoreModel} from 'state/index' +import {useStores} from 'state/index' import { requestPhotoAccessIfNeeded, requestCameraAccessIfNeeded, } from 'lib/permissions' - -const MAX_WIDTH = 2000 -const MAX_HEIGHT = 2000 -const MAX_SIZE = 1000000 - -const IMAGE_PARAMS = { - width: 2000, - height: 2000, - freeStyleCropEnabled: true, -} - -export async function cropPhoto( - store: RootStoreModel, - path: string, - imgWidth = MAX_WIDTH, - imgHeight = MAX_HEIGHT, -) { - // choose target dimensions based on the original - // this causes the photo cropper to start with the full image "selected" - const {width, height} = scaleDownDimensions( - {width: imgWidth, height: imgHeight}, - {width: MAX_WIDTH, height: MAX_HEIGHT}, - ) - const cropperRes = await openCropper(store, { - mediaType: 'photo', - path, - freeStyleCropEnabled: true, - width, - height, - }) - - const img = await compressIfNeeded(cropperRes, MAX_SIZE) - const permanentPath = await moveToPremanantPath(img.path) - return permanentPath -} +import { + POST_IMG_MAX_WIDTH, + POST_IMG_MAX_HEIGHT, + POST_IMG_MAX_SIZE, +} from 'lib/constants' export const PhotoCarouselPicker = ({ selectedPhotos, @@ -92,9 +59,11 @@ export const PhotoCarouselPicker = ({ } const cameraRes = await openCamera(store, { mediaType: 'photo', - ...IMAGE_PARAMS, + width: POST_IMG_MAX_WIDTH, + height: POST_IMG_MAX_HEIGHT, + freeStyleCropEnabled: true, }) - const img = await compressIfNeeded(cameraRes, MAX_SIZE) + const img = await compressIfNeeded(cameraRes, POST_IMG_MAX_SIZE) onSelectPhotos([...selectedPhotos, img.path]) } catch (err: any) { // ignore @@ -106,11 +75,15 @@ export const PhotoCarouselPicker = ({ async (item: PhotoIdentifier) => { track('PhotoCarouselPicker:PhotoSelected') try { - const imgPath = await cropPhoto( + const imgPath = await cropAndCompressFlow( store, item.node.image.uri, - item.node.image.width, - item.node.image.height, + { + width: item.node.image.width, + height: item.node.image.height, + }, + {width: POST_IMG_MAX_WIDTH, height: POST_IMG_MAX_HEIGHT}, + POST_IMG_MAX_SIZE, ) onSelectPhotos([...selectedPhotos, imgPath]) } catch (err: any) { @@ -132,24 +105,16 @@ export const PhotoCarouselPicker = ({ mediaType: 'photo', }) const result = [] - for (const image of items) { - // choose target dimensions based on the original - // this causes the photo cropper to start with the full image "selected" - const {width, height} = scaleDownDimensions( - {width: image.width, height: image.height}, - {width: MAX_WIDTH, height: MAX_HEIGHT}, + result.push( + await cropAndCompressFlow( + store, + image.path, + image, + {width: POST_IMG_MAX_WIDTH, height: POST_IMG_MAX_HEIGHT}, + POST_IMG_MAX_SIZE, + ), ) - const cropperRes = await openCropper(store, { - mediaType: 'photo', - path: image.path, - ...IMAGE_PARAMS, - width, - height, - }) - const finalImg = await compressIfNeeded(cropperRes, MAX_SIZE) - const permanentPath = await moveToPremanantPath(finalImg.path) - result.push(permanentPath) } onSelectPhotos([...selectedPhotos, ...result]) }, [track, store, selectedPhotos, onSelectPhotos]) diff --git a/src/view/com/composer/photos/PhotoCarouselPicker.web.tsx b/src/view/com/composer/photos/PhotoCarouselPicker.web.tsx index 607f8e724..ff4350b0c 100644 --- a/src/view/com/composer/photos/PhotoCarouselPicker.web.tsx +++ b/src/view/com/composer/photos/PhotoCarouselPicker.web.tsx @@ -1,158 +1,10 @@ -import React, {useCallback} from 'react' -import {StyleSheet, TouchableOpacity, ScrollView} from 'react-native' -import { - FontAwesomeIcon, - FontAwesomeIconStyle, -} from '@fortawesome/react-native-fontawesome' -import { - openPicker, - openCamera, - openCropper, -} from '../../util/images/image-crop-picker/ImageCropPicker' -import {compressIfNeeded, scaleDownDimensions} from 'lib/images' -import {usePalette} from 'lib/hooks/usePalette' -import {useStores, RootStoreModel} from 'state/index' +import React from 'react' -const MAX_WIDTH = 1000 -const MAX_HEIGHT = 1000 -const MAX_SIZE = 300000 +// Not used on Web -const IMAGE_PARAMS = { - width: 1000, - height: 1000, - freeStyleCropEnabled: true, -} - -export async function cropPhoto( - store: RootStoreModel, - path: string, - imgWidth = MAX_WIDTH, - imgHeight = MAX_HEIGHT, -) { - // choose target dimensions based on the original - // this causes the photo cropper to start with the full image "selected" - const {width, height} = scaleDownDimensions( - {width: imgWidth, height: imgHeight}, - {width: MAX_WIDTH, height: MAX_HEIGHT}, - ) - const cropperRes = await openCropper(store, { - mediaType: 'photo', - path, - freeStyleCropEnabled: true, - width, - height, - }) - const img = await compressIfNeeded(cropperRes, MAX_SIZE) - return img.path -} - -export const PhotoCarouselPicker = ({ - selectedPhotos, - onSelectPhotos, -}: { +export const PhotoCarouselPicker = (_opts: { selectedPhotos: string[] onSelectPhotos: (v: string[]) => void }) => { - const pal = usePalette('default') - const store = useStores() - - const handleOpenCamera = useCallback(async () => { - try { - const cameraRes = await openCamera(store, { - mediaType: 'photo', - ...IMAGE_PARAMS, - }) - const img = await compressIfNeeded(cameraRes, MAX_SIZE) - onSelectPhotos([...selectedPhotos, img.path]) - } catch (err: any) { - // ignore - store.log.warn('Error using camera', err) - } - }, [store, selectedPhotos, onSelectPhotos]) - - const handleOpenGallery = useCallback(() => { - openPicker(store, { - multiple: true, - maxFiles: 4 - selectedPhotos.length, - mediaType: 'photo', - }).then(async items => { - const result = [] - - for (const image of items) { - // choose target dimensions based on the original - // this causes the photo cropper to start with the full image "selected" - const {width, height} = scaleDownDimensions( - {width: image.width, height: image.height}, - {width: MAX_WIDTH, height: MAX_HEIGHT}, - ) - const cropperRes = await openCropper(store, { - mediaType: 'photo', - path: image.path, - freeStyleCropEnabled: true, - width, - height, - }) - const finalImg = await compressIfNeeded(cropperRes, MAX_SIZE) - result.push(finalImg.path) - } - onSelectPhotos([...selectedPhotos, ...result]) - }) - }, [store, selectedPhotos, onSelectPhotos]) - - return ( - <ScrollView - testID="photoCarouselPickerView" - horizontal - style={[pal.view, styles.photosContainer]} - keyboardShouldPersistTaps="always" - showsHorizontalScrollIndicator={false}> - <TouchableOpacity - testID="openCameraButton" - style={[styles.galleryButton, pal.border, styles.photo]} - onPress={handleOpenCamera}> - <FontAwesomeIcon - icon="camera" - size={24} - style={pal.link as FontAwesomeIconStyle} - /> - </TouchableOpacity> - <TouchableOpacity - testID="openGalleryButton" - style={[styles.galleryButton, pal.border, styles.photo]} - onPress={handleOpenGallery}> - <FontAwesomeIcon - icon="image" - style={pal.link as FontAwesomeIconStyle} - size={24} - /> - </TouchableOpacity> - </ScrollView> - ) + return <></> } - -const styles = StyleSheet.create({ - photosContainer: { - width: '100%', - maxHeight: 96, - padding: 8, - overflow: 'hidden', - }, - galleryButton: { - borderWidth: 1, - alignItems: 'center', - justifyContent: 'center', - }, - photoButton: { - width: 75, - height: 75, - marginRight: 8, - borderWidth: 1, - borderRadius: 16, - }, - photo: { - width: 75, - height: 75, - marginRight: 8, - borderRadius: 16, - }, -}) diff --git a/src/view/com/lightbox/Lightbox.tsx b/src/view/com/lightbox/Lightbox.tsx index 894c6b118..7509e07c4 100644 --- a/src/view/com/lightbox/Lightbox.tsx +++ b/src/view/com/lightbox/Lightbox.tsx @@ -4,7 +4,7 @@ import {observer} from 'mobx-react-lite' import ImageView from './ImageViewing' import {useStores} from 'state/index' import * as models from 'state/models/shell-ui' -import {saveImageModal} from 'lib/images' +import {saveImageModal} from 'lib/media/manip' import {ImageSource} from './ImageViewing/@types' export const Lightbox = observer(function Lightbox() { 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.web.tsx b/src/view/com/modals/Modal.web.tsx index 3c6551093..2af02695a 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -21,7 +21,10 @@ export const Modal = observer(function Modal() { return null } - const onClose = () => { + const onPressMask = () => { + if (store.shell.activeModal?.name === 'crop-image') { + return // dont close on mask presses during crop + } store.shell.closeModal() } const onInnerPress = () => { @@ -70,7 +73,7 @@ export const Modal = observer(function Modal() { } return ( - <TouchableWithoutFeedback onPress={onClose}> + <TouchableWithoutFeedback onPress={onPressMask}> <View style={styles.mask}> <TouchableWithoutFeedback onPress={onInnerPress}> <View style={[styles.container, pal.view]}>{element}</View> 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, diff --git a/src/view/com/util/PostEmbeds/index.tsx b/src/view/com/util/PostEmbeds/index.tsx index 031f01e88..d2186b600 100644 --- a/src/view/com/util/PostEmbeds/index.tsx +++ b/src/view/com/util/PostEmbeds/index.tsx @@ -13,7 +13,7 @@ import {ImageLayoutGrid} from '../images/ImageLayoutGrid' import {ImagesLightbox} from 'state/models/shell-ui' import {useStores} from 'state/index' import {usePalette} from 'lib/hooks/usePalette' -import {saveImageModal} from 'lib/images' +import {saveImageModal} from 'lib/media/manip' import YoutubeEmbed from './YoutubeEmbed' import ExternalLinkEmbed from './ExternalLinkEmbed' import {getYoutubeVideoId} from 'lib/strings/url-helpers' diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index 9b8dd3de5..0c5c9d254 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -9,7 +9,7 @@ import { openCropper, openPicker, PickedMedia, -} from './images/image-crop-picker/ImageCropPicker' +} from '../../../lib/media/picker' import { requestPhotoAccessIfNeeded, requestCameraAccessIfNeeded, diff --git a/src/view/com/util/UserBanner.tsx b/src/view/com/util/UserBanner.tsx index dc140b035..c17294f3d 100644 --- a/src/view/com/util/UserBanner.tsx +++ b/src/view/com/util/UserBanner.tsx @@ -10,7 +10,7 @@ import { openCropper, openPicker, PickedMedia, -} from './images/image-crop-picker/ImageCropPicker' +} from '../../../lib/media/picker' import {useStores} from 'state/index' import { requestPhotoAccessIfNeeded, diff --git a/src/view/com/util/images/image-crop-picker/ImageCropPicker.tsx b/src/view/com/util/images/image-crop-picker/ImageCropPicker.tsx deleted file mode 100644 index d723fef99..000000000 --- a/src/view/com/util/images/image-crop-picker/ImageCropPicker.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { - openPicker as openPickerFn, - openCamera as openCameraFn, - openCropper as openCropperFn, - ImageOrVideo, -} from 'react-native-image-crop-picker' -import {RootStoreModel} from 'state/index' -import {PickerOpts, CameraOpts, CropperOpts, PickedMedia} from './types' -export type {PickedMedia} from './types' - -/** - * NOTE - * These methods all include the RootStoreModel as the first param - * because the web versions require it. The signatures have to remain - * equivalent between the different forms, but the store param is not - * used here. - * -prf - */ - -export async function openPicker( - _store: RootStoreModel, - opts: PickerOpts, -): Promise<PickedMedia[]> { - const mediaType = opts.mediaType || 'photo' - const items = await openPickerFn({ - mediaType, - multiple: opts.multiple, - maxFiles: opts.maxFiles, - }) - const toMedia = (item: ImageOrVideo) => ({ - mediaType, - path: item.path, - mime: item.mime, - size: item.size, - width: item.width, - height: item.height, - }) - if (Array.isArray(items)) { - return items.map(toMedia) - } - return [toMedia(items)] -} - -export async function openCamera( - _store: RootStoreModel, - opts: CameraOpts, -): Promise<PickedMedia> { - const mediaType = opts.mediaType || 'photo' - const item = await openCameraFn({ - mediaType, - width: opts.width, - height: opts.height, - freeStyleCropEnabled: opts.freeStyleCropEnabled, - cropperCircleOverlay: opts.cropperCircleOverlay, - cropping: true, - forceJpg: true, // ios only - compressImageQuality: 1.0, - }) - return { - mediaType, - path: item.path, - mime: item.mime, - size: item.size, - width: item.width, - height: item.height, - } -} - -export async function openCropper( - _store: RootStoreModel, - opts: CropperOpts, -): Promise<PickedMedia> { - const mediaType = opts.mediaType || 'photo' - const item = await openCropperFn({ - path: opts.path, - mediaType: opts.mediaType || 'photo', - width: opts.width, - height: opts.height, - freeStyleCropEnabled: opts.freeStyleCropEnabled, - cropperCircleOverlay: opts.cropperCircleOverlay, - forceJpg: true, // ios only - compressImageQuality: 1.0, - }) - return { - mediaType, - path: item.path, - mime: item.mime, - size: item.size, - width: item.width, - height: item.height, - } -} diff --git a/src/view/com/util/images/image-crop-picker/ImageCropPicker.web.tsx b/src/view/com/util/images/image-crop-picker/ImageCropPicker.web.tsx deleted file mode 100644 index d632590d6..000000000 --- a/src/view/com/util/images/image-crop-picker/ImageCropPicker.web.tsx +++ /dev/null @@ -1,75 +0,0 @@ -/// <reference lib="dom" /> - -import {CropImageModal} from 'state/models/shell-ui' -import {PickerOpts, CameraOpts, CropperOpts, PickedMedia} from './types' -export type {PickedMedia} from './types' -import {RootStoreModel} from 'state/index' - -interface PickedFile { - uri: string - path: string - size: number -} - -export async function openPicker( - store: RootStoreModel, - opts: PickerOpts, -): Promise<PickedMedia[] | PickedMedia> { - const res = await selectFile(opts) - return new Promise((resolve, reject) => { - store.shell.openModal( - new CropImageModal(res.uri, (img?: PickedMedia) => { - if (img) { - resolve(img) - } else { - reject(new Error('Canceled')) - } - }), - ) - }) -} - -export async function openCamera( - _store: RootStoreModel, - _opts: CameraOpts, -): Promise<PickedMedia> { - // const mediaType = opts.mediaType || 'photo' TODO - throw new Error('TODO') -} - -export async function openCropper( - _store: RootStoreModel, - _opts: CropperOpts, -): Promise<PickedMedia> { - // const mediaType = opts.mediaType || 'photo' TODO - throw new Error('TODO') -} - -function selectFile(opts: PickerOpts): Promise<PickedFile> { - return new Promise((resolve, reject) => { - var input = document.createElement('input') - input.type = 'file' - input.accept = opts.mediaType === 'photo' ? 'image/*' : '*/*' - input.onchange = e => { - const target = e.target as HTMLInputElement - const file = target?.files?.[0] - if (!file) { - return reject(new Error('Canceled')) - } - - var reader = new FileReader() - reader.readAsDataURL(file) - reader.onload = readerEvent => { - if (!readerEvent.target) { - return reject(new Error('Canceled')) - } - resolve({ - uri: readerEvent.target.result as string, - path: file.name, - size: file.size, - }) - } - } - input.click() - }) -} diff --git a/src/view/com/util/images/image-crop-picker/types.ts b/src/view/com/util/images/image-crop-picker/types.ts deleted file mode 100644 index 3197b4d3e..000000000 --- a/src/view/com/util/images/image-crop-picker/types.ts +++ /dev/null @@ -1,31 +0,0 @@ -export interface PickerOpts { - mediaType?: 'photo' - multiple?: boolean - maxFiles?: number -} - -export interface CameraOpts { - mediaType?: 'photo' - width: number - height: number - freeStyleCropEnabled?: boolean - cropperCircleOverlay?: boolean -} - -export interface CropperOpts { - path: string - mediaType?: 'photo' - width: number - height: number - freeStyleCropEnabled?: boolean - cropperCircleOverlay?: boolean -} - -export interface PickedMedia { - mediaType: 'photo' - path: string - mime: string - size: number - width: number - height: number -} |