ui: Use $lib instead of ../../../../ mess
This commit is contained in:
parent
3cf92b4798
commit
3a6daa3d04
48 changed files with 81 additions and 81 deletions
27
frontend/ui/src/lib/stores/challengeinfo.js
Normal file
27
frontend/ui/src/lib/stores/challengeinfo.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { readable, writable } from 'svelte/store';
|
||||
|
||||
function createChallengeStore() {
|
||||
const { subscribe, set, update } = writable({});
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
|
||||
refresh: async (cb) => {
|
||||
challengeInfo.update(await fetch('challenge.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
},
|
||||
|
||||
update: (res_challenge, cb) => {
|
||||
if (res_challenge.status === 200) {
|
||||
res_challenge.json().then((challenge) => {
|
||||
update((s) => (Object.assign({}, challenge)));
|
||||
|
||||
if (cb) {
|
||||
cb(challenge);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const challengeInfo = createChallengeStore();
|
||||
1
frontend/ui/src/lib/stores/common.js
Normal file
1
frontend/ui/src/lib/stores/common.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
export let stop_refresh = false;
|
||||
76
frontend/ui/src/lib/stores/issues.js
Normal file
76
frontend/ui/src/lib/stores/issues.js
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import { derived, writable } from 'svelte/store';
|
||||
|
||||
import { stop_refresh } from './common';
|
||||
|
||||
let refresh_interval_issues = null;
|
||||
|
||||
function createIssuesStore() {
|
||||
const { subscribe, set, update } = writable({issues: [], issues_idx: {}, issues_nb_responses: 0, issues_need_info: 0});
|
||||
|
||||
function updateFunc (res_issues, cb=null) {
|
||||
if (res_issues.status === 200) {
|
||||
res_issues.json().then((issues) => {
|
||||
const issues_idx = {};
|
||||
let issues_nb_responses = 0;
|
||||
let issues_need_info = 0;
|
||||
issues.forEach(function(issue, k) {
|
||||
issues_idx[issue.id] = issue;
|
||||
issues_nb_responses += issue.texts.length;
|
||||
if (issue.state == 'need-info') issues_need_info++;
|
||||
issues[k].texts.reverse();
|
||||
})
|
||||
update((i) => (Object.assign(i, {issues, issues_idx, issues_nb_responses, issues_need_info})));
|
||||
|
||||
if (cb) {
|
||||
cb(issues, issues_idx, issues_nb_responses, issues_need_info);
|
||||
}
|
||||
});
|
||||
} else if (res_issues.status === 404) {
|
||||
update((i) => ({issues: [], issues_idx: {}, issues_nb_responses: 0, issues_need_info: 0}));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
|
||||
refresh: async (cb=null, interval=null) => {
|
||||
if (refresh_interval_issues)
|
||||
clearInterval(refresh_interval_issues);
|
||||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 32000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_issues = setInterval(refresh_issues, interval);
|
||||
|
||||
updateFunc(await fetch('issues.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
},
|
||||
|
||||
update: updateFunc,
|
||||
};
|
||||
}
|
||||
|
||||
export const issuesStore = createIssuesStore();
|
||||
|
||||
export const issues = derived(
|
||||
issuesStore,
|
||||
($issuesStore) => ($issuesStore.issues),
|
||||
);
|
||||
|
||||
export const issues_idx = derived(
|
||||
issuesStore,
|
||||
($issuesStore) => ($issuesStore.issues_idx),
|
||||
);
|
||||
|
||||
export const issues_nb_responses = derived(
|
||||
issuesStore,
|
||||
($issuesStore) => ($issuesStore.issues_nb_responses),
|
||||
);
|
||||
|
||||
export const issues_need_info = derived(
|
||||
issuesStore,
|
||||
($issuesStore) => ($issuesStore.issues_need_info),
|
||||
);
|
||||
|
||||
export const issues_known_responses = writable(0);
|
||||
64
frontend/ui/src/lib/stores/my.js
Normal file
64
frontend/ui/src/lib/stores/my.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import { writable } from 'svelte/store';
|
||||
|
||||
import { stop_refresh } from './common';
|
||||
|
||||
let refresh_interval_my = null;
|
||||
|
||||
function createMyStore() {
|
||||
const { subscribe, set, update } = writable(null);
|
||||
|
||||
function updateFunc(res_my, cb=null) {
|
||||
if (res_my.status === 200) {
|
||||
res_my.json().then((my) => {
|
||||
for (let k in my.exercices) {
|
||||
my.exercices[k].id = k;
|
||||
|
||||
if (my.exercices[k].flags) {
|
||||
let nb = 0;
|
||||
for (let j in my.exercices[k].flags) {
|
||||
if (!my.exercices[k].flags[j].found)
|
||||
nb += 1;
|
||||
}
|
||||
my.exercices[k].non_found_flags = nb;
|
||||
}
|
||||
|
||||
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)));
|
||||
|
||||
if (cb) {
|
||||
cb(my);
|
||||
}
|
||||
});
|
||||
} else if (res_my.status === 404) {
|
||||
update((m) => (null));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
|
||||
refresh: async (cb=null, interval=null) => {
|
||||
if (refresh_interval_my)
|
||||
clearInterval(refresh_interval_my);
|
||||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 24000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_my = setInterval(refresh_my, interval);
|
||||
|
||||
updateFunc(await fetch('my.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
},
|
||||
|
||||
update: updateFunc,
|
||||
};
|
||||
}
|
||||
|
||||
export const my = createMyStore();
|
||||
0
frontend/ui/src/lib/stores/myresponses.js
Normal file
0
frontend/ui/src/lib/stores/myresponses.js
Normal file
69
frontend/ui/src/lib/stores/mythemes.js
Normal file
69
frontend/ui/src/lib/stores/mythemes.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import { derived } from 'svelte/store';
|
||||
|
||||
import seedrandom from 'seedrandom';
|
||||
|
||||
import { my } from './my.js';
|
||||
import { themesStore } from './themes.js';
|
||||
|
||||
export const myThemes = derived([my, themesStore], ([$my, $themesStore]) => {
|
||||
const themes = {};
|
||||
|
||||
for (let key in $themesStore.themes) {
|
||||
themes[key] = {exercice_solved: 0};
|
||||
|
||||
if ($my && $my.exercices) {
|
||||
for (let k in $themesStore.themes[key].exercices) {
|
||||
if ($my.exercices[k] && $my.exercices[k].solved_rank) {
|
||||
themes[key].exercice_solved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return themes;
|
||||
});
|
||||
|
||||
export const themes = derived(
|
||||
[my, themesStore],
|
||||
([$my, $themesStore]) => {
|
||||
const arr = [];
|
||||
for (let th in $themesStore.themes) {
|
||||
$themesStore.themes[th].id = th
|
||||
arr.push($themesStore.themes[th]);
|
||||
}
|
||||
const size = arr.length;
|
||||
const rng = new seedrandom($my && $my.team_id ? $my.team_id : 0);
|
||||
const resp = [];
|
||||
const keys = [];
|
||||
|
||||
for(let i=0;i<size;i++) keys.push(i);
|
||||
for(let i=0;i<size;i++) {
|
||||
const r = Math.floor(rng() * keys.length);
|
||||
const g = keys[r];
|
||||
keys.splice(r,1);
|
||||
resp.push(arr[g]);
|
||||
}
|
||||
|
||||
return resp;
|
||||
},
|
||||
);
|
||||
|
||||
export const tags = derived([my, themesStore], ([$my, $themesStore]) => {
|
||||
const tags = {};
|
||||
|
||||
for (let key in $themesStore.themes) {
|
||||
for (let k in $themesStore.themes[key].exercices) {
|
||||
$themesStore.themes[key].exercices[k].tags.forEach((tag) => {
|
||||
if (!tags[tag])
|
||||
tags[tag] = {count: 1, solved: 0};
|
||||
else
|
||||
tags[tag].count += 1;
|
||||
|
||||
if ($my && $my.exercices && $my.exercices[k] && $my.exercices[k].solved_rank)
|
||||
tags[tag].solved += 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return tags;
|
||||
});
|
||||
150
frontend/ui/src/lib/stores/settings.js
Normal file
150
frontend/ui/src/lib/stores/settings.js
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
import { readable, writable } from 'svelte/store';
|
||||
|
||||
import { stop_refresh } from './common';
|
||||
|
||||
let refresh_interval_settings = null;
|
||||
|
||||
function createSettingsStore() {
|
||||
const { subscribe, set, update } = writable({});
|
||||
|
||||
function updateFunc(res_settings, cb) {
|
||||
const recvTime = (new Date()).getTime();
|
||||
|
||||
if (res_settings.status === 200) {
|
||||
res_settings.json().then((settings) => {
|
||||
if (settings.start)
|
||||
settings.start = new Date(settings.start);
|
||||
if (settings.end)
|
||||
settings.end = new Date(settings.end);
|
||||
if (settings.generation)
|
||||
settings.generation = new Date(settings.generation);
|
||||
if (settings.activateTime)
|
||||
settings.activateTime = new Date(settings.activateTime);
|
||||
if (!settings.disablesubmitbutton)
|
||||
settings.disablesubmitbutton = null;
|
||||
|
||||
settings.recvTime = recvTime;
|
||||
const x_fic_time = res_settings.headers.get("x-fic-time");
|
||||
if (x_fic_time) {
|
||||
settings.currentTime = Math.floor(x_fic_time * 1000);
|
||||
} else {
|
||||
settings.currentTime = settings.recvTime;
|
||||
}
|
||||
|
||||
update((s) => (Object.assign({}, settings)));
|
||||
|
||||
if (cb) {
|
||||
cb(settings);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
|
||||
refresh: async (cb=null, interval=null) => {
|
||||
if (refresh_interval_settings)
|
||||
clearInterval(refresh_interval_settings);
|
||||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 32000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_settings = setInterval(refresh_settings, interval);
|
||||
|
||||
if (!cb) {
|
||||
// Before we start, update settings more frequently.
|
||||
cb = function(stgs) {
|
||||
const srv_cur = new Date(Date.now() + (stgs.currentTime - stgs.recvTime));
|
||||
|
||||
if (settings.start > srv_cur) {
|
||||
const startIn = settings.start - srv_cur;
|
||||
if (startIn > 15000) {
|
||||
setTimeout(refresh_settings, Math.floor(Math.random() * 10000) + 2400)
|
||||
} else if (startIn > 1500) {
|
||||
setTimeout(refresh_settings, startIn - 1000 - Math.floor(Math.random() * 500))
|
||||
} else {
|
||||
// On scheduled start time, refresh my.json file
|
||||
setTimeout(refresh_my, startIn + Math.floor(Math.random() * 200))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
updateFunc(await fetch('settings.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
},
|
||||
|
||||
update: updateFunc,
|
||||
}
|
||||
}
|
||||
|
||||
export const settings = createSettingsStore();
|
||||
|
||||
function updateTime(settings) {
|
||||
const time = {};
|
||||
|
||||
const srv_cur = new Date(Date.now() + (settings.currentTime - settings.recvTime));
|
||||
|
||||
let remain = 0;
|
||||
if (settings.start === undefined || settings.start == 0) {
|
||||
return time;
|
||||
} else if (settings.start > srv_cur) {
|
||||
time.startIn = Math.floor((settings.start - srv_cur) / 1000);
|
||||
remain = settings.end - settings.start;
|
||||
} else if (settings.end > srv_cur) {
|
||||
time.startIn = 0;
|
||||
remain = settings.end - srv_cur;
|
||||
}
|
||||
|
||||
time.progression = 1 - remain / (settings.end - settings.start);
|
||||
|
||||
remain = remain / 1000;
|
||||
|
||||
if (remain < 0) {
|
||||
remain = 0;
|
||||
time.end = true;
|
||||
time.expired = true;
|
||||
} else if (remain < 60) {
|
||||
time.end = false;
|
||||
time.expired = true;
|
||||
} else {
|
||||
time.end = false;
|
||||
time.expired = false;
|
||||
}
|
||||
|
||||
time.remaining = remain;
|
||||
time.hours = Math.floor(remain / 3600);
|
||||
time.minutes = Math.floor((remain % 3600) / 60);
|
||||
time.seconds = Math.floor(remain % 60);
|
||||
|
||||
if (time.hours <= 9) {
|
||||
time.hours = "0" + time.hours;
|
||||
}
|
||||
if (time.minutes <= 9) {
|
||||
time.minutes = "0" + time.minutes;
|
||||
}
|
||||
if (time.seconds <= 9) {
|
||||
time.seconds = "0" + time.seconds;
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
export const time = readable({}, function start(set) {
|
||||
let _settings = {};
|
||||
|
||||
const unsubscribe = settings.subscribe((settings) => {
|
||||
_settings = settings;
|
||||
});
|
||||
|
||||
const interval = setInterval(() => {
|
||||
set(updateTime(_settings));
|
||||
}, 1000);
|
||||
|
||||
return function stop() {
|
||||
clearInterval(interval);
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
67
frontend/ui/src/lib/stores/teams.js
Normal file
67
frontend/ui/src/lib/stores/teams.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { derived, writable } from 'svelte/store';
|
||||
|
||||
import { stop_refresh } from './common';
|
||||
|
||||
let refresh_interval_teams = null;
|
||||
|
||||
function createTeamsStore() {
|
||||
const { subscribe, set, update } = writable({teams:{}, teams_count: 0, rank: []});
|
||||
|
||||
function updateFunc(res_teams, cb=null) {
|
||||
if (res_teams.status === 200) {
|
||||
res_teams.json().then((teams) => {
|
||||
const teams_count = Object.keys(teams).length
|
||||
|
||||
const rank = [];
|
||||
for (const tid in teams) {
|
||||
teams[tid].id = Number(tid);
|
||||
rank.push(teams[tid]);
|
||||
}
|
||||
rank.sort((a, b) => (a.rank > b.rank ? 1 : (a.rank == b.rank ? 0 : -1)));
|
||||
|
||||
update((t) => (Object.assign(t, {teams, teams_count, rank})));
|
||||
|
||||
if (cb) {
|
||||
cb(teams, teams_count, rank);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
|
||||
refresh: async (cb=null, interval=null) => {
|
||||
if (refresh_interval_teams)
|
||||
clearInterval(refresh_interval_teams);
|
||||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 32000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_teams = setInterval(refresh_teams, interval);
|
||||
|
||||
updateFunc(await fetch('teams.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
},
|
||||
|
||||
update: updateFunc,
|
||||
};
|
||||
}
|
||||
|
||||
export const teamsStore = createTeamsStore();
|
||||
|
||||
export const teams = derived(
|
||||
teamsStore,
|
||||
($teamsStore) => ($teamsStore.teams)
|
||||
);
|
||||
|
||||
export const teams_count = derived(
|
||||
teamsStore,
|
||||
($teamsStore) => ($teamsStore.teams_count)
|
||||
);
|
||||
|
||||
export const rank = derived(
|
||||
teamsStore,
|
||||
($teamsStore) => ($teamsStore.rank)
|
||||
);
|
||||
89
frontend/ui/src/lib/stores/themes.js
Normal file
89
frontend/ui/src/lib/stores/themes.js
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import { derived, writable } from 'svelte/store';
|
||||
|
||||
import { stop_refresh } from './common';
|
||||
|
||||
let refresh_interval_themes = null;
|
||||
|
||||
function createThemesStore() {
|
||||
const { subscribe, set, update } = writable({themes: null, exercices_idx: {}, max_solved: 0});
|
||||
|
||||
async function updateFunc (res_themes, cb=null) {
|
||||
if (res_themes.status === 200) {
|
||||
const themes = await res_themes.json();
|
||||
|
||||
let max_solved = 0;
|
||||
const exercices_idx = {};
|
||||
|
||||
for (let key in themes) {
|
||||
const theme = themes[key];
|
||||
|
||||
if (theme.solved > max_solved) {
|
||||
max_solved = theme.solved;
|
||||
}
|
||||
|
||||
themes[key].exercice_count = Object.keys(theme.exercices).length;
|
||||
themes[key].exercice_coeff_max = 0;
|
||||
themes[key].max_gain = 0;
|
||||
let last_exercice = null;
|
||||
for (let k in theme.exercices) {
|
||||
const exercice = theme.exercices[k];
|
||||
|
||||
themes[key].max_gain += exercice.gain;
|
||||
if (themes[key].exercice_coeff_max < exercice.curcoeff) {
|
||||
themes[key].exercice_coeff_max = exercice.curcoeff;
|
||||
}
|
||||
|
||||
if (last_exercice != null)
|
||||
themes[key].exercices[last_exercice].next = k;
|
||||
last_exercice = k;
|
||||
|
||||
exercice.id = k;
|
||||
exercices_idx[k] = exercice;
|
||||
}
|
||||
}
|
||||
|
||||
update((t) => (Object.assign(t, {themes, exercices_idx, max_solved})));
|
||||
|
||||
if (cb) {
|
||||
cb(themes, exercices_idx, max_solved);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
|
||||
refresh: async (cb=null, interval=null) => {
|
||||
if (refresh_interval_themes)
|
||||
clearInterval(refresh_interval_themes);
|
||||
if (interval === null) {
|
||||
interval = Math.floor(Math.random() * 24000) + 32000;
|
||||
}
|
||||
if (stop_refresh) {
|
||||
return;
|
||||
}
|
||||
refresh_interval_themes = setInterval(refresh_themes, interval);
|
||||
|
||||
await updateFunc(await fetch('themes.json', {headers: {'Accept': 'application/json'}}), cb);
|
||||
},
|
||||
|
||||
update: updateFunc,
|
||||
};
|
||||
}
|
||||
|
||||
export const themesStore = createThemesStore();
|
||||
|
||||
export const themes = derived(
|
||||
themesStore,
|
||||
($themesStore) => ($themesStore.themes),
|
||||
);
|
||||
|
||||
export const exercices_idx = derived(
|
||||
themesStore,
|
||||
($themesStore) => ($themesStore.exercices_idx),
|
||||
);
|
||||
|
||||
export const max_solved = derived(
|
||||
themesStore,
|
||||
($themesStore) => ($themesStore.max_solved),
|
||||
);
|
||||
Reference in a new issue