UI: lås spillerkontekstfelter efter join (#91)
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#guessStatus { margin: 6px 0 10px; font-size: 0.95rem; color: #333; }
|
#guessStatus { margin: 6px 0 10px; font-size: 0.95rem; color: #333; }
|
||||||
#lieStatus { 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; }
|
#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; }
|
#phaseStatus { margin: 6px 0 10px; font-size: 0.95rem; color: #333; }
|
||||||
#lieStatus.locked { color: #0a5f2d; font-weight: 600; }
|
#lieStatus.locked { color: #0a5f2d; font-weight: 600; }
|
||||||
#guessStatus.locked { color: #0a5f2d; font-weight: 600; }
|
#guessStatus.locked { color: #0a5f2d; font-weight: 600; }
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
<input id="nickname" placeholder="Nickname">
|
<input id="nickname" placeholder="Nickname">
|
||||||
<button id="joinBtn" onclick="joinSession()">1) Join</button>
|
<button id="joinBtn" onclick="joinSession()">1) Join</button>
|
||||||
<p id="joinStatus">Klar til join.</p>
|
<p id="joinStatus">Klar til join.</p>
|
||||||
|
<p id="contextLockHint">Kontekst er ikke låst endnu.</p>
|
||||||
<input id="playerId" placeholder="Player id">
|
<input id="playerId" placeholder="Player id">
|
||||||
<input id="sessionToken" placeholder="Session token" type="password" readonly>
|
<input id="sessionToken" placeholder="Session token" type="password" readonly>
|
||||||
<input id="roundQuestionId" placeholder="Round question id">
|
<input id="roundQuestionId" placeholder="Round question id">
|
||||||
@@ -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 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 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 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 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 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.";}
|
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 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 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 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 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(":");}
|
function lieStorageKey(){var c=code();var p=pid();var q=rq();if(!c||!p||!q){return "";}return ["wppLie",c,p,q].join(":");}
|
||||||
|
|||||||
@@ -829,6 +829,9 @@ class UiScreenTests(TestCase):
|
|||||||
self.assertContains(response, "canAttemptJoin")
|
self.assertContains(response, "canAttemptJoin")
|
||||||
self.assertContains(response, "missing_join_input")
|
self.assertContains(response, "missing_join_input")
|
||||||
self.assertContains(response, "Udfyld kode og nickname for at join.")
|
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, "already_joined_client")
|
||||||
self.assertContains(response, "missing_submit_context")
|
self.assertContains(response, "missing_submit_context")
|
||||||
self.assertContains(response, "invalid_client_guess")
|
self.assertContains(response, "invalid_client_guess")
|
||||||
|
|||||||
Reference in New Issue
Block a user