first commit! 🎉
This commit is contained in:
commit
c38c13e54a
5 changed files with 451 additions and 0 deletions
195
main.js
Normal file
195
main.js
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
// 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('<br>'))
|
||||
timeslotSubtitle.innerText = '';
|
||||
schedule.days[day].subtitle = timeslotSubtitle.innerText;
|
||||
});
|
||||
timeslotTime.addEventListener('keyup', () => {
|
||||
schedule.days[day].time = timeslotTime.innerText;
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue