Continued work on media scheduler
This commit is contained in:
parent
9d01b4c962
commit
d5a2a51be2
14 changed files with 415 additions and 54 deletions
|
|
@ -57,7 +57,7 @@ class channel{
|
|||
this.socket.on("error", console.log);
|
||||
|
||||
this.socket.on("queue", (data) => {
|
||||
this.queue = data.queue;
|
||||
this.queue = new Map(data.queue);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ class channel{
|
|||
this.chatBox.handleClientInfo(data);
|
||||
|
||||
//Store queue for use by the queue panel
|
||||
this.queue = data.queue;
|
||||
this.queue = new Map(data.queue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class chatBox{
|
|||
this.autocompleteDisplay.addEventListener("click", this.tabComplete.bind(this));
|
||||
this.sendButton.addEventListener("click", this.send.bind(this));
|
||||
this.settingsIcon.addEventListener("click", ()=>{this.client.cPanel.setActivePanel(new panelObj(client))});
|
||||
this.adminIcon.addEventListener("click", ()=>{this.client.cPanel.setActivePanel(new panelObj(client))});
|
||||
this.adminIcon.addEventListener("click", ()=>{this.client.cPanel.setActivePanel(new queuePanel(client))});
|
||||
this.emoteIcon.addEventListener("click", ()=>{this.client.cPanel.setActivePanel(new emotePanel(client))});
|
||||
|
||||
//Header icons
|
||||
|
|
@ -310,11 +310,11 @@ class chatBox{
|
|||
const limit = window.innerWidth * .2;
|
||||
|
||||
//Set width to target or 20vh depending on whether or not we've hit the width limit
|
||||
this.chatPanel.style.width = targetChatWidth > limit ? `${targetChatWidth}px` : '20vh';
|
||||
this.chatPanel.style.flexBasis = targetChatWidth > limit ? `${targetChatWidth}px` : '20vh';
|
||||
|
||||
//Fix busted layout
|
||||
var pageBreak = document.body.scrollWidth - document.body.getBoundingClientRect().width;
|
||||
this.chatPanel.style.width = `${this.chatPanel.getBoundingClientRect().width + pageBreak}px`;
|
||||
this.chatPanel.style.flexBasis = `${this.chatPanel.getBoundingClientRect().width + pageBreak}px`;
|
||||
//This sometimes gets called before userList ahs been initiated :p
|
||||
if(this.client.userList != null){
|
||||
this.client.userList.clickDragger.fixCutoff();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class cPanel{
|
|||
this.poppedPanels = [];
|
||||
|
||||
//ClickDragger Objects
|
||||
this.activePanelDragger = new canopyUXUtils.clickDragger("#cpanel-active-drag-handle", "#cpanel-active-div", false);
|
||||
this.activePanelDragger = new canopyUXUtils.clickDragger("#cpanel-active-drag-handle", "#cpanel-active-div", false, null, false);
|
||||
this.pinnedPanelDragger = new canopyUXUtils.clickDragger("#cpanel-pinned-drag-handle", "#cpanel-pinned-div", false, this.client.chatBox.clickDragger);
|
||||
|
||||
//Element Nodes
|
||||
|
|
@ -150,6 +150,7 @@ class panelObj{
|
|||
this.name = name;
|
||||
this.pageURL = pageURL;
|
||||
this.panelDocument = panelDocument;
|
||||
this.ownerDoc = this.panelDocument.ownerDocument == null ? this.panelDocument : this.panelDocument.ownerDocument;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +163,8 @@ class panelObj{
|
|||
}
|
||||
|
||||
docSwitch(){
|
||||
//Set owner doc
|
||||
this.ownerDoc = this.panelDocument.ownerDocument == null ? this.panelDocument : this.panelDocument.ownerDocument;
|
||||
}
|
||||
|
||||
closer(){
|
||||
|
|
|
|||
|
|
@ -8,11 +8,16 @@ class queuePanel extends panelObj{
|
|||
//Create variable to hold rescale timer
|
||||
this.rescaleTimer = null;
|
||||
|
||||
this.autoscroll = true;
|
||||
|
||||
//Define non-input event listeners
|
||||
this.defineListeners();
|
||||
}
|
||||
|
||||
docSwitch(){
|
||||
//Call derived doc switch function
|
||||
super.docSwitch();
|
||||
|
||||
//Get queue div
|
||||
this.queue = this.panelDocument.querySelector('#queue');
|
||||
//Get queue container
|
||||
|
|
@ -24,6 +29,21 @@ class queuePanel extends panelObj{
|
|||
//Re-acquire time marker
|
||||
this.timeMarker = this.panelDocument.querySelector('#time-marker');
|
||||
|
||||
//Get main control buttons
|
||||
this.addMediaButton = this.panelDocument.querySelector('#queue-add-media');
|
||||
this.scrollLockButton = this.panelDocument.querySelector('#queue-scroll-lock');
|
||||
|
||||
//Get control divs
|
||||
//Add Media
|
||||
this.addMediaDiv = this.panelDocument.querySelector('#queue-media-prompts');
|
||||
|
||||
//Get control div elements
|
||||
//Add Media
|
||||
this.addMediaLinkPrompt = this.panelDocument.querySelector('#media-link-input');
|
||||
this.addMediaNamePrompt = this.panelDocument.querySelector('#media-name-input');
|
||||
this.queueLastButton = this.panelDocument.querySelector('#queue-last-button');
|
||||
this.queueAtButton = this.panelDocument.querySelector('#queue-at-button');
|
||||
|
||||
//Render out the queue
|
||||
this.fullRender();
|
||||
|
||||
|
|
@ -38,13 +58,48 @@ class queuePanel extends panelObj{
|
|||
|
||||
|
||||
defineListeners(){
|
||||
this.client.socket.on("queue", (data) => {
|
||||
this.renderQueue();
|
||||
})
|
||||
//Render queue when we receive a new copy of the queue data from the server
|
||||
this.client.socket.on("clientMetadata", (data) => {this.renderQueue();})
|
||||
this.client.socket.on("queue", (data) => {this.renderQueue();})
|
||||
}
|
||||
|
||||
setupInput(){
|
||||
//Re-render queue and time-marker on window resize as time-relative absolute positioning will be absolutely thrown
|
||||
this.ownerDoc.defaultView.addEventListener('resize', this.resizeRender.bind(this));
|
||||
|
||||
//queue
|
||||
this.queue.addEventListener('wheel', this.scaleScroll.bind(this));
|
||||
|
||||
//control bar controls
|
||||
this.addMediaButton.addEventListener('click', this.toggleAddMedia.bind(this));
|
||||
this.scrollLockButton.addEventListener('click', this.lockScroll.bind(this));
|
||||
|
||||
//control bar divs
|
||||
this.queueLastButton.addEventListener('click', this.queueLast.bind(this))
|
||||
}
|
||||
|
||||
toggleAddMedia(event){
|
||||
if(this.addMediaDiv.style.display == 'none'){
|
||||
this.addMediaDiv.style.display = '';
|
||||
}else{
|
||||
this.addMediaDiv.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
queueLast(event){
|
||||
//Send off the request
|
||||
this.client.socket.emit("queue",{url:this.addMediaLinkPrompt.value, title:this.addMediaNamePrompt.value});
|
||||
this.addMediaLinkPrompt.value = '';
|
||||
this.addMediaNamePrompt.value = '';
|
||||
}
|
||||
|
||||
lockScroll(event){
|
||||
//Enable scroll lock
|
||||
this.autoscroll = true;
|
||||
//Light the indicator
|
||||
this.scrollLockButton.classList.add('positive-button');
|
||||
//Render the marker early to insta-jump
|
||||
this.renderTimeMarker();
|
||||
}
|
||||
|
||||
scaleScroll(event){
|
||||
|
|
@ -85,7 +140,6 @@ class queuePanel extends panelObj{
|
|||
//Clear out the queue UI
|
||||
this.clearQueue();
|
||||
|
||||
|
||||
//Calculate new scale
|
||||
const newScale = this.scale + (scaleFactor * scrollDirection);
|
||||
|
||||
|
|
@ -107,6 +161,12 @@ class queuePanel extends panelObj{
|
|||
clearTimeout(this.rescaleTimer);
|
||||
//Set timeout to re-render after input stops
|
||||
this.rescaleTimer = setTimeout(this.fullRender.bind(this), 500);
|
||||
//Otherwise, if we're just scrolling
|
||||
}else{
|
||||
//Disable scroll lock
|
||||
this.autoscroll = false;
|
||||
//Unlight the indicator
|
||||
this.scrollLockButton.classList.remove('positive-button');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -167,12 +227,26 @@ class queuePanel extends panelObj{
|
|||
return timeStrings.join(', ');
|
||||
}
|
||||
|
||||
resizeRender(event){
|
||||
const date = new Date();
|
||||
this.renderQueue(date);
|
||||
this.renderTimeMarker(date);
|
||||
}
|
||||
|
||||
clearQueue(){
|
||||
//Clear out queue container
|
||||
this.queueContainer.innerHTML = '';
|
||||
this.queueContainer.innerHTML = '';;
|
||||
//Clear out queue marker container
|
||||
this.queueMarkerContainer.innerHTML = '';
|
||||
|
||||
//Grab all related tooltips
|
||||
const tooltips = this.ownerDoc.body.querySelectorAll('.media-tooltip');
|
||||
|
||||
//clear them out since we're clearing out the elements with the event to remove them
|
||||
//These should clear out on their own on mousemove but this makes things look a *little* prettier :)
|
||||
for(let tooltip of tooltips){
|
||||
tooltip.parentNode.remove();
|
||||
}
|
||||
|
||||
//Clear any marker timers
|
||||
clearTimeout(this.timeMarkerTimer);
|
||||
|
|
@ -206,13 +280,16 @@ class queuePanel extends panelObj{
|
|||
}
|
||||
|
||||
//render the time marker
|
||||
this.renderTimeMarker(date);
|
||||
this.renderTimeMarker(date, true);
|
||||
|
||||
//render out the queue
|
||||
this.renderQueue(date);
|
||||
}
|
||||
|
||||
renderQueue(date = new Date()){
|
||||
//Clear out queue container
|
||||
this.queueContainer.innerHTML = '';
|
||||
|
||||
//for every entry in the queue
|
||||
for(let entry of this.client.queue){
|
||||
//Create entry div
|
||||
|
|
@ -224,9 +301,64 @@ class queuePanel extends panelObj{
|
|||
entryDiv.style.bottom = `${this.offsetByDate(new Date(entry[1].startTime + (entry[1].duration * 1000)), true)}px`;
|
||||
|
||||
//Create entry title
|
||||
const entryTitle = document.createElement('a');
|
||||
const entryTitle = document.createElement('p');
|
||||
entryTitle.textContent = entry[1].title;
|
||||
entryTitle.href = entry[1].url;
|
||||
|
||||
//Tooltip generation
|
||||
//tooltip div
|
||||
const tooltipDiv = document.createElement('div');
|
||||
tooltipDiv.classList.add('media-tooltip');
|
||||
|
||||
//tooltip title
|
||||
const tooltipTitle = document.createElement('p');
|
||||
tooltipTitle.textContent = `Title: ${entry[1].title}`;
|
||||
|
||||
//tooltip filename
|
||||
const tooltipFilename = document.createElement('p');
|
||||
tooltipFilename.textContent = `File Name: ${entry[1].fileName}`;
|
||||
|
||||
//tooltip source
|
||||
const tooltipSource = document.createElement('p');
|
||||
tooltipSource.textContent = `Source: ${entry[1].type}`;
|
||||
|
||||
//tooltip duration
|
||||
const tooltipDuration = document.createElement('p');
|
||||
tooltipDuration.textContent = `Duration: ${entry[1].duration}`;
|
||||
|
||||
//tooltip start
|
||||
const tooltipStart = document.createElement('p');
|
||||
tooltipStart.textContent = `Start Time: ${new Date(entry[1].startTime).toLocaleString()}`;
|
||||
|
||||
//tooltip end
|
||||
const tooltipEnd = document.createElement('p');
|
||||
tooltipEnd.textContent = `Start Time: ${new Date(entry[1].startTime + (entry[1].duration * 1000)).toLocaleString()}`;
|
||||
|
||||
//append components
|
||||
for(let component of [
|
||||
tooltipTitle,
|
||||
tooltipFilename,
|
||||
tooltipSource,
|
||||
tooltipDuration,
|
||||
tooltipStart,
|
||||
tooltipEnd
|
||||
]){
|
||||
tooltipDiv.append(component);
|
||||
}
|
||||
|
||||
//Setup media tooltip
|
||||
entryDiv.addEventListener('mouseenter',(event)=>{utils.ux.displayTooltip(event, tooltipDiv, false, null, true, this.ownerDoc);});
|
||||
|
||||
//context menu
|
||||
const menuMap = new Map([
|
||||
["Play now", ()=>{this.client.socket.emit('move', {uuid: entry[1].uuid})}],
|
||||
["Move To...", ()=>{}],
|
||||
["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);}],
|
||||
]);
|
||||
|
||||
//Setup context menu
|
||||
entryDiv.addEventListener('contextmenu', (event)=>{utils.ux.displayContextMenu(event, '', menuMap, this.ownerDoc);});
|
||||
|
||||
//Append entry elements
|
||||
entryDiv.append(entryTitle);
|
||||
|
|
@ -236,7 +368,7 @@ class queuePanel extends panelObj{
|
|||
}
|
||||
}
|
||||
|
||||
renderTimeMarker(date = new Date()){
|
||||
renderTimeMarker(date = new Date(), forceScroll = false){
|
||||
//Calculate marker position by date
|
||||
const markerPosition = Math.round(this.offsetByDate(date));
|
||||
|
||||
|
|
@ -260,12 +392,9 @@ class queuePanel extends panelObj{
|
|||
this.timeMarker.style.top = `${markerPosition}px`;
|
||||
|
||||
//If the panel document isn't null (we're not actively switching panels)
|
||||
if(this.panelDocument != null){
|
||||
//Grab the current owner document object
|
||||
const ownerDoc = this.panelDocument.ownerDocument == null ? this.panelDocument : this.panelDocument.ownerDocument;
|
||||
|
||||
if(this.panelDocument != null && (this.autoscroll || forceScroll)){
|
||||
//Get height difference between window and queue layout controller
|
||||
const docDifference = ownerDoc.defaultView.innerHeight - this.queueLayoutController.getBoundingClientRect().height;
|
||||
const docDifference = this.ownerDoc.defaultView.innerHeight - this.queueLayoutController.getBoundingClientRect().height;
|
||||
//Calculate scroll target by body difference and marker position
|
||||
const scrollTarget = (markerPosition - (this.queueLayoutController.getBoundingClientRect().height - docDifference) / 2) + docDifference;
|
||||
//Calculate scroll behavior by distance
|
||||
|
|
@ -292,6 +421,9 @@ class queuePanel extends panelObj{
|
|||
}
|
||||
|
||||
renderQueueScale(inputDate = new Date()){
|
||||
//Clear out queue marker container
|
||||
this.queueMarkerContainer.innerHTML = '';
|
||||
|
||||
//Make sure we don't modify the date we're handed
|
||||
const date = structuredClone(inputDate);
|
||||
|
||||
|
|
@ -350,8 +482,8 @@ class queuePanel extends panelObj{
|
|||
}
|
||||
|
||||
offsetByDate(date = new Date(), bottomOffset = false){
|
||||
//Pull start of day epoch from given date
|
||||
const dayEpoch = structuredClone(date).setHours(0,0,0,0);
|
||||
//Pull start of day epoch from given date, make sure to use a new date object so we don't fuck up any date objects passed to us
|
||||
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
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ class player{
|
|||
this.showVideoIcon.style.display = "flex";
|
||||
this.client.chatBox.hideChatIcon.style.display = "none";
|
||||
//Need to clear the width from the split, or else it doesn't display properly
|
||||
this.client.chatBox.chatPanel.style.width = "100%";
|
||||
this.client.chatBox.chatPanel.style.flexBasis = "100%";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue