@sage-rsc/talking-head-react 1.0.52 → 1.0.54
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/dist/index.cjs +2 -2
- package/dist/index.js +1062 -992
- package/package.json +1 -1
- package/src/components/CurriculumLearning.jsx +152 -6
package/package.json
CHANGED
|
@@ -303,7 +303,7 @@ const CurriculumLearning = forwardRef(({
|
|
|
303
303
|
const speakFirstQuestion = () => {
|
|
304
304
|
if (!avatarRef.current || !firstQuestion) return;
|
|
305
305
|
|
|
306
|
-
avatarRef.current.setMood("
|
|
306
|
+
avatarRef.current.setMood("happy");
|
|
307
307
|
|
|
308
308
|
// Play custom animation if available
|
|
309
309
|
if (animations.questionStart) {
|
|
@@ -404,7 +404,7 @@ const CurriculumLearning = forwardRef(({
|
|
|
404
404
|
avatarRef.current.speakText(`Now let's try this one: ${nextQuestionObj.question}`, {
|
|
405
405
|
lipsyncLang: config.lipsyncLang
|
|
406
406
|
});
|
|
407
|
-
|
|
407
|
+
} else {
|
|
408
408
|
avatarRef.current.speakText(`Here's the next question: ${nextQuestionObj.question}`, {
|
|
409
409
|
lipsyncLang: config.lipsyncLang
|
|
410
410
|
});
|
|
@@ -459,11 +459,18 @@ const CurriculumLearning = forwardRef(({
|
|
|
459
459
|
stateRef.current.score = 0;
|
|
460
460
|
stateRef.current.totalQuestions = 0;
|
|
461
461
|
|
|
462
|
+
// Check if there's a next lesson available after this one
|
|
463
|
+
const currentModuleAfterMove = curriculum.modules[stateRef.current.currentModuleIndex];
|
|
464
|
+
const hasNextLessonInModuleAfterMove = stateRef.current.currentLessonIndex < (currentModuleAfterMove?.lessons?.length || 0) - 1;
|
|
465
|
+
const hasNextModuleAfterMove = stateRef.current.currentModuleIndex < (curriculum.modules?.length || 0) - 1;
|
|
466
|
+
const hasNextLessonAfterMove = hasNextLessonInModuleAfterMove || hasNextModuleAfterMove;
|
|
467
|
+
|
|
462
468
|
// Clear current question in UI and notify parent
|
|
463
469
|
callbacksRef.current.onCustomAction({
|
|
464
470
|
type: 'lessonStart',
|
|
465
471
|
moduleIndex: stateRef.current.currentModuleIndex,
|
|
466
|
-
lessonIndex: stateRef.current.currentLessonIndex
|
|
472
|
+
lessonIndex: stateRef.current.currentLessonIndex,
|
|
473
|
+
hasNextLesson: hasNextLessonAfterMove
|
|
467
474
|
});
|
|
468
475
|
|
|
469
476
|
// Notify parent that lesson has changed - parent decides when to start teaching
|
|
@@ -475,7 +482,7 @@ const CurriculumLearning = forwardRef(({
|
|
|
475
482
|
|
|
476
483
|
if (avatarRef.current) {
|
|
477
484
|
avatarRef.current.setMood("happy");
|
|
478
|
-
|
|
485
|
+
avatarRef.current.setBodyMovement("idle");
|
|
479
486
|
}
|
|
480
487
|
} else {
|
|
481
488
|
// No more lessons in current module - check if there's a next module
|
|
@@ -492,11 +499,18 @@ const CurriculumLearning = forwardRef(({
|
|
|
492
499
|
stateRef.current.score = 0;
|
|
493
500
|
stateRef.current.totalQuestions = 0;
|
|
494
501
|
|
|
502
|
+
// Check if there's a next lesson available after this one
|
|
503
|
+
const currentModuleAfterMove = curriculum.modules[stateRef.current.currentModuleIndex];
|
|
504
|
+
const hasNextLessonInModuleAfterMove = stateRef.current.currentLessonIndex < (currentModuleAfterMove?.lessons?.length || 0) - 1;
|
|
505
|
+
const hasNextModuleAfterMove = stateRef.current.currentModuleIndex < (curriculum.modules?.length || 0) - 1;
|
|
506
|
+
const hasNextLessonAfterMove = hasNextLessonInModuleAfterMove || hasNextModuleAfterMove;
|
|
507
|
+
|
|
495
508
|
// Clear current question in UI and notify parent
|
|
496
509
|
callbacksRef.current.onCustomAction({
|
|
497
510
|
type: 'lessonStart',
|
|
498
511
|
moduleIndex: stateRef.current.currentModuleIndex,
|
|
499
|
-
lessonIndex: stateRef.current.currentLessonIndex
|
|
512
|
+
lessonIndex: stateRef.current.currentLessonIndex,
|
|
513
|
+
hasNextLesson: hasNextLessonAfterMove
|
|
500
514
|
});
|
|
501
515
|
|
|
502
516
|
// Notify parent that lesson has changed - parent decides when to start teaching
|
|
@@ -647,7 +661,7 @@ const CurriculumLearning = forwardRef(({
|
|
|
647
661
|
if (animations.incorrect) {
|
|
648
662
|
try {
|
|
649
663
|
avatarRef.current.playAnimation(animations.incorrect, true);
|
|
650
|
-
|
|
664
|
+
} catch (error) {
|
|
651
665
|
avatarRef.current.setBodyMovement("idle");
|
|
652
666
|
}
|
|
653
667
|
}
|
|
@@ -732,6 +746,136 @@ const CurriculumLearning = forwardRef(({
|
|
|
732
746
|
}
|
|
733
747
|
}, [getCurrentQuestion, checkAnswer]);
|
|
734
748
|
|
|
749
|
+
// Move to previous question
|
|
750
|
+
const previousQuestion = useCallback(() => {
|
|
751
|
+
if (stateRef.current.currentQuestionIndex > 0) {
|
|
752
|
+
stateRef.current.currentQuestionIndex -= 1;
|
|
753
|
+
|
|
754
|
+
// Trigger custom action for UI update
|
|
755
|
+
const prevQuestionObj = getCurrentQuestion();
|
|
756
|
+
if (prevQuestionObj) {
|
|
757
|
+
callbacksRef.current.onCustomAction({
|
|
758
|
+
type: 'questionStart',
|
|
759
|
+
moduleIndex: stateRef.current.currentModuleIndex,
|
|
760
|
+
lessonIndex: stateRef.current.currentLessonIndex,
|
|
761
|
+
questionIndex: stateRef.current.currentQuestionIndex,
|
|
762
|
+
totalQuestions: stateRef.current.totalQuestions,
|
|
763
|
+
question: prevQuestionObj
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Function to speak the previous question
|
|
768
|
+
const speakPrevQuestion = () => {
|
|
769
|
+
if (!avatarRef.current || !prevQuestionObj) return;
|
|
770
|
+
|
|
771
|
+
avatarRef.current.setMood("happy");
|
|
772
|
+
avatarRef.current.setBodyMovement("idle");
|
|
773
|
+
|
|
774
|
+
const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
|
|
775
|
+
|
|
776
|
+
// Speak the question text
|
|
777
|
+
if (prevQuestionObj.type === 'code_test') {
|
|
778
|
+
avatarRef.current.speakText(`Let's go back to this coding challenge: ${prevQuestionObj.question}`, {
|
|
779
|
+
lipsyncLang: config.lipsyncLang
|
|
780
|
+
});
|
|
781
|
+
} else {
|
|
782
|
+
avatarRef.current.speakText(`Going back to: ${prevQuestionObj.question}`, {
|
|
783
|
+
lipsyncLang: config.lipsyncLang
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
// Try to speak immediately if avatar is ready
|
|
789
|
+
if (avatarRef.current && avatarRef.current.isReady && prevQuestionObj) {
|
|
790
|
+
speakPrevQuestion();
|
|
791
|
+
} else if (prevQuestionObj) {
|
|
792
|
+
// Avatar not ready yet - wait for it to be ready, then speak
|
|
793
|
+
const checkReady = setInterval(() => {
|
|
794
|
+
if (avatarRef.current && avatarRef.current.isReady) {
|
|
795
|
+
clearInterval(checkReady);
|
|
796
|
+
speakPrevQuestion();
|
|
797
|
+
}
|
|
798
|
+
}, 100);
|
|
799
|
+
|
|
800
|
+
setTimeout(() => {
|
|
801
|
+
clearInterval(checkReady);
|
|
802
|
+
}, 5000);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}, [getCurrentQuestion]);
|
|
806
|
+
|
|
807
|
+
// Move to previous lesson
|
|
808
|
+
const previousLesson = useCallback(() => {
|
|
809
|
+
const curriculum = curriculumRef.current || { modules: [] };
|
|
810
|
+
const currentModule = curriculum.modules[stateRef.current.currentModuleIndex];
|
|
811
|
+
|
|
812
|
+
// Check if there's a previous lesson in the current module
|
|
813
|
+
const hasPrevLessonInModule = stateRef.current.currentLessonIndex > 0;
|
|
814
|
+
|
|
815
|
+
if (hasPrevLessonInModule) {
|
|
816
|
+
// Move to previous lesson in current module
|
|
817
|
+
stateRef.current.currentLessonIndex -= 1;
|
|
818
|
+
stateRef.current.currentQuestionIndex = 0;
|
|
819
|
+
stateRef.current.lessonCompleted = false;
|
|
820
|
+
stateRef.current.isQuestionMode = false;
|
|
821
|
+
stateRef.current.isTeaching = false;
|
|
822
|
+
stateRef.current.score = 0;
|
|
823
|
+
stateRef.current.totalQuestions = 0;
|
|
824
|
+
|
|
825
|
+
// Notify parent that lesson has changed
|
|
826
|
+
callbacksRef.current.onCustomAction({
|
|
827
|
+
type: 'lessonStart',
|
|
828
|
+
moduleIndex: stateRef.current.currentModuleIndex,
|
|
829
|
+
lessonIndex: stateRef.current.currentLessonIndex
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
callbacksRef.current.onLessonStart({
|
|
833
|
+
moduleIndex: stateRef.current.currentModuleIndex,
|
|
834
|
+
lessonIndex: stateRef.current.currentLessonIndex,
|
|
835
|
+
lesson: getCurrentLesson()
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
if (avatarRef.current) {
|
|
839
|
+
avatarRef.current.setMood("happy");
|
|
840
|
+
avatarRef.current.setBodyMovement("idle");
|
|
841
|
+
}
|
|
842
|
+
} else {
|
|
843
|
+
// No previous lesson in current module - check if there's a previous module
|
|
844
|
+
const hasPrevModule = stateRef.current.currentModuleIndex > 0;
|
|
845
|
+
|
|
846
|
+
if (hasPrevModule) {
|
|
847
|
+
// Move to last lesson of previous module
|
|
848
|
+
const prevModule = curriculum.modules[stateRef.current.currentModuleIndex - 1];
|
|
849
|
+
stateRef.current.currentModuleIndex -= 1;
|
|
850
|
+
stateRef.current.currentLessonIndex = (prevModule?.lessons?.length || 1) - 1;
|
|
851
|
+
stateRef.current.currentQuestionIndex = 0;
|
|
852
|
+
stateRef.current.lessonCompleted = false;
|
|
853
|
+
stateRef.current.isQuestionMode = false;
|
|
854
|
+
stateRef.current.isTeaching = false;
|
|
855
|
+
stateRef.current.score = 0;
|
|
856
|
+
stateRef.current.totalQuestions = 0;
|
|
857
|
+
|
|
858
|
+
// Notify parent that lesson has changed
|
|
859
|
+
callbacksRef.current.onCustomAction({
|
|
860
|
+
type: 'lessonStart',
|
|
861
|
+
moduleIndex: stateRef.current.currentModuleIndex,
|
|
862
|
+
lessonIndex: stateRef.current.currentLessonIndex
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
callbacksRef.current.onLessonStart({
|
|
866
|
+
moduleIndex: stateRef.current.currentModuleIndex,
|
|
867
|
+
lessonIndex: stateRef.current.currentLessonIndex,
|
|
868
|
+
lesson: getCurrentLesson()
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
if (avatarRef.current) {
|
|
872
|
+
avatarRef.current.setMood("happy");
|
|
873
|
+
avatarRef.current.setBodyMovement("idle");
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}, [getCurrentLesson]);
|
|
878
|
+
|
|
735
879
|
// Reset curriculum
|
|
736
880
|
const resetCurriculum = useCallback(() => {
|
|
737
881
|
stateRef.current.currentModuleIndex = 0;
|
|
@@ -781,7 +925,9 @@ const CurriculumLearning = forwardRef(({
|
|
|
781
925
|
handleAnswerSelect,
|
|
782
926
|
handleCodeTestResult,
|
|
783
927
|
nextQuestion,
|
|
928
|
+
previousQuestion,
|
|
784
929
|
nextLesson,
|
|
930
|
+
previousLesson,
|
|
785
931
|
completeLesson,
|
|
786
932
|
completeCurriculum,
|
|
787
933
|
resetCurriculum,
|