wop commited on
Commit
dfd08ac
Β·
verified Β·
1 Parent(s): 5945c09

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +121 -56
templates/index.html CHANGED
@@ -389,13 +389,12 @@
389
  }
390
 
391
  /* ── Markdown Elements ── */
392
- .bubble p, .best-answer-bubble p, .other-answer-text p, .version-text p { margin: 3px 0; white-space: normal; }
393
 
394
  .bubble h1, .bubble h2, .bubble h3, .bubble h4, .bubble h5, .bubble h6,
395
  .best-answer-bubble h1, .best-answer-bubble h2, .best-answer-bubble h3,
396
  .best-answer-bubble h4, .best-answer-bubble h5, .best-answer-bubble h6,
397
- .other-answer-text h1, .other-answer-text h2, .other-answer-text h3,
398
- .version-text h1, .version-text h2, .version-text h3 {
399
  line-height: 1.3; margin: 8px 0 3px; white-space: normal;
400
  }
401
  .bubble h1, .best-answer-bubble h1 { font-size: 1.35em; font-weight: 800; }
@@ -406,10 +405,10 @@
406
  .bubble h6, .best-answer-bubble h6 { font-size: .88em; font-weight: 700; }
407
 
408
  .bubble ul, .bubble ol, .best-answer-bubble ul, .best-answer-bubble ol,
409
- .other-answer-text ul, .other-answer-text ol, .version-text ul, .version-text ol {
410
  margin: 3px 0 3px 18px; padding: 0; white-space: normal;
411
  }
412
- .bubble li, .best-answer-bubble li, .other-answer-text li, .version-text li { margin: 1px 0; white-space: normal; }
413
 
414
  /* Task lists */
415
  .task-item { list-style: none; margin-left: -18px; }
@@ -420,7 +419,7 @@
420
  cursor: default;
421
  }
422
 
423
- .bubble code, .best-answer-bubble code, .other-answer-text code, .version-text code {
424
  font-family: var(--mono); font-size: .87em;
425
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.1);
426
  border-radius: var(--radius-xs); padding: 1px 5px;
@@ -430,18 +429,18 @@
430
  .code-block-wrapper {
431
  position: relative; margin: 6px 0;
432
  }
433
- .bubble pre, .best-answer-bubble pre, .other-answer-text pre, .version-text pre {
434
  background: rgba(0,0,0,.38); border: 1px solid var(--border);
435
  border-radius: var(--radius-sm); padding: 10px 12px;
436
  overflow-x: auto; white-space: pre;
437
  font-family: var(--mono); font-size: .84em; line-height: 1.5;
438
  margin: 0;
439
  }
440
- .bubble pre code, .best-answer-bubble pre code, .other-answer-text pre code, .version-text pre code {
441
  background: none; border: none; padding: 0; font-size: inherit;
442
  }
443
  .code-lang-label {
444
- position: absolute; top: 0; right: 32px;
445
  background: rgba(255,255,255,.06);
446
  border-radius: 0 0 var(--radius-xs) var(--radius-xs);
447
  padding: 2px 8px;
@@ -466,17 +465,8 @@
466
  .copy-code-btn:hover { color: var(--text); border-color: rgba(108,131,255,.4); }
467
  .copy-code-btn.copied { color: var(--good); border-color: rgba(45,212,191,.4); opacity: 1; }
468
 
469
- /* Syntax highlight tokens */
470
- .tok-kw { color: #c792ea; }
471
- .tok-str { color: #c3e88d; }
472
- .tok-num { color: #f78c6c; }
473
- .tok-cmt { color: #546e7a; font-style: italic; }
474
- .tok-fn { color: #82aaff; }
475
- .tok-op { color: #89ddff; }
476
- .tok-cls { color: #ffcb6b; }
477
-
478
  .bubble blockquote, .best-answer-bubble blockquote,
479
- .other-answer-text blockquote, .version-text blockquote {
480
  border-left: 3px solid var(--accent);
481
  background: rgba(124,166,255,.04);
482
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
@@ -485,20 +475,19 @@
485
  font-style: italic;
486
  }
487
  .bubble hr, .best-answer-bubble hr { border: none; border-top: 1px solid var(--border2); margin: 8px 0; }
488
- .bubble a, .best-answer-bubble a, .other-answer-text a, .version-text a {
489
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
490
  }
491
  .bubble a[href^="http"]::after,
492
  .best-answer-bubble a[href^="http"]::after {
493
  content: " β†—"; font-size: .75em; opacity: .5;
494
  }
495
- .bubble table, .best-answer-bubble table, .other-answer-text table, .version-text table {
496
  border-collapse: collapse; width: 100%; margin: 8px 0; font-size: 13px; white-space: normal;
497
  }
498
  .bubble th, .bubble td,
499
  .best-answer-bubble th, .best-answer-bubble td,
500
- .other-answer-text th, .other-answer-text td,
501
- .version-text th, .version-text td {
502
  border: 1px solid var(--border2); padding: 6px 10px; text-align: left;
503
  }
504
  .bubble th, .best-answer-bubble th { background: rgba(255,255,255,.05); font-weight: 600; }
@@ -568,22 +557,6 @@
568
  }
569
  .action-btn:hover { border-color: rgba(108,131,255,.35); color: var(--text); background: rgba(108,131,255,.05); }
570
 
571
- /* Card loading shimmer */
572
- .card-loading { position: relative; overflow: hidden; }
573
- .card-loading::after {
574
- content: "";
575
- position: absolute; inset: 0;
576
- background: linear-gradient(90deg, transparent, rgba(108,131,255,.05), transparent);
577
- background-size: 200% 100%;
578
- animation: shimmer 1.5s ease infinite;
579
- border-radius: inherit;
580
- pointer-events: none;
581
- }
582
- @keyframes shimmer {
583
- from { background-position: 200% 0; }
584
- to { background-position: -200% 0; }
585
- }
586
-
587
  /* ── Write answer inline panel ── */
588
  .write-answer-btn {
589
  border: 1px solid rgba(45,212,191,.3);
@@ -696,13 +669,6 @@
696
  .other-answer-card.related {
697
  background: linear-gradient(180deg, rgba(108,131,255,.05), rgba(255,255,255,.02));
698
  border-color: rgba(108,131,255,.16);
699
- opacity: .9;
700
- }
701
- .other-answer-card.related::after {
702
- content: "From similar question";
703
- position: absolute; top: 8px; right: 10px;
704
- font-size: 9px; color: var(--accent);
705
- font-family: var(--mono); pointer-events: none;
706
  }
707
  .other-answer-head {
708
  display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
@@ -710,6 +676,55 @@
710
  }
711
  .other-answer-text { font-size: 13px; line-height: 1.6; white-space: pre-wrap; word-break: break-word; }
712
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
  /* ── Versions ── */
714
  .versions-toggle {
715
  margin-top: var(--space-1); color: var(--muted); font-size: 10px;
@@ -735,7 +750,6 @@
735
  font-size: 10px; color: var(--muted); font-family: var(--mono);
736
  display: flex; gap: 5px; flex-wrap: wrap; align-items: center; margin-bottom: var(--space-1);
737
  }
738
- .version-text { font-size: 12px; line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
739
 
740
  /* ── Propose version ── */
741
  .propose-panel {
@@ -1150,6 +1164,7 @@
1150
  .top-btn:focus-visible,
1151
  .vote-btn:focus-visible,
1152
  .action-btn:focus-visible,
 
1153
  .write-answer-btn:focus-visible,
1154
  .other-answers-toggle:focus-visible,
1155
  .related-toggle:focus-visible,
@@ -1180,7 +1195,7 @@
1180
  #jumpLatest { bottom: 120px; max-width: calc(100vw - 24px); white-space: nowrap; }
1181
  }
1182
  @media (pointer: coarse) {
1183
- .vote-btn, .action-btn, .versions-toggle, .other-answers-toggle,
1184
  .related-toggle, .write-answer-btn {
1185
  min-height: 44px; padding: 8px 14px;
1186
  }
@@ -1441,6 +1456,18 @@
1441
  }
1442
  function nl2br(s) { return esc(s).replace(/\n/g, '<br>'); }
1443
 
 
 
 
 
 
 
 
 
 
 
 
 
1444
  /* ═══════════════════════════════════════════════
1445
  SYNTAX HIGHLIGHTER (lightweight)
1446
  ═══════���═══════════════════════════════════════ */
@@ -1880,8 +1907,17 @@
1880
  <span>${relativeTime(v.created_at)}</span><span aria-hidden="true">Β·</span>
1881
  <span>${Number(v.votes || 0)} vote${Number(v.votes || 0) !== 1 ? 's' : ''}</span>
1882
  </div>
1883
- <div class="version-text">${renderMarkdown(v.text || '')}</div>
1884
- ${renderVoteRow(answer.id, v)}
 
 
 
 
 
 
 
 
 
1885
  </div>`).join('')}
1886
  </div>`;
1887
  }
@@ -1989,17 +2025,31 @@
1989
  <span class="arrow" aria-hidden="true">β–Ά</span> ${rel.length} related answer${rel.length > 1 ? 's' : ''}
1990
  </button>
1991
  <div class="related-panel" id="relatedPanel" role="region" aria-label="Related answers">
1992
- ${rel.map(r => `
 
 
1993
  <div class="other-answer-card related">
1994
  <div class="other-answer-head">
1995
  <span class="chip matched">related</span>
1996
- <span>${esc(r.question || '')}</span>
1997
- <span aria-hidden="true">Β·</span>
1998
  <span class="chip related-score">score ${Number(r.score || 0).toFixed(2)}</span>
1999
  </div>
2000
- <div class="other-answer-text">${renderMarkdown(r.answer || '')}</div>
2001
- </div>`).join('')}
2002
- <p class="related-note">Read-only answers from semantically similar questions β€” useful context, separate thread.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2003
  </div>
2004
  </div>`;
2005
  }
@@ -2181,6 +2231,13 @@
2181
  const voteBtn = e.target.closest('[data-vote]');
2182
  if (voteBtn) { await handleVote(voteBtn); return; }
2183
 
 
 
 
 
 
 
 
2184
  // Copy answer text
2185
  const copyAns = e.target.closest('[data-copy-answer]');
2186
  if (copyAns) { await handleCopyAnswer(copyAns); return; }
@@ -2341,6 +2398,14 @@
2341
  } catch { toast('Could not copy', 'bad'); }
2342
  }
2343
 
 
 
 
 
 
 
 
 
2344
  function handleToggleVersions(btn) {
2345
  const id = btn.getAttribute('data-toggle-versions');
2346
  const p = $('vp-' + id);
 
389
  }
390
 
391
  /* ── Markdown Elements ── */
392
+ .bubble p, .best-answer-bubble p, .other-answer-text p { margin: 3px 0; white-space: normal; }
393
 
394
  .bubble h1, .bubble h2, .bubble h3, .bubble h4, .bubble h5, .bubble h6,
395
  .best-answer-bubble h1, .best-answer-bubble h2, .best-answer-bubble h3,
396
  .best-answer-bubble h4, .best-answer-bubble h5, .best-answer-bubble h6,
397
+ .other-answer-text h1, .other-answer-text h2, .other-answer-text h3 {
 
398
  line-height: 1.3; margin: 8px 0 3px; white-space: normal;
399
  }
400
  .bubble h1, .best-answer-bubble h1 { font-size: 1.35em; font-weight: 800; }
 
405
  .bubble h6, .best-answer-bubble h6 { font-size: .88em; font-weight: 700; }
406
 
407
  .bubble ul, .bubble ol, .best-answer-bubble ul, .best-answer-bubble ol,
408
+ .other-answer-text ul, .other-answer-text ol {
409
  margin: 3px 0 3px 18px; padding: 0; white-space: normal;
410
  }
411
+ .bubble li, .best-answer-bubble li, .other-answer-text li { margin: 1px 0; white-space: normal; }
412
 
413
  /* Task lists */
414
  .task-item { list-style: none; margin-left: -18px; }
 
419
  cursor: default;
420
  }
421
 
422
+ .bubble code, .best-answer-bubble code, .other-answer-text code {
423
  font-family: var(--mono); font-size: .87em;
424
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.1);
425
  border-radius: var(--radius-xs); padding: 1px 5px;
 
429
  .code-block-wrapper {
430
  position: relative; margin: 6px 0;
431
  }
432
+ .bubble pre, .best-answer-bubble pre, .other-answer-text pre {
433
  background: rgba(0,0,0,.38); border: 1px solid var(--border);
434
  border-radius: var(--radius-sm); padding: 10px 12px;
435
  overflow-x: auto; white-space: pre;
436
  font-family: var(--mono); font-size: .84em; line-height: 1.5;
437
  margin: 0;
438
  }
439
+ .bubble pre code, .best-answer-bubble pre code, .other-answer-text pre code {
440
  background: none; border: none; padding: 0; font-size: inherit;
441
  }
442
  .code-lang-label {
443
+ position: absolute; top: 5px; left: 6px;
444
  background: rgba(255,255,255,.06);
445
  border-radius: 0 0 var(--radius-xs) var(--radius-xs);
446
  padding: 2px 8px;
 
465
  .copy-code-btn:hover { color: var(--text); border-color: rgba(108,131,255,.4); }
466
  .copy-code-btn.copied { color: var(--good); border-color: rgba(45,212,191,.4); opacity: 1; }
467
 
 
 
 
 
 
 
 
 
 
468
  .bubble blockquote, .best-answer-bubble blockquote,
469
+ .other-answer-text blockquote {
470
  border-left: 3px solid var(--accent);
471
  background: rgba(124,166,255,.04);
472
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
 
475
  font-style: italic;
476
  }
477
  .bubble hr, .best-answer-bubble hr { border: none; border-top: 1px solid var(--border2); margin: 8px 0; }
478
+ .bubble a, .best-answer-bubble a, .other-answer-text a {
479
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
480
  }
481
  .bubble a[href^="http"]::after,
482
  .best-answer-bubble a[href^="http"]::after {
483
  content: " β†—"; font-size: .75em; opacity: .5;
484
  }
485
+ .bubble table, .best-answer-bubble table, .other-answer-text table {
486
  border-collapse: collapse; width: 100%; margin: 8px 0; font-size: 13px; white-space: normal;
487
  }
488
  .bubble th, .bubble td,
489
  .best-answer-bubble th, .best-answer-bubble td,
490
+ .other-answer-text th, .other-answer-text td {
 
491
  border: 1px solid var(--border2); padding: 6px 10px; text-align: left;
492
  }
493
  .bubble th, .best-answer-bubble th { background: rgba(255,255,255,.05); font-weight: 600; }
 
557
  }
558
  .action-btn:hover { border-color: rgba(108,131,255,.35); color: var(--text); background: rgba(108,131,255,.05); }
559
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
  /* ── Write answer inline panel ── */
561
  .write-answer-btn {
562
  border: 1px solid rgba(45,212,191,.3);
 
669
  .other-answer-card.related {
670
  background: linear-gradient(180deg, rgba(108,131,255,.05), rgba(255,255,255,.02));
671
  border-color: rgba(108,131,255,.16);
 
 
 
 
 
 
 
672
  }
673
  .other-answer-head {
674
  display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
 
676
  }
677
  .other-answer-text { font-size: 13px; line-height: 1.6; white-space: pre-wrap; word-break: break-word; }
678
 
679
+ /* ── Preview lines (similar questions + versions) ── */
680
+ .preview-block {
681
+ display: flex; gap: 8px; align-items: flex-start;
682
+ margin-top: 6px;
683
+ }
684
+ .preview-label {
685
+ flex: 0 0 auto;
686
+ font-family: var(--mono); font-size: 9px;
687
+ color: var(--muted);
688
+ background: rgba(255,255,255,.04);
689
+ border: 1px solid var(--border);
690
+ border-radius: var(--radius-xs);
691
+ padding: 2px 6px; line-height: 1.3;
692
+ letter-spacing: .06em;
693
+ }
694
+ .preview-text {
695
+ flex: 1; min-width: 0;
696
+ font-size: 12.5px; line-height: 1.5;
697
+ color: var(--text);
698
+ display: -webkit-box;
699
+ -webkit-line-clamp: 3;
700
+ line-clamp: 3;
701
+ -webkit-box-orient: vertical;
702
+ overflow: hidden;
703
+ white-space: normal; word-break: break-word;
704
+ }
705
+ .preview-text.muted-preview { color: var(--muted); }
706
+ .preview-actions {
707
+ display: flex; align-items: center; gap: 6px;
708
+ margin-top: 8px; flex-wrap: wrap;
709
+ }
710
+ .preview-actions .vote-row { margin-top: 0; }
711
+
712
+ /* Ask button */
713
+ .ask-btn {
714
+ border: 1px solid rgba(108,131,255,.35);
715
+ background: rgba(108,131,255,.1);
716
+ color: var(--accent);
717
+ border-radius: var(--radius-sm);
718
+ padding: 4px 11px;
719
+ font: inherit; font-size: 11px; font-weight: 600;
720
+ cursor: pointer;
721
+ transition: border-color 160ms var(--ease-out), color 160ms var(--ease-out), background 160ms var(--ease-out), transform 160ms var(--ease-spring);
722
+ display: inline-flex; align-items: center; gap: 4px;
723
+ }
724
+ .ask-btn:hover { background: rgba(108,131,255,.2); border-color: rgba(108,131,255,.55); }
725
+ .ask-btn:active { transform: scale(.95); }
726
+ .ask-btn svg { width: 11px; height: 11px; }
727
+
728
  /* ── Versions ── */
729
  .versions-toggle {
730
  margin-top: var(--space-1); color: var(--muted); font-size: 10px;
 
750
  font-size: 10px; color: var(--muted); font-family: var(--mono);
751
  display: flex; gap: 5px; flex-wrap: wrap; align-items: center; margin-bottom: var(--space-1);
752
  }
 
753
 
754
  /* ── Propose version ── */
755
  .propose-panel {
 
1164
  .top-btn:focus-visible,
1165
  .vote-btn:focus-visible,
1166
  .action-btn:focus-visible,
1167
+ .ask-btn:focus-visible,
1168
  .write-answer-btn:focus-visible,
1169
  .other-answers-toggle:focus-visible,
1170
  .related-toggle:focus-visible,
 
1195
  #jumpLatest { bottom: 120px; max-width: calc(100vw - 24px); white-space: nowrap; }
1196
  }
1197
  @media (pointer: coarse) {
1198
+ .vote-btn, .action-btn, .ask-btn, .versions-toggle, .other-answers-toggle,
1199
  .related-toggle, .write-answer-btn {
1200
  min-height: 44px; padding: 8px 14px;
1201
  }
 
1456
  }
1457
  function nl2br(s) { return esc(s).replace(/\n/g, '<br>'); }
1458
 
1459
+ /* Strip markdown markers for clean inline previews */
1460
+ function previewText(s) {
1461
+ return String(s || '')
1462
+ .replace(/```[\s\S]*?```/g, ' [code] ')
1463
+ .replace(/!\[[^\]]*\]\([^)]*\)/g, ' [image] ')
1464
+ .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
1465
+ .replace(/^[#>\-*+]\s+/gm, '')
1466
+ .replace(/[*_~`]+/g, '')
1467
+ .replace(/\s+/g, ' ')
1468
+ .trim();
1469
+ }
1470
+
1471
  /* ═══════════════════════════════════════════════
1472
  SYNTAX HIGHLIGHTER (lightweight)
1473
  ═══════���═══════════════════════════════════════ */
 
1907
  <span>${relativeTime(v.created_at)}</span><span aria-hidden="true">Β·</span>
1908
  <span>${Number(v.votes || 0)} vote${Number(v.votes || 0) !== 1 ? 's' : ''}</span>
1909
  </div>
1910
+ <div class="preview-block">
1911
+ <span class="preview-label">A</span>
1912
+ <div class="preview-text">${esc(previewText(v.text || ''))}</div>
1913
+ </div>
1914
+ <div class="preview-actions">
1915
+ ${renderVoteRow(answer.id, v)}
1916
+ <button class="ask-btn" type="button" data-ask-current="1" aria-label="Ask this question again in a fresh conversation">
1917
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
1918
+ Ask
1919
+ </button>
1920
+ </div>
1921
  </div>`).join('')}
1922
  </div>`;
1923
  }
 
2025
  <span class="arrow" aria-hidden="true">β–Ά</span> ${rel.length} related answer${rel.length > 1 ? 's' : ''}
2026
  </button>
2027
  <div class="related-panel" id="relatedPanel" role="region" aria-label="Related answers">
2028
+ ${rel.map(r => {
2029
+ const q = String(r.question || '');
2030
+ return `
2031
  <div class="other-answer-card related">
2032
  <div class="other-answer-head">
2033
  <span class="chip matched">related</span>
 
 
2034
  <span class="chip related-score">score ${Number(r.score || 0).toFixed(2)}</span>
2035
  </div>
2036
+ <div class="preview-block">
2037
+ <span class="preview-label">Q</span>
2038
+ <div class="preview-text">${esc(previewText(q))}</div>
2039
+ </div>
2040
+ <div class="preview-block">
2041
+ <span class="preview-label">A</span>
2042
+ <div class="preview-text muted-preview">${esc(previewText(r.answer || ''))}</div>
2043
+ </div>
2044
+ <div class="preview-actions">
2045
+ <button class="ask-btn" type="button" data-ask-question="${esc(q)}" aria-label="Ask this question">
2046
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
2047
+ Ask
2048
+ </button>
2049
+ </div>
2050
+ </div>`;
2051
+ }).join('')}
2052
+ <p class="related-note">Previews of answers from semantically similar questions. Click Ask to start a fresh conversation.</p>
2053
  </div>
2054
  </div>`;
2055
  }
 
2231
  const voteBtn = e.target.closest('[data-vote]');
2232
  if (voteBtn) { await handleVote(voteBtn); return; }
2233
 
2234
+ // Ask a related/similar question
2235
+ const askQ = e.target.closest('[data-ask-question]');
2236
+ if (askQ) { handleAskFromCard(askQ.getAttribute('data-ask-question')); return; }
2237
+
2238
+ // Re-ask the current question
2239
+ if (e.target.closest('[data-ask-current]')) { handleAskFromCard(S.currentQuestion); return; }
2240
+
2241
  // Copy answer text
2242
  const copyAns = e.target.closest('[data-copy-answer]');
2243
  if (copyAns) { await handleCopyAnswer(copyAns); return; }
 
2398
  } catch { toast('Could not copy', 'bad'); }
2399
  }
2400
 
2401
+ function handleAskFromCard(q) {
2402
+ const text = String(q || '').trim();
2403
+ if (!text || S.loading) return;
2404
+ const p = $('prompt');
2405
+ if (p) { p.value = text; autoGrow(p); }
2406
+ submitPrompt();
2407
+ }
2408
+
2409
  function handleToggleVersions(btn) {
2410
  const id = btn.getAttribute('data-toggle-versions');
2411
  const p = $('vp-' + id);