/*
* 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 .
*/
$(function() {
const helpers = {};
// Delay in ms for animations.
helpers.DELAY_MS = 325;
// Debug states enums.
helpers.DEBUG_STATES = {
NONE: 0,
DEBUG: 1,
INFO: 2,
FORCE: 3
};
// Debug status. 0 = off | 1 = on.
helpers.DEBUG_STATE = (localStorage.getItem('phantombot_debug_state') !== null ? parseInt(localStorage.getItem('phantombot_debug_state')) : helpers.DEBUG_STATES.NONE);
// Debug types.
helpers.LOG_TYPE = helpers.DEBUG_STATES;
// Panel version. SEE: https://semver.org/
// Example: MAJOR.MINOR.PATCH
helpers.PANEL_VERSION = "1.3.0";
/*
* @function adds commas to thousands.
*
* @param {String} number
* @return {String}
*/
helpers.parseNumber = function(number) {
return (number + '').replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};
/*
* @function Fixes the number
*
* @param {String} number
* @return {JSON}
*/
helpers.fixNumber = function(number, force) {
const newNumber = parseInt(number.toString().replace(/,/g, ''));
const thousandReplace = 9999;
const millionReplace = 999999;
if (!isNaN(newNumber)) {
if (newNumber > thousandReplace && newNumber < millionReplace) {
return ((newNumber / 1000).toFixed(1) + 'K');
} else if (newNumber > millionReplace) {
return ((newNumber / 1000000).toFixed(1) + 'M');
}
}
return number;
};
/*
* @function checks if the object has a valid string or number.
*
* @param {Object} obj
* @return {Boolean}
*/
helpers.isValidNumberOrString = function(obj) {
let value = (typeof obj === 'object' ? obj.val() : obj);
if (isNaN(value)) {
if (typeof value === 'string' && value.length > 0) {
return true;
}
} else {
if (typeof value === 'number' && value > 0) {
return true;
}
}
return false;
};
/*
* @function Checks if the value is null and returns the default if it is.
*
* @param {String} value
* @param {String} def
* @return {String}
*/
helpers.getDefaultIfNullOrUndefined = function(value, def) {
if (value === null || value === undefined) {
return def;
} else {
return value;
}
};
/*
* @function gets the proper event message.
*
* @param {Object} event
* @return {String}
*/
helpers.getEventMessage = function(event) {
switch (event.type.toLowerCase()) {
case 'subscriber':
return (event.username + ' just subscribed!');
case 'prime subscriber':
return (event.username + ' just subscribed with Twitch Prime!');
case 'resubscriber':
return (event.username + ' just resubscribed for ' + event.months + ' months in a row!');
case 'follower':
return (event.username + ' just followed!');
case 'bits':
return (event.username + ' just cheered ' + event.amount + ' bits!');
case 'host':
return (event.username + ' just hosted with ' + event.viewers + ' viewers!');
case 'auto-host':
return (event.username + ' just auto-hosted with ' + event.viewers + ' viewers!');
case 'tip': // To be added soon.
break;
case 'raid':
return (event.username + ' raided for ' + event.viewers + ' viewers!');
case 'gifted subscription':
return (event.username + ' gifted a subscription to ' + event.recipient + '!');
}
};
/*
* @function that gets the right color for an event.
*
* @param {String} event
* @return {String}
*/
// Use these colours for this function: https://mdbootstrap.com/css/colors/
helpers.getEventColor = function(event) {
switch (event.toLowerCase()) {
case 'subscriber':
return 'background-color: #16a7d9;';
case 'prime subscriber':
return 'background-color: #1693bc;';
case 'resubscriber':
return 'background-color: #ed961c;';
case 'follower':
return 'background-color: #c62828;';
case 'bits':
return 'background-color: #6441a5;';
case 'host':
return 'background-color: #ed4c1c;';
case 'auto-host':
return 'background-color: #ffff00; color: #000000;';
case 'tip': // To be added soon.
return 'background-color: #6441a5;';
case 'raid':
return 'background-color: #4caf50;';
case 'gifted subscription':
return 'background-color: #01579b;';
}
};
/*
* @function handles the string input checks.
*
* @param {Object} obj
* @return {Boolean}
*/
helpers.handleInputString = function(obj) {
if (obj.length === 0) {
helpers.logError('Failed to handle string due to the object being null.', helpers.LOG_TYPE.FORCE);
return;
}
// Make sure the input has a value in it.
if (obj.val().length < 1) {
if (!obj.parent().hasClass('has-error')) {
// Add the error class to the parent.
obj.parent().addClass('has-error');
// Append text saying the form cannot be empty.
obj.after($('
', {
'class': 'help-block',
'text': 'You cannot leave this field empty.'
}));
let btn = obj.closest('form').find('button');
if (btn.data('candisable') !== undefined) {
// Disable the button
obj.closest('form').find('button').prop('disabled', true).addClass('disabled');
}
toastr.error('Missing data in input field.');
return false;
}
} else {
if (obj.parent().find('p').length > 0) {
if (obj.parent().hasClass('has-error')) {
// Remove error class.
obj.parent().removeClass('has-error');
// Remove the help text.
obj.parent().find('p').remove();
// Enabled the button again.
obj.closest('form').find('button').prop('disabled', false).removeClass('disabled');
return true;
}
}
}
return !obj.parent().hasClass('has-error');
};
/*
* @function handles the number input checks.
*
* @param {Object} obj
* @return {Boolean}
*/
helpers.handleInputNumber = function(obj, min, max) {
if (obj.length === 0) {
helpers.logError('Failed to handle number due to the object being null.', helpers.LOG_TYPE.FORCE);
return;
}
min = (min === undefined ? 0 : min);
let newMax = (max === undefined ? Number.MAX_SAFE_INTEGER : max);
// Make sure the input has a value in it.
if (isNaN(parseInt(obj.val())) || isNaN(obj.val()) || parseInt(obj.val()) < min || parseInt(obj.val()) > newMax) {
if (!obj.parent().hasClass('has-error')) {
// Add the error class to the parent.
obj.parent().addClass('has-error');
// Append text saying the form cannot be empty.
obj.after($('', {
'class': 'help-block',
'text': 'Please enter a number that is greater or equal to ' + min + (max !== undefined ? ' and less or equal than ' + newMax + '' : '') + '.'
}));
let btn = obj.closest('form').find('button');
if (btn.data('candisable') !== undefined) {
// Disable the button
obj.closest('form').find('button').prop('disabled', true).addClass('disabled');
}
toastr.error('Missing data in input field.');
return false;
}
} else {
if (obj.parent().find('p').length > 0) {
if (obj.parent().hasClass('has-error')) {
// Remove error class.
obj.parent().removeClass('has-error');
// Remove the help text.
obj.parent().find('p').remove();
// Enabled the button again.
obj.closest('form').find('button').removeClass('disabled');
return true;
}
}
}
return !obj.parent().hasClass('has-error');
};
/*
* @function handles the date input checks.
*
* @param {Object} obj
* @return {Boolean}
*/
helpers.handleInputDate = function(obj) {
if (obj.length === 0) {
helpers.logError('Failed to handle date due to the object being null.', helpers.LOG_TYPE.FORCE);
return;
}
let matched = obj.val().match(/^((\d{2}|\d{4})(\\|\/|\.|-)(\d{2})(\\|\/|\.|-)(\d{4}|\d{2}))$/);
// Make sure the input has a value in it.
if (matched === null || ((matched[6].length < 4 && matched[2].length == 2) || (matched[6].length == 2 && matched[2].length < 4))) {
if (!obj.parent().hasClass('has-error')) {
// Add the error class to the parent.
obj.parent().addClass('has-error');
// Append text saying the form cannot be empty.
obj.after($('', {
'class': 'help-block',
'text': 'Please enter a valid date (mm/dd/yyyy or dd/mm/yyyy).'
}));
let btn = obj.closest('form').find('button');
if (btn.data('candisable') !== undefined) {
// Disable the button
obj.closest('form').find('button').prop('disabled', true).addClass('disabled');
}
toastr.error('Bad date in field.');
return false;
}
} else {
if (obj.parent().find('p').length > 0) {
if (obj.parent().hasClass('has-error')) {
// Remove error class.
obj.parent().removeClass('has-error');
// Remove the help text.
obj.parent().find('p').remove();
// Enabled the button again.
obj.closest('form').find('button').removeClass('disabled');
return true;
}
}
}
return !obj.parent().hasClass('has-error');
};
/*
* @function handles hiding info for the panels (the four dashboard info panels).
*
* @param {Object} obj
* @param {String} id
*/
helpers.handlePanelToggleInfo = function(obj, id) {
id = 'phantombot_' + id.substring(id.indexOf('-') + 1);
if (localStorage.getItem(id) === 'false') {
if (parseInt(obj.data('number').replace(/,/g, '')) < 9999) {
obj.html(obj.data('number'));
} else {
obj.html($('.small-box').width() < 230 ? obj.data('parsed') : obj.data('number'));
}
localStorage.setItem(id, 'true');
} else {
obj.html('Hidden');
localStorage.setItem(id, 'false');
}
};
/*
* @function handles setting the info for the panels (the four dashboard info panels).
*
* @param {Object} obj
* @param {String} id
*/
helpers.handlePanelSetInfo = function(obj, id, parsed) {
let item = localStorage.getItem('phantombot_' + id.substring(id.indexOf('-') + 1)),
isSmall = $('.small-box').width() < 230;
if (item === 'true' || item === null) {
if (parseInt(obj.data('number').replace(/,/g, '')) < 9999) {
obj.html(obj.data('number'));
} else {
obj.html(isSmall ? parsed : obj.data('number'));
}
} else {
obj.html('Hidden');
}
obj.data('parsed', parsed);
};
/*
* @function Adds padding to the date with a 0.
*
* @param {String} dateString
* @return {String}
*/
helpers.getPaddedDateString = function(dateString) {
let dateMatches = dateString.match(/((\d+)|([^\d]*))/g);
for (let i = 0; i < dateMatches.length; i++) {
if (parseInt(dateMatches[i]) < 10 && !dateMatches[i].startsWith('0')) {
dateMatches[i] = ('0' + dateMatches[i]);
}
}
return dateMatches.join('');
};
/*
* @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 = function(id, title, btn, body, onClose) {
return $('', {
'class': 'modal fade',
'tabindex': '99',
'id': id
}).append($('', {
'class': 'modal-dialog'
}).append($('', {
'class': 'modal-content'
}).append($('', {
'class': 'modal-header',
}).append($('', {
'type': 'button',
'class': 'close',
'data-dismiss': 'modal',
'html': '×'
})).append($('', {
'class': 'modal-title',
'text': title
}))).append($('', {
'class': 'modal-body',
'html': body
})).append($('', {
'class': 'modal-footer',
}).append($('', {
'class': 'btn btn-primary',
'type': 'button',
'text': btn,
'click': onClose
})).append($('', {
'class': 'btn btn-default',
'type': 'button',
'text': 'Cancel',
'data-dismiss': 'modal'
}))))).on('shown.bs.modal', function() {
$('#' + id).focus();
}).on('hidden.bs.modal', function() {
$('#' + id).remove();
});
};
/*
* @function Generates an advance 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.getAdvanceModal = function(id, title, btn, body, onClose) {
return $('', {
'class': 'modal fade',
'tabindex': '99',
'id': id
}).append($('', {
'class': 'modal-dialog'
}).append($('', {
'class': 'modal-content'
}).append($('', {
'class': 'modal-header',
}).append($('', {
'type': 'button',
'class': 'close',
'data-dismiss': 'modal',
'html': '×'
})).append($('', {
'class': 'modal-title',
'text': title
}))).append($('', {
'class': 'modal-body',
'html': body
})).append($('', {
'class': 'modal-footer',
}).append($('', {
'class': 'btn btn-default pull-left',
'type': 'button',
'data-toggle': 'collapse',
'data-target': '#advance-collapse',
'html': $('', {
'class': 'glyphicon glyphicon-chevron-down pull-right',
'style': 'top: 4px; padding-left: 5px;'
})
}).append($('', {
'class': 'collapse-btn',
'html': 'Show Advanced'
}))).append($('', {
'class': 'btn btn-primary',
'type': 'button',
'text': btn,
'click': onClose
})).append($('', {
'class': 'btn btn-default',
'type': 'button',
'text': 'Cancel',
'data-dismiss': 'modal'
}))))).on('shown.bs.modal', function() {
$('#' + id).focus();
}).on('hidden.bs.modal', function() {
$('#' + id).remove();
}).on('show.bs.collapse', function() {
$(this).find('.glyphicon').removeClass('glyphicon-chevron-down').addClass('glyphicon-chevron-up');
$(this).find('.collapse-btn').html('Hide Advanced');
}).on('hide.bs.collapse', function() {
$(this).find('.glyphicon').removeClass('glyphicon-chevron-up').addClass('glyphicon-chevron-down');
$(this).find('.collapse-btn').html('Show Advanced');
});
};
/*
* @function Generates an input group
*
* @param {String} id
* @param {String} type
* @param {String} title
* @param {String} placeholder
* @param {String} value
* @param {String} toolTip
* @param {Boolean} disabled
* @return {Object}
*/
helpers.getInputGroup = function(id, type, title, placeholder, value, toolTip, disabled) {
return $('', {
'class': 'form-group'
}).append($('', {
'html': $('', {
'text': title
})
})).append($('', {
'id': id,
'type': type,
'class': 'form-control',
'style': 'margin-top: 5px;',
'data-toggle': 'tooltip',
'title': toolTip,
'data-str': type,
'placeholder': placeholder,
'value': (value === undefined ? '' : (value + ''))
}).prop('disabled', (disabled === undefined ? false : disabled)));
};
/*
* @function Generates a textarea group
*
* @param {String} id
* @param {String} type
* @param {String} title
* @param {String} placeholder
* @param {String} value
* @param {String} toolTip
* @param {Boolean} unlimited
* @return {Object}
*/
helpers.getTextAreaGroup = function(id, type, title, placeholder, value, toolTip, unlimited) {
return $('', {
'class': 'form-group'
}).append($('', {
'html': $('', {
'text': title
})
})).append($('', {
'id': id,
'type': type,
'maxlength': (unlimited ? Number.MAX_SAFE_INTEGER : 480),
'class': 'form-control',
'style': 'margin-top: 5px;',
'rows': '2',
'data-toggle': 'tooltip',
'title': toolTip,
'data-str': type,
'placeholder': placeholder,
'text': (value === undefined ? '' : (value + ''))
}));
};
/*
* @function Generates a dropdown.
*
* @param {String} id
* @param {String} title
* @param {String} def
* @param {Array} options
* @param {String} toolTip
* @return {Object}
*/
helpers.getDropdownGroup = function(id, title, def, options, toolTip) {
return $('', {
'class': 'form-group'
}).append($('', {
'html': $('', {
'text': title
})
})).append($('', {
'class': 'dropdown',
'data-toggle': 'tooltip',
'title': toolTip
}).append($('', {
'class': 'form-control',
'id': id,
'text': def,
'style': 'width: 100%; cursor: pointer;',
'data-toggle': 'dropdown'
}).append($('', {
'html': def,
'selected': 'true',
'disabled': 'true',
'hidden': 'true'
})).append(options.map(function(option) {
return $('', {
'html': option
});
}))));
};
/*
* @function Generates a multi-select dropdown.
*
* @param {String} id
* @param {String} title
* @param {String} def
* @param {Array} options [
{
'title': 'Some title',
'options': [
{
'name': 'option name',
'selected': 'true'
},
...
]
},
...
]
* @param {String} toolTip
* @return {Object}
*/
helpers.getMultiDropdownGroup = function(id, title, options, toolTip) {
return $('', {
'class': 'form-group'
}).append($('', {
'html': $('', {
'text': title
})
})).append($('', {
'class': 'dropdown',
'data-toggle': 'tooltip',
'title': toolTip
}).append($('', {
'class': 'form-control select2 select2-hidden-accessible',
'multiple': 'multiple',
'id': id,
'style': 'width: 100%; cursor: pointer;'
}).append(options.map(function(option) {
let selected = option.selected;
let roles = option.options;
let group = $('', {
'label': option.title
});
for (let i = 0; i < roles.length; i++) {
let o = $('', {
'html': roles[i].name,
'id': roles[i]._id
});
if (roles[i].selected !== undefined && roles[i].selected === 'true') {
o.attr('selected', 'selected');
} else if (selected !== undefined && selected.indexOf(roles[i]._id) > -1) {
o.attr('selected', 'selected');
}
group.append(o);
}
return group;
}))));
};
/*
* @function gets a checkbox
*
* @param {String} id
* @param {Boolean} value
* @param {String} text
* @param {String} tooltip
* @return {Object}
*/
helpers.getCheckBox = function(id, value, text, tooltip) {
return $('', {
'class': 'pretty p-icon'
}).append($('', {
'id': id,
'type': 'checkbox',
'data-toggle': 'tooltip',
'title': tooltip,
'checked': value
})).append($('', {
'class': 'state p-default'
}).append($('', {
'class': 'icon fa fa-check'
})).append($('', {
'text': text
})));
// return $('', {
// 'class': 'checkbox',
// 'style': 'margin-top: 0px; !important'
// }).append($('', {
// 'style': 'margin-right: 10px;',
// 'data-toggle': 'tooltip',
// 'title': tooltip
// }).append($('', {
// 'type': 'checkbox',
// 'id': id,
// 'style': 'cursor: pointer;'
// }).prop('checked', value)).append(text));
};
/*
* @function gets a collapsible accordion panel.
*
* @param {String} id
* @param {String} title
* @param {String} body
* @return {Object}
*/
helpers.getCollapsibleAccordion = function(id, title, body) {
return $('', {
'class': 'panel panel-default'
}).append($('', {
'class': 'panel-heading'
}).append($('', {
'data-toggle': 'collapse',
'data-parent': '#accordion',
'style': 'color: #ccc !important',
'text': '',
'href': '#' + id
}).append($('', {
'class': 'panel-title',
'html': title
})))).append($('', {
'class': 'panel-collapse collapse' + (id.endsWith('1') ? ' in' : ''), // If the ID ends with one, this one should be opened by default.
'id': id
}).append($('', {
'class': 'panel-body',
'html': body
})));
};
/*
* @function gets the confrim delete modal
*
* @param {String} id
* @param {String} title
* @param {Boolean} hasBodyMsg
* @param {String} closeMessage
* @param {Function} onClose
* @return {Object}
*/
helpers.getConfirmDeleteModal = function(id, title, hasBodyMsg, closeMessage, onClose) {
swal({
'title': title,
'text': (hasBodyMsg ? 'Once removed, it be will gone forever.' : ''),
'icon': 'warning',
'reverseButtons': true,
'buttons': {
'confirm': {
'text': 'Delete',
'visible': true
},
'cancel': {
'text': 'Cancel',
'visible': true
}
},
'dangerMode': true
}).then(function(isRemoved) {
if (isRemoved) {
onClose();
swal(closeMessage, {
'icon': 'success',
});
}
});
};
/*
* @function Generates a random string.
*
* @param {Number} len
* @return {String}
*/
helpers.getRandomString = function(len) {
let randStr = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
str = '';
for (let i = 0; i < len; i++) {
str += randStr.charAt(Math.floor(Math.random() * randStr.length));
}
return str;
};
/*
* @function Creates a new timer interval.
*
* @param {Function} func
* @param {Number} interval
*/
helpers.setInterval = function(func, interval) {
timers.push(setInterval(func, interval));
};
/*
* @function Creates a new timer timeout.
*
* @param {Function} func
* @param {Number} timeout
*/
helpers.setTimeout = function(func, timeout) {
timers.push(setTimeout(func, timeout));
};
/*
* @function Clears all timers.
*/
helpers.clearTimers = function() {
for (let i = 0; i < timers.length; i++) {
clearInterval(timers[i]);
}
};
/*
* @function checked if a module is on.
*
* @param {String}|{Array} id
* @return {Boolean}
*/
helpers.getModuleStatus = function(id, toggle, swit) {
if (typeof id === 'object') {
for (let i = 0; i < id.length; i++) {
if (toggle === 'false') {
//$('#' + id[i]).slideUp(helpers.DELAY_MS);
$('#' + id[i] + ' *').prop('disabled', true);
} else {
//$('#' + id[i]).slideDown(helpers.DELAY_MS);
$('#' + id[i] + ' *').prop('disabled', false);
}
}
// Handle the switch toggle
$('#' + swit).prop('checked', toggle === 'true');
} else {
if (toggle === 'false') {
$('#' + id + 'Toggle').prop('checked', false);
//$('#' + id).slideUp(helpers.DELAY_MS);
$('#' + id + ' *').prop('disabled', true);
} else {
$('#' + id + 'Toggle').prop('checked', true);
//$('#' + id).slideDown(helpers.DELAY_MS);
$('#' + id + ' *').prop('disabled', false);
}
}
return toggle === 'true';
};
/*
* @function Same as the function above but doesn't return anything but true.
*
* @param {String}|{Array} id
* @return {Boolean}
*/
helpers.handleModuleLoadUp = function(id, toggle, swit) {
return helpers.getModuleStatus(id, toggle, swit);
};
/*
* @function Gets the group ID by its name.
*
* @param {String} name
* @param {Boolean} asString
* @return {Number}
*/
helpers.getGroupIdByName = function(name, asString) {
switch (name.toLowerCase()) {
case 'casters':
case 'caster':
return (asString ? '0' : 0);
case 'administrators':
case 'administrator':
return (asString ? '1' : 1);
case 'moderators':
case 'moderator':
return (asString ? '2' : 2);
case 'subscribers':
case 'subscriber':
return (asString ? '3' : 3);
case 'donators':
case 'donator':
return (asString ? '4' : 4);
case 'vips':
case 'vip':
return (asString ? '5' : 5);
case 'regulars':
case 'regular':
return (asString ? '6' : 6);
default:
return (asString ? '7' : 7);
}
};
/*
* @function Gets the group ID by its name.
*
* @param {String} name
* @param {Boolean} asString
* @return {Number}
*/
helpers.getDiscordGroupIdByName = function(name, asString) {
/*switch (name.toLowerCase()) {
case 'administrators':
case 'administrator':
return (asString ? '1' : 1);
default:
return (asString ? '0' : 0);
}*/
return 'null';
};
/*
* @function Gets the group name by its ID.
*
* @param {String} id
* @return {Number}
*/
helpers.getGroupNameById = function(id) {
switch (id.toString()) {
case '0':
return 'Caster';
case '1':
return 'Administrators';
case '2':
return 'Moderators';
case '3':
return 'Subscribers';
case '4':
return 'Donators';
case '5':
return 'vips';
case '6':
return 'Regulars';
default:
return 'Viewers';
}
};
/*
* @function Gets the group name by its ID.
*
* @param {String} j
* @return {Number}
*/
helpers.getDiscordGroupNameById = function(j) {
let json = JSON.parse(j);
let roles = [];
let perms = [];
for (let i = 0; i < json.roles.length; i++) {
if (json.roles[i].selected == 'true')
roles.push(json.roles[i].name);
}
if (roles.length === 0) {
roles.push('None');
}
for (let i = 0; i < json.permissions.length; i++) {
if (json.permissions[i].selected == 'true')
perms.push(json.permissions[i].name);
}
if (perms.length === 0) {
perms.push('None');
}
return {
roles: roles,
perms: perms
};
};
/*
* @function Handles the dark mode toggle.
*
* @param {Boolean} isDark
* @param {Boolean} isAtLoadUp
*/
helpers.handleDarkMode = function(isDark, isAtLoadUp) {
// Only load styles once.
if (helpers.isStylesLoaded !== undefined) {
return;
}
helpers.isStylesLoaded = true;
let head = $('head');
if (isDark) {
// select2.
head.append($('', {
'rel': 'stylesheet',
'href': '/panel/vendors/select2/select2.dark.min.css'
}));
// AdminLTE.
head.append($('', {
'rel': 'stylesheet',
'href': '/panel/vendors/adminlte/css/AdminLTE.dark.min.css'
}));
// skins.
head.append($('', {
'rel': 'stylesheet',
'href': '/panel/vendors/adminlte/css/skins/skin-purple.dark.min.css'
}));
// AdminLTE.
head.append($('', {
'rel': 'stylesheet',
'href': '/panel/css/style.dark.min.css'
}));
} else {
// select2.
head.append($('', {
'rel': 'stylesheet',
'href': '/panel/vendors/select2/select2.min.css'
}));
// AdminLTE.
head.append($('', {
'rel': 'stylesheet',
'href': '/panel/vendors/adminlte/css/AdminLTE.min.css'
}));
// skins.
head.append($('', {
'rel': 'stylesheet',
'href': '/panel/vendors/adminlte/css/skins/skin-purple.min.css'
}));
// AdminLTE.
head.append($('', {
'rel': 'stylesheet',
'href': '/panel/css/style.min.css'
}));
}
};
/*
* @function Handles showing new updates to the user.
*
* @param {String} version
* @param {String} downloadLink
*/
helpers.handleNewBotUpdate = function(version, downloadLink) {
if (version !== null) {
if ($('#notifications-total').data('isset') === false) {
// Send a warning to the user.
toastr.warning('New update available for PhantomBot!', {
'timeOut': 2000
});
// Set the total notifications.
$('#notifications-total').html('1').data('isset', 'true');
// Show the notification.
$('#notifications-amount').prop('style', 'display: inline;');
// Add a new notfication.
$('#notifications-menu-ul').append($('').append($('', {
'href': 'javascript:void(0);',
'click': function() {
helpers.getModal('pb-update', 'PhantomBot Update', 'Ok', $('', {
'role': 'form'
})
.append($('', {
'html': 'Version ' + version + ' of PhantomBot is now available to download! ' +
'You can view the changes of this version ' +
$('', { 'target': '_blank' }).prop('href', 'https://github.com/PhantomBot/PhantomBot/releases/' + version).append('here.')[0].outerHTML + ' ' +
'You can grab your own copy of version ' + version + ' of PhantomBot ' +
$('', { 'target': '_blank' }).prop('href', downloadLink).append('here.')[0].outerHTML + ' ' +
'Please check ' +
$('', { 'target': '_blank' }).prop('href', 'https://phantombot.github.io/PhantomBot/guides/#guide=content/setupbot/updatebot').append('this guide')[0].outerHTML +
' on how to properly update PhantomBot.'
})), function() {
$('#pb-update').modal('toggle');
}).modal('toggle');
}
}).append($('', {
'class': 'fa fa-warning text-yellow'
})).append('Update available')))
}
}
};
/*
* @function Gets a random rgb color.
*
* @return {String}
*/
helpers.getRandomRgbColor = function() {
return 'rgb(' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ', ' + Math.floor(Math.random() * 256) + ')';
};
/*
* @function Used to print debug messages in the console.
*
* @param {String} message
* @param {Number} type
*/
helpers.log = function(message, type) {
if (helpers.DEBUG_STATE === helpers.DEBUG_STATES.DEBUG || type === helpers.DEBUG_STATE || type === helpers.LOG_TYPE.FORCE) {
console.log('%c[PhantomBot Log]', 'color: #6441a5; font-weight: 900;', message);
}
};
/*
* @function Used to print error messages in the console.
*
* @param {String} message
* @param {Number} type
*/
helpers.logError = function(message, type) {
console.log('%c[PhantomBot Error]', 'color: red; font-weight: 900;', message);
};
/*
* @function Gets the epoch time from a date.
*
* @param {String} date
* @param {Boolean} force - If you know the format is wrong, force.
* @return {Number}
*/
helpers.getEpochFromDate = function(date, force) {
let parsedDate = Date.parse(date),
now = Date.now();
if (isNaN(parsedDate) || force) {
let matcher = date.match(/((\d{1,2})(\\|\/|\.|-)(\d{1,2})(\\|\/|\.|-)(\d{2,4}))/);
// Make sure we have a match.
if (matcher !== null) {
parsedDate = Date.parse(matcher[4] + '.' + matcher[2] + '.' + matcher[6]);
if (isNaN(parsedDate)) {
helpers.logError('Failed to parse date from "' + date + '". Returning current date.', true);
parsedDate = now;
}
} else {
helpers.logError('Failed to parse date from "' + date + '". Returning current date.', true);
parsedDate = now;
}
}
return parsedDate;
};
// Export.
window.helpers = helpers;
window.helpers.temp = {};
});