fix: ensure all cover images load properly
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import { Dimensions, ViewProps } from 'react-native';
|
import { Dimensions, ViewProps } from 'react-native';
|
||||||
import { Canvas, Blur, Image as SkiaImage, useImage, Offset, Mask, RoundedRect, Shadow } from '@shopify/react-native-skia';
|
import { Canvas, Blur, Image as SkiaImage, useImage, Offset, Mask, RoundedRect, Shadow } from '@shopify/react-native-skia';
|
||||||
import useDefaultStyles, { useUserOrSystemScheme } from './Colors';
|
import useDefaultStyles, { useUserOrSystemScheme } from './Colors';
|
||||||
@@ -13,7 +13,7 @@ const Container = styled.View<{ size: number }>`
|
|||||||
z-index: 0;
|
z-index: 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const BlurContainer = styled(Canvas)<{ size: number, offset: number }>`
|
const BlurContainer = styled(Canvas) <{ size: number, offset: number }>`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -${(props) => props.offset}px;
|
left: -${(props) => props.offset}px;
|
||||||
top: -${(props) => props.offset}px;
|
top: -${(props) => props.offset}px;
|
||||||
@@ -40,18 +40,19 @@ const emptyAlbumDark = require('@/assets/images/empty-album-dark.png');
|
|||||||
* to the corners.
|
* to the corners.
|
||||||
*/
|
*/
|
||||||
function CoverImage({
|
function CoverImage({
|
||||||
blurRadius = 256,
|
blurRadius = 256,
|
||||||
opacity = 0.85,
|
opacity = 0.85,
|
||||||
margin = 112,
|
margin = 112,
|
||||||
radius = 12,
|
radius = 12,
|
||||||
style,
|
style,
|
||||||
src,
|
src,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const defaultStyles = useDefaultStyles();
|
const defaultStyles = useDefaultStyles();
|
||||||
const colorScheme = useUserOrSystemScheme();
|
const colorScheme = useUserOrSystemScheme();
|
||||||
|
const [hasFailed, setFailed] = useState(false);
|
||||||
|
|
||||||
const image = useImage(src || null);
|
const image = useImage(src || null, () => setFailed(true));
|
||||||
const fallback = useImage(colorScheme === 'light' ? emptyAlbumLight: emptyAlbumDark);
|
const fallback = useImage(colorScheme === 'light' ? emptyAlbumLight : emptyAlbumDark);
|
||||||
const { canvasSize, imageSize } = useMemo(() => {
|
const { canvasSize, imageSize } = useMemo(() => {
|
||||||
const imageSize = Screen.width - margin;
|
const imageSize = Screen.width - margin;
|
||||||
const canvasSize = imageSize + blurRadius * 2;
|
const canvasSize = imageSize + blurRadius * 2;
|
||||||
@@ -68,14 +69,14 @@ function CoverImage({
|
|||||||
<Shadow dx={0} dy={8} blur={16} color="#0000000d" />
|
<Shadow dx={0} dy={8} blur={16} color="#0000000d" />
|
||||||
<Shadow dx={0} dy={16} blur={32} color="#0000000d" />
|
<Shadow dx={0} dy={16} blur={32} color="#0000000d" />
|
||||||
</RoundedRect>
|
</RoundedRect>
|
||||||
{image ? (
|
{src && (
|
||||||
<>
|
<>
|
||||||
<SkiaImage
|
<SkiaImage
|
||||||
image={image || fallback}
|
image={image}
|
||||||
width={imageSize}
|
width={imageSize}
|
||||||
height={imageSize}
|
height={imageSize}
|
||||||
opacity={opacity}
|
opacity={opacity}
|
||||||
key={image ? 'image-blur' : 'fallback-blur'}
|
key="image-blur"
|
||||||
>
|
>
|
||||||
<Offset x={blurRadius} y={blurRadius} />
|
<Offset x={blurRadius} y={blurRadius} />
|
||||||
<Blur blur={blurRadius / 2} />
|
<Blur blur={blurRadius / 2} />
|
||||||
@@ -89,14 +90,31 @@ function CoverImage({
|
|||||||
y={blurRadius} r={radius}
|
y={blurRadius} r={radius}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
key={image ? 'image' : 'fallback'}
|
key="image"
|
||||||
>
|
>
|
||||||
<SkiaImage image={image || fallback} width={imageSize} height={imageSize}>
|
<SkiaImage image={image} width={imageSize} height={imageSize}>
|
||||||
<Offset x={blurRadius} y={blurRadius} />
|
<Offset x={blurRadius} y={blurRadius} />
|
||||||
</SkiaImage>
|
</SkiaImage>
|
||||||
</Mask>
|
</Mask>
|
||||||
</>
|
</>
|
||||||
) : null}
|
)}
|
||||||
|
{(!src || hasFailed) && (
|
||||||
|
<Mask
|
||||||
|
mask={
|
||||||
|
<RoundedRect
|
||||||
|
width={imageSize}
|
||||||
|
height={imageSize}
|
||||||
|
x={blurRadius}
|
||||||
|
y={blurRadius} r={radius}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
key="fallback"
|
||||||
|
>
|
||||||
|
<SkiaImage image={fallback} width={imageSize} height={imageSize}>
|
||||||
|
<Offset x={blurRadius} y={blurRadius} />
|
||||||
|
</SkiaImage>
|
||||||
|
</Mask>
|
||||||
|
)}
|
||||||
</BlurContainer>
|
</BlurContainer>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user