355 lines
9.7 KiB
JavaScript
355 lines
9.7 KiB
JavaScript
/*
|
||
* @Author: printempw
|
||
* @Date: 2016-09-15 10:39:41
|
||
* @Last Modified by: g-plane
|
||
* @Last Modified time: 2017-04-26 15:57:50
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
console.log(`\n %c Blessing Skin v${blessing.version} %c https://blessing.studio \n\n`,"color: #fadfa3; background: #030307; padding:5px 0;","background: #fadfa3; padding:5px 0;");
|
||
|
||
$.locales = {};
|
||
$.currentLocale = {};
|
||
|
||
/**
|
||
* Check if given value is empty.
|
||
*
|
||
* @param {any} obj
|
||
* @return {Boolean}
|
||
*/
|
||
function isEmpty(obj) {
|
||
|
||
// null and undefined are "empty"
|
||
if (obj == null) return true;
|
||
|
||
// Assume if it has a length property with a non-zero value
|
||
// that that property is correct.
|
||
if (obj.length > 0) return false;
|
||
if (obj.length === 0) return true;
|
||
|
||
// If it isn't an object at this point
|
||
// it is empty, but it can't be anything *but* empty
|
||
// Is it empty? Depends on your application.
|
||
if (typeof obj !== "object") return true;
|
||
|
||
// Otherwise, does it have any properties of its own?
|
||
// Note that this doesn't handle
|
||
// toString and valueOf enumeration bugs in IE < 9
|
||
for (var key in obj) {
|
||
if (hasOwnProperty.call(obj, key)) return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Load current selected language.
|
||
*
|
||
* @return void
|
||
*/
|
||
function loadLocales() {
|
||
for (lang in $.locales) {
|
||
if (!isEmpty($.locales[lang])) {
|
||
$.currentLocale = $.locales[lang] || {};
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Translate according to given key.
|
||
*
|
||
* @param {string} key
|
||
* @param {dict} parameters
|
||
* @return {string}
|
||
*/
|
||
function trans(key, parameters = {}) {
|
||
if (isEmpty($.currentLocale)) {
|
||
loadLocales();
|
||
}
|
||
|
||
let segments = key.split('.');
|
||
let temp = $.currentLocale || {};
|
||
|
||
for (i in segments) {
|
||
if (isEmpty(temp[segments[i]])) {
|
||
return key;
|
||
} else {
|
||
temp = temp[segments[i]];
|
||
}
|
||
}
|
||
|
||
for (i in parameters) {
|
||
if (!isEmpty(parameters[i])) {
|
||
temp = temp.replace(':'+i, parameters[i]);
|
||
}
|
||
}
|
||
|
||
return temp;
|
||
}
|
||
|
||
function showModal(msg, title = 'Messgae', type = 'default', options = {}) {
|
||
let btnType = (type != "default") ? "btn-outline" : "btn-primary";
|
||
let onClick = (options.callback === undefined) ? 'data-dismiss="modal"' : `onclick="${options.callback}"`;
|
||
|
||
let dom = `
|
||
<div class="modal modal-${type} fade in">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
<h4 class="modal-title">${title}</h4>
|
||
</div>
|
||
<div class="modal-body">
|
||
<p>${msg}</p>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" ${onClick} class="btn ${btnType}">OK</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>`;
|
||
|
||
$(dom).modal(options);
|
||
}
|
||
|
||
/**
|
||
* Show message to div#msg with level
|
||
*
|
||
* @param {string} msg
|
||
* @param {string} type
|
||
* @return {void}
|
||
*/
|
||
function showMsg(msg, type = 'info') {
|
||
$("[id=msg]").removeClass().addClass("callout").addClass('callout-'+type).html(msg);
|
||
}
|
||
|
||
/**
|
||
* Show modal if error occured when sending an ajax request.
|
||
*
|
||
* @param {object} json
|
||
* @return {void}
|
||
*/
|
||
function showAjaxError(json) {
|
||
if (!json.responseText) {
|
||
console.warn('Empty Ajax response body.');
|
||
return;
|
||
}
|
||
|
||
showModal(json.responseText.replace(/\n/g, '<br />'), trans('general.fatalError'), 'danger');
|
||
}
|
||
|
||
/**
|
||
* Get parameters in query string with key.
|
||
*
|
||
* @param {string} key
|
||
* @return {string}
|
||
*/
|
||
function getQueryString(key) {
|
||
result = location.search.match(new RegExp('[\?\&]'+key+'=([^\&]+)','i'));
|
||
|
||
if (result == null || result.length < 1){
|
||
return null;
|
||
} else {
|
||
return result[1];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Return a debounced function
|
||
*
|
||
* @param {Function} func
|
||
* @param {number} delay
|
||
* @param {Array} args
|
||
* @param {Object} context
|
||
*/
|
||
function debounce(func, delay, args = [], context = undefined) {
|
||
if (isNaN(delay) || typeof func !== 'function') {
|
||
throw new Error('Arguments type of function "debounce" is incorrent!');
|
||
}
|
||
|
||
let timer = null;
|
||
return function () {
|
||
clearTimeout(timer);
|
||
timer = setTimeout(() => {
|
||
func.apply(context, args);
|
||
}, delay);
|
||
}
|
||
}
|
||
|
||
// polyfill of String.prototype.endsWith
|
||
if (!String.prototype.endsWith) {
|
||
String.prototype.endsWith = function (searchString, position) {
|
||
var subjectString = this.toString();
|
||
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
|
||
position = subjectString.length;
|
||
}
|
||
position -= searchString.length;
|
||
var lastIndex = subjectString.lastIndexOf(searchString, position);
|
||
return lastIndex !== -1 && lastIndex === position;
|
||
};
|
||
}
|
||
|
||
function url(relativeUri) {
|
||
relativeUri = relativeUri || "";
|
||
blessing.base_url = blessing.base_url || "";
|
||
|
||
if (relativeUri[0] != "/") {
|
||
relativeUri = "/" + relativeUri;
|
||
}
|
||
|
||
return blessing.base_url + relativeUri;
|
||
}
|
||
|
||
function confirmLogout() {
|
||
swal({
|
||
text: trans('general.confirmLogout'),
|
||
type: 'warning',
|
||
showCancelButton: true,
|
||
confirmButtonText: trans('general.confirm'),
|
||
cancelButtonText: trans('general.cancel')
|
||
}).then(() => {
|
||
logout().then((json) => {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
});
|
||
window.setTimeout(() => window.location = url(), 1000);
|
||
});
|
||
});
|
||
}
|
||
|
||
function logout() {
|
||
return new Promise((resolve, reject) => {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: url('auth/logout'),
|
||
dataType: "json",
|
||
success: (json) => resolve(json),
|
||
error: (json) => {
|
||
showAjaxError(json);
|
||
reject(json);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
$('#logout-button').click(() => confirmLogout());
|
||
|
||
$(document).ready(() => $('li.active > ul').show());
|
||
|
||
var TexturePreview = function (type, tid, preference) {
|
||
this.tid = tid;
|
||
this.type = type;
|
||
this.selector = $('#' + type);
|
||
this.preference = type == 'steve' ? 'default' : 'slim';
|
||
this.playerPreference = preference;
|
||
|
||
this.change2dPreview = function () {
|
||
this.selector
|
||
.attr('src', url(`preview/200/${this.tid}.png`))
|
||
.show()
|
||
.parent().attr('href', url('skinlib/show/' + this.tid))
|
||
.next().hide();
|
||
|
||
return this;
|
||
}
|
||
|
||
this.change3dPreview = function () {
|
||
|
||
if (this.playerPreference == this.preference) {
|
||
$.ajax({
|
||
type: "GET",
|
||
url: url(`skinlib/info/${this.tid}`),
|
||
dataType: "json",
|
||
success: (json) => {
|
||
let textureUrl = url('textures/' + json.hash);
|
||
|
||
if (this.type == 'cape') {
|
||
MSP.changeCape(textureUrl);
|
||
} else {
|
||
MSP.changeSkin(textureUrl);
|
||
}
|
||
},
|
||
error: (json) => showAjaxError(json)
|
||
});
|
||
}
|
||
|
||
return this;
|
||
}
|
||
|
||
this.showNotUploaded = function () {
|
||
this.selector.hide().parent().next().show();
|
||
|
||
return this;
|
||
}
|
||
}
|
||
|
||
TexturePreview.previewType = '3D';
|
||
|
||
TexturePreview.init3dPreview = () => {
|
||
if (TexturePreview.previewType == '2D') return;
|
||
|
||
$('#preview-2d').hide();
|
||
|
||
if ($(window).width() < 800) {
|
||
var canvas = MSP.get3dSkinCanvas($('#skinpreview').width(), $('#skinpreview').width());
|
||
$("#skinpreview").append($(canvas).prop("id", "canvas3d"));
|
||
} else {
|
||
var canvas = MSP.get3dSkinCanvas(350, 350);
|
||
$("#skinpreview").append($(canvas).prop("id", "canvas3d"));
|
||
}
|
||
}
|
||
|
||
TexturePreview.show3dPreview = () => {
|
||
TexturePreview.previewType = "3D";
|
||
|
||
TexturePreview.init3dPreview();
|
||
$('#preview-2d').hide();
|
||
$('.operations').show();
|
||
$('#preview-switch').html(trans('user.switch2dPreview'));
|
||
}
|
||
|
||
TexturePreview.show2dPreview = () => {
|
||
TexturePreview.previewType = '2D';
|
||
|
||
$('#canvas3d').remove();
|
||
$('.operations').hide();
|
||
$('#preview-2d').show();
|
||
$('#preview-switch').html(trans('user.switch3dPreview')).attr('onclick', 'show3dPreview();');
|
||
}
|
||
|
||
// change 3D preview status
|
||
$('.fa-pause').click(function () {
|
||
MSP.setStatus('rotation', ! MSP.getStatus('rotation'));
|
||
MSP.setStatus('movements', ! MSP.getStatus('movements'));
|
||
|
||
$(this).toggleClass('fa-pause').toggleClass('fa-play');
|
||
});
|
||
|
||
$('.fa-forward').click(() => MSP.setStatus('running', !MSP.getStatus('running')) );
|
||
$('.fa-repeat' ).click(() => MSP.setStatus('rotation', !MSP.getStatus('rotation')) );
|
||
|
||
(function ($) {
|
||
if ($('#copyright-text').length != 0 && $('#copyright-text').text().indexOf('Blessing') >= 0) {
|
||
return;
|
||
}
|
||
|
||
$.ajax({
|
||
type: 'POST',
|
||
url: 'https://work.prinzeugen.net/statistics/whitelist',
|
||
dataType: 'json',
|
||
data: { site_name: blessing.site_name, site_url: blessing.base_url }
|
||
}).done((json) => {
|
||
if (!json.inWhiteList) {
|
||
// :(
|
||
showModal("It looks like that you have removed the program's copyright. It's better for you to restore it ASAP, otherwise something terrible will be applied to your site :)<br><br>If there is a false alarm, please send a mail to h@prinzeugen.net to correct it.", 'CMN BAD ASS', 'danger', {
|
||
'backdrop': 'static',
|
||
'keyboard': false
|
||
});
|
||
}
|
||
});
|
||
})(jQuery);
|