ui: Almost all interface done with Svelte

This commit is contained in:
nemunaire 2021-08-30 12:46:18 +02:00
commit 7e13cf28bd
54 changed files with 2809 additions and 16 deletions

View file

@ -0,0 +1,55 @@
import { derived, writable } from 'svelte/store';
function createIssuesStore() {
const { subscribe, set, update } = writable({issues: [], issues_idx: {}, issues_nb_responses: 0, issues_need_info: 0});
return {
subscribe,
update: (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}));
}
},
};
}
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);

View file

@ -0,0 +1,28 @@
import { writable } from 'svelte/store';
function createMyStore() {
const { subscribe, set, update } = writable(null);
return {
subscribe,
update: (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;
}
update((m) => (Object.assign(m?m:{}, my)));
if (cb) {
cb(my);
}
});
} else if (res_my.status === 404) {
update((m) => (null));
}
},
};
}
export const my = createMyStore();

View file

@ -0,0 +1,42 @@
import { derived } from 'svelte/store';
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) {
themes[key].exercice_solved++;
}
}
}
}
return themes;
});
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)
tags[tag].solved += 1;
});
}
}
return tags;
});

View file

@ -0,0 +1,108 @@
import { readable, writable } from 'svelte/store';
function createSettingsStore() {
const { subscribe, set, update } = writable({});
return {
subscribe,
update: (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);
settings.recvTime = recvTime;
const x_fic_time = res_settings.headers["x-fic-time"];
if (x_fic_time) {
settings.currentTime = Math.floor(x_fic_time * 1000);
} else {
settings.currentTime = settings.recvTime;
}
update((s) => (Object.assign(s, settings)));
if (cb) {
cb(settings);
}
});
}
},
}
}
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();
}
});

View file

@ -0,0 +1,45 @@
import { derived, writable } from 'svelte/store';
function createTeamsStore() {
const { subscribe, set, update } = writable({teams:{}, teams_count: 0, rank: []});
return {
subscribe,
update: (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]);
}
update((t) => (Object.assign(t, {teams, teams_count, rank})));
if (cb) {
cb(teams, teams_count, rank);
}
});
}
},
};
}
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)
);

View file

@ -0,0 +1,68 @@
import { derived, writable } from 'svelte/store';
function createThemesStore() {
const { subscribe, set, update } = writable({themes: {}, exercices_idx: {}, max_solved: 0});
return {
subscribe,
update: (res_themes, cb=null) => {
if (res_themes.status === 200) {
res_themes.json().then((themes) => {
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);
}
});
}
},
};
}
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),
);