Compare commits

...

5 Commits

Author SHA1 Message Date
Samuel Newman 0fd8643718 fix inset styles 2024-09-19 15:46:28 +01:00
Samuel Newman 6662b4fe5a decrease gap on desktop 2024-09-19 15:46:28 +01:00
Samuel Newman a96f3d4057 increase rounding on media inset border 2024-09-19 15:46:28 +01:00
Samuel Newman 0e41cb8f33 fix reply image preview and covert to atoms 2024-09-19 15:46:28 +01:00
Samuel Newman 30706328c5 tweak image styles 2024-09-19 15:46:28 +01:00
5 changed files with 189 additions and 123 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ export function MediaInsetBorder({
return (
<Fill
style={[
a.rounded_sm,
a.rounded_md,
a.border,
opaque
? [t.atoms.border_contrast_low]
+67 -90
View File
@@ -16,7 +16,7 @@ import {ComposerOptsPostRef} from 'state/shell/composer'
import {QuoteEmbed} from 'view/com/util/post-embeds/QuoteEmbed'
import {Text} from 'view/com/util/text/Text'
import {PreviewableUserAvatar} from 'view/com/util/UserAvatar'
import {useTheme} from '#/alf'
import {atoms as a, useTheme} from '#/alf'
export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
const t = useTheme()
@@ -122,94 +122,87 @@ function ComposerReplyToImages({
showFull: boolean
}) {
return (
<View
style={{
width: 65,
flexDirection: 'column',
alignItems: 'center',
}}>
<View style={styles.imagesContainer}>
{(images.length === 1 && (
<Image
source={{uri: images[0].thumb}}
style={styles.singleImage}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<View style={[styles.imagesContainer, a.mx_xs]}>
{(images.length === 1 && (
<Image
source={{uri: images[0].thumb}}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
)) ||
(images.length === 2 && (
<View style={[a.flex_1, a.flex_row, a.gap_2xs]}>
<Image
source={{uri: images[0].thumb}}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<Image
source={{uri: images[1].thumb}}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
</View>
)) ||
(images.length === 2 && (
<View style={[styles.imagesInner, styles.imagesRow]}>
(images.length === 3 && (
<View style={[a.flex_1, a.flex_row, a.gap_2xs]}>
<Image
source={{uri: images[0].thumb}}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<View style={[a.flex_1, a.gap_2xs]}>
<Image
source={{uri: images[1].thumb}}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<Image
source={{uri: images[2].thumb}}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
</View>
</View>
)) ||
(images.length === 4 && (
<View style={[a.flex_1, a.gap_2xs]}>
<View style={[a.flex_1, a.flex_row, a.gap_2xs]}>
<Image
source={{uri: images[0].thumb}}
style={styles.doubleImageTall}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<Image
source={{uri: images[1].thumb}}
style={styles.doubleImageTall}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
</View>
)) ||
(images.length === 3 && (
<View style={[styles.imagesInner, styles.imagesRow]}>
<View style={[a.flex_1, a.flex_row, a.gap_2xs]}>
<Image
source={{uri: images[0].thumb}}
style={styles.doubleImageTall}
source={{uri: images[2].thumb}}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<Image
source={{uri: images[3].thumb}}
style={[a.flex_1]}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<View style={styles.imagesInner}>
<Image
source={{uri: images[1].thumb}}
style={styles.doubleImage}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<Image
source={{uri: images[2].thumb}}
style={styles.doubleImage}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
</View>
</View>
)) ||
(images.length === 4 && (
<View style={styles.imagesInner}>
<View style={[styles.imagesInner, styles.imagesRow]}>
<Image
source={{uri: images[0].thumb}}
style={styles.doubleImage}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<Image
source={{uri: images[1].thumb}}
style={styles.doubleImage}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
</View>
<View style={[styles.imagesInner, styles.imagesRow]}>
<Image
source={{uri: images[2].thumb}}
style={styles.doubleImage}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
<Image
source={{uri: images[3].thumb}}
style={styles.doubleImage}
cachePolicy="memory-disk"
accessibilityIgnoresInvertColors
/>
</View>
</View>
))}
</View>
</View>
))}
</View>
)
}
@@ -240,23 +233,7 @@ const styles = StyleSheet.create({
borderRadius: 6,
overflow: 'hidden',
marginTop: 2,
},
imagesInner: {
gap: 2,
},
imagesRow: {
flexDirection: 'row',
},
singleImage: {
width: 65,
height: 65,
},
doubleImageTall: {
width: 32.5,
height: 65,
},
doubleImage: {
width: 32.5,
height: 32.5,
height: 64,
width: 64,
},
})
+2 -2
View File
@@ -88,7 +88,7 @@ export function ConstrainedImage({
<View
style={[
a.h_full,
a.rounded_sm,
a.rounded_md,
a.overflow_hidden,
t.atoms.bg_contrast_25,
fullBleed ? a.w_full : {aspectRatio},
@@ -219,7 +219,7 @@ export function AutoSizedImage({
accessibilityHint={_(msg`Tap to view full image`)}
style={[
a.w_full,
a.rounded_sm,
a.rounded_md,
a.overflow_hidden,
t.atoms.bg_contrast_25,
{aspectRatio: max},
+10 -9
View File
@@ -1,6 +1,6 @@
import React, {ComponentProps, FC} from 'react'
import {Pressable, View} from 'react-native'
import {Image} from 'expo-image'
import React from 'react'
import {Pressable, StyleProp, View, ViewStyle} from 'react-native'
import {Image, ImageStyle} from 'expo-image'
import {AppBskyEmbedImages} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -13,17 +13,18 @@ import {Text} from '#/components/Typography'
type EventFunction = (index: number) => void
interface GalleryItemProps {
interface Props {
images: AppBskyEmbedImages.ViewImage[]
index: number
onPress?: EventFunction
onLongPress?: EventFunction
onPressIn?: EventFunction
imageStyle?: ComponentProps<typeof Image>['style']
imageStyle?: StyleProp<ImageStyle>
viewContext?: PostEmbedViewContext
insetBorderStyle?: StyleProp<ViewStyle>
}
export const GalleryItem: FC<GalleryItemProps> = ({
export function GalleryItem({
images,
index,
imageStyle,
@@ -31,7 +32,8 @@ export const GalleryItem: FC<GalleryItemProps> = ({
onPressIn,
onLongPress,
viewContext,
}) => {
insetBorderStyle,
}: Props) {
const t = useTheme()
const {_} = useLingui()
const largeAltBadge = useLargeAltBadgeEnabled()
@@ -47,7 +49,6 @@ export const GalleryItem: FC<GalleryItemProps> = ({
onLongPress={onLongPress ? () => onLongPress(index) : undefined}
style={[
a.flex_1,
a.rounded_sm,
a.overflow_hidden,
t.atoms.bg_contrast_25,
imageStyle,
@@ -63,7 +64,7 @@ export const GalleryItem: FC<GalleryItemProps> = ({
accessibilityHint=""
accessibilityIgnoresInvertColors
/>
<MediaInsetBorder />
<MediaInsetBorder style={insetBorderStyle} />
</Pressable>
{hasAlt && !hideBadges ? (
<View
+109 -21
View File
@@ -1,5 +1,5 @@
import React from 'react'
import {StyleProp, View, ViewStyle} from 'react-native'
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
import {AppBskyEmbedImages} from '@atproto/api'
import {PostEmbedViewContext} from '#/view/com/util/post-embeds/types'
@@ -22,14 +22,23 @@ export function ImageLayoutGrid({style, ...props}: ImageLayoutGridProps) {
? gtMobile
? a.gap_xs
: a.gap_2xs
: gtMobile
? a.gap_sm
: a.gap_xs
const count = props.images.length
const aspectRatio = count === 2 ? 2 : count === 3 ? 1.5 : 1
let aspectRatio
switch (count) {
case 2:
aspectRatio = 2
break
case 3:
aspectRatio = 2
break
case 4:
aspectRatio = undefined
break
}
return (
<View style={style}>
<View style={[gap, {aspectRatio}]}>
<View style={[gap, a.rounded_md, a.overflow_hidden, {aspectRatio}]}>
<ImageLayoutGridInner {...props} gap={gap} />
</View>
</View>
@@ -54,10 +63,18 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
return (
<View style={[a.flex_1, a.flex_row, gap]}>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={0} />
<GalleryItem
{...props}
index={0}
insetBorderStyle={noCorners(['topRight', 'bottomRight'])}
/>
</View>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} />
<GalleryItem
{...props}
index={1}
insetBorderStyle={noCorners(['topLeft', 'bottomLeft'])}
/>
</View>
</View>
)
@@ -65,15 +82,35 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
case 3:
return (
<View style={[a.flex_1, a.flex_row, gap]}>
<View style={{flex: 2}}>
<GalleryItem {...props} index={0} />
<View style={[a.flex_1]}>
<GalleryItem
{...props}
index={0}
insetBorderStyle={noCorners(['topRight', 'bottomRight'])}
/>
</View>
<View style={[a.flex_1, gap]}>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} />
<View style={[a.flex_1]}>
<GalleryItem
{...props}
index={1}
insetBorderStyle={noCorners([
'topLeft',
'bottomLeft',
'bottomRight',
])}
/>
</View>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={2} />
<View style={[a.flex_1]}>
<GalleryItem
{...props}
index={2}
insetBorderStyle={noCorners([
'topLeft',
'bottomLeft',
'topRight',
])}
/>
</View>
</View>
</View>
@@ -83,19 +120,51 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
return (
<>
<View style={[a.flex_row, gap]}>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={0} />
<View style={[a.flex_1, {aspectRatio: 1.5}]}>
<GalleryItem
{...props}
index={0}
insetBorderStyle={noCorners([
'bottomLeft',
'topRight',
'bottomRight',
])}
/>
</View>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={1} />
<View style={[a.flex_1, {aspectRatio: 1.5}]}>
<GalleryItem
{...props}
index={1}
insetBorderStyle={noCorners([
'topLeft',
'bottomLeft',
'bottomRight',
])}
/>
</View>
</View>
<View style={[a.flex_row, gap]}>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={2} />
<View style={[a.flex_1, {aspectRatio: 1.5}]}>
<GalleryItem
{...props}
index={2}
insetBorderStyle={noCorners([
'topLeft',
'topRight',
'bottomRight',
])}
/>
</View>
<View style={[a.flex_1, {aspectRatio: 1}]}>
<GalleryItem {...props} index={3} />
<View style={[a.flex_1, {aspectRatio: 1.5}]}>
<GalleryItem
{...props}
index={3}
insetBorderStyle={noCorners([
'topLeft',
'bottomLeft',
'topRight',
])}
/>
</View>
</View>
</>
@@ -105,3 +174,22 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
return null
}
}
function noCorners(
corners: ('topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight')[],
) {
const styles: StyleProp<ViewStyle>[] = []
if (corners.includes('topLeft')) {
styles.push({borderTopLeftRadius: 0})
}
if (corners.includes('topRight')) {
styles.push({borderTopRightRadius: 0})
}
if (corners.includes('bottomLeft')) {
styles.push({borderBottomLeftRadius: 0})
}
if (corners.includes('bottomRight')) {
styles.push({borderBottomRightRadius: 0})
}
return StyleSheet.flatten(styles)
}