mirror of
https://github.com/tooot-app/app
synced 2025-01-18 20:21:15 +01:00
Prepare for future media needs
NOT USED
This commit is contained in:
parent
b5a5ce01a3
commit
e33e8550f6
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
|
||||
.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 = ({
|
||||
instances: { instances }
|
||||
}: RootState) =>
|
||||
|
Loading…
Reference in New Issue
Block a user