[Lightbox] Add border radius to avatars (#6136)
* Preserve shape in lightbox * Rename shapes to semantic meanings It looks like after all I do want to fork based on those. * Round avatars on the web * Oops
This commit is contained in:
@@ -64,6 +64,7 @@ let ProfileHeaderShell = ({
|
|||||||
height: 1000,
|
height: 1000,
|
||||||
width: 1000,
|
width: 1000,
|
||||||
},
|
},
|
||||||
|
type: 'circle-avi',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
index: 0,
|
index: 0,
|
||||||
|
|||||||
@@ -21,4 +21,5 @@ export type ImageSource = {
|
|||||||
thumbUri: string
|
thumbUri: string
|
||||||
alt?: string
|
alt?: string
|
||||||
dimensions: Dimensions | null
|
dimensions: Dimensions | null
|
||||||
|
type: 'image' | 'circle-avi' | 'rect-avi'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,6 +302,11 @@ const ImageItem = ({
|
|||||||
committedTransform.value = withClampedSpring(finalTransform)
|
committedTransform.value = withClampedSpring(finalTransform)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const innerStyle = useAnimatedStyle(() => ({
|
||||||
|
width: '100%',
|
||||||
|
aspectRatio: imageAspect,
|
||||||
|
}))
|
||||||
|
|
||||||
const composedGesture = isScrollViewBeingDragged
|
const composedGesture = isScrollViewBeingDragged
|
||||||
? // If the parent is not at rest, provide a no-op gesture.
|
? // If the parent is not at rest, provide a no-op gesture.
|
||||||
Gesture.Manual()
|
Gesture.Manual()
|
||||||
@@ -312,6 +317,9 @@ const ImageItem = ({
|
|||||||
singleTap,
|
singleTap,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const type = imageSrc.type
|
||||||
|
const borderRadius =
|
||||||
|
type === 'circle-avi' ? 1e5 : type === 'rect-avi' ? 20 : 0
|
||||||
return (
|
return (
|
||||||
<GestureDetector gesture={composedGesture}>
|
<GestureDetector gesture={composedGesture}>
|
||||||
<Animated.View style={imageStyle} renderToHardwareTextureAndroid>
|
<Animated.View style={imageStyle} renderToHardwareTextureAndroid>
|
||||||
@@ -326,7 +334,7 @@ const ImageItem = ({
|
|||||||
source={{uri: imageSrc.uri}}
|
source={{uri: imageSrc.uri}}
|
||||||
placeholderContentFit="contain"
|
placeholderContentFit="contain"
|
||||||
placeholder={{uri: imageSrc.thumbUri}}
|
placeholder={{uri: imageSrc.thumbUri}}
|
||||||
style={[styles.image]}
|
style={[innerStyle, {borderRadius}]}
|
||||||
accessibilityLabel={imageSrc.alt}
|
accessibilityLabel={imageSrc.alt}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
accessibilityIgnoresInvertColors
|
accessibilityIgnoresInvertColors
|
||||||
@@ -342,9 +350,7 @@ const styles = StyleSheet.create({
|
|||||||
container: {
|
container: {
|
||||||
height: '100%',
|
height: '100%',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
},
|
justifyContent: 'center',
|
||||||
image: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
},
|
||||||
loading: {
|
loading: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|||||||
@@ -143,6 +143,9 @@ const ImageItem = ({
|
|||||||
singleTap,
|
singleTap,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const type = imageSrc.type
|
||||||
|
const borderRadius =
|
||||||
|
type === 'circle-avi' ? 1e5 : type === 'rect-avi' ? 20 : 0
|
||||||
return (
|
return (
|
||||||
<GestureDetector gesture={composedGesture}>
|
<GestureDetector gesture={composedGesture}>
|
||||||
<Animated.ScrollView
|
<Animated.ScrollView
|
||||||
@@ -163,7 +166,7 @@ const ImageItem = ({
|
|||||||
source={{uri: imageSrc.uri}}
|
source={{uri: imageSrc.uri}}
|
||||||
placeholderContentFit="contain"
|
placeholderContentFit="contain"
|
||||||
placeholder={{uri: imageSrc.thumbUri}}
|
placeholder={{uri: imageSrc.thumbUri}}
|
||||||
style={animatedStyle}
|
style={[animatedStyle, {borderRadius}]}
|
||||||
accessibilityLabel={imageSrc.alt}
|
accessibilityLabel={imageSrc.alt}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
enableLiveTextInteraction={showControls && !scaled}
|
enableLiveTextInteraction={showControls && !scaled}
|
||||||
|
|||||||
@@ -21,13 +21,9 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
|||||||
import {colors, s} from '#/lib/styles'
|
import {colors, s} from '#/lib/styles'
|
||||||
import {useLightbox, useLightboxControls} from '#/state/lightbox'
|
import {useLightbox, useLightboxControls} from '#/state/lightbox'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
|
import {ImageSource} from './ImageViewing/@types'
|
||||||
import ImageDefaultHeader from './ImageViewing/components/ImageDefaultHeader'
|
import ImageDefaultHeader from './ImageViewing/components/ImageDefaultHeader'
|
||||||
|
|
||||||
interface Img {
|
|
||||||
uri: string
|
|
||||||
alt?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Lightbox() {
|
export function Lightbox() {
|
||||||
const {activeLightbox} = useLightbox()
|
const {activeLightbox} = useLightbox()
|
||||||
const {closeLightbox} = useLightboxControls()
|
const {closeLightbox} = useLightboxControls()
|
||||||
@@ -54,7 +50,7 @@ function LightboxInner({
|
|||||||
initialIndex = 0,
|
initialIndex = 0,
|
||||||
onClose,
|
onClose,
|
||||||
}: {
|
}: {
|
||||||
imgs: Img[]
|
imgs: ImageSource[]
|
||||||
initialIndex: number
|
initialIndex: number
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
}) {
|
}) {
|
||||||
@@ -101,6 +97,8 @@ function LightboxInner({
|
|||||||
return isTabletOrDesktop ? 32 : 24
|
return isTabletOrDesktop ? 32 : 24
|
||||||
}, [isTabletOrDesktop])
|
}, [isTabletOrDesktop])
|
||||||
|
|
||||||
|
const img = imgs[index]
|
||||||
|
const isAvi = img.type === 'circle-avi' || img.type === 'rect-avi'
|
||||||
return (
|
return (
|
||||||
<View style={styles.mask}>
|
<View style={styles.mask}>
|
||||||
<TouchableWithoutFeedback
|
<TouchableWithoutFeedback
|
||||||
@@ -109,12 +107,32 @@ function LightboxInner({
|
|||||||
accessibilityLabel={_(msg`Close image viewer`)}
|
accessibilityLabel={_(msg`Close image viewer`)}
|
||||||
accessibilityHint={_(msg`Exits image view`)}
|
accessibilityHint={_(msg`Exits image view`)}
|
||||||
onAccessibilityEscape={onClose}>
|
onAccessibilityEscape={onClose}>
|
||||||
|
{isAvi ? (
|
||||||
|
<View style={styles.aviCenterer}>
|
||||||
|
<img
|
||||||
|
src={img.uri}
|
||||||
|
// @ts-ignore web-only
|
||||||
|
style={
|
||||||
|
{
|
||||||
|
...styles.avi,
|
||||||
|
borderRadius:
|
||||||
|
img.type === 'circle-avi'
|
||||||
|
? '50%'
|
||||||
|
: img.type === 'rect-avi'
|
||||||
|
? '10%'
|
||||||
|
: 0,
|
||||||
|
} as ImageStyle
|
||||||
|
}
|
||||||
|
alt={img.alt}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
<View style={styles.imageCenterer}>
|
<View style={styles.imageCenterer}>
|
||||||
<Image
|
<Image
|
||||||
accessibilityIgnoresInvertColors
|
accessibilityIgnoresInvertColors
|
||||||
source={imgs[index]}
|
source={img}
|
||||||
style={styles.image as ImageStyle}
|
style={styles.image as ImageStyle}
|
||||||
accessibilityLabel={imgs[index].alt}
|
accessibilityLabel={img.alt}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
/>
|
/>
|
||||||
{canGoLeft && (
|
{canGoLeft && (
|
||||||
@@ -156,8 +174,9 @@ function LightboxInner({
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
)}
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
{imgs[index].alt ? (
|
{img.alt ? (
|
||||||
<View style={styles.footer}>
|
<View style={styles.footer}>
|
||||||
<Pressable
|
<Pressable
|
||||||
accessibilityLabel={_(msg`Expand alt text`)}
|
accessibilityLabel={_(msg`Expand alt text`)}
|
||||||
@@ -171,7 +190,7 @@ function LightboxInner({
|
|||||||
style={s.white}
|
style={s.white}
|
||||||
numberOfLines={isAltExpanded ? 0 : 3}
|
numberOfLines={isAltExpanded ? 0 : 3}
|
||||||
ellipsizeMode="tail">
|
ellipsizeMode="tail">
|
||||||
{imgs[index].alt}
|
{img.alt}
|
||||||
</Text>
|
</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</View>
|
</View>
|
||||||
@@ -203,6 +222,19 @@ const styles = StyleSheet.create({
|
|||||||
height: '100%',
|
height: '100%',
|
||||||
resizeMode: 'contain',
|
resizeMode: 'contain',
|
||||||
},
|
},
|
||||||
|
aviCenterer: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
avi: {
|
||||||
|
// @ts-ignore web-only
|
||||||
|
maxWidth: `calc(min(400px, 100vw))`,
|
||||||
|
// @ts-ignore web-only
|
||||||
|
maxHeight: `calc(min(400px, 100vh))`,
|
||||||
|
padding: 16,
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
},
|
||||||
icon: {
|
icon: {
|
||||||
color: colors.white,
|
color: colors.white,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export function ProfileSubpageHeader({
|
|||||||
height: 1000,
|
height: 1000,
|
||||||
width: 1000,
|
width: 1000,
|
||||||
},
|
},
|
||||||
|
type: 'rect-avi',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
index: 0,
|
index: 0,
|
||||||
|
|||||||
@@ -152,7 +152,10 @@ export function PostEmbeds({
|
|||||||
thumbDims: MeasuredDimensions | null,
|
thumbDims: MeasuredDimensions | null,
|
||||||
) => {
|
) => {
|
||||||
openLightbox({
|
openLightbox({
|
||||||
images: items,
|
images: items.map(item => ({
|
||||||
|
...item,
|
||||||
|
type: 'image',
|
||||||
|
})),
|
||||||
index,
|
index,
|
||||||
thumbDims,
|
thumbDims,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user