Merge pull request 'UI: host action guards ved manglende kontekst (#66)' (#67) from feature/ui-host-action-guards into main
All checks were successful
CI / test-and-quality (push) Successful in 1m28s
All checks were successful
CI / test-and-quality (push) Successful in 1m28s
This commit was merged in pull request #67.
This commit is contained in:
@@ -9,13 +9,14 @@
|
|||||||
<button id="startRoundBtn" onclick="startRound()" disabled>2) Start runde</button>
|
<button id="startRoundBtn" onclick="startRound()" disabled>2) Start runde</button>
|
||||||
<p id="startRoundHint">Kræver mindst 3 spillere i lobbyen.</p>
|
<p id="startRoundHint">Kræver mindst 3 spillere i lobbyen.</p>
|
||||||
<p id="playerCountStatus">Spillere i session: ukendt</p>
|
<p id="playerCountStatus">Spillere i session: ukendt</p>
|
||||||
<button onclick="showQuestion()">3) Vis spørgsmål</button>
|
<button id="showQuestionBtn" onclick="showQuestion()" disabled>3) Vis spørgsmål</button>
|
||||||
<input id="roundQuestionId" placeholder="Round question id">
|
<input id="roundQuestionId" placeholder="Round question id">
|
||||||
<button onclick="mixAnswers()">4) Mix svar</button>
|
<button id="mixAnswersBtn" onclick="mixAnswers()" disabled>4) Mix svar</button>
|
||||||
<button onclick="calcScores()">5) Beregn score</button>
|
<button id="calcScoresBtn" onclick="calcScores()" disabled>5) Beregn score</button>
|
||||||
<button onclick="showScoreboard()">6) Scoreboard</button>
|
<button id="showScoreboardBtn" onclick="showScoreboard()" disabled>6) Scoreboard</button>
|
||||||
<button onclick="nextRound()">7) Næste runde</button>
|
<button id="nextRoundBtn" onclick="nextRound()" disabled>7) Næste runde</button>
|
||||||
<button onclick="finishGame()">8) Afslut spil</button>
|
<button id="finishGameBtn" onclick="finishGame()" disabled>8) Afslut spil</button>
|
||||||
|
<p id="hostActionHint">Angiv sessionkode for at aktivere host-actions.</p>
|
||||||
<button onclick="sessionDetail()">Session-status</button>
|
<button onclick="sessionDetail()">Session-status</button>
|
||||||
<pre id="out">Klar.</pre>
|
<pre id="out">Klar.</pre>
|
||||||
<script>
|
<script>
|
||||||
@@ -25,7 +26,8 @@ function rq(){return document.getElementById("roundQuestionId").value.trim();}
|
|||||||
function saveHostContext(){try{localStorage.setItem("wppHostContext",JSON.stringify({code:code(),round_question_id:rq()}));}catch(_e){}}
|
function saveHostContext(){try{localStorage.setItem("wppHostContext",JSON.stringify({code:code(),round_question_id:rq()}));}catch(_e){}}
|
||||||
function restoreHostContext(){try{var raw=localStorage.getItem("wppHostContext");if(!raw){return false;}var ctx=JSON.parse(raw);if(ctx.code){document.getElementById("code").value=(ctx.code||"").toUpperCase();}if(ctx.round_question_id){document.getElementById("roundQuestionId").value=ctx.round_question_id;}return !!ctx.code;}catch(_e){return false;}}
|
function restoreHostContext(){try{var raw=localStorage.getItem("wppHostContext");if(!raw){return false;}var ctx=JSON.parse(raw);if(ctx.code){document.getElementById("code").value=(ctx.code||"").toUpperCase();}if(ctx.round_question_id){document.getElementById("roundQuestionId").value=ctx.round_question_id;}return !!ctx.code;}catch(_e){return false;}}
|
||||||
function syncStartRoundGuard(data){var btn=document.getElementById("startRoundBtn");var hint=document.getElementById("startRoundHint");var status=document.getElementById("playerCountStatus");if(!btn||!hint||!status){return;}var count=(data&&data.session&&typeof data.session.players_count==="number")?data.session.players_count:null;if(count===null){btn.disabled=true;status.textContent="Spillere i session: ukendt";hint.textContent="Opdatér session-status for at validere min. 3 spillere.";return;}status.textContent="Spillere i session: "+count;if(count<3){btn.disabled=true;hint.textContent="Mangler spillere: kræver mindst 3 for at starte runde.";return;}btn.disabled=false;hint.textContent="Klar: nok spillere til at starte runde.";}
|
function syncStartRoundGuard(data){var btn=document.getElementById("startRoundBtn");var hint=document.getElementById("startRoundHint");var status=document.getElementById("playerCountStatus");if(!btn||!hint||!status){return;}var count=(data&&data.session&&typeof data.session.players_count==="number")?data.session.players_count:null;if(count===null){btn.disabled=true;status.textContent="Spillere i session: ukendt";hint.textContent="Opdatér session-status for at validere min. 3 spillere.";return;}status.textContent="Spillere i session: "+count;if(count<3){btn.disabled=true;hint.textContent="Mangler spillere: kræver mindst 3 for at starte runde.";return;}btn.disabled=false;hint.textContent="Klar: nok spillere til at starte runde.";}
|
||||||
async function api(path,method,payload){var o={method:method||"GET",headers:{"Accept":"application/json"}};if(payload!==null){o.headers["Content-Type"]="application/json";o.headers["X-CSRFToken"]=csrf();o.body=JSON.stringify(payload);}var r=await fetch(path,o);var d=await r.json().catch(function(){return {};});document.getElementById("out").textContent=JSON.stringify({status:r.status,data:d},null,2);if(d.session&&d.session.code){document.getElementById("code").value=d.session.code;}if(d.round_question&&d.round_question.id){document.getElementById("roundQuestionId").value=d.round_question.id;}syncStartRoundGuard(d);saveHostContext();return d;}
|
function updateHostActionState(){var hasCode=!!code();var hasRound=!!rq();var showQuestionBtn=document.getElementById("showQuestionBtn");var mixAnswersBtn=document.getElementById("mixAnswersBtn");var calcScoresBtn=document.getElementById("calcScoresBtn");var showScoreboardBtn=document.getElementById("showScoreboardBtn");var nextRoundBtn=document.getElementById("nextRoundBtn");var finishGameBtn=document.getElementById("finishGameBtn");var hint=document.getElementById("hostActionHint");if(showQuestionBtn){showQuestionBtn.disabled=!hasCode;}if(showScoreboardBtn){showScoreboardBtn.disabled=!hasCode;}if(nextRoundBtn){nextRoundBtn.disabled=!hasCode;}if(finishGameBtn){finishGameBtn.disabled=!hasCode;}if(mixAnswersBtn){mixAnswersBtn.disabled=!hasCode||!hasRound;}if(calcScoresBtn){calcScoresBtn.disabled=!hasCode||!hasRound;}if(!hint){return;}if(!hasCode){hint.textContent="Angiv sessionkode for at aktivere host-actions.";return;}if(!hasRound){hint.textContent="Round question id mangler: mix/beregn score er låst.";return;}hint.textContent="Host-actions er klar.";}
|
||||||
|
async function api(path,method,payload){var o={method:method||"GET",headers:{"Accept":"application/json"}};if(payload!==null){o.headers["Content-Type"]="application/json";o.headers["X-CSRFToken"]=csrf();o.body=JSON.stringify(payload);}var r=await fetch(path,o);var d=await r.json().catch(function(){return {};});document.getElementById("out").textContent=JSON.stringify({status:r.status,data:d},null,2);if(d.session&&d.session.code){document.getElementById("code").value=d.session.code;}if(d.round_question&&d.round_question.id){document.getElementById("roundQuestionId").value=d.round_question.id;}syncStartRoundGuard(d);updateHostActionState();saveHostContext();return d;}
|
||||||
function createSession(){return api("/lobby/sessions/create","POST",{});}
|
function createSession(){return api("/lobby/sessions/create","POST",{});}
|
||||||
function sessionDetail(){return api("/lobby/sessions/"+code(),"GET",null);}
|
function sessionDetail(){return api("/lobby/sessions/"+code(),"GET",null);}
|
||||||
function startRound(){if(document.getElementById("startRoundBtn").disabled){return Promise.resolve({error:"not_enough_players_client_guard"});}return api("/lobby/sessions/"+code()+"/rounds/start","POST",{category_slug:document.getElementById("category").value});}
|
function startRound(){if(document.getElementById("startRoundBtn").disabled){return Promise.resolve({error:"not_enough_players_client_guard"});}return api("/lobby/sessions/"+code()+"/rounds/start","POST",{category_slug:document.getElementById("category").value});}
|
||||||
@@ -35,8 +37,8 @@ function calcScores(){return api("/lobby/sessions/"+code()+"/questions/"+rq()+"/
|
|||||||
function showScoreboard(){return api("/lobby/sessions/"+code()+"/scoreboard","GET",null);}
|
function showScoreboard(){return api("/lobby/sessions/"+code()+"/scoreboard","GET",null);}
|
||||||
function nextRound(){return api("/lobby/sessions/"+code()+"/rounds/next","POST",{});}
|
function nextRound(){return api("/lobby/sessions/"+code()+"/rounds/next","POST",{});}
|
||||||
function finishGame(){return api("/lobby/sessions/"+code()+"/finish","POST",{});}
|
function finishGame(){return api("/lobby/sessions/"+code()+"/finish","POST",{});}
|
||||||
["code","roundQuestionId"].forEach(function(fieldId){var field=document.getElementById(fieldId);if(!field){return;}field.addEventListener("input",function(){syncStartRoundGuard(null);saveHostContext();});field.addEventListener("change",function(){syncStartRoundGuard(null);saveHostContext();});});
|
["code","roundQuestionId"].forEach(function(fieldId){var field=document.getElementById(fieldId);if(!field){return;}field.addEventListener("input",function(){syncStartRoundGuard(null);updateHostActionState();saveHostContext();});field.addEventListener("change",function(){syncStartRoundGuard(null);updateHostActionState();saveHostContext();});});
|
||||||
syncStartRoundGuard(null);
|
syncStartRoundGuard(null);updateHostActionState();
|
||||||
if(restoreHostContext()){sessionDetail();}else{saveHostContext();}
|
if(restoreHostContext()){sessionDetail();}else{saveHostContext();}
|
||||||
</script>
|
</script>
|
||||||
</body></html>
|
</body></html>
|
||||||
|
|||||||
@@ -775,6 +775,11 @@ class UiScreenTests(TestCase):
|
|||||||
self.assertContains(response, "Host panel")
|
self.assertContains(response, "Host panel")
|
||||||
self.assertContains(response, "saveHostContext")
|
self.assertContains(response, "saveHostContext")
|
||||||
self.assertContains(response, "restoreHostContext")
|
self.assertContains(response, "restoreHostContext")
|
||||||
|
self.assertContains(response, "id=\"showQuestionBtn\"")
|
||||||
|
self.assertContains(response, "id=\"mixAnswersBtn\"")
|
||||||
|
self.assertContains(response, "id=\"hostActionHint\"")
|
||||||
|
self.assertContains(response, "updateHostActionState")
|
||||||
|
self.assertContains(response, "Angiv sessionkode for at aktivere host-actions.")
|
||||||
|
|
||||||
def test_player_screen_is_public(self):
|
def test_player_screen_is_public(self):
|
||||||
response = self.client.get(reverse("lobby:player_screen"))
|
response = self.client.get(reverse("lobby:player_screen"))
|
||||||
|
|||||||
Reference in New Issue
Block a user