Clipboard aesthetic

pull/32/head
eric 2025-08-10 18:41:23 +02:00
parent adfaf00817
commit e27b6f2a23
1 changed files with 110 additions and 16 deletions

View File

@ -53,14 +53,50 @@
.tile .txt b{font-size:16px}
.tile .txt span{font-size:13px; color:var(--muted)}
/* Join form */
.row{display:flex; gap:10px; align-items:center; flex-wrap:wrap}
label{color:var(--muted)}
input[type="text"]{
background:#0f0f0f; color:var(--text); border:1px solid var(--border);
padding:12px 14px; border-radius:12px; outline:none; min-width:180px;
/* Join form Spotify-like Input */
.row{display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap}
.field{display:flex; flex-direction:column; gap:6px}
label{color:var(--muted); font-size:13px}
.inputWrap{position:relative; min-width:220px}
.inputWrap .leading-icon{
position:absolute; left:12px; top:50%; transform:translateY(-50%); opacity:.9;
}
input:focus{border-color:var(--accent); box-shadow:0 0 0 3px var(--glow)}
.inputWrap .chip{
position:absolute; right:10px; top:50%; transform:translateY(-50%);
font-size:11px; color:var(--muted);
border:1px solid var(--border); background:#0d0d0d;
padding:4px 8px; border-radius:999px;
}
input#gameId{
width:100%;
background:#0b0b0b; color:var(--text);
border:1px solid var(--border);
border-radius:999px;
padding:14px 78px 14px 42px; /* Platz für Icon + Chip */
outline:none;
letter-spacing:.12em; font-weight:600;
box-shadow: inset 0 1px 0 rgba(255,255,255,.02);
transition:border-color .2s, box-shadow .2s, background .2s, transform .06s;
}
input#gameId::placeholder{color:#777}
input#gameId:focus{
border-color:var(--accent);
box-shadow:0 0 0 4px var(--glow), inset 0 1px 0 rgba(255,255,255,.02);
background:#0e0e0e;
}
input#gameId:active{transform:translateY(1px)}
/* Icon-only clipboard button */
.icon-btn{width:auto; padding:10px; border-radius:999px; display:inline-flex; align-items:center; justify-content:center}
.icon-btn svg{display:block}
.icon-btn--accent{
background:var(--accent); color:#0a0a0a;
box-shadow:0 0 0 0 var(--glow);
transition: box-shadow .2s, filter .15s, transform .06s, background .2s;
}
.icon-btn--accent:hover{ filter:brightness(1.05); box-shadow:0 0 0 6px var(--glow) }
.icon-btn--accent:active{ background:var(--accent-press); transform:translateY(1px) }
</style>
</head>
<body>
@ -98,31 +134,89 @@
</div>
<!-- Direktes Join-Formular in der Lobby -->
<form id="joinForm" class="row" style="gap:10px; flex-wrap:nowrap">
<label for="gameId" class="muted" style="min-width:90px">SpielCode</label>
<input id="gameId" name="gameId" placeholder="4stellig" inputmode="numeric" maxlength="4" required />
<form id="joinForm" class="row">
<div class="field">
<label for="gameId">Spiel-Code</label>
<div class="inputWrap">
<span class="leading-icon" aria-hidden="true">
<svg width="18" height="18" viewBox="0 0 24 24" fill="#1db954">
<path d="M3 11h18v10H3V11Zm9-8a5 5 0 0 1 5 5v3h-2V8a3 3 0 1 0-6 0v3H7V8a5 5 0 0 1 5-5Z"/>
</svg>
</span>
<input id="gameId" name="gameId"
placeholder="••••"
inputmode="numeric"
pattern="\d{4}"
maxlength="4"
autocomplete="one-time-code"
required />
<span class="chip">4-stellig</span>
</div>
</div>
<!-- Icon-Button: Zwischenablage (grün) -->
<button type="button" id="pasteCode"
class="btn icon-btn icon-btn--accent"
aria-label="Code aus Zwischenablage einfügen"
title="Aus Zwischenablage">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M9 2h6a2 2 0 0 1 2 2h1a2 2 0 0 1 2 2v13a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V6a2 2 0 0 1 2-2h1a2 2 0 0 1 2-2Zm0 2a1 1 0 0 0-1 1h8a1 1 0 0 0-1-1H9Z"/>
</svg>
</button>
<button type="submit" class="btn btn-primary" style="width:auto">Beitreten</button>
<!-- Dummy-Button für Abwärtskompatibilität mit altem lobby.js -->
<!-- (legacy) -->
<button id="joinGame" type="button" style="display:none">Join (legacy)</button>
</form>
<p class="muted" style="margin-top:8px">Tipp: Code ist vierstellig (z.B. 3759).</p>
<p class="muted" style="margin-top:8px">Tipp: Code ist vierstellig (z. B. 6767).</p>
</div>
</div>
</section>
</div>
<!-- Username-Anzeige oben rechts -->
<!-- Username-Anzeige + Clipboard-Button -->
<script type="module">
// Username-Badge
const p = new URLSearchParams(location.search);
const u = p.get('username');
if (u) document.querySelector('#uname').textContent = u;
// Clipboard-Paste für Spiel-Code
const input = document.getElementById('gameId');
const pasteBtn = document.getElementById('pasteCode');
pasteBtn?.addEventListener('click', async () => {
try {
// Clipboard ist nur über HTTPS/localhost verfügbar
const text = await navigator.clipboard.readText();
const digits = (text.match(/\d/g) || []).join('').slice(0, 4);
if (!digits) {
alert('Keinen 4-stelligen Code in der Zwischenablage gefunden.');
return;
}
input.value = digits;
input.focus();
input.select();
// Optional auto-submit, wenn 4 Ziffern vorhanden
if (digits.length === 4) {
if (input.form?.requestSubmit) input.form.requestSubmit();
else input.form?.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
}
} catch (err) {
alert('Zwischenablage nicht verfügbar. Öffne die Seite über HTTPS oder erlaube Zugriff.');
console.error(err);
}
});
</script>
<script type="module" src="/js/lobby.js"></script>
<!-- Join-Handling wiederverwenden -->
<script type="module" src="/js/join-game.js"></script>
<!-- Optional: Klick auf alten Join-Button fokusiert Eingabefeld statt Redirect -->
<!-- Optional: alter Join-Button (legacy) fokussiert nur das Feld -->
<script>
const btn = document.getElementById('joinGame');
if (btn) {
@ -130,8 +224,8 @@
ev.preventDefault(); ev.stopImmediatePropagation();
const input = document.getElementById('gameId');
if (input) { input.focus(); input.select(); }
}, true); // capture-Phase, um evtl. ältere Listener zu überstimmen
}, true);
}
</script>
</body>
</html>
</html>