feat: fetch using a start/end window rather than everything, use eventSources from FC.js
This commit is contained in:
parent
dca9888373
commit
4b2426960b
2 changed files with 41 additions and 46 deletions
|
@ -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>
|
||||
|
|
|
@ -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]))
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue