Added proper handling of items that begin late and end early.
This commit is contained in:
parent
330c4c275b
commit
179a10fb72
|
|
@ -51,6 +51,7 @@ module.exports = class{
|
|||
|
||||
defineListeners(socket){
|
||||
socket.on("queue", (data) => {this.queueURL(socket, data)});
|
||||
socket.on("stop", (data) => {this.stopMedia(socket)});
|
||||
socket.on("delete", (data) => {this.deleteMedia(socket, data)});
|
||||
socket.on("move", (data) => {this.moveMedia(socket, data)});
|
||||
socket.on("clear", (data) => {this.deleteRange(socket, data)});
|
||||
|
|
@ -110,18 +111,6 @@ module.exports = class{
|
|||
return;
|
||||
}
|
||||
|
||||
//If we have an invalid time
|
||||
if(start == null || start < (new Date).getTime()){
|
||||
//Get last item from schedule
|
||||
const lastItem = (Array.from(this.schedule)[this.schedule.size - 1]);
|
||||
|
||||
//if we have a last item
|
||||
if(lastItem != null){
|
||||
//Throw it on five ms after the last item
|
||||
start = lastItem[1].startTime + (lastItem[1].duration * 1000) + 5;
|
||||
}
|
||||
}
|
||||
|
||||
//Queue the first media object given
|
||||
this.queueMedia(mediaList[0], start, socket);
|
||||
}catch(err){
|
||||
|
|
@ -143,7 +132,6 @@ module.exports = class{
|
|||
//and ignore it!
|
||||
return;
|
||||
}
|
||||
|
||||
//If end time isn't an integer
|
||||
if(data.end != null && !validator.isInt(String(data.end))){
|
||||
//Bitch, moan, complain...
|
||||
|
|
@ -195,7 +183,7 @@ module.exports = class{
|
|||
return;
|
||||
}
|
||||
|
||||
//If start time isn't an integer after the current epoch
|
||||
//If start time isn't an integer
|
||||
if(data.start != null && !validator.isInt(String(data.start))){
|
||||
//Null out time to tell the later parts of the function to start it now
|
||||
data.start = undefined;
|
||||
|
|
@ -224,9 +212,32 @@ module.exports = class{
|
|||
}
|
||||
|
||||
//Default start time to now + half a second to give everyone time to process shit
|
||||
queueMedia(inputMedia, start = new Date().getTime() + 50, socket){
|
||||
queueMedia(inputMedia, start, socket){
|
||||
//If we have an invalid time
|
||||
if(start == null || start < (new Date).getTime()){
|
||||
//Get last item from schedule
|
||||
const lastItem = (Array.from(this.schedule)[this.schedule.size - 1]);
|
||||
|
||||
const now = new Date().getTime()
|
||||
|
||||
//if we have a last item
|
||||
if(lastItem != null){
|
||||
//If the last item has ended
|
||||
if(lastItem[1].getEndTime() < now){
|
||||
start = now + 5;
|
||||
//If it hasn't started yet
|
||||
}else{
|
||||
//Throw it on five ms after the last item
|
||||
start = lastItem[1].getEndTime() + 5;
|
||||
}
|
||||
}else{
|
||||
//Throw it on five ms after the last item
|
||||
start = now + 5;
|
||||
}
|
||||
}
|
||||
|
||||
//Create a new media queued object, set start time to now
|
||||
const mediaObj = queuedMedia.fromMedia(inputMedia, start);
|
||||
const mediaObj = queuedMedia.fromMedia(inputMedia, start, 0);
|
||||
|
||||
//schedule the media
|
||||
this.scheduleMedia(mediaObj, socket);
|
||||
|
|
@ -244,7 +255,7 @@ module.exports = class{
|
|||
//If we have a current item and it isn't currently playing
|
||||
if(currentItem != null && (this.nowPlaying == null || currentItem.uuid != this.nowPlaying.uuid)){
|
||||
//Start the found item at w/ a pre-calculated time stamp to reflect the given start time
|
||||
this.start(currentItem, Math.round((new Date().getTime() - currentItem.startTime) / 1000));
|
||||
this.start(currentItem, Math.round((new Date().getTime() - currentItem.startTime) / 1000) + currentItem.startTimeStamp);
|
||||
}
|
||||
//otherwise if we have an item
|
||||
}else{
|
||||
|
|
@ -254,7 +265,7 @@ module.exports = class{
|
|||
//Clear out any item that might be up next
|
||||
clearTimeout(this.nextTimer);
|
||||
//Set the next timer
|
||||
this.nextTimer = setTimeout(()=>{this.start(nextItem)}, startsIn);
|
||||
this.nextTimer = setTimeout(()=>{this.start(nextItem, nextItem.startTimeStamp)}, startsIn);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -269,9 +280,9 @@ module.exports = class{
|
|||
}
|
||||
}
|
||||
|
||||
rescheduleMedia(uuid, start = new Date().getTime() + 50, socket){
|
||||
//Find and remove media from the schedule by UUID
|
||||
const media = this.removeMedia(uuid);
|
||||
rescheduleMedia(uuid, start = new Date().getTime() + 5, socket){
|
||||
//Find our media, don't remove it yet since we want to do some more testing first
|
||||
const media = this.getItemByUUID(uuid);
|
||||
|
||||
//If we got a bad request
|
||||
if(media == null){
|
||||
|
|
@ -284,20 +295,50 @@ module.exports = class{
|
|||
return;
|
||||
}
|
||||
|
||||
//If someone is trying to re-schedule something that starts in the past
|
||||
if(media.startTime < new Date().getTime()){
|
||||
//If an originating socket was provided for this request
|
||||
if(socket != null){
|
||||
|
||||
//If the item is currently playing
|
||||
if(media.getEndTime() > new Date().getTime()){
|
||||
//Yell at the user for being an asshole
|
||||
loggerUtils.socketErrorHandler(socket, "You cannot move an actively playing video!", "queue");
|
||||
//Otherwise, if it's already ended
|
||||
}else{
|
||||
//Yell at the user for being an asshole
|
||||
loggerUtils.socketErrorHandler(socket, "You cannot alter the past!", "queue");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Ignore it
|
||||
return;
|
||||
}
|
||||
|
||||
//Remove the media from the schedule
|
||||
this.removeMedia(uuid);
|
||||
|
||||
//Grab the old start time for safe keeping
|
||||
const oldStart = media.startTime;
|
||||
|
||||
//Set media time
|
||||
media.startTime = start;
|
||||
|
||||
//Reset the start time stamp for re-calculation
|
||||
media.startTimeStamp = 0;
|
||||
|
||||
//Attempt to schedule media at given time
|
||||
//Otherwise, if it returns false for fuckup
|
||||
if(!this.scheduleMedia(media, socket)){
|
||||
//Reset start time
|
||||
media.startTime = oldStart;
|
||||
|
||||
//Reset the start time stamp for re-calculation
|
||||
media.startTimeStamp = 0;
|
||||
|
||||
//Schedule in old slot
|
||||
this.scheduleMedia(media, socket);
|
||||
this.scheduleMedia(media, socket, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -335,7 +376,33 @@ module.exports = class{
|
|||
return media;
|
||||
}
|
||||
|
||||
scheduleMedia(mediaObj, socket){
|
||||
stopMedia(socket){
|
||||
//If we're not currently playing anything
|
||||
if(this.nowPlaying == null){
|
||||
//If an originating socket was provided for this request
|
||||
if(socket != null){
|
||||
//Yell at the user for being an asshole
|
||||
loggerUtils.socketErrorHandler(socket, "No media playing!", "queue");
|
||||
}
|
||||
|
||||
//Ignore it
|
||||
return false;
|
||||
}
|
||||
|
||||
//Stop playing
|
||||
const stoppedMedia = this.nowPlaying;
|
||||
|
||||
//End the media
|
||||
this.end();
|
||||
|
||||
//Get difference between current time and start time and set as early end
|
||||
stoppedMedia.earlyEnd = (new Date().getTime() - stoppedMedia.startTime) / 1000;
|
||||
|
||||
//Broadcast the channel queue
|
||||
this.broadcastQueue();
|
||||
}
|
||||
|
||||
scheduleMedia(mediaObj, socket, force = false){
|
||||
/* This is a fun method and I think it deserves it's own little explination...
|
||||
Since we're working with a time based schedule, using start epochs as keys for our iterable seemed the best option
|
||||
I don't want to store everything in a sparse array because that *feels* icky, and would probably be a pain in the ass.
|
||||
|
|
@ -364,8 +431,26 @@ module.exports = class{
|
|||
https://community.appsmith.com/content/blog/dark-side-foreach-why-you-should-think-twice-using-it
|
||||
*/
|
||||
|
||||
//If someone is trying to schedule something that starts and ends in the past
|
||||
if((mediaObj.getEndTime() < new Date().getTime()) && !force){
|
||||
//If an originating socket was provided for this request
|
||||
if(socket != null){
|
||||
//Yell at the user for being an asshole
|
||||
loggerUtils.socketErrorHandler(socket, "You cannot alter the past!", "queue");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//If the item has already started and it's not being forced
|
||||
if((mediaObj.startTime < new Date().getTime())){
|
||||
//Set time stamp to existing timestamp plus the difference between the orginal start-date and now
|
||||
mediaObj.startTimeStamp = mediaObj.startTimeStamp + ((new Date().getTime() - mediaObj.startTime) / 1000)
|
||||
//Start the item now
|
||||
mediaObj.startTime = new Date().getTime() + 5;
|
||||
}
|
||||
|
||||
//If there's already something queued right now
|
||||
if(this.getItemAtEpoch(mediaObj.startTime) != null || this.getItemAtEpoch(mediaObj.startTime + (mediaObj.duration * 1000))){
|
||||
if(this.getItemAtEpoch(mediaObj.startTime) != null || this.getItemAtEpoch(mediaObj.getEndTime())){
|
||||
//If an originating socket was provided for this request
|
||||
if(socket != null){
|
||||
//Yell at the user for being an asshole
|
||||
|
|
@ -375,7 +460,6 @@ module.exports = class{
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
//Create an empty temp array to sparsley populate with our schedule
|
||||
const tempSchedule = [];
|
||||
//Create new map to replace our current schedule map
|
||||
|
|
@ -409,7 +493,7 @@ module.exports = class{
|
|||
return mediaObj;
|
||||
}
|
||||
|
||||
start(mediaObj, timestamp = 0){
|
||||
start(mediaObj, timestamp = mediaObj.startTimeStamp){
|
||||
//Silently end the media
|
||||
this.end(true);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
|||
const media = require('./media');
|
||||
|
||||
module.exports = class extends media{
|
||||
constructor(title, fileName, url, id, type, duration, startTime){
|
||||
constructor(title, fileName, url, id, type, duration, startTime, startTimeStamp){
|
||||
//Call derived constructor
|
||||
super(title, fileName, url, id, type, duration);
|
||||
//Set media start time
|
||||
this.startTime = startTime;
|
||||
//Set the media start time stamp
|
||||
this.startTimeStamp = startTimeStamp;
|
||||
//Create empty variable to hold early end if media is stopped early
|
||||
this.earlyEnd = null;
|
||||
|
||||
//Generate id unique to this specific entry of this specific file within this specific channel's queue
|
||||
//That way even if we have six copies of the same video queued, we can still uniquely idenitify each instance
|
||||
|
|
@ -30,9 +34,17 @@ module.exports = class extends media{
|
|||
}
|
||||
|
||||
//statics
|
||||
static fromMedia(media, startTime){
|
||||
static fromMedia(media, startTime, startTimeStamp){
|
||||
//Create and return queuedMedia object from given media object and arguments
|
||||
return new this(media.title, media.fileName, media.url, media.id, media.type, media.duration, startTime);
|
||||
return new this(
|
||||
media.title,
|
||||
media.fileName,
|
||||
media.url,
|
||||
media.id,
|
||||
media.type,
|
||||
media.duration,
|
||||
startTime,
|
||||
startTimeStamp);
|
||||
}
|
||||
|
||||
//methods
|
||||
|
|
@ -41,6 +53,13 @@ module.exports = class extends media{
|
|||
}
|
||||
|
||||
getEndTime(){
|
||||
return this.startTime + (this.duration * 1000);
|
||||
//If we have an early ending
|
||||
if(this.earlyEnd == null){
|
||||
//Calculate our ending
|
||||
return this.startTime + ((this.duration - this.startTimeStamp) * 1000);
|
||||
}else{
|
||||
//Return our early end
|
||||
return this.startTime + (this.earlyEnd * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -505,18 +505,36 @@ div.queue-entry{
|
|||
background-color: var(--bg2-alt1);
|
||||
}
|
||||
|
||||
div.started-before-today{
|
||||
div.started-yesterday{
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-top: 1px dashed var(--accent1);
|
||||
}
|
||||
|
||||
div.ends-after-today{
|
||||
div.ends-tomorrow{
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom: 1px dashed var(--accent1);
|
||||
}
|
||||
|
||||
div.started-late{
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-top: 1px dashed var(--danger0-alt1);
|
||||
}
|
||||
|
||||
div.ended-early{
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom: 1px dashed var(--danger0-alt1);
|
||||
}
|
||||
|
||||
div.now-playing{
|
||||
color: var(--focus0);
|
||||
box-shadow: var(--focus-glow0);
|
||||
text-shadow: var(--focus-glow0);
|
||||
}
|
||||
|
||||
/* altcha theming*/
|
||||
div.altcha{
|
||||
box-shadow: 4px 4px 1px var(--bg1-alt0) inset;
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ class queuePanel extends panelObj{
|
|||
this.client.socket.on("clientMetadata", (data) => {this.renderQueue();});
|
||||
this.client.socket.on("queue", (data) => {this.renderQueue();});
|
||||
this.client.socket.on("lock", this.handleScheduleLock.bind(this));
|
||||
this.client.socket.on("error", this.handleQueueError.bind(this));
|
||||
}
|
||||
|
||||
setupInput(){
|
||||
|
|
@ -123,6 +124,26 @@ class queuePanel extends panelObj{
|
|||
}
|
||||
}
|
||||
|
||||
handleQueueError(data){
|
||||
//Create a flag to reload the queue
|
||||
let reloadQueue = false;
|
||||
|
||||
//Check errors
|
||||
for(let error of data.errors){
|
||||
//If we have a queue error
|
||||
if(error.type == "queue"){
|
||||
//Throw the reload flag
|
||||
reloadQueue = true;
|
||||
}
|
||||
}
|
||||
|
||||
//If we need to reload the queue
|
||||
if(reloadQueue){
|
||||
//Do so
|
||||
this.renderQueue();
|
||||
}
|
||||
}
|
||||
|
||||
/* queue control button functions */
|
||||
toggleAddMedia(event){
|
||||
//If the div is hidden
|
||||
|
|
@ -491,13 +512,13 @@ class queuePanel extends panelObj{
|
|||
entryDiv.style.top = `${this.offsetByDate(dawn)}px`;
|
||||
|
||||
//Run apply the rest of the styling rules
|
||||
entryDiv.classList.add('started-before-today');
|
||||
entryDiv.classList.add('started-yesterday');
|
||||
}
|
||||
|
||||
//If the item ends today
|
||||
if(endsToday){
|
||||
//Place the bottom of the entry div based on time
|
||||
entryDiv.style.bottom = `${this.offsetByDate(new Date(entry[1].startTime + (entry[1].duration * 1000)), true)}px`;
|
||||
entryDiv.style.bottom = `${this.offsetByDate(new Date(this.getMediaEnd(entry[1])), true)}px`;
|
||||
}else{
|
||||
//Get midnight
|
||||
const dusk = new Date();
|
||||
|
|
@ -507,7 +528,17 @@ class queuePanel extends panelObj{
|
|||
entryDiv.style.bottom = `${this.offsetByDate(dusk, true)}px`;
|
||||
|
||||
//Run apply the rest of the styling rules
|
||||
entryDiv.classList.add('ends-after-today');
|
||||
entryDiv.classList.add('ends-tomorrow');
|
||||
}
|
||||
|
||||
//If we started in the middle of the video
|
||||
if(entry[1].startTimeStamp > 0){
|
||||
entryDiv.classList.add('started-late');
|
||||
}
|
||||
|
||||
//If we ended early
|
||||
if(entry[1].earlyEnd != null){
|
||||
entryDiv.classList.add('ended-early');
|
||||
}
|
||||
|
||||
//Create entry title
|
||||
|
|
@ -526,8 +557,8 @@ class queuePanel extends panelObj{
|
|||
`File Name: ${entry[1].fileName}`,
|
||||
`Source: ${entry[1].type}`,
|
||||
`Duration: ${entry[1].duration}`,
|
||||
`Start Time: ${new Date(entry[1].startTime).toLocaleString()}`,
|
||||
`End Time: ${new Date(entry[1].startTime + (entry[1].duration * 1000)).toLocaleString()}`
|
||||
`Start Time: ${new Date(entry[1].startTime).toLocaleString()}${entry[1].startTimeStamp == 0 ? '' : ' (Started Late)'}`,
|
||||
`End Time: ${new Date(this.getMediaEnd(entry[1])).toLocaleString()}`
|
||||
]){
|
||||
//Create a 'p' node
|
||||
const component = document.createElement('p');
|
||||
|
|
@ -546,14 +577,29 @@ class queuePanel extends panelObj{
|
|||
}
|
||||
});
|
||||
|
||||
//context menu
|
||||
const menuMap = new Map([
|
||||
["Play now", ()=>{this.client.socket.emit('move', {uuid: entry[1].uuid})}],
|
||||
["Move To...", (event)=>{new reschedulePopup(event, this.client, entry[1], null, this.ownerDoc)}],
|
||||
["Delete", ()=>{this.client.socket.emit('delete', {uuid: entry[1].uuid})}],
|
||||
["Open in New Tab", ()=>{window.open(entry[1].url, '_blank').focus();}],
|
||||
["Copy URL", ()=>{navigator.clipboard.writeText(entry[1].url);}],
|
||||
]);
|
||||
//Create context menu map
|
||||
const menuMap = new Map();
|
||||
|
||||
//If the item hasn't started yet
|
||||
if(entry[1].startTime > new Date().getTime()){
|
||||
//Add 'Play' option to context menu
|
||||
menuMap.set("Play now", ()=>{this.client.socket.emit('move', {uuid: entry[1].uuid})});
|
||||
//Add 'Move To...' option to context menu
|
||||
menuMap.set("Move To...", (event)=>{new reschedulePopup(event, this.client, entry[1], null, this.ownerDoc)});
|
||||
//Otherwise, if the item is currently playing
|
||||
}else if(this.getMediaEnd(entry[1]) > new Date().getTime()){
|
||||
//Add 'Stop' option to context menu
|
||||
menuMap.set("Stop", ()=>{this.client.socket.emit('stop', {uuid: entry[1].uuid})});
|
||||
//Add the Now Playing glow, not the prettiest place to add this, but why let a good conditional go to waste?
|
||||
entryDiv.classList.add('now-playing');
|
||||
}
|
||||
|
||||
//Add 'Delete' option to context menu
|
||||
menuMap.set("Delete", ()=>{this.client.socket.emit('delete', {uuid: entry[1].uuid})})
|
||||
//Add 'New Tab' option to context menu
|
||||
menuMap.set("Open in New Tab", ()=>{window.open(entry[1].url, '_blank').focus();})
|
||||
//Add 'Copy URL' option to context menu
|
||||
menuMap.set("Copy URL", ()=>{navigator.clipboard.writeText(entry[1].url);})
|
||||
|
||||
//Setup drag n drop
|
||||
entryDiv.addEventListener('mousedown', clickEntry.bind(this));
|
||||
|
|
@ -582,8 +628,29 @@ class queuePanel extends panelObj{
|
|||
return;
|
||||
}
|
||||
|
||||
//Create variables to hold width and height
|
||||
const height = event.target.offsetHeight;
|
||||
//Grab existing height
|
||||
let height = event.target.offsetHeight;
|
||||
let cutoffOffset = 0;
|
||||
|
||||
//If the item got cut-off at the bottom
|
||||
if(event.target.classList.contains("ends-tomorrow") || event.target.classList.contains("ended-early")){
|
||||
//Calculate height from duration
|
||||
height = this.offsetByMilliseconds(Number(event.target.dataset['duration']) * 1000);
|
||||
//If the item got cut-off at the top
|
||||
}else if(event.target.classList.contains('started-yesterday') || event.target.classList.contains("started-late")){
|
||||
//Keep old height for now
|
||||
const oldHeight = height;
|
||||
|
||||
//Calculate height from duration
|
||||
height = this.offsetByMilliseconds(Number(event.target.dataset['duration']) * 1000);
|
||||
|
||||
//Calculate the mouse offset needed to keep it properly placed relative to the original click point
|
||||
cutoffOffset = height - oldHeight;
|
||||
}
|
||||
|
||||
//Remove any cut-off borders
|
||||
event.target.classList.remove('ends-tomorrow', 'started-yesterday', 'ended-early', 'started-late');
|
||||
|
||||
|
||||
//If we havent set height or width
|
||||
if(event.target.style.height == ""){
|
||||
|
|
@ -611,7 +678,7 @@ class queuePanel extends panelObj{
|
|||
this.ownerDoc.body.style.userSelect = 'none';
|
||||
|
||||
//Save top of target relative to window minus the mouse position as our drag offset
|
||||
event.target.dataset['dragoffset'] = (event.target.offsetTop + this.ownerDoc.defaultView.scrollY) - event.clientY;
|
||||
event.target.dataset['dragoffset'] = (event.target.offsetTop + this.ownerDoc.defaultView.scrollY) - event.clientY - cutoffOffset;
|
||||
|
||||
//Call the drag entry function to move the entry on click without re-writing the wheel
|
||||
(dragEntry.bind(this))(event, event.target, timetip);
|
||||
|
|
@ -711,7 +778,7 @@ class queuePanel extends panelObj{
|
|||
|
||||
function dropEntry(event, target, timetip){
|
||||
//Gross but works :P
|
||||
if(!target.isConnected){
|
||||
if(!target.isConnected || target.dataset['drag'] != "true"){
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -861,24 +928,9 @@ class queuePanel extends panelObj{
|
|||
const dayEpoch = new Date(date).setHours(0,0,0,0);
|
||||
//Get difference between now and day epoch to get time since the start of the current day in milliseconds
|
||||
const curTime = date.getTime() - dayEpoch;
|
||||
//Devide by amount of milliseconds in a day to convert time over to a floating point number between 0 and 1
|
||||
//Make sure to reverse it if bottomOffset is set to true
|
||||
const timeFloat = bottomOffset ? 1 - (curTime / 86400000) : 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){
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//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];
|
||||
//return position relative to parent
|
||||
return (offsetMax * timeFloat) + range[0];
|
||||
//Calculate the offset from todays milliseconds
|
||||
return this.offsetByMilliseconds(curTime, bottomOffset);
|
||||
}
|
||||
|
||||
dateByOffset(input = 0){
|
||||
|
|
@ -902,6 +954,38 @@ class queuePanel extends panelObj{
|
|||
//return our date
|
||||
return date;
|
||||
}
|
||||
|
||||
offsetByMilliseconds(input = 0, bottomOffset = false){
|
||||
//Convert amount of milliseconds to a float, 0 representing the start of the day and 1 representing the end.
|
||||
//Make sure to reverse it if bottomOffset is set to true
|
||||
const timeFloat = bottomOffset ? 1 - (input / 86400000) : input / 86400000;
|
||||
|
||||
//Get queue markers
|
||||
const markers = this.panelDocument.querySelectorAll('span.queue-marker');
|
||||
|
||||
//If the marker is null for some reason
|
||||
if(markers[0] == null){
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//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];
|
||||
//return position relative to parent
|
||||
return (offsetMax * timeFloat) + range[0];
|
||||
}
|
||||
|
||||
getMediaEnd(media){
|
||||
//If we have an early end
|
||||
if(media.earlyEnd != null){
|
||||
return media.startTime + (media.earlyEnd * 1000);
|
||||
//Otherwise
|
||||
}else{
|
||||
return media.startTime + ((media.duration - media.startTimeStamp) * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class schedulePopup{
|
||||
|
|
|
|||
|
|
@ -553,7 +553,19 @@ class canopyUXUtils{
|
|||
}
|
||||
|
||||
|
||||
fixCutoff(standalone = true, pageBreak = document.body.scrollWidth - document.body.getBoundingClientRect().width){
|
||||
fixCutoff(standalone = true, pageBreak){
|
||||
//If we have no pagebreak
|
||||
if(pageBreak == null){
|
||||
//If we have a document body
|
||||
if(document.body != null){
|
||||
pageBreak = document.body.scrollWidth - document.body.getBoundingClientRect().width
|
||||
//Otherwise
|
||||
}else{
|
||||
//Pretend nothing happened because we probably have bigger issues then a fucked up click-dragger cutoff
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Fix the page width
|
||||
if(this.flex){
|
||||
this.element.style.flexBasis = `${this.calcWidth(this.element.getBoundingClientRect().width + pageBreak)}vw`;
|
||||
|
|
|
|||
Loading…
Reference in a new issue