65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import React from 'react';
|
|
import { StyleSheet, View } from 'react-native';
|
|
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
|
import { useImageDimensions } from '@react-native-community/hooks';
|
|
import { AndroidScoped } from 'react-native-file-access';
|
|
import { useSelector } from 'react-redux';
|
|
import { Meme } from '../../database';
|
|
import { RootState } from '../../state';
|
|
import { AnimatedImage, LoadingView, MemeFail } from '..';
|
|
|
|
const memeViewItemStyles = StyleSheet.create({
|
|
view: {
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
});
|
|
|
|
const MemeViewItem = ({ meme }: { meme: Meme }) => {
|
|
const { height, width } = useSafeAreaFrame();
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
const storageUri = useSelector(
|
|
(state: RootState) => state.settings.storageUri,
|
|
)!;
|
|
|
|
const uri = AndroidScoped.appendPath(storageUri, meme.filename);
|
|
|
|
const { dimensions, loading, error } = useImageDimensions({ uri });
|
|
|
|
if (!error && (loading || !dimensions)) {
|
|
return <LoadingView style={{ width, height }} />;
|
|
}
|
|
|
|
return (
|
|
<View style={[{ width, height }, memeViewItemStyles.view]}>
|
|
{error || !dimensions ? (
|
|
<MemeFail
|
|
style={{
|
|
width: Math.min(width, height - 128),
|
|
height: Math.min(width, height - 128),
|
|
}}
|
|
iconSize={50}
|
|
/>
|
|
) : (
|
|
<AnimatedImage
|
|
source={{ uri }}
|
|
style={
|
|
dimensions.aspectRatio > width / (height - 128)
|
|
? {
|
|
width,
|
|
height: width / (dimensions.width / dimensions.height),
|
|
}
|
|
: {
|
|
width:
|
|
(height - 128) * (dimensions.width / dimensions.height),
|
|
height: height - 128,
|
|
}
|
|
}
|
|
/>
|
|
)}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default MemeViewItem;
|