diff --git a/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue b/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue index 688c868..2d264f6 100755 --- a/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue +++ b/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue @@ -140,6 +140,7 @@ import apiClient from '@/utils/axios.js'; import { normalizeComparableWithNumberWords } from '@/utils/numberAnswerVariants.js'; const PRACTICE_MIN_EXPOSURES = 3; +// The original daily batch remains stable when the dialog is reopened. const SRS_SESSION_STORAGE_VERSION = 2; const HARD_REQUIRED_CONSECUTIVE_CORRECT = 5; const MAX_DAILY_DUE = 50; @@ -502,10 +503,7 @@ export default { const dueIds = (this.pool || []).map((it) => it.id); const stored = this.loadSrsSession(); - // If the previous session is already complete, start fresh (new batch of due items). - if (stored && Number(stored.initialTotalDue || 0) > 0 && Array.isArray(stored.doneIds) && stored.doneIds.length >= stored.initialTotalDue) { - this.srsSession = null; - } else if (stored) { + if (stored) { this.srsSession = stored; } else { this.srsSession = null; @@ -543,16 +541,23 @@ export default { try { this.saveSrsSession(); } catch (_) {} } + const initialDueIds = Array.isArray(this.srsSession.initialDueIds) + ? this.srsSession.initialDueIds.slice(0, MAX_DAILY_DUE) + : []; const doneSet = new Set(Array.isArray(this.srsSession.doneIds) ? this.srsSession.doneIds : []); const finalReviewIds = Array.isArray(this.srsSession.finalReviewIds) ? this.srsSession.finalReviewIds : []; const finalReviewSet = new Set(finalReviewIds); const availableIds = new Set(dueIds); + // Never fill a partly completed daily batch with additional overdue + // cards. The 50 cards chosen when the session began remain today's + // batch; answered cards reduce its remaining count. this.srsQueueIds = [ - ...dueIds.filter((id) => !doneSet.has(id) && !finalReviewSet.has(id)), - ...finalReviewIds.filter((id) => !doneSet.has(id) && availableIds.has(id)) + ...initialDueIds.filter((id) => availableIds.has(id) && !doneSet.has(id) && !finalReviewSet.has(id)), + ...finalReviewIds.filter((id) => initialDueIds.includes(id) && !doneSet.has(id) && availableIds.has(id)) ]; - // Fallback: if SRS mode but queue is empty (e.g. mismatch between stored session and current pool), fall back to pool order - if (this.srsMode && Array.isArray(this.srsQueueIds) && this.srsQueueIds.length === 0) { + // Only a corrupted session without an original batch may use the pool + // as fallback. An empty, completed batch must remain empty today. + if (this.srsMode && initialDueIds.length === 0) { const fallbackIds = (this.pool || []).map((it) => it.id).filter(Boolean); if (fallbackIds.length > 0) { const limited = fallbackIds.slice(0, MAX_DAILY_DUE); diff --git a/frontend/src/i18n/locales/ceb/socialnetwork.json b/frontend/src/i18n/locales/ceb/socialnetwork.json index c656fe3..6f7af23 100755 --- a/frontend/src/i18n/locales/ceb/socialnetwork.json +++ b/frontend/src/i18n/locales/ceb/socialnetwork.json @@ -447,7 +447,7 @@ "courseFlowIntensiveStatusAction": "Tan-awa ang sunod nga balik-balik", "courseFlowIntensiveStatusTitle": "Sunod nga balik-balik sa bokabularyo", "courseFlowIntensiveStatusAllDone": "Wala pay dugang nga balik-balik sa bokabularyo nga nakaplano alang sa nahuman nga mga leksiyon.", - "courseFlowIntensiveStatusDue": "Karon / nalangan", + "courseFlowIntensiveStatusDue": "Nahibilin karon: {remaining} sa {quota} giplano · kinatibuk-ang angay: {total}", "courseFlowIntensiveStatusProgress": "{count} ka termino", "courseFlowIntensiveStatusNoDate": "Ang mga petsa nagsalig sa imong sakto nga tubag: 1, 3, 7, 14, 30, 60 ug 120 ka adlaw. Ang lisod nga mga termino gilain ug praktisahon sa lugar sa lisod nga mga termino.", "courseFlowPracticeTitle": "Libre nga pagpalalom", @@ -766,9 +766,9 @@ "quickReviewPromptTarget": "Type sa target pinulongan: \"{term}\"", "quickReviewAcknowledge": "Read, continue", "courseTodayPlanIntroNoDueReview": "Walay angay nga mubo nga balik-balik karon. Makita nimo ang sunod nga makatarunganon nga lakang sa block (limitado sa kabug-aton), unya ang intensive kung naay. Ang mubo nga balik-balik mobalik sa 1/3/7 ka adlaw.", - "srsDueStat": "SRS angay: {count}", + "srsDueStat": "Adlaw-adlaw nga balik-balik: {scheduled} sa {total} ka termino", "srsEyebrow": "Dugay nga memorya", - "srsTitle": "{count} ka termino ang angay karon", + "srsTitle": "Karon: {scheduled} sa {total} ka angay balik-balikon", "srsIntro": "Kini nga balik-balik gikan sa SRS nga plano sa matag pulong. Una kini kaysa bag-ong materyal kay nagpalig-on kini sa mga pulong nga hapit malimtan.", "srsStart": "Sugdi ang daily review", "courseTodayPlanIntroSrs": "Didaktik nga han-ay: una ang SRS daily review sa tagsa-tagsa ka pulong. Human ana, mubo nga review, padayon sa block, ug intensive review kung kinahanglan. Mao ni ang pagpalig-on sa daan nga materyal sa dili pa modugang ug bag-o." diff --git a/frontend/src/i18n/locales/de/socialnetwork.json b/frontend/src/i18n/locales/de/socialnetwork.json index 8e74084..e85a3db 100755 --- a/frontend/src/i18n/locales/de/socialnetwork.json +++ b/frontend/src/i18n/locales/de/socialnetwork.json @@ -777,7 +777,7 @@ "courseFlowIntensiveStatusAction": "Nächste Wiederholungen prüfen", "courseFlowIntensiveStatusTitle": "Nächste Vokabelwiederholungen", "courseFlowIntensiveStatusAllDone": "Für abgeschlossene Lektionen sind derzeit keine weiteren Vokabelwiederholungen geplant.", - "courseFlowIntensiveStatusDue": "Heute / überfällig", + "courseFlowIntensiveStatusDue": "Heute noch: {remaining} von {quota} eingeplant · insgesamt fällig: {total}", "courseFlowIntensiveStatusProgress": "{count} Begriffe", "courseFlowIntensiveStatusNoDate": "Die Termine richten sich nach deinen richtigen Antworten: 1, 3, 7, 14, 30, 60 und 120 Tage. Schwer markierte Begriffe werden getrennt im Bereich „Schwere Begriffe“ geübt.", "courseFlowPracticeTitle": "Freie Vertiefung", @@ -876,9 +876,9 @@ "reviewTimeNow": "jetzt", "reviewTimeTomorrow": "morgen", "reviewTimeInDays": "in {count} Tagen", - "srsDueStat": "Tageswiederholung: {scheduled} Begriffe", + "srsDueStat": "Tageswiederholung: {scheduled} von {total} Begriffen", "srsEyebrow": "Langzeitgedächtnis", - "srsTitle": "Heute: {scheduled} fällige Begriffe", + "srsTitle": "Heute: {scheduled} von {total} fälligen Begriffen", "srsIntro": "Diese Wiederholung kommt aus dem SRS-Plan einzelner Begriffe. Pro Tag werden höchstens 50 Begriffe eingeplant; weitere fällige Begriffe bleiben für die nächste Tageswiederholung erhalten.", "srsStart": "Tageswiederholung starten", "courseTodayPlanIntroSrs": "Didaktische Reihenfolge: Zuerst die fällige SRS-Tageswiederholung einzelner Begriffe. Danach kommen Kurz-Wiederholungen, Blockfortschritt und ggf. intensive Wiederholung. So wird altes Material stabilisiert, bevor neues Material dazukommt." diff --git a/frontend/src/i18n/locales/en/socialnetwork.json b/frontend/src/i18n/locales/en/socialnetwork.json index 8deba9c..584537a 100755 --- a/frontend/src/i18n/locales/en/socialnetwork.json +++ b/frontend/src/i18n/locales/en/socialnetwork.json @@ -777,7 +777,7 @@ "courseFlowIntensiveStatusAction": "Check upcoming reviews", "courseFlowIntensiveStatusTitle": "Upcoming vocabulary reviews", "courseFlowIntensiveStatusAllDone": "No further vocabulary reviews are currently scheduled for completed lessons.", - "courseFlowIntensiveStatusDue": "Today / overdue", + "courseFlowIntensiveStatusDue": "Remaining today: {remaining} of {quota} planned · total due: {total}", "courseFlowIntensiveStatusProgress": "{count} terms", "courseFlowIntensiveStatusNoDate": "Dates are based on correct answers: 1, 3, 7, 14, 30, 60 and 120 days. Terms marked hard are practised separately in the hard-terms area.", "courseFlowPracticeTitle": "Free practice", @@ -876,9 +876,9 @@ "reviewTimeNow": "now", "reviewTimeTomorrow": "tomorrow", "reviewTimeInDays": "in {count} days", - "srsDueStat": "Daily review: {scheduled} terms", + "srsDueStat": "Daily review: {scheduled} of {total} terms", "srsEyebrow": "Long-term memory", - "srsTitle": "Today: {scheduled} due terms", + "srsTitle": "Today: {scheduled} of {total} due terms", "srsIntro": "This review comes from the SRS schedule of individual terms. At most 50 terms are planned per day; any additional due terms remain for the next daily review.", "srsStart": "Start daily review", "courseTodayPlanIntroSrs": "Pedagogical order: start with the due SRS daily review for individual terms. Then quick reviews, block progress, and intensive review if needed. This stabilizes old material before new material is added." diff --git a/frontend/src/i18n/locales/es/socialnetwork.json b/frontend/src/i18n/locales/es/socialnetwork.json index 34c8185..db071ab 100755 --- a/frontend/src/i18n/locales/es/socialnetwork.json +++ b/frontend/src/i18n/locales/es/socialnetwork.json @@ -756,7 +756,7 @@ "courseFlowIntensiveStatusAction": "Consultar próximos repasos", "courseFlowIntensiveStatusTitle": "Próximos repasos de vocabulario", "courseFlowIntensiveStatusAllDone": "Actualmente no hay más repasos de vocabulario programados para las lecciones completadas.", - "courseFlowIntensiveStatusDue": "Hoy / atrasado", + "courseFlowIntensiveStatusDue": "Pendientes hoy: {remaining} de {quota} planificados · total pendientes: {total}", "courseFlowIntensiveStatusProgress": "{count} términos", "courseFlowIntensiveStatusNoDate": "Las fechas se basan en tus respuestas correctas: 1, 3, 7, 14, 30, 60 y 120 días. Los términos marcados como difíciles se practican por separado en el área de términos difíciles.", "courseFlowPracticeTitle": "Práctica libre", diff --git a/frontend/src/views/falukant/ReputationView.vue b/frontend/src/views/falukant/ReputationView.vue index 824a638..eeeec53 100755 --- a/frontend/src/views/falukant/ReputationView.vue +++ b/frontend/src/views/falukant/ReputationView.vue @@ -133,7 +133,7 @@
{{ $t('socialnetwork.vocab.courses.courseFlowIntensiveStatusNoDate') }}
-{{ $t('socialnetwork.vocab.courses.courseFlowIntensiveStatusAllDone') }}
+{{ $t('socialnetwork.vocab.courses.courseFlowIntensiveStatusAllDone') }}