added loading animations
This commit is contained in:
parent
facffe0f19
commit
77029294aa
8 changed files with 133 additions and 7 deletions
BIN
assets/Progress of loading hand.lottie
Normal file
BIN
assets/Progress of loading hand.lottie
Normal file
Binary file not shown.
|
|
@ -25,7 +25,7 @@ config.transformer = {
|
||||||
// Optimize resolver for better tree shaking and SVG support
|
// Optimize resolver for better tree shaking and SVG support
|
||||||
config.resolver = {
|
config.resolver = {
|
||||||
...config.resolver,
|
...config.resolver,
|
||||||
assetExts: config.resolver.assetExts.filter((ext) => ext !== 'svg'),
|
assetExts: [...config.resolver.assetExts.filter((ext) => ext !== 'svg'), 'lottie'],
|
||||||
sourceExts: [...config.resolver.sourceExts, 'svg'],
|
sourceExts: [...config.resolver.sourceExts, 'svg'],
|
||||||
resolverMainFields: ['react-native', 'browser', 'main'],
|
resolverMainFields: ['react-native', 'browser', 'main'],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
21
package-lock.json
generated
21
package-lock.json
generated
|
|
@ -46,6 +46,7 @@
|
||||||
"expo-system-ui": "^4.0.9",
|
"expo-system-ui": "^4.0.9",
|
||||||
"expo-web-browser": "~14.0.2",
|
"expo-web-browser": "~14.0.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"lottie-react-native": "^7.3.1",
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-native": "0.76.9",
|
"react-native": "0.76.9",
|
||||||
"react-native-gesture-handler": "~2.20.2",
|
"react-native-gesture-handler": "~2.20.2",
|
||||||
|
|
@ -10434,6 +10435,26 @@
|
||||||
"loose-envify": "cli.js"
|
"loose-envify": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lottie-react-native": {
|
||||||
|
"version": "7.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-7.3.1.tgz",
|
||||||
|
"integrity": "sha512-VW0gtiP1i3Jv6+PaVaNg6QDIqAXwAqmxVp1UOJFqsB6FeBN0zc8M/XR8DE8YiayZzd149nlqGOgmwoV7FbRGDw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@lottiefiles/dotlottie-react": "^0.6.5",
|
||||||
|
"react": "*",
|
||||||
|
"react-native": ">=0.46",
|
||||||
|
"react-native-windows": ">=0.63.x"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@lottiefiles/dotlottie-react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-native-windows": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lower-case": {
|
"node_modules/lower-case": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
"expo-system-ui": "^4.0.9",
|
"expo-system-ui": "^4.0.9",
|
||||||
"expo-web-browser": "~14.0.2",
|
"expo-web-browser": "~14.0.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"lottie-react-native": "^7.3.1",
|
||||||
"react": "18.3.1",
|
"react": "18.3.1",
|
||||||
"react-native": "0.76.9",
|
"react-native": "0.76.9",
|
||||||
"react-native-gesture-handler": "~2.20.2",
|
"react-native-gesture-handler": "~2.20.2",
|
||||||
|
|
|
||||||
86
src/components/common/DogLoadingSpinner.tsx
Normal file
86
src/components/common/DogLoadingSpinner.tsx
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { View, Text, StyleSheet, Dimensions } from 'react-native';
|
||||||
|
import LottieView from 'lottie-react-native';
|
||||||
|
import { useTheme } from '../../contexts/ThemeContext';
|
||||||
|
|
||||||
|
interface DogLoadingSpinnerProps {
|
||||||
|
text?: string;
|
||||||
|
size?: 'small' | 'medium' | 'large';
|
||||||
|
style?: any;
|
||||||
|
source?: any; // optional override for Lottie source
|
||||||
|
offsetY?: number; // optional vertical offset
|
||||||
|
}
|
||||||
|
|
||||||
|
const DogLoadingSpinner: React.FC<DogLoadingSpinnerProps> = ({
|
||||||
|
text,
|
||||||
|
size = 'large',
|
||||||
|
style,
|
||||||
|
source,
|
||||||
|
offsetY = 0,
|
||||||
|
}) => {
|
||||||
|
const { currentTheme } = useTheme();
|
||||||
|
|
||||||
|
const getSizeStyles = () => {
|
||||||
|
switch (size) {
|
||||||
|
case 'small':
|
||||||
|
return { width: 60, height: 60 };
|
||||||
|
case 'medium':
|
||||||
|
return { width: 100, height: 100 };
|
||||||
|
case 'large':
|
||||||
|
default:
|
||||||
|
return { width: 150, height: 150 };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTextSize = () => {
|
||||||
|
switch (size) {
|
||||||
|
case 'small':
|
||||||
|
return 12;
|
||||||
|
case 'medium':
|
||||||
|
return 14;
|
||||||
|
case 'large':
|
||||||
|
default:
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[styles.container, { transform: [{ translateY: offsetY }] }, style]}>
|
||||||
|
<LottieView
|
||||||
|
source={source || require('../../../assets/dog-running.lottie')}
|
||||||
|
autoPlay
|
||||||
|
loop
|
||||||
|
style={[styles.animation, getSizeStyles()]}
|
||||||
|
resizeMode="contain"
|
||||||
|
/>
|
||||||
|
{text && (
|
||||||
|
<Text style={[
|
||||||
|
styles.text,
|
||||||
|
{
|
||||||
|
color: currentTheme.colors.textMuted,
|
||||||
|
fontSize: getTextSize()
|
||||||
|
}
|
||||||
|
]}>
|
||||||
|
{text}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
// Size will be set by getSizeStyles()
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
marginTop: 16,
|
||||||
|
textAlign: 'center',
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DogLoadingSpinner;
|
||||||
|
|
@ -48,6 +48,7 @@ import { useSettings, settingsEmitter } from '../hooks/useSettings';
|
||||||
import FeaturedContent from '../components/home/FeaturedContent';
|
import FeaturedContent from '../components/home/FeaturedContent';
|
||||||
import CatalogSection from '../components/home/CatalogSection';
|
import CatalogSection from '../components/home/CatalogSection';
|
||||||
import { SkeletonFeatured } from '../components/home/SkeletonLoaders';
|
import { SkeletonFeatured } from '../components/home/SkeletonLoaders';
|
||||||
|
import DogLoadingSpinner from '../components/common/DogLoadingSpinner';
|
||||||
import homeStyles, { sharedStyles } from '../styles/homeStyles';
|
import homeStyles, { sharedStyles } from '../styles/homeStyles';
|
||||||
import { useTheme } from '../contexts/ThemeContext';
|
import { useTheme } from '../contexts/ThemeContext';
|
||||||
import type { Theme } from '../contexts/ThemeContext';
|
import type { Theme } from '../contexts/ThemeContext';
|
||||||
|
|
@ -92,7 +93,7 @@ const SkeletonCatalog = React.memo(() => {
|
||||||
return (
|
return (
|
||||||
<View style={styles.catalogContainer}>
|
<View style={styles.catalogContainer}>
|
||||||
<View style={styles.loadingPlaceholder}>
|
<View style={styles.loadingPlaceholder}>
|
||||||
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
<DogLoadingSpinner size="small" text="" />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
@ -545,8 +546,7 @@ const HomeScreen = () => {
|
||||||
translucent
|
translucent
|
||||||
/>
|
/>
|
||||||
<View style={styles.loadingMainContainer}>
|
<View style={styles.loadingMainContainer}>
|
||||||
<ActivityIndicator size="large" color={currentTheme.colors.primary} />
|
<DogLoadingSpinner size="large" offsetY={-20} />
|
||||||
<Text style={[styles.loadingText, { color: currentTheme.colors.textMuted }]}>Loading your content...</Text>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
@ -633,7 +633,7 @@ const HomeScreen = () => {
|
||||||
<View style={styles.catalogPlaceholder}>
|
<View style={styles.catalogPlaceholder}>
|
||||||
<View style={styles.placeholderHeader}>
|
<View style={styles.placeholderHeader}>
|
||||||
<View style={[styles.placeholderTitle, { backgroundColor: currentTheme.colors.elevation1 }]} />
|
<View style={[styles.placeholderTitle, { backgroundColor: currentTheme.colors.elevation1 }]} />
|
||||||
<ActivityIndicator size="small" color={currentTheme.colors.primary} />
|
<DogLoadingSpinner size="small" text="" />
|
||||||
</View>
|
</View>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
horizontal
|
horizontal
|
||||||
|
|
@ -793,7 +793,7 @@ const styles = StyleSheet.create<any>({
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingBottom: 90,
|
// Ensure perfect centering
|
||||||
},
|
},
|
||||||
loadingText: {
|
loadingText: {
|
||||||
marginTop: 12,
|
marginTop: 12,
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,11 @@ import { logger } from '../utils/logger';
|
||||||
import { BlurView } from 'expo-blur';
|
import { BlurView } from 'expo-blur';
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import { useTheme } from '../contexts/ThemeContext';
|
import { useTheme } from '../contexts/ThemeContext';
|
||||||
|
import DogLoadingSpinner from '../components/common/DogLoadingSpinner';
|
||||||
|
|
||||||
const { width, height } = Dimensions.get('window');
|
const { width, height } = Dimensions.get('window');
|
||||||
const isTablet = width >= 768;
|
const isTablet = width >= 768;
|
||||||
|
const TAB_BAR_HEIGHT = 85;
|
||||||
|
|
||||||
// Tablet-optimized poster sizes
|
// Tablet-optimized poster sizes
|
||||||
const HORIZONTAL_ITEM_WIDTH = isTablet ? width * 0.18 : width * 0.3;
|
const HORIZONTAL_ITEM_WIDTH = isTablet ? width * 0.18 : width * 0.3;
|
||||||
|
|
@ -582,7 +584,13 @@ const SearchScreen = () => {
|
||||||
{/* Content Container */}
|
{/* Content Container */}
|
||||||
<View style={[styles.contentContainer, { backgroundColor: currentTheme.colors.darkBackground }]}>
|
<View style={[styles.contentContainer, { backgroundColor: currentTheme.colors.darkBackground }]}>
|
||||||
{searching ? (
|
{searching ? (
|
||||||
<SimpleSearchAnimation />
|
<View style={styles.loadingOverlay} pointerEvents="none">
|
||||||
|
<DogLoadingSpinner
|
||||||
|
size="large"
|
||||||
|
offsetY={-60}
|
||||||
|
source={require('../../assets/Progress of loading hand.lottie')}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
) : query.trim().length === 1 ? (
|
) : query.trim().length === 1 ? (
|
||||||
<Animated.View
|
<Animated.View
|
||||||
style={styles.emptyContainer}
|
style={styles.emptyContainer}
|
||||||
|
|
@ -815,6 +823,16 @@ const styles = StyleSheet.create({
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
|
loadingOverlay: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
zIndex: 5,
|
||||||
|
},
|
||||||
loadingText: {
|
loadingText: {
|
||||||
marginTop: 16,
|
marginTop: 16,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue