feat: fetch using a start/end window rather than everything, use eventSources from FC.js

This commit is contained in:
Raito Bezarius 2022-03-06 17:30:42 +01:00
parent dca9888373
commit 4b2426960b
2 changed files with 41 additions and 46 deletions

View file

@ -10,7 +10,7 @@
import frLocale from '@fullcalendar/core/locales/fr';
import EventModal from './EventModal.svelte';
import FilterBar from './FilterBar.svelte';
import { refreshEvents, calendarTree } from './calendar';
import { mkSource, calendarTree } from './calendar';
import { debounce } from 'lodash';
import 'bootstrap/dist/css/bootstrap.css';
@ -57,34 +57,18 @@
month: mobile ? 'numeric' : 'long',
day: 'numeric'
},
events: [],
eventSources: [],
themeSystem: 'bootstrap5'
});
let selectedCalendars;
let updateTimer;
async function reloadEvents(selectedCalendars) {
const evts = await refreshEvents(selectedCalendars);
return evts.flat();
}
let selectedCalendars = [];
const updateEvents = debounce(calendars => {
return reloadEvents(calendars).then(events => {
options.update(opts => ({
...opts,
events
}));
});
}, 300);
onMount(async () => {
const events = await reloadEvents(selectedCalendars);
options.update(opts => ({
...opts,
events
eventSources: selectedCalendars.map(mkSource).filter(x => !!x)
}));
});
}, 300);
$: updateEvents(selectedCalendars);
</script>

View file

@ -1,5 +1,3 @@
import ICAL from 'ical.js'
const clouds = {
KLUB_RESEAU: 'klub-reseau',
ELEVES_ENS: 'eleves-ens'
@ -29,6 +27,10 @@ const calendars = {
}
}
const calendarsByName = Object.fromEntries(
Object.entries(calendars).map(([id, {name}]) => ([name, id]))
);
export const calendarTree = {
'Clubs COF': {
'Club réseau': {},
@ -47,12 +49,17 @@ export const calendarTree = {
const calendarIds = Object.keys(calendars)
function mkCalendarUrl(id, { cloud }) {
return `/cal/${cloud}/${id}/?export&accept=jcal`
function mkCalendarUrl(id, { cloud }, extra={}) {
return `/cal/${cloud}/${id}/?` + new URLSearchParams({
...extra,
export: true,
expand: true,
accept: 'jcal'
});
}
function fetchCalendar(id, cal) {
return fetch(mkCalendarUrl(id, cal), { credentials: 'omit' })
function fetchCalendar(id, cal, extra={}) {
return fetch(mkCalendarUrl(id, cal, extra), { credentials: 'omit' })
.then(resp => resp.json())
.catch(err => console.error(err))
}
@ -125,25 +132,29 @@ function mkEventsFromCalendar(id, cal) {
})
}
export function mkEvent(title, start, duration, ...rest) {
start = new Date(start)
const end = new Date(start)
end.setMinutes(start.getMinutes() + duration)
export function mkSource(name) {
const calendarId = calendarsByName[name];
if (!calendarId) return null;
const calendar = calendars[calendarId];
return {
title,
start,
end,
...rest
id: name,
...(calendar?.meta || {}),
success: calendarData => {
if (calendarData[0] !== 'vcalendar') return;
const cal = new Calendar(calendarId, calendarData);
return cal.events.map(fcEventFromjCalEvent(cal));
},
failure: error => {
console.error(`Fatal error during event source fetching of '${name}': ${error}`);
},
events: (info, successCallback, failureCallback) => {
const { start, end } = info;
fetchCalendar(calendarId, calendar, {
start: start.valueOf() / 1000,
end: end.valueOf() / 1000
})
.then(successCallback, failureCallback);
}
}
}
// TODO: move to FullCalendar custom fetcher to control start&end.
export function refreshEvents(selectedCalendars) {
return Promise.all(
calendarIds
.filter(id =>
selectedCalendars ? selectedCalendars.includes(calendars[id].name) : true
)
.map(id => mkEventsFromCalendar(id, calendars[id]))
)
}