forked from tochev/interlude
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschedule.js
More file actions
83 lines (61 loc) · 2.19 KB
/
schedule.js
File metadata and controls
83 lines (61 loc) · 2.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
class Schedule {
constructor(room, date, nowFunc) {
this.apiEndpointPrefix = 'https://cfp.openfest.org/openfest-2025';
this.nextLectureDelayMinutes = 4; // show the current lecture as next for the first N minutes
if(date) this.date = date;
if(room) this.room = room;
this.nowFunc = nowFunc;
// default to *actual* now if nowFunc not defined
this.now = () => moment(this.nowFunc?.call())
.subtract(this.nextLectureDelayMinutes, 'minutes');
this.roomMap = {
'A': 'Зала A',
'B': 'Зала B',
};
}
async update() {
const response = await fetch(this.apiEndpointPrefix + '/schedule/export/schedule.json?lang=bg');
if(!response.ok) { console.log("mrun"); return; }
const fullSchedule = await response.json();
const days = fullSchedule['schedule']['conference']['days'];
// select the current day, fallback to first day of conference
const today = this.date ? moment(this.date) : this.now();
let day = 0;
for(let i = 0; i < days.length; ++i) if(moment(days[i].date).isSame(today, 'day')) day = i;
let schedules;
if(this.room) schedules = { [this.roomMap[this.room]]: days[day]['rooms'][this.roomMap[this.room]] };
else schedules = Object.fromEntries(Object.entries(days[day]['rooms']).filter(([k,v]) => Object.values(this.roomMap).includes(k)));
this.rooms = Object.entries(schedules).map(([room, schedule]) => new RoomEvents(room, schedule, this.now));
}
}
class RoomEvents {
constructor(room, schedule, now) {
this.room = room;
this.now = now;
this.events = schedule.map(slot => ({
startTime: moment(slot.date),
endTime: moment(slot.date).add(moment.duration(slot.duration)),
...slot,
}));
}
roomName() { return this.room; }
upcomingEvents() {
return this.events.filter(e => e.startTime.isAfter(this.now()));
}
nextEvent() {
return this.upcomingEvents()[0];
}
currentEvent() {
const latestEvent = this.pastEvents().slice(-1).pop(); // get last, this is a huge js-ism
return latestEvent?.endTime.isAfter(this.now()) ? latestEvent : undefined;
}
futureEvents() {
return this.upcomingEvents().slice(1);
}
pastEvents() {
return this.events.filter(e => e.startTime.isBefore(this.now()));
}
allEvents() {
return this.events;
}
}