initial import

This commit is contained in:
br0tcraft
2024-08-17 18:57:14 +02:00
parent 16991fe2c0
commit fe1f00978b
15 changed files with 1486 additions and 0 deletions

151
static/script.js Normal file
View File

@ -0,0 +1,151 @@
const canvas = document.getElementById('drawingCanvas');
const ctx = canvas.getContext('2d');
const textElement = document.getElementById('text');
const wordDisplay = document.getElementById('wordDisplay');
const textInput = document.getElementById('textInput');
const submitAnswer = document.getElementById('submitAnswer');
const toggleInput = document.getElementById('toggleInput');
const clearCanvas = document.getElementById('clearCanvas');
const previewDrawing = document.getElementById('previewDrawing');
const recognizedText = document.getElementById('recognizedText');
let currentWord = null;
let currentInputMode = 'text'; // 'text' or 'drawing'
let isDrawing = false;
// Initialize input mode
function initializeInputMode() {
textInput.style.display = 'block';
canvas.style.display = 'none';
clearCanvas.style.display = 'none';
previewDrawing.style.display = 'none';
toggleInput.textContent = 'Zu Zeichnen wechseln';
recognizedText.textContent = '';
}
// Load a new word
function loadWord() {
fetch('/get_random_vocab')
.then(response => response.json())
.then(data => {
if (data.error) {
wordDisplay.textContent = 'Keine Vokabeln gefunden.';
} else {
currentWord = data;
const isEnglish = Math.random() < 0.5;
wordDisplay.textContent = isEnglish ? `English: ${currentWord.english}` : `Deutsch: ${currentWord.german}`;
textElement.textContent = '';
textInput.value = '';
recognizedText.textContent = '';
if (currentInputMode === 'drawing') {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}
})
.catch(error => console.error('Fehler beim Laden der Vokabel:', error));
}
// Switch between input modes
toggleInput.addEventListener('click', () => {
if (currentInputMode === 'text') {
textInput.style.display = 'none';
canvas.style.display = 'block';
clearCanvas.style.display = 'inline-block';
previewDrawing.style.display = 'inline-block';
toggleInput.textContent = 'Zu Texteingabe wechseln';
currentInputMode = 'drawing';
} else {
textInput.style.display = 'block';
canvas.style.display = 'none';
clearCanvas.style.display = 'none';
previewDrawing.style.display = 'none';
toggleInput.textContent = 'Zu Zeichnen wechseln';
currentInputMode = 'text';
}
});
// Clear the canvas
clearCanvas.addEventListener('click', () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
recognizedText.textContent = ''; // Clear the recognized text as well
});
// Drawing functionality
canvas.addEventListener('mousedown', () => {
isDrawing = true;
});
canvas.addEventListener('mouseup', () => {
isDrawing = false;
ctx.beginPath();
});
canvas.addEventListener('mousemove', draw);
function draw(event) {
if (!isDrawing) return;
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.strokeStyle = 'black';
ctx.lineTo(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
}
// Preview the drawing recognition
previewDrawing.addEventListener('click', () => {
const dataURL = canvas.toDataURL('image/png');
fetch(dataURL)
.then(res => res.blob())
.then(blob => {
Tesseract.recognize(
blob,
'eng',
{ logger: info => console.log(info) }
).then(({ data: { text } }) => {
recognizedText.textContent = `Erkannter Text: ${text.trim()}`;
});
})
.catch(error => {
console.error('Fehler beim Erkennen des Textes:', error);
});
});
// Submit answer
submitAnswer.addEventListener('click', () => {
let answer = '';
if (currentInputMode === 'text') {
answer = textInput.value.trim();
} else {
answer = recognizedText.textContent.replace('Erkannter Text:', '').trim();
}
checkAnswer(answer);
});
// Check if the answer is correct
function checkAnswer(answer) {
const correctAnswer = (wordDisplay.textContent.startsWith('English:') ? currentWord.german : currentWord.english).trim().toLowerCase();
if (answer.toLowerCase() === correctAnswer) {
textElement.textContent = 'Richtig!';
textElement.style.color = 'green';
// Update the vocabulary level
fetch(`/update_vocab_level/${currentWord.id}`, { method: 'POST' })
.then(() => {
setTimeout(loadWord, 2000); // Show the result for 2 seconds before loading the next word
});
} else {
textElement.textContent = `Falsch! Die richtige Antwort ist: ${correctAnswer}`;
textElement.style.color = 'red';
setTimeout(loadWord, 3000); // Show the result for 3 seconds before loading the next word
}
}
// Initialize the input mode and load the first word
initializeInputMode();
loadWord();

33
static/styles.css Normal file
View File

@ -0,0 +1,33 @@
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f4f4f4;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
}
canvas {
border: 1px solid #000;
background-color: #fff;
}
button {
margin-top: 10px;
padding: 10px 20px;
background-color: #007bff;
color: #fff;
border: none;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}

160
static/vocab.js Normal file
View File

@ -0,0 +1,160 @@
document.addEventListener('DOMContentLoaded', () => {
loadVocab();
document.getElementById('addVocab').addEventListener('click', () => {
const englishInput = document.getElementById('englishInput').value;
const germanInput = document.getElementById('germanInput').value;
if (englishInput && germanInput) {
fetch('/add_vocab', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
english: englishInput,
german: germanInput,
level: 1 // Automatisch Level 1 setzen
})
}).then(response => response.json())
.then(data => {
if (data.success) {
loadVocab();
document.getElementById('englishInput').value = '';
document.getElementById('germanInput').value = '';
} else {
alert(data.error);
}
}).catch(error => {
console.error('Fehler beim Hinzufügen der Vokabel:', error);
});
} else {
alert('Bitte alle Felder ausfüllen.');
}
});
document.getElementById('backToHome').addEventListener('click', () => {
window.location.href = '/'; // Pfad zur Startseite anpassen
});
});
function loadVocab() {
fetch('/get_vocab')
.then(response => response.json())
.then(vocabList => {
const tables = [1, 2, 3, 4, 5].map(level => document.getElementById(`vocab-list-${level}`));
tables.forEach(table => table.querySelector('tbody').innerHTML = '');
vocabList.forEach(vocab => {
const row = document.createElement('tr');
row.dataset.id = vocab.id;
row.dataset.level = vocab.level; // Level in dataset speichern
row.innerHTML = `
<td class="editable">${vocab.english}</td>
<td class="editable">${vocab.german}</td>
<td>
<button class="edit-btn">Bearbeiten</button>
<button class="delete-btn" data-id="${vocab.id}">Löschen</button>
</td>
`;
const targetTable = document.getElementById(`vocab-list-${vocab.level}`);
targetTable.querySelector('tbody').appendChild(row);
});
// Event-Listener für den „Löschen“-Button
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', (event) => {
const vocabId = event.target.getAttribute('data-id');
fetch(`/delete_vocab/${vocabId}`, {
method: 'DELETE'
}).then(response => response.json())
.then(data => {
if (data.success) {
loadVocab();
} else {
alert(data.error);
}
}).catch(error => {
console.error('Fehler beim Löschen der Vokabel:', error);
});
});
});
// Event-Listener für den „Bearbeiten“-Button
document.querySelectorAll('.edit-btn').forEach(btn => {
btn.addEventListener('click', (event) => {
const row = event.target.closest('tr');
const id = row.dataset.id;
const english = row.children[0].textContent;
const german = row.children[1].textContent;
const level = row.dataset.level || 1; // Level aus dem dataset lesen, Fallback auf 1
// Setze die Zeile in den Bearbeitungsmodus
row.innerHTML = `
<td><input type="text" class="editable-input" value="${english}"></td>
<td><input type="text" class="editable-input" value="${german}"></td>
<td class="edit-controls">
<div class="level-input-container">
<label for="levelInput">Level:</label>
<input type="number" id="levelInput" class="level-input" min="1" max="5" value="${level}">
</div>
<button class="save-btn">Speichern</button>
<button class="cancel-btn">Abbrechen</button>
</td>
`;
row.querySelector('.save-btn').addEventListener('click', () => {
const englishInput = row.querySelector('.editable-input').value;
const germanInput = row.querySelectorAll('.editable-input')[1].value;
const levelInput = row.querySelector('#levelInput').value;
fetch(`/update_vocab/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
english: englishInput,
german: germanInput,
level: parseInt(levelInput, 10)
})
}).then(response => response.json())
.then(data => {
if (data.success) {
loadVocab();
} else {
alert(data.error);
}
}).catch(error => {
console.error('Fehler beim Aktualisieren der Vokabel:', error);
});
});
row.querySelector('.cancel-btn').addEventListener('click', () => {
loadVocab();
});
});
});
}).catch(error => {
console.error('Fehler beim Laden der Vokabeln:', error);
});
}
//sqlite3 anstatt cokkies