ui: Prepare ui for public interface
This commit is contained in:
parent
d010b86fa0
commit
56d8d49304
5
frontend/ui/package-lock.json
generated
5
frontend/ui/package-lock.json
generated
|
@ -707,6 +707,11 @@
|
|||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"hash-wasm": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.9.0.tgz",
|
||||
"integrity": "sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w=="
|
||||
},
|
||||
"ignore": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"bootstrap": "^5.1.0",
|
||||
"bootstrap-icons": "^1.5.0",
|
||||
"bootswatch": "^5.1.0",
|
||||
"hash-wasm": "^4.9.0",
|
||||
"seedrandom": "^3.0.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
Spinner,
|
||||
} from 'sveltestrap';
|
||||
|
||||
import { blake2b } from 'hash-wasm';
|
||||
|
||||
import { my } from '../stores/my.js';
|
||||
|
||||
import DateFormat from './DateFormat.svelte';
|
||||
import FlagKey from './FlagKey.svelte';
|
||||
import FlagMCQ from './FlagMCQ.svelte';
|
||||
|
@ -36,42 +40,89 @@
|
|||
})
|
||||
}
|
||||
|
||||
export let forcesolved = false;
|
||||
let responses = { };
|
||||
async function submitFlags() {
|
||||
submitInProgress = true;
|
||||
sberr = "";
|
||||
message = "";
|
||||
|
||||
const response = await fetch(
|
||||
"submit/" + exercice.id,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {'Accept': 'application/json'},
|
||||
body: JSON.stringify(responses),
|
||||
}
|
||||
)
|
||||
if ($my && $my.team_id === 0) {
|
||||
let allGoodResponse = true;
|
||||
for (const f in flags) {
|
||||
const flag = flags[f];
|
||||
|
||||
let soluce = "";
|
||||
if (flag.type == "mcq") {
|
||||
for (const c in flag.choices) {
|
||||
soluce += responses.mcqs[c] ? "t" : "f";
|
||||
}
|
||||
} else {
|
||||
soluce = responses.flags[flag.id];
|
||||
}
|
||||
|
||||
if (flag.ignore_case) {
|
||||
soluce = soluce.toLowerCase();
|
||||
}
|
||||
|
||||
if (flag.validator_regexp) {
|
||||
let re = new RegExp(flag.validator_regexp, flag.ignore_case?'i':'');
|
||||
soluce = soluce.match(re).slice(1).join("+");
|
||||
}
|
||||
|
||||
if (await blake2b(soluce) == flag.soluce) {
|
||||
flags[f].found = new Date();
|
||||
} else if (!flag.found) {
|
||||
allGoodResponse = false;
|
||||
}
|
||||
flags = flags;
|
||||
}
|
||||
|
||||
if (allGoodResponse) {
|
||||
forcesolved = true;
|
||||
}
|
||||
|
||||
if (exercice.tries) {
|
||||
exercice.tries += 1;
|
||||
} else {
|
||||
exercice.tries = 1;
|
||||
}
|
||||
exercice.solved_time = new Date();
|
||||
exercice = exercice;
|
||||
|
||||
if (response.status < 300) {
|
||||
const data = await response.json();
|
||||
messageClass = 'text-success';
|
||||
message = data.errmsg;
|
||||
waitDiff(20);
|
||||
} else {
|
||||
submitInProgress = false;
|
||||
} else {
|
||||
const response = await fetch(
|
||||
"submit/" + exercice.id,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {'Accept': 'application/json'},
|
||||
body: JSON.stringify(responses),
|
||||
}
|
||||
)
|
||||
|
||||
messageClass = 'text-danger';
|
||||
|
||||
let data = "";
|
||||
try {
|
||||
data = await response.json();
|
||||
} catch(e) {
|
||||
data = null;
|
||||
}
|
||||
|
||||
if (data && data.errmsg)
|
||||
if (response.status < 300) {
|
||||
const data = await response.json();
|
||||
messageClass = 'text-success';
|
||||
message = data.errmsg;
|
||||
if (response.statys != 402)
|
||||
sberr = "Oups !";
|
||||
waitDiff(20);
|
||||
} else {
|
||||
submitInProgress = false;
|
||||
|
||||
messageClass = 'text-danger';
|
||||
|
||||
let data = "";
|
||||
try {
|
||||
data = await response.json();
|
||||
} catch(e) {
|
||||
data = null;
|
||||
}
|
||||
|
||||
if (data && data.errmsg)
|
||||
message = data.errmsg;
|
||||
if (response.statys != 402)
|
||||
sberr = "Oups !";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
})
|
||||
}
|
||||
|
||||
function showHint(hint) {
|
||||
hint.hidden = false;
|
||||
hints = hints; // Force Svelte update
|
||||
}
|
||||
|
||||
async function openHint(hint) {
|
||||
hints_submitted[hint.id] = true;
|
||||
hinterror = "";
|
||||
|
@ -122,7 +127,7 @@
|
|||
</button>
|
||||
{/if}
|
||||
{#if !hint.file && hint.hidden}
|
||||
<button type="button" ng-click="hint.hidden = false;" class="btn btn-info">
|
||||
<button type="button" on:click={() => showHint(hint)} class="btn btn-info">
|
||||
<Icon name="lock" aria-hidden="true" />
|
||||
Afficher
|
||||
</button>
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
export let theme;
|
||||
export let exercice;
|
||||
let solved = {};
|
||||
|
||||
export let refresh_my;
|
||||
export let refresh_teams;
|
||||
|
@ -158,11 +159,12 @@
|
|||
</Col>
|
||||
{/if}
|
||||
<Col lg="6" class="mb-5">
|
||||
{#if !$my.exercices[exercice.id].solved_rank}
|
||||
{#if !$my.exercices[exercice.id].solved_rank && !solved[exercice.id]}
|
||||
<ExerciceFlags
|
||||
{refresh_my}
|
||||
{refresh_teams}
|
||||
exercice={$my.exercices[exercice.id]}
|
||||
bind:forcesolved={solved[exercice.id]}
|
||||
flags={$my.exercices[exercice.id].flags}
|
||||
/>
|
||||
{:else}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
import { themesStore } from '../stores/themes.js';
|
||||
import { settings, time } from '../stores/settings.js';
|
||||
|
||||
let stop_refresh = false;
|
||||
|
||||
let refresh_interval_settings = null;
|
||||
async function refresh_settings(cb=null, interval=null) {
|
||||
if (refresh_interval_settings)
|
||||
|
@ -12,6 +14,9 @@
|
|||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 32000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_settings = setInterval(refresh_settings, interval);
|
||||
|
||||
if (!cb) {
|
||||
|
@ -43,6 +48,9 @@
|
|||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 32000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_teams = setInterval(refresh_teams, interval);
|
||||
|
||||
teamsStore.update(await fetch('teams.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
|
@ -55,6 +63,9 @@
|
|||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 32000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_themes = setInterval(refresh_themes, interval);
|
||||
|
||||
await themesStore.update(await fetch('themes.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
|
@ -67,6 +78,9 @@
|
|||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 24000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_my = setInterval(refresh_my, interval);
|
||||
|
||||
my.update(await fetch('my.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
|
@ -79,6 +93,9 @@
|
|||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 32000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_issues = setInterval(refresh_issues, interval);
|
||||
|
||||
issuesStore.update(await fetch('issues.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
|
@ -88,7 +105,11 @@
|
|||
await refresh_settings();
|
||||
await refresh_themes();
|
||||
refresh_teams();
|
||||
refresh_my();
|
||||
refresh_my((my) => {
|
||||
if (my && my.team_id === 0) {
|
||||
stop_refresh = true;
|
||||
}
|
||||
});
|
||||
refresh_issues();
|
||||
|
||||
return {
|
||||
|
|
|
@ -10,6 +10,12 @@ function createMyStore() {
|
|||
res_my.json().then((my) => {
|
||||
for (let k in my.exercices) {
|
||||
my.exercices[k].id = k;
|
||||
|
||||
if (my.team_id === 0 && my.exercices[k].hints) {
|
||||
for (let j in my.exercices[k].hints) {
|
||||
my.exercices[k].hints[j].hidden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update((m) => (Object.assign(m?m:{}, my)));
|
||||
|
|
Loading…
Reference in New Issue
Block a user