mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	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:
		| @@ -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 | ||||
							
								
								
									
										38
									
								
								src/components/Timeline/Shared/Attachment/dimensions.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/components/Timeline/Shared/Attachment/dimensions.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
|         } | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user