Pepguy commited on
Commit
5c5066e
·
verified ·
1 Parent(s): eee307e

Update public/index.html

Browse files
Files changed (1) hide show
  1. public/index.html +53 -12
public/index.html CHANGED
@@ -125,10 +125,14 @@
125
  </main>
126
 
127
  <script>
 
 
 
128
  marked.setOptions({
129
  highlight: function(code, lang) {
 
130
  const language = hljs.getLanguage(lang) ? lang : 'plaintext';
131
- return hljs.highlight(code, { language }).value;
132
  }
133
  });
134
 
@@ -293,7 +297,7 @@
293
 
294
  function renderMessages(messages) {
295
  const container = document.getElementById('chat-window');
296
- const isScrolledToBottom = container.scrollHeight - container.clientHeight <= container.scrollTop + 20;
297
 
298
  container.innerHTML = messages.map(m => {
299
  let html = '';
@@ -328,7 +332,8 @@
328
  }
329
  });
330
 
331
- if (isScrolledToBottom) scrollToBottom();
 
332
  }
333
 
334
  function pollGeneratingChat(id) {
@@ -419,6 +424,9 @@
419
  const decoder = new TextDecoder("utf-8");
420
  let aiContent = "";
421
  let aiReasoning = "";
 
 
 
422
 
423
  while (true) {
424
  const { value, done } = await reader.read();
@@ -450,17 +458,50 @@
450
  }
451
  }
452
 
453
- let tempHtml = "";
454
- if (aiReasoning) tempHtml += `<div class="reasoning-block"><i>Thinking Process</i><br/>${marked.parse(aiReasoning)}</div>`;
455
- if (aiContent) tempHtml += DOMPurify.sanitize(marked.parse(aiContent));
456
-
457
- document.getElementById('temp-ai-msg').innerHTML = tempHtml || "<span class='animate-pulse text-gray-400'>Thinking...</span>";
458
-
459
- const distanceToBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
460
- if (distanceToBottom < 100) scrollToBottom();
 
 
 
 
 
461
  }
462
 
463
- selectChat(currentChatId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
464
 
465
  } catch (error) {
466
  console.error(error);
 
125
  </main>
126
 
127
  <script>
128
+ // NEW FEATURE: Toggle high-cost rendering during stream to prevent memory crashes
129
+ let enableHighlighting = true;
130
+
131
  marked.setOptions({
132
  highlight: function(code, lang) {
133
+ if (!enableHighlighting) return code; // Skip highlighting while streaming!
134
  const language = hljs.getLanguage(lang) ? lang : 'plaintext';
135
+ try { return hljs.highlight(code, { language }).value; } catch(e) { return code; }
136
  }
137
  });
138
 
 
297
 
298
  function renderMessages(messages) {
299
  const container = document.getElementById('chat-window');
300
+ const isScrolledToBottom = container.scrollHeight - container.clientHeight <= container.scrollTop + 50;
301
 
302
  container.innerHTML = messages.map(m => {
303
  let html = '';
 
332
  }
333
  });
334
 
335
+ // Prevent unwanted jump to bottom if chat is empty or user scrolled up
336
+ if (isScrolledToBottom && messages.length > 0) scrollToBottom();
337
  }
338
 
339
  function pollGeneratingChat(id) {
 
424
  const decoder = new TextDecoder("utf-8");
425
  let aiContent = "";
426
  let aiReasoning = "";
427
+
428
+ enableHighlighting = false; // SPEED UP: Disable expensive highlighting during stream
429
+ let lastRenderTime = Date.now();
430
 
431
  while (true) {
432
  const { value, done } = await reader.read();
 
458
  }
459
  }
460
 
461
+ // THROTTLE RENDER: Only update DOM max 5 times a second to prevent memory crashes
462
+ if (Date.now() - lastRenderTime > 200) {
463
+ let tempHtml = "";
464
+ if (aiReasoning) tempHtml += `<div class="reasoning-block"><i>Thinking Process</i><br/>${marked.parse(aiReasoning)}</div>`;
465
+ if (aiContent) tempHtml += DOMPurify.sanitize(marked.parse(aiContent));
466
+
467
+ document.getElementById('temp-ai-msg').innerHTML = tempHtml || "<span class='animate-pulse text-gray-400'>Thinking...</span>";
468
+
469
+ const distanceToBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
470
+ if (distanceToBottom < 100) scrollToBottom();
471
+
472
+ lastRenderTime = Date.now();
473
+ }
474
  }
475
 
476
+ // FINAL RENDER: Stream is complete, turn highlighting back on and do a final pristine render
477
+ enableHighlighting = true;
478
+
479
+ let finalHtml = "";
480
+ if (aiReasoning) finalHtml += `<div class="reasoning-block"><i>Thinking Process</i><br/>${marked.parse(aiReasoning)}</div>`;
481
+ if (aiContent) finalHtml += DOMPurify.sanitize(marked.parse(aiContent));
482
+
483
+ const finalMsgElement = document.getElementById('temp-ai-msg');
484
+ finalMsgElement.innerHTML = finalHtml || "Done.";
485
+ finalMsgElement.removeAttribute('id'); // Remove ID so we don't accidentally overwrite it
486
+
487
+ // Attach copy buttons explicitly since we aren't calling renderMessages()
488
+ finalMsgElement.querySelectorAll('pre').forEach(pre => {
489
+ if (!pre.querySelector('.copy-btn')) {
490
+ const btn = document.createElement('button');
491
+ btn.className = 'copy-btn';
492
+ btn.innerText = 'Copy';
493
+ btn.onclick = () => {
494
+ const codeText = pre.querySelector('code')?.innerText || pre.innerText.replace('Copy', '');
495
+ navigator.clipboard.writeText(codeText.trim());
496
+ btn.innerText = 'Copied!';
497
+ setTimeout(() => btn.innerText = 'Copy', 2000);
498
+ };
499
+ pre.appendChild(btn);
500
+ }
501
+ });
502
+
503
+ scrollToBottom();
504
+ loadSidebar(); // Sync sidebar updates but PREVENT wiping the main chat DOM
505
 
506
  } catch (error) {
507
  console.error(error);