Finished Slides

This commit is contained in:
Mawoka
2022-12-26 11:04:26 +01:00
parent 809a9024b6
commit d9f174f40b
10 changed files with 122 additions and 64 deletions
-1
View File
@@ -198,7 +198,6 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput):
quiz.description = quiz_input.description
quiz.updated_at = datetime.now()
quiz.questions = quiz_input.dict()["questions"]
print(quiz.questions)
quiz.cover_image = quiz_input.cover_image
quiz.background_color = quiz_input.background_color
for image in images_to_delete:
+1
View File
@@ -68,6 +68,7 @@
"luxon": "^3.1.1",
"mapbox-gl": "^2.11.0",
"minisearch": "^5.1.0",
"pikaso": "^2.7.4",
"plausible-tracker": "^0.3.8",
"postcss": "^8.4.19",
"postcss-import": "^14.1.0",
+20
View File
@@ -56,6 +56,7 @@ specifiers:
luxon: ^3.1.1
mapbox-gl: ^2.11.0
minisearch: ^5.1.0
pikaso: ^2.7.4
plausible-tracker: ^0.3.8
postcss: ^8.4.19
postcss-import: ^14.1.0
@@ -138,6 +139,7 @@ devDependencies:
luxon: 3.1.1
mapbox-gl: 2.11.1
minisearch: 5.1.0
pikaso: 2.7.4
plausible-tracker: 0.3.8
postcss: 8.4.20
postcss-import: 14.1.0_postcss@8.4.20
@@ -3911,6 +3913,13 @@ packages:
engines: { node: '>=6' }
dev: true
/konva/8.3.14:
resolution:
{
integrity: sha512-6I/TZppgY3Frs//AvZ87YVQLFxLywitb8wLS3qMM+Ih9e4QcB5Yy8br6eq7DdUzxPdbsYTz1FQBHzNxs08M1Tw==
}
dev: true
/levn/0.3.0:
resolution:
{
@@ -4646,6 +4655,17 @@ packages:
engines: { node: '>=0.10.0' }
dev: true
/pikaso/2.7.4:
resolution:
{
integrity: sha512-30nqF5+xBUIBKiHHfDfjA3oZChjirN3AmhfWb456iUvTpMY2D51PKjGHfgF2SoQP5Jad7i4Zv+wrQAp7BhcNmQ==
}
dependencies:
deepmerge: 4.2.2
konva: 8.3.14
typescript: 4.7.4
dev: true
/plausible-tracker/0.3.8:
resolution:
{
+34 -6
View File
@@ -27,16 +27,21 @@
let timer_res: string;
let shown_question_now: number;
let final_results_clicked = false;
let timer_interval;
export let player_scores;
export const set_question_number = (q_number: number) => {
timer_res = '0';
clearInterval(timer_interval);
// setTimeout(() => {
question_results = null;
socket.emit('set_question_number', q_number.toString());
shown_question_now = q_number;
timer_res = quiz_data.questions[q_number].time;
selected_question = selected_question + 1;
timer(timer_res);
// }, 1000);
};
const get_question_results = () => {
socket.emit('get_question_results', {
@@ -53,6 +58,7 @@
const get_final_results = () => {
socket.emit('get_final_results', {});
final_results_clicked = true;
timer_res = '0';
};
socket.on('final_results', (data) => {
@@ -75,7 +81,7 @@
const timer = (time: string) => {
let seconds = Number(time);
let timer_interval = setInterval(() => {
timer_interval = setInterval(() => {
if (timer_res === '0') {
clearInterval(timer_interval);
// socket.emit('show_solutions', {});
@@ -109,7 +115,7 @@
/{quiz_data.questions.length}
</p>
<div class="justify-self-end ml-auto mr-0 col-start-3 col-end-3">
{#if selected_question + 1 === quiz_data.questions.length && timer_res === '0' && question_results !== null}
{#if selected_question + 1 === quiz_data.questions.length && ((timer_res === '0' && question_results !== null) || quiz_data?.questions?.[selected_question]?.type === QuizQuestionType.SLIDE)}
{#if JSON.stringify(final_results) === JSON.stringify([null])}
<button on:click={get_final_results} class="admin-button"
>Get final results
@@ -126,12 +132,34 @@
</button>
{/if}
{#if question_results === null && selected_question !== -1}
<button on:click={get_question_results} class="admin-button">Show results</button>
{#if quiz_data.questions[selected_question].type === QuizQuestionType.SLIDE}
<button
on:click={() => {
set_question_number(selected_question + 1);
}}
class="admin-button"
>Next Question ({selected_question + 2})
</button>
{:else}
<button on:click={get_question_results} class="admin-button"
>Show results</button
>
{/if}
{/if}
{:else if selected_question !== -1}
<button on:click={show_solutions} class="admin-button"
>Stop time and show solutions
</button>
{#if quiz_data.questions[selected_question].type === QuizQuestionType.SLIDE}
<button
on:click={() => {
set_question_number(selected_question + 1);
}}
class="admin-button"
>Next Question ({selected_question + 2})
</button>
{:else}
<button on:click={show_solutions} class="admin-button"
>Stop time and show solutions
</button>
{/if}
{:else}
<!-- <button
on:click={() => {
@@ -15,6 +15,7 @@
import StartGamePopup from './start_game.svelte';
import { onMount } from 'svelte';
import viewport from './useViewportAction.js';
import Spinner from '$lib/Spinner.svelte';
let copy_toast_open = false;
let start_game = null;
@@ -350,6 +351,28 @@
</div>
{/each}
</div>
{:else if question.type === QuizQuestionType.SLIDE}
<div
use:viewport
on:enterViewport={() => {
visibleImages[i][q] = true;
}}
on:exitViewport={() => {
visibleImages[i][q] = false;
}}
class="flex justify-center align-middle items-center"
>
{#await import('$lib/play/admin/slide.svelte')}
<Spinner my={false} />
{:then c}
<div class="max-h-[50%] max-w-[60%]">
<svelte:component
this={c.default}
bind:question
/>
</div>
{/await}
</div>
{/if}
</div>
</SwiperSlide>
-27
View File
@@ -23,26 +23,11 @@
let selected_element = undefined;
let canvas_el: HTMLDivElement | undefined;
let canvas: Pikaso;
let elements = [];
let selected_el: null | ShapeModel<Konva.Shape | Konva.Group, Konva.ShapeConfig> = null;
let elements_binds: Array<HTMLElement> | undefined = [];
let main_el: undefined | HTMLElement;
let settings_menu_open = false;
const get_location = (id: number): { row: number; col: number } => {
const numColumns = 12;
const row = Math.floor(id / numColumns);
const col = id % numColumns;
return { row, col };
};
const set_correct_position = (
e: CustomEvent<{ offsetX: number; offsetY: number; domRect: DOMRect }>
) => {
const id = parseInt(e.target.getAttribute('el_id'));
data.answers[id].x = e.detail.offsetX / main_el.offsetWidth;
data.answers[id].y = e.detail.offsetY / main_el.offsetHeight;
};
const set_correct_height = new ResizeObserver((e) => {
for (const i of e) {
@@ -116,10 +101,6 @@
assign_resize_handlers();
}
const set_correct_size = (e: UIEvent) => {
console.log(e, 'resized');
};
onMount(() => {
/* setTimeout(() => {
for (let i = 0; i < data.answers.length; i++) {
@@ -156,14 +137,6 @@
}
});
});
const get_shape_from_id = (id: number) => {
for (let i = 0; i < canvas.board.shapes.length; i++) {
if (canvas.board.shapes[i].node._id === id) {
return canvas.board.shapes[i].node;
}
}
};
</script>
<div class="flex h-full relative w-full" bind:this={main_el}>
+27 -29
View File
@@ -5,38 +5,36 @@
-->
<script lang="ts">
import type { Question } from '$lib/quiz_types';
import TextElement from '$lib/editor/slides/types/text.svelte';
import HeadlineElement from '$lib/editor/slides/types/headline.svelte';
import { ElementTypes } from '$lib/quiz_types.js';
import { draggable } from '@neodrag/svelte';
import { onMount } from 'svelte';
import Pikaso from 'pikaso';
export let question: Question;
let main_el: HTMLElement | undefined;
let canvas_el: HTMLDivElement | undefined;
let canvas: Pikaso;
let img_src = '';
onMount(() => {
canvas = new Pikaso({
container: canvas_el,
snapToGrid: {},
selection: {
interactive: false
}
});
if (typeof question.answers === 'string') {
const data = JSON.parse(question.answers);
canvas.import.json(data);
img_src = canvas.export.toImage();
}
});
</script>
<div class="w-full min-h-[calc(100vh-8rem)]" bind:this={main_el}>
{#if main_el}
{#each question.answers as el, i}
<div
use:draggable={{
bounds: 'parent',
handle: '.drag',
disabled: true,
defaultPosition: {
x: el.x * main_el.offsetWidth,
y: el.y * main_el.offsetHeight
}
}}
style="height: {el.height * main_el.offsetHeight}px; width: {el.width *
main_el.offsetWidth}px"
>
{#if el.type === ElementTypes.Text}
<TextElement bind:data={el.data} editor={false} />
{:else if el.type === ElementTypes.Headline}
<HeadlineElement bind:data={el.data} editor={false} />
{/if}
</div>
{/each}
{/if}
<div class="w-full h-full">
<div class="hidden">
<div bind:this={canvas_el} class="w-full h-full block" />
</div>
<div class="w-full h-full flex justify-center">
<img src={img_src} />
</div>
</div>
@@ -150,5 +150,13 @@
{#if timer_res === '0'}
<p>No correct answers, since this is a poll-question</p>
{/if}
{:else if question.type === QuizQuestionType.SLIDE}
{#await import('$lib/play/admin/slide.svelte')}
<Spinner my={false} />
{:then c}
<div class="max-h-[90%] max-w-[90%]">
<svelte:component this={c.default} bind:question />
</div>
{/await}
{/if}
</div>
-1
View File
@@ -5,7 +5,6 @@
*/
import * as yup from 'yup';
import { ElementTypes } from '$lib/quiz_types';
export const ABCDQuestionSchema = yup
.array()
@@ -11,6 +11,7 @@
import { QuizQuestionType } from '$lib/quiz_types.js';
import StartGamePopup from '$lib/dashboard/start_game.svelte';
import { onMount } from 'svelte';
import Spinner from '$lib/Spinner.svelte';
const tippy = createTippy({
arrow: true,
@@ -228,6 +229,14 @@
</div>
{/each}
</div>
{:else if question.type === QuizQuestionType.SLIDE}
{#await import('$lib/play/admin/slide.svelte')}
<Spinner my={false} />
{:then c}
<div class="max-h-[90%] max-w-[90%]">
<svelte:component this={c.default} bind:question />
</div>
{/await}
{/if}
</div>
</CollapsSection>