2020-12-30 14:33:33 +01:00
|
|
|
import Button from '@components/Button'
|
2021-01-01 23:10:47 +01:00
|
|
|
import haptics from '@components/haptics'
|
2021-02-08 23:47:20 +01:00
|
|
|
import AttachmentAudio from '@components/Timeline/Shared/Attachment/Audio'
|
|
|
|
import AttachmentImage from '@components/Timeline/Shared/Attachment/Image'
|
|
|
|
import AttachmentUnsupported from '@components/Timeline/Shared/Attachment/Unsupported'
|
|
|
|
import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video'
|
2020-12-30 14:33:33 +01:00
|
|
|
import { useNavigation } from '@react-navigation/native'
|
2022-04-29 23:57:18 +02:00
|
|
|
import { StackNavigationProp } from '@react-navigation/stack'
|
2021-08-29 16:08:02 +02:00
|
|
|
import { RootStackParamList } from '@utils/navigation/navigators'
|
2022-12-28 23:41:36 +01:00
|
|
|
import { usePreferencesQuery } from '@utils/queryHooks/preferences'
|
2020-12-30 14:33:33 +01:00
|
|
|
import { StyleConstants } from '@utils/styles/constants'
|
2023-02-12 15:50:55 +01:00
|
|
|
import { isLargeDevice } from '@utils/styles/scaling'
|
2023-02-11 23:37:17 +01:00
|
|
|
import { chunk } from 'lodash'
|
2023-02-12 17:08:44 +01:00
|
|
|
import React, { Fragment, useContext, useState } from 'react'
|
2021-01-01 23:10:47 +01:00
|
|
|
import { useTranslation } from 'react-i18next'
|
2022-04-30 21:29:08 +02:00
|
|
|
import { Pressable, View } from 'react-native'
|
2023-02-11 23:37:17 +01:00
|
|
|
import StatusContext from '../Context'
|
2020-10-30 20:03:44 +01:00
|
|
|
|
2022-12-03 20:47:11 +01:00
|
|
|
const TimelineAttachment = () => {
|
|
|
|
const { status, disableDetails } = useContext(StatusContext)
|
|
|
|
if (
|
|
|
|
!status ||
|
|
|
|
disableDetails ||
|
|
|
|
!Array.isArray(status.media_attachments) ||
|
|
|
|
!status.media_attachments.length
|
|
|
|
)
|
|
|
|
return null
|
|
|
|
|
|
|
|
const { t } = useTranslation('componentTimeline')
|
2020-10-31 21:04:46 +01:00
|
|
|
|
2022-12-28 23:41:36 +01:00
|
|
|
const { data: preferences } = usePreferencesQuery()
|
|
|
|
|
2022-12-03 20:47:11 +01:00
|
|
|
const defaultSensitive = () => {
|
2022-12-28 23:41:36 +01:00
|
|
|
switch (preferences?.['reading:expand:media']) {
|
2022-12-03 20:47:11 +01:00
|
|
|
case 'show_all':
|
|
|
|
return false
|
|
|
|
case 'hide_all':
|
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return status.sensitive
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const [sensitiveShown, setSensitiveShown] = useState(defaultSensitive())
|
2021-01-01 23:10:47 +01:00
|
|
|
|
2022-12-12 22:24:03 +01:00
|
|
|
// const testHorizontal: Mastodon.Attachment[] = Array(2).fill({
|
|
|
|
// id: Math.random().toString(),
|
|
|
|
// type: 'image',
|
|
|
|
// url: 'https://images.unsplash.com/photo-1670870764013-f0e36aa376b0?w=1000',
|
|
|
|
// preview_url: 'https://images.unsplash.com/photo-1543968996-ee822b8176ba?w=300',
|
|
|
|
// meta: { original: { width: 1000, height: 625 } }
|
|
|
|
// })
|
|
|
|
// const testVertical: Mastodon.Attachment[] = Array(7).fill({
|
|
|
|
// id: Math.random().toString(),
|
|
|
|
// type: 'image',
|
|
|
|
// url: 'https://images.unsplash.com/photo-1670842587871-326b95acbc8c?w=1000',
|
|
|
|
// preview_url: 'https://images.unsplash.com/photo-1670833288990-64b2f4ef7290?w=300',
|
|
|
|
// meta: { original: { width: 987, height: 1480 } }
|
|
|
|
// })
|
|
|
|
|
2022-12-03 20:47:11 +01:00
|
|
|
// @ts-ignore
|
|
|
|
const imageUrls: RootStackParamList['Screen-ImagesViewer']['imageUrls'] = status.media_attachments
|
|
|
|
.map(attachment => {
|
|
|
|
switch (attachment.type) {
|
|
|
|
case 'image':
|
|
|
|
return {
|
|
|
|
id: attachment.id,
|
|
|
|
preview_url: attachment.preview_url,
|
|
|
|
url: attachment.url,
|
|
|
|
remote_url: attachment.remote_url,
|
|
|
|
width: attachment.meta?.original?.width,
|
|
|
|
height: attachment.meta?.original?.height
|
|
|
|
}
|
2022-06-02 00:48:14 +02:00
|
|
|
default:
|
2022-12-03 20:47:11 +01:00
|
|
|
if (
|
2023-02-12 17:08:44 +01:00
|
|
|
// https://docs.expo.dev/versions/unversioned/sdk/image/#supported-image-formats
|
|
|
|
attachment.preview_url?.match(/.(?:a?png|jpe?g|webp|avif|heic|gif|svg|ico|icns)$/i) ||
|
|
|
|
attachment.remote_url?.match(/.(?:a?png|jpe?g|webp|avif|heic|gif|svg|ico|icns)$/i)
|
2022-12-03 20:47:11 +01:00
|
|
|
) {
|
|
|
|
return {
|
|
|
|
id: attachment.id,
|
|
|
|
preview_url: attachment.preview_url,
|
|
|
|
url: attachment.url,
|
|
|
|
remote_url: attachment.remote_url,
|
|
|
|
width: attachment.meta?.original?.width,
|
|
|
|
height: attachment.meta?.original?.height
|
|
|
|
}
|
|
|
|
}
|
2022-06-02 00:48:14 +02:00
|
|
|
}
|
2022-12-03 20:47:11 +01:00
|
|
|
})
|
|
|
|
.filter(i => i)
|
|
|
|
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>()
|
|
|
|
const navigateToImagesViewer = (id: string) => {
|
|
|
|
navigation.navigate('Screen-ImagesViewer', { imageUrls, id })
|
|
|
|
}
|
2020-12-03 01:28:56 +01:00
|
|
|
|
2023-02-11 23:37:17 +01:00
|
|
|
const mapAttachmentType = (attachment: Mastodon.Attachment, index: number) => {
|
|
|
|
switch (attachment.type) {
|
|
|
|
case 'image':
|
|
|
|
return (
|
|
|
|
<AttachmentImage
|
|
|
|
total={status.media_attachments.length}
|
|
|
|
index={index}
|
|
|
|
sensitiveShown={sensitiveShown}
|
|
|
|
image={attachment}
|
|
|
|
navigateToImagesViewer={navigateToImagesViewer}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
case 'video':
|
|
|
|
return (
|
|
|
|
<AttachmentVideo
|
|
|
|
total={status.media_attachments.length}
|
|
|
|
index={index}
|
|
|
|
sensitiveShown={sensitiveShown}
|
|
|
|
video={attachment}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
case 'gifv':
|
|
|
|
return (
|
|
|
|
<AttachmentVideo
|
|
|
|
total={status.media_attachments.length}
|
|
|
|
index={index}
|
|
|
|
sensitiveShown={sensitiveShown}
|
|
|
|
video={attachment}
|
|
|
|
gifv
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
case 'audio':
|
|
|
|
return (
|
|
|
|
<AttachmentAudio
|
|
|
|
total={status.media_attachments.length}
|
|
|
|
index={index}
|
|
|
|
sensitiveShown={sensitiveShown}
|
|
|
|
audio={attachment}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
default:
|
|
|
|
if (
|
|
|
|
// https://docs.expo.dev/versions/unversioned/sdk/image/#supported-image-formats
|
|
|
|
attachment.preview_url?.match(/.(?:a?png|jpe?g|webp|avif|heic|gif|svg|ico|icns)$/i) ||
|
|
|
|
attachment.remote_url?.match(/.(?:a?png|jpe?g|webp|avif|heic|gif|svg|ico|icns)$/i)
|
|
|
|
) {
|
|
|
|
return (
|
|
|
|
<AttachmentImage
|
|
|
|
total={status.media_attachments.length}
|
|
|
|
index={index}
|
|
|
|
sensitiveShown={sensitiveShown}
|
|
|
|
image={attachment as unknown as Mastodon.AttachmentImage}
|
|
|
|
navigateToImagesViewer={navigateToImagesViewer}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
} else if (attachment.remote_url?.match(/.(?:mp4|mkv)$/i)) {
|
|
|
|
return (
|
|
|
|
<AttachmentVideo
|
|
|
|
total={status.media_attachments.length}
|
|
|
|
index={index}
|
|
|
|
sensitiveShown={sensitiveShown}
|
|
|
|
video={attachment as unknown as Mastodon.AttachmentVideo}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
<AttachmentUnsupported
|
|
|
|
total={status.media_attachments.length}
|
|
|
|
index={index}
|
|
|
|
sensitiveShown={sensitiveShown}
|
|
|
|
attachment={attachment}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-03 20:47:11 +01:00
|
|
|
return (
|
2023-02-12 23:08:15 +01:00
|
|
|
<View style={{ marginTop: StyleConstants.Spacing.M, ...(isLargeDevice && { maxWidth: 375 }) }}>
|
2023-02-14 23:04:28 +01:00
|
|
|
<View style={{ marginBottom: StyleConstants.Spacing.XS }}>
|
2023-02-12 23:08:15 +01:00
|
|
|
{chunk(status.media_attachments, 2).map((chunk, chunkIndex) => (
|
|
|
|
<View
|
|
|
|
key={chunkIndex}
|
|
|
|
style={{
|
|
|
|
flex: 1,
|
|
|
|
flexDirection: 'row',
|
|
|
|
flexWrap: 'wrap',
|
|
|
|
justifyContent: 'center',
|
|
|
|
alignContent: 'stretch',
|
|
|
|
gap: StyleConstants.Spacing.XS
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{chunk.map((a, aIndex) => (
|
|
|
|
<Fragment key={aIndex}>{mapAttachmentType(a, chunkIndex * 2 + aIndex)}</Fragment>
|
|
|
|
))}
|
|
|
|
</View>
|
|
|
|
))}
|
|
|
|
</View>
|
2020-12-25 18:20:09 +01:00
|
|
|
|
2022-12-03 20:47:11 +01:00
|
|
|
{defaultSensitive() &&
|
|
|
|
(sensitiveShown ? (
|
|
|
|
<Pressable
|
|
|
|
style={{
|
|
|
|
position: 'absolute',
|
|
|
|
width: '100%',
|
|
|
|
height: '100%',
|
|
|
|
flex: 1,
|
|
|
|
justifyContent: 'center',
|
|
|
|
alignItems: 'center'
|
|
|
|
}}
|
|
|
|
>
|
2020-12-28 17:30:20 +01:00
|
|
|
<Button
|
2022-12-03 20:47:11 +01:00
|
|
|
type='text'
|
|
|
|
content={t('shared.attachment.sensitive.button')}
|
2020-12-28 17:30:20 +01:00
|
|
|
overlay
|
2022-04-30 21:29:08 +02:00
|
|
|
onPress={() => {
|
2022-12-03 20:47:11 +01:00
|
|
|
setSensitiveShown(false)
|
2022-04-30 21:29:08 +02:00
|
|
|
haptics('Light')
|
|
|
|
}}
|
2020-12-28 17:30:20 +01:00
|
|
|
/>
|
2022-12-03 20:47:11 +01:00
|
|
|
</Pressable>
|
|
|
|
) : (
|
|
|
|
<Button
|
|
|
|
type='icon'
|
2023-01-25 00:15:46 +01:00
|
|
|
content='eye-off'
|
2022-12-03 20:47:11 +01:00
|
|
|
round
|
|
|
|
overlay
|
|
|
|
onPress={() => {
|
|
|
|
setSensitiveShown(true)
|
|
|
|
haptics('Light')
|
|
|
|
}}
|
|
|
|
style={{
|
|
|
|
position: 'absolute',
|
2023-02-12 23:08:15 +01:00
|
|
|
top: StyleConstants.Spacing.S,
|
2022-12-03 20:47:11 +01:00
|
|
|
left: StyleConstants.Spacing.S
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
))}
|
|
|
|
</View>
|
|
|
|
)
|
|
|
|
}
|
2020-12-03 01:28:56 +01:00
|
|
|
|
2021-02-27 16:33:54 +01:00
|
|
|
export default TimelineAttachment
|