ntdservices commited on
Commit
366abe4
Β·
verified Β·
1 Parent(s): e3f391f

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +60 -9
templates/index.html CHANGED
@@ -1,3 +1,4 @@
 
1
  <!doctype html>
2
  <html lang="en">
3
  <head>
@@ -63,7 +64,7 @@
63
  ol{ padding-left: 22px; }
64
  ol li{ margin: 12px 0; }
65
  a{ color: var(--accent2); }
66
- .muted{ color:var(--muted); font-size:13px; }
67
 
68
  /* Sidebar: full merged text */
69
  .sidebar-backdrop{ position: fixed; inset: 0; background: rgba(0,0,0,.35); opacity:0; pointer-events:none; transition:.18s ease; z-index:60; }
@@ -74,8 +75,22 @@
74
  .sbar-hdr h3{ margin:0; font-size:16px; }
75
  .sbar-body{ overflow:auto; padding:16px; }
76
  .smallbtn{ font-size:12px; padding:6px 8px; border-radius:10px; background:#1a213f; color:#dbe2ff; border:1px solid #ffffff18; cursor:pointer; }
 
77
  pre#fullText{ margin:0; white-space:pre-wrap; word-wrap:break-word; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; line-height:1.5; }
78
  mark#centerMark{ background:#61e7ff55; padding:0 .5px; border-radius:3px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  </style>
80
  </head>
81
  <body>
@@ -170,10 +185,29 @@
170
  {% for r in results %}
171
  <li>
172
  <p>{{ r.text }}</p>
173
- <button type="button" class="smallbtn" onclick="openContext({{ r.idx }})">πŸ”Ž View context</button>
 
 
 
 
 
 
 
 
174
  </li>
175
  {% endfor %}
176
  </ol>
 
 
 
 
 
 
 
 
 
 
 
177
  {% endif %}
178
  </div>
179
  </section>
@@ -279,8 +313,9 @@
279
  btnClose.addEventListener('click', closeSidebar);
280
  backdrop.addEventListener('click', closeSidebar);
281
 
282
- jumpTop.addEventListener('click', () => { sidebarBody.scrollTo({ top: 0, behavior: 'smooth' }); });
283
- jumpBottom.addEventListener('click', () => { sidebarBody.scrollTo({ top: sidebarBody.scrollHeight, behavior: 'smooth' }); });
 
284
 
285
  function escapeHtml(s){
286
  return s.replaceAll('&','&amp;')
@@ -305,14 +340,11 @@
305
  const after = escapeHtml(merged.slice(end));
306
  pre.innerHTML = before + '<mark id="centerMark">' + middle + '</mark>' + after;
307
 
308
- // Smoothly center the highlight in view
309
  requestAnimationFrame(() => {
310
  const mark = document.getElementById('centerMark');
311
  if(mark){
312
- const rect = mark.getBoundingClientRect();
313
- const bodyRect = sidebarBody.getBoundingClientRect();
314
- const offset = (rect.top + rect.height/2) - (bodyRect.top + bodyRect.height/2);
315
- sidebarBody.scrollBy({ top: offset, behavior: 'smooth' });
316
  }
317
  });
318
  }
@@ -326,6 +358,25 @@
326
  alert('Error: ' + err.message);
327
  }
328
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
  </script>
330
  </body>
331
  </html>
 
1
+ <!-- templates/index.html -->
2
  <!doctype html>
3
  <html lang="en">
4
  <head>
 
64
  ol{ padding-left: 22px; }
65
  ol li{ margin: 12px 0; }
66
  a{ color: var(--accent2); }
67
+ .muted{ color:#b7c0ffcc; font-size:13px; }
68
 
69
  /* Sidebar: full merged text */
70
  .sidebar-backdrop{ position: fixed; inset: 0; background: rgba(0,0,0,.35); opacity:0; pointer-events:none; transition:.18s ease; z-index:60; }
 
75
  .sbar-hdr h3{ margin:0; font-size:16px; }
76
  .sbar-body{ overflow:auto; padding:16px; }
77
  .smallbtn{ font-size:12px; padding:6px 8px; border-radius:10px; background:#1a213f; color:#dbe2ff; border:1px solid #ffffff18; cursor:pointer; }
78
+
79
  pre#fullText{ margin:0; white-space:pre-wrap; word-wrap:break-word; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; line-height:1.5; }
80
  mark#centerMark{ background:#61e7ff55; padding:0 .5px; border-radius:3px; }
81
+
82
+ /* New: results toolbuttons + file label */
83
+ .tools{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-top:6px; }
84
+ .iconbtn{
85
+ display:inline-flex; align-items:center; justify-content:center;
86
+ width:28px; height:28px; border-radius:8px; border:1px solid #ffffff18;
87
+ background:#1a213f; color:#e6ecff; cursor:pointer; font-size:14px;
88
+ }
89
+ .filetag{
90
+ display:inline-flex; align-items:center; gap:6px;
91
+ padding:4px 8px; border-radius:999px; border:1px solid #ffffff18;
92
+ background:#0d1333; color:#cfe1ff; font-size:12px;
93
+ }
94
  </style>
95
  </head>
96
  <body>
 
185
  {% for r in results %}
186
  <li>
187
  <p>{{ r.text }}</p>
188
+ <div class="tools">
189
+ <button type="button" class="smallbtn" onclick="openContext({{ r.idx }})" title="Open full context sidebar">πŸ”Ž View context</button>
190
+
191
+ <!-- Clipboard icon: copies the 2nd line of the source file -->
192
+ <button type="button" class="iconbtn" onclick="copySecond({{ r.idx }}, this)" title="Copy 2nd line of this file">πŸ“‹</button>
193
+
194
+ <!-- File name label -->
195
+ <span class="filetag">πŸ“„ {{ r.file }}</span>
196
+ </div>
197
  </li>
198
  {% endfor %}
199
  </ol>
200
+
201
+ <!-- Provide per-paragraph metadata for JS (2nd line + filename) -->
202
+ <script>
203
+ window.PARA_META = {};
204
+ {% for r in results %}
205
+ PARA_META[{{ r.idx }}] = {
206
+ second: {{ r.second_line | tojson }},
207
+ file: {{ r.file | tojson }}
208
+ };
209
+ {% endfor %}
210
+ </script>
211
  {% endif %}
212
  </div>
213
  </section>
 
313
  btnClose.addEventListener('click', closeSidebar);
314
  backdrop.addEventListener('click', closeSidebar);
315
 
316
+ // Instant jumps for top/bottom
317
+ jumpTop.addEventListener('click', () => { sidebarBody.scrollTop = 0; });
318
+ jumpBottom.addEventListener('click', () => { sidebarBody.scrollTop = sidebarBody.scrollHeight; });
319
 
320
  function escapeHtml(s){
321
  return s.replaceAll('&','&amp;')
 
340
  const after = escapeHtml(merged.slice(end));
341
  pre.innerHTML = before + '<mark id="centerMark">' + middle + '</mark>' + after;
342
 
343
+ // Instantly jump to the highlight
344
  requestAnimationFrame(() => {
345
  const mark = document.getElementById('centerMark');
346
  if(mark){
347
+ mark.scrollIntoView({ block: 'center', inline: 'nearest' });
 
 
 
348
  }
349
  });
350
  }
 
358
  alert('Error: ' + err.message);
359
  }
360
  }
361
+
362
+ // Clipboard: copy the 2nd line of the source file for this paragraph
363
+ window.copySecond = function(idx, btn){
364
+ try{
365
+ const meta = window.PARA_META?.[idx];
366
+ if(!meta){ throw new Error("Missing metadata"); }
367
+ const text = meta.second || "";
368
+ navigator.clipboard.writeText(text).then(() => {
369
+ // simple visual feedback
370
+ const old = btn.textContent;
371
+ btn.textContent = 'βœ…';
372
+ setTimeout(()=>{ btn.textContent = 'πŸ“‹'; }, 900);
373
+ }, () => {
374
+ alert("Clipboard copy failed");
375
+ });
376
+ }catch(e){
377
+ alert("Clipboard error: " + e.message);
378
+ }
379
+ }
380
  </script>
381
  </body>
382
  </html>