update
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
<script setup>
|
||||
import { computed, nextTick, onUnmounted, ref, watch } from 'vue'
|
||||
import { api } from '../api.js'
|
||||
import { render, gefiltert, lesestat, renderGestuft } from '../markdown.js'
|
||||
import { render, lesestat } from '../markdown.js'
|
||||
|
||||
const props = defineProps({ topic: String, state: Object })
|
||||
const daten = ref(null)
|
||||
const level = ref('E') // Default: Einstieg — Umfang wächst per Toggle (E→M→S)
|
||||
const level = ref('E') // Durchgang-Wahl: jede Stufe ist ein eigener Lese-Durchgang
|
||||
const ansicht = ref('erklaerend') // erklaerend = Fließtext | kompakt = Stichpunkte
|
||||
const LEVEL_ICON = { E: '●○○', M: '●●○', S: '●●●' }
|
||||
const LEVEL_NAME = { E: 'Umfang: Grundgerüst', M: 'Umfang: + Standardstoff', S: 'Umfang: alles' }
|
||||
const LEVEL_NAME = { E: 'Durchgang 1: Grundgerüst', M: 'Durchgang 2: Standardstoff',
|
||||
S: 'Durchgang 3: Feinheiten' }
|
||||
const fokus = ref(false) // Fokus: Vollbild — App-Chrome + Navigation weg, Karten aufgelöst
|
||||
watch(fokus, (f) => document.body.classList.toggle('vollbild', f))
|
||||
onUnmounted(() => document.body.classList.remove('vollbild'))
|
||||
@@ -28,10 +29,9 @@ const htmlCache = new Map()
|
||||
watch(daten, () => htmlCache.clear())
|
||||
|
||||
function html(s) {
|
||||
const key = `${ansicht.value}|${level.value}|${s.baustein}`
|
||||
const key = `${ansicht.value}|${s.baustein}`
|
||||
if (!htmlCache.has(key)) {
|
||||
htmlCache.set(key, ansicht.value === 'kompakt'
|
||||
? render(s.kompakt || s.lang) : renderGestuft(s.lang, level.value))
|
||||
htmlCache.set(key, render(ansicht.value === 'kompakt' ? s.kompakt : s.lang))
|
||||
}
|
||||
return htmlCache.get(key)
|
||||
}
|
||||
@@ -47,23 +47,29 @@ function hoehe(i) {
|
||||
|
||||
function setAnsicht(a) {
|
||||
ansicht.value = a
|
||||
laden()
|
||||
}
|
||||
|
||||
// Nur Durchgänge anbieten, die es in diesem Thema gibt (ohne E- oder
|
||||
// S-Bausteine überspringt der Toggle die Stufe)
|
||||
const levels = computed(() => {
|
||||
const da = new Set((daten.value?.kapitel || []).map((k) => k.level))
|
||||
const folge = ['E', 'M', 'S'].filter((l) => da.has(l))
|
||||
return folge.length ? folge : ['E']
|
||||
})
|
||||
watch(levels, (l) => { if (!l.includes(level.value)) level.value = l[0] })
|
||||
|
||||
function levelToggle() {
|
||||
const folge = ['E', 'M', 'S']
|
||||
level.value = folge[(folge.indexOf(level.value) + 1) % 3]
|
||||
laden()
|
||||
const folge = levels.value
|
||||
level.value = folge[(folge.indexOf(level.value) + 1) % folge.length]
|
||||
}
|
||||
|
||||
// Nur Kapitel/Bausteine mit Inhalt im gewählten Umfang anzeigen — der
|
||||
// Level-Filter ließe sonst leere Titel-Hüllen stehen (36/66 Bausteine ohne E)
|
||||
// Der gewählte Durchgang: nur seine Kapitel, nur Sections mit Inhalt
|
||||
const anzeige = computed(() => {
|
||||
const out = []
|
||||
for (const kap of daten.value?.kapitel || []) {
|
||||
const sections = kap.sections.filter((s) => ansicht.value === 'kompakt'
|
||||
? (s.kompakt || s.lang || '').trim()
|
||||
: lesestat(gefiltert(s.lang, level.value)).woerter >= 10)
|
||||
if (kap.level !== level.value) continue
|
||||
const sections = kap.sections.filter((s) =>
|
||||
((ansicht.value === 'kompakt' ? s.kompakt : s.lang) || '').trim())
|
||||
if (sections.length) out.push({ ...kap, sections })
|
||||
}
|
||||
return out
|
||||
@@ -77,8 +83,7 @@ const stats = computed(() => {
|
||||
let woerter = ansicht.value === 'kompakt' ? 0 : lesestat(kap.intro).woerter
|
||||
let formeln = 0
|
||||
for (const s of kap.sections) {
|
||||
const st = lesestat(ansicht.value === 'kompakt' ? (s.kompakt || s.lang)
|
||||
: gefiltert(s.lang, level.value))
|
||||
const st = lesestat(ansicht.value === 'kompakt' ? s.kompakt : s.lang)
|
||||
woerter += st.woerter
|
||||
formeln += st.displayFormeln
|
||||
}
|
||||
@@ -156,12 +161,23 @@ function onScroll(e) {
|
||||
<div v-for="(kap, i) in anzeige" :key="kap.kapitel_id" class="kapitel"
|
||||
:ref="(el) => setKapEl(i, el)">
|
||||
<h2 class="kapitel-titel">{{ i + 1 }}. {{ kap.titel }}</h2>
|
||||
<div class="kapitel-meta">
|
||||
{{ (stats.je[i]?.woerter || 0).toLocaleString('de-DE') }} Wörter ·
|
||||
{{ zeit(stats.je[i]?.minuten || 0) }}
|
||||
</div>
|
||||
<template v-if="sichtbar(i)">
|
||||
<p v-if="kap.intro && ansicht === 'erklaerend'"
|
||||
style="color: var(--dim); margin-top: 0">{{ kap.intro }}</p>
|
||||
<div v-for="s in kap.sections" :key="s.baustein" class="guide-section">
|
||||
<h3 style="margin-top: 0">{{ s.titel }}</h3>
|
||||
<div :class="ansicht === 'kompakt' ? 'kompakt' : 'markdown'" v-html="html(s)"></div>
|
||||
<details v-if="ansicht === 'erklaerend' && s.fragen?.length" class="antworten">
|
||||
<summary>Antworten zu „Prüfe dich"</summary>
|
||||
<div v-for="(f, fi) in s.fragen" :key="fi" class="antwort">
|
||||
<div class="frage">{{ f.frage }}</div>
|
||||
<div v-html="render(f.antwort)"></div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="kapitel-platzhalter" :style="{ height: hoehe(i) + 'px' }"></div>
|
||||
|
||||
Reference in New Issue
Block a user