server/frontend/ui/src/components/ExerciceHints.svelte

132 lines
4.1 KiB
Svelte

<script>
import {
Card,
CardBody,
CardHeader,
CardText,
Icon,
ListGroup,
ListGroupItem,
Spinner,
} from 'sveltestrap';
import { settings } from '../stores/settings.js';
export let hints = [];
export let exercice = {};
export let refresh_my = null;
let hints_submitted = {};
function waitDiff(i, hint) {
refresh_my((my) => {
let openedHint = false;
if (my && my.exercices[exercice.id].hints) {
my.exercices[exercice.id].hints.forEach((h) => {
if (h.id == hint.id && (h.content || h.file)) {
openedHint = true;
}
})
}
if (openedHint) {
hints_submitted[hint.id] = false;
hinterror = "";
} else if (i > 0) {
setTimeout(waitDiff, 650, i-1, hint);
}
})
}
async function openHint(hint) {
hints_submitted[hint.id] = true;
hinterror = "";
const response = await fetch(
"/openhint/" + exercice.id,
{
method: "POST",
body: JSON.stringify({ id: hint.id }),
}
)
if (response.status < 300) {
waitDiff(15, hint);
} else {
hints_submitted[hint.id] = false;
let data = "";
try {
data = await response.json();
} catch(e) {
data = null;
}
if (data && data.errmsg)
hinterror = data.errmsg;
}
}
let hinterror = "";
</script>
{#if hints.length}
<Card class="mb-2">
<CardHeader class="bg-info text-light">
<Icon name="lightbulb-fill" />
Indices
</CardHeader>
{#if hinterror}
<CardBody>
<CardText class="text-danger">
{hinterror}
</CardText>
</CardBody>
{/if}
<ListGroup>
{#each hints as hint (hint.id)}
<ListGroupItem tag="a" href="{hint.file}" target="_self" class="d-flex align-items-center">
{#if hint.file}
<h1 class="me-3">
<Icon name="arrow-down-circle" />
</h1>
{/if}
<div class="flex-fill" style="min-width:0">
{#if !(hint.content || hint.file)}
<button type="button" on:click={openHint(hint)} class="float-end btn btn-info" class:disabled={hints_submitted[hint.id]}>
{#if hints_submitted[hint.id]}
<Spinner size="sm" class="me-2" />
{:else}
<Icon name="lock" aria-hidden="true" />
{/if}
Débloquer
</button>
{/if}
{#if !hint.file && hint.hidden}
<button type="button" ng-click="hint.hidden = false;" class="float-end btn btn-info">
<Icon name="lock" aria-hidden="true" />
Afficher
</button>
{/if}
<h4 class="fw-bold">{hint.title}</h4>
{#if hint.file}
<p style="overflow-x: auto">
Cliquez ici pour télécharger l'indice.<br>
b2sum&nbsp;:
<samp class="cksum" title="Somme de contrôle BLAKE2b : {hint.content}">{hint.content}</samp>
</p>
{:else if hint.content && !hint.hidden}
<p>{@html hint.content}</p>
{:else}
<p>
Débloquer cet indice vous fera perdre {hint.cost * $settings.hintCurrentCoefficient} {hint.cost * $settings.hintCurrentCoefficient == 1 ? "point" : "points"}.
</p>
{/if}
</div>
</ListGroupItem>
{/each}
</ListGroup>
</Card>
{/if}