feat(booth): copy-id button on the pickup banner (v0.1.3)
Adds a "⧉ copy" button next to the pickup id that copies the id to the
clipboard (flips to "✓ copied"). The Booth serves over plain HTTP on a LAN IP,
where navigator.clipboard is undefined (secure-context only) — so the handler
falls back to a hidden-textarea execCommand('copy') that works over HTTP.
Verified on the LAN-IP (non-secure) path: isSecureContext=false, clipboard API
absent, button state flips, no errors. Reusable via any .copy-btn[data-copy].
This commit is contained in:
@@ -111,6 +111,11 @@
|
||||
.pickup-note{margin:-.5rem 0 1.5rem;padding:.6rem .85rem;border:1px solid var(--border-subtle);
|
||||
border-left:3px solid var(--aus-bright-cyan);border-radius:var(--radius-md);background:var(--rk-well);
|
||||
font-family:var(--font-mono);font-size:.78rem;color:var(--fg-2)}
|
||||
.copy-btn{cursor:pointer;font-family:var(--font-mono);font-size:.68rem;letter-spacing:.04em;
|
||||
padding:.12rem .5rem;margin:0 .25rem;border:1px solid var(--border-default);border-radius:var(--radius-sm);
|
||||
background:transparent;color:var(--aus-bright-cyan);vertical-align:middle;transition:.12s var(--ease-out)}
|
||||
.copy-btn:hover{border-color:var(--aus-cyan);background:rgba(66,220,209,.08)}
|
||||
.copy-btn.copied{border-color:var(--aus-green);color:var(--aus-bright-green)}
|
||||
.dl-link{color:var(--aus-bright-cyan);text-decoration:none;margin-right:.4rem;font-size:.95em}
|
||||
.dl-link:hover{color:var(--aus-cyan)}
|
||||
.cap-text{color:var(--fg-2)}
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
{% if uploaded %}
|
||||
<div class="pickup-note">
|
||||
📦 Pickup <code>{{ name }}</code> — download files below, or on nh3-dev grab <code>~/booth-data/{{ name }}/</code>
|
||||
📦 Pickup <code>{{ name }}</code>
|
||||
<button type="button" class="copy-btn" data-copy="{{ name }}" title="copy id to clipboard">⧉ copy</button>
|
||||
— download files below, or on nh3-dev grab <code>~/booth-data/{{ name }}/</code>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -44,4 +46,38 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
/* Copy-to-clipboard for any .copy-btn[data-copy]. The Booth serves over plain
|
||||
HTTP on a LAN IP, where navigator.clipboard is undefined (secure-context
|
||||
only) — so fall back to a hidden-textarea execCommand('copy'). */
|
||||
(function () {
|
||||
function copyText(t) {
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
return navigator.clipboard.writeText(t);
|
||||
}
|
||||
var ta = document.createElement('textarea');
|
||||
ta.value = t;
|
||||
ta.setAttribute('readonly', '');
|
||||
ta.style.position = 'fixed';
|
||||
ta.style.top = '-1000px';
|
||||
ta.style.opacity = '0';
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
try { document.execCommand('copy'); } catch (e) {}
|
||||
document.body.removeChild(ta);
|
||||
return Promise.resolve();
|
||||
}
|
||||
document.querySelectorAll('.copy-btn').forEach(function (btn) {
|
||||
var label = btn.textContent;
|
||||
btn.addEventListener('click', function () {
|
||||
copyText(btn.getAttribute('data-copy')).then(function () {
|
||||
btn.classList.add('copied');
|
||||
btn.textContent = '✓ copied';
|
||||
setTimeout(function () { btn.classList.remove('copied'); btn.textContent = label; }, 1300);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "booth"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
description = "The Booth — a dead-simple standing web server that scans a data dir of drop-folders and renders each as an ephemeral media 'booth' (image/webm/audio auto-gallery, or a folder's own index.html verbatim). Also accepts browser/curl uploads for pickup under a human-readable id. 24h TTL, then the folder is wiped. Fleet tool for CC sessions to surface A/B and smoke results to the operator."
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
|
||||
Reference in New Issue
Block a user