@umituz/react-native-mascot 1.3.5 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/assets/index.ts +7 -7
- package/src/presentation/components/Mascot.tsx +17 -5
- package/src/presentation/components/SVGMascot.tsx +5 -5
- package/src/presentation/contexts/MascotContext.tsx +8 -6
- package/src/presentation/hooks/useMascotAnimation.ts +0 -15
- package/src/presentation/hooks/useMascotState.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-mascot",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.7",
|
|
4
4
|
"description": "Interactive mascot system for React Native apps - Customizable animated characters with Lottie and SVG support, mood system, and easy integration",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"lottie-react-native": "^7.3.4"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@umituz/react-native-animation": "
|
|
56
|
-
"@umituz/react-native-design-system": "
|
|
55
|
+
"@umituz/react-native-animation": "^1.4.3",
|
|
56
|
+
"@umituz/react-native-design-system": "4.29.3",
|
|
57
57
|
"expo": ">=54.0.0",
|
|
58
58
|
"react": ">=19.0.0",
|
|
59
59
|
"react-native": "*",
|
package/src/assets/index.ts
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
import type { MascotConfig, MascotAnimationType } from '../domain/types/MascotTypes';
|
|
7
7
|
import type { MascotAnimation } from '../domain/types/MascotTypes';
|
|
8
8
|
|
|
9
|
-
// Import JSON animations
|
|
10
|
-
import idleAnim from '
|
|
11
|
-
import waveAnim from '
|
|
12
|
-
import jumpAnim from '
|
|
13
|
-
import successAnim from '
|
|
14
|
-
import errorAnim from '
|
|
15
|
-
import danceAnim from '
|
|
9
|
+
// Import JSON animations from infrastructure/assets
|
|
10
|
+
import idleAnim from '../infrastructure/assets/lottie/idle.json';
|
|
11
|
+
import waveAnim from '../infrastructure/assets/lottie/wave.json';
|
|
12
|
+
import jumpAnim from '../infrastructure/assets/lottie/jump.json';
|
|
13
|
+
import successAnim from '../infrastructure/assets/lottie/success.json';
|
|
14
|
+
import errorAnim from '../infrastructure/assets/lottie/error.json';
|
|
15
|
+
import danceAnim from '../infrastructure/assets/lottie/dance.json';
|
|
16
16
|
|
|
17
17
|
export const BUILT_IN_MASCOTS: Record<string, MascotConfig> = {
|
|
18
18
|
'happy-robot': {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import React, { useEffect, memo } from 'react';
|
|
24
|
-
import { View, Image, StyleSheet, ViewStyle, ImageSourcePropType } from 'react-native';
|
|
24
|
+
import { View, Image, StyleSheet, ViewStyle, ImageSourcePropType, TextStyle } from 'react-native';
|
|
25
25
|
import Animated, {
|
|
26
26
|
useSharedValue,
|
|
27
27
|
useAnimatedStyle,
|
|
@@ -33,6 +33,9 @@ import Animated, {
|
|
|
33
33
|
|
|
34
34
|
import type { MascotState } from './types';
|
|
35
35
|
|
|
36
|
+
// Constants
|
|
37
|
+
const CIRCULAR_RADIUS = 9999;
|
|
38
|
+
|
|
36
39
|
export interface MascotProps {
|
|
37
40
|
/** Image source for the mascot (require() or URI) */
|
|
38
41
|
source: ImageSourcePropType;
|
|
@@ -247,7 +250,12 @@ function MascotComponent({
|
|
|
247
250
|
|
|
248
251
|
MascotComponent.displayName = 'Mascot';
|
|
249
252
|
|
|
250
|
-
|
|
253
|
+
interface MascotTextProps {
|
|
254
|
+
style: TextStyle;
|
|
255
|
+
children: React.ReactNode;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const MascotTextComponent = ({ style, children }: MascotTextProps) => (
|
|
251
259
|
<View>
|
|
252
260
|
{typeof children === 'string' ? (
|
|
253
261
|
<Animated.Text style={style}>{children}</Animated.Text>
|
|
@@ -255,7 +263,11 @@ const MascotText = memo(({ style, children }: { style: any; children: React.Reac
|
|
|
255
263
|
children
|
|
256
264
|
)}
|
|
257
265
|
</View>
|
|
258
|
-
)
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
MascotTextComponent.displayName = 'MascotText';
|
|
269
|
+
|
|
270
|
+
const MascotText = memo(MascotTextComponent);
|
|
259
271
|
|
|
260
272
|
export const Mascot = memo(MascotComponent);
|
|
261
273
|
|
|
@@ -264,7 +276,7 @@ const styles = StyleSheet.create({
|
|
|
264
276
|
alignItems: 'center',
|
|
265
277
|
},
|
|
266
278
|
glow: {
|
|
267
|
-
borderRadius:
|
|
279
|
+
borderRadius: CIRCULAR_RADIUS,
|
|
268
280
|
position: 'absolute',
|
|
269
281
|
},
|
|
270
282
|
glowContainer: {
|
|
@@ -273,7 +285,7 @@ const styles = StyleSheet.create({
|
|
|
273
285
|
position: 'relative',
|
|
274
286
|
},
|
|
275
287
|
mascotImage: {
|
|
276
|
-
borderRadius:
|
|
288
|
+
borderRadius: CIRCULAR_RADIUS,
|
|
277
289
|
},
|
|
278
290
|
messageContainer: {
|
|
279
291
|
borderRadius: 12,
|
|
@@ -25,7 +25,7 @@ const SVGMascotComponent = memo<SVGMascotProps>(({ mascot, size }) => {
|
|
|
25
25
|
<circle cx="35" cy="40" r="5" fill="#000" />
|
|
26
26
|
<circle cx="65" cy="40" r="5" fill="#000" />
|
|
27
27
|
{/* Mouth based on mood */}
|
|
28
|
-
<
|
|
28
|
+
<MoodExpression mood={mascot.personality.mood} />
|
|
29
29
|
</Svg>
|
|
30
30
|
);
|
|
31
31
|
});
|
|
@@ -35,11 +35,11 @@ SVGMascotComponent.displayName = 'SVGMascot';
|
|
|
35
35
|
export const SVGMascot = SVGMascotComponent;
|
|
36
36
|
|
|
37
37
|
// Mood-based mouth component
|
|
38
|
-
interface
|
|
38
|
+
interface MoodExpressionProps {
|
|
39
39
|
mood: string;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const
|
|
42
|
+
const MoodExpressionComponent = memo<MoodExpressionProps>(({ mood }) => {
|
|
43
43
|
switch (mood) {
|
|
44
44
|
case 'happy':
|
|
45
45
|
case 'excited':
|
|
@@ -56,6 +56,6 @@ const MoodMoodComponent = memo<MoodMoodProps>(({ mood }) => {
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
MoodExpressionComponent.displayName = 'MoodExpression';
|
|
60
60
|
|
|
61
|
-
const
|
|
61
|
+
const MoodExpression = memo(MoodExpressionComponent);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Thin wrapper that provides MascotService to components
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React, { createContext, useContext, ReactNode } from 'react';
|
|
6
|
+
import React, { createContext, useContext, ReactNode, useEffect } from 'react';
|
|
7
7
|
import type { Mascot } from '../../domain/entities/Mascot';
|
|
8
8
|
import type { MascotConfig } from '../../domain/types/MascotTypes';
|
|
9
9
|
import type { MascotService, MascotTemplate } from '../../application/services/MascotService';
|
|
@@ -33,11 +33,13 @@ export const MascotProvider: React.FC<MascotProviderProps> = ({
|
|
|
33
33
|
const service = container.getMascotService();
|
|
34
34
|
|
|
35
35
|
// Auto-initialize if config or template provided
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (initialConfig) {
|
|
38
|
+
service.initialize(initialConfig);
|
|
39
|
+
} else if (template) {
|
|
40
|
+
service.fromTemplate(template);
|
|
41
|
+
}
|
|
42
|
+
}, [initialConfig, template, service]);
|
|
41
43
|
|
|
42
44
|
const value: MascotContextValue = {
|
|
43
45
|
mascot: service.mascot,
|
|
@@ -14,14 +14,11 @@ export interface UseMascotAnimationOptions {
|
|
|
14
14
|
export interface UseMascotAnimationReturn {
|
|
15
15
|
isPlaying: boolean;
|
|
16
16
|
currentAnimation: string | null;
|
|
17
|
-
progress: number;
|
|
18
17
|
queue: string[];
|
|
19
18
|
play: (animationId: string, options?: AnimationOptions) => Promise<void>;
|
|
20
19
|
pause: () => void;
|
|
21
20
|
resume: () => void;
|
|
22
21
|
stop: () => void;
|
|
23
|
-
setSpeed: (speed: number) => void;
|
|
24
|
-
setProgress: (progress: number) => void;
|
|
25
22
|
queueAnimation: (animationId: string) => void;
|
|
26
23
|
clearQueue: () => void;
|
|
27
24
|
playSequence: (animationIds: string[]) => Promise<void>;
|
|
@@ -69,15 +66,6 @@ export function useMascotAnimation(
|
|
|
69
66
|
service.stopAnimation();
|
|
70
67
|
}, [service]);
|
|
71
68
|
|
|
72
|
-
const setSpeed = useCallback((_speed: number) => {
|
|
73
|
-
// Speed is handled via options in play() - this method is kept for API compatibility
|
|
74
|
-
// but does nothing as speed should be passed to play() directly
|
|
75
|
-
}, []);
|
|
76
|
-
|
|
77
|
-
const setProgress = useCallback((_progress: number) => {
|
|
78
|
-
// Progress tracking not yet implemented - would need AnimationController reference
|
|
79
|
-
}, []);
|
|
80
|
-
|
|
81
69
|
const queueAnimation = useCallback((animationId: string) => {
|
|
82
70
|
setQueue((prev: string[]) => [...prev, animationId]);
|
|
83
71
|
}, []);
|
|
@@ -106,14 +94,11 @@ export function useMascotAnimation(
|
|
|
106
94
|
return {
|
|
107
95
|
isPlaying: service.isPlaying,
|
|
108
96
|
currentAnimation: service.currentAnimation,
|
|
109
|
-
progress: 0, // Would need AnimationController reference
|
|
110
97
|
queue,
|
|
111
98
|
play,
|
|
112
99
|
pause,
|
|
113
100
|
resume,
|
|
114
101
|
stop,
|
|
115
|
-
setSpeed,
|
|
116
|
-
setProgress,
|
|
117
102
|
queueAnimation,
|
|
118
103
|
clearQueue,
|
|
119
104
|
playSequence,
|
|
@@ -137,7 +137,7 @@ export function useMascotState(options: UseMascotStateOptions = {}): UseMascotSt
|
|
|
137
137
|
try {
|
|
138
138
|
manager.transitionTo(newState);
|
|
139
139
|
} catch (error) {
|
|
140
|
-
|
|
140
|
+
// Invalid state transition - allow the transition anyway for flexibility
|
|
141
141
|
setState(newState);
|
|
142
142
|
onStateChangeRef.current?.(state, newState);
|
|
143
143
|
}
|