mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Prepare for future media needs
NOT USED
This commit is contained in:
		
							
								
								
									
										149
									
								
								src/components/mediaTransformation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								src/components/mediaTransformation.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | |||||||
|  | import { store } from '@root/store' | ||||||
|  | import { getInstanceConfigurationMediaAttachments } from '@utils/slices/instancesSlice' | ||||||
|  | import { Action, manipulateAsync, SaveFormat } from 'expo-image-manipulator' | ||||||
|  | import i18next from 'i18next' | ||||||
|  | import { Platform } from 'react-native' | ||||||
|  | import ImagePicker from 'react-native-image-crop-picker' | ||||||
|  |  | ||||||
|  | export interface Props { | ||||||
|  |   type: 'image' | 'video' | ||||||
|  |   uri: string // This can be pure path or uri starting with file:// | ||||||
|  |   mime?: string | ||||||
|  |   transform: { | ||||||
|  |     imageFormat?: SaveFormat.JPEG | SaveFormat.PNG | ||||||
|  |     resize?: boolean | ||||||
|  |     width?: number | ||||||
|  |     height?: number | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const getFileExtension = (uri: string) => { | ||||||
|  |   const extension = uri.split('.').pop() | ||||||
|  |   // Using mime type standard of jpeg | ||||||
|  |   return extension === 'jpg' ? 'jpeg' : extension | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const mediaTransformation = async ({ | ||||||
|  |   type, | ||||||
|  |   uri, | ||||||
|  |   mime, | ||||||
|  |   transform | ||||||
|  | }: Props): Promise<{ | ||||||
|  |   uri: string | ||||||
|  |   mime: string | ||||||
|  |   width: number | ||||||
|  |   height: number | ||||||
|  | }> => { | ||||||
|  |   const configurationMediaAttachments = | ||||||
|  |     getInstanceConfigurationMediaAttachments(store.getState()) | ||||||
|  |  | ||||||
|  |   const fileExtension = getFileExtension(uri) | ||||||
|  |  | ||||||
|  |   switch (type) { | ||||||
|  |     case 'image': | ||||||
|  |       if (mime === 'image/gif' || fileExtension === 'gif') { | ||||||
|  |         return Promise.reject('GIFs should not be transformed') | ||||||
|  |       } | ||||||
|  |       let targetFormat: SaveFormat.JPEG | SaveFormat.PNG = SaveFormat.JPEG | ||||||
|  |  | ||||||
|  |       const supportedImageTypes = | ||||||
|  |         configurationMediaAttachments.supported_mime_types.filter(mime => | ||||||
|  |           mime.startsWith('image/') | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |       // @ts-ignore | ||||||
|  |       const transformations: Action[] = [ | ||||||
|  |         !transform.resize && (transform.width || transform.height) | ||||||
|  |           ? { | ||||||
|  |               resize: { width: transform.width, height: transform.height } | ||||||
|  |             } | ||||||
|  |           : null | ||||||
|  |       ].filter(t => !!t) | ||||||
|  |  | ||||||
|  |       if (mime) { | ||||||
|  |         if ( | ||||||
|  |           mime !== `image/${fileExtension}` || | ||||||
|  |           !supportedImageTypes.includes(mime) | ||||||
|  |         ) { | ||||||
|  |           targetFormat = transform.imageFormat || SaveFormat.JPEG | ||||||
|  |         } else { | ||||||
|  |           targetFormat = mime.split('/').pop() as any | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         if (!fileExtension) { | ||||||
|  |           return Promise.reject('Unable to get file extension') | ||||||
|  |         } | ||||||
|  |         if (!supportedImageTypes.includes(`image/${fileExtension}`)) { | ||||||
|  |           targetFormat = transform.imageFormat || SaveFormat.JPEG | ||||||
|  |         } else { | ||||||
|  |           targetFormat = fileExtension as any | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       const converted = await manipulateAsync(uri, transformations, { | ||||||
|  |         base64: false, | ||||||
|  |         compress: Platform.OS === 'ios' ? 0.8 : 1, | ||||||
|  |         format: targetFormat | ||||||
|  |       }) | ||||||
|  |  | ||||||
|  |       if (transform.resize) { | ||||||
|  |         const resized = await ImagePicker.openCropper({ | ||||||
|  |           mediaType: 'photo', | ||||||
|  |           path: converted.uri, | ||||||
|  |           width: transform.width, | ||||||
|  |           height: transform.height, | ||||||
|  |           cropperChooseText: i18next.t('common:buttons.apply'), | ||||||
|  |           cropperCancelText: i18next.t('common:buttons.cancel'), | ||||||
|  |           hideBottomControls: true | ||||||
|  |         }) | ||||||
|  |         if (!resized) { | ||||||
|  |           return Promise.reject('Resize failed') | ||||||
|  |         } else { | ||||||
|  |           return { | ||||||
|  |             uri: resized.path, | ||||||
|  |             mime: resized.mime, | ||||||
|  |             width: resized.width, | ||||||
|  |             height: resized.height | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         return { | ||||||
|  |           uri: converted.uri, | ||||||
|  |           mime: transform.imageFormat || SaveFormat.JPEG, | ||||||
|  |           width: converted.width, | ||||||
|  |           height: converted.height | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     case 'video': | ||||||
|  |       const supportedVideoTypes = | ||||||
|  |         configurationMediaAttachments.supported_mime_types.filter(mime => | ||||||
|  |           mime.startsWith('video/') | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |       if (mime) { | ||||||
|  |         if (mime !== `video/${fileExtension}`) { | ||||||
|  |           console.warn('Video mime type and file extension does not match') | ||||||
|  |         } | ||||||
|  |         if (!supportedVideoTypes.includes(mime)) { | ||||||
|  |           return Promise.reject('Video file type is not supported') | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         if (!fileExtension) { | ||||||
|  |           return Promise.reject('Unable to get file extension') | ||||||
|  |         } | ||||||
|  |         if (!supportedVideoTypes.includes(`video/${fileExtension}`)) { | ||||||
|  |           return Promise.reject('Video file type is not supported') | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       return { | ||||||
|  |         uri: uri, | ||||||
|  |         mime: mime || `video/${fileExtension}`, | ||||||
|  |         width: 0, | ||||||
|  |         height: 0 | ||||||
|  |       } | ||||||
|  |       break | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default mediaTransformation | ||||||
| @@ -381,6 +381,43 @@ export const getInstanceConfigurationStatusCharsURL = ({ | |||||||
|   instances[findInstanceActive(instances)]?.configuration?.statuses |   instances[findInstanceActive(instances)]?.configuration?.statuses | ||||||
|     .characters_reserved_per_url || 23 |     .characters_reserved_per_url || 23 | ||||||
|  |  | ||||||
|  | export const getInstanceConfigurationMediaAttachments = ({ | ||||||
|  |   instances: { instances } | ||||||
|  | }: RootState) => | ||||||
|  |   instances[findInstanceActive(instances)]?.configuration | ||||||
|  |     ?.media_attachments || { | ||||||
|  |     supported_mime_types: [ | ||||||
|  |       'image/jpeg', | ||||||
|  |       'image/png', | ||||||
|  |       'image/gif', | ||||||
|  |       'video/webm', | ||||||
|  |       'video/mp4', | ||||||
|  |       'video/quicktime', | ||||||
|  |       'video/ogg', | ||||||
|  |       'audio/wave', | ||||||
|  |       'audio/wav', | ||||||
|  |       'audio/x-wav', | ||||||
|  |       'audio/x-pn-wave', | ||||||
|  |       'audio/ogg', | ||||||
|  |       'audio/vorbis', | ||||||
|  |       'audio/mpeg', | ||||||
|  |       'audio/mp3', | ||||||
|  |       'audio/webm', | ||||||
|  |       'audio/flac', | ||||||
|  |       'audio/aac', | ||||||
|  |       'audio/m4a', | ||||||
|  |       'audio/x-m4a', | ||||||
|  |       'audio/mp4', | ||||||
|  |       'audio/3gpp', | ||||||
|  |       'video/x-ms-asf' | ||||||
|  |     ], | ||||||
|  |     image_size_limit: 10485760, | ||||||
|  |     image_matrix_limit: 16777216, | ||||||
|  |     video_size_limit: 41943040, | ||||||
|  |     video_frame_rate_limit: 60, | ||||||
|  |     video_matrix_limit: 2304000 | ||||||
|  |   } | ||||||
|  |  | ||||||
| export const getInstanceConfigurationPoll = ({ | export const getInstanceConfigurationPoll = ({ | ||||||
|   instances: { instances } |   instances: { instances } | ||||||
| }: RootState) => | }: RootState) => | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user