1. Use jqPaginator 2. Use CSR for closet 3. Use AJAX for closet 4. Just type to search instead of pressing ENTER key 5. Link to skin library is according to current category when closet is empty 6. Texture indicator shows category of texture
685 lines
21 KiB
JavaScript
685 lines
21 KiB
JavaScript
/*
|
||
* @Author: printempw
|
||
* @Date: 2016-07-16 10:02:24
|
||
* @Last Modified by: printempw
|
||
* @Last Modified time: 2017-01-20 21:19:07
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
$('body').on('click', '.player', function () {
|
||
$('.player-selected').removeClass('player-selected');
|
||
$(this).addClass('player-selected');
|
||
|
||
showPlayerTexturePreview(this.id);
|
||
});
|
||
|
||
$('body').on('click', '#preview-switch', () => {
|
||
TexturePreview.previewType == '3D' ? TexturePreview.show2dPreview() : TexturePreview.show3dPreview();
|
||
});
|
||
|
||
let skinSelected = false, capeSelected = false;
|
||
|
||
$('body').on('click', '.item-body', function () {
|
||
$('.item-selected').parent().removeClass('item-selected');
|
||
$(this).parent().addClass('item-selected');
|
||
|
||
const tid = $(this).parent().attr('tid');
|
||
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "../skinlib/info/" + tid,
|
||
dataType: "json",
|
||
success: (json) => {
|
||
if (json.type == "cape") {
|
||
MSP.changeCape('../textures/' + json.hash);
|
||
capeSelected = true;
|
||
} else {
|
||
MSP.changeSkin('../textures/' + json.hash);
|
||
skinSelected = true;
|
||
}
|
||
|
||
if (skinSelected && capeSelected)
|
||
$('#textures-indicator').text(`${trans('general.skin')} & ${trans('general.cape')}`);
|
||
else if (skinSelected)
|
||
$('#textures-indicator').text(trans('general.skin'));
|
||
else if (capeSelected)
|
||
$('#textures-indicator').text(trans('general.cape'));
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
|
||
$('body').on('click', '.category-switch', () => {
|
||
const category = $('a[href="#skin-category"]').parent().hasClass('active') ? 'cape' : 'skin';
|
||
const page = parseInt($('#closet-paginator').attr(`last-${category}-page`));
|
||
const search = $('input[name=q]').val();
|
||
reloadCloset(category, page, search);
|
||
});
|
||
|
||
function renderClosetItemComponent(item, rootPath) {
|
||
return `
|
||
<div class="item" tid="${item.tid}">
|
||
<div class="item-body">
|
||
<img src="${rootPath}/preview/${item.tid}.png">
|
||
</div>
|
||
<div class="item-footer">
|
||
<p class="texture-name">
|
||
<span title="${item.name}">${item.name} <small>(${item.type})</small></span>
|
||
</p>
|
||
|
||
<a href="${rootPath}/skinlib/show/${item.tid}" title="${trans('user.viewInSkinlib')}" class="more" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-share"></i></a>
|
||
<span title="${trans('general.more')}" class="more" data-toggle="dropdown" aria-haspopup="true" id="more-button"><i class="fa fa-cog"></i></span>
|
||
|
||
<ul class="dropup dropdown-menu" aria-labelledby="more-button">
|
||
<li><a href="javascript:renameClosetItem(${item.tid}, '${item.name}');">${trans('user.renameItem')}</a></li>
|
||
<li><a href="javascript:removeFromCloset(${item.tid});">${trans('user.removeItem')}</a></li>
|
||
<li><a href="javascript:setAsAvatar(${item.tid});">${trans('user.setAsAvatar')}</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
|
||
function renderCloset(items, category) {
|
||
const rootPath = /(^https?.*)\/user\/closet/.exec(window.location.href)[1];
|
||
const search = $('input[name=q]').val();
|
||
let container = $(`#${category}-category`);
|
||
container.html('');
|
||
if (items.length === 0) {
|
||
$('#closet-paginator').hide();
|
||
if (search === '') {
|
||
container.html(`<div class="empty-msg">
|
||
${trans('user.emptyClosetMsg', { url: rootPath + '/skinlib?filter=' + category })}</div>`);
|
||
} else {
|
||
container.html(`<div class="empty-msg">${trans('general.noResult')}</div>`);
|
||
}
|
||
} else {
|
||
$('#closet-paginator').show();
|
||
for (const item of items) {
|
||
container.append(renderClosetItemComponent(item, rootPath));
|
||
}
|
||
}
|
||
}
|
||
|
||
function reloadCloset(category, page, search) {
|
||
Promise.resolve($.ajax({
|
||
type: 'GET',
|
||
url: /(^https?.*)\/user\/closet/.exec(window.location.href)[1] + '/user/closet-data',
|
||
dataType: 'json',
|
||
data: {
|
||
category: category,
|
||
page: page,
|
||
q: search
|
||
}
|
||
})).then(result => {
|
||
renderCloset(result.items, result.category);
|
||
let paginator = $('#closet-paginator');
|
||
paginator.attr(`last-${result.category}-page`, page);
|
||
paginator.jqPaginator('option', {
|
||
currentPage: page,
|
||
totalPages: result.total_pages
|
||
});
|
||
}).catch(error => showAjaxError);
|
||
}
|
||
|
||
function showPlayerTexturePreview(pid) {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: url('user/player/show'),
|
||
dataType: "json",
|
||
data: { "pid": pid },
|
||
success: (json) => {
|
||
|
||
['steve', 'alex', 'cape'].forEach((type) => {
|
||
let tid = json[`tid_${type}`];
|
||
let preview = new TexturePreview(type, tid, json.preference);
|
||
|
||
if (tid) {
|
||
preview.change2dPreview().change3dPreview();
|
||
} else {
|
||
preview.showNotUploaded();
|
||
}
|
||
});
|
||
|
||
if ((json.preference == "default" && !json.tid_steve) || (json.preference == "slim" && !json.tid_alex)) {
|
||
// show default skin
|
||
MSP.changeSkin(defaultSkin);
|
||
}
|
||
|
||
console.log(`Texture previews of player ${json.player_name} rendered.`);
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
}
|
||
|
||
function renameClosetItem(tid, oldName) {
|
||
swal({
|
||
title: trans('user.renameClosetItem'),
|
||
input: 'text',
|
||
inputValue: oldName,
|
||
showCancelButton: true,
|
||
inputValidator: function(value) {
|
||
return new Promise(function(resolve, reject) {
|
||
if (value) {
|
||
resolve();
|
||
} else {
|
||
reject(trans('skinlib.emptyNewTextureName'));
|
||
}
|
||
});
|
||
}
|
||
}).then(function(new_name) {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./closet/rename",
|
||
dataType: "json",
|
||
data: { 'tid': tid, 'new_name': new_name },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
$("[tid="+tid+"]>.item-footer>.texture-name>span").html(new_name);
|
||
toastr.success(json.msg);
|
||
} else {
|
||
toastr.warning(json.msg);
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
}
|
||
|
||
function removeFromCloset(tid) {
|
||
swal({
|
||
text: trans('user.removeFromClosetNotice'),
|
||
type: 'warning',
|
||
showCancelButton: true
|
||
}).then(function() {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./closet/remove",
|
||
dataType: "json",
|
||
data: { 'tid' : tid },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
});
|
||
|
||
$('div[tid='+tid+']').remove();
|
||
} else {
|
||
toastr.warning(json.msg);
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
}
|
||
|
||
function setAsAvatar(tid) {
|
||
swal({
|
||
title: trans('user.setAvatar'),
|
||
text: trans('user.setAvatarNotice'),
|
||
type: 'question',
|
||
showCancelButton: true
|
||
}).then(function() {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./profile/avatar",
|
||
dataType: "json",
|
||
data: { "tid": tid },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
toastr.success(json.msg);
|
||
// refersh avatars
|
||
$('[alt="User Image"]').each(function() {
|
||
$(this).prop('src', $(this).attr('src') + '?' + new Date().getTime());
|
||
})
|
||
} else {
|
||
toastr.warning(json.msg);
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
}
|
||
|
||
$(document).ready(function() {
|
||
$('input[type=radio]').iCheck({
|
||
radioClass: 'iradio_square-blue'
|
||
});
|
||
swal.setDefaults({
|
||
confirmButtonText: trans('general.confirm'),
|
||
cancelButtonText: trans('general.cancel')
|
||
});
|
||
|
||
if (window.location.pathname.includes('/user/closet')) {
|
||
Promise.resolve($.ajax({
|
||
type: 'GET',
|
||
url: /(^https?.*)\/user\/closet/.exec(window.location.href)[1] + '/user/closet-data',
|
||
dataType: 'json'
|
||
})).then(result => {
|
||
renderCloset(result.items, result.category);
|
||
$('#closet-paginator').jqPaginator({
|
||
totalPages: result.total_pages,
|
||
visiblePages: 5,
|
||
currentPage: 1,
|
||
first: '<li><a style="cursor: pointer;">«</a></li>',
|
||
prev: '<li><a style="cursor: pointer;">‹</a></li>',
|
||
next: '<li><a style="cursor: pointer;">›</a></li>',
|
||
last: '<li><a style="cursor: pointer;">»</a></li>',
|
||
page: '<li><a style="cursor: pointer;">{{page}}</a></li>',
|
||
wrapper: '<ul class="pagination pagination-sm no-margin"></ul>',
|
||
onPageChange: page => {
|
||
reloadCloset(
|
||
$('#skin-category').hasClass('active') ? 'skin' : 'cape',
|
||
page,
|
||
$('input[name=q]').val()
|
||
);
|
||
}
|
||
});
|
||
}).catch(error => showAjaxError);
|
||
|
||
$('input[name=q]').on('input', _.debounce(() => {
|
||
const category = $('#skin-category').hasClass('active') ? 'skin' : 'cape';
|
||
reloadCloset(
|
||
category,
|
||
1,
|
||
$('input[name=q]').val()
|
||
);
|
||
}, 350));
|
||
}
|
||
});
|
||
|
||
function setTexture() {
|
||
var pid = 0;
|
||
|
||
$('input[name="player"]').each(function(){
|
||
if (this.checked) pid = this.id;
|
||
});
|
||
|
||
if (!pid) {
|
||
toastr.info(trans('user.emptySelectedPlayer'));
|
||
} else if (selected.length == 0) {
|
||
toastr.info(trans('user.emptySelectedTexture'));
|
||
} else {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./player/set",
|
||
dataType: "json",
|
||
data: {
|
||
'pid': pid,
|
||
'tid[skin]': selected['skin'],
|
||
'tid[cape]': selected['cape']
|
||
},
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
});
|
||
$('#modal-use-as').modal('hide');
|
||
} else {
|
||
toastr.warning(json.msg);
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
}
|
||
}
|
||
|
||
$('body').on('change', '#preference', function() {
|
||
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./player/preference",
|
||
dataType: "json",
|
||
data: { 'pid' : $(this).attr('pid'), 'preference' : $(this).val() },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
toastr.success(json.msg);
|
||
} else {
|
||
toastr.warning(json.msg);
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
|
||
function changePlayerName(pid, current_player_name) {
|
||
swal({
|
||
title: trans('user.changePlayerName'),
|
||
text: trans('user.playerNameRule'),
|
||
inputValue: current_player_name,
|
||
input: 'text',
|
||
showCancelButton: true,
|
||
inputValidator: function(value) {
|
||
return new Promise(function(resolve, reject) {
|
||
if (value) {
|
||
resolve();
|
||
} else {
|
||
reject(trans('user.emptyPlayerName'));
|
||
}
|
||
});
|
||
}
|
||
}).then(function(new_player_name) {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./player/rename",
|
||
dataType: "json",
|
||
data: { 'pid' : pid, 'new_player_name' : new_player_name },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
});
|
||
$('td:contains("'+pid+'")').next().html(new_player_name);
|
||
} else {
|
||
swal({
|
||
type: 'error',
|
||
html: json.msg
|
||
});
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
}
|
||
|
||
function clearTexture(pid) {
|
||
swal({
|
||
text: trans('user.clearTexture'),
|
||
type: 'warning',
|
||
showCancelButton: true
|
||
}).then(function() {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./player/texture/clear",
|
||
dataType: "json",
|
||
data: { 'pid' : pid },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
});
|
||
} else {
|
||
swal({
|
||
type: 'error',
|
||
html: json.msg
|
||
});
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
}
|
||
|
||
function deletePlayer(pid) {
|
||
swal({
|
||
title: trans('user.deletePlayer'),
|
||
text: trans('user.deletePlayerNotice'),
|
||
type: 'warning',
|
||
showCancelButton: true,
|
||
cancelButtonColor: '#3085d6',
|
||
confirmButtonColor: '#d33'
|
||
}).then(function() {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./player/delete",
|
||
dataType: "json",
|
||
data: { 'pid' : pid },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
}).then(function() {
|
||
$('tr#'+pid).remove();
|
||
});
|
||
} else {
|
||
swal({
|
||
type: 'error',
|
||
html: json.msg
|
||
});
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
}
|
||
|
||
function addNewPlayer() {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./player/add",
|
||
dataType: "json",
|
||
data: { 'player_name' : $('#player_name').val() },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
}).then(function() {
|
||
location.reload();
|
||
});
|
||
$('#modal-add-player').modal('hide');
|
||
} else {
|
||
toastr.warning(json.msg);
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
}
|
||
|
||
function changeNickName() {
|
||
var new_nickname = $('#new-nickname').val();
|
||
|
||
if (!new_nickname) {
|
||
swal({
|
||
type: 'error',
|
||
html: trans('user.emptyNewNickName')
|
||
});
|
||
return;
|
||
}
|
||
|
||
swal({
|
||
text: trans('user.changeNickName', { new_nickname: new_nickname }),
|
||
type: 'question',
|
||
showCancelButton: true
|
||
}).then(function() {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./profile?action=nickname",
|
||
dataType: "json",
|
||
data: { 'new_nickname' : new_nickname },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
});
|
||
$('.nickname').each(function() {
|
||
$(this).html(new_nickname);
|
||
});
|
||
} else {
|
||
swal({
|
||
type: 'warning',
|
||
html: json.msg
|
||
});
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
}
|
||
|
||
function changePassword() {
|
||
|
||
var password = $('#password').val();
|
||
var new_passwd = $('#new-passwd').val();
|
||
|
||
if (password == "") {
|
||
toastr.info(trans('user.emptyPassword'));
|
||
$('#passwd').focus();
|
||
} else if (new_passwd == "") {
|
||
toastr.info(trans('user.emptyNewPassword'));
|
||
$('#new-passwd').focus();
|
||
} else if ($('#confirm-pwd').val() == "") {
|
||
toastr.info(trans('auth.emptyConfirmPwd'));
|
||
$('#confirm-pwd').focus();
|
||
} else if (new_passwd != $('#confirm-pwd').val()) {
|
||
toastr.warning(trans('auth.invalidConfirmPwd'));
|
||
$('#confirm-pwd').focus();
|
||
} else {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./profile?action=password",
|
||
dataType: "json",
|
||
data: { 'current_password': password, 'new_password': new_passwd},
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
}).then(function() {
|
||
logout(true, function() {
|
||
window.location = "../auth/login";
|
||
});
|
||
});
|
||
} else {
|
||
swal({
|
||
type: 'warning',
|
||
html: json.msg
|
||
});
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
}
|
||
return false;
|
||
}
|
||
|
||
$('#new-email').focusin(function() {
|
||
$('#current-password').parent().show();
|
||
}).focusout(function() {
|
||
window.setTimeout(function() {
|
||
if (!$('#current-password').is(':focus'))
|
||
$('#current-password').parent().hide();
|
||
}, 10);
|
||
})
|
||
|
||
function changeEmail() {
|
||
var new_email = $('#new-email').val();
|
||
|
||
if (!new_email) {
|
||
swal({
|
||
type: 'error',
|
||
html: trans('user.emptyNewEmail')
|
||
});
|
||
return;
|
||
}
|
||
// check valid email address
|
||
if (!/\S+@\S+\.\S+/.test(new_email)) {
|
||
swal({
|
||
type: 'warning',
|
||
html: trans('auth.invalidEmail')
|
||
}); return;
|
||
}
|
||
|
||
swal({
|
||
text: trans('user.changeEmail', { new_email: new_email }),
|
||
type: 'question',
|
||
showCancelButton: true
|
||
}).then(function() {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./profile?action=email",
|
||
dataType: "json",
|
||
data: { 'new_email' : new_email, 'password' : $('#current-password').val() },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
}).then(function() {
|
||
logout(true, function() {
|
||
window.location = "../auth/login";
|
||
});
|
||
});
|
||
} else {
|
||
swal({
|
||
type: 'warning',
|
||
html: json.msg
|
||
});
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
});
|
||
}
|
||
|
||
function deleteAccount() {
|
||
var password = $('.modal-body>#password').val();
|
||
|
||
if (!password) {
|
||
swal({
|
||
type: 'warning',
|
||
html: trans('user.emptyDeletePassword')
|
||
}); return;
|
||
}
|
||
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./profile?action=delete",
|
||
dataType: "json",
|
||
data: { 'password' : password },
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
}).then(function() {
|
||
window.location = "../auth/login";
|
||
});
|
||
} else {
|
||
swal({
|
||
type: 'warning',
|
||
html: json.msg
|
||
});
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
}
|
||
|
||
function signIn() {
|
||
$.ajax({
|
||
type: "POST",
|
||
url: "./user/sign-in",
|
||
dataType: "json",
|
||
success: function(json) {
|
||
if (json.errno == 0) {
|
||
$('#score').html(json.score);
|
||
var dom = '<i class="fa fa-calendar-check-o"></i> ' + trans('user.signInRemainingTime', { time: String(json.remaining_time) });
|
||
$('#sign-in-button').attr('disabled', 'disabled').html(dom);
|
||
|
||
if (json.storage.used > 1024) {
|
||
$('#user-storage').html(`<b>${Math.round(json.storage.used)}</b>/ ${Math.round(json.storage.total)} MB`);
|
||
} else {
|
||
$('#user-storage').html(`<b>${Math.round(json.storage.used)}</b>/ ${Math.round(json.storage.total)} KB`);
|
||
}
|
||
|
||
$('#user-storage-bar').css('width', `${json.storage.percentage}%`)
|
||
|
||
swal({
|
||
type: 'success',
|
||
html: json.msg
|
||
});
|
||
} else {
|
||
toastr.warning(json.msg);
|
||
}
|
||
},
|
||
error: showAjaxError
|
||
});
|
||
}
|