mirror of
https://github.com/tooot-app/app
synced 2025-01-31 10:44:58 +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
|
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) =>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user