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.

602 lines
15 KiB
JavaScript

var socket,
config,
11 years ago
app = {
"username": null,
"uid": null,
"isFocused": true,
"currentRoom": null
11 years ago
};
(function () {
var showWelcomeMessage = false;
var body = $('body');
app.loadConfig = function() {
$.ajax({
url: RELATIVE_PATH + '/api/config',
success: function (data) {
config = data;
if(socket) {
socket.disconnect();
setTimeout(function() {
socket.socket.connect();
}, 200);
} else {
var max_reconnection_attemps = 5;
var reconnection_delay = 200;
socket = io.connect('', {
'max reconnection attempts': max_reconnection_attemps,
'reconnection delay': reconnection_delay
});
var reconnecting = false,
reconnectEl, reconnectTimer;
socket.on('event:connect', function (data) {
app.username = data.username;
11 years ago
app.uid = data.uid;
app.isAdmin = data.isAdmin;
11 years ago
app.showLoginMessage();
socket.emit('meta.updateHeader', {
fields: ['username', 'picture', 'userslug']
}, app.updateHeader);
body.trigger('action:connected');
});
12 years ago
socket.on('event:alert', function (data) {
app.alert(data);
});
socket.on('connect', function (data) {
if (reconnecting) {
reconnectEl.tooltip('destroy');
reconnectEl.html('<i class="fa fa-check"></i>');
reconnecting = false;
// Rejoin room that was left when we disconnected
var url_parts = document.location.pathname.slice(RELATIVE_PATH.length).split('/').slice(1),
room;
switch(url_parts[0]) {
case 'user':
room = 'user/' + templates.get('theirid');
case 'topic':
room = 'topic_' + url_parts[1];
break;
case 'category':
room = 'category_' + url_parts[1];
break;
case 'recent': // intentional fall-through
case 'unread':
room = 'recent_posts';
break;
case 'admin':
room = 'admin';
break;
default:
room = 'global';
break;
}
app.enterRoom(room, true);
socket.emit('meta.reconnected');
body.trigger('action:reconnected');
11 years ago
setTimeout(function() {
reconnectEl.removeClass('active').addClass("hide");
}, 3000);
}
socket.emit('meta.updateHeader', {
fields: ['username', 'picture', 'userslug']
}, app.updateHeader);
});
socket.on('event:disconnect', function() {
body.trigger('action:disconnected');
socket.socket.connect();
});
socket.on('reconnecting', function (data, attempt) {
if(attempt == max_reconnection_attemps) {
socket.socket.reconnectionAttempts = 0;
socket.socket.reconnectionDelay = reconnection_delay;
return;
}
if (!reconnectEl) reconnectEl = $('#reconnect');
reconnecting = true;
if (!reconnectEl.hasClass('active')) reconnectEl.html('<i class="fa fa-spinner fa-spin"></i>');
reconnectEl.addClass('active').removeClass("hide");
reconnectEl.tooltip({
placement: 'bottom'
});
});
11 years ago
socket.on('event:banned', function() {
app.alert({
title: '[[global:alert.banned]]',
message: '[[global:alert.banned.message]]',
11 years ago
type: 'warning',
timeout: 1000
});
setTimeout(app.logout, 1000);
});
socket.on('meta.updateHeader', app.updateHeader);
app.enterRoom('global');
11 years ago
if (config.environment === 'development' && console && console.log) {
var log = console.log;
console.log = function() {
log.apply(this, arguments);
socket.emit('tools.log', arguments);
}
}
}
},
async: false
});
};
11 years ago
app.logout = function() {
$.post(RELATIVE_PATH + '/logout', {
_csrf: $('#csrf_token').val()
}, function() {
11 years ago
window.location.href = RELATIVE_PATH + '/';
11 years ago
});
};
11 years ago
// takes a string like 1000 and returns 1,000
app.addCommas = function (text) {
12 years ago
return text.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
};
// use unique alert_id to have multiple alerts visible at a time, use the same alert_id to fade out the current instance
// type : error, success, info, warning/notify
// title = bolded title text
// message = alert message content
// timeout default = permanent
// location : alert_window (default) or content
app.alert = function (params) {
var alert_id = 'alert_button_' + ((params.alert_id) ? params.alert_id : new Date().getTime());
12 years ago
var alert = $('#' + alert_id);
var title = params.title || '';
12 years ago
function startTimeout(div, timeout) {
var timeoutId = setTimeout(function () {
$(div).fadeOut(1000, function () {
$(this).remove();
12 years ago
});
}, timeout);
12 years ago
$(div).attr('timeoutId', timeoutId);
}
12 years ago
if (alert.length > 0) {
alert.find('strong').html(title);
alert.find('p').html(params.message);
11 years ago
alert.attr('class', "alert alert-dismissable alert-" + params.type);
12 years ago
clearTimeout(alert.attr('timeoutId'));
startTimeout(alert, params.timeout);
12 years ago
} else {
11 years ago
var div = $('<div id="' + alert_id + '" class="alert alert-dismissable alert-' + params.type +'"></div>'),
button = $('<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>'),
strong = $('<strong>' + title + '</strong>'),
p = $('<p>' + params.message + '</p>');
div.append(button)
.append(strong)
.append(p);
button.on('click', function () {
div.remove();
});
if (params.location == null)
params.location = 'alert_window';
translator.translate(div.html(), function(translatedHTML) {
div.html(translatedHTML);
$('#' + params.location).prepend(div.fadeIn('100'));
});
if (params.timeout) {
12 years ago
startTimeout(div, params.timeout);
}
if (params.clickfn) {
div.on('click', function () {
params.clickfn();
div.fadeOut(500, function () {
$(this).remove();
});
});
}
}
};
app.alertSuccess = function (message, timeout) {
12 years ago
if (!timeout)
timeout = 2000;
app.alert({
title: '[[global:alert.success]]',
message: message,
type: 'success',
timeout: timeout
});
};
app.alertError = function (message, timeout) {
12 years ago
if (!timeout)
timeout = 2000;
app.alert({
title: '[[global:alert.error]]',
message: message,
type: 'danger',
timeout: timeout
});
};
12 years ago
app.enterRoom = function (room, force) {
12 years ago
if (socket) {
if (app.currentRoom === room && !force) {
return;
}
socket.emit('meta.rooms.enter', {
'enter': room,
'leave': app.currentRoom
});
app.currentRoom = room;
}
};
app.populateOnlineUsers = function () {
var uids = [];
jQuery('.post-row').each(function () {
11 years ago
var uid = $(this).attr('data-uid');
if(uids.indexOf(uid) === -1) {
uids.push(uid);
}
});
11 years ago
socket.emit('user.getOnlineUsers', uids, function (err, users) {
jQuery('.username-field').each(function (index, element) {
var el = jQuery(this),
uid = el.parents('li').attr('data-uid');
if (uid && users[uid]) {
el.siblings('i').attr('class', 'fa fa-circle status ' + users[uid].status)
}
});
});
};
function highlightNavigationLink() {
var path = window.location.pathname,
parts = path.split('/'),
12 years ago
active = parts[parts.length - 1];
12 years ago
jQuery('#main-nav li').removeClass('active');
12 years ago
if (active) {
jQuery('#main-nav li a').each(function () {
12 years ago
var href = this.getAttribute('href');
12 years ago
if (active == "sort-posts" || active == "sort-reputation" || active == "search" || active == "latest" || active == "online")
12 years ago
active = 'users';
12 years ago
if (href && href.match(active)) {
12 years ago
jQuery(this.parentNode).addClass('active');
return false;
}
});
}
};
app.createUserTooltips = function() {
$('img[title].teaser-pic,img[title].user-img').each(function() {
$(this).tooltip({
placement: 'top',
title: $(this).attr('title')
});
});
};
app.makeNumbersHumanReadable = function(elements) {
elements.each(function() {
$(this).html(utils.makeNumberHumanReadable($(this).attr('title')));
11 years ago
});
};
11 years ago
app.processPage = function () {
app.populateOnlineUsers();
highlightNavigationLink();
12 years ago
12 years ago
$('span.timeago').timeago();
$('.post-content img').addClass('img-responsive');
11 years ago
11 years ago
app.makeNumbersHumanReadable($('.human-readable-number'));
12 years ago
app.createUserTooltips();
setTimeout(function () {
window.scrollTo(0, 1); // rehide address bar on mobile after page load completes.
}, 100);
};
app.showLoginMessage = function () {
function showAlert() {
12 years ago
app.alert({
type: 'success',
title: 'Welcome Back ' + app.username + '!',
message: 'You have successfully logged in!',
timeout: 5000
});
}
12 years ago
if (showWelcomeMessage) {
showWelcomeMessage = false;
12 years ago
if (document.readyState !== 'complete') {
$(document).ready(showAlert);
} else {
showAlert();
}
}
};
12 years ago
app.addCommasToNumbers = function () {
$('.formatted-number').each(function (index, element) {
12 years ago
$(element).html(app.addCommas($(element).html()));
});
};
12 years ago
app.openChat = function (username, touid) {
if (username === app.username) {
app.alert({
type: 'warning',
title: 'Invalid Chat',
message: "You can't chat with yourself!",
timeout: 5000
});
return;
}
if (!app.username) {
app.alert({
type: 'danger',
title: 'Not Logged In',
message: 'Please log in to chat with <strong>' + username + '</strong>',
timeout: 5000
});
return;
}
require(['chat'], function (chat) {
12 years ago
if (!chat.modalExists(touid)) {
chat.createModal(username, touid, loadAndCenter);
12 years ago
} else {
loadAndCenter(chat.getModal(touid));
}
function loadAndCenter(chatModal) {
chat.load(chatModal.attr('UUID'));
chat.center(chatModal);
12 years ago
}
});
};
app.scrollToTop = function () {
$('body,html').animate({
scrollTop: 0
});
};
app.scrollToBottom = function () {
$('body,html').animate({
scrollTop: $('html').height() - 100
});
};
app.enableInfiniteLoading = function(callback) {
$(window).off('scroll').on('scroll', function() {
var bottom = ($(document).height() - $(window).height()) * 0.9;
if ($(window).scrollTop() > bottom) {
callback();
}
});
}
var titleObj = {
active: false,
interval: undefined,
titles: []
};
11 years ago
app.alternatingTitle = function (title) {
if (typeof title !== 'string') {
return;
}
if (title.length > 0 && !app.isFocused) {
titleObj.titles[1] = title;
if (titleObj.interval) {
clearInterval(titleObj.interval);
}
titleObj.interval = setInterval(function() {
window.document.title = titleObj.titles[titleObj.titles.indexOf(window.document.title) ^ 1];
}, 2000);
} else {
if (titleObj.interval) {
clearInterval(titleObj.interval);
}
if (titleObj.titles[0]) {
window.document.title = titleObj.titles[0];
}
}
};
app.refreshTitle = function(url) {
if (!url) {
var a = document.createElement('a');
a.href = document.location;
url = a.pathname.slice(1);
}
11 years ago
socket.emit('meta.buildTitle', url, function(err, title, numNotifications) {
titleObj.titles[0] = (numNotifications > 0 ? '(' + numNotifications + ') ' : '') + title;
app.alternatingTitle('');
});
};
function updateOnlineStatus(uid) {
socket.emit('user.isOnline', uid, function(err, data) {
$('#logged-in-menu #user_label #user-profile-link>i').attr('class', 'fa fa-circle status ' + data.status);
});
}
11 years ago
app.updateHeader = function(err, data) {
$('#search-button').off().on('click', function(e) {
e.stopPropagation();
$('#search-fields').removeClass('hide').show();
$(this).hide();
$('#search-fields input').focus();
$('#search-form').on('submit', function() {
$('#search-fields').hide();
$('#search-button').show();
});
$('#search-fields input').on('blur', function() {
$('#search-fields').hide();
$('#search-button').show();
});
return false;
});
var loggedInMenu = $('#logged-in-menu'),
isLoggedIn = data.uid > 0,
allowGuestSearching = (data.config || {}).allowGuestSearching === '1';
if (isLoggedIn) {
$('.nodebb-loggedin').show();
$('.nodebb-loggedout').hide();
$('#logged-out-menu').addClass('hide');
$('#logged-in-menu').removeClass('hide');
$('#search-button').removeClass("hide").show();
var userLabel = loggedInMenu.find('#user_label');
if (userLabel.length) {
if (data.userslug) {
userLabel.find('#user-profile-link').attr('href', RELATIVE_PATH + '/user/' + data.userslug);
}
if (data.picture) {
userLabel.find('img').attr('src', data.picture);
}
if (data.username) {
userLabel.find('#user-profile-link>span').html(' ' + data.username);
}
$('#logout-link').on('click', app.logout);
}
updateOnlineStatus(data.uid);
} else {
if (allowGuestSearching) {
$('#search-button').removeClass("hide").show();
$('#mobile-search-button').removeClass("hide").show();
} else {
$('#search-button').addClass("hide").hide();
$('#mobile-search-button').addClass("hide").hide();
}
$('.nodebb-loggedin').hide();
$('.nodebb-loggedout').show();
$('#logged-out-menu').removeClass('hide');
$('#logged-in-menu').addClass('hide');
}
11 years ago
$('#main-nav a,#user-control-list a,#logged-out-menu li a,#logged-in-menu .visible-xs').off('click').on('click', function() {
if($('.navbar .navbar-collapse').hasClass('in')) {
$('.navbar-header button').click();
}
});
$('#user-control-list .user-status').off('click').on('click', function(e) {
socket.emit('user.setStatus', $(this).attr('data-status'), function(err, data) {
if(err) {
return app.alertError(err.message);
}
updateOnlineStatus(data.uid);
});
e.preventDefault();
});
};
jQuery('document').ready(function () {
$('#search-form').on('submit', function () {
var input = $(this).find('input');
ajaxify.go("search/" + input.val());
input.val('');
return false;
12 years ago
});
$(window).blur(function(){
app.isFocused = false;
});
$(window).focus(function(){
app.isFocused = true;
app.alternatingTitle('');
});
createHeaderTooltips();
templates.setGlobal('relative_path', RELATIVE_PATH);
templates.setGlobal('usePagination', config.usePagination);
templates.setGlobal('topicsPerPage', config.topicsPerPage);
templates.setGlobal('postsPerPage', config.postsPerPage);
});
function createHeaderTooltips() {
$('#header-menu li i[title]').each(function() {
11 years ago
$(this).parents('a').tooltip({
placement: 'bottom',
title: $(this).attr('title')
});
});
11 years ago
$('#user_dropdown').tooltip({
placement: 'bottom',
title: $('#user_dropdown').attr('title')
});
}
showWelcomeMessage = location.href.indexOf('loggedin') !== -1;
app.loadConfig();
app.alternatingTitle('');
12 years ago
}());