Add homepage quick join flow
This commit is contained in:
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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 %}
|
||||||
|
|||||||
Reference in New Issue
Block a user