Got drag-n-drop to schedule working.

This commit is contained in:
rainbow napkin 2025-02-03 22:13:51 -05:00
parent 90be85de26
commit 85bbe39578
6 changed files with 152 additions and 47 deletions

View file

@ -55,17 +55,23 @@ module.exports = class{
async queueURL(socket, data){ async queueURL(socket, data){
try{ try{
//Set url //Set url
const url = encodeURI(data.url); var url = data.url;
//pull URL and start time from data //pull URL and start time from data
//let {url, start, title} = data; //let {url, start, title} = data;
//If we where given a bad URL //If we where given a bad URL
if(!validator.isURL(url)){
//Attempt to fix the situation by encoding it
url = encodeURI(url);
//If it's still bad
if(!validator.isURL(url)){ if(!validator.isURL(url)){
//Bitch, moan, complain... //Bitch, moan, complain...
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation"); loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
//and ignore it! //and ignore it!
return; return;
} }
}
//If the title is too long //If the title is too long
if(!validator.isLength(data.title, {max:30})){ if(!validator.isLength(data.title, {max:30})){

View file

@ -74,7 +74,7 @@ module.exports.fetchMetadata = async function(link){
function compatibilityFilter(file){ function compatibilityFilter(file){
//return true for all files that match for web-safe formats //return true for all files that match for web-safe formats
return file.format == "h.264" || file.format == "Ogg Video" || file.format.match("MPEG4"); return file.format == "h.264 IA" || file.format == "h.264" || file.format == "Ogg Video" || file.format.match("MPEG4");
} }
function pathFilter(file){ function pathFilter(file){

View file

@ -108,6 +108,10 @@ div#chat-panel-main-div{
width: 0.6em; width: 0.6em;
} }
#chat-panel-users-drag-handle{
z-index: 2;
}
#chat-panel-multipanel-div{ #chat-panel-multipanel-div{
height: 100%; height: 100%;
} }

View file

@ -96,11 +96,18 @@ div.queue-entry{
right: 0; right: 0;
left: 0; left: 0;
cursor:grab; cursor:grab;
display: flex;
justify-content: center;
align-items: center;
} }
div.queue-entry a{ div.queue-entry p{
position: relative;
z-index: 2; z-index: 2;
pointer-events: none;
}
div.dragging-queue-entry{
z-index: 3;
} }
#time-marker{ #time-marker{

View file

@ -413,10 +413,11 @@ class queuePanel extends panelObj{
//Create entry div //Create entry div
const entryDiv = document.createElement('div'); const entryDiv = document.createElement('div');
entryDiv.classList.add('queue-entry'); entryDiv.classList.add('queue-entry');
entryDiv.dataset['uuid'] = entry[1].uuid;
//If this item starts today //If this item starts today
if(startsToday){ if(startsToday){
//Place entry div based on time //Place the top of the entry div based on time
entryDiv.style.top = `${this.offsetByDate(new Date(entry[1].startTime))}px`; entryDiv.style.top = `${this.offsetByDate(new Date(entry[1].startTime))}px`;
}else{ }else{
//Get dawn //Get dawn
@ -426,13 +427,13 @@ class queuePanel extends panelObj{
//Place item beginning at dawn //Place item beginning at dawn
entryDiv.style.top = `${this.offsetByDate(dawn)}px`; entryDiv.style.top = `${this.offsetByDate(dawn)}px`;
//Run entry from top //Run apply the rest of the styling rules
entryDiv.classList.add('started-before-today'); entryDiv.classList.add('started-before-today');
} }
//If the item ends today //If the item ends today
if(endsToday){ if(endsToday){
//Place entry div based on time //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(entry[1].startTime + (entry[1].duration * 1000)), true)}px`;
}else{ }else{
//Get midnight //Get midnight
@ -442,7 +443,7 @@ class queuePanel extends panelObj{
//Place item beginning at dawn //Place item beginning at dawn
entryDiv.style.bottom = `${this.offsetByDate(dusk, true)}px`; entryDiv.style.bottom = `${this.offsetByDate(dusk, true)}px`;
//Run entry to bottom //Run apply the rest of the styling rules
entryDiv.classList.add('ends-after-today'); entryDiv.classList.add('ends-after-today');
} }
@ -455,44 +456,32 @@ class queuePanel extends panelObj{
const tooltipDiv = document.createElement('div'); const tooltipDiv = document.createElement('div');
tooltipDiv.classList.add('media-tooltip'); tooltipDiv.classList.add('media-tooltip');
//tooltip title //tooltip components
const tooltipTitle = document.createElement('p'); //For each string
tooltipTitle.textContent = `Title: ${entry[1].title}`; for(let string of [
`Title: ${entry[1].title}`,
//tooltip filename `File Name: ${entry[1].fileName}`,
const tooltipFilename = document.createElement('p'); `Source: ${entry[1].type}`,
tooltipFilename.textContent = `File Name: ${entry[1].fileName}`; `Duration: ${entry[1].duration}`,
`Start Time: ${new Date(entry[1].startTime).toLocaleString()}`,
//tooltip source `End Time: ${new Date(entry[1].startTime + (entry[1].duration * 1000)).toLocaleString()}`
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 = `End Time: ${new Date(entry[1].startTime + (entry[1].duration * 1000)).toLocaleString()}`;
//append components
for(let component of [
tooltipTitle,
tooltipFilename,
tooltipSource,
tooltipDuration,
tooltipStart,
tooltipEnd
]){ ]){
//Create a 'p' node
const component = document.createElement('p');
//Fill it with the string
component.textContent = string;
//Append it to the tooltip div
tooltipDiv.append(component); tooltipDiv.append(component);
} }
//Setup media tooltip //Setup media tooltip
entryDiv.addEventListener('mouseenter',(event)=>{utils.ux.displayTooltip(event, tooltipDiv, false, null, true, this.ownerDoc);}); entryDiv.addEventListener('mouseenter',(event)=>{
//If we're not dragging
if(event.target.dataset['drag'] != 'true'){
//Display tooltip
utils.ux.displayTooltip(event, tooltipDiv, false, null, true, this.ownerDoc);
}
});
//context menu //context menu
const menuMap = new Map([ const menuMap = new Map([
@ -503,8 +492,17 @@ class queuePanel extends panelObj{
["Copy URL", ()=>{navigator.clipboard.writeText(entry[1].url);}], ["Copy URL", ()=>{navigator.clipboard.writeText(entry[1].url);}],
]); ]);
//Setup drag n drop
entryDiv.addEventListener('mousedown', clickEntry.bind(this));
//Setup context menu //Setup context menu
entryDiv.addEventListener('contextmenu', (event)=>{utils.ux.displayContextMenu(event, '', menuMap, this.ownerDoc);}); entryDiv.addEventListener('contextmenu', (event)=>{
//If we're not dragging
if(event.target.dataset['drag'] != 'true'){
//Display context menu
utils.ux.displayContextMenu(event, '', menuMap, this.ownerDoc);
}
});
//Append entry elements //Append entry elements
entryDiv.append(entryTitle); entryDiv.append(entryTitle);
@ -514,6 +512,74 @@ class queuePanel extends panelObj{
} }
} }
function clickEntry(event){
//If it's not a left click
if(event.buttons != 1){
//fuck off
return;
}
//Create variables to hold width and height
const height = event.target.offsetHeight;
//If we havent set height or width
if(event.target.style.height == ""){
//Preserve calculated entry height
event.target.style.height = `${height}px`;
}
event.target.classList.add('dragging-queue-entry');
event.target.dataset['drag'] = true;
//Drag entry with mouse
this.ownerDoc.body.addEventListener('mousemove', (nestedEvent)=>{(dragEntry.bind(this))(nestedEvent, event.target)});
//Drop on moust up
this.ownerDoc.body.addEventListener('mouseup', (nestedEvent)=>{(dropEntry.bind(this))(nestedEvent, event.target)});
//Disable selection on body
this.ownerDoc.body.style.userSelect = 'none';
//Save top of target relative to window minus the mouse position as our drag offset
// ((event.target.getBoundingClientRect().top + this.ownerDoc.defaultView.scrollY) - event.clientY);
event.target.dataset['dragoffset'] = event.clientY - (event.target.getBoundingClientRect().top + this.ownerDoc.defaultView.scrollY);
//Call the drag entry function to move the entry on click without re-writing the wheel
(dragEntry.bind(this))(event, event.target);
}
function dragEntry(event, target){
//Gross but works :P
if(!target.isConnected || target.dataset['drag'] != "true"){
return;
}
console.log("fuck")
//Calculate offset from rest of window
const windowOffset = this.queueContainer.getBoundingClientRect().top + this.ownerDoc.defaultView.scrollY;
//Move the entry to the mouse offset by the target nodes height and the queue layouts scroll
target.style.top = `${event.clientY - Number(target.dataset['dragoffset']) - windowOffset}px`;
}
function dropEntry(event, target){
//Gross but works :P
if(!target.isConnected){
return;
}
//Asynchronously send move command item by calculated time to server
this.client.socket.emit('move', {uuid: target.dataset['uuid'], start: this.dateByOffset(target.offsetTop).getTime()});
//allow selection on body
this.ownerDoc.body.style.userSelect = 'none';
//Finish dragging
target.dataset['drag'] = false;
}
class reschedulePopup{ class reschedulePopup{
constructor(event, client, media, cb){ constructor(event, client, media, cb){
//Set Client //Set Client
@ -742,4 +808,26 @@ class queuePanel extends panelObj{
//return position relative to parent //return position relative to parent
return (offsetMax * timeFloat) + range[0]; return (offsetMax * timeFloat) + range[0];
} }
dateByOffset(input = 0){
//Get markers
const markers = this.panelDocument.querySelectorAll('span.queue-marker');
//get range of position from top to bottom marker
const range = [markers[0].offsetTop, markers[markers.length - 1].offsetTop]
//get max offset relative to markers
const offsetMax = range[1] - range[0];
//input offset + relative difference between top marker and parent devided by offset max
//save as 'float' between 0 and 1
const relativeInput = ((input - range[0]) / offsetMax);
//Get the current date
const date = new Date();
//Convert our 'float' from 0-1 to a time between 0-24
date.setHours(0,0,0,relativeInput * 86400000);
//return our date
return date;
}
} }

View file

@ -122,7 +122,7 @@ class canopyUXUtils{
if(soft){ if(soft){
//remove the tooltip on context menu open //remove the tooltip on context menu open
event.target.addEventListener('click', tooltip.remove.bind(tooltip)); event.target.addEventListener('mousedown', tooltip.remove.bind(tooltip));
event.target.addEventListener('contextmenu', tooltip.remove.bind(tooltip)); event.target.addEventListener('contextmenu', tooltip.remove.bind(tooltip));
} }