Quiz is no loner stored in player's browser and more improvements under the hood

This commit is contained in:
Mawoka
2022-09-19 19:21:24 +02:00
parent 8039269cf3
commit 2c02f2ef54
9 changed files with 209 additions and 97 deletions
+36 -9
View File
@@ -43,6 +43,10 @@
});
timer_res = '0';
};
const show_solutions = () => {
socket.emit('show_solutions', {});
timer_res = '0';
};
const get_final_results = () => {
socket.emit('get_final_results', {});
@@ -67,6 +71,7 @@
let timer_interval = setInterval(() => {
if (timer_res === '0') {
clearInterval(timer_interval);
socket.emit('show_solutions', {});
return;
} else {
seconds--;
@@ -85,6 +90,7 @@
circular_prgoress = 0;
}
}
$: console.log(quiz_data.questions.length, 'length of quiz');
</script>
{#if game_mode === 'kahoot'}
@@ -100,13 +106,32 @@
</div>
{/if}
<div class="justify-self-end ml-auto mr-0 col-start-3 col-end-3">
<button
on:click={() => {
set_question_number(selected_question + 1);
}}
>Next Question ({selected_question + 2}
)
</button>
{#if selected_question + 1 === quiz_data.questions.length && timer_res === '0'}
{#if JSON.stringify(final_results) === JSON.stringify([null])}
<button on:click={get_final_results}>Get final results</button>
{/if}
{:else if timer_res === '0' || selected_question === -1}
<button
on:click={() => {
set_question_number(selected_question + 1);
}}
>Next Question ({selected_question + 2})
</button>
{#if question_results === null && selected_question !== -1}
<button on:click={get_question_results}>Show results</button>
{/if}
{:else if selected_question !== -1}
<button on:click={show_solutions}>Stop time and show solutions</button>
{:else}
<p>!OK!</p>
<button
on:click={() => {
set_question_number(selected_question + 1);
}}
>Next Question ({selected_question + 2}
)
</button>
{/if}
</div>
</div>
{#if timer_res !== '0' && selected_question >= 0}
@@ -228,10 +253,12 @@
{#if game_mode === 'normal'}
<div class="w-full flex justify-center">
<button
on:click={get_question_results}
on:click={() => {
timer_res = '0';
}}
id="GetQuestionResultsAndStopTime"
class="px-4 py-2 leading-5 text-white transition-colors duration-200 transform bg-gray-700 rounded text-center hover:bg-gray-600 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50"
>{$t('admin_page.get_results_and_stop_time')}</button
>{$t('admin_page.stop_time')}</button
>
</div>
{/if}
+13 -6
View File
@@ -9,7 +9,7 @@
const { t } = getLocalization();
export let quiz_data: QuizData;
export let question_count: number;
export let final_results: Array<null> | Array<Array<PlayerAnswer>>;
interface PlayerAnswer {
@@ -23,7 +23,7 @@
const getWinnersSorted = () => {
let winners = {};
let q_count = quiz_data.questions.length;
let q_count = question_count;
console.log(
JSON.stringify(final_results),
JSON.stringify(final_results) === '{}',
@@ -42,9 +42,15 @@
try {
for (let i = 0; i < q_count; i++) {
let q_res = final_results[i];
if (q_res === null) {
if (!q_res) {
continue;
} else {
q_res = final_results[String(i)];
if (!q_res) {
continue;
}
}
console.log(q_res);
for (let j = 0; j < q_res.length; j++) {
let res = q_res[j];
if (res['right']) {
@@ -68,6 +74,7 @@
data_available = true;
return close_to_res;
} catch (e) {
console.log(e);
data_available = false;
}
};
@@ -93,7 +100,7 @@
<span
>{$t('play_page.with_out_of', {
correct_questions: winners_arr[0][1] ?? 0,
total_question_count: quiz_data.questions.length
total_question_count: question_count
})}</span
>
</p>
@@ -106,7 +113,7 @@
<span
>{$t('play_page.with_out_of', {
correct_questions: winners_arr[1][1] ?? 0,
total_question_count: quiz_data.questions.length
total_question_count: question_count
})}</span
>
</p>
@@ -120,7 +127,7 @@
<span>
{$t('play_page.with_out_of', {
correct_questions: winners_arr[2][1] ?? 0,
total_question_count: quiz_data.questions.length
total_question_count: question_count
})}
</span>
</p>
+55 -29
View File
@@ -17,13 +17,23 @@
export let question: Question;
export let game_mode;
export let question_index: string | number;
export let solution;
if (typeof question_index === 'string') {
question_index = parseInt(question_index);
$: console.log(question_index, question, 'hi!');
console.log(question);
if (question.type === undefined) {
question.type = QuizQuestionType.ABCD;
} else {
throw new Error('question_index must be a string or number');
question.type = QuizQuestionType[question.type];
}
/* if (typeof question_index === 'string') {
question_index = parseInt(question_index);
} else {
throw new Error('question_index must be a string or number');
}*/
let timer_res = question.time;
let selected_answer: string;
@@ -44,6 +54,12 @@
timer(question.time);
$: {
if (solution !== undefined) {
timer_res = '0';
}
}
const selectAnswer = (answer: string) => {
selected_answer = answer;
//timer_res = '0';
@@ -75,6 +91,8 @@
circular_prgoress = 0;
}
}
$: console.log(solution);
</script>
<div class="flex flex-col justify-center w-screen h-1/6">
@@ -149,31 +167,39 @@
{/await}
{/if}
{:else if question.type === QuizQuestionType.ABCD}
<div class="flex flex-wrap">
{#each question.answers as answer}
{#if answer.right}
<button
class="w-1/2 text-3xl bg-green-600 border border-white"
disabled
class:opacity-30={answer.answer !== selected_answer}>{answer.answer}</button
>
{:else}
<button
class="w-1/2 text-3xl bg-red-500 border border-white"
disabled
class:opacity-30={answer.answer !== selected_answer}>{answer.answer}</button
>
{/if}
{/each}
</div>
{#if solution === undefined}
<Spinner />
{:else}
<div class="flex flex-wrap">
{#each solution.answers as answer}
{#if answer.right}
<button
class="w-1/2 text-3xl bg-green-600 border border-white"
disabled
class:opacity-30={answer.answer !== selected_answer}>{answer.answer}</button
>
{:else}
<button
class="w-1/2 text-3xl bg-red-500 border border-white"
disabled
class:opacity-30={answer.answer !== selected_answer}>{answer.answer}</button
>
{/if}
{/each}
</div>
{/if}
{:else if question.type === QuizQuestionType.RANGE}
<p class="text-center">
Every number between {question.answers.min_correct} and {question.answers.max_correct} was correct.
You got {selected_answer}, so you have been
{#if question.answers.min_correct <= parseInt(selected_answer) && parseInt(selected_answer) <= question.answers.max_correct}
correct
{:else}
wrong.
{/if}
</p>
{#if solution === undefined}
<Spinner />
{:else}
<p class="text-center">
Every number between {solution.answers.min_correct} and {solution.answers.max_correct} was
correct. You got {selected_answer}, so you have been
{#if solution.answers.min_correct <= parseInt(selected_answer) && parseInt(selected_answer) <= solution.answers.max_correct}
correct
{:else}
wrong.
{/if}
</p>
{/if}
{/if}
+12 -14
View File
@@ -4,7 +4,7 @@
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<script lang="ts">
import type { Answer, QuizData } from '$lib/quiz_types';
import type { Answer, Question, QuizData } from '$lib/quiz_types';
import { getLocalization } from '$lib/i18n';
import { QuizQuestionType } from '../quiz_types.js';
import Spinner from '$lib/Spinner.svelte';
@@ -12,10 +12,11 @@
const { t } = getLocalization();
export let results: Array<Answer>;
export let game_data: QuizData;
export let solution: Question;
export let question_index: string;
let data_store = {};
const question = game_data.questions[parseInt(question_index)].answers;
const question = solution.answers;
for (let i = 0; i < question.length; i++) {
data_store[question[i].answer] = 0;
}
@@ -24,11 +25,8 @@
data_store[results[i].answer] += 1;
}
let slider_values = [
game_data.questions[parseInt(question_index)].answers.min_correct ?? 0,
game_data.questions[parseInt(question_index)].answers.max_correct ?? 0
];
console.log(slider_values, game_data.questions[parseInt(question_index)].answers);
let slider_values = [solution.answers.min_correct ?? 0, solution.answers.max_correct ?? 0];
console.log(slider_values, solution.answers);
</script>
<!-- Show the results from the results object -->
@@ -38,7 +36,7 @@
<div>
<h2 class="text-center text-3xl mb-8">{$t('words.result', { count: 2 })}</h2>
<div class="w-screen flex justify-center">
{#if game_data.questions[parseInt(question_index)].type === QuizQuestionType.ABCD}
{#if solution.type === QuizQuestionType.ABCD}
<div class="relative overflow-x-auto shadow-md rounded-lg">
<table class="w-fit text-sm text-left text-gray-500 dark:text-gray-400">
<thead class="bg-gray-50 dark:bg-gray-700">
@@ -64,7 +62,7 @@
</tr>
</thead>
<tbody>
{#each game_data.questions[parseInt(question_index)].answers as answer}
{#each solution.answers as answer}
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<td
class="py-4 px-6 text-sm font-medium text-gray-900 whitespace-nowrap dark:text-white"
@@ -90,10 +88,10 @@
</tbody>
</table>
</div>
{:else if game_data.questions[parseInt(question_index)].type === QuizQuestionType.RANGE}
{:else if solution.type === QuizQuestionType.RANGE}
<!--<p class="text-center">
Every number between {game_data.questions[parseInt(question_index)].answers
.min_correct} and {game_data.questions[parseInt(question_index)].answers
Every number between {solution.answers
.min_correct} and {solution.answers
.max_correct} was correct.
</p>-->
{#await import('svelte-range-slider-pips')}
@@ -103,8 +101,8 @@
<svelte:component
this={c.default}
bind:values={slider_values}
bind:min={game_data.questions[parseInt(question_index)].answers.min}
bind:max={game_data.questions[parseInt(question_index)].answers.max}
bind:min={solution.answers.min}
bind:max={solution.answers.max}
pips
float
all="label"
+5 -1
View File
@@ -119,7 +119,11 @@
>
</div>
{#await import('$lib/play/end.svelte') then c}
<svelte:component this={c.default} bind:final_results bind:quiz_data />
<svelte:component
this={c.default}
bind:final_results
bind:question_count={quiz_data.questions.length}
/>
{/await}
{/if}
{#if !success}
+19 -22
View File
@@ -2,7 +2,7 @@
<script lang="ts">
import { socket } from '$lib/socket';
import JoinGame from '$lib/play/join.svelte';
import type { Answer, QuizData } from '$lib/quiz_types';
import type { Answer, QuizData, Question } from '$lib/quiz_types';
import ShowTitle from '$lib/play/title.svelte';
import Question from '$lib/play/question.svelte';
import ShowResults from '$lib/play/show_results.svelte';
@@ -37,11 +37,14 @@
navbarVisible.set(false);
let game_pin_valid: boolean;
let answer_results: Array<Answer>;
let gameData: QuizData;
let gameData;
let solution: Question;
let gameMeta: GameMeta = {
started: false
};
let question;
// Functions
function restart() {
unique = {};
@@ -56,17 +59,7 @@
// Socket-events
socket.on('joined_game', (data) => {
console.log('joined_game', data);
let temp_data = JSON.parse(data);
for (let i = 0; i < temp_data.questions.length; i++) {
let question = temp_data.questions[i];
if (question.type === undefined) {
temp_data.questions[i].type = QuizQuestionType.ABCD;
} else {
temp_data.questions[i].type = QuizQuestionType[question.type];
}
}
gameData = temp_data;
gameData = data;
// eslint-disable-next-line no-undef
plausible('Joined Game', { props: { quiz_id: gameData.quiz_id } });
});
@@ -76,9 +69,12 @@
});
socket.on('set_question_number', (data) => {
solution = undefined;
restart();
console.log(data, data.question_index);
question = data.question;
question_index = data.question_index;
answer_results = undefined;
question_index = data;
});
socket.on('start_game', () => {
@@ -97,6 +93,10 @@
socket.on('final_results', (data) => {
final_results = data;
});
socket.on('solutions', (data) => {
solution = data;
});
// The rest
</script>
@@ -109,19 +109,19 @@
<svelte:window on:beforeunload={confirmUnload} />
<svelte:head>
<title>ClassQuiz - Play</title>
{#if gameData !== undefined && game_mode !== 'kahoot'}
<!-- {#if gameData !== undefined && game_mode !== 'kahoot'}
{#each gameData.questions as question}
{#if question.image !== undefined}
<link rel="preload" as="image" href={question.image} />
{/if}
{/each}
{/if}
{/if}-->
</svelte:head>
<div>
{#if !gameMeta.started && gameData === undefined}
<JoinGame {game_pin} bind:game_mode />
{:else if JSON.stringify(final_results) !== JSON.stringify([null])}
<ShowEndScreen bind:final_results bind:quiz_data={gameData} />
<ShowEndScreen bind:final_results bind:question_count={gameData.question_count} />
{:else if gameData !== undefined && question_index === ''}
<ShowTitle
bind:title={gameData.title}
@@ -130,11 +130,7 @@
/>
{:else if gameMeta.started && gameData !== undefined && question_index !== '' && answer_results === undefined}
{#key unique}
<Question
bind:game_mode
bind:question={gameData.questions[parseInt(question_index)]}
bind:question_index
/>
<Question bind:game_mode bind:question bind:question_index bind:solution />
{/key}
{:else if gameMeta.started && answer_results !== undefined}
{#if answer_results === null}
@@ -147,6 +143,7 @@
bind:results={answer_results}
bind:game_data={gameData}
bind:question_index
bind:solution
/>
{/key}
{/if}