feat: Zeilenweise Lektionsanzeige und kompakte Lektionsnummern

Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
jamulix 2025-10-21 20:51:54 +02:00
commit 4fa2a1a040
2 changed files with 53 additions and 42 deletions

View file

@ -14,9 +14,14 @@ document.addEventListener('DOMContentLoaded', function() {
// Aktuelle Textdaten
let currentText = window.initialText;
let lines = window.lines;
let currentLineIndex = window.currentLineIndex;
let startTime = null;
let timerInterval = null;
// Zeige die erste Zeile an
updateLineDisplay();
// Fokus auf das Eingabefeld setzen
userInput.focus();
@ -33,35 +38,27 @@ document.addEventListener('DOMContentLoaded', function() {
// Aktualisiere die Statistik bei Eingabe
userInput.addEventListener('input', function() {
const userValue = this.value;
updateStatistics(userValue, currentText);
const currentLine = lines[currentLineIndex];
updateStatistics(userValue, currentLine);
// Wenn der Text vollständig getippt wurde, automatisch zur nächsten Zeile
if (userValue === currentText) {
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = null;
// Wenn die Zeile vollständig korrekt getippt wurde, zur nächsten Zeile
if (userValue === currentLine) {
if (currentLineIndex < lines.length - 1) {
currentLineIndex++;
userInput.value = '';
updateLineDisplay();
updateStatistics('', lines[currentLineIndex]);
} else {
// Lektion beendet - Statistik speichern
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = null;
}
// Hier könnten wir die Statistik an den Server senden
alert('Lektion beendet!');
// Setze zurück für nächste Lektion?
// Oder automatisch zur nächsten Lektion?
}
setTimeout(function() {
fetch('/next_text', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
.then(response => response.json())
.then(data => {
currentText = data.text;
document.getElementById('target-text').textContent = currentText;
// Aktualisiere den Lektionstitel
document.getElementById('lesson-title').textContent = data.title;
userInput.value = '';
userInput.focus(); // Fokus zurück auf Eingabefeld
updateStatistics('', currentText);
// Zurücksetzen der Zeitmessung
startTime = null;
})
.catch(error => console.error('Fehler:', error));
}, 100); // Kurze Verzögerung für bessere Benutzererfahrung
}
});
@ -73,9 +70,9 @@ document.addEventListener('DOMContentLoaded', function() {
}
}
// Event-Listener für Lektions-Buttons
document.querySelectorAll('.lesson-btn').forEach(button => {
button.addEventListener('click', function() {
// Event-Listener für Lektions-Links
document.querySelectorAll('.lesson-link').forEach(link => {
link.addEventListener('click', function() {
const lessonIndex = parseInt(this.getAttribute('data-lesson-index'));
// Stoppe Timer und setze Zeit zurück
if (timerInterval) {
@ -99,11 +96,13 @@ document.addEventListener('DOMContentLoaded', function() {
alert('Fehler: ' + data.error);
} else {
currentText = data.text;
document.getElementById('target-text').textContent = currentText;
lines = currentText.split('\n');
currentLineIndex = 0;
updateLineDisplay();
document.getElementById('lesson-title').textContent = data.title;
userInput.value = '';
userInput.focus();
updateStatistics('', currentText);
updateStatistics('', lines[currentLineIndex]);
}
})
.catch(error => console.error('Fehler:', error));
@ -128,18 +127,21 @@ document.addEventListener('DOMContentLoaded', function() {
.then(response => response.json())
.then(data => {
currentText = data.text;
document.getElementById('target-text').textContent = currentText;
lines = currentText.split('\n');
currentLineIndex = 0;
updateLineDisplay();
// Aktualisiere den Lektionstitel
document.getElementById('lesson-title').textContent = data.title;
userInput.value = '';
userInput.focus(); // Fokus zurück auf Eingabefeld
updateStatistics('', currentText);
updateStatistics('', lines[currentLineIndex]);
})
.catch(error => console.error('Fehler:', error));
});
// Beenden Button
endBtn.addEventListener('click', function() {
// Hier könnten wir die aktuelle Statistik speichern
fetch('/end_session', {
method: 'POST',
headers: {
@ -242,7 +244,14 @@ document.addEventListener('DOMContentLoaded', function() {
targetElement.innerHTML = highlightedText;
}
// Hilfsfunktion zum Aktualisieren der Zeilenanzeige
function updateLineDisplay() {
const targetElement = document.getElementById('target-text');
targetElement.textContent = lines[currentLineIndex];
updateTextHighlighting('', lines[currentLineIndex]);
}
// Initialisiere Statistik und Textfarben
updateTextHighlighting('', currentText);
updateStatistics('', currentText);
updateLineDisplay();
updateStatistics('', lines[currentLineIndex]);
});

View file

@ -20,11 +20,13 @@
<div class="mb-4">
<h5 class="card-title">Vorlage: <span id="lesson-title">{{ current_lesson_title }}</span></h5>
<div id="target-text" class="border p-3 bg-white rounded" style="white-space: pre-wrap; font-family: monospace;">
<!-- Text wird durch JavaScript eingefügt -->
<!-- Text wird zeilenweise durch JavaScript eingefügt -->
</div>
</div>
<script>
window.initialText = {{ current_text|tojson }};
window.currentLineIndex = 0;
window.lines = window.initialText.split('\n');
</script>
<!-- Eingabefeld -->
@ -91,11 +93,11 @@
<h5 class="card-title">Lektionen</h5>
<div class="row">
{% for lesson in lessons %}
<div class="col-md-2 col-3 mb-2">
<button class="btn btn-outline-primary btn-sm w-100 lesson-btn"
data-lesson-index="{{ loop.index0 }}">
{{ lesson.get('description', (loop.index0 + 1)) }}
</button>
<div class="col-md-1 col-2 mb-1 text-center">
<span class="lesson-link text-primary" style="cursor: pointer; font-size: 0.9rem;"
data-lesson-index="{{ loop.index0 }}">
{{ loop.index0 + 1 }}
</span>
</div>
{% endfor %}
</div>