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 [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
|
// @ts-ignore
|
||||||
const imageUrls: RootStackParamList['Screen-ImagesViewer']['imageUrls'] = status.media_attachments
|
const imageUrls: RootStackParamList['Screen-ImagesViewer']['imageUrls'] = status.media_attachments
|
||||||
.map(attachment => {
|
.map(attachment => {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import { AppState, AppStateStatus, StyleSheet, View } from 'react-native'
|
import { AppState, AppStateStatus, StyleSheet, View } from 'react-native'
|
||||||
import { Blurhash } from 'react-native-blurhash'
|
import { Blurhash } from 'react-native-blurhash'
|
||||||
import AttachmentAltText from './AltText'
|
import AttachmentAltText from './AltText'
|
||||||
import attachmentAspectRatio from './aspectRatio'
|
import { aspectRatio } from './dimensions'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
total: number
|
total: number
|
||||||
|
@ -64,7 +64,7 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
|
||||||
styles.base,
|
styles.base,
|
||||||
{
|
{
|
||||||
backgroundColor: colors.disabled,
|
backgroundColor: colors.disabled,
|
||||||
aspectRatio: attachmentAspectRatio({ total, index })
|
aspectRatio: aspectRatio({ total, index, ...audio.meta?.original })
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { View } from 'react-native'
|
import { View } from 'react-native'
|
||||||
import AttachmentAltText from './AltText'
|
import AttachmentAltText from './AltText'
|
||||||
import attachmentAspectRatio from './aspectRatio'
|
import { aspectRatio } from './dimensions'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
total: number
|
total: number
|
||||||
|
@ -20,6 +21,8 @@ const AttachmentImage = ({
|
||||||
image,
|
image,
|
||||||
navigateToImagesViewer
|
navigateToImagesViewer
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
const { colors } = useTheme()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
|
@ -28,21 +31,16 @@ const AttachmentImage = ({
|
||||||
padding: StyleConstants.Spacing.XS / 2
|
padding: StyleConstants.Spacing.XS / 2
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<GracefullyImage
|
<View style={{ flex: 1, backgroundColor: colors.shimmerDefault }}>
|
||||||
accessibilityLabel={image.description}
|
<GracefullyImage
|
||||||
hidden={sensitiveShown}
|
accessibilityLabel={image.description}
|
||||||
uri={{ original: image.preview_url, remote: image.remote_url }}
|
hidden={sensitiveShown}
|
||||||
blurhash={image.blurhash}
|
uri={{ original: image.preview_url, remote: image.remote_url }}
|
||||||
onPress={() => navigateToImagesViewer(image.id)}
|
blurhash={image.blurhash}
|
||||||
style={{
|
onPress={() => navigateToImagesViewer(image.id)}
|
||||||
aspectRatio:
|
style={{ aspectRatio: aspectRatio({ total, index, ...image.meta?.original }) }}
|
||||||
total > 1 || !image.meta?.original?.width || !image.meta?.original?.height
|
/>
|
||||||
? attachmentAspectRatio({ total, index })
|
</View>
|
||||||
: image.meta.original.height / image.meta.original.width > 1
|
|
||||||
? 1
|
|
||||||
: image.meta.original.width / image.meta.original.height
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<AttachmentAltText sensitiveShown={sensitiveShown} text={image.description} />
|
<AttachmentAltText sensitiveShown={sensitiveShown} text={image.description} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next'
|
||||||
import { View } from 'react-native'
|
import { View } from 'react-native'
|
||||||
import { Blurhash } from 'react-native-blurhash'
|
import { Blurhash } from 'react-native-blurhash'
|
||||||
import AttachmentAltText from './AltText'
|
import AttachmentAltText from './AltText'
|
||||||
import attachmentAspectRatio from './aspectRatio'
|
import { aspectRatio } from './dimensions'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
total: number
|
total: number
|
||||||
|
@ -29,7 +29,7 @@ const AttachmentUnsupported: React.FC<Props> = ({ total, index, sensitiveShown,
|
||||||
padding: StyleConstants.Spacing.XS / 2,
|
padding: StyleConstants.Spacing.XS / 2,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
aspectRatio: attachmentAspectRatio({ total, index })
|
aspectRatio: aspectRatio({ total, index, ...attachment.meta?.original })
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{attachment.blurhash ? (
|
{attachment.blurhash ? (
|
||||||
|
|
|
@ -4,10 +4,10 @@ import { ResizeMode, Video, VideoFullscreenUpdate } from 'expo-av'
|
||||||
import React, { useRef, useState } from 'react'
|
import React, { useRef, useState } from 'react'
|
||||||
import { Pressable, View } from 'react-native'
|
import { Pressable, View } from 'react-native'
|
||||||
import { Blurhash } from 'react-native-blurhash'
|
import { Blurhash } from 'react-native-blurhash'
|
||||||
import attachmentAspectRatio from './aspectRatio'
|
|
||||||
import AttachmentAltText from './AltText'
|
import AttachmentAltText from './AltText'
|
||||||
import { Platform } from 'expo-modules-core'
|
import { Platform } from 'expo-modules-core'
|
||||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||||
|
import { aspectRatio } from './dimensions'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
total: number
|
total: number
|
||||||
|
@ -49,7 +49,7 @@ const AttachmentVideo: React.FC<Props> = ({
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexBasis: '50%',
|
flexBasis: '50%',
|
||||||
padding: StyleConstants.Spacing.XS / 2,
|
padding: StyleConstants.Spacing.XS / 2,
|
||||||
aspectRatio: attachmentAspectRatio({ total, index })
|
aspectRatio: aspectRatio({ total, index, ...video.meta?.original })
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Video
|
<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