talking-head-studio 0.2.5 → 0.2.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.
Files changed (111) hide show
  1. package/README.md +8 -7
  2. package/dist/TalkingHead.d.ts +0 -1
  3. package/dist/TalkingHead.js +31 -29
  4. package/dist/TalkingHead.web.d.ts +1 -3
  5. package/dist/TalkingHead.web.js +72 -43
  6. package/dist/appearance/apply.d.ts +0 -1
  7. package/dist/appearance/apply.js +8 -5
  8. package/dist/appearance/index.d.ts +0 -1
  9. package/dist/appearance/index.js +9 -3
  10. package/dist/appearance/matchers.d.ts +0 -1
  11. package/dist/appearance/matchers.js +4 -1
  12. package/dist/appearance/schema.d.ts +0 -1
  13. package/dist/appearance/schema.js +4 -1
  14. package/dist/editor/AvatarCanvas.d.ts +1 -2
  15. package/dist/editor/AvatarCanvas.js +44 -60
  16. package/dist/editor/AvatarCanvasErrorBoundary.d.ts +1 -2
  17. package/dist/editor/AvatarCanvasErrorBoundary.js +9 -14
  18. package/dist/editor/AvatarModel.d.ts +1 -2
  19. package/dist/editor/AvatarModel.js +17 -13
  20. package/dist/editor/RigidAccessory.d.ts +1 -2
  21. package/dist/editor/RigidAccessory.js +19 -17
  22. package/dist/editor/SkinnedClothing.d.ts +1 -2
  23. package/dist/editor/SkinnedClothing.js +46 -9
  24. package/dist/editor/index.d.ts +0 -1
  25. package/dist/editor/index.js +11 -4
  26. package/dist/editor/types.d.ts +0 -1
  27. package/dist/editor/types.js +2 -1
  28. package/dist/html.d.ts +0 -1
  29. package/dist/html.js +8 -5
  30. package/dist/index.d.ts +0 -1
  31. package/dist/index.js +20 -2
  32. package/dist/index.web.d.ts +0 -1
  33. package/dist/index.web.js +20 -2
  34. package/dist/sketchfab/api.d.ts +0 -1
  35. package/dist/sketchfab/api.js +10 -4
  36. package/dist/sketchfab/categories.d.ts +0 -1
  37. package/dist/sketchfab/categories.js +5 -2
  38. package/dist/sketchfab/index.d.ts +0 -1
  39. package/dist/sketchfab/index.js +13 -3
  40. package/dist/sketchfab/types.d.ts +0 -1
  41. package/dist/sketchfab/types.js +2 -1
  42. package/dist/sketchfab/useSketchfabSearch.d.ts +0 -1
  43. package/dist/sketchfab/useSketchfabSearch.js +20 -17
  44. package/dist/voice/convertToWav.d.ts +0 -1
  45. package/dist/voice/convertToWav.js +4 -1
  46. package/dist/voice/index.d.ts +0 -1
  47. package/dist/voice/index.js +9 -3
  48. package/dist/voice/useAudioPlayer.d.ts +0 -1
  49. package/dist/voice/useAudioPlayer.js +7 -4
  50. package/dist/voice/useAudioRecording.d.ts +0 -1
  51. package/dist/voice/useAudioRecording.js +20 -17
  52. package/package.json +10 -8
  53. package/dist/TalkingHead.d.ts.map +0 -1
  54. package/dist/TalkingHead.web.d.ts.map +0 -1
  55. package/dist/__tests__/TalkingHead.test.d.ts +0 -2
  56. package/dist/__tests__/TalkingHead.test.d.ts.map +0 -1
  57. package/dist/__tests__/TalkingHead.test.js +0 -23
  58. package/dist/__tests__/sketchfab.test.d.ts +0 -2
  59. package/dist/__tests__/sketchfab.test.d.ts.map +0 -1
  60. package/dist/__tests__/sketchfab.test.js +0 -21
  61. package/dist/appearance/apply.d.ts.map +0 -1
  62. package/dist/appearance/index.d.ts.map +0 -1
  63. package/dist/appearance/matchers.d.ts.map +0 -1
  64. package/dist/appearance/schema.d.ts.map +0 -1
  65. package/dist/editor/AvatarCanvas.d.ts.map +0 -1
  66. package/dist/editor/AvatarCanvasErrorBoundary.d.ts.map +0 -1
  67. package/dist/editor/AvatarModel.d.ts.map +0 -1
  68. package/dist/editor/RigidAccessory.d.ts.map +0 -1
  69. package/dist/editor/SkinnedClothing.d.ts.map +0 -1
  70. package/dist/editor/index.d.ts.map +0 -1
  71. package/dist/editor/types.d.ts.map +0 -1
  72. package/dist/html.d.ts.map +0 -1
  73. package/dist/index.d.ts.map +0 -1
  74. package/dist/index.web.d.ts.map +0 -1
  75. package/dist/sketchfab/api.d.ts.map +0 -1
  76. package/dist/sketchfab/categories.d.ts.map +0 -1
  77. package/dist/sketchfab/index.d.ts.map +0 -1
  78. package/dist/sketchfab/types.d.ts.map +0 -1
  79. package/dist/sketchfab/useSketchfabSearch.d.ts.map +0 -1
  80. package/dist/voice/convertToWav.d.ts.map +0 -1
  81. package/dist/voice/index.d.ts.map +0 -1
  82. package/dist/voice/useAudioPlayer.d.ts.map +0 -1
  83. package/dist/voice/useAudioRecording.d.ts.map +0 -1
  84. package/src/TalkingHead.tsx +0 -276
  85. package/src/TalkingHead.web.tsx +0 -220
  86. package/src/__tests__/TalkingHead.test.tsx +0 -32
  87. package/src/__tests__/sketchfab.test.ts +0 -24
  88. package/src/appearance/apply.ts +0 -94
  89. package/src/appearance/index.ts +0 -4
  90. package/src/appearance/matchers.ts +0 -43
  91. package/src/appearance/schema.ts +0 -35
  92. package/src/editor/AvatarCanvas.tsx +0 -167
  93. package/src/editor/AvatarCanvasErrorBoundary.tsx +0 -64
  94. package/src/editor/AvatarModel.tsx +0 -49
  95. package/src/editor/RigidAccessory.tsx +0 -130
  96. package/src/editor/SkinnedClothing.tsx +0 -114
  97. package/src/editor/index.ts +0 -5
  98. package/src/editor/r3f-shim.d.ts +0 -34
  99. package/src/editor/types.ts +0 -30
  100. package/src/html.ts +0 -678
  101. package/src/index.ts +0 -11
  102. package/src/index.web.ts +0 -8
  103. package/src/sketchfab/api.ts +0 -82
  104. package/src/sketchfab/categories.ts +0 -127
  105. package/src/sketchfab/index.ts +0 -6
  106. package/src/sketchfab/types.ts +0 -40
  107. package/src/sketchfab/useSketchfabSearch.ts +0 -110
  108. package/src/voice/convertToWav.ts +0 -87
  109. package/src/voice/index.ts +0 -7
  110. package/src/voice/useAudioPlayer.ts +0 -78
  111. package/src/voice/useAudioRecording.ts +0 -207
@@ -11,4 +11,3 @@ export interface UseAudioRecordingReturn {
11
11
  cancelRecording: () => void;
12
12
  }
13
13
  export declare function useAudioRecording({ maxDurationSeconds, onRecordingComplete, }?: UseAudioRecordingOptions): UseAudioRecordingReturn;
14
- //# sourceMappingURL=useAudioRecording.d.ts.map
@@ -1,16 +1,19 @@
1
- import { useCallback, useEffect, useRef, useState } from 'react';
2
- import { convertToWav } from './convertToWav';
3
- export function useAudioRecording({ maxDurationSeconds = 29, onRecordingComplete, } = {}) {
4
- const [isRecording, setIsRecording] = useState(false);
5
- const [duration, setDuration] = useState(0);
6
- const [error, setError] = useState(null);
7
- const mediaRecorderRef = useRef(null);
8
- const chunksRef = useRef([]);
9
- const streamRef = useRef(null);
10
- const timerRef = useRef(null);
11
- const startTimeRef = useRef(null);
12
- const cancelledRef = useRef(false);
13
- const startRecording = useCallback(async () => {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useAudioRecording = useAudioRecording;
4
+ const react_1 = require("react");
5
+ const convertToWav_1 = require("./convertToWav");
6
+ function useAudioRecording({ maxDurationSeconds = 29, onRecordingComplete, } = {}) {
7
+ const [isRecording, setIsRecording] = (0, react_1.useState)(false);
8
+ const [duration, setDuration] = (0, react_1.useState)(0);
9
+ const [error, setError] = (0, react_1.useState)(null);
10
+ const mediaRecorderRef = (0, react_1.useRef)(null);
11
+ const chunksRef = (0, react_1.useRef)([]);
12
+ const streamRef = (0, react_1.useRef)(null);
13
+ const timerRef = (0, react_1.useRef)(null);
14
+ const startTimeRef = (0, react_1.useRef)(null);
15
+ const cancelledRef = (0, react_1.useRef)(false);
16
+ const startRecording = (0, react_1.useCallback)(async () => {
14
17
  try {
15
18
  setError(null);
16
19
  chunksRef.current = [];
@@ -71,7 +74,7 @@ export function useAudioRecording({ maxDurationSeconds = 29, onRecordingComplete
71
74
  return;
72
75
  // Convert to WAV format to avoid needing ffmpeg on the backend.
73
76
  try {
74
- const wavBlob = await convertToWav(webmBlob);
77
+ const wavBlob = await (0, convertToWav_1.convertToWav)(webmBlob);
75
78
  onRecordingComplete?.(wavBlob, recordedDuration);
76
79
  }
77
80
  catch (err) {
@@ -113,7 +116,7 @@ export function useAudioRecording({ maxDurationSeconds = 29, onRecordingComplete
113
116
  setIsRecording(false);
114
117
  }
115
118
  }, [maxDurationSeconds, onRecordingComplete]);
116
- const stopRecording = useCallback(() => {
119
+ const stopRecording = (0, react_1.useCallback)(() => {
117
120
  if (mediaRecorderRef.current && isRecording) {
118
121
  mediaRecorderRef.current.stop();
119
122
  setIsRecording(false);
@@ -123,7 +126,7 @@ export function useAudioRecording({ maxDurationSeconds = 29, onRecordingComplete
123
126
  }
124
127
  }
125
128
  }, [isRecording]);
126
- const cancelRecording = useCallback(() => {
129
+ const cancelRecording = (0, react_1.useCallback)(() => {
127
130
  if (mediaRecorderRef.current) {
128
131
  cancelledRef.current = true; // Must be set before stop() triggers onstop.
129
132
  chunksRef.current = [];
@@ -141,7 +144,7 @@ export function useAudioRecording({ maxDurationSeconds = 29, onRecordingComplete
141
144
  }
142
145
  }, []);
143
146
  // Cleanup on unmount.
144
- useEffect(() => {
147
+ (0, react_1.useEffect)(() => {
145
148
  return () => {
146
149
  if (timerRef.current !== null) {
147
150
  clearInterval(timerRef.current);
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "talking-head-studio",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Cross-platform 3D avatar component for React Native & web — lip-sync, gestures, accessories, and LLM integration. Powered by TalkingHead + Three.js.",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
5
+ "main": "dist/index.web.js",
6
+ "browser": "dist/index.web.js",
7
+ "react-native": "dist/index.js",
8
+ "types": "dist/index.web.d.ts",
7
9
  "source": "src/index.ts",
8
10
  "exports": {
9
11
  ".": {
10
12
  "react-native": "./dist/index.js",
11
- "types": "./dist/index.d.ts",
13
+ "types": "./dist/index.web.d.ts",
12
14
  "default": "./dist/index.web.js"
13
15
  },
14
16
  "./editor": {
@@ -29,16 +31,16 @@
29
31
  }
30
32
  },
31
33
  "files": [
32
- "dist",
33
- "src"
34
+ "dist"
34
35
  ],
35
36
  "scripts": {
36
- "build": "tsc --project tsconfig.json",
37
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
38
+ "build": "npm run clean && tsc --project tsconfig.json",
37
39
  "typecheck": "tsc --noEmit",
38
40
  "lint": "eslint 'src/**/*.{ts,tsx}'",
39
41
  "format": "prettier --write 'src/**/*.{ts,tsx}'",
40
42
  "test": "jest",
41
- "prepublishOnly": "npm run build"
43
+ "prepublishOnly": "npm run lint && npm run typecheck && npm test -- --runInBand && npm run build"
42
44
  },
43
45
  "keywords": [
44
46
  "react-native",
@@ -1 +0,0 @@
1
- {"version":3,"file":"TalkingHead.d.ts","sourceRoot":"","sources":["../src/TalkingHead.tsx"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"TalkingHead.web.d.ts","sourceRoot":"","sources":["../src/TalkingHead.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,KAAK,SAAS,EAAoB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAEhF,OAAO,KAAK,EACV,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,CAAC;AAEhE,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,OAAO,GACP,KAAK,GACL,OAAO,GACP,SAAS,GACT,UAAU,GACV,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,eAAe,EAAE,CAAC,QAAQ,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC/D,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IACzC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,cAAc,EAAE,CAAC,WAAW,EAAE,oBAAoB,EAAE,KAAK,IAAI,CAAC;CAC/D;AAED,eAAO,MAAM,WAAW,yFAmJvB,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=TalkingHead.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TalkingHead.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/TalkingHead.test.tsx"],"names":[],"mappings":""}
@@ -1,23 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react-native';
3
- import { TalkingHead } from '../TalkingHead';
4
- // Mock react-native-webview
5
- jest.mock('react-native-webview', () => {
6
- // eslint-disable-next-line @typescript-eslint/no-require-imports
7
- const React = require('react');
8
- // eslint-disable-next-line @typescript-eslint/no-require-imports
9
- const { View } = require('react-native');
10
- const MockWebView = React.forwardRef((props, ref) => {
11
- React.useImperativeHandle(ref, () => ({
12
- postMessage: jest.fn(),
13
- }));
14
- return <View {...props}/>;
15
- });
16
- MockWebView.displayName = 'MockWebView';
17
- return { WebView: MockWebView };
18
- });
19
- describe('TalkingHead', () => {
20
- it('renders without crashing', () => {
21
- render(<TalkingHead avatarUrl="https://example.com/avatar.glb" style={{ flex: 1 }}/>);
22
- });
23
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=sketchfab.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sketchfab.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sketchfab.test.ts"],"names":[],"mappings":""}
@@ -1,21 +0,0 @@
1
- import { ACCESSORY_CATEGORIES } from '../sketchfab';
2
- describe('ACCESSORY_CATEGORIES', () => {
3
- it('includes the full accessory category set used by the app browsers', () => {
4
- expect(ACCESSORY_CATEGORIES.map((category) => category.id)).toEqual(expect.arrayContaining([
5
- 'hair',
6
- 'hat',
7
- 'glasses',
8
- 'necklace',
9
- 'handheld',
10
- 'glove',
11
- 'wings',
12
- 'tail',
13
- 'cape',
14
- 'belt',
15
- 'shoulder_pad',
16
- 'top',
17
- 'bottom',
18
- 'footwear',
19
- ]));
20
- });
21
- });
@@ -1 +0,0 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/appearance/apply.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAuB,MAAM,UAAU,CAAC;AAmBtE,KAAK,YAAY,GAAG;IAClB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;CACzD,CAAC;AAcF,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,gBAAgB,GAC3B,IAAI,CAsDN"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/appearance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,KAAK,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/appearance/matchers.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC;AAwBtE,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAkB/E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/appearance/schema.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAElC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAgBD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,CAW7E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AvatarCanvas.d.ts","sourceRoot":"","sources":["../../src/editor/AvatarCanvas.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKtD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAW7D,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAEzE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,UAAU,EACV,QAAa,EACb,UAAe,EACf,cAAqB,EACrB,iBAAiB,EACjB,UAAU,EACV,KAAK,EACL,SAAS,GACV,EAAE,iBAAiB,+BA0HnB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AvatarCanvasErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/editor/AvatarCanvasErrorBoundary.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAElE,UAAU,8BAA8B;IACtC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,8BAA8B;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,yBAA0B,SAAQ,SAAS,CACtD,8BAA8B,EAC9B,8BAA8B,CAC/B;IACC,KAAK,EAAE,8BAA8B,CAGnC;IAEF,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAI3D,MAAM,CAAC,wBAAwB,IAAI,8BAA8B;IAOjE,OAAO,CAAC,WAAW,CAKjB;IAEF,MAAM;CAyBP"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AvatarModel.d.ts","sourceRoot":"","sources":["../../src/editor/AvatarModel.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAQ,OAAO,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5E;AAED,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,UAAU,EACV,KAAS,EACT,eAAe,EACf,aAAa,GACd,EAAE,gBAAgB,+BA0BlB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"RigidAccessory.d.ts","sourceRoot":"","sources":["../../src/editor/RigidAccessory.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IAEZ,WAAW,EAAE,GAAG,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CAC1E;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,GAAG,EACH,WAAW,EACX,UAAU,EACV,cAAc,EACd,cAAc,EACd,KAAS,EACT,SAAiB,EACjB,iBAAiB,GAClB,EAAE,mBAAmB,sCAoGrB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"SkinnedClothing.d.ts","sourceRoot":"","sources":["../../src/editor/SkinnedClothing.tsx"],"names":[],"mappings":"AAMA,UAAU,oBAAoB;IAC5B,GAAG,EAAE,MAAM,CAAC;IAEZ,cAAc,EAAE,GAAG,CAAC;CACrB;AAwED,wBAAgB,eAAe,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,oBAAoB,+BA+B5E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/editor/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,CAAC;IACjG,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAIF,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAupB5D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,cAAc,cAAc,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../src/index.web.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,cAAc,cAAc,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/sketchfab/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAKjE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwBjG;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxF;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe5F;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,CAAC,YAAY,CAAC,EACxC,WAAW,SAAM,GAChB,MAAM,CAUR"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/sketchfab/categories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,eAAO,MAAM,oBAAoB,EAAE,iBAAiB,EA6GnD,CAAC;AAEF,0FAA0F;AAC1F,eAAO,MAAM,aAAa,mHAYhB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sketchfab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AACzF,YAAY,EAAE,sBAAsB,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACnE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sketchfab/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE;QAAE,MAAM,EAAE,uBAAuB,EAAE,CAAA;KAAE,CAAC;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAC5D;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useSketchfabSearch.d.ts","sourceRoot":"","sources":["../../src/sketchfab/useSketchfabSearch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,YAA0C,EAC1C,UAAgB,GACjB,EAAE,yBAAyB,GAAG,wBAAwB,CAmFtD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"convertToWav.d.ts","sourceRoot":"","sources":["../../src/voice/convertToWav.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAajE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/voice/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE7F,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEpF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useAudioPlayer.d.ts","sourceRoot":"","sources":["../../src/voice/useAudioPlayer.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,GACR,GAAE,qBAA0B,GAAG,oBAAoB,CA8DnD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useAudioRecording.d.ts","sourceRoot":"","sources":["../../src/voice/useAudioRecording.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,kBAAuB,EACvB,mBAAmB,GACpB,GAAE,wBAA6B,GAAG,uBAAuB,CA0LzD"}
@@ -1,276 +0,0 @@
1
- import React, {
2
- forwardRef,
3
- useCallback,
4
- useEffect,
5
- useImperativeHandle,
6
- useMemo,
7
- useRef,
8
- useState,
9
- } from 'react';
10
- import { type StyleProp, StyleSheet, View, type ViewStyle } from 'react-native';
11
- import { WebView, type WebViewMessageEvent } from 'react-native-webview';
12
- import { buildAvatarHtml } from './html';
13
-
14
- export type TalkingHeadMood =
15
- | 'neutral'
16
- | 'happy'
17
- | 'sad'
18
- | 'angry'
19
- | 'excited'
20
- | 'thinking'
21
- | 'concerned'
22
- | 'surprised';
23
-
24
- /**
25
- * Standard viseme keys supported by the avatar.
26
- * Use with sendViseme() from your TTS viseme callbacks.
27
- */
28
- export type TalkingHeadViseme =
29
- | 'sil' | 'PP' | 'FF' | 'TH' | 'DD' | 'kk' | 'CH' | 'SS' | 'nn' | 'RR'
30
- | 'aa' | 'ee' | 'ih' | 'oh' | 'ou';
31
-
32
- /** Rhubarb mouth shape cue (Preston Blair set: A-H, X) */
33
- export interface TalkingHeadVisemeCue {
34
- startMs: number;
35
- endMs: number;
36
- viseme: 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'X';
37
- }
38
-
39
- /**
40
- * A full viseme schedule from the Rhubarb sidecar endpoint.
41
- * Pass to scheduleVisemes() when agent_visemes arrives on the data channel.
42
- */
43
- export interface TalkingHeadVisemeSchedule {
44
- /** Matches X-TTS-Request-Id / agent_visemes.requestId */
45
- requestId?: string;
46
- /**
47
- * Wall-clock ms at which audio playback started.
48
- * Anchor this to the moment you observe agent_state: speaking.
49
- * Used to skip cues that are already in the past on late delivery.
50
- */
51
- startedAtMs?: number;
52
- durationMs?: number;
53
- cues: TalkingHeadVisemeCue[];
54
- }
55
-
56
- export interface TalkingHeadAccessory {
57
- id: string;
58
- url: string;
59
- bone: string;
60
- position: [number, number, number];
61
- rotation: [number, number, number];
62
- scale: number;
63
- }
64
-
65
- export interface TalkingHeadProps {
66
- avatarUrl: string;
67
- authToken?: string | null;
68
- mood?: TalkingHeadMood;
69
- cameraView?: 'head' | 'upper' | 'full';
70
- cameraDistance?: number;
71
- hairColor?: string;
72
- skinColor?: string;
73
- eyeColor?: string;
74
- accessories?: TalkingHeadAccessory[];
75
- onReady?: () => void;
76
- onError?: (message: string) => void;
77
- style?: StyleProp<ViewStyle>;
78
- }
79
-
80
- export interface TalkingHeadRef {
81
- sendAmplitude: (amplitude: number) => void;
82
- /**
83
- * Drive a viseme morph target from your TTS pipeline.
84
- * Works on iOS/Android WebViews where AudioWorklet is unavailable.
85
- *
86
- * @example
87
- * // ElevenLabs websocket:
88
- * ws.on('viseme', ({ visemeId }) => avatarRef.current?.sendViseme(ELEVENLABS_MAP[visemeId], 1.0));
89
- * // Azure TTS:
90
- * synthesizer.visemeReceived = (s, e) => avatarRef.current?.sendViseme(AZURE_MAP[e.visemeId], 1.0);
91
- */
92
- sendViseme: (viseme: TalkingHeadViseme, weight?: number) => void;
93
- /**
94
- * Schedule a full Rhubarb viseme payload for playback.
95
- * Call this when agent_visemes arrives on the LiveKit data channel.
96
- * The scheduler gates amplitude fallback while visemes are active.
97
- *
98
- * @example
99
- * room.on(RoomEvent.DataReceived, (payload) => {
100
- * const msg = JSON.parse(new TextDecoder().decode(payload));
101
- * if (msg.type === 'agent_visemes') {
102
- * avatarRef.current?.scheduleVisemes({ ...msg, startedAtMs: speakingStartedAt });
103
- * }
104
- * });
105
- */
106
- scheduleVisemes: (schedule: TalkingHeadVisemeSchedule) => void;
107
- /** Cancel any running viseme schedule and return to amplitude fallback. */
108
- clearVisemes: () => void;
109
- setMood: (mood: TalkingHeadMood) => void;
110
- setHairColor: (color: string) => void;
111
- setSkinColor: (color: string) => void;
112
- setEyeColor: (color: string) => void;
113
- setAccessories: (accessories: TalkingHeadAccessory[]) => void;
114
- }
115
-
116
- export const TalkingHead = forwardRef<TalkingHeadRef, TalkingHeadProps>(
117
- (
118
- {
119
- avatarUrl,
120
- authToken,
121
- mood = 'neutral',
122
- cameraView = 'upper',
123
- cameraDistance = -0.5,
124
- hairColor,
125
- skinColor,
126
- eyeColor,
127
- accessories,
128
- onReady,
129
- onError,
130
- style,
131
- },
132
- ref,
133
- ) => {
134
- const webViewRef = useRef<WebView>(null);
135
- const readyRef = useRef(false);
136
- const accessoriesRef = useRef(accessories);
137
-
138
- // The WebView HTML is built once from stable initial values.
139
- // avatarUrl + authToken changing causes a controlled key-based remount.
140
- // All other prop changes (mood, colors, accessories) go via postMessage.
141
- const [webViewKey, setWebViewKey] = useState(() => `${avatarUrl}__${authToken ?? ''}`);
142
- const prevAvatarRef = useRef({ avatarUrl, authToken });
143
-
144
- useEffect(() => {
145
- const prev = prevAvatarRef.current;
146
- if (prev.avatarUrl !== avatarUrl || prev.authToken !== authToken) {
147
- prevAvatarRef.current = { avatarUrl, authToken };
148
- readyRef.current = false;
149
- setWebViewKey(`${avatarUrl}__${authToken ?? ''}`);
150
- }
151
- }, [avatarUrl, authToken]);
152
-
153
- const post = useCallback((msg: object) => {
154
- webViewRef.current?.postMessage(JSON.stringify(msg));
155
- }, []);
156
-
157
- useImperativeHandle(
158
- ref,
159
- () => ({
160
- sendAmplitude: (amplitude) => post({ type: 'amplitude', value: amplitude }),
161
- sendViseme: (viseme, weight = 1.0) => post({ type: 'viseme', viseme, weight }),
162
- scheduleVisemes: (schedule) => post({ type: 'schedule_visemes', schedule }),
163
- clearVisemes: () => post({ type: 'clear_visemes' }),
164
- setMood: (nextMood) => post({ type: 'mood', value: nextMood }),
165
- setHairColor: (color) => post({ type: 'hair_color', value: color }),
166
- setSkinColor: (color) => post({ type: 'skin_color', value: color }),
167
- setEyeColor: (color) => post({ type: 'eye_color', value: color }),
168
- setAccessories: (newAccessories) =>
169
- post({ type: 'set_accessories', accessories: newAccessories }),
170
- }),
171
- [post],
172
- );
173
-
174
- // Sync mood via postMessage only — never causes a WebView reload
175
- useEffect(() => {
176
- if (readyRef.current) post({ type: 'mood', value: mood });
177
- }, [mood, post]);
178
-
179
- useEffect(() => {
180
- accessoriesRef.current = accessories;
181
- if (accessories && readyRef.current) {
182
- post({ type: 'set_accessories', accessories });
183
- }
184
- }, [accessories, post]);
185
-
186
- useEffect(() => {
187
- if (hairColor && readyRef.current) post({ type: 'hair_color', value: hairColor });
188
- }, [hairColor, post]);
189
-
190
- useEffect(() => {
191
- if (skinColor && readyRef.current) post({ type: 'skin_color', value: skinColor });
192
- }, [skinColor, post]);
193
-
194
- useEffect(() => {
195
- if (eyeColor && readyRef.current) post({ type: 'eye_color', value: eyeColor });
196
- }, [eyeColor, post]);
197
-
198
- // Capture stable initial values at first mount only
199
- const [initialMood] = useState(mood);
200
- const [initialHairColor] = useState(hairColor);
201
- const [initialSkinColor] = useState(skinColor);
202
- const [initialEyeColor] = useState(eyeColor);
203
-
204
- // html is stable — only rebuilds when webViewKey changes (avatarUrl/authToken)
205
- const html = useMemo(
206
- () =>
207
- buildAvatarHtml({
208
- avatarUrl,
209
- authToken,
210
- mood: initialMood,
211
- cameraView,
212
- cameraDistance,
213
- initialHairColor,
214
- initialSkinColor,
215
- initialEyeColor,
216
- }),
217
- // eslint-disable-next-line react-hooks/exhaustive-deps
218
- [webViewKey], // intentionally keyed only on webViewKey, not every prop
219
- );
220
-
221
- const onMessage = useCallback(
222
- (event: WebViewMessageEvent) => {
223
- try {
224
- const msg = JSON.parse(event.nativeEvent.data);
225
- if (msg.type === 'ready') {
226
- readyRef.current = true;
227
- // Flush pending props that may have arrived before WebView was ready
228
- if (accessoriesRef.current?.length) {
229
- post({ type: 'set_accessories', accessories: accessoriesRef.current });
230
- }
231
- onReady?.();
232
- } else if (msg.type === 'error') {
233
- onError?.(msg.message);
234
- } else if (msg.type === 'log') {
235
- console.log('[TalkingHead]', msg.message);
236
- }
237
- } catch (err) {
238
- console.warn('[TalkingHead] Invalid message from WebView:', err);
239
- }
240
- },
241
- [onReady, onError, post],
242
- );
243
-
244
- return (
245
- <View style={[styles.container, style]}>
246
- <WebView
247
- key={webViewKey}
248
- ref={webViewRef}
249
- source={{ html }}
250
- style={styles.webview}
251
- javaScriptEnabled
252
- domStorageEnabled
253
- allowsInlineMediaPlayback
254
- mediaPlaybackRequiresUserAction={false}
255
- onMessage={onMessage}
256
- originWhitelist={['*']}
257
- mixedContentMode="always"
258
- />
259
- </View>
260
- );
261
- },
262
- );
263
-
264
- TalkingHead.displayName = 'TalkingHead';
265
-
266
- const styles = StyleSheet.create({
267
- container: {
268
- overflow: 'hidden',
269
- borderRadius: 12,
270
- backgroundColor: 'transparent',
271
- },
272
- webview: {
273
- flex: 1,
274
- backgroundColor: 'transparent',
275
- },
276
- });