@memori.ai/memori-react 7.5.1 → 7.6.1

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 (218) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +10 -2
  3. package/dist/components/Avatar/Avatar.d.ts +2 -0
  4. package/dist/components/Avatar/Avatar.js +11 -6
  5. package/dist/components/Avatar/Avatar.js.map +1 -1
  6. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.d.ts +20 -0
  7. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +107 -0
  8. package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -0
  9. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controls.d.ts +26 -0
  10. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controls.js +59 -0
  11. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controls.js.map +1 -0
  12. package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.d.ts +30 -0
  13. package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js +148 -0
  14. package/dist/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js.map +1 -0
  15. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.d.ts +15 -0
  16. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js +77 -0
  17. package/dist/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js.map +1 -0
  18. package/dist/components/Avatar/AvatarView/AvatarComponent/components/loader.d.ts +5 -0
  19. package/dist/components/Avatar/AvatarView/AvatarComponent/components/loader.js +12 -0
  20. package/dist/components/Avatar/AvatarView/AvatarComponent/components/loader.js.map +1 -0
  21. package/dist/components/Avatar/AvatarView/components/avatar.d.ts +9 -0
  22. package/dist/components/Avatar/AvatarView/components/avatar.js +39 -0
  23. package/dist/components/Avatar/AvatarView/components/avatar.js.map +1 -0
  24. package/dist/components/Avatar/AvatarView/components/fullbodyAvatar.d.ts +2 -1
  25. package/dist/components/Avatar/AvatarView/components/fullbodyAvatar.js +8 -9
  26. package/dist/components/Avatar/AvatarView/components/fullbodyAvatar.js.map +1 -1
  27. package/dist/components/Avatar/AvatarView/index.d.ts +6 -1
  28. package/dist/components/Avatar/AvatarView/index.js +14 -84
  29. package/dist/components/Avatar/AvatarView/index.js.map +1 -1
  30. package/dist/components/Avatar/AvatarView/utils/useEyeBlink.d.ts +16 -2
  31. package/dist/components/Avatar/AvatarView/utils/useEyeBlink.js +62 -38
  32. package/dist/components/Avatar/AvatarView/utils/useEyeBlink.js.map +1 -1
  33. package/dist/components/Avatar/AvatarView/utils/useMouthAnimation.d.ts +16 -0
  34. package/dist/components/Avatar/AvatarView/utils/useMouthAnimation.js +59 -0
  35. package/dist/components/Avatar/AvatarView/utils/useMouthAnimation.js.map +1 -0
  36. package/dist/components/Avatar/AvatarView/utils/useMouthSpeaking.js +1 -1
  37. package/dist/components/Avatar/AvatarView/utils/useMouthSpeaking.js.map +1 -1
  38. package/dist/components/Avatar/AvatarView/utils/useSmile.js +1 -1
  39. package/dist/components/Avatar/AvatarView/utils/useSmile.js.map +1 -1
  40. package/dist/components/Avatar/AvatarView/utils/useViseme.d.ts +18 -0
  41. package/dist/components/Avatar/AvatarView/utils/useViseme.js +141 -0
  42. package/dist/components/Avatar/AvatarView/utils/useViseme.js.map +1 -0
  43. package/dist/components/Avatar/AvatarView/utils/visemeContext.d.ts +24 -0
  44. package/dist/components/Avatar/AvatarView/utils/visemeContext.js +157 -0
  45. package/dist/components/Avatar/AvatarView/utils/visemeContext.js.map +1 -0
  46. package/dist/components/ChatBubble/ChatBubble.js +2 -3
  47. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  48. package/dist/components/CompletionProviderStatus/CompletionProviderStatus.d.ts +1 -1
  49. package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js +24 -3
  50. package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
  51. package/dist/components/MemoriWidget/MemoriWidget.d.ts +1 -1
  52. package/dist/components/MemoriWidget/MemoriWidget.js +25 -3
  53. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  54. package/dist/components/MemoriWidget/enhanceSSML/enhanceSSML.d.ts +4 -0
  55. package/dist/components/MemoriWidget/enhanceSSML/enhanceSSML.js +157 -0
  56. package/dist/components/MemoriWidget/enhanceSSML/enhanceSSML.js.map +1 -0
  57. package/dist/components/StartPanel/StartPanel.js +1 -1
  58. package/dist/components/StartPanel/StartPanel.js.map +1 -1
  59. package/dist/components/layouts/HiddenChat.d.ts +4 -0
  60. package/dist/components/layouts/HiddenChat.js +50 -0
  61. package/dist/components/layouts/HiddenChat.js.map +1 -0
  62. package/dist/components/layouts/ZoomedFullBody.d.ts +4 -0
  63. package/dist/components/layouts/ZoomedFullBody.js +8 -0
  64. package/dist/components/layouts/ZoomedFullBody.js.map +1 -0
  65. package/dist/components/layouts/ZoomedHalfBody.d.ts +4 -0
  66. package/dist/components/layouts/ZoomedHalfBody.js +8 -0
  67. package/dist/components/layouts/ZoomedHalfBody.js.map +1 -0
  68. package/dist/components/layouts/hidden-chat.css +184 -0
  69. package/dist/components/layouts/zoomed-half-body.css +3 -0
  70. package/dist/context/visemeContext.d.ts +27 -0
  71. package/dist/context/visemeContext.js +221 -0
  72. package/dist/context/visemeContext.js.map +1 -0
  73. package/dist/helpers/utils.d.ts +7 -0
  74. package/dist/helpers/utils.js +51 -1
  75. package/dist/helpers/utils.js.map +1 -1
  76. package/dist/index.js +20 -16
  77. package/dist/index.js.map +1 -1
  78. package/dist/styles.css +1 -0
  79. package/esm/components/Avatar/Avatar.d.ts +2 -0
  80. package/esm/components/Avatar/Avatar.js +11 -6
  81. package/esm/components/Avatar/Avatar.js.map +1 -1
  82. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.d.ts +20 -0
  83. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +102 -0
  84. package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -0
  85. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controls.d.ts +26 -0
  86. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controls.js +56 -0
  87. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controls.js.map +1 -0
  88. package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.d.ts +30 -0
  89. package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js +145 -0
  90. package/esm/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.js.map +1 -0
  91. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.d.ts +15 -0
  92. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js +73 -0
  93. package/esm/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.js.map +1 -0
  94. package/esm/components/Avatar/AvatarView/AvatarComponent/components/loader.d.ts +5 -0
  95. package/esm/components/Avatar/AvatarView/AvatarComponent/components/loader.js +9 -0
  96. package/esm/components/Avatar/AvatarView/AvatarComponent/components/loader.js.map +1 -0
  97. package/esm/components/Avatar/AvatarView/components/avatar.d.ts +9 -0
  98. package/esm/components/Avatar/AvatarView/components/avatar.js +35 -0
  99. package/esm/components/Avatar/AvatarView/components/avatar.js.map +1 -0
  100. package/esm/components/Avatar/AvatarView/components/fullbodyAvatar.d.ts +2 -1
  101. package/esm/components/Avatar/AvatarView/components/fullbodyAvatar.js +8 -9
  102. package/esm/components/Avatar/AvatarView/components/fullbodyAvatar.js.map +1 -1
  103. package/esm/components/Avatar/AvatarView/index.d.ts +6 -1
  104. package/esm/components/Avatar/AvatarView/index.js +15 -85
  105. package/esm/components/Avatar/AvatarView/index.js.map +1 -1
  106. package/esm/components/Avatar/AvatarView/utils/useEyeBlink.d.ts +16 -2
  107. package/esm/components/Avatar/AvatarView/utils/useEyeBlink.js +61 -38
  108. package/esm/components/Avatar/AvatarView/utils/useEyeBlink.js.map +1 -1
  109. package/esm/components/Avatar/AvatarView/utils/useMouthAnimation.d.ts +16 -0
  110. package/esm/components/Avatar/AvatarView/utils/useMouthAnimation.js +55 -0
  111. package/esm/components/Avatar/AvatarView/utils/useMouthAnimation.js.map +1 -0
  112. package/esm/components/Avatar/AvatarView/utils/useMouthSpeaking.js +1 -1
  113. package/esm/components/Avatar/AvatarView/utils/useMouthSpeaking.js.map +1 -1
  114. package/esm/components/Avatar/AvatarView/utils/useSmile.js +1 -1
  115. package/esm/components/Avatar/AvatarView/utils/useSmile.js.map +1 -1
  116. package/esm/components/Avatar/AvatarView/utils/useViseme.d.ts +18 -0
  117. package/esm/components/Avatar/AvatarView/utils/useViseme.js +137 -0
  118. package/esm/components/Avatar/AvatarView/utils/useViseme.js.map +1 -0
  119. package/esm/components/Avatar/AvatarView/utils/visemeContext.d.ts +24 -0
  120. package/esm/components/Avatar/AvatarView/utils/visemeContext.js +152 -0
  121. package/esm/components/Avatar/AvatarView/utils/visemeContext.js.map +1 -0
  122. package/esm/components/ChatBubble/ChatBubble.js +2 -3
  123. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  124. package/esm/components/CompletionProviderStatus/CompletionProviderStatus.d.ts +1 -1
  125. package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js +24 -3
  126. package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
  127. package/esm/components/MemoriWidget/MemoriWidget.d.ts +1 -1
  128. package/esm/components/MemoriWidget/MemoriWidget.js +26 -4
  129. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  130. package/esm/components/MemoriWidget/enhanceSSML/enhanceSSML.d.ts +4 -0
  131. package/esm/components/MemoriWidget/enhanceSSML/enhanceSSML.js +152 -0
  132. package/esm/components/MemoriWidget/enhanceSSML/enhanceSSML.js.map +1 -0
  133. package/esm/components/StartPanel/StartPanel.js +1 -1
  134. package/esm/components/StartPanel/StartPanel.js.map +1 -1
  135. package/esm/components/layouts/HiddenChat.d.ts +4 -0
  136. package/esm/components/layouts/HiddenChat.js +47 -0
  137. package/esm/components/layouts/HiddenChat.js.map +1 -0
  138. package/esm/components/layouts/ZoomedFullBody.d.ts +4 -0
  139. package/esm/components/layouts/ZoomedFullBody.js +5 -0
  140. package/esm/components/layouts/ZoomedFullBody.js.map +1 -0
  141. package/esm/components/layouts/ZoomedHalfBody.d.ts +4 -0
  142. package/esm/components/layouts/ZoomedHalfBody.js +5 -0
  143. package/esm/components/layouts/ZoomedHalfBody.js.map +1 -0
  144. package/esm/components/layouts/hidden-chat.css +184 -0
  145. package/esm/components/layouts/zoomed-half-body.css +3 -0
  146. package/esm/context/visemeContext.d.ts +27 -0
  147. package/esm/context/visemeContext.js +216 -0
  148. package/esm/context/visemeContext.js.map +1 -0
  149. package/esm/helpers/utils.d.ts +7 -0
  150. package/esm/helpers/utils.js +45 -0
  151. package/esm/helpers/utils.js.map +1 -1
  152. package/esm/index.js +20 -16
  153. package/esm/index.js.map +1 -1
  154. package/esm/styles.css +1 -0
  155. package/package.json +2 -2
  156. package/src/components/Avatar/Avatar.test.tsx +28 -20
  157. package/src/components/Avatar/Avatar.tsx +19 -5
  158. package/src/components/Avatar/AvatarView/AvatarComponent/avatarComponent.tsx +222 -0
  159. package/src/components/Avatar/AvatarView/{components → AvatarComponent/components}/controls.tsx +16 -10
  160. package/src/components/Avatar/AvatarView/AvatarComponent/components/fullbodyAvatar.tsx +234 -0
  161. package/src/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.tsx +123 -0
  162. package/src/components/Avatar/AvatarView/{components → AvatarComponent/components}/loader.tsx +1 -1
  163. package/src/components/Avatar/AvatarView/AvatarView.stories.tsx +47 -8
  164. package/src/components/Avatar/AvatarView/index.tsx +35 -167
  165. package/src/components/Avatar/AvatarView/utils/useEyeBlink.ts +89 -48
  166. package/src/components/Avatar/AvatarView/utils/useMouthAnimation.ts +93 -0
  167. package/src/components/Avatar/AvatarView/utils/useSmile.ts +1 -1
  168. package/src/components/ChatBubble/ChatBubble.tsx +3 -4
  169. package/src/components/CompletionProviderStatus/CompletionProviderStatus.tsx +33 -3
  170. package/src/components/CompletionProviderStatus/__snapshots__/CompletionProviderStatus.test.tsx.snap +18 -0
  171. package/src/components/MemoriWidget/MemoriWidget.tsx +60 -5
  172. package/src/components/StartPanel/StartPanel.tsx +1 -1
  173. package/src/components/layouts/Chat.test.tsx +7 -5
  174. package/src/components/layouts/FullPage.test.tsx +11 -8
  175. package/src/components/layouts/HiddenChat.test.tsx +37 -0
  176. package/src/components/layouts/HiddenChat.tsx +107 -0
  177. package/src/components/layouts/Totem.test.tsx +6 -4
  178. package/src/components/layouts/WebsiteAssistant.test.tsx +7 -5
  179. package/src/components/layouts/ZoomedFullBody.test.tsx +37 -0
  180. package/src/components/layouts/ZoomedFullBody.tsx +55 -0
  181. package/src/components/layouts/__snapshots__/HiddenChat.test.tsx.snap +210 -0
  182. package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +444 -0
  183. package/src/components/layouts/hidden-chat.css +184 -0
  184. package/src/components/layouts/layouts.stories.tsx +135 -19
  185. package/src/context/visemeContext.tsx +328 -0
  186. package/src/helpers/utils.ts +73 -0
  187. package/src/index.stories.tsx +40 -17
  188. package/src/index.tsx +82 -78
  189. package/src/styles.css +1 -0
  190. package/dist/components/AttachmentMediaModal/AttachmentMediaModal.d.ts +0 -14
  191. package/dist/components/AttachmentMediaModal/AttachmentMediaModal.js +0 -66
  192. package/dist/components/AttachmentMediaModal/AttachmentMediaModal.js.map +0 -1
  193. package/dist/components/ImageUpload/ImageUpload.css +0 -168
  194. package/dist/components/ImageUpload/ImageUpload.d.ts +0 -28
  195. package/dist/components/ImageUpload/ImageUpload.js +0 -163
  196. package/dist/components/ImageUpload/ImageUpload.js.map +0 -1
  197. package/dist/components/layouts/Default.d.ts +0 -17
  198. package/dist/components/layouts/Default.js +0 -8
  199. package/dist/components/layouts/Default.js.map +0 -1
  200. package/dist/components/ui/Message.d.ts +0 -17
  201. package/dist/components/ui/Message.js +0 -13
  202. package/dist/components/ui/Message.js.map +0 -1
  203. package/esm/components/AttachmentMediaModal/AttachmentMediaModal.d.ts +0 -14
  204. package/esm/components/AttachmentMediaModal/AttachmentMediaModal.js +0 -63
  205. package/esm/components/AttachmentMediaModal/AttachmentMediaModal.js.map +0 -1
  206. package/esm/components/ImageUpload/ImageUpload.css +0 -168
  207. package/esm/components/ImageUpload/ImageUpload.d.ts +0 -28
  208. package/esm/components/ImageUpload/ImageUpload.js +0 -160
  209. package/esm/components/ImageUpload/ImageUpload.js.map +0 -1
  210. package/esm/components/layouts/Default.d.ts +0 -17
  211. package/esm/components/layouts/Default.js +0 -5
  212. package/esm/components/layouts/Default.js.map +0 -1
  213. package/esm/components/ui/Message.d.ts +0 -17
  214. package/esm/components/ui/Message.js +0 -10
  215. package/esm/components/ui/Message.js.map +0 -1
  216. package/src/components/Avatar/AvatarView/components/fullbodyAvatar.tsx +0 -120
  217. package/src/components/Avatar/AvatarView/components/halfbodyAvatar.tsx +0 -69
  218. package/src/components/Avatar/AvatarView/utils/useMouthSpeaking.ts +0 -87
@@ -0,0 +1,184 @@
1
+ .memori-sidebar-container {
2
+ position: fixed;
3
+ z-index: 1000;
4
+ top: 0;
5
+ right: 0;
6
+ height: 100%;
7
+ }
8
+
9
+ .memori-sidebar-toggle {
10
+ display: none;
11
+ }
12
+
13
+ .memori-sidebar-toggle-label {
14
+ position: absolute;
15
+ top: 50%;
16
+ right: 0;
17
+ display: flex;
18
+ width: auto;
19
+ height: 80px;
20
+ align-items: center;
21
+ justify-content: center;
22
+ padding: 10px 5px;
23
+ background-color: var(--memori-primary);
24
+ color: white;
25
+ cursor: pointer;
26
+ font-size: 18px;
27
+ font-weight: bold;
28
+ text-orientation: mixed;
29
+ transform: translateY(-50%);
30
+ transition: all 0.3s ease-in-out;
31
+ writing-mode: vertical-rl;
32
+ }
33
+
34
+ .memori-open-label {
35
+ border-radius: 5px 0 0 5px;
36
+ }
37
+
38
+ .memori-close-label {
39
+ right: 350px;
40
+ border-radius: 0 5px 5px 0;
41
+ opacity: 0;
42
+ pointer-events: none;
43
+ transform: rotate(180deg);
44
+ }
45
+
46
+ .memori-sidebar {
47
+ position: fixed;
48
+ z-index: 1000;
49
+ top: 0;
50
+ right: -350px;
51
+ width: 350px;
52
+ height: 100%;
53
+ background-color: white;
54
+ box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
55
+ transition: right 0.3s ease-in-out;
56
+ }
57
+
58
+ .memori-sidebar-content h2 {
59
+ margin-bottom: 20px;
60
+ color: var(--memori-primary);
61
+ font-size: 24px;
62
+ font-weight: bold;
63
+ }
64
+
65
+ .memori-sidebar-content ul {
66
+ padding: 0;
67
+ list-style-type: none;
68
+ }
69
+
70
+ .memori-sidebar-content li {
71
+ margin-bottom: 10px;
72
+ }
73
+
74
+ .memori-sidebar-content a {
75
+ display: flex;
76
+ align-items: center;
77
+ color: #4b5563;
78
+ text-decoration: none;
79
+ transition: color 0.2s ease-in-out;
80
+ }
81
+
82
+ .memori-sidebar-content a:hover {
83
+ color: var(--memori-primary);
84
+ }
85
+
86
+ .memori-sidebar-content svg {
87
+ width: 20px;
88
+ height: 20px;
89
+ margin-right: 10px;
90
+ }
91
+
92
+ .memori-sidebar-toggle:checked ~ .memori-sidebar-container .memori-sidebar {
93
+ right: 0;
94
+ }
95
+
96
+ .memori-sidebar-toggle:checked ~ .memori-sidebar-container .memori-open-label {
97
+ opacity: 0;
98
+ pointer-events: none;
99
+ transform: translateY(-50%) translateX(350px);
100
+ }
101
+
102
+ .memori-loading {
103
+ display: flex;
104
+ height: 100%;
105
+ align-items: center;
106
+ justify-content: center;
107
+ }
108
+
109
+
110
+ .memori-sidebar-content {
111
+ position: absolute;
112
+ top: -10px;
113
+ width: 100%;
114
+ padding: 20px;
115
+ }
116
+
117
+ .memori-sidebar-toggle:checked ~ .memori-sidebar-container .memori-close-label {
118
+ opacity: 1;
119
+ pointer-events: auto;
120
+ }
121
+
122
+ .memori-hidden-chat-layout--controls {
123
+ display: flex;
124
+ height: 90%;
125
+ padding: 10px;
126
+ margin-top: 50px;
127
+ }
128
+
129
+ .memori-hidden-chat-layout-header--layout {
130
+ display: flex;
131
+ width: 100%;
132
+ align-items: center;
133
+ justify-content: flex-end;
134
+ padding: 10px;
135
+ margin: 0;
136
+ background-color: white;
137
+ color: white;
138
+ }
139
+
140
+ .memori-hidden-chat-layout-header--layout > button, .memori-hidden-chat-layout-header--layout > div > button {
141
+ display: flex;
142
+ width: 38px;
143
+ height: 38px;
144
+ align-items: center;
145
+ justify-content: center;
146
+ border-radius: 50%;
147
+ aspect-ratio: 1;
148
+ background-color: var(--memori-primary);
149
+ cursor: pointer;
150
+ transition: background-color 0.3s ease-in-out;
151
+ }
152
+
153
+ .memori-button--icon > svg {
154
+ margin: 0;
155
+ }
156
+
157
+ .memori-icon,.memori-icon-close {
158
+ width: 25px;
159
+ height: 25px;
160
+ }
161
+
162
+ .memori-icon-close{
163
+ fill: white;
164
+ }
165
+
166
+
167
+ @media (max-width: 768px) {
168
+ .memori-sidebar-container {
169
+ display: none;
170
+ }
171
+
172
+ .memori-sidebar {
173
+ right: -100%;
174
+ width: 100%;
175
+ }
176
+
177
+ .memori-sidebar-toggle:checked ~ .memori-sidebar-container .memori-open-label {
178
+ transform: translateY(-50%) translateX(100%);
179
+ }
180
+
181
+ .memori-close-label {
182
+ right: 100%;
183
+ }
184
+ }
@@ -4,6 +4,7 @@ import { memori, tenant, integration } from '../../mocks/data';
4
4
  import Memori, { LayoutProps, Props } from '../MemoriWidget/MemoriWidget';
5
5
  import I18nWrapper from '../../I18nWrapper';
6
6
  import Spin from '../ui/Spin';
7
+ import { VisemeProvider } from '../../context/visemeContext';
7
8
 
8
9
  const meta: Meta = {
9
10
  title: 'General/Layouts',
@@ -62,7 +63,9 @@ export const CustomLayout: React.FC<LayoutProps> = ({
62
63
 
63
64
  const Template: Story<Props> = args => (
64
65
  <I18nWrapper>
65
- <Memori {...args} />
66
+ <VisemeProvider>
67
+ <Memori {...args} />
68
+ </VisemeProvider>
66
69
  </I18nWrapper>
67
70
  );
68
71
  // By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
@@ -197,8 +200,20 @@ ChatOnly.args = {
197
200
  layout: 'CHAT',
198
201
  };
199
202
 
200
- export const Totem = Template.bind({});
201
- Totem.args = {
203
+
204
+ export const Custom = Template.bind({});
205
+ Custom.args = {
206
+ uiLang: 'it',
207
+ showShare: true,
208
+ showSettings: true,
209
+ memori,
210
+ tenant,
211
+ layout: 'FULLPAGE',
212
+ customLayout: CustomLayout,
213
+ };
214
+
215
+ export const WebsiteAssistant = Template.bind({});
216
+ WebsiteAssistant.args = {
202
217
  uiLang: 'it',
203
218
  showShare: true,
204
219
  showSettings: true,
@@ -303,25 +318,16 @@ Totem.args = {
303
318
  }),
304
319
  },
305
320
  tenant,
306
- layout: 'TOTEM',
307
- };
308
-
309
- export const Custom = Template.bind({});
310
- Custom.args = {
311
- uiLang: 'it',
312
- showShare: true,
313
- showSettings: true,
314
- memori,
315
- tenant,
316
- layout: 'FULLPAGE',
317
- customLayout: CustomLayout,
321
+ layout: 'WEBSITE_ASSISTANT',
318
322
  };
319
323
 
320
- export const WebsiteAssistant = Template.bind({});
321
- WebsiteAssistant.args = {
324
+ export const HiddenChat = Template.bind({});
325
+ HiddenChat.args = {
322
326
  uiLang: 'it',
323
327
  showShare: true,
324
328
  showSettings: true,
329
+ // memori,
330
+ // tenant,
325
331
  memori: {
326
332
  memoriID: '6573844d-a7cd-47ef-9e78-840d82020c21',
327
333
  name: 'Nicola',
@@ -422,6 +428,116 @@ WebsiteAssistant.args = {
422
428
  new Date(Date.now()).getTime(),
423
429
  }),
424
430
  },
425
- tenant,
426
- layout: 'WEBSITE_ASSISTANT',
431
+ layout: 'HIDDEN_CHAT',
432
+ };
433
+
434
+
435
+ export const ZoomedFullBody = Template.bind({});
436
+ ZoomedFullBody.args = {
437
+ uiLang: 'it',
438
+ showShare: true,
439
+ showSettings: true,
440
+ showAudio: true,
441
+ enableAudio: true,
442
+ memori: {
443
+ memoriID: '6573844d-a7cd-47ef-9e78-840d82020c21',
444
+ name: 'Nicola',
445
+ password: null,
446
+ recoveryTokens: null,
447
+ newPassword: null,
448
+ ownerUserID: null,
449
+ ownerUserName: 'nzambello',
450
+ ownerTenantName: 'aisuru.com',
451
+ memoriConfigurationID: 'fd10bb42-98d9-4c08-8e02-2b08bd4e4975',
452
+ description:
453
+ 'Sono Nicola Zambello, sviluppatore e attivista per un web etico e sostenibile',
454
+ completionDescription: null,
455
+ engineMemoriID: '9b0a2913-d3d8-4e98-a49d-6e1c99479e1b',
456
+ isOwner: false,
457
+ isGiver: false,
458
+ isReceiver: false,
459
+ giverTag: null,
460
+ giverPIN: null,
461
+ privacyType: 'PUBLIC',
462
+ enableAudio: true,
463
+ secretToken: null,
464
+ minimumNumberOfRecoveryTokens: null,
465
+ totalNumberOfRecoveryTokens: null,
466
+ sentInvitations: [],
467
+ receivedInvitations: [],
468
+ integrations: [
469
+ {
470
+ integrationID: '62de8c99-0ac2-4cbe-bd95-a39ad7dc6b32',
471
+ memoriID: '6573844d-a7cd-47ef-9e78-840d82020c21',
472
+ type: 'LANDING_EXPERIENCE',
473
+ state: 'NEW',
474
+ deviceEmails: null,
475
+ invocationText: null,
476
+ jobID: null,
477
+ customData:
478
+ '{"textColor":"#000000","buttonBgColor":"#007eb6","buttonTextColor":"#ffffff","globalBackground":"https://assets.memori.ai/api/v2/asset/cade3b9c-0437-4342-b2bd-8db9c2a3a20e.png","blurBackground":true,"innerBgColor":"light","multilanguage":true,"avatar":"readyplayerme","avatarURL":"https://assets.memori.ai/api/v2/asset/893c41df-7619-436d-9e86-fe1d406fc933.glb#1681736752156","name":"Pagina pubblica","contextVars":"ANIMALE:CANE","personTag":"☠️","personPIN":"666666","personName":"Pirata","showShare":true,"avatarFullBodyURL":"https://models.readyplayer.me/63b55751f17e295642bf07a2.glb"}',
479
+ resources: [],
480
+ publish: true,
481
+ creationTimestamp: '2022-06-13T14:44:52.833573Z',
482
+ lastChangeTimestamp: '2022-06-13T14:44:52.833573Z',
483
+ },
484
+ ],
485
+ avatarURL:
486
+ 'https://assets.memori.ai/api/v2/asset/3049582f-db5f-452c-913d-e4340d4afd0a.png',
487
+ coverURL:
488
+ 'https://assets.memori.ai/api/v2/asset/e9bb9f6d-8f34-45ab-af9e-6d630d9a51a8.png',
489
+ avatar3DURL:
490
+ 'https://assets.memori.ai/api/v2/asset/3932bf70-e953-4e8a-b63a-f316544c283e.glb',
491
+ avatarOriginal3DURL:
492
+ 'https://assets.memori.ai/api/v2/asset/3932bf70-e953-4e8a-b63a-f316544c283e.glb',
493
+ needsPosition: false,
494
+ voiceType: 'FEMALE',
495
+ culture: 'it-IT',
496
+ categories: [
497
+ 'biografico',
498
+ 'tecnologia',
499
+ 'web',
500
+ 'open-source',
501
+ 'green',
502
+ 'privacy',
503
+ ],
504
+ exposed: true,
505
+ disableR2R3Loop: null,
506
+ disableR4Loop: null,
507
+ disableR5Loop: null,
508
+ enableCompletions: true,
509
+ completionModel: null,
510
+ chainingMemoriID: null,
511
+ chainingBaseURL: null,
512
+ chainingPassword: null,
513
+ contentQualityIndex: 210.8,
514
+ contentQualityIndexTimestamp: '2023-04-17T00:01:32.194744Z',
515
+ publishedInTheMetaverse: true,
516
+ metaverseEnvironment: 'apartment',
517
+ blockedUntil: null,
518
+ creationTimestamp: '2022-06-13T14:21:55.793034Z',
519
+ lastChangeTimestamp: '2023-04-15T08:15:36.403546Z',
520
+ },
521
+ integration: {
522
+ integrationID: '62de8c99-0ac2-4cbe-bd95-a39ad7dc6b32',
523
+ memoriID: '6573844d-a7cd-47ef-9e78-840d82020c21',
524
+ type: 'LANDING_EXPERIENCE',
525
+ state: 'NEW',
526
+ deviceEmails: null,
527
+ invocationText: null,
528
+ jobID: null,
529
+ publish: true,
530
+ creationTimestamp: '2022-06-13T14:44:52.833573Z',
531
+ lastChangeTimestamp: '2022-06-13T14:44:52.833573Z',
532
+ customData: JSON.stringify({
533
+ ...JSON.parse(
534
+ '{"textColor":"#000000","buttonBgColor":"#007eb6","buttonTextColor":"#ffffff","globalBackground":"https://assets.memori.ai/api/v2/asset/cade3b9c-0437-4342-b2bd-8db9c2a3a20e.png","blurBackground":true,"innerBgColor":"light","multilanguage":true,"avatar":"readyplayerme","avatarURL":"https://assets.memori.ai/api/v2/asset/893c41df-7619-436d-9e86-fe1d406fc933.glb#1681736752156","name":"Pagina pubblica","contextVars":"ANIMALE:CANE","personTag":"☠️","personPIN":"666666","personName":"Pirata","showShare":true,"avatarFullBodyURL":"https://models.readyplayer.me/63b55751f17e295642bf07a2.glb"}'
535
+ ),
536
+ avatar: 'readyplayerme-full',
537
+ avatarURL:
538
+ 'https://assets.memori.ai/api/v2/asset/3932bf70-e953-4e8a-b63a-f316544c283e.glb'+
539
+ new Date(Date.now()).getTime(),
540
+ }),
541
+ },
542
+ layout: 'ZOOMED_FULL_BODY',
427
543
  };
@@ -0,0 +1,328 @@
1
+ import React, {
2
+ createContext,
3
+ useContext,
4
+ useState,
5
+ useCallback,
6
+ useRef,
7
+ useEffect,
8
+ } from 'react';
9
+ import { SkinnedMesh } from 'three';
10
+
11
+ type AzureViseme = { visemeId: number; audioOffset: number };
12
+
13
+ type ProcessedViseme = {
14
+ name: string;
15
+ duration: number;
16
+ weight: number;
17
+ startTime: number;
18
+ };
19
+
20
+ interface VisemeContextType {
21
+ setMeshRef: (mesh: SkinnedMesh | null) => void;
22
+ addVisemeToQueue: (viseme: AzureViseme) => void;
23
+ processVisemeQueue: () => ProcessedViseme[];
24
+ clearVisemes: () => void;
25
+ isMeshSet: boolean;
26
+ setEmotion: (emotion: string) => void;
27
+ emotion: string;
28
+ getAzureStyleForEmotion: (emotion: string) => string;
29
+ }
30
+
31
+ const VisemeContext = createContext<VisemeContextType | undefined>(undefined);
32
+
33
+ const VISEME_SMOOTHING = 0.5;
34
+ const DEFAULT_VISEME_DURATION = 0.1;
35
+ const MINIMUM_ELAPSED_TIME = 0.01;
36
+ const VISEME_SPEED_FACTOR = 1.0;
37
+ const AUDIO_PLAYBACK_RATE = 1.0;
38
+ const VISEME_BASE_SPEED = 1.0;
39
+
40
+ const VISEME_MAP: { [key: number]: string } = {
41
+ 0: 'viseme_sil', // silence
42
+ 1: 'viseme_PP', // p, b, m
43
+ 2: 'viseme_FF', // f, v
44
+ 3: 'viseme_TH', // th, dh
45
+ 4: 'viseme_DD', // t, d, n, l
46
+ 5: 'viseme_kk', // k, g, ng
47
+ 6: 'viseme_CH', // tS, dZ, S, Z
48
+ 7: 'viseme_SS', // s, z
49
+ 8: 'viseme_nn', // Not explicitly defined in Azure mapping, keeping for compatibility
50
+ 9: 'viseme_RR', // r
51
+ 10: 'viseme_aa', // A:
52
+ 11: 'viseme_E', // e
53
+ 12: 'viseme_I', // I
54
+ 13: 'viseme_O', // O
55
+ 14: 'viseme_U', // u
56
+ // Mapping the rest based on closest matches or keeping them as in the original mapping
57
+ 15: 'viseme_kk', // g, k (same as 5)
58
+ 16: 'viseme_CH', // ch, j, sh, zh (same as 6)
59
+ 17: 'viseme_SS', // s, z (same as 7)
60
+ 18: 'viseme_TH', // th, dh (same as 3)
61
+ 19: 'viseme_RR', // r (same as 9)
62
+ 20: 'viseme_kk', // w (closest match, could be debated)
63
+ 21: 'viseme_PP', // y (closest match, could be debated)
64
+ };
65
+
66
+ export const VisemeProvider: React.FC<{ children: React.ReactNode }> = ({
67
+ children,
68
+ }) => {
69
+ const [isMeshSet, setIsMeshSet] = useState(false);
70
+ const [emotion, setEmotion] = useState('Neutral');
71
+ const isAnimatingRef = useRef(false);
72
+ const currentVisemesRef = useRef<ProcessedViseme[]>([]);
73
+ const visemeQueueRef = useRef<AzureViseme[]>([]);
74
+ const animationFrameRef = useRef<number | null>(null);
75
+ const startTimeRef = useRef<number | null>(null);
76
+ const currentVisemeWeightRef = useRef<{ [key: string]: number }>({});
77
+ const meshRef = useRef<SkinnedMesh | null>(null);
78
+
79
+ const lerp = (start: number, end: number, alpha: number): number => {
80
+ return start * (1 - alpha) + end * alpha;
81
+ };
82
+
83
+ const easeInOutCubic = (x: number): number => {
84
+ return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
85
+ };
86
+
87
+ const setMeshRef = useCallback(
88
+ (mesh: SkinnedMesh | null) => {
89
+ if (mesh && mesh.morphTargetDictionary && mesh.morphTargetInfluences) {
90
+ meshRef.current = mesh;
91
+ setIsMeshSet(true);
92
+ // console.log('Mesh set successfully:', mesh);
93
+ } else {
94
+ console.error('Invalid mesh provided:', mesh);
95
+ }
96
+ },
97
+ [meshRef]
98
+ );
99
+
100
+ const addVisemeToQueue = useCallback((viseme: AzureViseme) => {
101
+ visemeQueueRef.current.push(viseme);
102
+ // console.log('Viseme added to queue:', viseme);
103
+ }, []);
104
+
105
+ const getCurrentViseme = useCallback((elapsedTime: number) => {
106
+ if (elapsedTime < MINIMUM_ELAPSED_TIME) return null;
107
+
108
+ return currentVisemesRef.current.find((viseme, index) => {
109
+ const nextViseme = currentVisemesRef.current[index + 1];
110
+ return (
111
+ elapsedTime >= viseme.startTime &&
112
+ (!nextViseme || elapsedTime < nextViseme.startTime)
113
+ );
114
+ });
115
+ }, []);
116
+
117
+ const getDynamicSpeedFactor = (visemeDuration: number): number => {
118
+ const baseDuration = 0.1; // Average expected viseme duration
119
+ return (
120
+ VISEME_BASE_SPEED * (baseDuration / visemeDuration) * AUDIO_PLAYBACK_RATE
121
+ );
122
+ };
123
+
124
+ const applyViseme = useCallback(
125
+ (viseme: ProcessedViseme, elapsedTime: number) => {
126
+ if (!meshRef.current) {
127
+ console.error('Mesh not set');
128
+ return;
129
+ }
130
+
131
+ const visemeProgress = Math.min(
132
+ (elapsedTime - viseme.startTime) / viseme.duration,
133
+ 1
134
+ );
135
+
136
+ const dynamicSpeedFactor = getDynamicSpeedFactor(viseme.duration);
137
+ const adjustedProgress = visemeProgress * dynamicSpeedFactor;
138
+
139
+ // Use a cubic easing function for smoother transitions
140
+ const easedProgress = easeInOutCubic(adjustedProgress);
141
+ const targetWeight = Math.sin(easedProgress * Math.PI) * viseme.weight;
142
+
143
+ currentVisemeWeightRef.current[viseme.name] = lerp(
144
+ currentVisemeWeightRef.current[viseme.name] || 0,
145
+ targetWeight,
146
+ VISEME_SMOOTHING
147
+ );
148
+
149
+ const visemeIndex = meshRef.current.morphTargetDictionary?.[viseme.name];
150
+ if (
151
+ typeof visemeIndex === 'number' &&
152
+ meshRef.current.morphTargetInfluences
153
+ ) {
154
+ meshRef.current.morphTargetInfluences[visemeIndex] =
155
+ currentVisemeWeightRef.current[viseme.name];
156
+ // console.log(`Applied viseme: ${viseme.name}, weight: ${currentVisemeWeightRef.current[viseme.name]}`);
157
+ } else {
158
+ console.error(
159
+ `Viseme not found in morph target dictionary: ${viseme.name}`
160
+ );
161
+ }
162
+ },
163
+ []
164
+ );
165
+
166
+ const animate = useCallback(
167
+ (time: number) => {
168
+ if (startTimeRef.current === null) {
169
+ startTimeRef.current = time;
170
+ }
171
+
172
+ const elapsedTime =
173
+ ((time - startTimeRef.current) / 1000) * VISEME_SPEED_FACTOR;
174
+
175
+ const currentViseme = getCurrentViseme(elapsedTime);
176
+
177
+ if (currentViseme) {
178
+ applyViseme(currentViseme, elapsedTime);
179
+ }
180
+
181
+ if (
182
+ currentVisemesRef.current.length > 0 &&
183
+ elapsedTime <
184
+ currentVisemesRef.current[currentVisemesRef.current.length - 1]
185
+ .startTime +
186
+ currentVisemesRef.current[currentVisemesRef.current.length - 1]
187
+ .duration
188
+ ) {
189
+ animationFrameRef.current = requestAnimationFrame(animate);
190
+ } else {
191
+ clearVisemes();
192
+ }
193
+ },
194
+ [getCurrentViseme, applyViseme]
195
+ );
196
+
197
+ const processVisemeQueue = useCallback(() => {
198
+ const azureVisemes = [...visemeQueueRef.current];
199
+ visemeQueueRef.current = [];
200
+
201
+ if (azureVisemes.length === 0) {
202
+ // console.log('No visemes to process');
203
+ return [];
204
+ }
205
+
206
+ const processedVisemes: ProcessedViseme[] = azureVisemes.map(
207
+ (currentViseme, i) => {
208
+ const nextViseme = azureVisemes[i + 1];
209
+ const duration = nextViseme
210
+ ? (nextViseme.audioOffset - currentViseme.audioOffset) / 10000000
211
+ : DEFAULT_VISEME_DURATION;
212
+
213
+ const processedViseme = {
214
+ name: VISEME_MAP[currentViseme.visemeId] || 'viseme_sil',
215
+ duration,
216
+ weight: 1,
217
+ startTime: currentViseme.audioOffset / 10000000,
218
+ };
219
+ //console.log('Processed viseme:', processedViseme);
220
+ return processedViseme;
221
+ }
222
+ );
223
+
224
+ currentVisemesRef.current = processedVisemes;
225
+
226
+ // Start animation immediately if not already animating
227
+ if (!isAnimatingRef.current) {
228
+ isAnimatingRef.current = true;
229
+ startTimeRef.current = performance.now();
230
+ // console.log('Starting animation');
231
+ animationFrameRef.current = requestAnimationFrame(animate);
232
+ } else {
233
+ // If already animating, adjust the start time for the new visemes
234
+ if (startTimeRef.current !== null) {
235
+ const currentTime = performance.now();
236
+ const elapsedTime =
237
+ ((currentTime - startTimeRef.current) / 1000) * VISEME_SPEED_FACTOR;
238
+ startTimeRef.current =
239
+ currentTime - (elapsedTime / VISEME_SPEED_FACTOR) * 1000;
240
+ }
241
+ }
242
+
243
+ return processedVisemes;
244
+ }, [isMeshSet, animate]);
245
+
246
+ const clearVisemes = useCallback(() => {
247
+ currentVisemesRef.current = [];
248
+ visemeQueueRef.current = [];
249
+
250
+ if (animationFrameRef.current !== null) {
251
+ cancelAnimationFrame(animationFrameRef.current);
252
+ animationFrameRef.current = null;
253
+ }
254
+
255
+ if (
256
+ meshRef.current?.morphTargetDictionary &&
257
+ meshRef.current?.morphTargetInfluences
258
+ ) {
259
+ Object.values(meshRef.current.morphTargetDictionary).forEach(index => {
260
+ if (typeof index === 'number') {
261
+ meshRef.current!.morphTargetInfluences![index] = 0;
262
+ }
263
+ });
264
+ }
265
+
266
+ currentVisemeWeightRef.current = {};
267
+ startTimeRef.current = null;
268
+ isAnimatingRef.current = false;
269
+ // console.log('Visemes cleared');
270
+ }, []);
271
+
272
+ // Your existing emotion map
273
+ const emotionMap: Record<string, Record<string, number>> = {
274
+ Gioia: { Gioria: 1 },
275
+ Rabbia: { Rabbia: 1 },
276
+ Sorpresa: { Sorpresa: 1 },
277
+ Tristezza: { Tristezza: 1 },
278
+ Timore: { Timore: 1 },
279
+ };
280
+
281
+ // Mapping from your emotions to Azure styles
282
+ const emotionToAzureStyleMap: Record<string, string> = {
283
+ Gioia: 'cheerful',
284
+ Rabbia: 'angry',
285
+ Sorpresa: 'excited',
286
+ Tristezza: 'sad',
287
+ Timore: 'terrified',
288
+ };
289
+
290
+ // Function to get Azure style from emotion
291
+ function getAzureStyleForEmotion(emotion: string): string {
292
+ return emotionToAzureStyleMap[emotion] || 'neutral';
293
+ }
294
+
295
+
296
+ useEffect(() => {
297
+ return () => {
298
+ if (animationFrameRef.current !== null) {
299
+ cancelAnimationFrame(animationFrameRef.current);
300
+ }
301
+ };
302
+ }, []);
303
+
304
+ const contextValue: VisemeContextType = {
305
+ setMeshRef,
306
+ addVisemeToQueue,
307
+ processVisemeQueue,
308
+ clearVisemes,
309
+ isMeshSet,
310
+ setEmotion,
311
+ emotion,
312
+ getAzureStyleForEmotion,
313
+ };
314
+
315
+ return (
316
+ <VisemeContext.Provider value={contextValue}>
317
+ {children}
318
+ </VisemeContext.Provider>
319
+ );
320
+ };
321
+
322
+ export const useViseme = (): VisemeContextType => {
323
+ const context = useContext(VisemeContext);
324
+ if (context === undefined) {
325
+ throw new Error('useViseme must be used within a VisemeProvider');
326
+ }
327
+ return context;
328
+ };