Add skeleton placeholders
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
50
package-lock.json
generated
50
package-lock.json
generated
@@ -12,6 +12,7 @@
|
||||
"@bankify/redux-persist-realm": "^0.1.3",
|
||||
"@react-native-clipboard/clipboard": "^1.11.2",
|
||||
"@react-native-community/hooks": "^3.0.0",
|
||||
"@react-native-masked-view/masked-view": "^0.2.9",
|
||||
"@react-native-ml-kit/text-recognition": "^1.2.1",
|
||||
"@react-navigation/bottom-tabs": "^6.5.8",
|
||||
"@react-navigation/native": "^6.1.7",
|
||||
@@ -27,6 +28,7 @@
|
||||
"react-native-file-access": "^3.0.4",
|
||||
"react-native-gesture-handler": "^2.12.0",
|
||||
"react-native-get-random-values": "^1.9.0",
|
||||
"react-native-linear-gradient": "^2.8.1",
|
||||
"react-native-mime-types": "^2.4.0",
|
||||
"react-native-paper": "^5.9.1",
|
||||
"react-native-reanimated": "^3.3.0",
|
||||
@@ -35,6 +37,7 @@
|
||||
"react-native-screens": "^3.22.1",
|
||||
"react-native-share": "^9.2.3",
|
||||
"react-native-share-menu": "^6.0.0",
|
||||
"react-native-skeleton-placeholder": "^5.2.4",
|
||||
"react-native-vector-icons": "^9.2.0",
|
||||
"react-native-video": "^6.0.0-alpha.6",
|
||||
"react-redux": "^8.1.1",
|
||||
@@ -4115,6 +4118,15 @@
|
||||
"react-native": ">=0.65"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-masked-view/masked-view": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.2.9.tgz",
|
||||
"integrity": "sha512-Hs4vKBKj+15VxHZHFtMaFWSBxXoOE5Ea8saoigWhahp8Mepssm0ezU+2pTl7DK9z8Y9s5uOl/aPb4QmBZ3R3Zw==",
|
||||
"peerDependencies": {
|
||||
"react": ">=16",
|
||||
"react-native": ">=0.57"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-ml-kit/text-recognition": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-ml-kit/text-recognition/-/text-recognition-1.2.1.tgz",
|
||||
@@ -13480,6 +13492,15 @@
|
||||
"react-native": ">=0.56"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-linear-gradient": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.1.tgz",
|
||||
"integrity": "sha512-934R4Bnjo7mYT38W9ypS1Dq/YW6TgyGdkHg+w72HNxN0ZDKG1GqAnZ6XlicMUYJDh7ViiJAKN8eOF3Ho0N4J0Q==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-mime-types": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-mime-types/-/react-native-mime-types-2.4.0.tgz",
|
||||
@@ -13592,6 +13613,17 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-share-menu/-/react-native-share-menu-6.0.0.tgz",
|
||||
"integrity": "sha512-KdmRnqjI/B2MigSxGmhbYJ3WMJxKXj+0c47ANcVZ/PTzc2vtz6d1r4KQJgkBImXgNC+vowpuD2UGdPllxadr2A=="
|
||||
},
|
||||
"node_modules/react-native-skeleton-placeholder": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-skeleton-placeholder/-/react-native-skeleton-placeholder-5.2.4.tgz",
|
||||
"integrity": "sha512-OZntVq1hU1UX33FltxK2ezT2v9vHIhV8YnEbnMWUCvxT0N9OsgD1qxiHm6qb9YRJVgq2o5z3S7dNPsPnDF/jNg==",
|
||||
"peerDependencies": {
|
||||
"@react-native-masked-view/masked-view": "^0.2.8",
|
||||
"react": ">=0.14.8",
|
||||
"react-native": ">=0.50.1",
|
||||
"react-native-linear-gradient": "^2.5.6"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-vector-icons": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz",
|
||||
@@ -18819,6 +18851,12 @@
|
||||
"integrity": "sha512-g2OyxXHfwIytXUJitBR6Z/ISoOfp0WKx5FOv+NqJ/CrWjRDcTw6zXE5I1C9axfuh30kJqzWchVfCDrkzZYTxqg==",
|
||||
"requires": {}
|
||||
},
|
||||
"@react-native-masked-view/masked-view": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.2.9.tgz",
|
||||
"integrity": "sha512-Hs4vKBKj+15VxHZHFtMaFWSBxXoOE5Ea8saoigWhahp8Mepssm0ezU+2pTl7DK9z8Y9s5uOl/aPb4QmBZ3R3Zw==",
|
||||
"requires": {}
|
||||
},
|
||||
"@react-native-ml-kit/text-recognition": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-ml-kit/text-recognition/-/text-recognition-1.2.1.tgz",
|
||||
@@ -25903,6 +25941,12 @@
|
||||
"fast-base64-decode": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"react-native-linear-gradient": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.1.tgz",
|
||||
"integrity": "sha512-934R4Bnjo7mYT38W9ypS1Dq/YW6TgyGdkHg+w72HNxN0ZDKG1GqAnZ6XlicMUYJDh7ViiJAKN8eOF3Ho0N4J0Q==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-mime-types": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-mime-types/-/react-native-mime-types-2.4.0.tgz",
|
||||
@@ -25989,6 +26033,12 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-share-menu/-/react-native-share-menu-6.0.0.tgz",
|
||||
"integrity": "sha512-KdmRnqjI/B2MigSxGmhbYJ3WMJxKXj+0c47ANcVZ/PTzc2vtz6d1r4KQJgkBImXgNC+vowpuD2UGdPllxadr2A=="
|
||||
},
|
||||
"react-native-skeleton-placeholder": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-skeleton-placeholder/-/react-native-skeleton-placeholder-5.2.4.tgz",
|
||||
"integrity": "sha512-OZntVq1hU1UX33FltxK2ezT2v9vHIhV8YnEbnMWUCvxT0N9OsgD1qxiHm6qb9YRJVgq2o5z3S7dNPsPnDF/jNg==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-vector-icons": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz",
|
||||
|
@@ -17,6 +17,7 @@
|
||||
"@bankify/redux-persist-realm": "^0.1.3",
|
||||
"@react-native-clipboard/clipboard": "^1.11.2",
|
||||
"@react-native-community/hooks": "^3.0.0",
|
||||
"@react-native-masked-view/masked-view": "^0.2.9",
|
||||
"@react-native-ml-kit/text-recognition": "^1.2.1",
|
||||
"@react-navigation/bottom-tabs": "^6.5.8",
|
||||
"@react-navigation/native": "^6.1.7",
|
||||
@@ -32,6 +33,7 @@
|
||||
"react-native-file-access": "^3.0.4",
|
||||
"react-native-gesture-handler": "^2.12.0",
|
||||
"react-native-get-random-values": "^1.9.0",
|
||||
"react-native-linear-gradient": "^2.8.1",
|
||||
"react-native-mime-types": "^2.4.0",
|
||||
"react-native-paper": "^5.9.1",
|
||||
"react-native-reanimated": "^3.3.0",
|
||||
@@ -40,6 +42,7 @@
|
||||
"react-native-screens": "^3.22.1",
|
||||
"react-native-share": "^9.2.3",
|
||||
"react-native-share-menu": "^6.0.0",
|
||||
"react-native-skeleton-placeholder": "^5.2.4",
|
||||
"react-native-vector-icons": "^9.2.0",
|
||||
"react-native-video": "^6.0.0-alpha.6",
|
||||
"react-redux": "^8.1.1",
|
||||
|
@@ -6,3 +6,4 @@ export { default as LoadingView } from './loadingView';
|
||||
export { default as MemeFail } from './memeFail';
|
||||
export { default as TagChip } from './tagChip';
|
||||
export { default as TextOverlay } from './textOverlay';
|
||||
export { default as ThemedSkeletonPlaceholder } from './themedSkeletonPlaceholder';
|
||||
|
20
src/components/themedSkeletonPlaceholder.tsx
Normal file
20
src/components/themedSkeletonPlaceholder.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React, { ComponentProps } from 'react';
|
||||
import SkeletonPlaceholder from 'react-native-skeleton-placeholder';
|
||||
import { useTheme } from 'react-native-paper';
|
||||
import { rgbToRgba } from '../utilities';
|
||||
|
||||
const ThemedSkeletonPlaceholder = ({
|
||||
...props
|
||||
}: ComponentProps<typeof SkeletonPlaceholder>) => {
|
||||
const { colors } = useTheme();
|
||||
|
||||
return (
|
||||
<SkeletonPlaceholder
|
||||
backgroundColor={rgbToRgba(colors.surfaceVariant, 0.2)}
|
||||
highlightColor={rgbToRgba(colors.surfaceVariant, 0.7)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemedSkeletonPlaceholder;
|
@@ -2,8 +2,9 @@ import React, { useMemo } from 'react';
|
||||
import { TouchableHighlight } from 'react-native';
|
||||
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import SkeletonPlaceholder from 'react-native-skeleton-placeholder';
|
||||
import { MEME_TYPE, Meme } from '../../../database';
|
||||
import { MemeFail } from '../../../components';
|
||||
import { MemeFail, ThemedSkeletonPlaceholder } from '../../../components';
|
||||
import { getFontAwesome5IconSize } from '../../../utilities';
|
||||
import { useMemeDimensions } from '../../../hooks';
|
||||
|
||||
@@ -35,7 +36,7 @@ const MemesGridItem = ({
|
||||
return (
|
||||
<FastImage
|
||||
source={{ uri }}
|
||||
style={[{ width: itemWidth, height: itemWidth }]}
|
||||
style={{ width: itemWidth, height: itemWidth }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -45,7 +46,16 @@ const MemesGridItem = ({
|
||||
}
|
||||
}, [itemWidth, meme.memeType, uri]);
|
||||
|
||||
if (!error && (loading || !dimensions)) return <></>;
|
||||
const skeletonComponent = useMemo(
|
||||
() => (
|
||||
<ThemedSkeletonPlaceholder>
|
||||
<SkeletonPlaceholder.Item width={itemWidth} height={itemWidth} />
|
||||
</ThemedSkeletonPlaceholder>
|
||||
),
|
||||
[itemWidth],
|
||||
);
|
||||
|
||||
if (!error && (loading || !dimensions)) return skeletonComponent;
|
||||
|
||||
return (
|
||||
<TouchableHighlight onPress={focusMeme}>
|
||||
|
@@ -3,8 +3,9 @@ import { StyleSheet, View } from 'react-native';
|
||||
import { Text, TouchableRipple } from 'react-native-paper';
|
||||
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import SkeletonPlaceholder from 'react-native-skeleton-placeholder';
|
||||
import { MEME_TYPE, Meme } from '../../../database';
|
||||
import { MemeFail } from '../../../components';
|
||||
import { MemeFail, ThemedSkeletonPlaceholder } from '../../../components';
|
||||
import { useMemeDimensions } from '../../../hooks';
|
||||
|
||||
const memesListItemStyles = StyleSheet.create({
|
||||
@@ -54,7 +55,7 @@ const MemesListItem = ({
|
||||
case MEME_TYPE.IMAGE:
|
||||
case MEME_TYPE.GIF:
|
||||
case MEME_TYPE.VIDEO: {
|
||||
return <FastImage source={{ uri }} style={[memesListItemStyles.image]} />;
|
||||
return <FastImage source={{ uri }} style={memesListItemStyles.image} />;
|
||||
}
|
||||
default: {
|
||||
return <></>;
|
||||
@@ -62,7 +63,19 @@ const MemesListItem = ({
|
||||
}
|
||||
}, [meme.memeType, uri]);
|
||||
|
||||
if (!error && (loading || !dimensions)) return <></>;
|
||||
const skeletonComponent = useMemo(
|
||||
() => (
|
||||
<ThemedSkeletonPlaceholder>
|
||||
<SkeletonPlaceholder.Item
|
||||
width={listItemWidth.width + 75}
|
||||
height={90}
|
||||
/>
|
||||
</ThemedSkeletonPlaceholder>
|
||||
),
|
||||
[listItemWidth.width],
|
||||
);
|
||||
|
||||
if (!error && (loading || !dimensions)) return skeletonComponent;
|
||||
|
||||
return (
|
||||
<TouchableRipple onPress={focusMeme} style={memesListItemStyles.view}>
|
||||
|
@@ -2,8 +2,9 @@ import React, { useMemo } from 'react';
|
||||
import { StyleSheet, TouchableHighlight } from 'react-native';
|
||||
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import SkeletonPlaceholder from 'react-native-skeleton-placeholder';
|
||||
import { MEME_TYPE, Meme } from '../../../database';
|
||||
import { MemeFail } from '../../../components';
|
||||
import { MemeFail, ThemedSkeletonPlaceholder } from '../../../components';
|
||||
import { getFontAwesome5IconSize } from '../../../utilities';
|
||||
import { useMemeDimensions } from '../../../hooks';
|
||||
|
||||
@@ -52,10 +53,7 @@ const MemesMasonryItem = ({
|
||||
source={{ uri }}
|
||||
style={[
|
||||
memeMasonryItemStyles.image,
|
||||
{
|
||||
width: itemWidth,
|
||||
height: itemHeight,
|
||||
},
|
||||
{ width: itemWidth, height: itemHeight },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
@@ -66,7 +64,20 @@ const MemesMasonryItem = ({
|
||||
}
|
||||
}, [itemHeight, itemWidth, meme.memeType, uri]);
|
||||
|
||||
if (!error && (loading || !dimensions)) return <></>;
|
||||
const skeletonComponent = useMemo(
|
||||
() => (
|
||||
<ThemedSkeletonPlaceholder borderRadius={5}>
|
||||
<SkeletonPlaceholder.Item
|
||||
width={itemWidth}
|
||||
height={itemWidth}
|
||||
style={memeMasonryItemStyles.view}
|
||||
/>
|
||||
</ThemedSkeletonPlaceholder>
|
||||
),
|
||||
[itemWidth],
|
||||
);
|
||||
|
||||
if (!error && (loading || !dimensions)) return skeletonComponent;
|
||||
|
||||
return (
|
||||
<TouchableHighlight onPress={focusMeme} style={memeMasonryItemStyles.view}>
|
||||
|
Reference in New Issue
Block a user