mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at samuel/patch-onpaste 145 lines 4.0 kB view raw
1import React from 'react' 2import {StyleSheet, TouchableOpacity, View} from 'react-native' 3import {manipulateAsync, SaveFormat} from 'expo-image-manipulator' 4import {LinearGradient} from 'expo-linear-gradient' 5import {msg, Trans} from '@lingui/macro' 6import {useLingui} from '@lingui/react' 7import ReactCrop, {type PercentCrop} from 'react-image-crop' 8 9import {usePalette} from '#/lib/hooks/usePalette' 10import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 11import {type PickerImage} from '#/lib/media/picker.shared' 12import {getDataUriSize} from '#/lib/media/util' 13import {gradients, s} from '#/lib/styles' 14import {useModalControls} from '#/state/modals' 15import {Text} from '#/view/com/util/text/Text' 16 17export const snapPoints = ['0%'] 18 19export function Component({ 20 uri, 21 aspect, 22 circular, 23 onSelect, 24}: { 25 uri: string 26 aspect?: number 27 circular?: boolean 28 onSelect: (img?: PickerImage) => void 29}) { 30 const pal = usePalette('default') 31 const {_} = useLingui() 32 33 const {closeModal} = useModalControls() 34 const {isMobile} = useWebMediaQueries() 35 36 const imageRef = React.useRef<HTMLImageElement>(null) 37 const [crop, setCrop] = React.useState<PercentCrop>() 38 39 const isEmpty = !crop || (crop.width || crop.height) === 0 40 41 const onPressCancel = () => { 42 onSelect(undefined) 43 closeModal() 44 } 45 const onPressDone = async () => { 46 const img = imageRef.current! 47 48 const result = await manipulateAsync( 49 uri, 50 isEmpty 51 ? [] 52 : [ 53 { 54 crop: { 55 originX: (crop.x * img.naturalWidth) / 100, 56 originY: (crop.y * img.naturalHeight) / 100, 57 width: (crop.width * img.naturalWidth) / 100, 58 height: (crop.height * img.naturalHeight) / 100, 59 }, 60 }, 61 ], 62 { 63 base64: true, 64 format: SaveFormat.JPEG, 65 }, 66 ) 67 68 onSelect({ 69 path: result.uri, 70 mime: 'image/jpeg', 71 size: result.base64 !== undefined ? getDataUriSize(result.base64) : 0, 72 width: result.width, 73 height: result.height, 74 }) 75 76 closeModal() 77 } 78 79 return ( 80 <View> 81 <View style={[styles.cropper, pal.borderDark]}> 82 <ReactCrop 83 aspect={aspect} 84 crop={crop} 85 onChange={(_pixelCrop, percentCrop) => setCrop(percentCrop)} 86 circularCrop={circular}> 87 <img ref={imageRef} src={uri} style={{maxHeight: '75vh'}} /> 88 </ReactCrop> 89 </View> 90 <View style={[styles.btns, isMobile && {paddingHorizontal: 16}]}> 91 <TouchableOpacity 92 onPress={onPressCancel} 93 accessibilityRole="button" 94 accessibilityLabel={_(msg`Cancel image crop`)} 95 accessibilityHint={_(msg`Exits image cropping process`)}> 96 <Text type="xl" style={pal.link}> 97 <Trans>Cancel</Trans> 98 </Text> 99 </TouchableOpacity> 100 <View style={s.flex1} /> 101 <TouchableOpacity 102 onPress={onPressDone} 103 accessibilityRole="button" 104 accessibilityLabel={_(msg`Save image crop`)} 105 accessibilityHint={_(msg`Saves image crop settings`)}> 106 <LinearGradient 107 colors={[gradients.blueLight.start, gradients.blueLight.end]} 108 start={{x: 0, y: 0}} 109 end={{x: 1, y: 1}} 110 style={[styles.btn]}> 111 <Text type="xl-medium" style={s.white}> 112 <Trans>Done</Trans> 113 </Text> 114 </LinearGradient> 115 </TouchableOpacity> 116 </View> 117 </View> 118 ) 119} 120 121const styles = StyleSheet.create({ 122 cropper: { 123 marginLeft: 'auto', 124 marginRight: 'auto', 125 borderWidth: 1, 126 borderRadius: 4, 127 overflow: 'hidden', 128 alignItems: 'center', 129 }, 130 ctrls: { 131 flexDirection: 'row', 132 alignItems: 'center', 133 marginTop: 10, 134 }, 135 btns: { 136 flexDirection: 'row', 137 alignItems: 'center', 138 marginTop: 10, 139 }, 140 btn: { 141 borderRadius: 4, 142 paddingVertical: 8, 143 paddingHorizontal: 24, 144 }, 145})