deer social fork for personal usage. but you might see a use idk. github mirror
4
fork

Configure Feed

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

it's stupid that avatar and banner dont support webp wtf

ayla 121a1a75 4c8af389

+84 -30
+4 -2
src/lib/media/manip.ts
··· 28 28 export async function compressIfNeeded( 29 29 img: PickerImage, 30 30 maxSize: number = POST_IMG_MAX.size, 31 + webp: boolean = true, 31 32 ): Promise<PickerImage> { 32 33 if (img.size < maxSize) { 33 34 return img ··· 36 37 width: img.width, 37 38 height: img.height, 38 39 maxSize, 40 + webp, 39 41 }) 40 42 const finalImageMovedPath = await moveToPermanentPath( 41 43 resizedImage.path, ··· 54 56 height: number 55 57 maxSize: number 56 58 timeout: number 59 + webp: boolean 57 60 } 58 61 59 62 export async function downloadAndResize(opts: DownloadAndResizeOpts) { ··· 63 66 const ext = urip.pathname.split('.').pop() 64 67 if (ext === 'png') { 65 68 appendExt = 'png' 66 - } else if (ext === 'webp') { 67 - appendExt = 'webp' 68 69 } 69 70 } catch (e: any) { 70 71 console.error('Invalid URI', opts.uri, e) ··· 180 181 width: number 181 182 height: number 182 183 maxSize: number 184 + webp: boolean 183 185 } 184 186 185 187 async function doResize(
+17 -8
src/lib/media/manip.web.ts
··· 10 10 export async function compressIfNeeded( 11 11 img: PickerImage, 12 12 maxSize: number, 13 + webp: boolean = true, 13 14 ): Promise<PickerImage> { 14 15 if (img.size < maxSize) { 15 16 return img ··· 18 19 width: img.width, 19 20 height: img.height, 20 21 maxSize, 22 + webp, 21 23 }) 22 24 } 23 25 ··· 27 29 height: number 28 30 maxSize: number 29 31 timeout: number 32 + webp: boolean 30 33 } 31 34 32 35 export async function downloadAndResize(opts: DownloadAndResizeOpts) { ··· 84 87 width: number 85 88 height: number 86 89 maxSize: number 90 + webp: boolean 87 91 } 88 92 89 93 async function doResize( ··· 97 101 let maxQualityPercentage = 110 //exclusive 98 102 let finalCompressionPercentage: number = 100 99 103 100 - const imageData = await createResizedImage(dataUri, { 104 + const [imageData, canvas] = await createResizedImage(dataUri, { 101 105 width: opts.width, 102 106 height: opts.height, 103 107 }) ··· 105 109 while (maxQualityPercentage > 1) { 106 110 const qualityPercentage = Math.round(maxQualityPercentage - 10) 107 111 108 - const [tempDataUri, size] = await createCompressedImage( 109 - imageData, 110 - qualityPercentage, 111 - ) 112 + const [tempDataUri, size] = opts.webp 113 + ? await createCompressedWebp(imageData, qualityPercentage) 114 + : (() => { 115 + const dataUrl = canvas.toDataURL( 116 + qualityPercentage === 100 ? 'image/png' : 'image/jpeg', 117 + qualityPercentage / 100, 118 + ) 119 + return [dataUrl, getDataUriSize(dataUrl)] 120 + })() 112 121 113 122 console.log(size, qualityPercentage, originalSize) 114 123 if (size <= opts.maxSize && size <= originalSize) { ··· 142 151 width: number 143 152 height: number 144 153 }, 145 - ): Promise<ImageData> { 154 + ): Promise<[ImageData, HTMLCanvasElement]> { 146 155 return new Promise((resolve, reject) => { 147 156 const img = document.createElement('img') 148 157 img.addEventListener('load', async () => { ··· 165 174 166 175 const imageData = ctx.getImageData(0, 0, img.width, img.height) 167 176 168 - resolve(imageData) 177 + resolve([imageData, canvas]) 169 178 }) 170 179 img.addEventListener('error', ev => { 171 180 reject(ev.error) ··· 174 183 }) 175 184 } 176 185 177 - async function createCompressedImage( 186 + async function createCompressedWebp( 178 187 imageData: ImageData, 179 188 quality: number, 180 189 ): Promise<[string, number]> {
+25 -8
src/state/gallery.ts
··· 188 188 return img 189 189 } 190 190 191 - export async function compressImage(img: ComposerImage): Promise<PickerImage> { 191 + export async function compressImage( 192 + img: ComposerImage, 193 + webp: boolean = true, 194 + ): Promise<PickerImage> { 192 195 const source = img.transformed || img.source 193 196 const originalSize = getDataUriSize(img.source.path) 194 197 ··· 207 210 while (maxQualityPercentage > 1) { 208 211 const qualityPercentage = Math.round(maxQualityPercentage - 10) 209 212 210 - const res = await manipulateWebp(resizedImage.uri, { 211 - compress: qualityPercentage, 212 - format: SaveFormat.WEBP, 213 - }) 213 + const format = webp 214 + ? SaveFormat.WEBP 215 + : qualityPercentage 216 + ? SaveFormat.PNG 217 + : SaveFormat.JPEG 218 + 219 + const res = webp 220 + ? await manipulateWebp(resizedImage.uri, { 221 + compress: qualityPercentage, 222 + format: SaveFormat.WEBP, 223 + }) 224 + : await manipulateAsync(source.path, [], { 225 + compress: qualityPercentage / 100, 226 + format, 227 + base64: true, 228 + }) 214 229 215 - if (res.size <= POST_IMG_MAX.size && res.size <= originalSize) { 230 + const size = 'size' in res ? res.size : getDataUriSize(res.base64!) 231 + 232 + if (size <= POST_IMG_MAX.size && size <= originalSize) { 216 233 newDataUri = { 217 234 path: await moveIfNecessary(res.uri), 218 235 width: w, 219 236 height: h, 220 - mime: 'image/webp', 221 - size: res.size, 237 + mime: `image/${format}`, 238 + size: size, 222 239 quality: qualityPercentage, 223 240 } 224 241 break
+28 -10
src/state/gallery.web.ts
··· 151 151 return img 152 152 } 153 153 154 - export async function compressImage(img: ComposerImage): Promise<PickerImage> { 154 + export async function compressImage( 155 + img: ComposerImage, 156 + webp: boolean = true, 157 + ): Promise<PickerImage> { 155 158 const source = img.transformed || img.source 156 159 // i should probably go and turn it into base64 and whatever but nah who cares 157 160 const originalSize = img.source.path.startsWith('blob:') ··· 172 175 while (maxQualityPercentage > 1) { 173 176 const qualityPercentage = Math.round(maxQualityPercentage - 10) 174 177 175 - const res = await manipulateWebp(resizedImage, { 176 - compress: qualityPercentage, 177 - format: SaveFormat.WEBP, 178 - }) 178 + const format = webp 179 + ? SaveFormat.WEBP 180 + : qualityPercentage 181 + ? SaveFormat.PNG 182 + : SaveFormat.JPEG 179 183 180 - if (res.size <= POST_IMG_MAX.size && res.size <= originalSize) { 184 + const res = webp 185 + ? await manipulateWebp(resizedImage, { 186 + compress: qualityPercentage, 187 + format: SaveFormat.WEBP, 188 + }) 189 + : await manipulateAsync(source.path, [], { 190 + compress: qualityPercentage / 100, 191 + format, 192 + base64: true, 193 + }) 194 + 195 + const size = 196 + 'size' in res ? (res.size as number) : getDataUriSize(res.base64!) 197 + 198 + if (size <= POST_IMG_MAX.size && size <= originalSize) { 181 199 newDataUri = { 182 200 path: res.uri, 183 - width: res.width, 184 - height: res.height, 185 - mime: 'image/webp', 186 - size: res.size, 201 + width: w, 202 + height: h, 203 + mime: `image/${format}`, 204 + size: size, 187 205 quality: qualityPercentage, 188 206 } 189 207 break
+5 -1
src/view/com/util/UserAvatar.tsx
··· 383 383 await openCamera({ 384 384 aspect: [1, 1], 385 385 }), 386 + undefined, 387 + false, 386 388 ), 387 389 ) 388 390 }, [onSelectNewAvatar, requestCameraAccessIfNeeded]) ··· 411 413 shape: circular ? 'circle' : 'rectangle', 412 414 aspectRatio: 1, 413 415 }), 416 + undefined, 417 + false, 414 418 ), 415 419 ) 416 420 } else { ··· 437 441 438 442 const onChangeEditImage = useCallback( 439 443 async (image: ComposerImage) => { 440 - const compressed = await compressImage(image) 444 + const compressed = await compressImage(image, false) 441 445 onSelectNewAvatar(compressed) 442 446 }, 443 447 [onSelectNewAvatar],
+5 -1
src/view/com/util/UserBanner.tsx
··· 81 81 await openCamera({ 82 82 aspect: [3, 1], 83 83 }), 84 + undefined, 85 + false, 84 86 ), 85 87 ) 86 88 }, [onSelectNewBanner, requestCameraAccessIfNeeded]) ··· 102 104 imageUri: items[0].path, 103 105 aspectRatio: 3 / 1, 104 106 }), 107 + undefined, 108 + false, 105 109 ), 106 110 ) 107 111 } else { ··· 155 159 156 160 const onChangeEditImage = useCallback( 157 161 async (image: ComposerImage) => { 158 - const compressed = await compressImage(image) 162 + const compressed = await compressImage(image, false) 159 163 onSelectNewBanner?.(compressed) 160 164 }, 161 165 [onSelectNewBanner],