@memori.ai/memori-react 7.15.2 → 7.16.0

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.
Files changed (65) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.d.ts +5 -0
  3. package/dist/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js +55 -0
  4. package/dist/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js.map +1 -0
  5. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +24 -22
  6. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  7. package/dist/components/ChatTextArea/ChatTextArea.js +1 -1
  8. package/dist/components/ChatTextArea/ChatTextArea.js.map +1 -1
  9. package/dist/components/UploadButton/UploadButton.css +7 -0
  10. package/dist/components/UploadButton/UploadButton.js +90 -19
  11. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  12. package/dist/components/ui/Alert.css +93 -0
  13. package/dist/components/ui/Alert.d.ts +18 -0
  14. package/dist/components/ui/Alert.js +42 -0
  15. package/dist/components/ui/Alert.js.map +1 -0
  16. package/dist/styles.css +1 -1
  17. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.d.ts +5 -0
  18. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js +53 -0
  19. package/esm/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.js.map +1 -0
  20. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +25 -24
  21. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  22. package/esm/components/ChatTextArea/ChatTextArea.js +1 -1
  23. package/esm/components/ChatTextArea/ChatTextArea.js.map +1 -1
  24. package/esm/components/UploadButton/UploadButton.css +7 -0
  25. package/esm/components/UploadButton/UploadButton.js +90 -19
  26. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  27. package/esm/components/ui/Alert.css +93 -0
  28. package/esm/components/ui/Alert.d.ts +18 -0
  29. package/esm/components/ui/Alert.js +39 -0
  30. package/esm/components/ui/Alert.js.map +1 -0
  31. package/esm/styles.css +1 -1
  32. package/package.json +1 -1
  33. package/src/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.tsx +96 -0
  34. package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.tsx +42 -39
  35. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +9 -0
  36. package/src/components/ChatInputs/__snapshots__/ChatInputs.test.tsx.snap +6 -0
  37. package/src/components/ChatTextArea/ChatTextArea.tsx +1 -0
  38. package/src/components/ChatTextArea/__snapshots__/ChatTextArea.test.tsx.snap +3 -0
  39. package/src/components/UploadButton/UploadButton.css +7 -0
  40. package/src/components/UploadButton/UploadButton.tsx +194 -52
  41. package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +56 -2
  42. package/src/components/ui/Alert.css +93 -0
  43. package/src/components/ui/Alert.stories.tsx +137 -0
  44. package/src/components/ui/Alert.test.tsx +129 -0
  45. package/src/components/ui/Alert.tsx +123 -0
  46. package/src/components/ui/__snapshots__/Alert.test.tsx.snap +56 -0
  47. package/src/styles.css +1 -1
  48. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.d.ts +0 -17
  49. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.js +0 -73
  50. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.js.map +0 -1
  51. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.d.ts +0 -17
  52. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.js +0 -25
  53. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.js.map +0 -1
  54. package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.d.ts +0 -26
  55. package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js +0 -166
  56. package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js.map +0 -1
  57. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.d.ts +0 -17
  58. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.js +0 -69
  59. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/MorhTargetController.js.map +0 -1
  60. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.d.ts +0 -17
  61. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.js +0 -22
  62. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/constants.js.map +0 -1
  63. package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.d.ts +0 -26
  64. package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js +0 -163
  65. package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js.map +0 -1
@@ -0,0 +1,96 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { Canvas } from '@react-three/fiber';
3
+ import { ContactShadows, PerspectiveCamera } from '@react-three/drei';
4
+
5
+ const DynamicShadow = ({
6
+ currentBaseAction,
7
+ avatarPosition,
8
+ }: {
9
+ currentBaseAction: any;
10
+ avatarPosition: any;
11
+ }) => {
12
+ // Calculate shadow properties based on animation
13
+ const getShadowProps = () => {
14
+ const baseProps = {
15
+ width: 10,
16
+ height: 10,
17
+ blur: 2.5,
18
+ scale: 10,
19
+ far: 5,
20
+ resolution: 1024,
21
+ color: '#000000',
22
+ };
23
+
24
+ // Adjust shadow based on animation type
25
+ if (currentBaseAction.action.startsWith('Loading')) {
26
+ return {
27
+ ...baseProps,
28
+ opacity: 0.85,
29
+ blur: 3,
30
+ width: 12,
31
+ height: 12,
32
+ };
33
+ } else if (
34
+ currentBaseAction.action.includes('Gioia') ||
35
+ currentBaseAction.action.includes('Joy')
36
+ ) {
37
+ return {
38
+ ...baseProps,
39
+ opacity: 0.9,
40
+ blur: 2,
41
+ width: 11,
42
+ height: 11,
43
+ };
44
+ } else if (
45
+ currentBaseAction.action.includes('Rabbia') ||
46
+ currentBaseAction.action.includes('Anger')
47
+ ) {
48
+ return {
49
+ ...baseProps,
50
+ opacity: 0.95,
51
+ blur: 1.8,
52
+ width: 12,
53
+ height: 12,
54
+ };
55
+ }
56
+
57
+ // Default idle state
58
+ return {
59
+ ...baseProps,
60
+ opacity: 0.9,
61
+ blur: 2.2,
62
+ };
63
+ };
64
+
65
+ const shadowProps = getShadowProps();
66
+
67
+ return (
68
+ <>
69
+ {/* Main body shadow */}
70
+ <ContactShadows
71
+ opacity={shadowProps.opacity}
72
+ scale={shadowProps.scale}
73
+ blur={shadowProps.blur}
74
+ far={shadowProps.far}
75
+ resolution={shadowProps.resolution}
76
+ color={shadowProps.color}
77
+ frames={Infinity}
78
+ position={[0, avatarPosition.y, 0]}
79
+ />
80
+
81
+ {/* Foot shadow - smaller and sharper */}
82
+ <ContactShadows
83
+ opacity={1}
84
+ width={5}
85
+ height={5}
86
+ blur={1}
87
+ far={2}
88
+ resolution={1024}
89
+ color="#000000"
90
+ position={[0, -0.98, 0]}
91
+ />
92
+ </>
93
+ );
94
+ };
95
+
96
+ export default DynamicShadow;
@@ -4,6 +4,7 @@ import {
4
4
  SkinnedMesh,
5
5
  Object3D,
6
6
  AnimationAction,
7
+ Vector3
7
8
  } from 'three';
8
9
  import { useAnimations, useGLTF } from '@react-three/drei';
9
10
  import { useFrame } from '@react-three/fiber';
@@ -19,6 +20,7 @@ import {
19
20
  DEFAULT_CONFIG,
20
21
  SCALE_LERP_FACTOR,
21
22
  } from '../../constants';
23
+ import DynamicShadow from '../../Shadow/DynamicShadow';
22
24
 
23
25
  export function FullbodyAvatar({
24
26
  url,
@@ -44,6 +46,10 @@ export function FullbodyAvatar({
44
46
  const animationControllerRef = useRef<AnimationController>();
45
47
  const morphTargetControllerRef = useRef<MorphTargetController>();
46
48
  const positionControllerRef = useRef<AvatarPositionController>();
49
+ const lastPositionRef = useRef<Vector3>(AVATAR_POSITION.clone());
50
+ const positionUpdateThrottleRef = useRef<number>(0);
51
+ const POSITION_UPDATE_INTERVAL = 1; // ~1000fps for more frequent updates
52
+ const POSITION_THRESHOLD = 0.000001; // Much smaller threshold for more sensitive detection
47
53
 
48
54
  const blinkStateRef = useRef({
49
55
  isBlinking: false,
@@ -68,19 +74,23 @@ export function FullbodyAvatar({
68
74
  );
69
75
 
70
76
  if (headMesh) {
71
- // console.log('[FullbodyAvatar] Head mesh found:', headMesh.name);
72
77
  morphTargetControllerRef.current = new MorphTargetController(headMesh);
73
78
 
74
79
  if (headMesh.morphTargetDictionary && headMesh.morphTargetInfluences) {
75
- // console.log('[FullbodyAvatar] Setting morph target dictionary and influences', headMesh.morphTargetDictionary, headMesh.morphTargetInfluences);
76
80
  setMorphTargetDictionary(headMesh.morphTargetDictionary);
77
81
  const initialInfluences = Object.keys(headMesh.morphTargetDictionary)
78
82
  .reduce((acc, key) => ({ ...acc, [key]: 0 }), {});
79
- // console.log('[FullbodyAvatar] Setting initial influences', initialInfluences);
80
83
  setMorphTargetInfluences(initialInfluences);
81
84
  }
82
85
  }
86
+
87
+ // Initialize position tracking with high precision
88
+ const initialPosition = AVATAR_POSITION.clone();
89
+ initialPosition.setX(Number(initialPosition.x.toFixed(6)));
90
+ initialPosition.setY(Number(initialPosition.y.toFixed(6)));
91
+ initialPosition.setZ(Number(initialPosition.z.toFixed(6)));
83
92
  }, [actions, scene]);
93
+
84
94
  useEffect(() => {
85
95
  if (positionControllerRef.current) {
86
96
  positionControllerRef.current.updateHeight(avatarHeight, false);
@@ -113,36 +123,6 @@ export function FullbodyAvatar({
113
123
  return foundMesh;
114
124
  }, [scene]);
115
125
 
116
- // Initialize controllers
117
- useEffect(() => {
118
- if (!actions || !headMesh) return;
119
-
120
- const mixer = new AnimationMixer(scene);
121
- animationControllerRef.current = new AnimationController(
122
- mixer,
123
- actions as Record<string, AnimationAction>,
124
- { ...DEFAULT_CONFIG }
125
- );
126
-
127
- morphTargetControllerRef.current = new MorphTargetController(headMesh);
128
-
129
- // Initialize morph target dictionary and influences
130
- if (headMesh.morphTargetDictionary && headMesh.morphTargetInfluences) {
131
- setMorphTargetDictionary(headMesh.morphTargetDictionary);
132
- const initialInfluences = Object.keys(
133
- headMesh.morphTargetDictionary
134
- ).reduce((acc, key) => ({ ...acc, [key]: 0 }), {});
135
- setMorphTargetInfluences(initialInfluences);
136
- }
137
- }, [
138
- actions,
139
- headMesh,
140
- scene,
141
- setMorphTargetDictionary,
142
- setMorphTargetInfluences,
143
- timeScale,
144
- ]);
145
-
146
126
  // Handle animation state changes
147
127
  useEffect(() => {
148
128
  if (!animationControllerRef.current) return;
@@ -153,7 +133,7 @@ export function FullbodyAvatar({
153
133
  AnimationState.LOADING,
154
134
  currentBaseAction.action
155
135
  );
156
- } else if (currentBaseAction.action.includes('->')) {
136
+ } else if (currentBaseAction.action.includes('->')) {
157
137
  animationControllerRef.current.playSequence(currentBaseAction.action);
158
138
  } else if (currentBaseAction.action.startsWith('Idle')) {
159
139
  animationControllerRef.current.transitionTo(AnimationState.IDLE);
@@ -170,8 +150,7 @@ export function FullbodyAvatar({
170
150
  animationControllerRef.current?.setTimeScale(timeScale);
171
151
  }, [timeScale]);
172
152
 
173
-
174
- // Animation and scaling update loop
153
+ // Animation and scaling update loop with high precision position tracking
175
154
  useFrame((state, delta) => {
176
155
  const currentTime = state.clock.elapsedTime * 1000;
177
156
 
@@ -190,22 +169,46 @@ export function FullbodyAvatar({
190
169
  );
191
170
  }
192
171
 
193
- // Update scale with smooth transition
172
+ // Update scale and check position changes with high precision
194
173
  if (scene && positionControllerRef.current) {
195
174
  const newScale = positionControllerRef.current.updateScale(SCALE_LERP_FACTOR);
196
175
  scene.scale.copy(newScale);
176
+
177
+ // High frequency position update check
178
+ if (currentTime - positionUpdateThrottleRef.current >= POSITION_UPDATE_INTERVAL) {
179
+ const currentPosition = positionControllerRef.current.getPosition();
180
+
181
+ // Round to 6 decimal places for high precision
182
+ currentPosition.setX(Number(currentPosition.x.toFixed(6)));
183
+ currentPosition.setY(Number(currentPosition.y.toFixed(6)));
184
+ currentPosition.setZ(Number(currentPosition.z.toFixed(6)));
185
+
186
+ const positionDelta = currentPosition.distanceTo(lastPositionRef.current);
187
+
188
+ lastPositionRef.current.copy(currentPosition);
189
+
190
+ positionUpdateThrottleRef.current = currentTime;
191
+ }
197
192
  }
198
193
  });
199
194
 
200
- // Get current position from controller
201
- const position = positionControllerRef.current?.getPosition() || AVATAR_POSITION;
195
+ // Get current position from controller with fallback
196
+ const position = useMemo(() => {
197
+ return positionControllerRef.current?.getPosition() || AVATAR_POSITION.clone();
198
+ }, [positionControllerRef.current]);
202
199
 
203
200
  return (
201
+ <>
202
+ <DynamicShadow
203
+ currentBaseAction={currentBaseAction}
204
+ avatarPosition={position}
205
+ />
204
206
  <group
205
207
  position={position}
206
208
  rotation={AVATAR_ROTATION}
207
209
  >
208
210
  <primitive object={scene} />
209
211
  </group>
212
+ </>
210
213
  );
211
214
  }
@@ -479,6 +479,7 @@ exports[`renders Chat unchanged 1`] = `
479
479
  >
480
480
  <textarea
481
481
  class="memori-chat-textarea--input"
482
+ maxlength="100000"
482
483
  />
483
484
  <div
484
485
  class="memori-chat-textarea--expand"
@@ -1041,6 +1042,7 @@ exports[`renders Chat with context vars unchanged 1`] = `
1041
1042
  >
1042
1043
  <textarea
1043
1044
  class="memori-chat-textarea--input"
1045
+ maxlength="100000"
1044
1046
  />
1045
1047
  <div
1046
1048
  class="memori-chat-textarea--expand"
@@ -1549,6 +1551,7 @@ exports[`renders Chat with custom user avatar as react element unchanged 1`] = `
1549
1551
  >
1550
1552
  <textarea
1551
1553
  class="memori-chat-textarea--input"
1554
+ maxlength="100000"
1552
1555
  />
1553
1556
  <div
1554
1557
  class="memori-chat-textarea--expand"
@@ -2063,6 +2066,7 @@ exports[`renders Chat with custom user avatar unchanged 1`] = `
2063
2066
  >
2064
2067
  <textarea
2065
2068
  class="memori-chat-textarea--input"
2069
+ maxlength="100000"
2066
2070
  />
2067
2071
  <div
2068
2072
  class="memori-chat-textarea--expand"
@@ -2630,6 +2634,7 @@ exports[`renders Chat with dates unchanged 1`] = `
2630
2634
  >
2631
2635
  <textarea
2632
2636
  class="memori-chat-textarea--input"
2637
+ maxlength="100000"
2633
2638
  />
2634
2639
  <div
2635
2640
  class="memori-chat-textarea--expand"
@@ -3188,6 +3193,7 @@ exports[`renders Chat with hints unchanged 1`] = `
3188
3193
  >
3189
3194
  <textarea
3190
3195
  class="memori-chat-textarea--input"
3196
+ maxlength="100000"
3191
3197
  />
3192
3198
  <div
3193
3199
  class="memori-chat-textarea--expand"
@@ -4121,6 +4127,7 @@ exports[`renders Chat with media unchanged 1`] = `
4121
4127
  >
4122
4128
  <textarea
4123
4129
  class="memori-chat-textarea--input"
4130
+ maxlength="100000"
4124
4131
  />
4125
4132
  <div
4126
4133
  class="memori-chat-textarea--expand"
@@ -4674,6 +4681,7 @@ exports[`renders Chat with memori typing unchanged 1`] = `
4674
4681
  >
4675
4682
  <textarea
4676
4683
  class="memori-chat-textarea--input"
4684
+ maxlength="100000"
4677
4685
  />
4678
4686
  <div
4679
4687
  class="memori-chat-textarea--expand"
@@ -5188,6 +5196,7 @@ exports[`renders Chat with user unchanged 1`] = `
5188
5196
  >
5189
5197
  <textarea
5190
5198
  class="memori-chat-textarea--input"
5199
+ maxlength="100000"
5191
5200
  />
5192
5201
  <div
5193
5202
  class="memori-chat-textarea--expand"
@@ -17,6 +17,7 @@ exports[`renders ChatInputs disabled unchanged 1`] = `
17
17
  <textarea
18
18
  class="memori-chat-textarea--input"
19
19
  disabled=""
20
+ maxlength="100000"
20
21
  >
21
22
  Lorem ipsum
22
23
  </textarea>
@@ -120,6 +121,7 @@ exports[`renders ChatInputs listening unchanged 1`] = `
120
121
  >
121
122
  <textarea
122
123
  class="memori-chat-textarea--input"
124
+ maxlength="100000"
123
125
  >
124
126
  Lorem ipsum
125
127
  </textarea>
@@ -223,6 +225,7 @@ exports[`renders ChatInputs on instruct unchanged 1`] = `
223
225
  >
224
226
  <textarea
225
227
  class="memori-chat-textarea--input"
228
+ maxlength="100000"
226
229
  >
227
230
  Lorem ipsum
228
231
  </textarea>
@@ -326,6 +329,7 @@ exports[`renders ChatInputs unchanged 1`] = `
326
329
  >
327
330
  <textarea
328
331
  class="memori-chat-textarea--input"
332
+ maxlength="100000"
329
333
  />
330
334
  <div
331
335
  class="memori-chat-textarea--expand"
@@ -428,6 +432,7 @@ exports[`renders ChatInputs with user message unchanged 1`] = `
428
432
  >
429
433
  <textarea
430
434
  class="memori-chat-textarea--input"
435
+ maxlength="100000"
431
436
  >
432
437
  Lorem ipsum
433
438
  </textarea>
@@ -531,6 +536,7 @@ exports[`renders ChatInputs without microphone button unchanged 1`] = `
531
536
  >
532
537
  <textarea
533
538
  class="memori-chat-textarea--input"
539
+ maxlength="100000"
534
540
  >
535
541
  Lorem ipsum
536
542
  </textarea>
@@ -48,6 +48,7 @@ const ChatTextArea: React.FC<Props> = ({
48
48
  }}
49
49
  onFocus={onFocus}
50
50
  onBlur={onBlur}
51
+ maxLength={100000}
51
52
  />
52
53
  <div className="memori-chat-textarea--expand">
53
54
  <Button
@@ -11,6 +11,7 @@ exports[`renders ChatTextArea unchanged 1`] = `
11
11
  >
12
12
  <textarea
13
13
  class="memori-chat-textarea--input"
14
+ maxlength="100000"
14
15
  />
15
16
  <div
16
17
  class="memori-chat-textarea--expand"
@@ -52,6 +53,7 @@ exports[`renders ChatTextArea with long text unchanged 1`] = `
52
53
  >
53
54
  <textarea
54
55
  class="memori-chat-textarea--input"
56
+ maxlength="100000"
55
57
  >
56
58
  Suspendisse sit amet volutpat velit. Nunc at commodo tortor, id rutrum nunc. Vivamus condimentum vel nunc et congue. Ut laoreet imperdiet nisi ac finibus. Suspendisse molestie risus a justo sagittis efficitur. Suspendisse sit amet volutpat velit. Nunc at commodo tortor, id rutrum nunc. Vivamus condimentum vel nunc et congue. Ut laoreet imperdiet nisi ac finibus. Suspendisse molestie risus a justo sagittis efficitur.
57
59
  </textarea>
@@ -95,6 +97,7 @@ exports[`renders ChatTextArea with value unchanged 1`] = `
95
97
  >
96
98
  <textarea
97
99
  class="memori-chat-textarea--input"
100
+ maxlength="100000"
98
101
  >
99
102
  Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.
100
103
  </textarea>
@@ -36,3 +36,10 @@
36
36
  transition: fill 0.2s ease;
37
37
  }
38
38
 
39
+ .memori--error-message-container {
40
+ position: absolute;
41
+ z-index: 1000;
42
+ right: 0;
43
+ bottom: 50%;
44
+ width: 100%;
45
+ }