enhance lesson generation and focus mode functionality
This commit is contained in:
@@ -529,6 +529,7 @@ const focusMode = ref(false);
|
||||
const currentChunk = ref<{ text: string; start: number; end: number } | null>(null);
|
||||
const karaokeAudioEl = ref<HTMLAudioElement | null>(null);
|
||||
const questionPlaying = ref(false);
|
||||
const focusEverActivated = ref(false);
|
||||
|
||||
if (import.meta.client) {
|
||||
const stored = localStorage.getItem("revisione-focus-mode");
|
||||
@@ -543,8 +544,10 @@ const hasAudio = computed(() => {
|
||||
const showKaraoke = computed(() => {
|
||||
if (!focusMode.value) return false;
|
||||
const ds = displayStep.value;
|
||||
return (lessonState.mode === "main" || lessonState.mode === "branch") &&
|
||||
(ds?.type === "concept" || ds?.type === "example");
|
||||
if (!((lessonState.mode === "main" || lessonState.mode === "branch") &&
|
||||
(ds?.type === "concept" || ds?.type === "example"))) return false;
|
||||
// dont show overlay if this step has no audio — avoids perma-"..." with missing TTS
|
||||
return !!(ds?.audioPath && ds?.audioChunks && (ds.audioChunks as any[]).length > 0);
|
||||
});
|
||||
|
||||
const showQuestionOverlay = computed(() =>
|
||||
@@ -554,10 +557,24 @@ const showQuestionOverlay = computed(() =>
|
||||
questionPlaying.value
|
||||
);
|
||||
|
||||
function toggleFocusMode() {
|
||||
async function toggleFocusMode() {
|
||||
focusMode.value = !focusMode.value;
|
||||
if (import.meta.client) localStorage.setItem("revisione-focus-mode", String(focusMode.value));
|
||||
|
||||
if (focusMode.value) {
|
||||
// on first activation, re-fetch lesson so we have the latest audio paths from the DB
|
||||
if (!focusEverActivated.value) {
|
||||
focusEverActivated.value = true;
|
||||
try {
|
||||
const fresh = await $fetch<any>(`/api/topics/${topicId}/lesson`);
|
||||
lesson.value = fresh;
|
||||
const s0 = fresh?.content?.steps?.[0];
|
||||
console.log("[focus] step 0 audioPath:", s0?.audioPath, "| chunks:", s0?.audioChunks?.length ?? "none");
|
||||
} catch (e) {
|
||||
console.warn("[focus] re-fetch failed, using cached lesson data", e);
|
||||
}
|
||||
}
|
||||
|
||||
nextTick(() => startStepAudio());
|
||||
} else {
|
||||
stopAllAudio();
|
||||
@@ -686,7 +703,16 @@ function startStepAudio() {
|
||||
if (!s) return;
|
||||
|
||||
if (s.type === "concept" || s.type === "example" || s.type === "summary") {
|
||||
if (!s.audioPath || !s.audioChunks) return;
|
||||
if (!s.audioPath || !s.audioChunks || (s.audioChunks as any[]).length === 0) {
|
||||
// no usable audio for this step — skip it automatically so focus mode stays alive
|
||||
if (!isLastMainStep.value) {
|
||||
lessonState.stepIndex++;
|
||||
nextTick(() => startStepAudio());
|
||||
} else {
|
||||
completeLesson();
|
||||
}
|
||||
return;
|
||||
}
|
||||
const audio = karaokeAudioEl.value;
|
||||
if (!audio) return;
|
||||
audio.src = s.audioPath;
|
||||
@@ -705,7 +731,10 @@ function startStepAudio() {
|
||||
}
|
||||
} else if (lessonState.mode === "branch") {
|
||||
const bs = currentBranchStep.value;
|
||||
if (!bs?.audioPath || !bs.audioChunks) return;
|
||||
if (!bs?.audioPath || !bs.audioChunks || (bs.audioChunks as any[]).length === 0) {
|
||||
advanceBranchStep();
|
||||
return;
|
||||
}
|
||||
const audio = karaokeAudioEl.value;
|
||||
if (!audio) return;
|
||||
audio.src = bs.audioPath;
|
||||
|
||||
Reference in New Issue
Block a user