Last active
June 24, 2024 16:56
-
-
Save mattbloomfield/a37b447ae9ca97439c3e0c2382325488 to your computer and use it in GitHub Desktop.
Exports all the events on your agenda for Figma's config (2024 only)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const days = document.querySelectorAll('.bigmarker-cg-myagenda-section-part'); | |
let index = 0; | |
for (let day of days) { | |
index++; | |
let sessions = day.querySelectorAll('.session-li'); | |
let sessionDate = day.querySelector('.bigmarker-cg-myagenda-section-date').textContent; | |
if (sessionDate.includes('Wednesday')) { | |
sessionDate = '2024-06-26'; | |
} | |
if (sessionDate.includes('Thursday')) { | |
sessionDate = '2024-06-27'; | |
} | |
let sessionIndex = 0; | |
const insertArea = day.querySelector('.bigmarker-cg-myagenda-section-top'); | |
const downloadButton = document.createElement('button'); | |
downloadButton.textContent = 'Download All Sessions'; | |
downloadButton.addEventListener('click', () => { | |
for (let session of sessions) { | |
sessionIndex++; | |
let sessionTitle = session.querySelector('.bigmarker-cg-myagenda-session-name').textContent.replace(/\n/g, '').replace(/\s+/g, ' ').trim(); | |
let sessionTime = session.querySelector('.bigmarker-cg-myagenda-session-time').textContent.replace(/\n/g, '').replace(/\s+/g, ' ').trim();; | |
sessionTime = getDateTimes(sessionDate, sessionTime); | |
let sessionInfo = session.querySelector('.bigmarker-cg-myagenda-session-right').textContent | |
// remove extra spaces and escape newlines | |
sessionInfo = sessionInfo.replace(/\n{2,}/g, '\\n').replace(/\s+/g, ' ').trim(); | |
// now remove any instance of multiple newlines and replace with a single newline | |
// sessionInfo = sessionInfo.replace(/\\n{2,}/g, '\\n'); | |
console.log(sessionTitle, sessionTime, sessionInfo); | |
const ics = convertToIcs(index + '-' + sessionIndex, sessionTitle, sessionTime, sessionInfo); | |
// download the file | |
const link = document.createElement('a'); | |
link.href = ics; | |
link.download = `${sessionTitle + '-' + index + '-' + sessionIndex}.ics`; | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
} | |
}); | |
insertArea.appendChild(downloadButton); | |
} | |
function getDateTimes(sessionDate, sessionTime) { | |
const parsedTime = sessionTime.split('-'); | |
const startTime = parsedTime[0]; | |
const endTime = parsedTime[1]; | |
let startHour = parseInt(startTime.split(':')[0]); | |
let endHour = parseInt(endTime.split(':')[0]); | |
let startMinute = parseInt(startTime.split(':')[1]); | |
let endMinute = parseInt(endTime.split(':')[1]); | |
if (endTime.includes('P')) { | |
if (startHour < 12) { | |
startHour = startHour + 12; | |
} | |
if (endHour < 12) { | |
endHour = endHour + 12; | |
} | |
} | |
// adjust hours and minutes to always be two digits | |
startHour = startHour < 10 ? '0' + startHour : startHour; | |
endHour = endHour < 10 ? '0' + endHour : endHour; | |
startMinute = startMinute < 10 ? '0' + startMinute : startMinute; | |
endMinute = endMinute < 10 ? '0' + endMinute : endMinute; | |
// convert to this format: YYYYMMDDTHHMMSS | |
sessionDate = sessionDate.replace(/-/g, ''); | |
return { | |
start: `${sessionDate}T${startHour}${startMinute}00`, | |
end: `${sessionDate}T${endHour}${endMinute}00` | |
}; | |
} | |
function convertToIcs(index, summary, date, description) { | |
var icsFile = null; | |
var fileContents = | |
"BEGIN:VCALENDAR\n" + | |
"PRODID:-//Figma Config Cal//EN\n" + | |
"VERSION:2.0\n" + | |
"CALSCALE:GREGORIAN\n" + | |
"METHOD:PUBLISH\n" + | |
"BEGIN:VTIMEZONE\n" + | |
"TZID:America/Los_Angeles\n" + | |
"LAST-MODIFIED:20231222T233358Z\n" + | |
"TZURL:https://www.tzurl.org/zoneinfo-outlook/America/Los_Angeles\n" + | |
"X-LIC-LOCATION:America/Los_Angeles\n" + | |
"BEGIN:DAYLIGHT\n" + | |
"TZNAME:PDT\n" + | |
"TZOFFSETFROM:-0800\n" + | |
"TZOFFSETTO:-0700\n" + | |
"DTSTART:19700308T020000\n" + | |
"RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU\n" + | |
"END:DAYLIGHT\n" + | |
"BEGIN:STANDARD\n" + | |
"TZNAME:PST\n" + | |
"TZOFFSETFROM:-0700\n" + | |
"TZOFFSETTO:-0800\n" + | |
"DTSTART:19701101T020000\n" + | |
"RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\n" + | |
"END:STANDARD\n" + | |
"END:VTIMEZONE\n" + | |
"BEGIN:VEVENT\n" + | |
"DTSTAMP:20240624T000000Z\n" + | |
"UID:config-" + index + "\n" + | |
"DTSTART;TZID=America/Los_Angeles:" + date.start + "\n" + | |
"DTEND;TZID=America/Los_Angeles:" + date.end + "\n" + | |
"SUMMARY:" + summary + "\n" + | |
"TZID:America/Los_Angeles\n" + | |
"DESCRIPTION:" + description + "\n" + | |
"BEGIN:VALARM\n" + | |
"TRIGGER:-PT10M\n" + | |
"ACTION:DISPLAY\n" + | |
"DESCRIPTION:Reminder\n" + | |
"END:VALARM\n" + | |
"END:VEVENT\n" + | |
"END:VCALENDAR"; | |
var data = new File([fileContents], { type: "text/plain" }); | |
// If we are replacing a previously generated file we need to | |
// manually revoke the object URL to avoid memory leaks. | |
if (icsFile !== null) { | |
window.URL.revokeObjectURL(icsFile); | |
} | |
icsFile = window.URL.createObjectURL(data); | |
return icsFile; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment