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 typescript-check 152 lines 3.6 kB view raw
1import RNFetchBlob from 'rn-fetch-blob' 2import ImageResizer from '@bam.tech/react-native-image-resizer' 3import {Share} from 'react-native' 4import RNFS from 'react-native-fs' 5 6import * as Toast from '../view/com/util/Toast' 7 8export interface DownloadAndResizeOpts { 9 uri: string 10 width: number 11 height: number 12 mode: 'contain' | 'cover' | 'stretch' 13 maxSize: number 14 timeout: number 15} 16 17export interface Image { 18 path: string 19 mime: string 20 size: number 21 width: number 22 height: number 23} 24 25export async function downloadAndResize(opts: DownloadAndResizeOpts) { 26 let appendExt 27 try { 28 const urip = new URL(opts.uri) 29 const ext = urip.pathname.split('.').pop() 30 if (ext === 'jpg' || ext === 'jpeg') { 31 appendExt = 'jpeg' 32 } else if (ext === 'png') { 33 appendExt = 'png' 34 } else { 35 return 36 } 37 } catch (e: any) { 38 console.error('Invalid URI', opts.uri, e) 39 return 40 } 41 42 let downloadRes 43 try { 44 const downloadResPromise = RNFetchBlob.config({ 45 fileCache: true, 46 appendExt, 47 }).fetch('GET', opts.uri) 48 const to1 = setTimeout(() => downloadResPromise.cancel(), opts.timeout) 49 downloadRes = await downloadResPromise 50 clearTimeout(to1) 51 52 let localUri = downloadRes.path() 53 if (!localUri.startsWith('file://')) { 54 localUri = `file://${localUri}` 55 } 56 57 return await resize(localUri, opts) 58 } finally { 59 if (downloadRes) { 60 downloadRes.flush() 61 } 62 } 63} 64 65export interface ResizeOpts { 66 width: number 67 height: number 68 mode: 'contain' | 'cover' | 'stretch' 69 maxSize: number 70} 71 72export async function resize( 73 localUri: string, 74 opts: ResizeOpts, 75): Promise<Image> { 76 for (let i = 0; i < 9; i++) { 77 const quality = 100 - i * 10 78 const resizeRes = await ImageResizer.createResizedImage( 79 localUri, 80 opts.width, 81 opts.height, 82 'JPEG', 83 quality, 84 undefined, 85 undefined, 86 undefined, 87 {mode: opts.mode}, 88 ) 89 if (resizeRes.size < opts.maxSize) { 90 return { 91 path: resizeRes.path, 92 mime: 'image/jpeg', 93 size: resizeRes.size, 94 width: resizeRes.width, 95 height: resizeRes.height, 96 } 97 } 98 } 99 throw new Error( 100 `This image is too big! We couldn't compress it down to ${opts.maxSize} bytes`, 101 ) 102} 103 104export async function compressIfNeeded( 105 img: Image, 106 maxSize: number, 107): Promise<Image> { 108 const origUri = `file://${img.path}` 109 if (img.size < maxSize) { 110 return img 111 } 112 return await resize(origUri, { 113 width: img.width, 114 height: img.height, 115 mode: 'stretch', 116 maxSize, 117 }) 118} 119 120export interface Dim { 121 width: number 122 height: number 123} 124export function scaleDownDimensions(dim: Dim, max: Dim): Dim { 125 if (dim.width < max.width && dim.height < max.height) { 126 return dim 127 } 128 let wScale = dim.width > max.width ? max.width / dim.width : 1 129 let hScale = dim.height > max.height ? max.height / dim.height : 1 130 if (wScale < hScale) { 131 return {width: dim.width * wScale, height: dim.height * wScale} 132 } 133 return {width: dim.width * hScale, height: dim.height * hScale} 134} 135 136export const saveImageModal = async ({uri}: {uri: string}) => { 137 const downloadResponse = await RNFetchBlob.config({ 138 fileCache: true, 139 }).fetch('GET', uri) 140 141 const imagePath = downloadResponse.path() 142 const base64Data = await downloadResponse.readFile('base64') 143 const result = await Share.share({ 144 url: 'data:image/png;base64,' + base64Data, 145 }) 146 if (result.action === Share.sharedAction) { 147 Toast.show('Image saved to gallery') 148 } else if (result.action === Share.dismissedAction) { 149 // dismissed 150 } 151 RNFS.unlink(imagePath) 152}