Testpdf / templates /index.html
Docfile's picture
Update templates/index.html
79914b8 verified
raw
history blame
11 kB
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Résolveur d'Images</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/katex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/contrib/auto-render.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/katex.min.css">
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
}
h1 {
text-align: center;
color: #333;
}
.container {
display: flex;
flex-direction: column;
gap: 20px;
}
.upload-section {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
border: 2px dashed #ccc;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s;
}
.upload-section:hover {
border-color: #888;
}
#file-input {
display: none;
}
.preview-container {
width: 100%;
text-align: center;
margin-top: 10px;
}
#image-preview {
max-width: 100%;
max-height: 300px;
display: none;
}
#solving-container {
display: none;
background-color: #f5f5f5;
padding: 20px;
border-radius: 8px;
}
.response-container {
margin-top: 20px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #fff;
display: none;
}
.thinking {
color: #777;
font-style: italic;
}
.button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 10px 2px;
cursor: pointer;
border-radius: 4px;
transition: background-color 0.3s;
}
.button:hover {
background-color: #45a049;
}
.button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.copy-button {
background-color: #2196F3;
}
.copy-button:hover {
background-color: #0b7dda;
}
.loading {
text-align: center;
font-style: italic;
margin: 10px 0;
}
.status {
text-align: center;
margin-bottom: 10px;
font-weight: bold;
}
</style>
</head>
<body>
<h1>Résolveur d'Images</h1>
<div class="container">
<div id="upload-section" class="upload-section">
<p>Cliquez ou glissez-déposez une image ici</p>
<input type="file" id="file-input" accept="image/*">
<div class="preview-container">
<img id="image-preview" src="#" alt="Aperçu de l'image">
</div>
</div>
<button id="solve-button" class="button" disabled>Résoudre</button>
<div id="solving-container">
<div class="status" id="status">En attente de résolution...</div>
<div class="loading" id="loading-text">Traitement en cours...</div>
<div class="response-container" id="response-container">
<div id="response"></div>
<button id="copy-button" class="button copy-button">Copier la réponse</button>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const uploadSection = document.getElementById('upload-section');
const fileInput = document.getElementById('file-input');
const imagePreview = document.getElementById('image-preview');
const solveButton = document.getElementById('solve-button');
const solvingContainer = document.getElementById('solving-container');
const responseContainer = document.getElementById('response-container');
const response = document.getElementById('response');
const copyButton = document.getElementById('copy-button');
const statusElement = document.getElementById('status');
const loadingText = document.getElementById('loading-text');
let selectedFile = null;
// Événements pour l'upload d'image
uploadSection.addEventListener('click', () => fileInput.click());
uploadSection.addEventListener('dragover', (e) => {
e.preventDefault();
uploadSection.style.borderColor = '#2196F3';
});
uploadSection.addEventListener('dragleave', () => {
uploadSection.style.borderColor = '#ccc';
});
uploadSection.addEventListener('drop', (e) => {
e.preventDefault();
uploadSection.style.borderColor = '#ccc';
if (e.dataTransfer.files.length) {
handleFileSelection(e.dataTransfer.files[0]);
}
});
fileInput.addEventListener('change', (e) => {
if (e.target.files.length) {
handleFileSelection(e.target.files[0]);
}
});
function handleFileSelection(file) {
if (!file.type.startsWith('image/')) {
alert('Veuillez sélectionner une image valide');
return;
}
selectedFile = file;
solveButton.disabled = false;
const reader = new FileReader();
reader.onload = (e) => {
imagePreview.src = e.target.result;
imagePreview.style.display = 'block';
};
reader.readAsDataURL(file);
}
// Événement pour résoudre l'image
solveButton.addEventListener('click', () => {
if (!selectedFile) return;
solveButton.disabled = true;
solvingContainer.style.display = 'block';
responseContainer.style.display = 'none';
statusElement.textContent = 'En attente de résolution...';
loadingText.style.display = 'block';
response.innerHTML = '';
const formData = new FormData();
formData.append('image', selectedFile);
// Création d'une connexion SSE pour recevoir la réponse en streaming
const eventSource = new EventSource('/solve?' + new URLSearchParams({
t: new Date().getTime()
}));
fetch('/solve', {
method: 'POST',
body: formData
}).then(response => {
if (!response.ok) {
throw new Error('Erreur lors de la résolution');
}
// Gestion du SSE
const eventSource = new EventSource('/solve');
let fullResponse = '';
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
if (data.mode === 'thinking') {
statusElement.textContent = 'Gemini réfléchit...';
response.className = 'thinking';
} else if (data.mode === 'answering') {
statusElement.textContent = 'Réponse:';
response.className = '';
responseContainer.style.display = 'block';
loadingText.style.display = 'none';
}
if (data.content) {
fullResponse += data.content;
response.innerHTML = fullResponse;
renderMathInElement(response);
}
if (data.error) {
statusElement.textContent = 'Erreur:';
response.innerHTML = data.error;
eventSource.close();
solveButton.disabled = false;
}
};
eventSource.onerror = function() {
eventSource.close();
solveButton.disabled = false;
};
}).catch(error => {
statusElement.textContent = 'Erreur:';
response.innerHTML = 'Une erreur est survenue lors de la communication avec le serveur.';
responseContainer.style.display = 'block';
loadingText.style.display = 'none';
solveButton.disabled = false;
});
});
// Événement pour copier la réponse
copyButton.addEventListener('click', () => {
const range = document.createRange();
range.selectNode(response);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
document.execCommand('copy');
window.getSelection().removeAllRanges();
copyButton.textContent = 'Copié!';
setTimeout(() => {
copyButton.textContent = 'Copier la réponse';
}, 2000);
});
});
// Rendu des formules LaTeX
document.addEventListener('DOMContentLoaded', function() {
renderMathInElement(document.body, {
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
]
});
});
</script>
</body>
</html>