mirror of https://github.com/tooot-app/app
Fixed #552
Assuming most toot won't include more than 4 images. For below 4 images, mostly they are not cropped unless they are too long. For single image, mostly it is not cropped unless it is longer than 3/2.
This commit is contained in:
parent
91be219ff3
commit
96497aad25
|
@ -45,6 +45,21 @@ const TimelineAttachment = () => {
|
|||
}
|
||||
const [sensitiveShown, setSensitiveShown] = useState(defaultSensitive())
|
||||
|
||||
// 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 } }
|
||||
// })
|
||||
|
||||
// @ts-ignore
|
||||
const imageUrls: RootStackParamList['Screen-ImagesViewer']['imageUrls'] = status.media_attachments
|
||||
.map(attachment => {
|
||||
|
|
|
@ -8,7 +8,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'
|
|||
import { AppState, AppStateStatus, StyleSheet, View } from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import AttachmentAltText from './AltText'
|
||||
import attachmentAspectRatio from './aspectRatio'
|
||||
import { aspectRatio } from './dimensions'
|
||||
|
||||
export interface Props {
|
||||
total: number
|
||||
|
@ -64,7 +64,7 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
|
|||
styles.base,
|
||||
{
|
||||
backgroundColor: colors.disabled,
|
||||
aspectRatio: attachmentAspectRatio({ total, index })
|
||||
aspectRatio: aspectRatio({ total, index, ...audio.meta?.original })
|
||||
}
|
||||
]}
|
||||
>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { View } from 'react-native'
|
||||
import AttachmentAltText from './AltText'
|
||||
import attachmentAspectRatio from './aspectRatio'
|
||||
import { aspectRatio } from './dimensions'
|
||||
|
||||
export interface Props {
|
||||
total: number
|
||||
|
@ -20,6 +21,8 @@ const AttachmentImage = ({
|
|||
image,
|
||||
navigateToImagesViewer
|
||||
}: Props) => {
|
||||
const { colors } = useTheme()
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
|
@ -28,21 +31,16 @@ const AttachmentImage = ({
|
|||
padding: StyleConstants.Spacing.XS / 2
|
||||
}}
|
||||
>
|
||||
<GracefullyImage
|
||||
accessibilityLabel={image.description}
|
||||
hidden={sensitiveShown}
|
||||
uri={{ original: image.preview_url, remote: image.remote_url }}
|
||||
blurhash={image.blurhash}
|
||||
onPress={() => navigateToImagesViewer(image.id)}
|
||||
style={{
|
||||
aspectRatio:
|
||||
total > 1 || !image.meta?.original?.width || !image.meta?.original?.height
|
||||
? attachmentAspectRatio({ total, index })
|
||||
: image.meta.original.height / image.meta.original.width > 1
|
||||
? 1
|
||||
: image.meta.original.width / image.meta.original.height
|
||||
}}
|
||||
/>
|
||||
<View style={{ flex: 1, backgroundColor: colors.shimmerDefault }}>
|
||||
<GracefullyImage
|
||||
accessibilityLabel={image.description}
|
||||
hidden={sensitiveShown}
|
||||
uri={{ original: image.preview_url, remote: image.remote_url }}
|
||||
blurhash={image.blurhash}
|
||||
onPress={() => navigateToImagesViewer(image.id)}
|
||||
style={{ aspectRatio: aspectRatio({ total, index, ...image.meta?.original }) }}
|
||||
/>
|
||||
</View>
|
||||
<AttachmentAltText sensitiveShown={sensitiveShown} text={image.description} />
|
||||
</View>
|
||||
)
|
||||
|
|
|
@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import { View } from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import AttachmentAltText from './AltText'
|
||||
import attachmentAspectRatio from './aspectRatio'
|
||||
import { aspectRatio } from './dimensions'
|
||||
|
||||
export interface Props {
|
||||
total: number
|
||||
|
@ -29,7 +29,7 @@ const AttachmentUnsupported: React.FC<Props> = ({ total, index, sensitiveShown,
|
|||
padding: StyleConstants.Spacing.XS / 2,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
aspectRatio: attachmentAspectRatio({ total, index })
|
||||
aspectRatio: aspectRatio({ total, index, ...attachment.meta?.original })
|
||||
}}
|
||||
>
|
||||
{attachment.blurhash ? (
|
||||
|
|
|
@ -4,10 +4,10 @@ import { ResizeMode, Video, VideoFullscreenUpdate } from 'expo-av'
|
|||
import React, { useRef, useState } from 'react'
|
||||
import { Pressable, View } from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import attachmentAspectRatio from './aspectRatio'
|
||||
import AttachmentAltText from './AltText'
|
||||
import { Platform } from 'expo-modules-core'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { aspectRatio } from './dimensions'
|
||||
|
||||
export interface Props {
|
||||
total: number
|
||||
|
@ -49,7 +49,7 @@ const AttachmentVideo: React.FC<Props> = ({
|
|||
flex: 1,
|
||||
flexBasis: '50%',
|
||||
padding: StyleConstants.Spacing.XS / 2,
|
||||
aspectRatio: attachmentAspectRatio({ total, index })
|
||||
aspectRatio: aspectRatio({ total, index, ...video.meta?.original })
|
||||
}}
|
||||
>
|
||||
<Video
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
const attachmentAspectRatio = ({
|
||||
total,
|
||||
index
|
||||
}: {
|
||||
total: number
|
||||
index?: number
|
||||
}) => {
|
||||
switch (total) {
|
||||
case 1:
|
||||
case 4:
|
||||
return 16 / 9
|
||||
case 2:
|
||||
return 8 / 9
|
||||
case 3:
|
||||
if (index === 2) {
|
||||
return 32 / 9
|
||||
} else {
|
||||
return 16 / 9
|
||||
}
|
||||
default:
|
||||
return 16 / 9
|
||||
}
|
||||
}
|
||||
|
||||
export default attachmentAspectRatio
|
|
@ -0,0 +1,38 @@
|
|||
export const aspectRatio = ({
|
||||
total,
|
||||
index,
|
||||
width,
|
||||
height
|
||||
}: {
|
||||
total: number
|
||||
index?: number
|
||||
width?: number
|
||||
height?: number
|
||||
}): number => {
|
||||
const cropTooTall = (height || 1) / (width || 1) > 3 / 2 ? 2 / 3 : (width || 1) / (height || 1)
|
||||
|
||||
const isEven = total % 2 == 0
|
||||
if (total > 5) {
|
||||
switch (isEven) {
|
||||
case true:
|
||||
return total / 2 / 2
|
||||
case false:
|
||||
if ((index || -2) + 1 == total) {
|
||||
return Math.ceil(total / 2)
|
||||
} else {
|
||||
return Math.ceil(total / 2) / 2
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (isEven) {
|
||||
case true:
|
||||
return cropTooTall
|
||||
case false:
|
||||
if ((index || -2) + 1 == total) {
|
||||
return cropTooTall * 2
|
||||
} else {
|
||||
return cropTooTall
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue