This commit is contained in:
team3
2026-06-21 16:30:54 +02:00
parent 89a853981d
commit 920046b774
3 changed files with 36 additions and 23 deletions

View File

@@ -33,24 +33,26 @@ const st = computed(() => props.status || { gute_antworten: 0, streak: 0, absolv
const MODI = ['quiz_leicht', 'quiz_schwer', 'lueck_leicht', 'lueck_schwer', 'erklaeren']
const score = computed(() => st.value.gute_antworten || 0)
const schwerWahl = ref(false) // leicht/schwer in den Bändern unter 19 (ALT+E)
// Form wechselt NACH dem Meilenstein (>): Quiz 06, Lückentext 712, Erklären 1318,
// Zufall 1930 (jede Frage ein zufälliger Modus). 'zufall' = Platzhalter; das gezogene
// Objekt trägt die echte Form/Schwierigkeit.
const aktiverModus = computed(() => {
if (!musterModus.value) return 'erklaeren'
if (score.value > GEMEISTERT) return 'zufall'
if (score.value > VERSTANDEN) return 'erklaeren'
if (score.value > ABSOLVIERT) return schwerWahl.value ? 'lueck_schwer' : 'lueck_leicht'
return schwerWahl.value ? 'quiz_schwer' : 'quiz_leicht'
})
const imZufall = computed(() => aktiverModus.value === 'zufall')
// Reines Band aus dem aktuellen Score (ohne Schwierigkeit) — für den Abschnittswechsel.
const aktuellesBand = computed(() => {
if (score.value > GEMEISTERT) return 'zufall'
if (score.value > VERSTANDEN) return 'erklaeren'
if (score.value > ABSOLVIERT) return 'lueckentext'
// Band aus einem Score: Lückentext ab 6, Erklären ab 12, Zufall ab 18 (Meilenstein-inklusiv).
function bandFuer(s) {
if (s >= GEMEISTERT) return 'zufall'
if (s >= VERSTANDEN) return 'erklaeren'
if (s >= ABSOLVIERT) return 'lueckentext'
return 'quiz'
}
// Am Format-Max: Score eingefroren („Max"). Gilt auch bei cap 30 (FullGuide, endgültig).
const amDeckel = computed(() => score.value >= props.cap)
// Aktuelles Band: am Deckel bleibt das Band des erreichten Formats (cap1), sonst score-basiert.
// Ohne Frage-Muster (alter Baustein) gibt es nur Erklären.
const aktuellesBand = computed(() => musterModus.value ? bandFuer(amDeckel.value ? props.cap - 1 : score.value) : 'erklaeren')
// 'zufall' = Platzhalter; das gezogene Objekt trägt die echte Form/Schwierigkeit.
const aktiverModus = computed(() => {
const b = aktuellesBand.value
if (b === 'lueckentext') return schwerWahl.value ? 'lueck_schwer' : 'lueck_leicht'
if (b === 'quiz') return schwerWahl.value ? 'quiz_schwer' : 'quiz_leicht'
return b // 'erklaeren' | 'zufall'
})
const imZufall = computed(() => aktuellesBand.value === 'zufall')
const aktiveForm = computed(() => {
const m = aktiverModus.value
if (m === 'zufall') return 'quiz' // Platzhalter fürs idle-Widget; Objekt überschreibt
@@ -76,15 +78,13 @@ const modusRegel = computed(() => {
if (zeigeForm.value === 'lueckentext') return aktSchwer.value ? 'frei tippen · +3/1' : 'Begriff aus 4 · +1/1'
return '+1/+2/+3 · Nachfragen max +1 · schwach 1'
})
// Ende des aktuellen Bands (nächster Meilenstein) und ob der Score am Format-Deckel klebt.
// Ende des aktuellen Bands (nächster Meilenstein).
const bandZiel = computed(() => {
if (score.value > GEMEISTERT) return VOLL
if (score.value > VERSTANDEN) return GEMEISTERT
if (score.value > ABSOLVIERT) return VERSTANDEN
if (score.value >= GEMEISTERT) return VOLL
if (score.value >= VERSTANDEN) return GEMEISTERT
if (score.value >= ABSOLVIERT) return VERSTANDEN
return ABSOLVIERT
})
// Am Format-Max: Score eingefroren („Max"). Gilt auch bei cap 30 (FullGuide, endgültig).
const amDeckel = computed(() => score.value >= props.cap)
const FORM_NAME = { quiz: 'Quiz', lueckentext: 'Lückentext', erklaeren: 'Erklären' }
const NAECHSTES_FORMAT = { 6: 'Guide', 12: 'ProGuide', 18: 'FullGuide' }
@@ -207,7 +207,15 @@ function objText(o) { return (o && (o.frage || o.satz)) || '' }
// Lückensatz rendern: an „___" splitten, Teile inline (mit $…$-Mathe), Lücke als Span.
// So bleibt die Lücke erhalten und Markdown fasst die Unterstriche nicht an.
function lueckSatzHtml(satz) {
return String(satz || '').split('___').map((t) => renderMarkdownInline(t)).join('<span class="bp-luecke">______</span>')
satz = String(satz || '')
const m = satz.match(/_{3,}/) // erste Lücke (drei oder mehr Unterstriche)
if (!m) return renderMarkdownInline(satz)
// Liegt die Lücke INNERHALB einer $…$-Formel (ungerade Zahl $ davor)? Dann nicht splitten
// (das zerreißt die Formel) — stattdessen durch eine KaTeX-Linie ersetzen, Satz am Stück rendern.
const inFormel = ((satz.slice(0, m.index).match(/\$/g) || []).length % 2) === 1
if (inFormel) return renderMarkdownInline(satz.replace(/_{3,}/, '\\rule{2.5em}{0.4pt}'))
// Lücke im Text: splitten + Lücken-Span.
return satz.split(/_{3,}/).map((t) => renderMarkdownInline(t)).join('<span class="bp-luecke">______</span>')
}
function istBekannt(o) {