Make join codes easy to copy
This commit is contained in:
@@ -39,10 +39,28 @@
|
|||||||
min-width: 10.5rem;
|
min-width: 10.5rem;
|
||||||
padding: 0.85rem 1.1rem 0.95rem;
|
padding: 0.85rem 1.1rem 0.95rem;
|
||||||
background: color-mix(in srgb, var(--accent) 12%, var(--well));
|
background: color-mix(in srgb, var(--accent) 12%, var(--well));
|
||||||
|
color: var(--text);
|
||||||
border: 2px solid var(--accent);
|
border: 2px solid var(--accent);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
box-shadow: var(--shadow-soft);
|
box-shadow: var(--shadow-soft);
|
||||||
|
font: inherit;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition-smooth);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-join-code:hover {
|
||||||
|
background: color-mix(in srgb, var(--accent) 20%, var(--well));
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-join-code:focus-visible {
|
||||||
|
outline: 3px solid color-mix(in srgb, var(--accent) 35%, transparent);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-join-code.copied {
|
||||||
|
border-color: var(--success);
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-join-code-label {
|
.admin-join-code-label {
|
||||||
@@ -65,6 +83,13 @@
|
|||||||
letter-spacing: 0.16em;
|
letter-spacing: 0.16em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.admin-join-code-hint {
|
||||||
|
display: block;
|
||||||
|
margin-top: 0.35rem;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.admin-summary {
|
.admin-summary {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -38,6 +38,11 @@
|
|||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lobby-join-code-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.copy-container {
|
.copy-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|||||||
@@ -58,6 +58,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="links-box glass-panel">
|
<div class="links-box glass-panel">
|
||||||
|
{#if state.player.is_admin}
|
||||||
|
<div class="link-item lobby-join-code-item">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="admin-join-code"
|
||||||
|
class:copied={copiedLink === 'code'}
|
||||||
|
aria-label="Copy join code {state.game.join_code}"
|
||||||
|
on:click={() => copyLink('code', state.game.join_code)}
|
||||||
|
>
|
||||||
|
<span class="admin-join-code-label">Join Code</span>
|
||||||
|
<strong>{state.game.join_code}</strong>
|
||||||
|
<span class="admin-join-code-hint">{copiedLink === 'code' ? '✓ Copied!' : 'Click to copy'}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<div class="link-item">
|
<div class="link-item">
|
||||||
<h4>Share Join Link:</h4>
|
<h4>Share Join Link:</h4>
|
||||||
<div class="copy-container">
|
<div class="copy-container">
|
||||||
|
|||||||
@@ -6,10 +6,17 @@
|
|||||||
// - Add a CHANGELOG entry only when a commit changes something players can
|
// - Add a CHANGELOG entry only when a commit changes something players can
|
||||||
// see. Skip refactors, tests, and tooling. Keep wording player-facing.
|
// see. Skip refactors, tests, and tooling. Keep wording player-facing.
|
||||||
|
|
||||||
export const VERSION = 22;
|
export const VERSION = 23;
|
||||||
|
|
||||||
// Newest first. Each entry: { version, date: 'YYYY-MM-DD', changes: [string, ...] }.
|
// Newest first. Each entry: { version, date: 'YYYY-MM-DD', changes: [string, ...] }.
|
||||||
export const CHANGELOG = [
|
export const CHANGELOG = [
|
||||||
|
{
|
||||||
|
version: 23,
|
||||||
|
date: '2026-07-10',
|
||||||
|
changes: [
|
||||||
|
'Admins can now click the join code to copy it, and the code is available directly from the lobby.',
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
version: 21,
|
version: 21,
|
||||||
date: '2026-07-10',
|
date: '2026-07-10',
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
let copiedTimer = null;
|
let copiedTimer = null;
|
||||||
let copiedInvite = false;
|
let copiedInvite = false;
|
||||||
let copiedInviteTimer = null;
|
let copiedInviteTimer = null;
|
||||||
|
let copiedJoinCode = false;
|
||||||
|
let copiedJoinCodeTimer = null;
|
||||||
|
|
||||||
$: setPageTitle('Admin', data?.game?.crew_name);
|
$: setPageTitle('Admin', data?.game?.crew_name);
|
||||||
|
|
||||||
@@ -48,6 +50,13 @@
|
|||||||
copiedInviteTimer = setTimeout(() => { copiedInvite = false; }, 2000);
|
copiedInviteTimer = setTimeout(() => { copiedInvite = false; }, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function copyJoinCode() {
|
||||||
|
navigator.clipboard.writeText(data.game.join_code);
|
||||||
|
copiedJoinCode = true;
|
||||||
|
clearTimeout(copiedJoinCodeTimer);
|
||||||
|
copiedJoinCodeTimer = setTimeout(() => { copiedJoinCode = false; }, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Try to load admin_key from local storage
|
// Try to load admin_key from local storage
|
||||||
adminKey = localStorage.getItem(`admin_key_${gameId}`) || '';
|
adminKey = localStorage.getItem(`admin_key_${gameId}`) || '';
|
||||||
@@ -123,10 +132,17 @@
|
|||||||
<p><strong>Phase:</strong> {data.game.phase}</p>
|
<p><strong>Phase:</strong> {data.game.phase}</p>
|
||||||
<p><strong>Admin Key:</strong> <span class="admin-key-chip">{data.game.admin_key}</span></p>
|
<p><strong>Admin Key:</strong> <span class="admin-key-chip">{data.game.admin_key}</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="admin-join-code" aria-label="Join code {data.game.join_code}">
|
<button
|
||||||
|
type="button"
|
||||||
|
class="admin-join-code"
|
||||||
|
class:copied={copiedJoinCode}
|
||||||
|
aria-label="Copy join code {data.game.join_code}"
|
||||||
|
on:click={copyJoinCode}
|
||||||
|
>
|
||||||
<span class="admin-join-code-label">Join Code</span>
|
<span class="admin-join-code-label">Join Code</span>
|
||||||
<strong>{data.game.join_code}</strong>
|
<strong>{data.game.join_code}</strong>
|
||||||
</div>
|
<span class="admin-join-code-hint">{copiedJoinCode ? '✓ Copied!' : 'Click to copy'}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if error}
|
{#if error}
|
||||||
|
|||||||
Reference in New Issue
Block a user