canopy/www/js/channel/panels/queuePanel.js

169 lines
6.1 KiB
JavaScript

class queuePanel extends panelObj{
constructor(client, panelDocument){
super(client, "Media Queue", "/panel/queue", panelDocument);
//Store releative scale of items in seconds, defaulting to 30 minute chunks
this.scale = 30 * 60;
}
docSwitch(){
//Get queue container
this.queueContainer = this.panelDocument.querySelector('#queue');
//If we have an existing time marker
if(this.timeMarker != null){
//Clear it out
this.timeMarker.remove();
this.timeMarker = null;
}
//Render out the queue
this.renderQueue();
}
closer(){
//Clear any remaining timers
clearTimeout(this.renderTimeMarker);
}
renderQueue(date = new Date()){
//Clear out queue container
this.queueContainer.innerHTML = '';
//Render out time scale
this.renderQueueScale(date);
for(let entry of this.client.queue){
//Create entry div
const entryDiv = document.createElement('div');
entryDiv.classList.add('queue-entry');
//Create entry title
const entryTitle = document.createElement('a');
entryTitle.textContent = entry[1].title;
entryTitle.href = entry[1].url;
//Append entry elements
entryDiv.append(entryTitle);
//Append entry
this.queueContainer.append(entryDiv);
}
}
renderTimeMarker(date = new Date()){
//Pull start of day epoch from given date
const dayEpoch = structuredClone(date).setHours(0,0,0,0);
//Get difference to get time since the start of the current day in seconds
const curTime = date.getTime() - dayEpoch;
//Get time in day as a float between 0 and 1
const timeFloat = curTime / 86400000;
//Get queue markers
const markers = this.panelDocument.querySelectorAll('span.queue-marker');
//If the marker is null for some reason
if(markers[0] == null){
//Try again in a second since the user probably just popped the panel or something :P
(smackTimer.bind(this))();
return;
}
//Get marker position range
const range = [markers[0].offsetTop, markers[markers.length - 1].offsetTop]
//Get maximum position relative to the range itself
const offsetMax = range[1] - range[0];
//Get marker position relative to parent
const markerPosition = (offsetMax * timeFloat) + range[0];
//if we need to make the time marker
if(this.timeMarker == null){
//Create time marker
this.timeMarker = document.createElement('span');
//Add time marker class
this.timeMarker.id = 'time-marker';
//Append time marker
this.queueContainer.appendChild(this.timeMarker);
}
//Set time marker position
this.timeMarker.style.top = `${markerPosition}px`;
(smackTimer.bind(this))();
function smackTimer(){
//Clear update timer
clearTimeout(this.timeMarkerTimer);
//Set timer to update marker every second
this.timeMarkerTimer = setTimeout(this.renderTimeMarker.bind(this), 1000);
}
}
renderQueueScale(inputDate = new Date()){
//Make sure we don't modify the date we're handed
const date = structuredClone(inputDate);
//Zero out date to midnight
date.setHours(0,0,0,0);
//Store epoch of current date at midnight for later user
const dateEpoch = date.getTime();
//while we've counted less than the amount of time in the day, count up by scale
for(let time = 0; time <= 86400; time += this.scale){
//Get index of current chunk by dividing time by scale
const index = time / this.scale;
//Set time by scale, we could do this against this.scale and date.getTime(), but this seemed cleaner :P
date.setTime(dateEpoch + (time * 1000))
//Create marker span
const markerSpan = document.createElement('div');
markerSpan.classList.add('queue-marker');
//Create marker line (unfortunately <hr> tags don't seem to play nice with parents who have display:flex)
const marker = document.createElement('span');
marker.classList.add('queue-marker');
//If it's even/zero
if(index % 2 == 0){
const markerLabel = document.createElement('p');
//If scale is over a minute then we don't need to display seconds
const seconds = this.scale > 60 ? '' : `:${('0' + date.getSeconds()).slice(-2)}`
//If we're counting AM
if(date.getHours() < 12){
//Display as AM
markerLabel.textContent = `${('0'+date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}${seconds}AM`
//If we're cointing noon
}else if(date.getHours() == 12){
//display as noon
markerLabel.textContent = `${('0'+date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}${seconds}PM`
//if we're counting pm
}else{
//display as pm
markerLabel.textContent = `${('0'+(date.getHours() - 12)).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}${seconds}PM`
}
//Add marker label to marker span
markerSpan.appendChild(markerLabel);
}
//Append marker to marker span
markerSpan.appendChild(marker);
//Append marker span to queue container
this.queueContainer.appendChild(markerSpan);
}
//Easiest way to wait for DOM to do it's thing is to:
//fires before next frame
requestAnimationFrame(()=>{
//fires before next-next frame (after next frame)
requestAnimationFrame(()=>{
//render the time marker
this.renderTimeMarker(inputDate);
});
});
}
}