From 99bd6cc32974ae06a3cb3319e55851eb7043b369 Mon Sep 17 00:00:00 2001 From: Mawoka Date: Tue, 4 Oct 2022 12:38:04 +0200 Subject: [PATCH 1/7] :sparkles: Implemented in Editor --- classquiz/db/models.py | 13 ++- .../lib/editor/RangeSelectorEditorPart.svelte | 4 +- .../src/lib/editor/VotingEditorPart.svelte | 83 +++++++++++++++++++ frontend/src/lib/editor/card.svelte | 13 ++- frontend/src/lib/editor/settings-card.svelte | 4 +- frontend/src/lib/editor/sidebar.svelte | 24 ++++++ frontend/src/lib/quiz_types.ts | 10 ++- frontend/src/lib/yupSchemas.ts | 25 +++++- 8 files changed, 162 insertions(+), 14 deletions(-) create mode 100644 frontend/src/lib/editor/VotingEditorPart.svelte diff --git a/classquiz/db/models.py b/classquiz/db/models.py index dbc41ba..ef79cea 100644 --- a/classquiz/db/models.py +++ b/classquiz/db/models.py @@ -85,24 +85,33 @@ class RangeQuizAnswer(BaseModel): max_correct: int +class VotingQuizAnswer(BaseModel): + answer: str + image: str | None = None + color: str | None + + class QuizQuestionType(str, Enum): ABCD = "ABCD" RANGE = "RANGE" + VOTING = "VOTING" class QuizQuestion(BaseModel): question: str time: str # in Secs type: None | QuizQuestionType = QuizQuestionType.ABCD - answers: list[ABCDQuizAnswer] | RangeQuizAnswer + answers: list[ABCDQuizAnswer] | RangeQuizAnswer | list[VotingQuizAnswer] image: str | None = None @validator("answers") def answers_not_none_if_abcd_type(cls, v, values): - if values["type"] == QuizQuestionType.ABCD and len(v) == 0: + if values["type"] == QuizQuestionType.ABCD and type(v[0]) != ABCDQuizAnswer: raise ValueError("Answers can't be none if type is ABCD") if values["type"] == QuizQuestionType.RANGE and type(v) != RangeQuizAnswer: raise ValueError("Answer must be from type RangeQuizAnswer if type is RANGE") + if values["type"] == QuizQuestionType.VOTING and type(v[0]) != VotingQuizAnswer: + raise ValueError("Answer must be from type RangeQuizAnswer if type is RANGE") return v diff --git a/frontend/src/lib/editor/RangeSelectorEditorPart.svelte b/frontend/src/lib/editor/RangeSelectorEditorPart.svelte index 541efaf..278bd53 100644 --- a/frontend/src/lib/editor/RangeSelectorEditorPart.svelte +++ b/frontend/src/lib/editor/RangeSelectorEditorPart.svelte @@ -66,10 +66,10 @@ {#await import('svelte-range-slider-pips')} - + {:then c} {#await sleep(100)} - + {:then _} + + + + +
+ {#if Array.isArray(data.questions[selected_question].answers)} + {#each data.questions[selected_question].answers as answer, index} +
+ { + data.questions[selected_question].answers.splice(index, 1); + data.questions[selected_question].answers = + data.questions[selected_question].answers; + }} + class="border-b-2 border-dotted w-5/6 text-center rounded-lg" + style="background-color: {answer.color ?? 'transparent'}" + placeholder="Empty..." + /> + { + answer.color = null; + }} + /> +
+ {/each} + {/if} + {#if data.questions[selected_question].answers.length < 4} + + {/if} +
diff --git a/frontend/src/lib/editor/card.svelte b/frontend/src/lib/editor/card.svelte index c2f4650..0ac4f7d 100644 --- a/frontend/src/lib/editor/card.svelte +++ b/frontend/src/lib/editor/card.svelte @@ -96,11 +96,11 @@ use:tippy={{ content: "Click to learn why it's loading so long." }} class="cursor-help" > - + {:else} {#await import('$lib/editor/uploader.svelte')} - + {:then c} +
{#if data.questions[selected_question].type === QuizQuestionType.ABCD} {#await import('$lib/editor/ABCDEditorPart.svelte')} - + {:then c} {/await} {:else if data.questions[selected_question].type === QuizQuestionType.RANGE} + {:else if data.questions[selected_question].type === QuizQuestionType.VOTING} + {#await import('$lib/editor/VotingEditorPart.svelte')} + + {:then c} + + {/await} {/if}

{$t('editor_page.right_click_to_delete')}

diff --git a/frontend/src/lib/editor/settings-card.svelte b/frontend/src/lib/editor/settings-card.svelte index 1d80891..068192e 100644 --- a/frontend/src/lib/editor/settings-card.svelte +++ b/frontend/src/lib/editor/settings-card.svelte @@ -67,11 +67,11 @@ {:else if pow_data === undefined} - + {:else} {#await import('$lib/editor/uploader.svelte')} - + {:then c} + {:else if question.type === QuizQuestionType.VOTING} + {#if Array.isArray(question.answers)} +
+ {#each question.answers as answer} + {#if answer.answer === ''} + Empty... + {:else} + {answer.answer} + {/if} + {/each} +
+ {/if} {:else}

Unknown Question Type (shouldn't happen)

{/if} diff --git a/frontend/src/lib/quiz_types.ts b/frontend/src/lib/quiz_types.ts index 93b3fde..5793508 100644 --- a/frontend/src/lib/quiz_types.ts +++ b/frontend/src/lib/quiz_types.ts @@ -18,7 +18,8 @@ export interface QuizData { export enum QuizQuestionType { ABCD = 'ABCD', // eslint-disable-line no-unused-vars - RANGE = 'RANGE' // eslint-disable-line no-unused-vars + RANGE = 'RANGE', // eslint-disable-line no-unused-vars + VOTING = 'VOTING' // eslint-disable-line no-unused-vars } export interface RangeQuizAnswer { @@ -33,7 +34,7 @@ export interface Question { question: string; type?: QuizQuestionType; image?: string; - answers: Answer[] | RangeQuizAnswer; + answers: Answer[] | RangeQuizAnswer | VotingAnswer[]; } export interface Answer { @@ -41,6 +42,11 @@ export interface Answer { answer: string; color?: string; } +export interface VotingAnswer { + answer: string; + image?: string; + color?: string; +} export interface EditorData { public: boolean; diff --git a/frontend/src/lib/yupSchemas.ts b/frontend/src/lib/yupSchemas.ts index 6309e1f..3f81e4a 100644 --- a/frontend/src/lib/yupSchemas.ts +++ b/frontend/src/lib/yupSchemas.ts @@ -17,6 +17,17 @@ export const ABCDQuestionSchema = yup .min(2, 'You need at least 2 answers') .max(16, "You can't have more than 16 answers"); +export const VotingQuestionSchema = yup + .array() + .of( + yup.object({ + answer: yup.string().required('You need an answer'), + image: yup.string().optional().nullable() + }) + ) + .min(2, 'You need at least 2 answers') + .max(16, "You can't have more than 16 answers"); + export const RangeQuestionSchema = yup.object({ min: yup.number(), max: yup.number(), @@ -50,9 +61,17 @@ export const dataSchema = yup.object({ "The image-url isn't valid" ) .lowercase(), - answers: yup.lazy((v) => - Array.isArray(v) ? ABCDQuestionSchema : RangeQuestionSchema - ) + answers: yup.lazy((v) => { + if (Array.isArray(v)) { + if (typeof v[0].right === 'boolean') { + return ABCDQuestionSchema; + } else { + return VotingQuestionSchema; + } + } else { + return RangeQuestionSchema; + } + }) }) ) .min(1, 'You need at least one question') From d11207cdea94cfb20aaa0a900b1c93ad3b54dc7e Mon Sep 17 00:00:00 2001 From: Mawoka Date: Tue, 4 Oct 2022 12:41:54 +0200 Subject: [PATCH 2/7] :sparkles: Implemented in Dashboard --- frontend/src/lib/dashboard/main_slider.svelte | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontend/src/lib/dashboard/main_slider.svelte b/frontend/src/lib/dashboard/main_slider.svelte index 55eee97..b7ad921 100644 --- a/frontend/src/lib/dashboard/main_slider.svelte +++ b/frontend/src/lib/dashboard/main_slider.svelte @@ -247,6 +247,18 @@ numbers between {question.answers.min} and {question .answers.max} can be selected.

+ {:else if question.type === QuizQuestionType.VOTING} +
+ {#each question.answers as answer} +
+

+ {answer.answer} +

+
+ {/each} +
{/if} From 512fc9e8eaf57f67e3929ea32c8db9786451fb1f Mon Sep 17 00:00:00 2001 From: Mawoka Date: Tue, 4 Oct 2022 12:46:42 +0200 Subject: [PATCH 3/7] :sparkles: Implemented in Public-Quiz-View --- frontend/src/routes/view/[quiz_id]/+page.svelte | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/src/routes/view/[quiz_id]/+page.svelte b/frontend/src/routes/view/[quiz_id]/+page.svelte index 3189b60..5a0c39f 100644 --- a/frontend/src/routes/view/[quiz_id]/+page.svelte +++ b/frontend/src/routes/view/[quiz_id]/+page.svelte @@ -169,6 +169,17 @@ and {question.answers.max_correct} are correct, where numbers between {question .answers.min} and {question.answers.max} can be selected.

+ {:else if question.type === QuizQuestionType.VOTING} +
+ {#each question.answers as answer, index_answer} +
+

+ {quiz.questions[index_question].answers[index_answer] + .answer} +

+
+ {/each} +
{/if} From 60822283e361c6d9cd5924655c9bbadc7eae7139 Mon Sep 17 00:00:00 2001 From: Mawoka Date: Tue, 4 Oct 2022 15:38:15 +0200 Subject: [PATCH 4/7] :sparkles: Implemented in Live-Game --- classquiz/db/models.py | 2 +- classquiz/socket_server/__init__.py | 27 ++-- frontend/pnpm-lock.yaml | 90 ++++-------- frontend/src/lib/admin.svelte | 40 ++++-- .../src/lib/editor/VotingEditorPart.svelte | 17 ++- .../src/lib/play/admin/voting_results.svelte | 50 +++++++ frontend/src/lib/play/question.svelte | 9 +- frontend/src/lib/practice/question.svelte | 102 ++++++++------ frontend/src/lib/yupSchemas.ts | 3 + frontend/src/routes/create/+page.svelte | 13 +- frontend/src/routes/test/+page.svelte | 129 ++++++++++++++++++ 11 files changed, 338 insertions(+), 144 deletions(-) create mode 100644 frontend/src/lib/play/admin/voting_results.svelte create mode 100644 frontend/src/routes/test/+page.svelte diff --git a/classquiz/db/models.py b/classquiz/db/models.py index ef79cea..829f867 100644 --- a/classquiz/db/models.py +++ b/classquiz/db/models.py @@ -111,7 +111,7 @@ class QuizQuestion(BaseModel): if values["type"] == QuizQuestionType.RANGE and type(v) != RangeQuizAnswer: raise ValueError("Answer must be from type RangeQuizAnswer if type is RANGE") if values["type"] == QuizQuestionType.VOTING and type(v[0]) != VotingQuizAnswer: - raise ValueError("Answer must be from type RangeQuizAnswer if type is RANGE") + raise ValueError("Answer must be from type VotingQuizAnswer if type is VOTING") return v diff --git a/classquiz/socket_server/__init__.py b/classquiz/socket_server/__init__.py index 537f2f7..29e3bfd 100644 --- a/classquiz/socket_server/__init__.py +++ b/classquiz/socket_server/__init__.py @@ -11,7 +11,7 @@ import socketio from cryptography.fernet import Fernet from classquiz.config import redis, settings -from classquiz.db.models import PlayGame, QuizQuestionType, GameSession, GamePlayer, QuizQuestion +from classquiz.db.models import PlayGame, QuizQuestionType, GameSession, GamePlayer, QuizQuestion, VotingQuizAnswer from pydantic import BaseModel, ValidationError, validator from datetime import datetime @@ -113,8 +113,10 @@ async def join_game(sid: str, data: dict): {"username": data.username, "sid": sid}, room=redis_res.admin, ) - lol = fernet.encrypt(datetime.now().isoformat().encode("utf-8")).decode("utf-8") - await sio.emit("time_sync", lol, room=sid) + # +++ Time-Sync +++ + encrypted_datetime = fernet.encrypt(datetime.now().isoformat().encode("utf-8")).decode("utf-8") + await sio.emit("time_sync", encrypted_datetime, room=sid) + # --- Time-Sync --- sio.enter_room(sid, data.game_pin) @@ -183,14 +185,16 @@ class RangeQuizAnswerWithoutSolution(BaseModel): class ReturnQuestion(QuizQuestion): - answers: list[ABCDQuizAnswerWithoutSolution] | RangeQuizAnswerWithoutSolution + answers: list[ABCDQuizAnswerWithoutSolution] | RangeQuizAnswerWithoutSolution | list[VotingQuizAnswer] @validator("answers") def answers_not_none_if_abcd_type(cls, v, values): - if values["type"] == QuizQuestionType.ABCD and len(v) == 0: + if values["type"] == QuizQuestionType.ABCD and type(v[0]) != ABCDQuizAnswerWithoutSolution: raise ValueError("Answers can't be none if type is ABCD") if values["type"] == QuizQuestionType.RANGE and type(v) != RangeQuizAnswerWithoutSolution: raise ValueError("Answer must be from type RangeQuizAnswer if type is RANGE") + if values["type"] == QuizQuestionType.VOTING and type(v[0]) != VotingQuizAnswer: + print("Answer must be from type VotingQuizAnswer if type is VOTING") return v @@ -204,13 +208,17 @@ async def set_question_number(sid, data: str): game_data.current_question = int(float(data)) await redis.set(f"game:{session['game_pin']}", game_data.json()) await redis.set(f"game:{session['game_pin']}:current_time", datetime.now().isoformat()) + # print(game_data.dict(include={"questions"})["questions"][int(float(data))]) + temp_return = game_data.dict(include={"questions"})["questions"][int(float(data))] + if game_data.questions[int(float(data))].type == QuizQuestionType.VOTING: + for i in range(len(temp_return["answers"])): + temp_return["answers"][i] = VotingQuizAnswer(**temp_return["answers"][i]) + print(temp_return) await sio.emit( "set_question_number", { "question_index": int(float(data)), - "question": ReturnQuestion( - **game_data.dict(include={"questions"})["questions"][int(float(data))] - ).dict(), + "question": ReturnQuestion(**temp_return).dict(), }, room=game_pin, ) @@ -258,6 +266,8 @@ async def submit_answer(sid: str, data: dict): <= game_data.questions[int(float(data.question_index))].answers.max_correct ): answer_right = True + elif game_data.questions[int(float(data.question_index))].type == QuizQuestionType.VOTING: + answer_right = False else: raise NotImplementedError latency = int(float((await sio.get_session(sid))["ping"])) @@ -317,7 +327,6 @@ async def submit_answer(sid: str, data: dict): async def get_final_results(sid: str, _data: dict): session: dict = await sio.get_session(sid) game_data = PlayGame(**json.loads(await redis.get(f"game:{session['game_pin']}"))) - results = {} if not session["admin"]: return results = await generate_final_results(game_data, session["game_pin"]) diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index fcaab13..2e68f12 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -77,7 +77,7 @@ devDependencies: '@sentry/tracing': 7.11.1 '@sveltejs/adapter-auto': 1.0.0-next.80 '@sveltejs/adapter-node': 1.0.0-next.86 - '@sveltejs/kit': 1.0.0-next.504_svelte@3.49.0+vite@3.1.2 + '@sveltejs/kit': 1.0.0-next.508_svelte@3.49.0+vite@3.1.2 '@tailwindcss/typography': 0.5.4_tailwindcss@3.1.8 '@types/canvas-confetti': 1.4.3 '@types/cookie': 0.5.1 @@ -579,10 +579,10 @@ packages: - supports-color dev: true - /@sveltejs/kit/1.0.0-next.504_svelte@3.49.0+vite@3.1.2: + /@sveltejs/kit/1.0.0-next.508_svelte@3.49.0+vite@3.1.2: resolution: { - integrity: sha512-KrhlSHT3aCVnhRgUoN6aGIjIw3nWEdNwfoZcE1x65F5D7Ju/K9D8dQwyal9v0aBAZyN9nFuXxsYGaMLE9sppfw== + integrity: sha512-qUnuhuL82meE0lSwrsS/FIvtDoE83Au4SxVLCim3FzoCnJc7bFZ9vYRbRUYxAjfYKRMjKVUrp9iHFObn9LmnUg== } engines: { node: '>=16.14' } hasBin: true @@ -598,13 +598,12 @@ packages: kleur: 4.1.5 magic-string: 0.26.3 mime: 3.0.0 - node-fetch: 3.2.10 sade: 1.8.1 set-cookie-parser: 2.5.1 sirv: 2.0.2 svelte: 3.49.0 tiny-glob: 0.2.9 - undici: 5.9.1 + undici: 5.11.0 vite: 3.1.2_sass@1.54.4 transitivePeerDependencies: - diff-match-patch @@ -1398,6 +1397,16 @@ packages: } dev: true + /busboy/1.6.0: + resolution: + { + integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + } + engines: { node: '>=10.16.0' } + dependencies: + streamsearch: 1.1.0 + dev: true + /callsites/3.1.0: resolution: { @@ -1717,14 +1726,6 @@ packages: css-tree: 1.1.3 dev: true - /data-uri-to-buffer/4.0.0: - resolution: - { - integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== - } - engines: { node: '>= 12' } - dev: true - /debug/4.3.4: resolution: { @@ -2503,17 +2504,6 @@ packages: svelte: 3.49.0 dev: true - /fetch-blob/3.2.0: - resolution: - { - integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== - } - engines: { node: ^12.20 || >= 14.13 } - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.2.1 - dev: true - /file-entry-cache/6.0.1: resolution: { @@ -2570,16 +2560,6 @@ packages: } dev: true - /formdata-polyfill/4.0.10: - resolution: - { - integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== - } - engines: { node: '>=12.20.0' } - dependencies: - fetch-blob: 3.2.0 - dev: true - /fraction.js/4.2.0: resolution: { @@ -3358,14 +3338,6 @@ packages: } dev: true - /node-domexception/1.0.0: - resolution: - { - integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== - } - engines: { node: '>=10.5.0' } - dev: true - /node-fetch/2.6.7: resolution: { @@ -3381,18 +3353,6 @@ packages: whatwg-url: 5.0.0 dev: true - /node-fetch/3.2.10: - resolution: - { - integrity: sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA== - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - dependencies: - data-uri-to-buffer: 4.0.0 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - dev: true - /node-gyp-build/4.5.0: resolution: { @@ -4540,6 +4500,14 @@ packages: deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' dev: true + /streamsearch/1.1.0: + resolution: + { + integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + } + engines: { node: '>=10.0.0' } + dev: true + /string-width/4.2.3: resolution: { @@ -4960,12 +4928,14 @@ packages: } dev: true - /undici/5.9.1: + /undici/5.11.0: resolution: { - integrity: sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg== + integrity: sha512-oWjWJHzFet0Ow4YZBkyiJwiK5vWqEYoH7BINzJAJOLedZ++JpAlCbUktW2GQ2DS2FpKmxD/JMtWUUWl1BtghGw== } engines: { node: '>=12.18' } + dependencies: + busboy: 1.6.0 dev: true /update-browserslist-db/1.0.5_browserslist@4.21.3: @@ -5057,14 +5027,6 @@ packages: pbf: 3.2.1 dev: true - /web-streams-polyfill/3.2.1: - resolution: - { - integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== - } - engines: { node: '>= 8' } - dev: true - /webidl-conversions/3.0.1: resolution: { diff --git a/frontend/src/lib/admin.svelte b/frontend/src/lib/admin.svelte index 0662483..8cf5b91 100644 --- a/frontend/src/lib/admin.svelte +++ b/frontend/src/lib/admin.svelte @@ -114,8 +114,8 @@ {#if selected_question + 1 === quiz_data.questions.length && timer_res === '0' && question_results !== null} {#if JSON.stringify(final_results) === JSON.stringify([null])} + >Get final results + {/if} {:else if timer_res === '0' || selected_question === -1} {#if (selected_question + 1 !== quiz_data.questions.length && question_results !== null) || selected_question === -1} @@ -129,13 +129,13 @@ {/if} {#if question_results === null && selected_question !== -1} + >Show results + {/if} {:else if selected_question !== -1} + >Stop time and show solutions + {:else} + + +
+
+ {#each quiz_answers as answer} + {#if sorted_data[answer] > 0}{sorted_data[answer]}{/if} + {/each} + {#each quiz_answers as answer} +
+ {/each} + {#each quiz_answers as answer} +
+

{answer}

+
+ {/each} +
+
diff --git a/frontend/src/lib/play/question.svelte b/frontend/src/lib/play/question.svelte index 287cb5c..701c640 100644 --- a/frontend/src/lib/play/question.svelte +++ b/frontend/src/lib/play/question.svelte @@ -113,7 +113,7 @@
{/if} {#if timer_res !== '0'} - {#if question.type === QuizQuestionType.ABCD} + {#if question.type === QuizQuestionType.ABCD || QuizQuestionType.VOTING} {#if game_mode === 'normal'}
{#each question.answers as answer} @@ -202,4 +202,11 @@ {/if}

{/if} + {/if} diff --git a/frontend/src/lib/practice/question.svelte b/frontend/src/lib/practice/question.svelte index 0722aa0..9479887 100644 --- a/frontend/src/lib/practice/question.svelte +++ b/frontend/src/lib/practice/question.svelte @@ -91,48 +91,64 @@ {/if}
{/if} - {:else if timer_res === '0'} - {#await import('svelte-range-slider-pips')} - - {:then c} -
- -
- {/await} - {:else} - {#await import('svelte-range-slider-pips')} - - {:then c} -
- -
-
- -
- {/await} + {:else if question.type === QuizQuestionType.RANGE} + {#if timer_res === '0'} + {#await import('svelte-range-slider-pips')} + + {:then c} +
+ +
+ {/await} + {:else} + {#await import('svelte-range-slider-pips')} + + {:then c} +
+ +
+
+ +
+ {/await} + {/if} + {:else if question.type === QuizQuestionType.VOTING} + {#each question.answers as answer, i} + + {/each} + {#if timer_res === '0'} +

No correct answers, since this is a poll-question

+ {/if} {/if} diff --git a/frontend/src/lib/yupSchemas.ts b/frontend/src/lib/yupSchemas.ts index 3f81e4a..31111dd 100644 --- a/frontend/src/lib/yupSchemas.ts +++ b/frontend/src/lib/yupSchemas.ts @@ -63,9 +63,12 @@ export const dataSchema = yup.object({ .lowercase(), answers: yup.lazy((v) => { if (Array.isArray(v)) { + console.log(v); if (typeof v[0].right === 'boolean') { + console.log('Yup, ABCD'); return ABCDQuestionSchema; } else { + console.log('Yup, Poll'); return VotingQuestionSchema; } } else { diff --git a/frontend/src/routes/create/+page.svelte b/frontend/src/routes/create/+page.svelte index 80e5597..ed657f4 100644 --- a/frontend/src/routes/create/+page.svelte +++ b/frontend/src/routes/create/+page.svelte @@ -9,6 +9,7 @@ import { getLocalization } from '$lib/i18n'; import { navbarVisible } from '$lib/stores'; import { QuizQuestionType } from '$lib/quiz_types'; + import type { Question } from '$lib/quiz_types'; navbarVisible.set(false); @@ -21,18 +22,6 @@ questions: Question[]; } - interface Question { - question: string; - time: string; - type?: QuizQuestionType; - answers: Answer[]; - } - - interface Answer { - right: boolean; - answer: string; - } - let responseData = { open: false }; diff --git a/frontend/src/routes/test/+page.svelte b/frontend/src/routes/test/+page.svelte new file mode 100644 index 0000000..fc47f52 --- /dev/null +++ b/frontend/src/routes/test/+page.svelte @@ -0,0 +1,129 @@ + + + +
+
+ {#each quiz_answers as answer} + {#if sorted_data[answer] > 0}{sorted_data[answer]}{/if} + {/each} + {#each quiz_answers as answer} +
+ {/each} + {#each quiz_answers as answer} +
+

{answer}

+
+ {/each} +
+
From a4d54a18ec48e28a75029f1b5d3a14987f339abc Mon Sep 17 00:00:00 2001 From: Mawoka Date: Tue, 4 Oct 2022 16:41:17 +0200 Subject: [PATCH 5/7] :sparkles: Implemented Vote-Thing for API --- classquiz/routers/live.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classquiz/routers/live.py b/classquiz/routers/live.py index 9196304..e140bd7 100644 --- a/classquiz/routers/live.py +++ b/classquiz/routers/live.py @@ -17,6 +17,7 @@ from classquiz.db.models import ( RangeQuizAnswer, ABCDQuizAnswer, QuizQuestionType, + VotingQuizAnswer, ) from classquiz.auth import check_api_key from classquiz.socket_server import ReturnQuestion, sio @@ -35,7 +36,7 @@ class _ABCDQuizAnswer(ABCDQuizAnswer): class _QuizQuestion(QuizQuestion): - answers: list[ABCDQuizAnswer] | RangeQuizAnswer + answers: list[ABCDQuizAnswer] | RangeQuizAnswer | list[VotingQuizAnswer] class _GetLivePlayGame(PlayGame): From 8f1ee22270f50f8e15c4ed97763331e56eaa5308 Mon Sep 17 00:00:00 2001 From: Mawoka Date: Tue, 4 Oct 2022 16:45:03 +0200 Subject: [PATCH 6/7] :rotating_light: Fixed linter errors --- frontend/src/lib/editor/VotingEditorPart.svelte | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/frontend/src/lib/editor/VotingEditorPart.svelte b/frontend/src/lib/editor/VotingEditorPart.svelte index a2f14a7..0b3aab5 100644 --- a/frontend/src/lib/editor/VotingEditorPart.svelte +++ b/frontend/src/lib/editor/VotingEditorPart.svelte @@ -9,7 +9,6 @@ import { reach } from 'yup'; import { getLocalization } from '$lib/i18n'; import { VotingQuestionSchema } from '$lib/yupSchemas'; - import { onMount } from 'svelte'; const { t } = getLocalization(); @@ -24,6 +23,7 @@ if (typeof data.questions[selected_question].answers[0].right === 'boolean') { data.questions[selected_question].answers = []; } + // eslint-disable-next-line no-empty } catch {} /*console.log(data.questions[selected_question].answers, 'moIn!', data.questions[selected_question].answers.length); @@ -35,12 +35,6 @@ });*/ - -
{#if Array.isArray(data.questions[selected_question].answers)} {#each data.questions[selected_question].answers as answer, index} From 16b4cae21e3258b942b4c72930492d81771c575b Mon Sep 17 00:00:00 2001 From: Mawoka Date: Tue, 4 Oct 2022 16:47:00 +0200 Subject: [PATCH 7/7] :rotating_light: Fixed linter errors (removed console.log's) --- frontend/src/lib/yupSchemas.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/frontend/src/lib/yupSchemas.ts b/frontend/src/lib/yupSchemas.ts index 31111dd..3f81e4a 100644 --- a/frontend/src/lib/yupSchemas.ts +++ b/frontend/src/lib/yupSchemas.ts @@ -63,12 +63,9 @@ export const dataSchema = yup.object({ .lowercase(), answers: yup.lazy((v) => { if (Array.isArray(v)) { - console.log(v); if (typeof v[0].right === 'boolean') { - console.log('Yup, ABCD'); return ABCDQuestionSchema; } else { - console.log('Yup, Poll'); return VotingQuestionSchema; } } else {