Spaces:
Running
Running
Update templates/philosophie.html
Browse files- templates/philosophie.html +336 -31
templates/philosophie.html
CHANGED
@@ -16,34 +16,199 @@
|
|
16 |
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
17 |
<style>
|
18 |
/* Styles pour le Glow Up */
|
19 |
-
:root {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
/* Styles pour la lisibilité du Markdown généré */
|
26 |
-
.prose {
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
/* Styles pour Select2 */
|
36 |
-
.select2-container--default .select2-selection--single {
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
/* Styles pour l'aperçu de l'image */
|
42 |
-
#image-preview {
|
|
|
|
|
|
|
|
|
43 |
|
44 |
/* Cacher le marqueur par défaut de <details> */
|
45 |
-
summary {
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
</style>
|
48 |
</head>
|
49 |
<body class="bg-gray-50 text-gray-900">
|
@@ -124,7 +289,7 @@
|
|
124 |
</div>
|
125 |
|
126 |
<!-- Thinking Process Section (Collapsible) -->
|
127 |
-
<div id="thinking-wrapper" class="hidden mt-8">
|
128 |
<details id="thinking-container" class="bg-white border border-gray-200 rounded-xl shadow-sm">
|
129 |
<summary class="flex justify-between items-center p-4 cursor-pointer">
|
130 |
<h3 class="text-md font-semibold text-gray-700">Processus de pensée de l'IA</h3>
|
@@ -132,14 +297,14 @@
|
|
132 |
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
133 |
</svg>
|
134 |
</summary>
|
135 |
-
<div id="thinking-process" class="p-4 border-t border-gray-200 text-sm text-gray-600 prose prose-sm max-w-none max-h-64 overflow-y-auto">
|
136 |
<!-- Le contenu du processus de pensée sera injecté ici -->
|
137 |
</div>
|
138 |
</details>
|
139 |
</div>
|
140 |
|
141 |
<!-- Response Section -->
|
142 |
-
<div id="response" class="hidden mt-6">
|
143 |
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6 sm:p-8 prose prose-violet max-w-none">
|
144 |
<!-- Le contenu de la réponse sera injecté ici -->
|
145 |
</div>
|
@@ -182,6 +347,49 @@ $(document).ready(function() {
|
|
182 |
moment.locale('fr');
|
183 |
const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000, timerProgressBar: true });
|
184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
// --- Gestion de l'interface ---
|
186 |
$('#type-select').change(function() {
|
187 |
const type = $(this).val();
|
@@ -210,17 +418,21 @@ $(document).ready(function() {
|
|
210 |
}
|
211 |
});
|
212 |
|
213 |
-
// --- Logique de Génération en Streaming ---
|
214 |
async function handleStreamedGeneration(url, options) {
|
215 |
Swal.fire({ title: 'Génération en cours...', html: 'Connexion au service IA...', allowOutsideClick: false, showConfirmButton: false, didOpen: () => Swal.showLoading() });
|
216 |
|
217 |
$('#thinking-wrapper, #response, #action-buttons').addClass('hidden');
|
218 |
-
$('#thinking-container').prop('open', false);
|
219 |
const thinkingDiv = $('#thinking-process');
|
220 |
const responseDiv = $('#response > div');
|
221 |
thinkingDiv.html('');
|
222 |
responseDiv.html('');
|
223 |
let fullResponseText = '', fullThinkingText = '', firstChunkReceived = false;
|
|
|
|
|
|
|
|
|
224 |
|
225 |
try {
|
226 |
const response = await fetch(url, options);
|
@@ -241,25 +453,55 @@ $(document).ready(function() {
|
|
241 |
buffer += decoder.decode(value, { stream: true });
|
242 |
const lines = buffer.split('\n');
|
243 |
buffer = lines.pop();
|
|
|
|
|
244 |
|
245 |
for (const line of lines) {
|
246 |
if (line.trim() === '') continue;
|
247 |
try {
|
248 |
const data = JSON.parse(line.trim());
|
|
|
|
|
249 |
if (data.type === 'thought') {
|
250 |
-
|
|
|
|
|
251 |
fullThinkingText += data.content;
|
252 |
-
|
253 |
} else if (data.type === 'answer') {
|
254 |
-
|
|
|
|
|
255 |
fullResponseText += data.content;
|
256 |
-
|
257 |
} else if (data.type === 'error') {
|
258 |
throw new Error(data.content);
|
259 |
}
|
260 |
-
} catch (e) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
}
|
262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
}
|
264 |
|
265 |
$('#action-buttons').removeClass('hidden').addClass('animate-fadeIn');
|
@@ -273,6 +515,9 @@ $(document).ready(function() {
|
|
273 |
title = $('#question').val().trim();
|
274 |
}
|
275 |
saveDissertation(title, fullResponseText);
|
|
|
|
|
|
|
276 |
|
277 |
} catch (error) {
|
278 |
Swal.fire({ icon: 'error', title: 'Erreur', text: error.message || "Une erreur inconnue est survenue." });
|
@@ -355,7 +600,7 @@ $(document).ready(function() {
|
|
355 |
</div>
|
356 |
</button>
|
357 |
<div class="content prose max-w-none border-t border-gray-200">
|
358 |
-
<div class="inner-content p-4"></div>
|
359 |
<div class="p-4 border-t border-gray-200 bg-gray-50 rounded-b-xl">
|
360 |
<button class="delete-btn text-sm text-red-600 hover:text-red-800 font-medium" data-index="${index}">Supprimer</button>
|
361 |
</div>
|
@@ -367,8 +612,23 @@ $(document).ready(function() {
|
|
367 |
});
|
368 |
}
|
369 |
|
|
|
370 |
$('#dissertations-list').on('click', '.collapsible', function() {
|
371 |
-
$(this).next('.content')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
372 |
$(this).toggleClass("active");
|
373 |
});
|
374 |
|
@@ -389,6 +649,51 @@ $(document).ready(function() {
|
|
389 |
});
|
390 |
});
|
391 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
392 |
// Init
|
393 |
updateSavedDissertationsList();
|
394 |
});
|
|
|
16 |
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
17 |
<style>
|
18 |
/* Styles pour le Glow Up */
|
19 |
+
:root {
|
20 |
+
font-family: 'Inter', sans-serif;
|
21 |
+
/* Variables pour des transitions plus fluides */
|
22 |
+
--transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
23 |
+
--transition-fast: all 0.15s ease-out;
|
24 |
+
}
|
25 |
+
|
26 |
+
/* Optimisations pour le scroll fluide */
|
27 |
+
html {
|
28 |
+
scroll-behavior: smooth;
|
29 |
+
-webkit-overflow-scrolling: touch;
|
30 |
+
}
|
31 |
|
32 |
+
body {
|
33 |
+
/* Prévenir le reflow lors de la génération */
|
34 |
+
will-change: scroll-position;
|
35 |
+
/* Améliorer les performances sur mobile */
|
36 |
+
-webkit-font-smoothing: antialiased;
|
37 |
+
-moz-osx-font-smoothing: grayscale;
|
38 |
+
}
|
39 |
+
|
40 |
+
.collapsible {
|
41 |
+
cursor: pointer;
|
42 |
+
padding: 1rem;
|
43 |
+
width: 100%;
|
44 |
+
border: none;
|
45 |
+
text-align: left;
|
46 |
+
outline: none;
|
47 |
+
transition: var(--transition-fast);
|
48 |
+
/* Optimiser pour les interactions tactiles */
|
49 |
+
touch-action: manipulation;
|
50 |
+
-webkit-tap-highlight-color: transparent;
|
51 |
+
}
|
52 |
+
|
53 |
+
.collapsible:hover {
|
54 |
+
background-color: #f9fafb;
|
55 |
+
}
|
56 |
+
|
57 |
+
.content {
|
58 |
+
padding: 0 1rem;
|
59 |
+
display: none;
|
60 |
+
overflow: hidden;
|
61 |
+
background-color: white;
|
62 |
+
/* Transition plus fluide pour l'ouverture */
|
63 |
+
transition: var(--transition-smooth);
|
64 |
+
}
|
65 |
|
66 |
/* Styles pour la lisibilité du Markdown généré */
|
67 |
+
.prose {
|
68 |
+
max-width: 100% !important;
|
69 |
+
/* Optimiser le rendu du texte */
|
70 |
+
text-rendering: optimizeLegibility;
|
71 |
+
}
|
72 |
|
73 |
+
#response .prose {
|
74 |
+
color: #374151;
|
75 |
+
word-wrap: break-word;
|
76 |
+
overflow-wrap: break-word;
|
77 |
+
/* Prévenir les débordements sur mobile */
|
78 |
+
hyphens: auto;
|
79 |
+
-webkit-hyphens: auto;
|
80 |
+
-moz-hyphens: auto;
|
81 |
+
}
|
82 |
+
|
83 |
+
.prose p, .prose ul, .prose ol, .prose li {
|
84 |
+
line-height: 1.75;
|
85 |
+
}
|
86 |
+
|
87 |
+
.prose h1, .prose h2, .prose h3 {
|
88 |
+
margin-top: 1.5em;
|
89 |
+
margin-bottom: 0.8em;
|
90 |
+
line-height: 1.3;
|
91 |
+
}
|
92 |
+
|
93 |
+
/* Animation fadeIn optimisée */
|
94 |
+
.animate-fadeIn {
|
95 |
+
animation: fadeIn 0.4s ease-out forwards;
|
96 |
+
/* Utiliser GPU pour l'animation */
|
97 |
+
transform: translateZ(0);
|
98 |
+
will-change: opacity, transform;
|
99 |
+
}
|
100 |
+
|
101 |
+
@keyframes fadeIn {
|
102 |
+
from {
|
103 |
+
opacity: 0;
|
104 |
+
transform: translateY(15px) translateZ(0);
|
105 |
+
}
|
106 |
+
to {
|
107 |
+
opacity: 1;
|
108 |
+
transform: translateY(0) translateZ(0);
|
109 |
+
}
|
110 |
+
}
|
111 |
|
112 |
/* Styles pour Select2 */
|
113 |
+
.select2-container--default .select2-selection--single {
|
114 |
+
border: 1px solid #d1d5db;
|
115 |
+
border-radius: 0.75rem;
|
116 |
+
height: auto;
|
117 |
+
padding: 0.75rem 1rem;
|
118 |
+
background-color: white;
|
119 |
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
120 |
+
}
|
121 |
+
|
122 |
+
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
123 |
+
color: #111827;
|
124 |
+
line-height: inherit;
|
125 |
+
padding-right: 1.5rem;
|
126 |
+
}
|
127 |
+
|
128 |
+
.select2-results__option .course-author {
|
129 |
+
font-size: 0.875rem;
|
130 |
+
color: #6b7280;
|
131 |
+
display: block;
|
132 |
+
margin-top: 0.1rem;
|
133 |
+
}
|
134 |
+
|
135 |
+
.select2-dropdown {
|
136 |
+
border-radius: 0.75rem;
|
137 |
+
border: 1px solid #d1d5db;
|
138 |
+
box-shadow: 0 4px 6px -1px rgba(0,0,0,.1);
|
139 |
+
}
|
140 |
|
141 |
/* Styles pour l'aperçu de l'image */
|
142 |
+
#image-preview {
|
143 |
+
max-height: 200px;
|
144 |
+
border-radius: 0.75rem;
|
145 |
+
box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
|
146 |
+
}
|
147 |
|
148 |
/* Cacher le marqueur par défaut de <details> */
|
149 |
+
summary {
|
150 |
+
list-style: none;
|
151 |
+
}
|
152 |
+
|
153 |
+
summary::-webkit-details-marker {
|
154 |
+
display: none;
|
155 |
+
}
|
156 |
+
|
157 |
+
/* Optimisations mobiles */
|
158 |
+
@media (max-width: 640px) {
|
159 |
+
/* Réduire les marges sur mobile pour plus d'espace */
|
160 |
+
.max-w-3xl {
|
161 |
+
max-width: 100%;
|
162 |
+
margin-left: 0.5rem;
|
163 |
+
margin-right: 0.5rem;
|
164 |
+
}
|
165 |
+
|
166 |
+
/* Optimiser l'affichage des sections de contenu */
|
167 |
+
#response, #thinking-wrapper {
|
168 |
+
/* Éviter les débordements horizontaux */
|
169 |
+
overflow-x: hidden;
|
170 |
+
}
|
171 |
+
|
172 |
+
/* Améliorer la lisibilité du texte généré */
|
173 |
+
.prose {
|
174 |
+
font-size: 0.95rem;
|
175 |
+
line-height: 1.6;
|
176 |
+
}
|
177 |
+
|
178 |
+
/* Réduire l'animation pour économiser la batterie */
|
179 |
+
.animate-fadeIn {
|
180 |
+
animation-duration: 0.2s;
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
/* Conteneur de génération avec scroll optimisé */
|
185 |
+
.generation-container {
|
186 |
+
/* Conteneur stable pour éviter les recalculs de layout */
|
187 |
+
contain: layout style;
|
188 |
+
/* Optimiser les performances de scroll */
|
189 |
+
transform: translateZ(0);
|
190 |
+
}
|
191 |
+
|
192 |
+
/* Améliorer les performances du textarea */
|
193 |
+
textarea {
|
194 |
+
/* Éviter les reflows pendant la saisie */
|
195 |
+
resize: none;
|
196 |
+
/* Optimiser sur mobile */
|
197 |
+
-webkit-appearance: none;
|
198 |
+
}
|
199 |
+
|
200 |
+
/* Optimiser les boutons pour le tactile */
|
201 |
+
button {
|
202 |
+
touch-action: manipulation;
|
203 |
+
-webkit-tap-highlight-color: transparent;
|
204 |
+
transition: var(--transition-fast);
|
205 |
+
}
|
206 |
+
|
207 |
+
/* Scroll fluide pour les éléments avec beaucoup de contenu */
|
208 |
+
.content-scrollable {
|
209 |
+
-webkit-overflow-scrolling: touch;
|
210 |
+
scroll-behavior: smooth;
|
211 |
+
}
|
212 |
</style>
|
213 |
</head>
|
214 |
<body class="bg-gray-50 text-gray-900">
|
|
|
289 |
</div>
|
290 |
|
291 |
<!-- Thinking Process Section (Collapsible) -->
|
292 |
+
<div id="thinking-wrapper" class="hidden mt-8 generation-container">
|
293 |
<details id="thinking-container" class="bg-white border border-gray-200 rounded-xl shadow-sm">
|
294 |
<summary class="flex justify-between items-center p-4 cursor-pointer">
|
295 |
<h3 class="text-md font-semibold text-gray-700">Processus de pensée de l'IA</h3>
|
|
|
297 |
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
298 |
</svg>
|
299 |
</summary>
|
300 |
+
<div id="thinking-process" class="p-4 border-t border-gray-200 text-sm text-gray-600 prose prose-sm max-w-none max-h-64 overflow-y-auto content-scrollable">
|
301 |
<!-- Le contenu du processus de pensée sera injecté ici -->
|
302 |
</div>
|
303 |
</details>
|
304 |
</div>
|
305 |
|
306 |
<!-- Response Section -->
|
307 |
+
<div id="response" class="hidden mt-6 generation-container">
|
308 |
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6 sm:p-8 prose prose-violet max-w-none">
|
309 |
<!-- Le contenu de la réponse sera injecté ici -->
|
310 |
</div>
|
|
|
347 |
moment.locale('fr');
|
348 |
const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000, timerProgressBar: true });
|
349 |
|
350 |
+
// Variables pour optimiser le scroll
|
351 |
+
let isScrolling = false;
|
352 |
+
let scrollTimer = null;
|
353 |
+
let lastScrollTime = 0;
|
354 |
+
|
355 |
+
// Fonction de scroll optimisée avec throttling
|
356 |
+
function smoothScrollToBottom(force = false) {
|
357 |
+
const now = Date.now();
|
358 |
+
|
359 |
+
// Throttling : éviter trop d'appels de scroll
|
360 |
+
if (!force && now - lastScrollTime < 100) {
|
361 |
+
return;
|
362 |
+
}
|
363 |
+
|
364 |
+
lastScrollTime = now;
|
365 |
+
|
366 |
+
// Annuler le timer précédent s'il existe
|
367 |
+
if (scrollTimer) {
|
368 |
+
clearTimeout(scrollTimer);
|
369 |
+
}
|
370 |
+
|
371 |
+
// Utiliser requestAnimationFrame pour un scroll plus fluide
|
372 |
+
if (!isScrolling) {
|
373 |
+
isScrolling = true;
|
374 |
+
|
375 |
+
requestAnimationFrame(() => {
|
376 |
+
// Scroll fluide vers le bas avec une marge
|
377 |
+
const targetScrollTop = Math.max(0, document.documentElement.scrollHeight - window.innerHeight - 50);
|
378 |
+
|
379 |
+
// Utiliser la méthode native pour de meilleures performances
|
380 |
+
window.scrollTo({
|
381 |
+
top: targetScrollTop,
|
382 |
+
behavior: 'smooth'
|
383 |
+
});
|
384 |
+
|
385 |
+
// Marquer comme terminé après l'animation
|
386 |
+
scrollTimer = setTimeout(() => {
|
387 |
+
isScrolling = false;
|
388 |
+
}, 200);
|
389 |
+
});
|
390 |
+
}
|
391 |
+
}
|
392 |
+
|
393 |
// --- Gestion de l'interface ---
|
394 |
$('#type-select').change(function() {
|
395 |
const type = $(this).val();
|
|
|
418 |
}
|
419 |
});
|
420 |
|
421 |
+
// --- Logique de Génération en Streaming Optimisée ---
|
422 |
async function handleStreamedGeneration(url, options) {
|
423 |
Swal.fire({ title: 'Génération en cours...', html: 'Connexion au service IA...', allowOutsideClick: false, showConfirmButton: false, didOpen: () => Swal.showLoading() });
|
424 |
|
425 |
$('#thinking-wrapper, #response, #action-buttons').addClass('hidden');
|
426 |
+
$('#thinking-container').prop('open', false);
|
427 |
const thinkingDiv = $('#thinking-process');
|
428 |
const responseDiv = $('#response > div');
|
429 |
thinkingDiv.html('');
|
430 |
responseDiv.html('');
|
431 |
let fullResponseText = '', fullThinkingText = '', firstChunkReceived = false;
|
432 |
+
|
433 |
+
// Compteur pour optimiser les updates
|
434 |
+
let chunkCount = 0;
|
435 |
+
const updateFrequency = 3; // Mettre à jour tous les 3 chunks pour réduire les recalculs
|
436 |
|
437 |
try {
|
438 |
const response = await fetch(url, options);
|
|
|
453 |
buffer += decoder.decode(value, { stream: true });
|
454 |
const lines = buffer.split('\n');
|
455 |
buffer = lines.pop();
|
456 |
+
|
457 |
+
let shouldUpdate = false;
|
458 |
|
459 |
for (const line of lines) {
|
460 |
if (line.trim() === '') continue;
|
461 |
try {
|
462 |
const data = JSON.parse(line.trim());
|
463 |
+
chunkCount++;
|
464 |
+
|
465 |
if (data.type === 'thought') {
|
466 |
+
if (!$('#thinking-wrapper').is(':visible')) {
|
467 |
+
$('#thinking-wrapper').removeClass('hidden').addClass('animate-fadeIn');
|
468 |
+
}
|
469 |
fullThinkingText += data.content;
|
470 |
+
shouldUpdate = true;
|
471 |
} else if (data.type === 'answer') {
|
472 |
+
if (!$('#response').is(':visible')) {
|
473 |
+
$('#response').removeClass('hidden').addClass('animate-fadeIn');
|
474 |
+
}
|
475 |
fullResponseText += data.content;
|
476 |
+
shouldUpdate = true;
|
477 |
} else if (data.type === 'error') {
|
478 |
throw new Error(data.content);
|
479 |
}
|
480 |
+
} catch (e) {
|
481 |
+
console.error("Erreur JSON parse:", line, e);
|
482 |
+
}
|
483 |
+
}
|
484 |
+
|
485 |
+
// Mettre à jour le DOM moins fréquemment pour de meilleures performances
|
486 |
+
if (shouldUpdate && (chunkCount % updateFrequency === 0 || done)) {
|
487 |
+
if (fullThinkingText) {
|
488 |
+
thinkingDiv.html(marked.parse(fullThinkingText));
|
489 |
+
}
|
490 |
+
if (fullResponseText) {
|
491 |
+
responseDiv.html(marked.parse(fullResponseText));
|
492 |
+
}
|
493 |
+
|
494 |
+
// Scroll optimisé vers le bas
|
495 |
+
smoothScrollToBottom();
|
496 |
}
|
497 |
+
}
|
498 |
+
|
499 |
+
// Mise à jour finale
|
500 |
+
if (fullThinkingText) {
|
501 |
+
thinkingDiv.html(marked.parse(fullThinkingText));
|
502 |
+
}
|
503 |
+
if (fullResponseText) {
|
504 |
+
responseDiv.html(marked.parse(fullResponseText));
|
505 |
}
|
506 |
|
507 |
$('#action-buttons').removeClass('hidden').addClass('animate-fadeIn');
|
|
|
515 |
title = $('#question').val().trim();
|
516 |
}
|
517 |
saveDissertation(title, fullResponseText);
|
518 |
+
|
519 |
+
// Scroll final pour s'assurer que tout est visible
|
520 |
+
smoothScrollToBottom(true);
|
521 |
|
522 |
} catch (error) {
|
523 |
Swal.fire({ icon: 'error', title: 'Erreur', text: error.message || "Une erreur inconnue est survenue." });
|
|
|
600 |
</div>
|
601 |
</button>
|
602 |
<div class="content prose max-w-none border-t border-gray-200">
|
603 |
+
<div class="inner-content p-4 content-scrollable"></div>
|
604 |
<div class="p-4 border-t border-gray-200 bg-gray-50 rounded-b-xl">
|
605 |
<button class="delete-btn text-sm text-red-600 hover:text-red-800 font-medium" data-index="${index}">Supprimer</button>
|
606 |
</div>
|
|
|
612 |
});
|
613 |
}
|
614 |
|
615 |
+
// Optimiser l'ouverture des dissertations avec une transition plus fluide
|
616 |
$('#dissertations-list').on('click', '.collapsible', function() {
|
617 |
+
const content = $(this).next('.content');
|
618 |
+
const isVisible = content.is(':visible');
|
619 |
+
|
620 |
+
// Animation plus fluide avec easing
|
621 |
+
content.stop(true, true).slideToggle({
|
622 |
+
duration: 300,
|
623 |
+
easing: 'swing',
|
624 |
+
start: function() {
|
625 |
+
$(this).css('overflow', 'hidden');
|
626 |
+
},
|
627 |
+
complete: function() {
|
628 |
+
$(this).css('overflow', isVisible ? 'hidden' : 'visible');
|
629 |
+
}
|
630 |
+
});
|
631 |
+
|
632 |
$(this).toggleClass("active");
|
633 |
});
|
634 |
|
|
|
649 |
});
|
650 |
});
|
651 |
|
652 |
+
// Optimisation pour les événements de scroll sur mobile
|
653 |
+
let ticking = false;
|
654 |
+
|
655 |
+
function updateScrollPosition() {
|
656 |
+
// Code pour gérer les changements de position de scroll si nécessaire
|
657 |
+
ticking = false;
|
658 |
+
}
|
659 |
+
|
660 |
+
window.addEventListener('scroll', function() {
|
661 |
+
if (!ticking) {
|
662 |
+
requestAnimationFrame(updateScrollPosition);
|
663 |
+
ticking = true;
|
664 |
+
}
|
665 |
+
}, { passive: true });
|
666 |
+
|
667 |
+
// Optimisation du resize pour mobile
|
668 |
+
let resizeTimer;
|
669 |
+
window.addEventListener('resize', function() {
|
670 |
+
clearTimeout(resizeTimer);
|
671 |
+
resizeTimer = setTimeout(function() {
|
672 |
+
// Recalculer les dimensions si nécessaire
|
673 |
+
if (window.innerWidth <= 640) {
|
674 |
+
// Optimisations spécifiques mobile
|
675 |
+
$('body').addClass('mobile-optimized');
|
676 |
+
} else {
|
677 |
+
$('body').removeClass('mobile-optimized');
|
678 |
+
}
|
679 |
+
}, 250);
|
680 |
+
}, { passive: true });
|
681 |
+
|
682 |
+
// Optimisation tactile pour mobile
|
683 |
+
if ('ontouchstart' in window) {
|
684 |
+
$('body').addClass('touch-device');
|
685 |
+
|
686 |
+
// Améliorer les interactions tactiles
|
687 |
+
$(document).on('touchstart', 'button, .collapsible', function() {
|
688 |
+
$(this).addClass('touch-active');
|
689 |
+
});
|
690 |
+
|
691 |
+
$(document).on('touchend', 'button, .collapsible', function() {
|
692 |
+
const element = $(this);
|
693 |
+
setTimeout(() => element.removeClass('touch-active'), 150);
|
694 |
+
});
|
695 |
+
}
|
696 |
+
|
697 |
// Init
|
698 |
updateSavedDissertationsList();
|
699 |
});
|