Implemented basic channel guide, needs moar polish

This commit is contained in:
rainbow napkin 2026-11-11 16:26:33 -05:00
parent c78b056cab
commit f7db5ea31d
3 changed files with 109 additions and 20 deletions

View file

@ -19,6 +19,9 @@ class ChannelGuide{
//define property to hold refresh timer
this.refreshTimer;
//define property to hold schedule cache
this.cache;
//Grab DOM Nodes
this.scheduleIndex = document.querySelector('#channel-guide-schedule-index');
this.channelList = document.querySelector('#channel-guide-channel-list');
@ -28,14 +31,17 @@ class ChannelGuide{
this.refreshList();
}
async refreshList(){
//Fetch latest channel list and render it to the schedule page
this.renderList(await utils.ajax.getChannels());
async refreshList(now = new Date()){
//Freshen up the local schedule cache
this.cache = await utils.ajax.getChannels();
//render the freshly pulled schedule data to the page
this.renderList(this.cache, now);
}
renderList(schedule, now = new Date()){
this.renderIndex(now);
this.renderChannelList(schedule, now);
this.renderChannelList(schedule);
this.renderSchedule(schedule, now);
//if we've got a job to refresh the list
@ -70,7 +76,7 @@ class ChannelGuide{
}
}
renderChannelList(schedule, now = new Date()){
renderChannelList(schedule){
//Clean out channel list
this.channelList.innerHTML = '';
@ -96,27 +102,24 @@ class ChannelGuide{
//Clear out the schedule
this.scheduledMediaDiv.innerHTML = '';
schedule = this.fillDeadAir(schedule, now);
//Iterate through all of the received channels
for(const channel of schedule){
//Create a div to hold all of the current channels entries
const channelTrack = document.createElement('div');
channelTrack.classList.add('channel-guide-schedule-track');
channelTrack.classList.add('channel-guide-schedule-track', 'channel-guide-schedule-row');
//For every scheduled video
for(const entry of channel.schedule){
//Create div for current schedule entry
const entryDiv = document.createElement('div');
entryDiv.classList.add('channel-guide-schedule-entry', 'channel-guide-schedule-row');
//Throw down an entry label
const entryLabel = document.createElement('h3');
entryLabel.textContent = utils.unescapeEntities(entry.title);
//Assemble the entry
entryDiv.appendChild(entryLabel);
for(const entryIndex in channel.schedule){
//Get entry by index
const entry = channel.schedule[entryIndex];
//Check if this is the last item
const last = entryIndex == channel.schedule.length - 1;
//slot entry into schedule track
channelTrack.appendChild(entryDiv);
channelTrack.appendChild(this.renderScheduleItem(entry, now, last));
}
//Inject channel track into schedule div
@ -124,7 +127,74 @@ class ChannelGuide{
}
}
renderScheduleItem(item){
fillDeadAir(schedule){
//For each video in the schedule
for(const video of schedule){
}
//Return processed schedule
return schedule;
}
renderScheduleItem(item, now = new Date(), last = false){
//Create div for current schedule entry
const entryDiv = document.createElement('div');
entryDiv.classList.add('channel-guide-schedule-entry', 'channel-guide-schedule-row');
//Throw down an entry label
const entryLabel = document.createElement('h3');
entryLabel.textContent = utils.unescapeEntities(item.title);
//calculate end epoch
const end = item.startTime + (item.duration * 1000);
//Place entryDiv by scheduled time
entryDiv.style.left = `${this.offsetByEpoch(item.startTime, now)}px`;
entryDiv.style.right = `${this.offsetByEpoch(end, now, true)}px`;
//if this started before the schedule time range
if(item.startTime < now.getTime()){
//mark it for css
entryDiv.classList.add('starts-before');
}
//if this is the last item and it ends before the schedule time range
if(last && end < now.getTime() + 5400000){
//mark it for css
entryDiv.classList.add('last-ends-before');
}
//Assemble the entry
entryDiv.appendChild(entryLabel);
//Return assembled entry div
return entryDiv;
}
offsetByEpoch(scheduleEpoch, now = new Date(), rightOffset = false){
//Calculate how many milliseconds after the current time our scheduled item is
const ms = scheduleEpoch - now.getTime();
//Calculate and return offset by milliseconds
return this.offsetByMilliseconds(ms, rightOffset, rightOffset);
}
offsetByMilliseconds(ms, rightOffset = false){
//Calculate place in schedule as float between 0 and 1 by deviding input by schedules range (90 minutes)
//Making sure to reverse value if rightOffset is thrown
const timeFloat = rightOffset ? 1 - ms / 5400000 : ms / 5400000;
//Get maximum position relative to the range itself
const offsetMax = this.scheduledMediaDiv.getBoundingClientRect().width;
//Calculate offset by timefloat and offset max
const offset = (offsetMax * timeFloat) < 0 ? 0 : (offsetMax * timeFloat);
//return position relative to parent, adding channel list width to left side to handle offset
return offset;
}
}