Got drag-n-drop to schedule working.
This commit is contained in:
parent
90be85de26
commit
85bbe39578
|
|
@ -55,16 +55,22 @@ 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)){
|
if(!validator.isURL(url)){
|
||||||
//Bitch, moan, complain...
|
//Attempt to fix the situation by encoding it
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
url = encodeURI(url);
|
||||||
//and ignore it!
|
|
||||||
return;
|
//If it's still bad
|
||||||
|
if(!validator.isURL(url)){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If the title is too long
|
//If the title is too long
|
||||||
|
|
|
||||||
|
|
@ -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){
|
||||||
|
|
|
||||||
|
|
@ -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%;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue