Added schedule locking and day jumping on scroll lock.
This commit is contained in:
parent
c83ca63f9a
commit
44dd613ea3
|
|
@ -139,8 +139,11 @@ module.exports = class{
|
||||||
//Get schedule as a temporary array
|
//Get schedule as a temporary array
|
||||||
const queue = Array.from(this.channel.queue.schedule);
|
const queue = Array.from(this.channel.queue.schedule);
|
||||||
|
|
||||||
|
//Get schedule lock status
|
||||||
|
const queueLock = this.channel.queue.locked;
|
||||||
|
|
||||||
//Send off the metadata to our user's clients
|
//Send off the metadata to our user's clients
|
||||||
this.emit("clientMetadata", {user: userObj, flairList, queue});
|
this.emit("clientMetadata", {user: userObj, flairList, queue, queueLock});
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendSiteEmotes(){
|
async sendSiteEmotes(){
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ const validator = require('validator');
|
||||||
const queuedMedia = require('./queuedMedia');
|
const queuedMedia = require('./queuedMedia');
|
||||||
const yanker = require('../../../utils/media/yanker');
|
const yanker = require('../../../utils/media/yanker');
|
||||||
const loggerUtils = require('../../../utils/loggerUtils');
|
const loggerUtils = require('../../../utils/loggerUtils');
|
||||||
|
const channelModel = require('../../../schemas/channel/channelSchema');
|
||||||
|
|
||||||
module.exports = class{
|
module.exports = class{
|
||||||
constructor(server, channel){
|
constructor(server, channel){
|
||||||
|
|
@ -43,145 +44,182 @@ module.exports = class{
|
||||||
this.nextTimer = null;
|
this.nextTimer = null;
|
||||||
//Create variable to hold currently playing media object
|
//Create variable to hold currently playing media object
|
||||||
this.nowPlaying = null;
|
this.nowPlaying = null;
|
||||||
|
|
||||||
|
//create boolean to hold schedule lock
|
||||||
|
this.locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineListeners(socket){
|
defineListeners(socket){
|
||||||
socket.on("queue", (data) => {this.queueURL(socket, data)});
|
socket.on("queue", (data) => {this.queueURL(socket, data)});
|
||||||
socket.on("delete", (data => {this.deleteMedia(socket, data)}));
|
socket.on("delete", (data) => {this.deleteMedia(socket, data)});
|
||||||
socket.on("move", (data => {this.moveMedia(socket, data)}));
|
socket.on("move", (data) => {this.moveMedia(socket, data)});
|
||||||
socket.on("clear", (data => {this.deleteRange(socket, data)}));
|
socket.on("clear", (data) => {this.deleteRange(socket, data)});
|
||||||
|
socket.on("lock", (data) => {this.toggleLock(socket)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async queueURL(socket, data){
|
async queueURL(socket, data){
|
||||||
try{
|
//Get the current channel from the database
|
||||||
//Set url
|
const chanDB = await channelModel.findOne({name: socket.chan});
|
||||||
var url = data.url;
|
|
||||||
|
|
||||||
//If we where given a bad URL
|
if((!this.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
if(!validator.isURL(url)){
|
try{
|
||||||
//Attempt to fix the situation by encoding it
|
//Set url
|
||||||
url = encodeURI(url);
|
var url = data.url;
|
||||||
|
|
||||||
//If it's still bad
|
//If we where given a bad URL
|
||||||
if(!validator.isURL(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)){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If the title is too long
|
||||||
|
if(!validator.isLength(data.title, {max:30})){
|
||||||
//Bitch, moan, complain...
|
//Bitch, moan, complain...
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad URL!", "validation");
|
loggerUtils.socketErrorHandler(socket, "Title too long!", "validation");
|
||||||
//and ignore it!
|
//and ignore it!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
//Set title
|
||||||
|
const title = validator.escape(validator.trim(data.title));
|
||||||
|
//set start
|
||||||
|
var start = data.start;
|
||||||
|
|
||||||
//If the title is too long
|
//If start time isn't an integer after the current epoch
|
||||||
if(!validator.isLength(data.title, {max:30})){
|
if(start != null &&!validator.isInt(String(start), (new Date().getTime()))){
|
||||||
//Bitch, moan, complain...
|
//Null out time to tell the later parts of the function to start it now
|
||||||
loggerUtils.socketErrorHandler(socket, "Title too long!", "validation");
|
start = null;
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set title
|
|
||||||
const title = validator.escape(validator.trim(data.title));
|
|
||||||
//set start
|
|
||||||
var start = data.start;
|
|
||||||
|
|
||||||
//If start time isn't an integer after the current epoch
|
|
||||||
if(start != null &&!validator.isInt(String(start), (new Date().getTime()))){
|
|
||||||
//Null out time to tell the later parts of the function to start it now
|
|
||||||
start = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Pull media list
|
|
||||||
const mediaList = await yanker.yankMedia(url, title);
|
|
||||||
|
|
||||||
//If we didn't find any media
|
|
||||||
if(mediaList == null || mediaList.length <= 0){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, "No media found!", "queue");
|
|
||||||
//and ignore it!
|
|
||||||
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
|
//Pull media list
|
||||||
this.queueMedia(mediaList[0], start, socket);
|
const mediaList = await yanker.yankMedia(url, title);
|
||||||
}catch(err){
|
|
||||||
return loggerUtils.socketExceptionHandler(socket, err);
|
//If we didn't find any media
|
||||||
|
if(mediaList == null || mediaList.length <= 0){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "No media found!", "queue");
|
||||||
|
//and ignore it!
|
||||||
|
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){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteRange(socket, data){
|
async deleteRange(socket, data){
|
||||||
try{
|
//Get the current channel from the database
|
||||||
//If start time isn't an integer
|
const chanDB = await channelModel.findOne({name: socket.chan});
|
||||||
if(data.start != null && !validator.isInt(String(data.start))){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad start date!", "queue");
|
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If end time isn't an integer
|
if((!this.locked && await chanDB.permCheck(socket.user, 'clearSchedule')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
if(data.end != null && !validator.isInt(String(data.end))){
|
try{
|
||||||
//Bitch, moan, complain...
|
//If start time isn't an integer
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad end date!", "queue");
|
if(data.start != null && !validator.isInt(String(data.start))){
|
||||||
//and ignore it!
|
//Bitch, moan, complain...
|
||||||
return;
|
loggerUtils.socketErrorHandler(socket, "Bad start date!", "queue");
|
||||||
}
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.removeRange(data.start, data.end, socket);
|
//If end time isn't an integer
|
||||||
}catch(err){
|
if(data.end != null && !validator.isInt(String(data.end))){
|
||||||
return loggerUtils.socketExceptionHandler(socket, err);
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Bad end date!", "queue");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.removeRange(data.start, data.end, socket);
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteMedia(socket, data){
|
async deleteMedia(socket, data){
|
||||||
try{
|
//Get the current channel from the database
|
||||||
//If we don't have a valid UUID
|
const chanDB = await channelModel.findOne({name: socket.chan});
|
||||||
if(!validator.isUUID(data.uuid)){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad UUID!", "validation");
|
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Remove media by UUID
|
if((!this.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
this.removeMedia(data.uuid, socket);
|
try{
|
||||||
}catch(err){
|
//If we don't have a valid UUID
|
||||||
return loggerUtils.socketExceptionHandler(socket, err);
|
if(!validator.isUUID(data.uuid)){
|
||||||
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Bad UUID!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove media by UUID
|
||||||
|
this.removeMedia(data.uuid, socket);
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moveMedia(socket, data){
|
async moveMedia(socket, data){
|
||||||
try{
|
//Get the current channel from the database
|
||||||
//If we don't have a valid UUID
|
const chanDB = await channelModel.findOne({name: socket.chan});
|
||||||
if(!validator.isUUID(data.uuid)){
|
|
||||||
//Bitch, moan, complain...
|
|
||||||
loggerUtils.socketErrorHandler(socket, "Bad UUID!", "validation");
|
|
||||||
//and ignore it!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If start time isn't an integer after the current epoch
|
if((!this.locked && await chanDB.permCheck(socket.user, 'scheduleMedia')) || await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
if(data.start != null && !validator.isInt(String(data.start))){
|
try{
|
||||||
//Null out time to tell the later parts of the function to start it now
|
//If we don't have a valid UUID
|
||||||
data.start = undefined;
|
if(!validator.isUUID(data.uuid)){
|
||||||
}
|
//Bitch, moan, complain...
|
||||||
|
loggerUtils.socketErrorHandler(socket, "Bad UUID!", "validation");
|
||||||
|
//and ignore it!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Move media by UUID
|
//If start time isn't an integer after the current epoch
|
||||||
this.rescheduleMedia(data.uuid, data.start, socket);
|
if(data.start != null && !validator.isInt(String(data.start))){
|
||||||
}catch(err){
|
//Null out time to tell the later parts of the function to start it now
|
||||||
return loggerUtils.socketExceptionHandler(socket, err);
|
data.start = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Move media by UUID
|
||||||
|
this.rescheduleMedia(data.uuid, data.start, socket);
|
||||||
|
}catch(err){
|
||||||
|
return loggerUtils.socketExceptionHandler(socket, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async toggleLock(socket){
|
||||||
|
//Get the current channel from the database
|
||||||
|
const chanDB = await channelModel.findOne({name: socket.chan});
|
||||||
|
|
||||||
|
//If the user is a schedule admin
|
||||||
|
if(await chanDB.permCheck(socket.user, 'scheduleAdmin')){
|
||||||
|
//Toggle the schedule lock
|
||||||
|
this.locked = !this.locked;
|
||||||
|
|
||||||
|
//Update schedule lock status for everyone in the channel
|
||||||
|
this.server.io.in(this.channel.name).emit("lock", {locked: this.locked});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,24 @@ const channelPermissionSchema = new mongoose.Schema({
|
||||||
default: "admin",
|
default: "admin",
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
scheduleMedia: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
enum: rankEnum,
|
||||||
|
default: "admin",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
clearSchedule:{
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
enum: rankEnum,
|
||||||
|
default: "admin",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
scheduleAdmin:{
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
enum: rankEnum,
|
||||||
|
default: "admin",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
deleteChannel: {
|
deleteChannel: {
|
||||||
type: mongoose.SchemaTypes.String,
|
type: mongoose.SchemaTypes.String,
|
||||||
enum: rankEnum,
|
enum: rankEnum,
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
|
||||||
<div id="queue-panel-layout-controller">
|
<div id="queue-panel-layout-controller">
|
||||||
<div id="queue-controls">
|
<div id="queue-controls">
|
||||||
<div id="queue-control-buttons">
|
<div id="queue-control-buttons">
|
||||||
<button id="queue-add-media"><i class="bi-plus-lg"></i></button>
|
<button id="queue-add-media" class="bi-plus-lg"></button>
|
||||||
<button id="queue-search-media"><i class="bi-search"></i></button>
|
<button id="queue-search-media" class="bi-search"></button>
|
||||||
<button id="queue-scroll-lock" class="positive-button"><i class="bi-clock-fill"></i><i class="bi-arrows-expand"></i></button>
|
<button id="queue-scroll-lock" class="positive-button"><i class="bi-clock-fill"></i><i class="bi-arrows-expand"></i></button>
|
||||||
<button id="queue-date"><i class="bi-calendar-fill"></i></button>
|
<button id="queue-date" class="bi-calendar-fill"></button>
|
||||||
<button id="queue-playlists"><i class="bi-list"></i></button>
|
<button id="queue-playlists" class="bi-list"></button>
|
||||||
<button id="queue-clear" class="danger-button"><i class="bi-trash-fill"></i></button>
|
<button id="queue-clear" class="danger-button bi-trash-fill"></button>
|
||||||
<button id="queue-lock" class="positive-button"><i class="bi-unlock-fill"></i></button>
|
<button id="queue-lock" class="positive-button bi-unlock-fill"></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="queue-control-date" style="display: none">
|
<div id="queue-control-date" style="display: none">
|
||||||
<i class="bi-caret-left" id="queue-control-date-decrement"></i>
|
<i class="bi-caret-left" id="queue-control-date-decrement"></i>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 3;
|
z-index: 4;
|
||||||
padding: 0.15em 0.3em;
|
padding: 0.15em 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,15 @@ class channel{
|
||||||
|
|
||||||
this.socket.on("clientMetadata", this.handleClientInfo.bind(this));
|
this.socket.on("clientMetadata", this.handleClientInfo.bind(this));
|
||||||
|
|
||||||
this.socket.on("error", console.log);
|
this.socket.on("error", utils.ux.displayResponseError);
|
||||||
|
|
||||||
this.socket.on("queue", (data) => {
|
this.socket.on("queue", (data) => {
|
||||||
this.queue = new Map(data.queue);
|
this.queue = new Map(data.queue);
|
||||||
})
|
});
|
||||||
|
|
||||||
|
this.socket.on("lock", (data) => {
|
||||||
|
this.queueLock = data.locked;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClientInfo(data){
|
handleClientInfo(data){
|
||||||
|
|
@ -75,6 +79,9 @@ class channel{
|
||||||
|
|
||||||
//Store queue for use by the queue panel
|
//Store queue for use by the queue panel
|
||||||
this.queue = new Map(data.queue);
|
this.queue = new Map(data.queue);
|
||||||
|
|
||||||
|
//Store queue lock status
|
||||||
|
this.queueLock = data.queueLock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ class queuePanel extends panelObj{
|
||||||
this.scrollLockButton = this.panelDocument.querySelector('#queue-scroll-lock');
|
this.scrollLockButton = this.panelDocument.querySelector('#queue-scroll-lock');
|
||||||
this.queueDateButton = this.panelDocument.querySelector('#queue-date')
|
this.queueDateButton = this.panelDocument.querySelector('#queue-date')
|
||||||
this.clearMediaButton = this.panelDocument.querySelector('#queue-clear');
|
this.clearMediaButton = this.panelDocument.querySelector('#queue-clear');
|
||||||
|
this.queueLockButton = this.panelDocument.querySelector('#queue-lock');
|
||||||
|
|
||||||
//Get control divs
|
//Get control divs
|
||||||
this.addMediaDiv = this.panelDocument.querySelector('#queue-media-prompts');
|
this.addMediaDiv = this.panelDocument.querySelector('#queue-media-prompts');
|
||||||
|
|
@ -61,6 +62,9 @@ class queuePanel extends panelObj{
|
||||||
this.queueDateIncrement = this.panelDocument.querySelector('#queue-control-date-increment');
|
this.queueDateIncrement = this.panelDocument.querySelector('#queue-control-date-increment');
|
||||||
this.queueDatePrompt = this.panelDocument.querySelector('#queue-control-date-prompt');
|
this.queueDatePrompt = this.panelDocument.querySelector('#queue-control-date-prompt');
|
||||||
|
|
||||||
|
//Display lock status
|
||||||
|
this.handleScheduleLock();
|
||||||
|
|
||||||
//Render out the queue
|
//Render out the queue
|
||||||
this.fullRender();
|
this.fullRender();
|
||||||
|
|
||||||
|
|
@ -76,8 +80,9 @@ class queuePanel extends panelObj{
|
||||||
|
|
||||||
defineListeners(){
|
defineListeners(){
|
||||||
//Render queue when we receive a new copy of the queue data from the server
|
//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("clientMetadata", (data) => {this.renderQueue();});
|
||||||
this.client.socket.on("queue", (data) => {this.renderQueue();})
|
this.client.socket.on("queue", (data) => {this.renderQueue();});
|
||||||
|
this.client.socket.on("lock", this.handleScheduleLock.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
setupInput(){
|
setupInput(){
|
||||||
|
|
@ -92,6 +97,7 @@ class queuePanel extends panelObj{
|
||||||
this.scrollLockButton.addEventListener('click', this.lockScroll.bind(this));
|
this.scrollLockButton.addEventListener('click', this.lockScroll.bind(this));
|
||||||
this.queueDateButton.addEventListener('click', this.toggleDateControl.bind(this));
|
this.queueDateButton.addEventListener('click', this.toggleDateControl.bind(this));
|
||||||
this.clearMediaButton.addEventListener('click', this.clearMedia.bind(this));
|
this.clearMediaButton.addEventListener('click', this.clearMedia.bind(this));
|
||||||
|
this.queueLockButton.addEventListener('click', this.lockSchedule.bind(this));
|
||||||
|
|
||||||
//control bar divs
|
//control bar divs
|
||||||
//Add Media
|
//Add Media
|
||||||
|
|
@ -103,6 +109,20 @@ class queuePanel extends panelObj{
|
||||||
this.queueDatePrompt.addEventListener('change', this.setQueueDate.bind(this));
|
this.queueDatePrompt.addEventListener('change', this.setQueueDate.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* socket.io listeners */
|
||||||
|
handleScheduleLock(){
|
||||||
|
//Get queue lock button icon
|
||||||
|
const icon = this.queueLockButton.querySelector('i');
|
||||||
|
|
||||||
|
if(this.client.queueLock){
|
||||||
|
this.queueLockButton.classList.remove('positive-button', 'bi-unlock-fill');
|
||||||
|
this.queueLockButton.classList.add('danger-button', 'bi-lock-fill');
|
||||||
|
}else{
|
||||||
|
this.queueLockButton.classList.remove('danger-button', 'bi-lock-fill');
|
||||||
|
this.queueLockButton.classList.add('positive-button', 'bi-unlock-fill');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* queue control button functions */
|
/* queue control button functions */
|
||||||
toggleAddMedia(event){
|
toggleAddMedia(event){
|
||||||
//If the div is hidden
|
//If the div is hidden
|
||||||
|
|
@ -119,7 +139,13 @@ class queuePanel extends panelObj{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lockScroll(event){
|
lockScroll(event, jumpToDay = true){
|
||||||
|
//If we're supposed to jump to the current day
|
||||||
|
if(jumpToDay){
|
||||||
|
//Set schedule to current day
|
||||||
|
this.setDay();
|
||||||
|
}
|
||||||
|
|
||||||
//Enable scroll lock
|
//Enable scroll lock
|
||||||
this.autoscroll = true;
|
this.autoscroll = true;
|
||||||
|
|
||||||
|
|
@ -159,6 +185,10 @@ class queuePanel extends panelObj{
|
||||||
new clearPopup(event, this.client, null, this.ownerDoc);
|
new clearPopup(event, this.client, null, this.ownerDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockSchedule(event){
|
||||||
|
client.socket.emit('lock');
|
||||||
|
}
|
||||||
|
|
||||||
/* add queue controls */
|
/* add queue controls */
|
||||||
queueLast(event){
|
queueLast(event){
|
||||||
//Send off the request
|
//Send off the request
|
||||||
|
|
@ -203,7 +233,7 @@ class queuePanel extends panelObj{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setDay(date){
|
setDay(date = new Date()){
|
||||||
//Set day
|
//Set day
|
||||||
this.day = date;
|
this.day = date;
|
||||||
//Zero out to midnight
|
//Zero out to midnight
|
||||||
|
|
@ -220,7 +250,7 @@ class queuePanel extends panelObj{
|
||||||
//If autoscroll is enabled
|
//If autoscroll is enabled
|
||||||
if(this.autoscroll){
|
if(this.autoscroll){
|
||||||
//Simulate a button click to un/re-light the button and trigger a scroll when the date is set to today
|
//Simulate a button click to un/re-light the button and trigger a scroll when the date is set to today
|
||||||
this.lockScroll();
|
this.lockScroll(null, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -610,7 +640,7 @@ class queuePanel extends panelObj{
|
||||||
let bottomInput = this.queueContainer.offsetHeight - ((target.offsetTop + target.offsetHeight) + (this.queueLayoutController.scrollTopMax - this.queueLayoutController.scrollTop));
|
let bottomInput = this.queueContainer.offsetHeight - ((target.offsetTop + target.offsetHeight) + (this.queueLayoutController.scrollTopMax - this.queueLayoutController.scrollTop));
|
||||||
|
|
||||||
//If the item we're dragging is fackin uge'
|
//If the item we're dragging is fackin uge'
|
||||||
if(target.offsetHeight > (this.queueLayoutController.offsetHeight - ((detectionDistance * 2) + 10))){
|
if(target.offsetHeight > (this.queueLayoutController.offsetHeight - ((detectionDistance * 2) + 20))){
|
||||||
//AND THEY FUCKING SAID YOU COULDN'T GET MOUSE POS OUTSIDE OF AN EVENT WITHOUT :HOVER TRICKS EAT MY FUCKING ASS
|
//AND THEY FUCKING SAID YOU COULDN'T GET MOUSE POS OUTSIDE OF AN EVENT WITHOUT :HOVER TRICKS EAT MY FUCKING ASS
|
||||||
topInput = Math.round(target.offsetTop - Number(target.dataset['dragoffset']) - (this.queueLayoutController.getBoundingClientRect().top + this.queueControlOffset.offsetHeight));
|
topInput = Math.round(target.offsetTop - Number(target.dataset['dragoffset']) - (this.queueLayoutController.getBoundingClientRect().top + this.queueControlOffset.offsetHeight));
|
||||||
bottomInput = this.queueLayoutController.offsetHeight - (topInput + this.queueControlOffset.offsetHeight);
|
bottomInput = this.queueLayoutController.offsetHeight - (topInput + this.queueControlOffset.offsetHeight);
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ class canopyUXUtils{
|
||||||
try{
|
try{
|
||||||
const errors = body.errors;
|
const errors = body.errors;
|
||||||
errors.forEach((err)=>{
|
errors.forEach((err)=>{
|
||||||
new canopyUXUtils.popup(`<h3>Server Error:</h3><p><br>${err.msg}</p>`);
|
new canopyUXUtils.popup(`<h3>${err.type} Error:</h3><p><br>${err.msg}</p>`);
|
||||||
});
|
});
|
||||||
}catch(err){
|
}catch(err){
|
||||||
console.error("Display Error Body:");
|
console.error("Display Error Body:");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue