diff --git a/plugin-api.js b/plugin-api.js index af2be45..e654ba4 100644 --- a/plugin-api.js +++ b/plugin-api.js @@ -1,5 +1,9 @@ const MAX_COUNTDOWN = 60; +let allEventsFromOfficialSchedule = null; + +var nextId = 0; + var countdown = MAX_COUNTDOWN; var now = Date.now(); var eventsOnNow = []; @@ -16,13 +20,14 @@ grist.onRecords(function (records) { eventsOnNext = []; now = Date.now(); - var i = 0; + + getCampScheduleAndAddToLists(); for (const r of records) { const venue = r["venue"]; - if (["Stage A", "Stage B", "Stage C", "Arts", "Arcade Workshop"].includes(venue)) { + if (venueUnderInterest(venue)) { let e = new Event( - i++, + nextId++, r["title"], venue, r["video_privacy"], @@ -32,24 +37,14 @@ grist.onRecords(function (records) { Date.parse(r["end_date"]) ); - if (e.hasStarted() && !e.hasEnded()) { - eventsOnNow.push(e); - } else if (!e.hasStarted() && !e.hasEnded()) { - eventsOnNext.push(e); - } + addEventToAppropriateList(e); } } - eventsOnNow.sort((e1, e2) => { - return (e1.timeUntilEnd() > e2.timeUntilEnd()) ? 1 : ((e2.timeUntilEnd() > e1.timeUntilEnd()) ? -1 : 0) - }); + sortEventLists(); - eventsOnNext.sort((e1, e2) => { - return (e1.timeUntilStart() > e2.timeUntilStart()) ? 1 : ((e2.timeUntilStart() > e1.timeUntilStart()) ? -1 : 0) - }); - - populateList("happeningNow", eventsOnNow, false); - populateList("happeningNext", eventsOnNext, true); + populateListHtml("happeningNow", eventsOnNow, false); + populateListHtml("happeningNext", eventsOnNext, true); if (intervalId != null) { window.clearInterval(intervalId); @@ -104,7 +99,68 @@ function convertTimeToString(time) { return hours + " hours, " + minutes + " minutes"; } -function populateList(elementName, items, getStartsIn) { +function getCampScheduleAndAddToLists() { + // Get stuff from official schedule and async add to list + const apiUrl = "https://www.emfcamp.org/schedule/2026.json"; + + // Make a GET request + fetch(apiUrl) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }) + .then(data => { + for (const e of data) { + if (!((eventsOnNow.concat(eventsOnNext)).map((x) => x.title).includes(e.title))) { + for (const o of e.occurrences) { + if (venueUnderInterest(o.venue)) { + const event = new Event( + nextId++, + e.title, + o.venue, + e.video_privacy, + false, + "", + new Date(o.start_time), + new Date(o.end_time) + ); + + addEventToAppropriateList(event); + sortEventLists(); + } + } + } + } + }) + .catch(error => { + console.error('Error:', error); + }); +} + +function addEventToAppropriateList(event) { + if (event.hasStarted() && !event.hasEnded()) { + eventsOnNow.push(event); + } else if (!event.hasStarted() && !event.hasEnded()) { + eventsOnNext.push(event); + } +} + +function venueUnderInterest(venue) { + return (["Stage A", "Stage B", "Stage C", "Arts", "Arcade Workshop"].includes(venue)); +} + +function sortEventLists() { + eventsOnNow.sort((e1, e2) => { + return (e1.timeUntilEnd() > e2.timeUntilEnd()) ? 1 : ((e2.timeUntilEnd() > e1.timeUntilEnd()) ? -1 : 0) + }); + + eventsOnNext.sort((e1, e2) => { + return (e1.timeUntilStart() > e2.timeUntilStart()) ? 1 : ((e2.timeUntilStart() > e1.timeUntilStart()) ? -1 : 0)}); +} + +function populateListHtml(elementName, items, getStartsIn) { document.getElementById(elementName).innerHTML = ""; for (const i of items) { @@ -179,6 +235,7 @@ function populateList(elementName, items, getStartsIn) { } function refreshLists() { + getCampScheduleAndAddToLists(); // Clear anything that's finished while (eventsOnNow.length >0 && eventsOnNow.at(0).hasEnded()) { eventsOnNow.shift(); @@ -198,8 +255,9 @@ function handleCountdown() { // now = Date.now(); now = Date.now(); refreshLists(); - populateList("happeningNow", eventsOnNow, false); - populateList("happeningNext", eventsOnNext, true); + getCampScheduleAndAddToLists(); + populateListHtml("happeningNow", eventsOnNow, false); + populateListHtml("happeningNext", eventsOnNext, true); } let counterElement = document.getElementById("counter");