init commit

This commit is contained in:
zino
2021-02-16 23:07:41 +01:00
parent ec3fc78e0f
commit 12b4ef5db4
5000 changed files with 2596132 additions and 0 deletions

View File

@@ -0,0 +1,282 @@
// Script that has helper functions.
$(function() {
var helpers = {};
/*
* @function Generates a basic modal, you have to append your own body with jQuery.
*
* @param {String} id
* @param {String} title
* @param {String} btn
* @param {Object} body
* @param {Function} onClose
* @return {Object}
*/
helpers.getModal = (id, title, btn, body, onClose) => {
return $('<div/>', {
'class': 'modal fade',
'id': id
}).append($('<div/>', {
'class': 'modal-dialog'
}).append($('<div/>', {
'class': 'modal-content'
}).append($('<div/>', {
'class': 'modal-header',
}).append($('<h5/>', {
'class': 'modal-title',
'text': title
})).append($('<button/>', {
'type': 'button',
'class': 'close',
'data-dismiss': 'modal',
'html': '&times;'
}))).append($('<div/>', {
'class': 'modal-body',
'html': body
})).append($('<div/>', {
'class': 'modal-footer',
}).append($('<button/>', {
'class': 'btn btn-primary',
'type': 'button',
'text': btn,
'data-dismiss': 'modal',
'click': onClose
}))))).on('hidden.bs.modal', () => {
$('#' + id).remove();
});
};
/*
* @function Generates a simple add song modal.
*
* @param {String} title
* @param {String} label
* @param {String} btn
* @param {String} placeholder
* @param {Function} onClose
* @return {Object}
*/
helpers.getSongModal = (title, label, btn, placeholder, onClose) => {
return helpers.getModal('song-modal', title, btn, $('<div/>', {
'class': 'form-group'
}).append($('<label/>', {
'text': label
})).append($('<input/>', {
'class': 'form-control',
'type': 'text',
'placeholder': placeholder,
'id': 'song-url',
'focus': () => {
$('#song-url').attr('placeholder', '');
},
'blur': () => {
$('#song-url').attr('placeholder', placeholder);
}
})), onClose);
};
/*
* @function Generates a load playlist modal
*
* @param {String} title
* @param {String} label
* @param {String} btn
* @param {String} placeholder
* @param {Array} playlists
* @param {Function} onClose
* @return {Object}
*/
helpers.getPlaylistModal = (title, label, btn, placeholder, playlists, onClose) => {
return helpers.getModal('playlist-load-modal', title, btn, $('<div/>', {
'class': 'form-group'
}).append($('<label/>', {
'text': label
})).append($('<select/>', {
'class': 'form-control',
'id': 'playlist-load',
'text': 'Select a playlist',
'style': 'width: 100%; cursor: pointer;',
'data-toggle': 'dropdown'
}).append($('<option/>', {
'html': 'Select a playlist',
'selected': 'true',
'disabled': 'true',
'hidden': 'true'
})).append(playlists.map(function(playlist) {
return $('<option/>', {
'html': playlist
});
})).append($('<option/>', {
'html': 'Select a playlist',
'disabled': 'true',
'hidden': 'true'
}))), onClose);
};
/*
* @function Generates a load playlist modal
*
* @param {String} title
* @param {String} body
* @param {Function} onClose
* @return {Object}
*/
helpers.getErrorModal = (title, body, onClose) => {
return helpers.getModal('err-modal', title, 'Ok', $('<div/>', {
'class': 'form-group'
}).append($('<p/>', {
'text': body
})), onClose);
};
/*
* @function Generates the settings modal
*
* @param {Function} onClose
*/
helpers.getSettingsModal = (onClose) => {
player.dbQuery('yt_settings', 'ytSettings', (e) => {
helpers.getModal('settings-modal', 'YouTube Player and Request Settings', 'Save', $('<form/>').append($('<div/>', {
'class': 'form-group'
}).append($('<label/>', {
'text': 'Player Size'
})).append($('<div/>', {
'class': 'dropdown'
}).append($('<button/>', {
'class': 'btn btn-secondary dropdown-toggle',
'type': 'button',
'data-toggle': 'dropdown',
'text': helpers.getPlayerSize(),
'id': 'player-size-btn'
})).append($('<div/>', {
'class': 'dropdown-menu',
'aria-labelledby': 'player-size-btn'
}).append($('<a/>', {
'class': 'dropdown-item',
'href': '#',
'text': 'Default',
'click': () => {
$('#player-size-btn').text('Default');
}
})).append($('<a/>', {
'class': 'dropdown-item',
'href': '#',
'text': 'Half',
'click': () => {
$('#player-size-btn').text('Half');
}
})).append($('<a/>', {
'class': 'dropdown-item',
'href': '#',
'text': 'Small',
'click': () => {
$('#player-size-btn').text('Small');
}
})).append($('<a/>', {
'class': 'dropdown-item',
'href': '#',
'text': 'Tiny',
'click': () => {
$('#player-size-btn').text('Tiny');
}
})).append($('<a/>', {
'class': 'dropdown-item',
'href': '#',
'text': 'Hidden',
'click': () => {
$('#player-size-btn').text('Hidden');
}
}))))).append($('<div/>', {
'class': 'form-group'
}).append($('<label/>', {
'text': 'Player DJ Name'
})).append($('<input/>', {
'type': 'text',
'data-toggle': 'tooltip',
'title': 'Name of the default playlist user.',
'class': 'form-control',
'id': 'dj-name',
'value': e.playlistDJname
}))).append($('<div/>', {
'class': 'form-group',
}).append($('<label/>', {
'text': 'Maximum Songs'
})).append($('<input/>', {
'type': 'number',
'data-toggle': 'tooltip',
'title': 'How many songs one user can have in the queue.',
'class': 'form-control',
'id': 'max-song-user',
'value': e.songRequestsMaxParallel
}))).append($('<div/>', {
'class': 'form-group'
}).append($('<label/>', {
'text': 'Maximum Song Duration'
})).append($('<input/>', {
'type': 'number',
'data-toggle': 'tooltip',
'id': 'max-song-length',
'title': 'How long in seconds a song can be.',
'class': 'form-control',
'value': e.songRequestsMaxSecondsforVideo
}))).append($('<div/>', {
'class': 'form-group'
}).append($('<label/>', {
'text': 'Vote Count'
})).append($('<input/>', {
'type': 'number',
'data-toggle': 'tooltip',
'id': 'vote-count',
'title': 'How many votes it takes to Skip.',
'class': 'form-control',
'value': e.voteCount
}))),onClose).modal('toggle');
});
};
/*
* @function Gets the player size.
*
* @return {String}
*/
helpers.getPlayerSize = () => {
let size = localStorage.getItem('phantombot_ytplayer_size');
return (size === null ? 'Default' : size[0].toUpperCase() + size.substr(1));
};
/*
* @function Sets the new player size.
*/
helpers.setPlayerSize = () => {
switch (localStorage.getItem('phantombot_ytplayer_size')) {
case 'half':
$('#left-section').attr('class', 'col-md-6').removeClass('off');
$('#right-section').attr('class', 'col-md-6');
break;
case 'small':
$('#left-section').attr('class', 'col-md-5').removeClass('off');
$('#right-section').attr('class', 'col-md-7');
break;
case 'tiny':
$('#left-section').attr('class', 'col-md-4').removeClass('off');
$('#right-section').attr('class', 'col-md-8');
break;
case 'hidden':
$('#left-section').addClass('off');
$('#right-section').attr('class', 'col-md-12');
break;
default:
$('#left-section').attr('class', 'col-md-7').removeClass('off');
$('#right-section').attr('class', 'col-md-5');
}
};
helpers.urlIsIP = () => {
var rx=/^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/;
return rx.test(window.location.hostname);
}
// Export object.
window.helpers = helpers;
});

View File

@@ -0,0 +1,419 @@
/*
* Copyright (C) 2016-2020 phantombot.github.io/PhantomBot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @author ScaniaTV
*/
$(function() {
var socket = new WebSocket((getProtocol() === 'https://' || window.location.protocol === 'https:' ? 'wss://' : 'ws://') + window.location.host + '/ws/ytplayer'),
listeners = [],
player = {},
hasAPIKey = true,
secondConnection = false;
/*
* @function sends data to the socket, this should only be used in this script.
*
* @param {Object} data
*/
var sendToSocket = (data) => {
// Do not send any requests or any other data to the Core for processing if there is no key.
if (!hasAPIKey) {
return;
}
try {
socket.send(JSON.stringify(data));
} catch (ex) {
console.error('Failed to send message to socket: ' + ex.message);
}
};
/*
* @function to determine is a second connection was detected.
*/
player.secondConnection = () => {
return secondConnection;
}
/*
* @function to determine if an API key exists.
*/
player.hasAPIKey = () => {
return hasAPIKey;
}
/*
* @function gets the playlist.
*
* @param {String} callback_id
*/
player.requestPlaylist = (callback_id) => {
// Request the data.
sendToSocket({
query: 'playlist'
});
};
/*
* @function gets the request list.
*
* @param {String} callback_id
*/
player.requestRequestList = (callback_id) => {
// Request the data.
sendToSocket({
query: 'songlist'
});
};
/*
* @function deletes a song from the current playlist.
*/
player.deleteFromPlaylist = () => {
sendToSocket({
command: 'deletecurrent'
});
};
/*
* @function "steals" a song and adds it to the default playlist.
*
* @param {String} song_id
* @param {String} requester
*/
player.addSongToPlaylist = (song_id, requester) => {
// Update the data.
sendToSocket({
command: 'stealsong',
youTubeID: (song_id === undefined ? '' : song_id),
requester: (requester === undefined ? '' : requester)
});
};
/*
* @function adds a song to the queue.
*
* @param {String} song_id
*/
player.requestSong = (song_id) => {
// Add song to queue.
sendToSocket({
command: 'songrequest',
search: song_id
});
};
/*
* @function removes a song from the default playlist.
*
* @param {String} song_id
* @param {String} requester
*/
player.removeSongFromPlaylist = (song_id) => {
// Update the data.
sendToSocket({
deletepl: song_id
});
};
/*
* @function removes a song from the queue.
*
* @param {String} song_id
* @param {String} requester
*/
player.removeSongFromRequest = (song_id) => {
// Update the data.
sendToSocket({
deletesr: song_id
});
};
/*
* @function shuffles the playlist.
*/
player.shufflePlaylist = () => {
// Update the data.
sendToSocket({
command: 'togglerandom'
});
};
/*
* @function loads a new playlist
*
* @param {String} playlist
*/
player.loadPlaylist = (playlist) => {
// Update the data.
sendToSocket({
command: 'loadpl',
playlist: playlist
});
};
/*
* @function skips the current song.
*/
player.skipSong = () => {
sendToSocket({
command: 'skipsong'
});
};
/*
* @function updates the player status.
*
* @param {Number} status
*/
player.updateState = (status) => {
sendToSocket({
status: {
state: status
}
});
};
/*
* @function updates the current song.
*
* @param {String} id
*/
player.updateSong = (id) => {
sendToSocket({
status: {
currentid: id
}
});
};
/*
* @function puts the player in ready mode.
*/
player.ready = () => {
sendToSocket({
status: {
ready: true
}
});
};
/*
* @function sends error code from YouTube Player
*
* @param {Number} status
*/
player.sendError = (status) => {
sendToSocket({
status: {
errorcode: status
}
});
};
/*
* @function updates the player volume.+
*
* @param {Number} volume
*/
player.updateVolume = (volume) => {
sendToSocket({
status: {
volume: volume
}
});
};
/*
* @function puts the player in ready-pause mode.
*/
player.readyPause = () => {
sendToSocket({
status: {
readypause: true
}
});
};
/*
* @function Gets all keys and values from a table
*
* @param {String} callback_id
* @param {String} table
* @param {Function} callback
*/
player.dbQuery = (callback_id, table, callback) => {
listeners[callback_id] = callback;
sendToSocket({
dbquery: true,
query_id: callback_id,
table: table
});
};
/*
* @function Updates a key and value in the database
*
* @param {String} callback_id
* @param {String} table
* @param {String} key
* @param {String} value
* @param {Function} callback
*/
player.dbUpdate = (callback_id, table, key, value, callback) => {
if (callback !== undefined) {
listeners[callback_id] = callback;
}
sendToSocket({
dbupdate: true,
query_id: callback_id,
update: {
table: table,
key: key,
value: value
}
});
};
/*
* @function adds a listener to the socket.
*
* @param {String} listener_id
* @param {Function} listener
*/
player.addListener = (listener_id, listener) => {
listeners[listener_id] = listener;
};
/* Socket functions */
/*
* @function is called when the socket opens.
*/
socket.onopen = (e) => {
console.info('Connection established with the websocket.');
// Send the auth to the bot.
sendToSocket({
authenticate: getAuth()
});
// Load the YouTube iframe.
$('body').append($('<script/>', {
src: 'https://www.youtube.com/iframe_api'
}));
};
/*
* @function the socket calls when it closes
*/
socket.onclose = (e) => {
console.error('Connection lost with the websocket.');
if (secondConnection) {
toastr.error('PhantomBot has closed the WebSocket.', '', {timeOut: 0});
} else {
toastr.error('Connection with WebSocket was lost. Refresh once reestablished.', '', {timeOut: 0});
}
};
/*
* @function the socket calls when it gets message.
*/
socket.onmessage = (e) => {
try {
let message = JSON.parse(e.data);
if (message.ping !== undefined) {
sendToSocket({
pong: "pong"
});
return;
}
// Check this message here before doing anything else.
if (message.secondconnection !== undefined) {
if (message.secondconnection === true) {
secondConnection = true;
toastr.error('PhantomBot rejected the connection due to a player window already being open.', '',
{timeOut: 0, extendedTimeOut: 0});
console.error('Only one instance allowed.');
}
return;
}
// Check this message here before doing anything else.
if (message.authresult !== undefined) {
if (message.authresult === false) {
console.error('Failed to auth with the socket.');
}
return;
}
// Check to ensure that there is an API key.
if (message.ytkeycheck !== undefined) {
if (message.ytkeycheck === false) {
hasAPIKey = false;
console.error("Missing YouTube API Key.");
toastr.error('A YouTube API key has not been configured. Please review the instructions ' +
'<a href="https://phantombot.github.io/PhantomBot/guides/#guide=content/integrations/youtubesetup">here' +
'</a> on the PhantomBot Community Forum.', 'Missing YouTube API Key',
{timeOut: 0, extendedTimeOut: 0});
}
return;
}
if (message.query_id !== undefined) {
if (listeners[message.query_id] !== undefined) {
listeners[message.query_id](message);
delete listeners[message.query_id];
}
} else if (message.command !== undefined) {
if (typeof message.command === 'object') {
let keys = Object.keys(message.command);
for (let i = 0; i < keys.length; i++) {
if (listeners[keys[i]] !== undefined) {
listeners[keys[i]](message.command);
return;
}
}
} else {
if (listeners[message.command] !== undefined) {
listeners[message.command](message);
}
}
} else {
let keys = Object.keys(message);
for (let i = 0; i < keys.length; i++) {
if (listeners[keys[i]] !== undefined) {
listeners[keys[i]](message);
return;
}
}
}
} catch (ex) {
console.error('Failed to parse message from socket: ' + ex.message);
}
}
// Make the player object global.
window.player = player;
});