ui: Refactor stores

This commit is contained in:
nemunaire 2022-11-02 10:07:44 +01:00
commit ffd43ac8e1
6 changed files with 136 additions and 86 deletions

View file

@ -10,6 +10,7 @@
Spinner, Spinner,
} from 'sveltestrap'; } from 'sveltestrap';
import { my } from '$lib/stores/my.js';
import { settings } from '$lib/stores/settings.js'; import { settings } from '$lib/stores/settings.js';
export let hints = []; export let hints = [];

View file

@ -5,28 +5,19 @@ import { stop_refresh } from './common';
let refresh_interval_issues = null; let refresh_interval_issues = null;
function createIssuesStore() { function createIssuesStore() {
const { subscribe, set, update } = writable({issues: [], issues_idx: {}, issues_nb_responses: 0, issues_need_info: 0}); const { subscribe, set, update } = writable([]);
function updateFunc (res_issues, cb=null) { function updateFunc (res_issues, cb=null) {
if (res_issues.status === 200) { if (res_issues.status === 200) {
res_issues.json().then((issues) => { res_issues.json().then((issues) => {
const issues_idx = {}; update((i) => issues);
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) { if (cb) {
cb(issues, issues_idx, issues_nb_responses, issues_need_info); cb(issues);
} }
}); });
} else if (res_issues.status === 404) { } else if (res_issues.status === 404) {
update((i) => ({issues: [], issues_idx: {}, issues_nb_responses: 0, issues_need_info: 0})); update((i) => ([]));
} }
} }
@ -57,22 +48,51 @@ export const issuesStore = createIssuesStore();
export const issues = derived( export const issues = derived(
issuesStore, issuesStore,
($issuesStore) => ($issuesStore.issues), ($issuesStore) => {
$issuesStore.forEach(function(issue, k) {
$issuesStore[k].texts.reverse();
})
return $issuesStore;
},
); );
export const issues_idx = derived( export const issues_idx = derived(
issuesStore, issues,
($issuesStore) => ($issuesStore.issues_idx), ($issues) => {
const issues_idx = {};
$issues.forEach(function(issue, k) {
issues_idx[issue.id] = issue;
})
return issues_idx;
},
); );
export const issues_nb_responses = derived( export const issues_nb_responses = derived(
issuesStore, issuesStore,
($issuesStore) => ($issuesStore.issues_nb_responses), ($issuesStore) => {
let issues_nb_responses = 0;
$issuesStore.forEach(function(issue, k) {
issues_nb_responses += issue.texts.length;
})
return issues_nb_responses;
},
); );
export const issues_need_info = derived( export const issues_need_info = derived(
issuesStore, issuesStore,
($issuesStore) => ($issuesStore.issues_need_info), ($issuesStore) => {
let issues_need_info = 0;
$issuesStore.forEach(function(issue, k) {
if (issue.state == 'need-info') issues_need_info++;
})
return issues_need_info;
},
); );
export const issues_known_responses = writable(0); export const issues_known_responses = writable(0);

View file

@ -3,33 +3,33 @@ import { derived } from 'svelte/store';
import seedrandom from 'seedrandom'; import seedrandom from 'seedrandom';
import { my } from './my.js'; import { my } from './my.js';
import { themesStore } from './themes.js'; import { themes as themesStore } from './themes.js';
export const myThemes = derived([my, themesStore], ([$my, $themesStore]) => { export const myThemes = derived([my, themesStore], ([$my, $themesStore]) => {
const themes = {}; const mythemes = {};
for (let key in $themesStore.themes) { for (let key in $themesStore) {
themes[key] = {exercice_solved: 0}; mythemes[key] = {exercice_solved: 0};
if ($my && $my.exercices) { if ($my && $my.exercices) {
for (let k in $themesStore.themes[key].exercices) { for (let k in $themesStore[key].exercices) {
if ($my.exercices[k] && $my.exercices[k].solved_rank) { if ($my.exercices[k] && $my.exercices[k].solved_rank) {
themes[key].exercice_solved++; mythemes[key].exercice_solved++;
} }
} }
} }
} }
return themes; return mythemes;
}); });
export const themes = derived( export const themes = derived(
[my, themesStore], [my, themesStore],
([$my, $themesStore]) => { ([$my, $themesStore]) => {
const arr = []; const arr = [];
for (let th in $themesStore.themes) { for (let th in $themesStore) {
$themesStore.themes[th].id = th $themesStore[th].id = th
arr.push($themesStore.themes[th]); arr.push($themesStore[th]);
} }
const size = arr.length; const size = arr.length;
const rng = new seedrandom($my && $my.team_id ? $my.team_id : 0); const rng = new seedrandom($my && $my.team_id ? $my.team_id : 0);
@ -51,9 +51,9 @@ export const themes = derived(
export const tags = derived([my, themesStore], ([$my, $themesStore]) => { export const tags = derived([my, themesStore], ([$my, $themesStore]) => {
const tags = {}; const tags = {};
for (let key in $themesStore.themes) { for (let key in $themesStore) {
for (let k in $themesStore.themes[key].exercices) { for (let k in $themesStore[key].exercices) {
$themesStore.themes[key].exercices[k].tags.forEach((tag) => { $themesStore[key].exercices[k].tags.forEach((tag) => {
if (!tags[tag]) if (!tags[tag])
tags[tag] = {count: 1, solved: 0}; tags[tag] = {count: 1, solved: 0};
else else

View file

@ -5,24 +5,15 @@ import { stop_refresh } from './common';
let refresh_interval_teams = null; let refresh_interval_teams = null;
function createTeamsStore() { function createTeamsStore() {
const { subscribe, set, update } = writable({teams:{}, teams_count: 0, rank: []}); const { subscribe, set, update } = writable({});
function updateFunc(res_teams, cb=null) { function updateFunc(res_teams, cb=null) {
if (res_teams.status === 200) { if (res_teams.status === 200) {
res_teams.json().then((teams) => { res_teams.json().then((teams) => {
const teams_count = Object.keys(teams).length update((t) => teams);
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) { if (cb) {
cb(teams, teams_count, rank); cb(teams);
} }
}); });
} }
@ -55,15 +46,33 @@ export const teamsStore = createTeamsStore();
export const teams = derived( export const teams = derived(
teamsStore, teamsStore,
($teamsStore) => ($teamsStore.teams) ($teamsStore) => {
const teams = {};
for (const tid in $teamsStore) {
teams[tid] = $teamsStore[tid];
teams[tid].id = Number(tid);
}
return teams;
}
); );
export const teams_count = derived( export const teams_count = derived(
teamsStore, teamsStore,
($teamsStore) => ($teamsStore.teams_count) ($teamsStore) => Object.keys(teams).length
); );
export const rank = derived( export const rank = derived(
teamsStore, teams,
($teamsStore) => ($teamsStore.rank) ($teams) => {
const rank = [];
for (const tid in $teams) {
rank.push($teams[tid]);
}
rank.sort((a, b) => (a.rank > b.rank ? 1 : (a.rank == b.rank ? 0 : -1)));
return rank;
}
); );

View file

@ -5,47 +5,16 @@ import { stop_refresh } from './common';
let refresh_interval_themes = null; let refresh_interval_themes = null;
function createThemesStore() { function createThemesStore() {
const { subscribe, set, update } = writable({themes: null, exercices_idx: {}, max_solved: 0}); const { subscribe, set, update } = writable({});
async function updateFunc (res_themes, cb=null) { async function updateFunc (res_themes, cb=null) {
if (res_themes.status === 200) { if (res_themes.status === 200) {
const themes = await res_themes.json(); const themes = await res_themes.json();
let max_solved = 0; update((t) => themes);
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) { if (cb) {
cb(themes, exercices_idx, max_solved); cb(themes);
} }
} }
} }
@ -77,15 +46,66 @@ export const themesStore = createThemesStore();
export const themes = derived( export const themes = derived(
themesStore, themesStore,
($themesStore) => ($themesStore.themes), ($themesStore) => {
const themes = {};
for (const key in $themesStore) {
const theme = $themesStore[key];
themes[key] = theme
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;
}
}
return themes;
},
); );
export const exercices_idx = derived( export const exercices_idx = derived(
themesStore, themesStore,
($themesStore) => ($themesStore.exercices_idx), ($themesStore) => {
const ret = {};
for (const key in $themesStore) {
const theme = $themesStore[key];
for (let k in theme.exercices) {
ret[k] = theme.exercices[k];
}
}
return ret;
},
); );
export const max_solved = derived( export const max_solved = derived(
themesStore, themesStore,
($themesStore) => ($themesStore.max_solved), ($themesStore) => {
let ret = 0;
for (const key in $themesStore) {
const theme = $themesStore[key];
if (theme.solved > ret) {
ret = theme.solved;
}
}
return ret;
},
); );

View file

@ -132,7 +132,7 @@
<th>Messages</th> <th>Messages</th>
<th> <th>
{#if !data.fillIssue} {#if !data.fillIssue}
<Button sm color="warning" on:click={newIssue}> <Button size="sm" color="warning" on:click={newIssue}>
<Icon name="file-earmark-plus" /> <Icon name="file-earmark-plus" />
</Button> </Button>
{/if} {/if}
@ -159,7 +159,7 @@
</td> </td>
<td> <td>
<Button <Button
sm size="sm"
color={issue.state == 'need-info'?'danger':'light'} color={issue.state == 'need-info'?'danger':'light'}
on:click={respondTo(issue)} on:click={respondTo(issue)}
> >