@sage-rsc/talking-head-react 1.0.51 → 1.0.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sage-rsc/talking-head-react",
3
- "version": "1.0.51",
3
+ "version": "1.0.52",
4
4
  "description": "A reusable React component for 3D talking avatars with lip-sync and text-to-speech",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -299,8 +299,10 @@ const CurriculumLearning = forwardRef(({
299
299
  });
300
300
  }
301
301
 
302
- // Ensure avatar is ready before speaking
303
- if (avatarRef.current && avatarRef.current.isReady && firstQuestion) {
302
+ // Function to speak the first question
303
+ const speakFirstQuestion = () => {
304
+ if (!avatarRef.current || !firstQuestion) return;
305
+
304
306
  avatarRef.current.setMood("curious");
305
307
 
306
308
  // Play custom animation if available
@@ -324,16 +326,30 @@ const CurriculumLearning = forwardRef(({
324
326
  } else {
325
327
  avatarRef.current.speakText(`Now let me ask you some questions. Here's the first one: ${firstQuestion.question}`, { lipsyncLang: config.lipsyncLang });
326
328
  }
329
+ };
330
+
331
+ // Try to speak immediately if avatar is ready
332
+ if (avatarRef.current && avatarRef.current.isReady && firstQuestion) {
333
+ speakFirstQuestion();
327
334
  } else if (avatarRef.current && avatarRef.current.isReady) {
335
+ // No question but avatar ready - just announce
328
336
  const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
329
337
  avatarRef.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: config.lipsyncLang });
330
338
  } else {
331
- // Avatar not ready yet, retry after a short delay
332
- setTimeout(() => {
333
- if (startQuestionsRef.current) {
334
- startQuestionsRef.current();
339
+ // Avatar not ready yet - wait for it to be ready, then speak
340
+ const checkReady = setInterval(() => {
341
+ if (avatarRef.current && avatarRef.current.isReady) {
342
+ clearInterval(checkReady);
343
+ if (firstQuestion) {
344
+ speakFirstQuestion();
345
+ }
335
346
  }
336
347
  }, 100);
348
+
349
+ // Timeout after 5 seconds
350
+ setTimeout(() => {
351
+ clearInterval(checkReady);
352
+ }, 5000);
337
353
  }
338
354
  }, [animations.questionStart, getCurrentLesson, getCurrentQuestion]);
339
355
 
@@ -357,15 +373,18 @@ const CurriculumLearning = forwardRef(({
357
373
  });
358
374
  }
359
375
 
360
- if (avatarRef.current && nextQuestionObj) {
376
+ // Function to speak the next question
377
+ const speakNextQuestion = () => {
378
+ if (!avatarRef.current || !nextQuestionObj) return;
379
+
361
380
  avatarRef.current.setMood("happy");
362
381
  avatarRef.current.setBodyMovement("idle");
363
-
382
+
364
383
  // Play custom animation if available
365
384
  if (animations.nextQuestion) {
366
385
  try {
367
386
  avatarRef.current.playAnimation(animations.nextQuestion, true);
368
- } catch (error) {
387
+ } catch (error) {
369
388
  console.warn('Failed to play nextQuestion animation:', error);
370
389
  }
371
390
  }
@@ -390,6 +409,24 @@ const CurriculumLearning = forwardRef(({
390
409
  lipsyncLang: config.lipsyncLang
391
410
  });
392
411
  }
412
+ };
413
+
414
+ // Try to speak immediately if avatar is ready
415
+ if (avatarRef.current && avatarRef.current.isReady && nextQuestionObj) {
416
+ speakNextQuestion();
417
+ } else if (nextQuestionObj) {
418
+ // Avatar not ready yet - wait for it to be ready, then speak
419
+ const checkReady = setInterval(() => {
420
+ if (avatarRef.current && avatarRef.current.isReady) {
421
+ clearInterval(checkReady);
422
+ speakNextQuestion();
423
+ }
424
+ }, 100);
425
+
426
+ // Timeout after 5 seconds
427
+ setTimeout(() => {
428
+ clearInterval(checkReady);
429
+ }, 5000);
393
430
  }
394
431
  } else {
395
432
  // No more questions - notify parent that all questions are done