Files
NodeBB/public/src/app.js

713 lines
18 KiB
JavaScript
Raw Normal View History

2017-02-18 01:56:23 -07:00
'use strict';
2015-07-21 11:23:16 -04:00
2019-06-22 21:23:19 -04:00
app = window.app || {};
2015-07-21 11:23:16 -04:00
app.isFocused = true;
app.currentRoom = null;
app.widgets = {};
app.flags = {};
2015-07-21 11:23:16 -04:00
app.cacheBuster = null;
(function () {
let appLoaded = false;
const isTouchDevice = utils.isTouchDevice();
2015-07-21 11:23:16 -04:00
2015-09-18 10:58:32 -04:00
app.cacheBuster = config['cache-buster'];
2015-07-21 11:23:16 -04:00
let hooks;
require(['hooks'], function (_hooks) {
hooks = _hooks;
});
$(document).ready(function () {
ajaxify.parseData();
app.load();
});
app.coldLoad = function () {
if (appLoaded) {
ajaxify.coldLoad();
} else {
$(window).on('action:app.load', function () {
ajaxify.coldLoad();
});
}
};
app.handleEarlyClicks = function () {
/**
* Occasionally, a button or anchor (not meant to be ajaxified) is clicked before
* ajaxify is ready. Capture that event and re-click it once NodeBB is ready.
*
* e.g. New Topic/Reply, post tools
*/
if (document.body) {
let earlyQueue = []; // once we can ES6, use Set instead
const earlyClick = function (ev) {
let btnEl = ev.target.closest('button');
const anchorEl = ev.target.closest('a');
if (!btnEl && anchorEl && (anchorEl.getAttribute('data-ajaxify') === 'false' || anchorEl.href === '#')) {
btnEl = anchorEl;
}
if (btnEl && !earlyQueue.includes(btnEl)) {
earlyQueue.push(btnEl);
ev.stopImmediatePropagation();
ev.preventDefault();
}
};
document.body.addEventListener('click', earlyClick);
require(['hooks'], function (hooks) {
hooks.on('action:ajaxify.end', function () {
document.body.removeEventListener('click', earlyClick);
earlyQueue.forEach(function (el) {
el.click();
});
earlyQueue = [];
});
});
} else {
setTimeout(app.handleEarlyClicks, 50);
}
};
app.handleEarlyClicks();
app.load = function () {
handleStatusChange();
2015-07-21 11:23:16 -04:00
if (config.searchEnabled) {
app.handleSearch();
}
2015-07-21 11:23:16 -04:00
Squashed commit of the following: commit 9c86d9b2904e14927cd7e9679b92aec0951d1063 Merge: ebfa63a 5a7f811 Author: Julian Lam <julian@nodebb.org> Date: Thu Jul 20 08:41:39 2017 -0400 Merge branch 'noscript-login' of https://github.com/An-dz/NodeBB into noscript commit 5a7f81185e8f9bd7d2d011c3d495988be7e437a3 Author: André Zanghelini <an_dz@simutrans-forum> Date: Mon Jul 17 23:07:14 2017 -0300 Rename clashing variable 'next' commit ebfa63a984073a58c17aa408c363cdb03ef89985 Merge: c1801cd f159d0d Author: Julian Lam <julian@nodebb.org> Date: Mon Jul 17 16:30:40 2017 -0400 Merge branch 'noscript-logout' of https://github.com/An-dz/NodeBB into noscript commit c1801cda14e6363491e30b659902e2ae71f7e1f7 Merge: 7a5f9f3 9fd542d Author: Julian Lam <julian@nodebb.org> Date: Mon Jul 17 16:30:31 2017 -0400 Merge branch 'noscript-register' of https://github.com/An-dz/NodeBB into noscript commit 7a5f9f35abc834bb72ddddc9ca07d34f2fde8353 Merge: 44851f9 d37b95c Author: Julian Lam <julian@nodebb.org> Date: Mon Jul 17 16:30:10 2017 -0400 Merge branch 'noscript-compose' of https://github.com/An-dz/NodeBB into noscript commit f159d0d9ef1b7f600e830a96fdb4b9c87c79bb4a Author: André Zanghelini <an_dz@simutrans-forum> Date: Thu Jul 6 12:16:38 2017 -0300 Prevent form submit Required for theme change commit d37b95cb71d32d4483190609798e244c331db165 Author: André Zanghelini <an_dz@simutrans-forum> Date: Thu Jul 6 01:49:52 2017 -0300 Prevent link action with scripts Required for the theme change that changes the buttons to `a` tags. commit 9fd542d8970b7d1a4126f4edc4b44eab7d708fb0 Author: André Zanghelini <an_dz@simutrans-forum> Date: Wed Jul 5 19:57:56 2017 -0300 Fix tests commit cdad5bf8c2891ad76f7441fd4d8a74b058a14e6d Author: André Zanghelini <an_dz@simutrans-forum> Date: Wed Jul 5 19:09:17 2017 -0300 Update error handling commit 4ff11cd136a4fb98483f837e2cebc741380dfe76 Author: André Zanghelini <an_dz@simutrans-forum> Date: Wed Jul 5 17:29:08 2017 -0300 Remove async waterfall commit df01d44e821a70c984b89e9585a325c3e02c6e37 Author: André Zanghelini <an_dz@simutrans-forum> Date: Wed Jul 5 16:59:43 2017 -0300 Set noscript compose as noscript at start commit 4bcc380da72239b8315cc849a77a3036e06e4a12 Author: André Zanghelini <an_dz@simutrans-forum> Date: Wed Jul 5 16:59:12 2017 -0300 Remove last useless next commit b5eac6fea11e209934c0648a7e75ad07a2167123 Author: André Zanghelini <an_dz@simutrans-forum> Date: Sun Jul 2 18:35:08 2017 -0300 Last function requires no next commit 20a5cce6e6e32a454c304c448383707ec44c75a8 Author: André Zanghelini <an_dz@simutrans-forum> Date: Sun Jul 2 18:06:58 2017 -0300 Remove more useless next calls commit 85ee22a79bcbbb1995106f43d4c74d6ba9206cab Author: André Zanghelini <an_dz@simutrans-forum> Date: Sun Jul 2 17:46:07 2017 -0300 Remove useless next calls commit 7d984c47ad24faac1fe537dee4a5a7d697e8634c Author: André Zanghelini <an_dz@simutrans-forum> Date: Sun Jul 2 15:45:31 2017 -0300 Support old themes commit 4a09dfbd08253115c342a9e829c4e6940cecb8cc Author: André Zanghelini <an_dz@simutrans-forum> Date: Sun Jul 2 15:37:23 2017 -0300 Moved all error handling into helpers function commit 391aa6e67ef9ab67304005e14ac0633cdb630713 Author: André Zanghelini <an_dz@simutrans-forum> Date: Thu Jun 8 15:37:37 2017 -0300 ESLint - Fix mixed conditionals commit 80ccc6fd581d791f31e7ab62de8de611837bfc3c Author: André Zanghelini <an_dz@simutrans-forum> Date: Sat Jun 3 18:08:15 2017 -0300 Compose without scripts commit 2aca811256721238ca0cede4954213d369009885 Author: André Zanghelini <an_dz@simutrans-forum> Date: Sat Jun 3 18:00:44 2017 -0300 Register without scripts commit 097bb51577fb26f8e22f86dc274cb670ab606a8a Author: André Zanghelini <an_dz@simutrans-forum> Date: Sat Jun 3 16:42:15 2017 -0300 Logout without scripts commit d497e08109891079656fee1c145043a9c0e55f2e Author: André Zanghelini <an_dz@simutrans-forum> Date: Sat Jun 3 16:27:10 2017 -0300 Login without script
2017-07-20 08:51:04 -04:00
$('body').on('click', '#new_topic', function (e) {
e.preventDefault();
app.newTopic();
});
2015-07-21 11:23:16 -04:00
$('#header-menu .container').on('click', '[component="user/logout"]', function () {
app.logout();
return false;
});
2015-07-21 11:23:16 -04:00
Visibility.change(function (event, state) {
2020-09-06 22:36:09 -04:00
app.isFocused = state === 'visible';
});
2015-08-22 12:20:17 -04:00
createHeaderTooltips();
2020-09-28 17:46:43 -04:00
registerServiceWorker();
2015-08-22 12:20:17 -04:00
2020-10-10 21:54:32 -04:00
require([
'taskbar',
'helpers',
'forum/pagination',
'translator',
'messages',
2020-10-10 21:54:32 -04:00
'forum/unread',
'forum/header/notifications',
'forum/header/chat',
'timeago/jquery.timeago',
], function (taskbar, helpers, pagination, translator, messages, unread, notifications, chat) {
2020-10-10 21:54:32 -04:00
notifications.prepareDOM();
chat.prepareDOM();
translator.prepareDOM();
taskbar.init();
helpers.register();
pagination.init();
if (app.user.uid > 0) {
unread.initUnreadTopics();
}
2020-11-19 20:34:26 -05:00
function finishLoad() {
hooks.fire('action:app.load');
messages.show();
2020-11-19 20:34:26 -05:00
appLoaded = true;
}
overrides.overrideTimeago();
if (app.user.timeagoCode && app.user.timeagoCode !== 'en') {
2020-11-19 20:34:26 -05:00
require(['timeago/locales/jquery.timeago.' + app.user.timeagoCode], finishLoad);
} else {
2020-11-19 20:34:26 -05:00
finishLoad();
}
2015-09-18 10:58:32 -04:00
});
};
app.require = async (modules) => { // allows you to await require.js modules
let single = false;
if (!Array.isArray(modules)) {
modules = [modules];
single = true;
}
return new Promise((resolve, reject) => {
require(modules, (...exports) => {
resolve(single ? exports.pop() : exports);
}, reject);
});
};
app.logout = function (redirect) {
redirect = redirect === undefined ? true : redirect;
hooks.fire('action:app.logout');
2016-07-14 21:44:33 +03:00
$.ajax(config.relative_path + '/logout', {
type: 'POST',
headers: {
2017-02-17 19:31:21 -07:00
'x-csrf-token': config.csrf_token,
2016-07-14 21:44:33 +03:00
},
beforeSend: function () {
app.flags._logout = true;
},
success: function (data) {
hooks.fire('action:app.loggedOut', data);
if (redirect) {
if (data.next) {
window.location.href = data.next;
} else {
window.location.reload();
}
}
2017-02-17 19:31:21 -07:00
},
2015-07-21 11:23:16 -04:00
});
return false;
2015-07-21 11:23:16 -04:00
};
app.alert = function (params) {
require(['alerts'], function (alerts) {
2015-07-21 11:23:16 -04:00
alerts.alert(params);
});
};
app.removeAlert = function (id) {
require(['alerts'], function (alerts) {
2015-07-21 11:23:16 -04:00
alerts.remove(id);
});
};
app.alertSuccess = function (message, timeout) {
app.alert({
alert_id: utils.generateUUID(),
2015-07-21 11:23:16 -04:00
title: '[[global:alert.success]]',
message: message,
type: 'success',
timeout: timeout || 5000,
2015-07-21 11:23:16 -04:00
});
};
app.alertError = function (message, timeout) {
message = (message && message.message) || message;
if (message === '[[error:revalidate-failure]]') {
socket.disconnect();
app.reconnect();
return;
2016-08-16 13:48:53 -04:00
}
2015-07-21 11:23:16 -04:00
app.alert({
alert_id: utils.generateUUID(),
2015-07-21 11:23:16 -04:00
title: '[[global:alert.error]]',
message: message,
type: 'danger',
timeout: timeout || 10000,
2015-07-21 11:23:16 -04:00
});
};
app.enterRoom = function (room, callback) {
callback = callback || function () { };
2015-11-05 14:39:52 -05:00
if (socket && app.user.uid && app.currentRoom !== room) {
const previousRoom = app.currentRoom;
2016-05-12 09:31:52 +03:00
app.currentRoom = room;
2015-07-21 11:23:16 -04:00
socket.emit('meta.rooms.enter', {
2017-02-17 19:31:21 -07:00
enter: room,
}, function (err) {
2015-07-21 11:23:16 -04:00
if (err) {
2016-05-12 09:31:52 +03:00
app.currentRoom = previousRoom;
2015-10-20 17:53:44 -04:00
return app.alertError(err.message);
2015-07-21 11:23:16 -04:00
}
2016-05-12 09:31:52 +03:00
2015-11-05 14:39:52 -05:00
callback();
2015-07-21 11:23:16 -04:00
});
}
};
app.leaveCurrentRoom = function () {
if (!socket || config.maintenanceMode) {
2015-10-20 17:53:44 -04:00
return;
}
const previousRoom = app.currentRoom;
2017-05-01 21:38:03 -04:00
app.currentRoom = '';
socket.emit('meta.rooms.leaveCurrent', function (err) {
2015-10-20 17:53:44 -04:00
if (err) {
2017-05-01 21:38:03 -04:00
app.currentRoom = previousRoom;
2015-10-20 17:53:44 -04:00
return app.alertError(err.message);
}
});
};
2015-10-20 17:53:44 -04:00
2015-07-21 11:23:16 -04:00
function highlightNavigationLink() {
$('#main-nav li')
.removeClass('active')
.find('a')
.filter(function (i, a) {
return $(a).attr('href') !== '#' && window.location.hostname === a.hostname &&
(
window.location.pathname === a.pathname ||
window.location.pathname.startsWith(a.pathname + '/')
);
})
.parent()
.addClass('active');
2015-07-21 11:23:16 -04:00
}
app.createUserTooltips = function (els, placement) {
if (isTouchDevice) {
return;
}
2015-10-04 01:13:47 -04:00
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'),
container: '#content',
});
2015-07-21 11:23:16 -04:00
});
};
app.createStatusTooltips = function () {
if (!isTouchDevice) {
$('body').tooltip({
2017-02-18 01:27:46 -07:00
selector: '.fa-circle.status',
2017-02-17 19:31:21 -07:00
placement: 'top',
});
}
2015-07-21 11:23:16 -04:00
};
app.processPage = function () {
highlightNavigationLink();
$('.timeago').timeago();
2015-07-21 11:23:16 -04:00
utils.makeNumbersHumanReadable($('.human-readable-number'));
utils.addCommasToNumbers($('.formatted-number'));
app.createUserTooltips($('#content'));
2015-07-21 11:23:16 -04:00
app.createStatusTooltips();
};
2016-10-02 15:17:22 +03:00
app.openChat = function (roomId, uid) {
2015-07-21 11:23:16 -04:00
if (!app.user.uid) {
return app.alertError('[[error:not-logged-in]]');
}
require(['chat'], function (chat) {
function loadAndCenter(chatModal) {
chat.load(chatModal.attr('data-uuid'));
2015-07-21 11:23:16 -04:00
chat.center(chatModal);
chat.focusInput(chatModal);
}
if (chat.modalExists(roomId)) {
2015-12-16 10:09:00 +02:00
loadAndCenter(chat.getModal(roomId));
} else {
2017-02-18 12:30:49 -07:00
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);
});
2016-10-02 15:17:22 +03:00
roomData.uid = uid || app.user.uid;
2019-04-25 21:43:21 -04:00
roomData.isSelf = true;
2015-12-23 11:27:34 +02:00
chat.createModal(roomData, loadAndCenter);
});
2015-07-21 11:23:16 -04:00
}
});
};
app.newChat = function (touid, callback) {
2017-04-14 10:08:50 -04:00
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 () { };
2015-12-16 11:30:10 +02:00
if (!app.user.uid) {
return app.alertError('[[error:not-logged-in]]');
}
2016-10-22 10:22:05 +03:00
if (parseInt(touid, 10) === parseInt(app.user.uid, 10)) {
return app.alertError('[[error:cant-chat-with-yourself]]');
}
2017-04-14 10:08:50 -04:00
socket.emit('modules.chats.isDnD', touid, function (err, isDnD) {
if (err) {
return app.alertError(err.message);
}
2017-04-14 10:08:50 -04:00
if (!isDnD) {
return createChat();
}
require(['bootbox'], function (bootbox) {
bootbox.confirm('[[modules:chat.confirm-chat-with-dnd-user]]', function (ok) {
if (ok) {
createChat();
}
});
2017-04-14 10:08:50 -04:00
});
});
2015-12-16 11:30:10 +02:00
};
app.toggleNavbar = function (state) {
require(['components'], (components) => {
const navbarEl = components.get('navbar');
navbarEl[state ? 'show' : 'hide']();
});
2015-07-21 11:23:16 -04:00
};
function createHeaderTooltips() {
const env = utils.findBootstrapEnvironment();
if (env === 'xs' || env === 'sm' || isTouchDevice) {
2015-07-21 11:23:16 -04:00
return;
}
$('#header-menu li a[title]').each(function () {
$(this).tooltip({
placement: 'bottom',
2016-07-18 23:34:52 +00:00
trigger: 'hover',
title: $(this).attr('title'),
});
});
2015-07-21 11:23:16 -04:00
$('#search-form').tooltip({
placement: 'bottom',
trigger: 'hover',
title: $('#search-button i').attr('title'),
});
$('#user_dropdown').tooltip({
placement: 'bottom',
trigger: 'hover',
title: $('#user_dropdown').attr('title'),
});
2015-07-21 11:23:16 -04:00
}
2020-06-10 15:11:57 -04:00
app.enableTopicSearch = function (options) {
if (!config.searchEnabled || !app.user.privileges['search:content']) {
return;
}
2020-06-10 16:56:05 -04:00
/* eslint-disable-next-line */
const searchOptions = Object.assign({ in: config.searchDefaultInQuick || 'titles' }, options.searchOptions);
const quickSearchResults = options.searchElements.resultEl;
const inputEl = options.searchElements.inputEl;
let oldValue = inputEl.val();
const filterCategoryEl = quickSearchResults.find('.filter-category');
2020-09-30 12:41:23 -04:00
function updateCategoryFilterName() {
if (ajaxify.data.template.category) {
require(['translator'], function (translator) {
translator.translate('[[search:search-in-category, ' + ajaxify.data.name + ']]', function (translated) {
const name = $('<div></div>').html(translated).text();
2020-09-30 12:41:23 -04:00
filterCategoryEl.find('.name').text(name);
});
});
}
filterCategoryEl.toggleClass('hidden', !ajaxify.data.template.category);
}
2020-06-10 16:56:05 -04:00
function doSearch() {
require(['search'], function (search) {
/* eslint-disable-next-line */
options.searchOptions = Object.assign({}, searchOptions);
options.searchOptions.term = inputEl.val();
2020-09-30 12:41:23 -04:00
updateCategoryFilterName();
if (ajaxify.data.template.category) {
if (filterCategoryEl.find('input[type="checkbox"]').is(':checked')) {
options.searchOptions.categories = [ajaxify.data.cid];
options.searchOptions.searchChildren = true;
}
}
2020-09-22 20:22:50 -04:00
quickSearchResults.removeClass('hidden').find('.quick-search-results-container').html('');
quickSearchResults.find('.loading-indicator').removeClass('hidden');
hooks.fire('action:search.quick.start', options);
2020-06-10 16:56:05 -04:00
options.searchOptions.searchOnly = 1;
search.api(options.searchOptions, function (data) {
2020-09-22 20:22:50 -04:00
quickSearchResults.find('.loading-indicator').addClass('hidden');
2020-06-10 16:56:05 -04:00
if (options.hideOnNoMatches && !data.posts.length) {
return quickSearchResults.addClass('hidden').find('.quick-search-results-container').html('');
2020-06-10 16:56:05 -04:00
}
data.posts.forEach(function (p) {
const text = $('<div>' + p.content + '</div>').text();
const query = inputEl.val().toLowerCase().replace(/^in:topic-\d+/, '');
const start = Math.max(0, text.toLowerCase().indexOf(query) - 40);
2020-06-16 14:58:02 -04:00
p.snippet = utils.escapeHTML((start > 0 ? '...' : '') +
text.slice(start, start + 80) +
(text.length - start > 80 ? '...' : ''));
2020-06-10 16:56:05 -04:00
});
app.parseAndTranslate('partials/quick-search-results', data, function (html) {
if (html.length) {
html.find('.timeago').timeago();
}
quickSearchResults.toggleClass('hidden', !html.length || !inputEl.is(':focus'))
2020-06-10 16:56:05 -04:00
.find('.quick-search-results-container')
.html(html.length ? html : '');
const highlightEls = quickSearchResults.find(
'.quick-search-results .quick-search-title, .quick-search-results .snippet'
);
search.highlightMatches(options.searchOptions.term, highlightEls);
hooks.fire('action:search.quick.complete', {
2020-06-10 16:56:05 -04:00
data: data,
options: options,
});
});
});
});
}
2020-06-09 16:49:56 -04:00
2020-09-30 12:41:23 -04:00
quickSearchResults.find('.filter-category input[type="checkbox"]').on('change', function () {
inputEl.focus();
doSearch();
});
inputEl.off('keyup').on('keyup', utils.debounce(function () {
if (inputEl.val().length < 3) {
quickSearchResults.addClass('hidden');
2020-06-09 16:49:56 -04:00
oldValue = inputEl.val();
return;
}
if (inputEl.val() === oldValue) {
return;
}
oldValue = inputEl.val();
if (!inputEl.is(':focus')) {
return quickSearchResults.addClass('hidden');
}
doSearch();
2021-10-25 21:22:44 -04:00
}, 500));
2020-06-10 16:56:05 -04:00
let mousedownOnResults = false;
quickSearchResults.on('mousedown', function () {
$(window).one('mouseup', function () {
quickSearchResults.addClass('hidden');
});
mousedownOnResults = true;
});
2020-06-10 16:56:05 -04:00
inputEl.on('blur', function () {
if (!inputEl.is(':focus') && !mousedownOnResults && !quickSearchResults.hasClass('hidden')) {
quickSearchResults.addClass('hidden');
}
2020-06-10 16:56:05 -04:00
});
let ajaxified = false;
2021-10-28 21:33:21 -04:00
require(['hooks'], function (hooks) {
hooks.on('action:ajaxify.end', function () {
if (!ajaxify.isCold()) {
ajaxified = true;
}
});
});
2021-10-28 21:33:21 -04:00
2020-06-10 16:56:05 -04:00
inputEl.on('focus', function () {
mousedownOnResults = false;
const query = inputEl.val();
oldValue = query;
if (query && quickSearchResults.find('#quick-search-results').children().length) {
2020-09-30 12:41:23 -04:00
updateCategoryFilterName();
if (ajaxified) {
doSearch();
ajaxified = false;
} else {
quickSearchResults.removeClass('hidden');
}
inputEl[0].setSelectionRange(
query.startsWith('in:topic') ? query.indexOf(' ') + 1 : 0,
query.length
);
2020-06-10 16:56:05 -04:00
}
});
inputEl.off('refresh').on('refresh', function () {
doSearch();
});
2019-02-19 11:26:26 -05:00
};
2020-06-10 15:11:57 -04:00
app.handleSearch = function (searchOptions) {
2021-08-18 20:35:39 -04:00
searchOptions = searchOptions || { in: config.searchDefaultInQuick || 'titles' };
const searchButton = $('#search-button');
const searchFields = $('#search-fields');
const searchInput = $('#search-fields input');
const quickSearchContainer = $('#quick-search-container');
2019-02-19 11:26:26 -05:00
$('#search-form .advanced-search-link').off('mousedown').on('mousedown', function () {
2019-02-19 11:26:26 -05:00
ajaxify.go('/search');
});
$('#search-form').off('submit').on('submit', function () {
2019-02-21 12:10:49 -05:00
searchInput.blur();
});
searchInput.off('blur').on('blur', dismissSearch);
2020-06-09 16:49:56 -04:00
searchInput.off('focus');
2019-02-19 11:26:26 -05:00
const searchElements = {
2019-02-19 11:26:26 -05:00
inputEl: searchInput,
2020-05-27 20:58:54 -04:00
resultEl: quickSearchContainer,
2020-06-10 15:11:57 -04:00
};
app.enableTopicSearch({
searchOptions: searchOptions,
searchElements: searchElements,
});
2015-07-21 11:23:16 -04:00
function dismissSearch() {
2020-09-30 12:41:23 -04:00
setTimeout(function () {
if (!searchInput.is(':focus')) {
searchFields.addClass('hidden');
searchButton.removeClass('hidden');
}
}, 200);
2015-07-21 11:23:16 -04:00
}
searchButton.off('click').on('click', function (e) {
2018-05-28 11:29:37 -04:00
if (!config.loggedIn && !app.user.privileges['search:content']) {
2015-07-21 11:23:16 -04:00
app.alert({
2017-02-18 01:27:46 -07:00
message: '[[error:search-requires-login]]',
2017-02-17 19:31:21 -07:00
timeout: 3000,
2015-07-21 11:23:16 -04:00
});
ajaxify.go('login');
return false;
}
e.stopPropagation();
app.prepareSearch();
return false;
});
$('#search-form').off('submit').on('submit', function () {
const input = $(this).find('input');
require(['search'], function (search) {
const data = search.getSearchPreferences();
2016-08-17 12:40:14 +03:00
data.term = input.val();
hooks.fire('action:search.submit', {
2020-06-10 16:56:05 -04:00
searchOptions: data,
2020-06-10 15:11:57 -04:00
searchElements: searchElements,
});
search.query(data, function () {
2015-07-21 11:23:16 -04:00
input.val('');
});
});
return false;
});
};
app.prepareSearch = function () {
2017-02-18 01:56:23 -07:00
$('#search-fields').removeClass('hidden');
$('#search-button').addClass('hidden');
2015-07-21 11:23:16 -04:00
$('#search-fields input').focus();
};
function handleStatusChange() {
$('[component="header/usercontrol"] [data-status]').off('click').on('click', function (e) {
const status = $(this).attr('data-status');
socket.emit('user.setStatus', status, function (err) {
if (err) {
2015-07-21 11:23:16 -04:00
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;
2015-07-21 11:23:16 -04:00
});
e.preventDefault();
});
}
app.updateUserStatus = function (el, status) {
2015-07-21 11:23:16 -04:00
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);
});
2015-07-21 11:23:16 -04:00
});
};
2016-09-08 14:01:20 +03:00
app.newTopic = function (cid, tags) {
hooks.fire('action:composer.topic.new', {
2016-09-08 14:01:20 +03:00
cid: cid || ajaxify.data.cid || 0,
2017-02-17 19:31:21 -07:00
tags: tags || (ajaxify.data.tag ? [ajaxify.data.tag] : []),
});
};
2015-07-21 11:23:16 -04:00
app.loadJQueryUI = function (callback) {
2015-07-21 11:23:16 -04:00
if (typeof $().autocomplete === 'function') {
return callback();
}
require([
'jquery-ui/widgets/datepicker',
'jquery-ui/widgets/autocomplete',
'jquery-ui/widgets/sortable',
'jquery-ui/widgets/resizable',
'jquery-ui/widgets/draggable',
], function () {
callback();
});
2015-07-21 11:23:16 -04:00
};
app.parseAndTranslate = function (template, blockName, data, callback) {
if (typeof blockName !== 'string') {
callback = data;
data = blockName;
blockName = undefined;
}
return new Promise((resolve, reject) => {
require(['translator', 'benchpress'], function (translator, Benchpress) {
Benchpress.render(template, data, blockName)
.then(rendered => translator.translate(rendered))
.then(translated => translator.unescape(translated))
.then(resolve, reject);
});
}).then((html) => {
html = $(html);
if (callback && typeof callback === 'function') {
setTimeout(callback, 0, html);
}
return html;
});
};
2020-09-28 17:46:43 -04:00
function registerServiceWorker() {
// Do not register for Safari browsers
if (!ajaxify.data._locals.useragent.isSafari && 'serviceWorker' in navigator) {
navigator.serviceWorker.register(config.relative_path + '/service-worker.js', { scope: config.relative_path + '/' })
2020-09-28 17:46:43 -04:00
.then(function () {
console.info('ServiceWorker registration succeeded.');
2020-09-28 17:46:43 -04:00
}).catch(function (err) {
console.info('ServiceWorker registration failed: ', err);
2020-09-28 17:46:43 -04:00
});
}
}
2015-07-21 11:23:16 -04:00
}());