chore: updated styles and added copy button to blob in kepler a5741a81
Steve · 2026-06-09 07:39 2 file(s) · +29 −11
apps/kepler/static/styles.css +12 −11
84 84
.tab.active {
85 85
    color: var(--fg);
86 86
    border-color: var(--border);
87 -
    border-radius: 4px 4px 0 0;
88 87
    background: var(--bg);
89 88
}
90 89
.repo-nav .tab:first-of-type { margin-left: auto; }
178 177
    align-items: center;
179 178
    gap: 0.75rem;
180 179
    border: 1px solid var(--border);
181 -
    border-radius: 4px;
182 180
    padding: 0.4rem 0.75rem;
183 181
    font-size: 13px;
184 182
    overflow: hidden;
200 198
    display: flex;
201 199
    align-items: baseline;
202 200
    padding: 0.25rem 0.5rem;
203 -
    border-radius: 4px;
204 201
}
205 202
.tree-entry:hover { opacity: 1; background: var(--bg-alt); }
206 203
.file-tree .name { white-space: nowrap; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
214 211
215 212
/* --- File / blob view --- */
216 213
217 -
.file-view { border: 1px solid var(--border); border-radius: 4px; }
214 +
.file-view { border: 1px solid var(--border);  }
218 215
.file-header {
219 216
    display: flex;
220 217
    gap: 0.75rem;
225 222
}
226 223
.file-name { font-weight: 700; flex: 1; }
227 224
.file-meta { color: var(--fg-dim); font-size: 12px; }
225 +
.copy-btn {
226 +
    background: none;
227 +
    border: 0;
228 +
    padding: 0;
229 +
    margin: 0;
230 +
    font: inherit;
231 +
    color: var(--link);
232 +
    cursor: pointer;
233 +
}
228 234
229 235
.blob-view { overflow: auto hidden; }
230 236
.blob-code { margin: 0; border-collapse: collapse; border-spacing: 0; width: 100%; }
268 274
.commit-info .body {
269 275
    background: var(--bg-alt);
270 276
    padding: 0.5rem 0.75rem;
271 -
    border-radius: 4px;
272 277
    font-size: 13px;
273 278
    margin: 0 0 1rem 0;
274 279
    white-space: pre-wrap;
290 295
291 296
/* --- Diff --- */
292 297
293 -
.diff-file { border: 1px solid var(--border); border-radius: 4px; margin-bottom: 1rem; overflow-x: auto; }
298 +
.diff-file { border: 1px solid var(--border);  margin-bottom: 1rem; overflow-x: auto; }
294 299
.diff-header {
295 300
    display: flex;
296 301
    align-items: center;
355 360
    color: var(--fg-dim);
356 361
}
357 362
.pagination a + a { border-left: none; }
358 -
.pagination a:first-child { border-radius: 4px 0 0 4px; }
359 -
.pagination a:last-child { border-radius: 0 4px 4px 0; }
360 -
.pagination a:only-child { border-radius: 4px; }
361 363
.pagination a:hover { color: var(--fg); opacity: 1; }
362 364
363 365
/* --- Readme --- */
371 373
    margin: 0.75rem 0;
372 374
    overflow-x: auto;
373 375
    font-size: 13px;
374 -
    border-radius: 4px;
375 376
}
376 377
.readme p { margin: 0.5rem 0; }
377 -
.readme code { background: var(--bg-alt); padding: 1px 4px; font-size: 13px; border-radius: 3px; }
378 +
.readme code { background: var(--bg-alt); padding: 1px 4px; font-size: 13px;  }
378 379
.readme pre code { background: transparent; padding: 0; }
379 380
.readme blockquote { border-left: 2px solid var(--border); margin: 0.75rem 0; padding-left: 0.75rem; color: var(--fg-dim); }
380 381
.readme table { border-collapse: collapse; margin: 0.75rem 0; }
apps/kepler/templates/blob.html +17 −0
14 14
    <header class="file-header">
15 15
        <span class="file-name">{{.Path}}</span>
16 16
        <span class="file-meta">{{humanSize .Size}}</span>
17 +
        {{if not .Binary}}<button type="button" class="copy-btn" data-raw="/{{.Repo.Name}}/raw/{{.Ref}}/{{.Path}}">copy</button>{{end}}
17 18
        <a href="/{{.Repo.Name}}/raw/{{.Ref}}/{{.Path}}">raw</a>
18 19
    </header>
19 20
    {{if .Binary}}
22 23
    <div class="blob-view">{{.HighlightedHTML}}</div>
23 24
    {{end}}
24 25
</div>
26 +
<script>
27 +
document.querySelectorAll(".copy-btn").forEach(function (btn) {
28 +
    btn.addEventListener("click", async function () {
29 +
        try {
30 +
            var res = await fetch(btn.dataset.raw);
31 +
            var text = await res.text();
32 +
            await navigator.clipboard.writeText(text);
33 +
            var prev = btn.textContent;
34 +
            btn.textContent = "copied";
35 +
            setTimeout(function () { btn.textContent = prev; }, 1500);
36 +
        } catch (e) {
37 +
            btn.textContent = "failed";
38 +
        }
39 +
    });
40 +
});
41 +
</script>
25 42
{{end}}