tooot/src/components/mediaSelector.ts

128 lines
3.5 KiB
TypeScript
Raw Normal View History

2021-05-13 02:03:24 +02:00
import { ActionSheetOptions } from '@expo/react-native-action-sheet'
2023-01-03 23:57:23 +01:00
import { queryClient } from '@utils/queryHooks'
import { QueryKeyInstance } from '@utils/queryHooks/instance'
2021-05-13 02:03:24 +02:00
import i18next from 'i18next'
2022-08-07 01:18:10 +02:00
import { Asset, launchImageLibrary } from 'react-native-image-picker'
2021-05-09 21:59:03 +02:00
const queryKeyInstance: QueryKeyInstance = ['Instance']
2023-02-12 18:38:06 +01:00
export const MAX_MEDIA_ATTACHMENTS = (): number =>
queryClient.getQueryData<Mastodon.Instance<any>>(queryKeyInstance)?.configuration?.statuses
.max_media_attachments || 4
2021-05-09 21:59:03 +02:00
export interface Props {
2022-06-05 17:58:18 +02:00
mediaType?: 'photo' | 'video'
resize?: { width?: number; height?: number }
maximum?: number
indicateMaximum?: boolean
2021-05-09 21:59:03 +02:00
showActionSheetWithOptions: (
options: ActionSheetOptions,
2021-11-15 22:34:43 +01:00
callback: (i?: number | undefined) => void | Promise<void>
2021-05-09 21:59:03 +02:00
) => void
}
const mediaSelector = async ({
2022-06-05 17:58:18 +02:00
mediaType,
2021-05-13 02:03:24 +02:00
resize,
2022-06-05 17:58:18 +02:00
maximum,
indicateMaximum = false,
2021-05-09 21:59:03 +02:00
showActionSheetWithOptions
2022-08-07 01:18:10 +02:00
}: Props): Promise<Asset[]> => {
2023-02-12 18:38:06 +01:00
const _maximum = maximum || MAX_MEDIA_ATTACHMENTS()
2022-06-05 17:58:18 +02:00
const options = () => {
switch (mediaType) {
case 'photo':
return [
i18next.t(
'componentMediaSelector:options.image',
2022-12-12 00:31:32 +01:00
indicateMaximum ? { context: 'max', max: _maximum } : {}
2022-06-05 17:58:18 +02:00
),
i18next.t('common:buttons.cancel')
]
case 'video':
return [
i18next.t(
'componentMediaSelector:options.video',
2022-12-12 00:31:32 +01:00
indicateMaximum ? { context: 'max', max: 1 } : {}
2022-06-05 17:58:18 +02:00
),
i18next.t('common:buttons.cancel')
]
default:
return [
i18next.t(
'componentMediaSelector:options.image',
2022-12-12 00:31:32 +01:00
indicateMaximum ? { context: 'max', max: _maximum } : {}
2022-06-05 17:58:18 +02:00
),
i18next.t(
'componentMediaSelector:options.video',
2022-12-12 00:31:32 +01:00
indicateMaximum ? { context: 'max', max: 1 } : {}
2022-06-05 17:58:18 +02:00
),
i18next.t('common:buttons.cancel')
]
}
}
return new Promise((resolve, reject) => {
const selectImage = async () => {
2022-08-07 01:18:10 +02:00
const images = await launchImageLibrary({
2022-06-05 17:58:18 +02:00
mediaType: 'photo',
2022-08-07 01:18:10 +02:00
...(resize && { maxWidth: resize.width, maxHeight: resize.height }),
includeBase64: false,
includeExtra: false,
selectionLimit: _maximum
})
2022-06-05 17:58:18 +02:00
2022-08-07 01:18:10 +02:00
if (!images.assets) {
2022-06-05 17:58:18 +02:00
return reject()
}
2022-08-07 01:18:10 +02:00
return resolve(images.assets)
2021-05-13 02:03:24 +02:00
}
2022-06-05 17:58:18 +02:00
const selectVideo = async () => {
2022-08-07 01:18:10 +02:00
const video = await launchImageLibrary({
2022-06-05 17:58:18 +02:00
mediaType: 'video',
2022-08-07 01:18:10 +02:00
includeBase64: false,
includeExtra: false,
selectionLimit: 1
})
2021-05-13 02:03:24 +02:00
2022-08-07 01:18:10 +02:00
if (video.assets?.[0]) {
return resolve(video.assets)
2022-06-05 17:58:18 +02:00
} else {
return reject()
}
}
2021-05-13 02:03:24 +02:00
showActionSheetWithOptions(
{
title: i18next.t('componentMediaSelector:title'),
message: i18next.t('componentMediaSelector:message'),
2022-06-05 17:58:18 +02:00
options: options(),
cancelButtonIndex: mediaType ? 1 : 2
2021-05-13 02:03:24 +02:00
},
async buttonIndex => {
2022-06-05 17:58:18 +02:00
switch (mediaType) {
case 'photo':
if (buttonIndex === 0) {
await selectImage()
2021-05-09 21:59:03 +02:00
}
2022-06-05 17:58:18 +02:00
break
case 'video':
if (buttonIndex === 0) {
await selectVideo()
2021-05-09 21:59:03 +02:00
}
2022-06-05 17:58:18 +02:00
break
default:
if (buttonIndex === 0) {
await selectImage()
} else if (buttonIndex === 1) {
await selectVideo()
}
break
2021-05-09 21:59:03 +02:00
}
}
2021-05-13 02:03:24 +02:00
)
})
2021-05-09 21:59:03 +02:00
}
export default mediaSelector