server/frontend/ui/src/routes/__layout.svelte

173 lines
5.0 KiB
Svelte

<script context="module">
import { challengeInfo } from '../stores/challengeinfo.js';
import { issuesStore } from '../stores/issues.js';
import { my } from '../stores/my.js';
import { teamsStore } from '../stores/teams.js';
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)
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))
}
}
};
}
settings.update(await fetch('settings.json', {headers: {'Accept': 'application/json'}}), cb);
}
async function refresh_challengeInfo(cb=null) {
challengeInfo.update(await fetch('challenge.json', {headers: {'Accept': 'application/json'}}), cb);
}
let refresh_interval_teams = null;
async function refresh_teams(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);
teamsStore.update(await fetch('teams.json', {headers: {'Accept': 'application/json'}}), cb);
}
let refresh_interval_themes = null;
async function refresh_themes(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 themesStore.update(await fetch('themes.json', {headers: {'Accept': 'application/json'}}), cb);
}
let refresh_interval_my = null;
async function refresh_my(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);
my.update(await fetch('my.json', {headers: {'Accept': 'application/json'}}), cb);
}
let refresh_interval_issues = null;
async function refresh_issues(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);
issuesStore.update(await fetch('issues.json', {headers: {'Accept': 'application/json'}}), cb);
}
export async function load({ stuff }) {
await refresh_challengeInfo();
await refresh_settings();
await refresh_themes();
refresh_teams();
refresh_my((my) => {
if (my && my.team_id === 0) {
stop_refresh = true;
}
});
refresh_issues();
return {
stuff: {
...stuff,
refresh_challengeInfo,
refresh_settings,
refresh_teams,
refresh_themes,
refresh_my,
refresh_issues,
}
};
}
</script>
<script>
import '../fic.scss'
import "bootstrap-icons/font/bootstrap-icons.css";
import {
Container,
//Styles,
} from 'sveltestrap';
import Header from '../components/Header.svelte';
</script>
<svelte:head>
<title>{$challengeInfo.title}</title>
<meta name="author" content="{$challengeInfo.authors}">
</svelte:head>
<!--Styles /-->
<Header />
<slot></slot>
<style>
:global(body) {
overflow-y: scroll;
}
:global(a.badge) {
text-decoration: none;
}
:global(.text-justify) {
text-align: justify;
}
:global(.niceborder) {
border-bottom-style: solid;
border-bottom-width: 5px !important;
border-bottom-color: #4eaee6;
}
</style>