diff options
author | Brian Kim <brian@tagg.id> | 2021-07-13 16:01:11 -0400 |
---|---|---|
committer | Brian Kim <brian@tagg.id> | 2021-07-13 16:01:11 -0400 |
commit | b7cba594635f4a6de3582ba4845bfc9757632ba1 (patch) | |
tree | 6336696356d8773bd505fe9c085cbb778f7e7b59 /src | |
parent | f12996bfd3bcdd9ae0589e4fd4ca740705ad6d29 (diff) |
Extremely rough working
Diffstat (limited to 'src')
-rw-r--r-- | src/components/comments/ZoomInCropper.tsx | 344 | ||||
-rw-r--r-- | src/screens/profile/CaptionScreen.tsx | 29 | ||||
-rw-r--r-- | src/utils/camera.ts | 39 | ||||
-rw-r--r-- | src/utils/index.ts | 1 |
4 files changed, 373 insertions, 40 deletions
diff --git a/src/components/comments/ZoomInCropper.tsx b/src/components/comments/ZoomInCropper.tsx index 7fa88f6e..3a492af3 100644 --- a/src/components/comments/ZoomInCropper.tsx +++ b/src/components/comments/ZoomInCropper.tsx @@ -1,15 +1,23 @@ import {RouteProp} from '@react-navigation/core'; import {useFocusEffect} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useState} from 'react'; -import {Image, StyleSheet, TouchableOpacity} from 'react-native'; +import React, {useCallback, useEffect, useRef, useState} from 'react'; +import {Image, StyleSheet, TouchableOpacity, View} from 'react-native'; import {normalize} from 'react-native-elements'; import ImageZoom, {IOnMove} from 'react-native-image-pan-zoom'; import PhotoManipulator from 'react-native-photo-manipulator'; import CloseIcon from '../../assets/ionicons/close-outline.svg'; import {MainStackParams} from '../../routes'; -import {HeaderHeight, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; +import { + cropVideo, + HeaderHeight, + SCREEN_HEIGHT, + SCREEN_WIDTH, + numberWithCommas, +} from '../../utils'; import {TaggSquareButton} from '../common'; +import ReactNativeZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView'; +import Video from 'react-native-video'; type ZoomInCropperRouteProps = RouteProp<MainStackParams, 'ZoomInCropper'>; type ZoomInCropperNavigationProps = StackNavigationProp< @@ -27,6 +35,9 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({ }) => { const {screenType, title, media} = route.params; const [aspectRatio, setAspectRatio] = useState<number>(1); + // width and height of video, if video + const [origDimensions, setOrigDimensions] = useState<number[]>([0, 0]); + const vidRef = useRef(null); // Stores the coordinates of the cropped image const [x0, setX0] = useState<number>(); @@ -34,6 +45,25 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({ const [y0, setY0] = useState<number>(); const [y1, setY1] = useState<number>(); + // Stores crop information for video + const [videoCrop, setVideoCrop] = useState<{ + cropWidth?: number; + cropHeight?: number; + cropOffsetX?: number; + cropOffsetY?: number; + }>({}); + + const checkIfUriImage = (uri: string) => { + return ( + uri.endsWith('jpg') || + uri.endsWith('JPG') || + uri.endsWith('PNG') || + uri.endsWith('png') || + uri.endsWith('GIF') || + uri.endsWith('gif') + ); + }; + useFocusEffect( useCallback(() => { navigation.dangerouslyGetParent()?.setOptions({ @@ -49,7 +79,7 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({ // Setting original aspect ratio of image useEffect(() => { - if (media.uri) { + if (media.uri && checkIfUriImage(media.uri)) { Image.getSize( media.uri, (w, h) => { @@ -57,45 +87,199 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({ }, (err) => console.log(err), ); + } else if (media.uri && !checkIfUriImage(media.uri)) { + const tempVideoCrop = {...videoCrop}; + tempVideoCrop.cropWidth = origDimensions[0]; + tempVideoCrop.cropHeight = origDimensions[1]; + setVideoCrop(tempVideoCrop); } }, []); + // Possible need to delay setting aspect ratio of video until loaded + useEffect(() => { + if (media.uri && !checkIfUriImage(media.uri)) { + const tempVideoCrop = {...videoCrop}; + tempVideoCrop.cropWidth = origDimensions[0]; + tempVideoCrop.cropHeight = origDimensions[1]; + setVideoCrop(tempVideoCrop); + } + }, [origDimensions]); + // Crops original image based of (x0, y0) and (x1, y1) coordinates const handleNext = () => { - if ( - x0 !== undefined && - x1 !== undefined && - y0 !== undefined && - y1 !== undefined - ) { - PhotoManipulator.crop(media.uri, { - x: x0, - y: y1, - width: Math.abs(x0 - x1), - height: Math.abs(y0 - y1), - }) - .then((croppedURL) => { + if (checkIfUriImage(media.uri)) { + if ( + x0 !== undefined && + x1 !== undefined && + y0 !== undefined && + y1 !== undefined + ) { + PhotoManipulator.crop(media.uri, { + x: x0, + y: y1, + width: Math.abs(x0 - x1), + height: Math.abs(y0 - y1), + }) + .then((croppedURL) => { + navigation.navigate('CaptionScreen', { + screenType, + title: title, + media: { + uri: croppedURL, + isVideo: false, + }, + }); + }) + .catch((err) => console.log('err: ', err)); + } else if ( + x0 === undefined && + x1 === undefined && + y0 === undefined && + y1 === undefined + ) { + navigation.navigate('CaptionScreen', { + screenType, + title: title, + media, + }); + } + } else { + if (!videoCrop.cropHeight || !videoCrop.cropWidth) { + const tempVideoCrop = {...videoCrop}; + tempVideoCrop.cropWidth = origDimensions[0]; + tempVideoCrop.cropHeight = origDimensions[1]; + setVideoCrop(tempVideoCrop); + } + cropVideo( + media.uri, + (croppedURL: string) => { navigation.navigate('CaptionScreen', { screenType, title: title, media: { uri: croppedURL, - isVideo: false, + isVideo: true, }, }); - }) - .catch((err) => console.log('err: ', err)); - } else if ( - x0 === undefined && - x1 === undefined && - y0 === undefined && - y1 === undefined - ) { - navigation.navigate('CaptionScreen', { - screenType, - title: title, - media, - }); + }, + videoCrop, + ); + } + }; + + // for whenever the video is altered by the user + const onVideoMove = (zoomableEvent: any) => { + const { + distanceBottom, + distanceLeft, + distanceRight, + distanceTop, + lastMovePinch, + lastX, + lastY, + lastZoomLevel, + offsetX, + offsetY, + originalHeight, + originalWidth, + zoomLevel, + } = zoomableEvent; + // let cropWidth = origDimensions[0] / (zoomLevel * aspectRatio); + // let cropOffsetX = Math.abs((origDimensions[0] - cropWidth) / 2); + // let screenScale = SCREEN_HEIGHT / origDimensions[1]; + // const relativeHeight = SCREEN_WIDTH / aspectRatio; + // let cropHeight = origDimensions[1]; + // let cropOffsetY = 0; + + let cropWidth = 0; + let cropHeight = 0; + let cropOffsetX = 0; + let cropOffsetY = 0; + + // if (aspectRatio > 1) { + // cropWidth = + // originalWidth * (originalWidth - (distanceLeft + distanceRight)); + // cropHeight = origDimensions[1]; + // } + + // console.log(relativeHeight * zoomLevel, SCREEN_HEIGHT, zoomLevel); + // if (cropHeight * screenScale > SCREEN_HEIGHT) { + // console.log('true'); + // } else { + // console.log('false'); + // } + + // console.log( + // aspectRatio, + // zoomLevel, + // originalWidth, + // originalHeight, + // origDimensions[0], + // origDimensions[1], + // cropWidth, + // cropHeight, + // distanceBottom, + // distanceLeft, + // distanceRight, + // distanceTop, + // SCREEN_WIDTH * zoomLevel - SCREEN_WIDTH, + // distanceBottom + distanceTop, + // distanceLeft + distanceRight, + // ); + // console.log( + // zoomLevel, + // distanceBottom, + // distanceLeft, + // distanceRight, + // distanceTop, + // originalWidth / (originalWidth - (distanceLeft + distanceRight)), + // ); + if (vidRef !== null && vidRef.current !== null) { + vidRef.current.measure( + ( + x: number, + y: number, + width: number, + height: number, + pageX: number, + pageY: number, + ) => { + // width + cropWidth = origDimensions[0] * (originalWidth / width); + + // offsetX + // cropOffsetX = (origDimensions[0] - cropWidth) / 2; + cropOffsetX = -1 * origDimensions[0] * (pageX / width); + if (cropOffsetX < 0) { + cropOffsetX = 0; + } else if (cropOffsetX + cropWidth > origDimensions[0]) { + cropOffsetX = origDimensions[0] - cropWidth - 1; + } + + // height + if ( + height * (SCREEN_WIDTH / aspectRatio / originalHeight) > + SCREEN_HEIGHT + ) { + const superHeight = width / aspectRatio; + cropHeight = origDimensions[1] * (originalHeight / superHeight); + // cropOffsetY = (origDimensions[1] - cropHeight) / 2; + if (cropOffsetY < 0) { + cropOffsetY = 0; + } else if (cropOffsetY + cropHeight > origDimensions[1]) { + cropOffsetY = origDimensions[1] - cropHeight - 1; + } + } else { + cropHeight = origDimensions[1]; + } + const tempVideoCrop = {...videoCrop}; + tempVideoCrop.cropWidth = cropWidth; + tempVideoCrop.cropHeight = cropHeight; + tempVideoCrop.cropOffsetX = cropOffsetX; + tempVideoCrop.cropOffsetY = cropOffsetY; + setVideoCrop(tempVideoCrop); + }, + ); } }; @@ -138,13 +322,13 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({ }; return ( - <> + <View style={styles.container}> <TouchableOpacity style={styles.closeButton} onPress={() => navigation.goBack()}> <CloseIcon height={25} width={25} color={'white'} /> </TouchableOpacity> - <ImageZoom + {/* <ImageZoom style={styles.zoomView} cropWidth={SCREEN_WIDTH} cropHeight={SCREEN_HEIGHT} @@ -157,7 +341,76 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({ uri: media.uri, }} /> - </ImageZoom> + </ImageZoom> */} + + {/* <Image style={{ flex: 1, width: null, height: '100%' }} + source={require('./image.jpg')} + resizeMode="contain" /> */} + {checkIfUriImage(media.uri) ? ( + <ImageZoom + style={styles.zoomView} + cropWidth={SCREEN_WIDTH} + cropHeight={SCREEN_HEIGHT} + imageWidth={SCREEN_WIDTH} + imageHeight={SCREEN_WIDTH / aspectRatio} + onMove={onMove}> + <Image + style={{width: SCREEN_WIDTH, height: SCREEN_WIDTH / aspectRatio}} + source={{ + uri: media.uri, + }} + /> + </ImageZoom> + ) : ( + <ReactNativeZoomableView + maxZoom={10} + minZoom={1} + zoomStep={0.5} + initialZoom={1} + bindToBorders={true} + // onZoomAfter={this.logOutZoomState} + onDoubleTapAfter={( + _1: any, + _2: any, + zoomableViewEventObject: any, + ) => { + onVideoMove(zoomableViewEventObject); + }} + onShiftingAfter={(_1: any, _2: any, zoomableViewEventObject: any) => { + onVideoMove(zoomableViewEventObject); + }} + onShiftingEnd={(_1: any, _2: any, zoomableViewEventObject: any) => { + onVideoMove(zoomableViewEventObject); + }} + onZoomAfter={(_1: any, _2: any, zoomableViewEventObject: any) => { + onVideoMove(zoomableViewEventObject); + }} + onZoomEnd={(_1: any, _2: any, zoomableViewEventObject: any) => { + onVideoMove(zoomableViewEventObject); + }} + style={styles.zoomView}> + <View style={styles.videoParent} ref={vidRef}> + <Video + source={{uri: media.uri}} + volume={1} + style={[ + styles.media, + { + height: SCREEN_WIDTH / aspectRatio, + }, + ]} + repeat={false} + resizeMode={'contain'} + onLoad={(response) => { + const {width, height} = response.naturalSize; + setOrigDimensions([width, height]); + setAspectRatio(width / height); + }} + /> + </View> + </ReactNativeZoomableView> + )} + <TaggSquareButton onPress={handleNext} title={'Next'} @@ -167,11 +420,18 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({ style={styles.button} labelStyle={styles.buttonLabel} /> - </> + </View> ); }; const styles = StyleSheet.create({ + container: { + backgroundColor: 'black', + height: SCREEN_HEIGHT, + width: SCREEN_WIDTH, + // flexDirection: 'column', + // justifyContent: 'center', + }, closeButton: { position: 'absolute', top: 0, @@ -195,5 +455,17 @@ const styles = StyleSheet.create({ letterSpacing: normalize(1.3), textAlign: 'center', }, - zoomView: {backgroundColor: 'black'}, + media: { + zIndex: 0, + flex: 1, + }, + videoParent: { + flex: 1, + }, + zoomView: { + backgroundColor: 'black', + flex: 1, + // borderColor: 'pink', + // borderWidth: 2, + }, }); diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx index c6cf767f..912865ae 100644 --- a/src/screens/profile/CaptionScreen.tsx +++ b/src/screens/profile/CaptionScreen.tsx @@ -69,8 +69,10 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { const [tags, setTags] = useState<MomentTagType[]>( selectedTags ? selectedTags : [], ); + const [aspectRatio, setAspectRatio] = useState<number>(1); const [taggedList, setTaggedList] = useState<string>(''); const mediaUri = moment ? moment.moment_url : route.params.media!.uri; + // console.log('mediaUri', mediaUri); // TODO: change this once moment refactor is done const isMediaAVideo = moment ? !( @@ -229,8 +231,8 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { {...{title: moment ? moment.moment_category : title ?? ''}} /> {isMediaAVideo ? ( - <> - <VideoPlayer + <View style={styles.mediaContainer}> + {/* <VideoPlayer //style={styles.media} ref={(ref) => (this.videoPlayerRef = ref)} startTime={startTime} // seconds @@ -260,8 +262,24 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { setStartTime(e.startTime); setEndTime(e.endTime); }} + /> */} + <Video + source={{uri: mediaUri}} + volume={1} + style={[ + styles.media, + { + height: SCREEN_WIDTH / aspectRatio, + }, + ]} + repeat={false} + resizeMode={'contain'} + onLoad={(response) => { + const {width, height} = response.naturalSize; + setAspectRatio(width / height); + }} /> - </> + </View> ) : ( <Image style={styles.media} @@ -331,6 +349,11 @@ const styles = StyleSheet.create({ width: SCREEN_WIDTH, aspectRatio: 1, marginBottom: '3%', + flex: 1, + }, + mediaContainer: { + width: SCREEN_WIDTH, + aspectRatio: 1, }, text: { position: 'relative', diff --git a/src/utils/camera.ts b/src/utils/camera.ts index ccdd42b0..2f189a1d 100644 --- a/src/utils/camera.ts +++ b/src/utils/camera.ts @@ -109,7 +109,7 @@ const options = { width: 1080, height: 1920, bitrateMultiplier: 3, - saveToCameraRoll: true, // default is false, iOS only + // saveToCameraRoll: true, // default is false, iOS only saveWithCurrentDate: true, // default is false, iOS only minimumBitrate: 300000, // removeAudio: true, // default is false @@ -140,3 +140,40 @@ export const showGIFFailureAlert = (onSuccess: () => void) => ), }, ); + +export const cropVideo = ( + sourceUri: string, + handleData: (data: any) => any, + videoCropValues?: { + cropWidth?: number; + cropHeight?: number; + cropOffsetX?: number; + cropOffsetY?: number; + }, +) => { + ProcessingManager.crop(sourceUri, { + cropWidth: videoCropValues + ? videoCropValues.cropWidth + ? Math.round(videoCropValues.cropWidth) + : 100 + : 100, + cropHeight: videoCropValues + ? videoCropValues.cropHeight + ? Math.round(videoCropValues.cropHeight) + : 100 + : 100, + cropOffsetX: videoCropValues + ? videoCropValues.cropOffsetX + ? Math.round(videoCropValues.cropOffsetX) + : 0 + : 0, + cropOffsetY: videoCropValues + ? videoCropValues.cropOffsetY + ? Math.round(videoCropValues.cropOffsetY) + : 0 + : 0, + quality: 'highest', + }).then((data: any) => { + handleData(data); + }); +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index 4ff9afac..dc00c049 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -5,3 +5,4 @@ export * from './users'; export * from './friends'; export * from './search'; export * from './messages'; +export * from './camera'; |