// import html2canvas from '/html2canvas-pro.min.js'; const scheduleDOM = document.getElementById('schedule'); const VERSION = "v1.0.0"; const days = [ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', ]; let schedule = { version: VERSION, days: {}, }; const offlineTitle = 'OFFLINE'; const offlineSubtitle = 'takin a nap'; document.addEventListener('readystatechange', () => { document.getElementById('version').innerText = VERSION; loadSchedule(); createSchedule(); document.getElementById('import').addEventListener('click', () => { importJSON(); }); document.getElementById('save').addEventListener('click', () => { saveSchedule(); }); document.getElementById('clipboard').addEventListener('click', () => { copyClipboard(); }); document.getElementById('save-image').addEventListener('click', () => { saveImage(); }); document.getElementById('export').addEventListener('click', () => { exportJSON(); }); }); function importJSON() { const filePicker = document.createElement('input'); filePicker.type = 'file'; filePicker.accept = 'application/json'; filePicker.addEventListener('input', () => { if (filePicker.files.length == 0) return; const file = filePicker.files[0]; file.text().then(text => { try { schedule = JSON.parse(text); for (const day in schedule.days) { const data = schedule.days[day]; const slot = document.getElementById(`slot-${day}`); if (!data.enabled) { slot.classList.add('disabled'); slot.querySelector('.timeslot-title').innerText = offlineTitle slot.querySelector('.timeslot-subtitle').innerText = offlineSubtitle continue; } slot.classList.remove('disabled'); slot.querySelector('.timeslot-time').innerText = data.time slot.querySelector('.timeslot-title').innerText = data.title slot.querySelector('.timeslot-subtitle').innerText = data.subtitle } } catch (err) { console.error(err); alert('Failed to import schedule. Check the browser console for details.'); } }).catch(err => { console.error(err); alert('Failed to import schedule. Check the browser console for details.'); }); }); filePicker.click(); } function saveSchedule() { localStorage.setItem('streamschedule', btoa(JSON.stringify(schedule))); } function loadSchedule() { const saved = localStorage.getItem('streamschedule'); if (!saved) return; schedule = JSON.parse(atob(saved)); } function copyClipboard() { html2canvas(scheduleDOM).then(/** @typeof HTMLCanvasElement */ canvas => { canvas.toBlob(blob => { const item = new ClipboardItem({ 'image/png': blob }); navigator.clipboard.write([item]); }) }); } function saveImage() { html2canvas(scheduleDOM).then(canvas => { document.body.appendChild(canvas); }); } function exportJSON() { const json = JSON.stringify(schedule, null, '\t'); const data = new Blob([json], { type: 'application/json', }); const link = document.createElement('a'); link.href = URL.createObjectURL(data); link.download = 'stream-schedule.json'; link.click(); } function createSchedule() { for (let i = 0; i < days.length; i++) { const day = days[i]; if (schedule.days[day] == undefined) schedule.days[day] = { enabled: false, time: '6pm UTC', title: 'Untitled Event', subtitle: "yep, that sure is an event if i've ever seen one", }; const container = document.createElement('div'); container.className = 'timeslot'; container.id = `slot-${day}`; if (!schedule.days[day].enabled) container.classList.add('disabled'); const timeslotDateContainer = document.createElement('div'); timeslotDateContainer.className = 'timeslot-date'; const timeslotDay = document.createElement('div'); timeslotDay.className = 'timeslot-day'; timeslotDay.innerText = day.substring(0, 3).toUpperCase(); timeslotDateContainer.appendChild(timeslotDay); const timeslotTime = document.createElement('div'); timeslotTime.className = 'timeslot-time'; timeslotTime.innerText = schedule.days[day].time; timeslotTime.contentEditable = true; timeslotDateContainer.appendChild(timeslotTime); container.appendChild(timeslotDateContainer); const timeslotContentContainer = document.createElement('div'); timeslotContentContainer.className = 'timeslot-content'; const timeslotTitle = document.createElement('div'); timeslotTitle.className = 'timeslot-title'; timeslotTitle.innerText = schedule.days[day].enabled ? schedule.days[day].title : offlineTitle; timeslotTitle.contentEditable = schedule.days[day].enabled; timeslotTitle.spellcheck = false; timeslotContentContainer.appendChild(timeslotTitle); const timeslotSubtitle = document.createElement('div'); timeslotSubtitle.className = 'timeslot-subtitle'; timeslotSubtitle.innerText = schedule.days[day].enabled ? schedule.days[day].subtitle : offlineSubtitle; timeslotSubtitle.contentEditable = schedule.days[day].enabled; timeslotSubtitle.spellcheck = false; timeslotContentContainer.appendChild(timeslotSubtitle); container.appendChild(timeslotContentContainer); scheduleDOM.appendChild(container); timeslotDay.addEventListener('click', () => { schedule.days[day].enabled = !schedule.days[day].enabled; timeslotTitle.contentEditable = schedule.days[day].enabled; timeslotSubtitle.contentEditable = schedule.days[day].enabled; if (schedule.days[day].enabled) { container.classList.remove('disabled'); timeslotTitle.innerText = schedule.days[day].title; timeslotSubtitle.innerText = schedule.days[day].subtitle; } else { container.classList.add('disabled'); timeslotTitle.innerText = offlineTitle; timeslotSubtitle.innerText = offlineSubtitle; } }); timeslotTitle.addEventListener('keyup', () => { schedule.days[day].title = timeslotTitle.innerText; }); timeslotSubtitle.addEventListener('keyup', () => { if (timeslotSubtitle.innerHTML.includes('
')) timeslotSubtitle.innerText = ''; schedule.days[day].subtitle = timeslotSubtitle.innerText; }); timeslotTime.addEventListener('keyup', () => { schedule.days[day].time = timeslotTime.innerText; }); } }