diff --git a/lobby/templates/lobby/player_screen.html b/lobby/templates/lobby/player_screen.html index 8f5c2d8..5bf8b81 100644 --- a/lobby/templates/lobby/player_screen.html +++ b/lobby/templates/lobby/player_screen.html @@ -7,6 +7,7 @@ #guessStatus { margin: 6px 0 10px; font-size: 0.95rem; color: #333; } #lieStatus { margin: 6px 0 10px; font-size: 0.95rem; color: #333; } #joinStatus { margin: 6px 0 10px; font-size: 0.95rem; color: #333; } +#contextLockHint { margin: 6px 0 10px; font-size: 0.95rem; color: #333; } #phaseStatus { margin: 6px 0 10px; font-size: 0.95rem; color: #333; } #lieStatus.locked { color: #0a5f2d; font-weight: 600; } #guessStatus.locked { color: #0a5f2d; font-weight: 600; } @@ -18,6 +19,7 @@

Klar til join.

+

Kontekst er ikke låst endnu.

@@ -57,6 +59,8 @@ function savePlayerContext(){try{localStorage.setItem(PLAYER_CONTEXT_KEY,JSON.st function loadPlayerContext(){try{var raw=localStorage.getItem(PLAYER_CONTEXT_KEY);if(!raw){return null;}return JSON.parse(raw);}catch(_e){return null;}} function restorePlayerContext(){var ctx=loadPlayerContext();if(!ctx){return false;}if(ctx.code){document.getElementById("code").value=(ctx.code||"").toUpperCase();}if(ctx.nickname){document.getElementById("nickname").value=ctx.nickname;}if(ctx.player_id){document.getElementById("playerId").value=ctx.player_id;}if(ctx.session_token){document.getElementById("sessionToken").value=ctx.session_token;}if(ctx.round_question_id){document.getElementById("roundQuestionId").value=ctx.round_question_id;}playerAutoRefreshEnabled=!!ctx.auto_refresh;updatePlayerAutoRefreshUi();return !!(ctx.code&&ctx.player_id&&ctx.session_token);} function hasSubmitContext(){return !!(code()&&pid()&&rq()&&document.getElementById("sessionToken").value.trim());} +function isPlayerContextLocked(){return !!(pid()&&document.getElementById("sessionToken").value.trim());} +function updateContextLockState(){var locked=isPlayerContextLocked()||joinInFlight;var codeField=document.getElementById("code");var nicknameField=document.getElementById("nickname");var playerIdField=document.getElementById("playerId");var tokenField=document.getElementById("sessionToken");if(codeField){codeField.readOnly=locked;}if(nicknameField){nicknameField.readOnly=locked;}if(playerIdField){playerIdField.readOnly=locked;}if(tokenField){tokenField.readOnly=true;}var hint=document.getElementById("contextLockHint");if(!hint){return;}if(joinInFlight){hint.textContent="Låser kontekst…";return;}if(locked){hint.textContent="Spillerkontekst er låst efter join.";return;}hint.textContent="Kontekst er ikke låst endnu.";} function canAttemptJoin(){return !!(code()&&document.getElementById("nickname").value.trim());} function normalizeApiError(data){if(!data||typeof data!=="object"){return"";}return (data.error_code||data.error||"").toString();} function mapUiErrorMessage(errorKey){if(!errorKey){return"";}var key=errorKey.toLowerCase();if(key.indexOf("phase")!==-1){return"Ugyldig fase for handlingen. Opdatér session-status og prøv igen.";}if(key.indexOf("token")!==-1||key.indexOf("auth")!==-1){return"Session-token er ugyldig eller udløbet. Rejoin sessionen og prøv igen.";}if(key.indexOf("round")!==-1||key.indexOf("question")!==-1||key.indexOf("state")!==-1){return"Runde-kontekst matcher ikke længere. Opdatér session-status før næste handling.";}if(key.indexOf("session")!==-1){return"Sessionkoden er ugyldig eller sessionen findes ikke længere.";}return"Handling fejlede. Opdatér session-status og prøv igen.";} @@ -68,7 +72,7 @@ function stopPlayerAutoRefresh(reason){playerAutoRefreshEnabled=false;if(playerA function startPlayerAutoRefresh(){if(!code()){updatePlayerAutoRefreshUi();return;}playerAutoRefreshEnabled=true;if(playerAutoRefreshTimer){clearInterval(playerAutoRefreshTimer);}playerAutoRefreshTimer=setInterval(function(){if(!code()){return;}if(currentSessionStatus==="finished"){stopPlayerAutoRefresh("Auto-refresh stoppet: spillet er afsluttet.");return;}sessionDetail();},10000);updatePlayerAutoRefreshUi();savePlayerContext();} function togglePlayerAutoRefresh(){if(playerAutoRefreshEnabled){stopPlayerAutoRefresh();return;}startPlayerAutoRefresh();} function updatePlayerErrorHint(status,data){var el=document.getElementById("playerErrorHint");if(!el){return;}if(status>=200&&status<300){el.textContent="Ingen fejl.";return;}var errKey=normalizeApiError(data);el.textContent="Fejl: "+mapUiErrorMessage(errKey)+" ("+(errKey||("http_"+status))+")";} -function updateJoinState(){var btn=document.getElementById("joinBtn");var status=document.getElementById("joinStatus");var joined=!!(pid()&&document.getElementById("sessionToken").value.trim());var canJoin=canAttemptJoin();if(btn){btn.disabled=joinInFlight||joined||!canJoin;}if(!status){return;}if(joinInFlight){status.textContent="Joiner…";return;}if(joined){status.textContent="Join gennemført.";return;}if(!canJoin){status.textContent="Udfyld kode og nickname for at join.";return;}status.textContent="Klar til join.";} +function updateJoinState(){var btn=document.getElementById("joinBtn");var status=document.getElementById("joinStatus");var joined=!!(pid()&&document.getElementById("sessionToken").value.trim());var canJoin=canAttemptJoin();if(btn){btn.disabled=joinInFlight||joined||!canJoin;}if(!status){updateContextLockState();return;}if(joinInFlight){status.textContent="Joiner…";updateContextLockState();return;}if(joined){status.textContent="Join gennemført.";updateContextLockState();return;}if(!canJoin){status.textContent="Udfyld kode og nickname for at join.";updateContextLockState();return;}status.textContent="Klar til join.";updateContextLockState();} function guessStorageKey(){var c=code();var p=pid();var q=rq();if(!c||!p||!q){return "";}return ["wppGuess",c,p,q].join(":");} function lieStorageKey(){var c=code();var p=pid();var q=rq();if(!c||!p||!q){return "";}return ["wppLie",c,p,q].join(":");} diff --git a/lobby/tests.py b/lobby/tests.py index 3e01327..2af4a13 100644 --- a/lobby/tests.py +++ b/lobby/tests.py @@ -829,6 +829,9 @@ class UiScreenTests(TestCase): self.assertContains(response, "canAttemptJoin") self.assertContains(response, "missing_join_input") self.assertContains(response, "Udfyld kode og nickname for at join.") + self.assertContains(response, "id=\"contextLockHint\"") + self.assertContains(response, "updateContextLockState") + self.assertContains(response, "Spillerkontekst er låst efter join.") self.assertContains(response, "already_joined_client") self.assertContains(response, "missing_submit_context") self.assertContains(response, "invalid_client_guess")