Add homepage quick join flow

This commit is contained in:
2026-03-03 19:07:40 +01:00
parent d1b432f8aa
commit 8a6ea5a592
3 changed files with 84 additions and 10 deletions
+31
View File
@@ -79,6 +79,26 @@ body {
border-radius: 4px; border-radius: 4px;
} }
.quick-join-form {
display: flex;
align-items: center;
gap: 8px;
}
.quick-join-form input {
width: 116px;
border: 1px solid var(--border);
border-radius: 4px;
padding: 9px 10px;
font: inherit;
text-transform: uppercase;
background: var(--surface);
}
.home-join {
margin-top: 10px;
}
.page-wrap { .page-wrap {
max-width: 1000px; max-width: 1000px;
margin: 0 auto; margin: 0 auto;
@@ -329,6 +349,17 @@ h3 {
text-align: center; text-align: center;
} }
.quick-join-form {
flex: 1;
min-width: 0;
}
.quick-join-form input {
flex: 1;
min-width: 0;
width: auto;
}
.page-wrap { .page-wrap {
padding: 16px 14px 24px; padding: 16px 14px 24px;
} }
+37 -10
View File
@@ -87,6 +87,7 @@ export class PlayApp {
this.displayBoardSize = 640; this.displayBoardSize = 640;
this.squareSize = 80; this.squareSize = 80;
this.dpr = Math.max(1, window.devicePixelRatio || 1); this.dpr = Math.max(1, window.devicePixelRatio || 1);
this.urlJoinConsumed = false;
this.loadPieceImages(); this.loadPieceImages();
this.installControls(); this.installControls();
@@ -127,6 +128,7 @@ export class PlayApp {
installSocket() { installSocket() {
this.socket = createWSClient({ this.socket = createWSClient({
onServerReady: () => this.consumeJoinCodeFromUrl(),
onGameStarted: handleGameStarted, onGameStarted: handleGameStarted,
onP2Connected: handleP2Connected, onP2Connected: handleP2Connected,
onGameCreated: handleCodeGameCreated, onGameCreated: handleCodeGameCreated,
@@ -170,16 +172,7 @@ export class PlayApp {
}); });
this.joinBtn.addEventListener("click", () => { this.joinBtn.addEventListener("click", () => {
const code = this.joinInput.value.trim().toUpperCase(); this.joinCode(this.joinInput.value);
if (!code) {
this.showModal("Join game", "Enter a game code first.", [
{ label: "OK" },
]);
return;
}
this.gameCode = code;
this.socket.emit("join_code_game", { code });
this.setLobbyStatus("Joining game...");
}); });
this.copyCodeBtn.addEventListener("click", async () => { this.copyCodeBtn.addEventListener("click", async () => {
@@ -358,6 +351,40 @@ export class PlayApp {
}); });
} }
joinCode(rawCode) {
const code = String(rawCode || "").trim().toUpperCase();
if (!code) {
this.showModal("Join game", "Enter a game code first.", [
{ label: "OK" },
]);
return false;
}
this.gameCode = code;
this.joinInput.value = code;
this.socket.emit("join_code_game", { code });
this.setLobbyStatus("Joining game...");
return true;
}
consumeJoinCodeFromUrl() {
if (this.urlJoinConsumed) {
return;
}
const url = new URL(window.location.href);
const code = url.searchParams.get("code");
if (!code) {
return;
}
this.urlJoinConsumed = true;
url.searchParams.delete("code");
const nextUrl = `${url.pathname}${url.search}${url.hash}`;
window.history.replaceState({}, "", nextUrl);
this.joinCode(code);
}
onCodeCreated(data) { onCodeCreated(data) {
this.gameCode = data.code; this.gameCode = data.code;
this.codeEl.textContent = data.code; this.codeEl.textContent = data.code;
+16
View File
@@ -10,4 +10,20 @@
>Past games</a >Past games</a
> >
</div> </div>
<div class="home-join">
<form
class="quick-join-form"
action="{{ url_for('main.play') }}"
method="get"
>
<input
type="text"
name="code"
maxlength="6"
placeholder="Game code"
aria-label="Join by code"
/>
<button class="btn btn-secondary" type="submit">Join</button>
</form>
</div>
{% endblock %} {% endblock %}