You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
932 lines
24 KiB
JavaScript
932 lines
24 KiB
JavaScript
'use strict';
|
|
|
|
|
|
var app = window.app || {};
|
|
|
|
app.isFocused = true;
|
|
app.currentRoom = null;
|
|
app.widgets = {};
|
|
app.cacheBuster = null;
|
|
|
|
(function () {
|
|
var params = utils.params();
|
|
var showWelcomeMessage = !!params.loggedin;
|
|
var registerMessage = params.register;
|
|
var isTouchDevice = utils.isTouchDevice();
|
|
|
|
require(['benchpress'], function (Benchpress) {
|
|
Benchpress.setGlobal('config', config);
|
|
if (Object.defineProperty) {
|
|
Object.defineProperty(window, 'templates', {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get: function () {
|
|
console.warn('[deprecated] Accessing benchpress (formerly known as templates.js) globally is deprecated. Use `require(["benchpress"], function (Benchpress) { ... })` instead');
|
|
return Benchpress;
|
|
},
|
|
});
|
|
} else {
|
|
window.templates = Benchpress;
|
|
}
|
|
});
|
|
|
|
app.cacheBuster = config['cache-buster'];
|
|
|
|
bootbox.setDefaults({
|
|
locale: config.userLang,
|
|
});
|
|
|
|
app.load = function () {
|
|
app.loadProgressiveStylesheet();
|
|
|
|
overrides.overrideTimeago();
|
|
|
|
var url = ajaxify.start(window.location.pathname.slice(1) + window.location.search + window.location.hash);
|
|
ajaxify.updateHistory(url, true);
|
|
ajaxify.parseData();
|
|
ajaxify.end(url, app.template);
|
|
|
|
handleStatusChange();
|
|
|
|
if (config.searchEnabled) {
|
|
app.handleSearch();
|
|
}
|
|
|
|
$('body').on('click', '#new_topic', function (e) {
|
|
e.preventDefault();
|
|
app.newTopic();
|
|
});
|
|
|
|
$('#header-menu .container').on('click', '[component="user/logout"]', app.logout);
|
|
|
|
Visibility.change(function (event, state) {
|
|
if (state === 'visible') {
|
|
app.isFocused = true;
|
|
app.alternatingTitle('');
|
|
} else if (state === 'hidden') {
|
|
app.isFocused = false;
|
|
}
|
|
});
|
|
|
|
createHeaderTooltips();
|
|
app.showEmailConfirmWarning();
|
|
app.showCookieWarning();
|
|
|
|
socket.removeAllListeners('event:nodebb.ready');
|
|
socket.on('event:nodebb.ready', function (data) {
|
|
if ((data.hostname === app.upstreamHost) && (!app.cacheBuster || app.cacheBuster !== data['cache-buster'])) {
|
|
app.cacheBuster = data['cache-buster'];
|
|
|
|
app.alert({
|
|
alert_id: 'forum_updated',
|
|
title: '[[global:updated.title]]',
|
|
message: '[[global:updated.message]]',
|
|
clickfn: function () {
|
|
window.location.reload();
|
|
},
|
|
type: 'warning',
|
|
});
|
|
}
|
|
});
|
|
socket.on('event:livereload', function () {
|
|
if (app.user.isAdmin && !ajaxify.currentPage.match(/admin/)) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
|
|
require(['taskbar', 'helpers', 'forum/pagination'], function (taskbar, helpers, pagination) {
|
|
taskbar.init();
|
|
|
|
helpers.register();
|
|
|
|
pagination.init();
|
|
|
|
$(window).trigger('action:app.load');
|
|
});
|
|
};
|
|
|
|
app.updateHeader = function (data, callback) {
|
|
/**
|
|
* data:
|
|
* header (obj)
|
|
* config (obj)
|
|
* next (string)
|
|
*/
|
|
require([
|
|
'benchpress',
|
|
'translator',
|
|
'forum/unread',
|
|
'forum/header/notifications',
|
|
'forum/header/chat',
|
|
], function (Benchpress, translator, Unread, Notifications, Chat) {
|
|
app.user = data.header.user;
|
|
data.header.config = data.config;
|
|
config = data.config;
|
|
Benchpress.setGlobal('config', config);
|
|
|
|
var htmlEl = $('html');
|
|
htmlEl.attr('data-dir', data.header.languageDirection);
|
|
htmlEl.css('direction', data.header.languageDirection);
|
|
|
|
// Manually reconnect socket.io
|
|
socket.close();
|
|
socket.open();
|
|
|
|
// Re-render top bar menu
|
|
var toRender = {
|
|
'slideout-menu': $('.slideout-menu'),
|
|
menu: $('#header-menu .container'),
|
|
'chats-menu': $('#chats-menu'),
|
|
};
|
|
Promise.all(Object.keys(toRender).map(function (tpl) {
|
|
return Benchpress.render('partials/' + tpl, data.header).then(function (render) {
|
|
return translator.Translator.create().translate(render);
|
|
});
|
|
})).then(function (html) {
|
|
Object.values(toRender).forEach(function (element, idx) {
|
|
element.html(html[idx]);
|
|
});
|
|
Unread.initUnreadTopics();
|
|
Notifications.prepareDOM();
|
|
Chat.prepareDOM();
|
|
app.reskin(data.header.bootswatchSkin);
|
|
translator.switchTimeagoLanguage(callback);
|
|
bootbox.setLocale(config.userLang);
|
|
|
|
if (config.searchEnabled) {
|
|
app.handleSearch();
|
|
}
|
|
|
|
handleStatusChange();
|
|
|
|
$(window).trigger('action:app.updateHeader');
|
|
});
|
|
});
|
|
};
|
|
|
|
app.logout = function (e) {
|
|
if (e) {
|
|
e.preventDefault();
|
|
}
|
|
$(window).trigger('action:app.logout');
|
|
|
|
/*
|
|
Set session refresh flag (otherwise the session check will trip and throw invalid session modal)
|
|
We know the session is/will be invalid (uid mismatch) because the user is logging out
|
|
*/
|
|
app.flags = app.flags || {};
|
|
app.flags._sessionRefresh = true;
|
|
|
|
$.ajax(config.relative_path + '/logout', {
|
|
type: 'POST',
|
|
headers: {
|
|
'x-csrf-token': config.csrf_token,
|
|
},
|
|
success: function (data) {
|
|
// ACP logouts go to frontend via page load, not ajaxify
|
|
if (ajaxify.data.template.name.startsWith('admin/')) {
|
|
$(window).trigger('action:app.loggedOut', data);
|
|
window.location.href = config.relative_path + (data.next || '/');
|
|
return;
|
|
}
|
|
|
|
app.updateHeader(data, function () {
|
|
// Overwrite in hook (below) to redirect elsewhere
|
|
data.next = data.next || undefined;
|
|
|
|
$(window).trigger('action:app.loggedOut', data);
|
|
if (data.next) {
|
|
if (data.next.startsWith('http')) {
|
|
window.location.href = data.next;
|
|
return;
|
|
}
|
|
|
|
ajaxify.go(data.next);
|
|
} else {
|
|
ajaxify.refresh();
|
|
}
|
|
});
|
|
},
|
|
});
|
|
};
|
|
|
|
app.alert = function (params) {
|
|
require(['alerts'], function (alerts) {
|
|
alerts.alert(params);
|
|
});
|
|
};
|
|
|
|
app.removeAlert = function (id) {
|
|
require(['alerts'], function (alerts) {
|
|
alerts.remove(id);
|
|
});
|
|
};
|
|
|
|
app.alertSuccess = function (message, timeout) {
|
|
app.alert({
|
|
title: '[[global:alert.success]]',
|
|
message: message,
|
|
type: 'success',
|
|
timeout: timeout || 5000,
|
|
});
|
|
};
|
|
|
|
app.alertError = function (message, timeout) {
|
|
message = message.message || message;
|
|
|
|
if (message === '[[error:invalid-session]]') {
|
|
return app.handleInvalidSession();
|
|
}
|
|
|
|
app.alert({
|
|
title: '[[global:alert.error]]',
|
|
message: message,
|
|
type: 'danger',
|
|
timeout: timeout || 10000,
|
|
});
|
|
};
|
|
|
|
app.handleInvalidSession = function () {
|
|
if (app.flags && app.flags._sessionRefresh) {
|
|
return;
|
|
}
|
|
|
|
app.flags = app.flags || {};
|
|
app.flags._sessionRefresh = true;
|
|
|
|
socket.disconnect();
|
|
|
|
require(['translator'], function (translator) {
|
|
translator.translate('[[error:invalid-session-text]]', function (translated) {
|
|
bootbox.alert({
|
|
title: '[[error:invalid-session]]',
|
|
message: translated,
|
|
closeButton: false,
|
|
callback: function () {
|
|
window.location.reload();
|
|
},
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
app.enterRoom = function (room, callback) {
|
|
callback = callback || function () {};
|
|
if (socket && app.user.uid && app.currentRoom !== room) {
|
|
var previousRoom = app.currentRoom;
|
|
app.currentRoom = room;
|
|
socket.emit('meta.rooms.enter', {
|
|
enter: room,
|
|
}, function (err) {
|
|
if (err) {
|
|
app.currentRoom = previousRoom;
|
|
return app.alertError(err.message);
|
|
}
|
|
|
|
callback();
|
|
});
|
|
}
|
|
};
|
|
|
|
app.leaveCurrentRoom = function () {
|
|
if (!socket) {
|
|
return;
|
|
}
|
|
var previousRoom = app.currentRoom;
|
|
app.currentRoom = '';
|
|
socket.emit('meta.rooms.leaveCurrent', function (err) {
|
|
if (err) {
|
|
app.currentRoom = previousRoom;
|
|
return app.alertError(err.message);
|
|
}
|
|
});
|
|
};
|
|
|
|
function highlightNavigationLink() {
|
|
$('#main-nav li')
|
|
.removeClass('active')
|
|
.find('a')
|
|
.filter(function (i, x) { return window.location.pathname.startsWith(x.getAttribute('href')); })
|
|
.parent()
|
|
.addClass('active');
|
|
}
|
|
|
|
app.createUserTooltips = function (els, placement) {
|
|
if (isTouchDevice) {
|
|
return;
|
|
}
|
|
els = els || $('body');
|
|
els.find('.avatar,img[title].teaser-pic,img[title].user-img,div.user-icon,span.user-icon').each(function () {
|
|
$(this).tooltip({
|
|
placement: placement || $(this).attr('title-placement') || 'top',
|
|
title: $(this).attr('title'),
|
|
});
|
|
});
|
|
};
|
|
|
|
app.createStatusTooltips = function () {
|
|
if (!isTouchDevice) {
|
|
$('body').tooltip({
|
|
selector: '.fa-circle.status',
|
|
placement: 'top',
|
|
});
|
|
}
|
|
};
|
|
|
|
app.processPage = function () {
|
|
highlightNavigationLink();
|
|
|
|
$('.timeago').timeago();
|
|
|
|
utils.makeNumbersHumanReadable($('.human-readable-number'));
|
|
|
|
utils.addCommasToNumbers($('.formatted-number'));
|
|
|
|
app.createUserTooltips();
|
|
|
|
app.createStatusTooltips();
|
|
|
|
// Scroll back to top of page
|
|
if (!ajaxify.isCold()) {
|
|
window.scrollTo(0, 0);
|
|
}
|
|
};
|
|
|
|
app.showMessages = function () {
|
|
var messages = {
|
|
login: {
|
|
format: 'alert',
|
|
title: '[[global:welcome_back]] ' + app.user.username + '!',
|
|
message: '[[global:you_have_successfully_logged_in]]',
|
|
},
|
|
register: {
|
|
format: 'modal',
|
|
},
|
|
};
|
|
|
|
function showAlert(type, message) {
|
|
switch (messages[type].format) {
|
|
case 'alert':
|
|
app.alert({
|
|
type: 'success',
|
|
title: messages[type].title,
|
|
message: messages[type].message,
|
|
timeout: 5000,
|
|
});
|
|
break;
|
|
|
|
case 'modal':
|
|
require(['translator'], function (translator) {
|
|
translator.translate(message || messages[type].message, function (translated) {
|
|
bootbox.alert({
|
|
title: messages[type].title,
|
|
message: translated,
|
|
});
|
|
});
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (showWelcomeMessage) {
|
|
showWelcomeMessage = false;
|
|
$(document).ready(function () {
|
|
showAlert('login');
|
|
});
|
|
}
|
|
if (registerMessage) {
|
|
$(document).ready(function () {
|
|
showAlert('register', decodeURIComponent(registerMessage));
|
|
registerMessage = false;
|
|
});
|
|
}
|
|
};
|
|
|
|
app.openChat = function (roomId, uid) {
|
|
if (!app.user.uid) {
|
|
return app.alertError('[[error:not-logged-in]]');
|
|
}
|
|
|
|
require(['chat'], function (chat) {
|
|
function loadAndCenter(chatModal) {
|
|
chat.load(chatModal.attr('data-uuid'));
|
|
chat.center(chatModal);
|
|
chat.focusInput(chatModal);
|
|
}
|
|
|
|
if (chat.modalExists(roomId)) {
|
|
loadAndCenter(chat.getModal(roomId));
|
|
} else {
|
|
socket.emit('modules.chats.loadRoom', { roomId: roomId, uid: uid || app.user.uid }, function (err, roomData) {
|
|
if (err) {
|
|
return app.alertError(err.message);
|
|
}
|
|
roomData.users = roomData.users.filter(function (user) {
|
|
return user && parseInt(user.uid, 10) !== parseInt(app.user.uid, 10);
|
|
});
|
|
roomData.uid = uid || app.user.uid;
|
|
roomData.isSelf = true;
|
|
chat.createModal(roomData, loadAndCenter);
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
app.newChat = function (touid, callback) {
|
|
function createChat() {
|
|
socket.emit('modules.chats.newRoom', { touid: touid }, function (err, roomId) {
|
|
if (err) {
|
|
return app.alertError(err.message);
|
|
}
|
|
|
|
if (!ajaxify.data.template.chats) {
|
|
app.openChat(roomId);
|
|
} else {
|
|
ajaxify.go('chats/' + roomId);
|
|
}
|
|
|
|
callback(false, roomId);
|
|
});
|
|
}
|
|
|
|
callback = callback || function () {};
|
|
if (!app.user.uid) {
|
|
return app.alertError('[[error:not-logged-in]]');
|
|
}
|
|
|
|
if (parseInt(touid, 10) === parseInt(app.user.uid, 10)) {
|
|
return app.alertError('[[error:cant-chat-with-yourself]]');
|
|
}
|
|
socket.emit('modules.chats.isDnD', touid, function (err, isDnD) {
|
|
if (err) {
|
|
return app.alertError(err.message);
|
|
}
|
|
if (!isDnD) {
|
|
return createChat();
|
|
}
|
|
bootbox.confirm('[[modules:chat.confirm-chat-with-dnd-user]]', function (ok) {
|
|
if (ok) {
|
|
createChat();
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
var titleObj = {
|
|
active: false,
|
|
interval: undefined,
|
|
titles: [],
|
|
};
|
|
|
|
app.alternatingTitle = function (title) {
|
|
if (typeof title !== 'string') {
|
|
return;
|
|
}
|
|
|
|
if (title.length > 0 && !app.isFocused) {
|
|
if (!titleObj.titles[0]) {
|
|
titleObj.titles[0] = window.document.title;
|
|
}
|
|
|
|
require(['translator'], function (translator) {
|
|
translator.translate(title, function (translated) {
|
|
titleObj.titles[1] = translated;
|
|
if (titleObj.interval) {
|
|
clearInterval(titleObj.interval);
|
|
}
|
|
|
|
titleObj.interval = setInterval(function () {
|
|
var title = titleObj.titles[titleObj.titles.indexOf(window.document.title) ^ 1];
|
|
if (title) {
|
|
window.document.title = $('<div/>').html(title).text();
|
|
}
|
|
}, 2000);
|
|
});
|
|
});
|
|
} else {
|
|
if (titleObj.interval) {
|
|
clearInterval(titleObj.interval);
|
|
}
|
|
if (titleObj.titles[0]) {
|
|
window.document.title = $('<div/>').html(titleObj.titles[0]).text();
|
|
}
|
|
}
|
|
};
|
|
|
|
app.refreshTitle = function (title) {
|
|
if (!title) {
|
|
return;
|
|
}
|
|
require(['translator'], function (translator) {
|
|
title = config.titleLayout.replace(/{/g, '{').replace(/}/g, '}')
|
|
.replace('{pageTitle}', function () { return title; })
|
|
.replace('{browserTitle}', function () { return config.browserTitle; });
|
|
|
|
// Allow translation strings in title on ajaxify (#5927)
|
|
title = translator.unescape(title);
|
|
|
|
translator.translate(title, function (translated) {
|
|
titleObj.titles[0] = translated;
|
|
app.alternatingTitle('');
|
|
});
|
|
});
|
|
};
|
|
|
|
app.toggleNavbar = function (state) {
|
|
var navbarEl = $('.navbar');
|
|
if (navbarEl) {
|
|
navbarEl.toggleClass('hidden', !state);
|
|
}
|
|
};
|
|
|
|
function createHeaderTooltips() {
|
|
var env = utils.findBootstrapEnvironment();
|
|
if (env === 'xs' || env === 'sm' || isTouchDevice) {
|
|
return;
|
|
}
|
|
$('#header-menu li a[title]').each(function () {
|
|
$(this).tooltip({
|
|
placement: 'bottom',
|
|
trigger: 'hover',
|
|
title: $(this).attr('title'),
|
|
});
|
|
});
|
|
|
|
|
|
$('#search-form').parent().tooltip({
|
|
placement: 'bottom',
|
|
trigger: 'hover',
|
|
title: $('#search-button i').attr('title'),
|
|
});
|
|
|
|
|
|
$('#user_dropdown').tooltip({
|
|
placement: 'bottom',
|
|
trigger: 'hover',
|
|
title: $('#user_dropdown').attr('title'),
|
|
});
|
|
}
|
|
|
|
app.enableTopicSearch = function (options) {
|
|
var quickSearchResults = options.resultEl;
|
|
var inputEl = options.inputEl;
|
|
var template = options.template || 'partials/quick-search-results';
|
|
var searchTimeoutId = 0;
|
|
inputEl.on('keyup', function () {
|
|
if (searchTimeoutId) {
|
|
clearTimeout(searchTimeoutId);
|
|
searchTimeoutId = 0;
|
|
}
|
|
if (inputEl.val().length < 3) {
|
|
return;
|
|
}
|
|
|
|
searchTimeoutId = setTimeout(function () {
|
|
if (!inputEl.is(':focus')) {
|
|
return quickSearchResults.addClass('hidden');
|
|
}
|
|
require(['search'], function (search) {
|
|
var data = {
|
|
term: inputEl.val(),
|
|
in: 'titles',
|
|
searchOnly: 1,
|
|
};
|
|
search.api(data, function (data) {
|
|
if (!data.matchCount) {
|
|
quickSearchResults.html('').addClass('hidden');
|
|
return;
|
|
}
|
|
data.posts.forEach(function (p) {
|
|
p.snippet = utils.escapeHTML($(p.content).text().slice(0, 80) + '...');
|
|
});
|
|
app.parseAndTranslate(template, data, function (html) {
|
|
html.find('.timeago').timeago();
|
|
quickSearchResults.html(html).removeClass('hidden').show();
|
|
});
|
|
});
|
|
});
|
|
}, 250);
|
|
});
|
|
};
|
|
|
|
app.handleSearch = function () {
|
|
var searchButton = $('#search-button');
|
|
var searchFields = $('#search-fields');
|
|
var searchInput = $('#search-fields input');
|
|
var quickSearchResults = $('#quick-search-results');
|
|
|
|
$('#search-form .advanced-search-link').on('mousedown', function () {
|
|
ajaxify.go('/search');
|
|
});
|
|
|
|
$('#search-form').on('submit', function () {
|
|
searchInput.blur();
|
|
});
|
|
searchInput.on('blur', dismissSearch);
|
|
searchInput.on('focus', function () {
|
|
if (searchInput.val() && quickSearchResults.children().length) {
|
|
quickSearchResults.removeClass('hidden').show();
|
|
}
|
|
});
|
|
|
|
app.enableTopicSearch({
|
|
inputEl: searchInput,
|
|
resultEl: quickSearchResults,
|
|
});
|
|
|
|
function dismissSearch() {
|
|
searchFields.addClass('hidden');
|
|
searchButton.removeClass('hidden');
|
|
setTimeout(function () {
|
|
quickSearchResults.addClass('hidden');
|
|
}, 200);
|
|
}
|
|
|
|
searchButton.on('click', function (e) {
|
|
if (!config.loggedIn && !app.user.privileges['search:content']) {
|
|
app.alert({
|
|
message: '[[error:search-requires-login]]',
|
|
timeout: 3000,
|
|
});
|
|
ajaxify.go('login');
|
|
return false;
|
|
}
|
|
e.stopPropagation();
|
|
|
|
app.prepareSearch();
|
|
return false;
|
|
});
|
|
|
|
$('#search-form').on('submit', function () {
|
|
var input = $(this).find('input');
|
|
require(['search'], function (search) {
|
|
var data = search.getSearchPreferences();
|
|
data.term = input.val();
|
|
search.query(data, function () {
|
|
input.val('');
|
|
});
|
|
});
|
|
return false;
|
|
});
|
|
};
|
|
|
|
app.prepareSearch = function () {
|
|
$('#search-fields').removeClass('hidden');
|
|
$('#search-button').addClass('hidden');
|
|
$('#search-fields input').focus();
|
|
};
|
|
|
|
function handleStatusChange() {
|
|
$('[component="header/usercontrol"] [data-status]').off('click').on('click', function (e) {
|
|
var status = $(this).attr('data-status');
|
|
socket.emit('user.setStatus', status, function (err) {
|
|
if (err) {
|
|
return app.alertError(err.message);
|
|
}
|
|
$('[data-uid="' + app.user.uid + '"] [component="user/status"], [component="header/profilelink"] [component="user/status"]')
|
|
.removeClass('away online dnd offline')
|
|
.addClass(status);
|
|
$('[component="header/usercontrol"] [data-status]').each(function () {
|
|
$(this).find('span').toggleClass('bold', $(this).attr('data-status') === status);
|
|
});
|
|
app.user.status = status;
|
|
});
|
|
e.preventDefault();
|
|
});
|
|
}
|
|
|
|
app.updateUserStatus = function (el, status) {
|
|
if (!el.length) {
|
|
return;
|
|
}
|
|
|
|
require(['translator'], function (translator) {
|
|
translator.translate('[[global:' + status + ']]', function (translated) {
|
|
el.removeClass('online offline dnd away')
|
|
.addClass(status)
|
|
.attr('title', translated)
|
|
.attr('data-original-title', translated);
|
|
});
|
|
});
|
|
};
|
|
|
|
app.newTopic = function (cid, tags) {
|
|
$(window).trigger('action:composer.topic.new', {
|
|
cid: cid || ajaxify.data.cid || 0,
|
|
tags: tags || (ajaxify.data.tag ? [ajaxify.data.tag] : []),
|
|
});
|
|
};
|
|
|
|
app.loadJQueryUI = function (callback) {
|
|
if (typeof $().autocomplete === 'function') {
|
|
return callback();
|
|
}
|
|
|
|
var scriptEl = document.createElement('script');
|
|
scriptEl.type = 'text/javascript';
|
|
scriptEl.src = config.relative_path + '/assets/vendor/jquery/js/jquery-ui.js?' + config['cache-buster'];
|
|
scriptEl.onload = callback;
|
|
document.head.appendChild(scriptEl);
|
|
};
|
|
|
|
app.showEmailConfirmWarning = function (err) {
|
|
if (!config.requireEmailConfirmation || !app.user.uid) {
|
|
return;
|
|
}
|
|
var msg = {
|
|
alert_id: 'email_confirm',
|
|
type: 'warning',
|
|
timeout: 0,
|
|
};
|
|
|
|
if (!app.user.email) {
|
|
msg.message = '[[error:no-email-to-confirm]]';
|
|
msg.clickfn = function () {
|
|
app.removeAlert('email_confirm');
|
|
ajaxify.go('user/' + app.user.userslug + '/edit');
|
|
};
|
|
app.alert(msg);
|
|
} else if (!app.user['email:confirmed'] && !app.user.isEmailConfirmSent) {
|
|
msg.message = err ? err.message : '[[error:email-not-confirmed]]';
|
|
msg.clickfn = function () {
|
|
app.removeAlert('email_confirm');
|
|
socket.emit('user.emailConfirm', {}, function (err) {
|
|
if (err) {
|
|
return app.alertError(err.message);
|
|
}
|
|
app.alertSuccess('[[notifications:email-confirm-sent]]');
|
|
});
|
|
};
|
|
|
|
app.alert(msg);
|
|
} else if (!app.user['email:confirmed'] && app.user.isEmailConfirmSent) {
|
|
msg.message = '[[error:email-not-confirmed-email-sent]]';
|
|
app.alert(msg);
|
|
}
|
|
};
|
|
|
|
app.parseAndTranslate = function (template, blockName, data, callback) {
|
|
require(['translator', 'benchpress'], function (translator, Benchpress) {
|
|
function translate(html, callback) {
|
|
translator.translate(html, function (translatedHTML) {
|
|
translatedHTML = translator.unescape(translatedHTML);
|
|
callback($(translatedHTML));
|
|
});
|
|
}
|
|
|
|
if (typeof blockName === 'string') {
|
|
Benchpress.parse(template, blockName, data, function (html) {
|
|
translate(html, callback);
|
|
});
|
|
} else {
|
|
callback = data;
|
|
data = blockName;
|
|
Benchpress.parse(template, data, function (html) {
|
|
translate(html, callback);
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
app.loadProgressiveStylesheet = function () {
|
|
var linkEl = document.createElement('link');
|
|
linkEl.rel = 'stylesheet';
|
|
linkEl.href = config.relative_path + '/assets/js-enabled.css?' + app.cacheBuster;
|
|
|
|
document.head.appendChild(linkEl);
|
|
};
|
|
|
|
app.showCookieWarning = function () {
|
|
require(['translator', 'storage'], function (translator, storage) {
|
|
if (!config.cookies.enabled || !navigator.cookieEnabled) {
|
|
// Skip warning if cookie consent subsystem disabled (obviously), or cookies not in use
|
|
return;
|
|
} else if (window.location.pathname.startsWith(config.relative_path + '/admin')) {
|
|
// No need to show cookie consent warning in ACP
|
|
return;
|
|
} else if (storage.getItem('cookieconsent') === '1') {
|
|
return;
|
|
}
|
|
|
|
config.cookies.message = translator.unescape(config.cookies.message);
|
|
config.cookies.dismiss = translator.unescape(config.cookies.dismiss);
|
|
config.cookies.link = translator.unescape(config.cookies.link);
|
|
|
|
app.parseAndTranslate('partials/cookie-consent', config.cookies, function (html) {
|
|
$(document.body).append(html);
|
|
$(document.body).addClass('cookie-consent-open');
|
|
|
|
var warningEl = $('.cookie-consent');
|
|
var dismissEl = warningEl.find('button');
|
|
dismissEl.on('click', function () {
|
|
// Save consent cookie and remove warning element
|
|
storage.setItem('cookieconsent', '1');
|
|
warningEl.remove();
|
|
$(document.body).removeClass('cookie-consent-open');
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
app.reskin = function (skinName) {
|
|
var clientEl = Array.prototype.filter.call(document.querySelectorAll('link[rel="stylesheet"]'), function (el) {
|
|
return el.href.indexOf(config.relative_path + '/assets/client') !== -1;
|
|
})[0] || null;
|
|
if (!clientEl) {
|
|
return;
|
|
}
|
|
|
|
var currentSkinClassName = $('body').attr('class').split(/\s+/).filter(function (className) {
|
|
return className.startsWith('skin-');
|
|
});
|
|
if (!currentSkinClassName[0]) {
|
|
return;
|
|
}
|
|
var currentSkin = currentSkinClassName[0].slice(5);
|
|
currentSkin = currentSkin !== 'noskin' ? currentSkin : '';
|
|
|
|
// Stop execution if skin didn't change
|
|
if (skinName === currentSkin) {
|
|
return;
|
|
}
|
|
|
|
var linkEl = document.createElement('link');
|
|
linkEl.rel = 'stylesheet';
|
|
linkEl.type = 'text/css';
|
|
linkEl.href = config.relative_path + '/assets/client' + (skinName ? '-' + skinName : '') + '.css';
|
|
linkEl.onload = function () {
|
|
clientEl.parentNode.removeChild(clientEl);
|
|
|
|
// Update body class with proper skin name
|
|
$('body').removeClass(currentSkinClassName.join(' '));
|
|
$('body').addClass('skin-' + (skinName || 'noskin'));
|
|
};
|
|
|
|
document.head.appendChild(linkEl);
|
|
};
|
|
|
|
app.updateTags = function () {
|
|
var metaWhitelist = ['title', 'description', /og:.+/, /article:.+/].map(function (val) {
|
|
return new RegExp(val);
|
|
});
|
|
var linkWhitelist = ['canonical', 'alternate', 'up'];
|
|
|
|
// Delete the old meta tags
|
|
Array.prototype.slice
|
|
.call(document.querySelectorAll('head meta'))
|
|
.filter(function (el) {
|
|
var name = el.getAttribute('property') || el.getAttribute('name');
|
|
return metaWhitelist.some(function (exp) {
|
|
return !!exp.test(name);
|
|
});
|
|
})
|
|
.forEach(function (el) {
|
|
document.head.removeChild(el);
|
|
});
|
|
|
|
// Add new meta tags
|
|
ajaxify.data._header.tags.meta
|
|
.filter(function (tagObj) {
|
|
var name = tagObj.name || tagObj.property;
|
|
return metaWhitelist.some(function (exp) {
|
|
return !!exp.test(name);
|
|
});
|
|
})
|
|
.forEach(function (tagObj) {
|
|
var metaEl = document.createElement('meta');
|
|
Object.keys(tagObj).forEach(function (prop) {
|
|
metaEl.setAttribute(prop, tagObj[prop]);
|
|
});
|
|
document.head.appendChild(metaEl);
|
|
});
|
|
|
|
// Delete the old link tags
|
|
Array.prototype.slice
|
|
.call(document.querySelectorAll('head link'))
|
|
.filter(function (el) {
|
|
var name = el.getAttribute('rel');
|
|
return linkWhitelist.some(function (item) {
|
|
return item === name;
|
|
});
|
|
})
|
|
.forEach(function (el) {
|
|
document.head.removeChild(el);
|
|
});
|
|
|
|
// Add new link tags
|
|
ajaxify.data._header.tags.link
|
|
.filter(function (tagObj) {
|
|
return linkWhitelist.some(function (item) {
|
|
return item === tagObj.rel;
|
|
});
|
|
})
|
|
.forEach(function (tagObj) {
|
|
var linkEl = document.createElement('link');
|
|
Object.keys(tagObj).forEach(function (prop) {
|
|
linkEl.setAttribute(prop, tagObj[prop]);
|
|
});
|
|
document.head.appendChild(linkEl);
|
|
});
|
|
};
|
|
}());
|