feat: add fallback images when album cover isn't available
This commit is contained in:
BIN
src/assets/images/empty-album-dark.png
Normal file
BIN
src/assets/images/empty-album-dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1005 KiB |
BIN
src/assets/images/empty-album-light.png
Normal file
BIN
src/assets/images/empty-album-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 926 KiB |
@@ -1,5 +1,5 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { Dimensions, ViewProps } from 'react-native';
|
import { Dimensions, useColorScheme, 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 from './Colors';
|
import useDefaultStyles from './Colors';
|
||||||
import styled from 'styled-components/native';
|
import styled from 'styled-components/native';
|
||||||
@@ -45,8 +45,10 @@ function CoverImage({
|
|||||||
src,
|
src,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const defaultStyles = useDefaultStyles();
|
const defaultStyles = useDefaultStyles();
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
|
|
||||||
const image = useImage(src || '');
|
const image = useImage(src || null);
|
||||||
|
const fallback = useImage(colorScheme === 'light' ? require('assets/images/empty-album-light.png') : require('assets/images/empty-album-dark.png'));
|
||||||
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;
|
||||||
@@ -63,15 +65,15 @@ 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 ? (
|
{(image || fallback) ? (
|
||||||
<>
|
<>
|
||||||
<SkiaImage image={image} width={imageSize} height={imageSize} opacity={opacity}>
|
<SkiaImage image={image || fallback} width={imageSize} height={imageSize} opacity={opacity}>
|
||||||
<Offset x={blurRadius} y={blurRadius} />
|
<Offset x={blurRadius} y={blurRadius} />
|
||||||
<Blur blur={blurRadius / 2} />
|
<Blur blur={blurRadius / 2} />
|
||||||
</SkiaImage>
|
</SkiaImage>
|
||||||
<Mask mask={<RoundedRect width={imageSize} height={imageSize} x={blurRadius} y={blurRadius} r={radius} />}>
|
<Mask mask={<RoundedRect width={imageSize} height={imageSize} x={blurRadius} y={blurRadius} r={radius} />}>
|
||||||
{image ? (
|
{(image || fallback) ? (
|
||||||
<SkiaImage image={image} width={imageSize} height={imageSize}>
|
<SkiaImage image={image || fallback} width={imageSize} height={imageSize}>
|
||||||
<Offset x={blurRadius} y={blurRadius} />
|
<Offset x={blurRadius} y={blurRadius} />
|
||||||
</SkiaImage>
|
</SkiaImage>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
import styled from 'styled-components/native';
|
|
||||||
import FastImage from 'react-native-fast-image';
|
|
||||||
import { Dimensions } from 'react-native';
|
|
||||||
|
|
||||||
const Screen = Dimensions.get('screen');
|
|
||||||
export const AlbumWidth = Screen.width / 2 - 24;
|
|
||||||
export const AlbumHeight = AlbumWidth + 40;
|
|
||||||
export const CoverSize = AlbumWidth - 16;
|
|
||||||
|
|
||||||
export const AlbumItem = styled.View`
|
|
||||||
width: ${AlbumWidth}px;
|
|
||||||
height: ${AlbumHeight}px;
|
|
||||||
padding: 8px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const AlbumImage = styled(FastImage)`
|
|
||||||
border-radius: 10px;
|
|
||||||
width: ${CoverSize}px;
|
|
||||||
height: ${CoverSize}px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default AlbumImage;
|
|
||||||
39
src/screens/Music/stacks/components/AlbumImage.tsx
Normal file
39
src/screens/Music/stacks/components/AlbumImage.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import styled from 'styled-components/native';
|
||||||
|
import FastImage, { FastImageProps } from 'react-native-fast-image';
|
||||||
|
import { Dimensions, Image, useColorScheme } from 'react-native';
|
||||||
|
|
||||||
|
const Screen = Dimensions.get('screen');
|
||||||
|
export const AlbumWidth = Screen.width / 2 - 24;
|
||||||
|
export const AlbumHeight = AlbumWidth + 40;
|
||||||
|
export const CoverSize = AlbumWidth - 16;
|
||||||
|
|
||||||
|
export const AlbumItem = styled.View`
|
||||||
|
width: ${AlbumWidth}px;
|
||||||
|
height: ${AlbumHeight}px;
|
||||||
|
padding: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Container = styled(FastImage)`
|
||||||
|
border-radius: 10px;
|
||||||
|
width: ${CoverSize}px;
|
||||||
|
height: ${CoverSize}px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
function AlbumImage(props: FastImageProps) {
|
||||||
|
const [hasError, setError] = useState(false);
|
||||||
|
const colorScheme = useColorScheme();
|
||||||
|
|
||||||
|
if (!props.source || hasError) {
|
||||||
|
return (
|
||||||
|
<Container source={colorScheme === 'light' ? require('assets/images/empty-album-light.png') : require('assets/images/empty-album-dark.png')} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container {...props} onError={() => setError(true)} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AlbumImage;
|
||||||
Reference in New Issue
Block a user