revamped client side scripts so that they are loaded using Require.js instead.

This commit is contained in:
Julian Lam
2013-10-03 15:04:25 -04:00
parent b49c7b8609
commit 038e04dee6
60 changed files with 2472 additions and 2431 deletions

View File

@@ -76,6 +76,9 @@ var ajaxify = {};
templates.flush();
templates.load_template(function () {
exec_body_scripts(content);
require(['forum/' + tpl_url], function(script) {
if (script) script.init();
});
if (callback) {
callback();

View File

@@ -1,85 +1,92 @@
(function() {
var yourid = templates.get('yourid'),
theirid = templates.get('theirid'),
isFollowing = templates.get('isFollowing');
define(['forum/accountheader'], function(header) {
var Account = {};
$(document).ready(function() {
var username = $('.account-username a').html();
app.enter_room('user/' + theirid);
Account.init = function() {
header.init();
app.addCommasToNumbers();
var yourid = templates.get('yourid'),
theirid = templates.get('theirid'),
isFollowing = templates.get('isFollowing');
var followBtn = $('#follow-btn');
var unfollowBtn = $('#unfollow-btn');
$(document).ready(function() {
var username = $('.account-username a').html();
app.enter_room('user/' + theirid);
if (yourid !== theirid) {
if (isFollowing) {
followBtn.hide();
unfollowBtn.show();
} else {
followBtn.show();
unfollowBtn.hide();
}
} else {
followBtn.hide();
unfollowBtn.hide();
}
app.addCommasToNumbers();
followBtn.on('click', function() {
socket.emit('api:user.follow', {
uid: theirid
}, function(success) {
if (success) {
var followBtn = $('#follow-btn');
var unfollowBtn = $('#unfollow-btn');
if (yourid !== theirid) {
if (isFollowing) {
followBtn.hide();
unfollowBtn.show();
app.alertSuccess('You are now following ' + username + '!');
} else {
app.alertError('There was an error following' + username + '!');
}
});
return false;
});
unfollowBtn.on('click', function() {
socket.emit('api:user.unfollow', {
uid: theirid
}, function(success) {
if (success) {
followBtn.show();
unfollowBtn.hide();
app.alertSuccess('You are no longer following ' + username + '!');
} else {
app.alertError('There was an error unfollowing ' + username + '!');
}
} else {
followBtn.hide();
unfollowBtn.hide();
}
followBtn.on('click', function() {
socket.emit('api:user.follow', {
uid: theirid
}, function(success) {
if (success) {
followBtn.hide();
unfollowBtn.show();
app.alertSuccess('You are now following ' + username + '!');
} else {
app.alertError('There was an error following' + username + '!');
}
});
return false;
});
return false;
});
$('.user-recent-posts .topic-row').on('click', function() {
ajaxify.go($(this).attr('topic-url'));
});
unfollowBtn.on('click', function() {
socket.emit('api:user.unfollow', {
uid: theirid
}, function(success) {
if (success) {
followBtn.show();
unfollowBtn.hide();
app.alertSuccess('You are no longer following ' + username + '!');
} else {
app.alertError('There was an error unfollowing ' + username + '!');
}
});
return false;
});
$('.user-recent-posts .topic-row').on('click', function() {
ajaxify.go($(this).attr('topic-url'));
});
socket.on('api:user.isOnline', Account.handleUserOnline);
socket.emit('api:user.isOnline', theirid, Account.handleUserOnline);
socket.on('event:new_post', function(data) {
var html = templates.prepare(templates['account'].blocks['posts']).parse(data);
$('.user-recent-posts').prepend(html);
});
});
};
Account.handleUserOnline = function(data) {
var onlineStatus = $('.account-online-status');
function handleUserOnline(data) {
if (data.online) {
onlineStatus.find('span span').text('online');
onlineStatus.find('i').attr('class', 'icon-circle');
} else {
onlineStatus.find('span span').text('offline');
onlineStatus.find('i').attr('class', 'icon-circle-blank');
}
if (data.online) {
onlineStatus.find('span span').text('online');
onlineStatus.find('i').attr('class', 'icon-circle');
} else {
onlineStatus.find('span span').text('offline');
onlineStatus.find('i').attr('class', 'icon-circle-blank');
}
};
socket.on('api:user.isOnline', handleUserOnline);
socket.emit('api:user.isOnline', theirid, handleUserOnline);
socket.on('event:new_post', function(data) {
var html = templates.prepare(templates['account'].blocks['posts']).parse(data);
$('.user-recent-posts').prepend(html);
});
});
}());
return Account;
});

View File

@@ -1,88 +1,258 @@
var gravatarPicture = templates.get('gravatarpicture');
var uploadedPicture = templates.get('uploadedpicture');
define(['forum/accountheader'], function(header) {
var AccountEdit = {};
$(document).ready(function() {
AccountEdit.init = function() {
header.init();
var gravatarPicture = templates.get('gravatarpicture');
var uploadedPicture = templates.get('uploadedpicture');
$('#uploadForm').submit(function() {
AccountEdit.status('uploading the file ...');
$('#uploadForm').submit(function() {
status('uploading the file ...');
$('#upload-progress-bar').css('width', '0%');
$('#upload-progress-box').show();
$('#upload-progress-box').removeClass('hide');
$('#upload-progress-bar').css('width', '0%');
$('#upload-progress-box').show();
$('#upload-progress-box').removeClass('hide');
if (!$('#userPhotoInput').val()) {
error('select an image to upload!');
return false;
}
$(this).find('#imageUploadCsrf').val($('#csrf_token').val());
$(this).ajaxSubmit({
error: function(xhr) {
error('Error: ' + xhr.status);
},
uploadProgress: function(event, position, total, percent) {
console.log(percent);
$('#upload-progress-bar').css('width', percent + '%');
},
success: function(response) {
if (response.error) {
error(response.error);
return;
}
var imageUrlOnServer = response.path;
$('#user-current-picture').attr('src', imageUrlOnServer);
$('#user-uploaded-picture').attr('src', imageUrlOnServer);
uploadedPicture = imageUrlOnServer;
setTimeout(function() {
hideAlerts();
$('#upload-picture-modal').modal('hide');
}, 750);
socket.emit('api:updateHeader', {
fields: ['username', 'picture', 'userslug']
});
success('File uploaded successfully!');
if (!$('#userPhotoInput').val()) {
AccountEdit.error('select an image to upload!');
return false;
}
$(this).find('#imageUploadCsrf').val($('#csrf_token').val());
$(this).ajaxSubmit({
error: function(xhr) {
AccountEdit.error('Error: ' + xhr.status);
},
uploadProgress: function(event, position, total, percent) {
console.log(percent);
$('#upload-progress-bar').css('width', percent + '%');
},
success: function(response) {
if (response.error) {
AccountEdit.error(response.error);
return;
}
var imageUrlOnServer = response.path;
$('#user-current-picture').attr('src', imageUrlOnServer);
$('#user-uploaded-picture').attr('src', imageUrlOnServer);
uploadedPicture = imageUrlOnServer;
setTimeout(function() {
AccountEdit.hideAlerts();
$('#upload-picture-modal').modal('hide');
}, 750);
socket.emit('api:updateHeader', {
fields: ['username', 'picture', 'userslug']
});
AccountEdit.success('File uploaded successfully!');
}
});
return false;
});
return false;
});
var selectedImageType = '';
function hideAlerts() {
$('#submitBtn').on('click', function() {
var userData = {
uid: $('#inputUID').val(),
email: $('#inputEmail').val(),
fullname: $('#inputFullname').val(),
website: $('#inputWebsite').val(),
birthday: $('#inputBirthday').val(),
location: $('#inputLocation').val(),
signature: $('#inputSignature').val()
};
socket.emit('api:user.updateProfile', userData, function(err, data) {
if (data.success) {
app.alertSuccess('Your profile has been updated successfully!');
if (data.picture) {
$('#user-current-picture').attr('src', data.picture);
$('#user_label img').attr('src', data.picture);
}
if (data.gravatarpicture) {
$('#user-gravatar-picture').attr('src', data.gravatarpicture);
gravatarPicture = data.gravatarpicture;
}
} else {
app.alertError('There was an error updating your profile! ' + err.error);
}
});
return false;
});
$('#changePictureBtn').on('click', function() {
selectedImageType = '';
AccountEdit.updateImages();
$('#change-picture-modal').modal('show');
$('#change-picture-modal').removeClass('hide');
return false;
});
$('#gravatar-box').on('click', function() {
$('#gravatar-box .icon-ok').show();
$('#uploaded-box .icon-ok').hide();
selectedImageType = 'gravatar';
});
$('#uploaded-box').on('click', function() {
$('#gravatar-box .icon-ok').hide();
$('#uploaded-box .icon-ok').show();
selectedImageType = 'uploaded';
});
$('#savePictureChangesBtn').on('click', function() {
$('#change-picture-modal').modal('hide');
if (selectedImageType) {
AccountEdit.changeUserPicture(selectedImageType);
if (selectedImageType == 'gravatar')
$('#user-current-picture').attr('src', gravatarPicture);
else if (selectedImageType == 'uploaded')
$('#user-current-picture').attr('src', uploadedPicture);
}
});
$('#upload-picture-modal').on('hide', function() {
$('#userPhotoInput').val('');
});
$('#uploadPictureBtn').on('click', function() {
$('#change-picture-modal').modal('hide');
$('#upload-picture-modal').modal('show');
$('#upload-picture-modal').removeClass('hide');
AccountEdit.hideAlerts();
return false;
});
$('#pictureUploadSubmitBtn').on('click', function() {
$('#uploadForm').submit();
});
(function handlePasswordChange() {
var currentPassword = $('#inputCurrentPassword');
var password_notify = $('#password-notify');
var password_confirm_notify = $('#password-confirm-notify');
var password = $('#inputNewPassword');
var password_confirm = $('#inputNewPasswordAgain');
var passwordvalid = false;
var passwordsmatch = false;
function onPasswordChanged() {
passwordvalid = utils.isPasswordValid(password.val());
if (password.val().length < config.minimumPasswordLength) {
password_notify.html('Password too short');
password_notify.attr('class', 'alert alert-danger');
password_notify.removeClass('hide');
} else if (!passwordvalid) {
password_notify.html('Invalid password');
password_notify.attr('class', 'alert alert-danger');
password_notify.removeClass('hide');
} else {
password_notify.html('OK!');
password_notify.attr('class', 'alert alert-success');
password_notify.removeClass('hide');
}
onPasswordConfirmChanged();
}
function onPasswordConfirmChanged() {
if (password_notify.hasClass('alert-danger') || !password_confirm.val()) {
password_confirm_notify.addClass('hide');
return;
}
if (password.val() !== password_confirm.val()) {
password_confirm_notify.html('Passwords must match!');
password_confirm_notify.attr('class', 'alert alert-danger');
password_confirm_notify.removeClass('hide');
passwordsmatch = false;
} else {
password_confirm_notify.html('OK!');
password_confirm_notify.attr('class', 'alert alert-success');
password_confirm_notify.removeClass('hide');
passwordsmatch = true;
}
}
password.on('blur', onPasswordChanged);
password_confirm.on('blur', onPasswordConfirmChanged);
$('#changePasswordBtn').on('click', function() {
if (passwordvalid && passwordsmatch && currentPassword.val()) {
socket.emit('api:user.changePassword', {
'currentPassword': currentPassword.val(),
'newPassword': password.val()
}, function(err) {
currentPassword.val('');
password.val('');
password_confirm.val('');
password_notify.addClass('hide');
password_confirm_notify.addClass('hide');
passwordsmatch = false;
passwordvalid = false;
if (err) {
app.alertError(err.error);
return;
}
app.alertSuccess('Your password is updated!');
});
}
return false;
});
}());
};
AccountEdit.hideAlerts = function() {
$('#alert-status').addClass('hide');
$('#alert-success').addClass('hide');
$('#alert-error').addClass('hide');
$('#upload-progress-box').addClass('hide');
}
function status(message) {
hideAlerts();
AccountEdit.status = function(message) {
AccountEdit.hideAlerts();
$('#alert-status').text(message).removeClass('hide');
}
function success(message) {
hideAlerts();
AccountEdit.success = function(message) {
AccountEdit.hideAlerts();
$('#alert-success').text(message).removeClass('hide');
}
function error(message) {
hideAlerts();
AccountEdit.error = function(message) {
AccountEdit.hideAlerts();
$('#alert-error').text(message).removeClass('hide');
}
function changeUserPicture(type) {
AccountEdit.changeUserPicture = function(type) {
var userData = {
type: type
};
@@ -94,40 +264,10 @@ $(document).ready(function() {
});
}
var selectedImageType = '';
$('#submitBtn').on('click', function() {
var userData = {
uid: $('#inputUID').val(),
email: $('#inputEmail').val(),
fullname: $('#inputFullname').val(),
website: $('#inputWebsite').val(),
birthday: $('#inputBirthday').val(),
location: $('#inputLocation').val(),
signature: $('#inputSignature').val()
};
socket.emit('api:user.updateProfile', userData, function(err, data) {
if (data.success) {
app.alertSuccess('Your profile has been updated successfully!');
if (data.picture) {
$('#user-current-picture').attr('src', data.picture);
$('#user_label img').attr('src', data.picture);
}
if (data.gravatarpicture) {
$('#user-gravatar-picture').attr('src', data.gravatarpicture);
gravatarPicture = data.gravatarpicture;
}
} else {
app.alertError('There was an error updating your profile! ' + err.error);
}
});
return false;
});
function updateImages() {
AccountEdit.updateImages = function() {
var currentPicture = $('#user-current-picture').attr('src');
var gravatarPicture = templates.get('gravatarpicture');
var uploadedPicture = templates.get('uploadedpicture');
if (gravatarPicture) {
$('#user-gravatar-picture').attr('src', gravatarPicture);
@@ -153,139 +293,5 @@ $(document).ready(function() {
$('#uploaded-box .icon-ok').hide();
}
$('#changePictureBtn').on('click', function() {
selectedImageType = '';
updateImages();
$('#change-picture-modal').modal('show');
$('#change-picture-modal').removeClass('hide');
return false;
});
$('#gravatar-box').on('click', function() {
$('#gravatar-box .icon-ok').show();
$('#uploaded-box .icon-ok').hide();
selectedImageType = 'gravatar';
});
$('#uploaded-box').on('click', function() {
$('#gravatar-box .icon-ok').hide();
$('#uploaded-box .icon-ok').show();
selectedImageType = 'uploaded';
});
$('#savePictureChangesBtn').on('click', function() {
$('#change-picture-modal').modal('hide');
if (selectedImageType) {
changeUserPicture(selectedImageType);
if (selectedImageType == 'gravatar')
$('#user-current-picture').attr('src', gravatarPicture);
else if (selectedImageType == 'uploaded')
$('#user-current-picture').attr('src', uploadedPicture);
}
});
$('#upload-picture-modal').on('hide', function() {
$('#userPhotoInput').val('');
});
$('#uploadPictureBtn').on('click', function() {
$('#change-picture-modal').modal('hide');
$('#upload-picture-modal').modal('show');
$('#upload-picture-modal').removeClass('hide');
hideAlerts();
return false;
});
$('#pictureUploadSubmitBtn').on('click', function() {
$('#uploadForm').submit();
});
(function handlePasswordChange() {
var currentPassword = $('#inputCurrentPassword');
var password_notify = $('#password-notify');
var password_confirm_notify = $('#password-confirm-notify');
var password = $('#inputNewPassword');
var password_confirm = $('#inputNewPasswordAgain');
var passwordvalid = false;
var passwordsmatch = false;
function onPasswordChanged() {
passwordvalid = utils.isPasswordValid(password.val());
if (password.val().length < config.minimumPasswordLength) {
password_notify.html('Password too short');
password_notify.attr('class', 'alert alert-danger');
password_notify.removeClass('hide');
} else if (!passwordvalid) {
password_notify.html('Invalid password');
password_notify.attr('class', 'alert alert-danger');
password_notify.removeClass('hide');
} else {
password_notify.html('OK!');
password_notify.attr('class', 'alert alert-success');
password_notify.removeClass('hide');
}
onPasswordConfirmChanged();
}
function onPasswordConfirmChanged() {
if (password_notify.hasClass('alert-danger') || !password_confirm.val()) {
password_confirm_notify.addClass('hide');
return;
}
if (password.val() !== password_confirm.val()) {
password_confirm_notify.html('Passwords must match!');
password_confirm_notify.attr('class', 'alert alert-danger');
password_confirm_notify.removeClass('hide');
passwordsmatch = false;
} else {
password_confirm_notify.html('OK!');
password_confirm_notify.attr('class', 'alert alert-success');
password_confirm_notify.removeClass('hide');
passwordsmatch = true;
}
}
password.on('blur', onPasswordChanged);
password_confirm.on('blur', onPasswordConfirmChanged);
$('#changePasswordBtn').on('click', function() {
if (passwordvalid && passwordsmatch && currentPassword.val()) {
socket.emit('api:user.changePassword', {
'currentPassword': currentPassword.val(),
'newPassword': password.val()
}, function(err) {
currentPassword.val('');
password.val('');
password_confirm.val('');
password_notify.addClass('hide');
password_confirm_notify.addClass('hide');
passwordsmatch = false;
passwordvalid = false;
if (err) {
app.alertError(err.error);
return;
}
app.alertSuccess('Your password is updated!');
});
}
return false;
});
}());
return AccountEdit;
});

View File

@@ -1,24 +1,11 @@
(function() {
var yourid = templates.get('yourid'),
theirid = templates.get('theirid');
define(function() {
var AccountHeader = {};
AccountHeader.init = function() {
var yourid = templates.get('yourid'),
theirid = templates.get('theirid');
function createMenu() {
var userslug = $('.account-username-box').attr('data-userslug');
var links = $('<div class="account-sub-links inline-block pull-right">\
<span id="settingsLink" class="pull-right"><a href="/user/' + userslug + '/settings">settings</a></span>\
<span id="favouritesLink" class="pull-right"><a href="/user/' + userslug + '/favourites">favourites</a></span>\
<span class="pull-right"><a href="/user/' + userslug + '/followers">followers</a></span>\
<span class="pull-right"><a href="/user/' + userslug + '/following">following</a></span>\
<span id="editLink" class="pull-right"><a href="/user/' + userslug + '/edit">edit</a></span>\
</div>');
$('.account-username-box').append(links);
}
$(document).ready(function() {
createMenu();
AccountHeader.createMenu();
var editLink = $('#editLink');
var settingsLink = $('#settingsLink');
@@ -37,6 +24,20 @@
return false;
}
});
});
}
}());
AccountHeader.createMenu = function() {
var userslug = $('.account-username-box').attr('data-userslug');
var links = $('<div class="account-sub-links inline-block pull-right">\
<span id="settingsLink" class="pull-right"><a href="/user/' + userslug + '/settings">settings</a></span>\
<span id="favouritesLink" class="pull-right"><a href="/user/' + userslug + '/favourites">favourites</a></span>\
<span class="pull-right"><a href="/user/' + userslug + '/followers">followers</a></span>\
<span class="pull-right"><a href="/user/' + userslug + '/following">following</a></span>\
<span id="editLink" class="pull-right"><a href="/user/' + userslug + '/edit">edit</a></span>\
</div>');
$('.account-username-box').append(links);
}
return AccountHeader;
});

View File

@@ -1,19 +1,25 @@
$(document).ready(function() {
define(['forum/accountheader'], function(header) {
var AccountSettings = {};
$('#submitBtn').on('click', function() {
AccountSettings.init = function() {
header.init();
var settings = {
showemail: $('#showemailCheckBox').is(':checked') ? 1 : 0
};
$('#submitBtn').on('click', function() {
socket.emit('api:user.saveSettings', settings, function(success) {
if (success) {
app.alertSuccess('Settings saved!');
} else {
app.alertError('There was an error saving settings!');
}
var settings = {
showemail: $('#showemailCheckBox').is(':checked') ? 1 : 0
};
socket.emit('api:user.saveSettings', settings, function(success) {
if (success) {
app.alertSuccess('Settings saved!');
} else {
app.alertError('There was an error saving settings!');
}
});
return false;
});
return false;
});
};
});
return AccountSettings;
});

View File

@@ -1,139 +1,144 @@
var modified_categories = {};
define(function() {
var Categories = {};
function modified(el) {
var cid = $(el).parents('li').attr('data-cid');
Categories.init = function() {
var modified_categories = {};
modified_categories[cid] = modified_categories[cid] || {};
modified_categories[cid][$(el).attr('data-name')] = $(el).val();
}
function modified(el) {
var cid = $(el).parents('li').attr('data-cid');
function save() {
socket.emit('api:admin.categories.update', modified_categories);
modified_categories = {};
}
function select_icon(el) {
var selected = el.attr('class').replace(' icon-2x', '');
jQuery('#icons .selected').removeClass('selected');
if (selected)
jQuery('#icons .' + selected).parent().addClass('selected');
bootbox.confirm('<h2>Select an icon.</h2>' + document.getElementById('icons').innerHTML, function(confirm) {
if (confirm) {
var iconClass = jQuery('.bootbox .selected').children(':first').attr('class');
el.attr('class', iconClass + ' icon-2x');
el.val(iconClass);
modified(el);
}
});
setTimeout(function() { //bootbox was rewritten for BS3 and I had to add this timeout for the previous code to work. TODO: to look into
jQuery('.bootbox .col-md-3').on('click', function() {
jQuery('.bootbox .selected').removeClass('selected');
jQuery(this).addClass('selected');
});
}, 500);
}
function update_blockclass(el) {
el.parentNode.parentNode.className = 'entry-row ' + el.value;
}
jQuery('#entry-container').sortable();
jQuery('.blockclass').each(function() {
jQuery(this).val(this.getAttribute('data-value'));
});
//DRY Failure. this needs to go into an ajaxify onready style fn. Currently is copy pasted into every single function so after ACP is off the ground fix asap
(function() {
function showCreateCategoryModal() {
$('#new-category-modal').modal();
}
function createNewCategory() {
var category = {
name: $('#inputName').val(),
description: $('#inputDescription').val(),
icon: $('#new-category-modal i').attr('value'),
blockclass: $('#inputBlockclass').val()
};
socket.emit('api:admin.categories.create', category, function(err, data) {
if (!err) {
app.alert({
alert_id: 'category_created',
title: 'Created',
message: 'Category successfully created!',
type: 'success',
timeout: 2000
});
var html = templates.prepare(templates['admin/categories'].blocks['categories']).parse({
categories: [data]
});
$('#entry-container').append(html);
$('#new-category-modal').modal('hide');
}
});
}
jQuery('document').ready(function() {
var url = window.location.href,
parts = url.split('/'),
active = parts[parts.length - 1];
jQuery('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) {
jQuery(this.parentNode).addClass('active');
return false;
}
});
jQuery('#save').on('click', save);
jQuery('#addNew').on('click', showCreateCategoryModal);
jQuery('#create-category-btn').on('click', createNewCategory);
jQuery('#entry-container').on('click', '.icon', function(ev) {
select_icon($(this).find('i'));
});
jQuery('.blockclass').on('change', function(ev) {
update_blockclass(ev.target);
});
jQuery('.category_name, .category_description, .blockclass').on('change', function(ev) {
modified(ev.target);
});
jQuery('.entry-row button').each(function(index, element) {
var disabled = $(element).attr('data-disabled');
if (disabled == "0" || disabled == "")
$(element).html('Disable');
else
$(element).html('Enable');
});
jQuery('.entry-row button').on('click', function(ev) {
var btn = jQuery(this);
var categoryRow = btn.parents('li');
var cid = categoryRow.attr('data-cid');
var disabled = btn.html() == "Disable" ? "1" : "0";
categoryRow.remove();
modified_categories[cid] = modified_categories[cid] || {};
modified_categories[cid]['disabled'] = disabled;
modified_categories[cid][$(el).attr('data-name')] = $(el).val();
}
save();
return false;
function save() {
socket.emit('api:admin.categories.update', modified_categories);
modified_categories = {};
}
function select_icon(el) {
var selected = el.attr('class').replace(' icon-2x', '');
jQuery('#icons .selected').removeClass('selected');
if (selected)
jQuery('#icons .' + selected).parent().addClass('selected');
bootbox.confirm('<h2>Select an icon.</h2>' + document.getElementById('icons').innerHTML, function(confirm) {
if (confirm) {
var iconClass = jQuery('.bootbox .selected').children(':first').attr('class');
el.attr('class', iconClass + ' icon-2x');
el.val(iconClass);
modified(el);
}
});
setTimeout(function() { //bootbox was rewritten for BS3 and I had to add this timeout for the previous code to work. TODO: to look into
jQuery('.bootbox .col-md-3').on('click', function() {
jQuery('.bootbox .selected').removeClass('selected');
jQuery(this).addClass('selected');
});
}, 500);
}
function update_blockclass(el) {
el.parentNode.parentNode.className = 'entry-row ' + el.value;
}
jQuery('#entry-container').sortable();
jQuery('.blockclass').each(function() {
jQuery(this).val(this.getAttribute('data-value'));
});
});
}());
//DRY Failure. this needs to go into an ajaxify onready style fn. Currently is copy pasted into every single function so after ACP is off the ground fix asap
function showCreateCategoryModal() {
$('#new-category-modal').modal();
}
function createNewCategory() {
var category = {
name: $('#inputName').val(),
description: $('#inputDescription').val(),
icon: $('#new-category-modal i').attr('value'),
blockclass: $('#inputBlockclass').val()
};
socket.emit('api:admin.categories.create', category, function(err, data) {
if (!err) {
app.alert({
alert_id: 'category_created',
title: 'Created',
message: 'Category successfully created!',
type: 'success',
timeout: 2000
});
var html = templates.prepare(templates['admin/categories'].blocks['categories']).parse({
categories: [data]
});
$('#entry-container').append(html);
$('#new-category-modal').modal('hide');
}
});
}
jQuery('document').ready(function() {
var url = window.location.href,
parts = url.split('/'),
active = parts[parts.length - 1];
jQuery('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) {
jQuery(this.parentNode).addClass('active');
return false;
}
});
jQuery('#save').on('click', save);
jQuery('#addNew').on('click', showCreateCategoryModal);
jQuery('#create-category-btn').on('click', createNewCategory);
jQuery('#entry-container').on('click', '.icon', function(ev) {
select_icon($(this).find('i'));
});
jQuery('.blockclass').on('change', function(ev) {
update_blockclass(ev.target);
});
jQuery('.category_name, .category_description, .blockclass').on('change', function(ev) {
modified(ev.target);
});
jQuery('.entry-row button').each(function(index, element) {
var disabled = $(element).attr('data-disabled');
if (disabled == "0" || disabled == "")
$(element).html('Disable');
else
$(element).html('Enable');
});
jQuery('.entry-row button').on('click', function(ev) {
var btn = jQuery(this);
var categoryRow = btn.parents('li');
var cid = categoryRow.attr('data-cid');
var disabled = btn.html() == "Disable" ? "1" : "0";
categoryRow.remove();
modified_categories[cid] = modified_categories[cid] || {};
modified_categories[cid]['disabled'] = disabled;
save();
return false;
});
});
};
return Categories;
});

View File

@@ -1,121 +1,44 @@
var nodebb_admin = (function(nodebb_admin) {
jQuery('document').ready(function() {
// On menu click, change "active" state
var menuEl = document.querySelector('.sidebar-nav'),
liEls = menuEl.querySelectorAll('li')
parentEl = null;
nodebb_admin.config = undefined;
nodebb_admin.prepare = function() {
// Come back in 500ms if the config isn't ready yet
if (nodebb_admin.config === undefined) {
setTimeout(function() {
nodebb_admin.prepare();
}, 500);
return;
}
// Populate the fields on the page from the config
var fields = document.querySelectorAll('#content [data-field]'),
numFields = fields.length,
saveBtn = document.getElementById('save'),
x, key, inputType;
for (x = 0; x < numFields; x++) {
key = fields[x].getAttribute('data-field');
inputType = fields[x].getAttribute('type');
if (fields[x].nodeName === 'INPUT') {
if (nodebb_admin.config[key]) {
switch (inputType) {
case 'text':
case 'textarea':
case 'number':
fields[x].value = nodebb_admin.config[key];
break;
case 'checkbox':
fields[x].checked = nodebb_admin.config[key] === '1' ? true : false;
break;
}
}
} else if (fields[x].nodeName === 'TEXTAREA') {
if (nodebb_admin.config[key]) fields[x].value = nodebb_admin.config[key];
menuEl.addEventListener('click', function(e) {
parentEl = e.target.parentNode;
if (parentEl.nodeName === 'LI') {
for (var x = 0, numLis = liEls.length; x < numLis; x++) {
if (liEls[x] !== parentEl) jQuery(liEls[x]).removeClass('active');
else jQuery(parentEl).addClass('active');
}
}
}, false);
});
saveBtn.addEventListener('click', function(e) {
var key, value;
e.preventDefault();
socket.once('api:config.get', function(config) {
require(['forum/admin/settings'], function(Settings) {
Settings.config = config;
});
});
for (x = 0; x < numFields; x++) {
key = fields[x].getAttribute('data-field');
if (fields[x].nodeName === 'INPUT') {
inputType = fields[x].getAttribute('type');
switch (inputType) {
case 'text':
case 'number':
value = fields[x].value;
break;
socket.emit('api:config.get');
case 'checkbox':
value = fields[x].checked ? '1' : '0';
break;
}
} else if (fields[x].nodeName === 'TEXTAREA') {
value = fields[x].value;
}
socket.emit('api:config.set', {
key: key,
value: value
});
}
socket.on('api:config.set', function(data) {
if (data.status === 'ok') {
app.alert({
alert_id: 'config_status',
timeout: 2500,
title: 'Changes Saved',
message: 'Your changes to the NodeBB configuration have been saved.',
type: 'success'
});
} else {
app.alert({
alert_id: 'config_status',
timeout: 2500,
title: 'Changes Not Saved',
message: 'NodeBB encountered a problem saving your changes',
type: 'danger'
});
}
nodebb_admin.remove = function(key) {
socket.emit('api:config.remove', key);
}
jQuery('document').ready(function() {
// On menu click, change "active" state
var menuEl = document.querySelector('.sidebar-nav'),
liEls = menuEl.querySelectorAll('li')
parentEl = null;
menuEl.addEventListener('click', function(e) {
parentEl = e.target.parentNode;
if (parentEl.nodeName === 'LI') {
for (var x = 0, numLis = liEls.length; x < numLis; x++) {
if (liEls[x] !== parentEl) jQuery(liEls[x]).removeClass('active');
else jQuery(parentEl).addClass('active');
}
}
}, false);
});
socket.once('api:config.get', function(config) {
nodebb_admin.config = config;
});
socket.emit('api:config.get');
socket.on('api:config.set', function(data) {
if (data.status === 'ok') {
app.alert({
alert_id: 'config_status',
timeout: 2500,
title: 'Changes Saved',
message: 'Your changes to the NodeBB configuration have been saved.',
type: 'success'
});
} else {
app.alert({
alert_id: 'config_status',
timeout: 2500,
title: 'Changes Not Saved',
message: 'NodeBB encountered a problem saving your changes',
type: 'danger'
});
}
});
return nodebb_admin;
}(nodebb_admin || {}));
});

View File

@@ -1,194 +1,200 @@
$(document).ready(function() {
var createEl = document.getElementById('create'),
createModal = $('#create-modal'),
createSubmitBtn = document.getElementById('create-modal-go'),
createNameEl = $('#create-group-name'),
detailsModal = $('#group-details-modal'),
detailsSearch = detailsModal.find('#group-details-search'),
searchResults = detailsModal.find('#group-details-search-results'),
groupMembersEl = detailsModal.find('ul.current_members'),
detailsModalSave = detailsModal.find('.btn-primary'),
searchDelay = undefined,
listEl = $('#groups-list');
define(function() {
var Groups = {};
createEl.addEventListener('click', function() {
createModal.modal('show');
setTimeout(function() {
createNameEl.focus();
}, 250);
}, false);
Groups.init = function() {
var createEl = document.getElementById('create'),
createModal = $('#create-modal'),
createSubmitBtn = document.getElementById('create-modal-go'),
createNameEl = $('#create-group-name'),
detailsModal = $('#group-details-modal'),
detailsSearch = detailsModal.find('#group-details-search'),
searchResults = detailsModal.find('#group-details-search-results'),
groupMembersEl = detailsModal.find('ul.current_members'),
detailsModalSave = detailsModal.find('.btn-primary'),
searchDelay = undefined,
listEl = $('#groups-list');
createSubmitBtn.addEventListener('click', function() {
var submitObj = {
name: createNameEl.val(),
description: $('#create-group-desc').val()
},
errorEl = $('#create-modal-error'),
errorText;
createEl.addEventListener('click', function() {
createModal.modal('show');
setTimeout(function() {
createNameEl.focus();
}, 250);
}, false);
socket.emit('api:groups.create', submitObj, function(err, data) {
if (err) {
switch (err) {
case 'group-exists':
errorText = '<strong>Please choose another name</strong><p>There seems to be a group with this name already.</p>';
break;
case 'name-too-short':
errorText = '<strong>Please specify a grou name</strong><p>A group name is required for administrative purposes.</p>';
break;
default:
errorText = '<strong>Uh-Oh</strong><p>There was a problem creating your group. Please try again later!</p>';
break;
createSubmitBtn.addEventListener('click', function() {
var submitObj = {
name: createNameEl.val(),
description: $('#create-group-desc').val()
},
errorEl = $('#create-modal-error'),
errorText;
socket.emit('api:groups.create', submitObj, function(err, data) {
if (err) {
switch (err) {
case 'group-exists':
errorText = '<strong>Please choose another name</strong><p>There seems to be a group with this name already.</p>';
break;
case 'name-too-short':
errorText = '<strong>Please specify a grou name</strong><p>A group name is required for administrative purposes.</p>';
break;
default:
errorText = '<strong>Uh-Oh</strong><p>There was a problem creating your group. Please try again later!</p>';
break;
}
errorEl.html(errorText).removeClass('hide');
} else {
createModal.modal('hide');
errorEl.addClass('hide');
createNameEl.val('');
ajaxify.go('admin/groups');
}
});
});
errorEl.html(errorText).removeClass('hide');
} else {
createModal.modal('hide');
errorEl.addClass('hide');
createNameEl.val('');
ajaxify.go('admin/groups');
listEl.on('click', 'button[data-action]', function() {
var action = this.getAttribute('data-action'),
gid = $(this).parents('li[data-gid]').attr('data-gid');
switch (action) {
case 'delete':
bootbox.confirm('Are you sure you wish to delete this group?', function(confirm) {
if (confirm) {
socket.emit('api:groups.delete', gid, function(err, data) {
if (data === 'OK') ajaxify.go('admin/groups');
});
}
});
break;
case 'members':
socket.emit('api:groups.get', gid, function(err, groupObj) {
var formEl = detailsModal.find('form'),
nameEl = formEl.find('#change-group-name'),
descEl = formEl.find('#change-group-desc'),
memberIcon = document.createElement('li'),
numMembers = groupObj.members.length,
membersFrag = document.createDocumentFragment(),
memberIconImg, x;
nameEl.val(groupObj.name);
descEl.val(groupObj.description);
// Member list
memberIcon.innerHTML = '<img /><span></span>';
memberIconImg = memberIcon.querySelector('img');
memberIconLabel = memberIcon.querySelector('span');
if (numMembers > 0) {
for (x = 0; x < numMembers; x++) {
memberIconImg.src = groupObj.members[x].picture;
memberIconLabel.innerHTML = groupObj.members[x].username;
memberIcon.setAttribute('data-uid', groupObj.members[x].uid);
membersFrag.appendChild(memberIcon.cloneNode(true));
}
groupMembersEl.html('');
groupMembersEl[0].appendChild(membersFrag);
}
detailsModal.attr('data-gid', groupObj.gid);
detailsModal.modal('show');
});
break;
}
});
});
listEl.on('click', 'button[data-action]', function() {
var action = this.getAttribute('data-action'),
gid = $(this).parents('li[data-gid]').attr('data-gid');
detailsSearch.on('keyup', function() {
var searchEl = this;
switch (action) {
case 'delete':
bootbox.confirm('Are you sure you wish to delete this group?', function(confirm) {
if (confirm) {
socket.emit('api:groups.delete', gid, function(err, data) {
if (data === 'OK') ajaxify.go('admin/groups');
});
}
});
break;
case 'members':
socket.emit('api:groups.get', gid, function(err, groupObj) {
var formEl = detailsModal.find('form'),
nameEl = formEl.find('#change-group-name'),
descEl = formEl.find('#change-group-desc'),
memberIcon = document.createElement('li'),
numMembers = groupObj.members.length,
membersFrag = document.createDocumentFragment(),
memberIconImg, x;
if (searchDelay) clearTimeout(searchDelay);
searchDelay = setTimeout(function() {
var searchText = searchEl.value,
resultsEl = document.getElementById('group-details-search-results'),
foundUser = document.createElement('li'),
foundUserImg, foundUserLabel;
nameEl.val(groupObj.name);
descEl.val(groupObj.description);
foundUser.innerHTML = '<img /><span></span>';
foundUserImg = foundUser.getElementsByTagName('img')[0];
foundUserLabel = foundUser.getElementsByTagName('span')[0];
// Member list
memberIcon.innerHTML = '<img /><span></span>';
memberIconImg = memberIcon.querySelector('img');
memberIconLabel = memberIcon.querySelector('span');
if (numMembers > 0) {
for (x = 0; x < numMembers; x++) {
memberIconImg.src = groupObj.members[x].picture;
memberIconLabel.innerHTML = groupObj.members[x].username;
memberIcon.setAttribute('data-uid', groupObj.members[x].uid);
membersFrag.appendChild(memberIcon.cloneNode(true));
socket.emit('api:admin.user.search', searchText, function(err, results) {
if (!err && results && results.length > 0) {
var numResults = results.length,
resultsSlug = document.createDocumentFragment(),
x;
if (numResults > 4) numResults = 4;
for (x = 0; x < numResults; x++) {
foundUserImg.src = results[x].picture;
foundUserLabel.innerHTML = results[x].username;
foundUser.setAttribute('title', results[x].username);
foundUser.setAttribute('data-uid', results[x].uid);
resultsSlug.appendChild(foundUser.cloneNode(true));
}
groupMembersEl.html('');
groupMembersEl[0].appendChild(membersFrag);
}
detailsModal.attr('data-gid', groupObj.gid);
detailsModal.modal('show');
resultsEl.innerHTML = '';
resultsEl.appendChild(resultsSlug);
} else resultsEl.innerHTML = '<li>No Users Found</li>';
});
break;
}
});
detailsSearch.on('keyup', function() {
var searchEl = this;
if (searchDelay) clearTimeout(searchDelay);
searchDelay = setTimeout(function() {
var searchText = searchEl.value,
resultsEl = document.getElementById('group-details-search-results'),
foundUser = document.createElement('li'),
foundUserImg, foundUserLabel;
foundUser.innerHTML = '<img /><span></span>';
foundUserImg = foundUser.getElementsByTagName('img')[0];
foundUserLabel = foundUser.getElementsByTagName('span')[0];
socket.emit('api:admin.user.search', searchText, function(err, results) {
if (!err && results && results.length > 0) {
var numResults = results.length,
resultsSlug = document.createDocumentFragment(),
x;
if (numResults > 4) numResults = 4;
for (x = 0; x < numResults; x++) {
foundUserImg.src = results[x].picture;
foundUserLabel.innerHTML = results[x].username;
foundUser.setAttribute('title', results[x].username);
foundUser.setAttribute('data-uid', results[x].uid);
resultsSlug.appendChild(foundUser.cloneNode(true));
}
resultsEl.innerHTML = '';
resultsEl.appendChild(resultsSlug);
} else resultsEl.innerHTML = '<li>No Users Found</li>';
});
}, 200);
});
searchResults.on('click', 'li[data-uid]', function() {
var userLabel = this,
uid = parseInt(this.getAttribute('data-uid')),
gid = detailsModal.attr('data-gid'),
members = [];
groupMembersEl.find('li[data-uid]').each(function() {
members.push(parseInt(this.getAttribute('data-uid')));
}, 200);
});
if (members.indexOf(uid) === -1) {
socket.emit('api:groups.join', {
searchResults.on('click', 'li[data-uid]', function() {
var userLabel = this,
uid = parseInt(this.getAttribute('data-uid')),
gid = detailsModal.attr('data-gid'),
members = [];
groupMembersEl.find('li[data-uid]').each(function() {
members.push(parseInt(this.getAttribute('data-uid')));
});
if (members.indexOf(uid) === -1) {
socket.emit('api:groups.join', {
gid: gid,
uid: uid
}, function(err, data) {
if (!err) {
groupMembersEl.append(userLabel.cloneNode(true));
}
});
}
});
groupMembersEl.on('click', 'li[data-uid]', function() {
var uid = this.getAttribute('data-uid'),
gid = detailsModal.attr('data-gid');
socket.emit('api:groups.leave', {
gid: gid,
uid: uid
}, function(err, data) {
if (!err) {
groupMembersEl.append(userLabel.cloneNode(true));
groupMembersEl.find('li[data-uid="' + uid + '"]').remove();
}
});
}
});
groupMembersEl.on('click', 'li[data-uid]', function() {
var uid = this.getAttribute('data-uid'),
gid = detailsModal.attr('data-gid');
socket.emit('api:groups.leave', {
gid: gid,
uid: uid
}, function(err, data) {
if (!err) {
groupMembersEl.find('li[data-uid="' + uid + '"]').remove();
}
});
});
detailsModalSave.on('click', function() {
var formEl = detailsModal.find('form'),
nameEl = formEl.find('#change-group-name'),
descEl = formEl.find('#change-group-desc'),
gid = detailsModal.attr('data-gid');
detailsModalSave.on('click', function() {
var formEl = detailsModal.find('form'),
nameEl = formEl.find('#change-group-name'),
descEl = formEl.find('#change-group-desc'),
gid = detailsModal.attr('data-gid');
socket.emit('api:groups.update', {
gid: gid,
values: {
name: nameEl.val(),
description: descEl.val()
}
}, function(err) {
if (!err) {
detailsModal.modal('hide');
ajaxify.go('admin/groups');
}
socket.emit('api:groups.update', {
gid: gid,
values: {
name: nameEl.val(),
description: descEl.val()
}
}, function(err) {
if (!err) {
detailsModal.modal('hide');
ajaxify.go('admin/groups');
}
});
});
});
};
return Groups;
});

View File

@@ -1,25 +1,28 @@
define(function() {
var Admin = {};
(function() {
Admin.init = function() {
ajaxify.register_events(['api:get_all_rooms']);
socket.on('api:get_all_rooms', function(data) {
ajaxify.register_events(['api:get_all_rooms']);
socket.on('api:get_all_rooms', function(data) {
var active_users = document.getElementById('active_users'),
total = 0;
active_users.innerHTML = '';
var active_users = document.getElementById('active_users'),
total = 0;
active_users.innerHTML = '';
for (var room in data) {
if (room !== '') {
var count = data[room].length;
total += count;
active_users.innerHTML = active_users.innerHTML + "<div class='alert alert-success'><strong>" + room + "</strong> " + count + " active user" + (count > 1 ? "s" : "") + "</div>";
for (var room in data) {
if (room !== '') {
var count = data[room].length;
total += count;
active_users.innerHTML = active_users.innerHTML + "<div class='alert alert-success'><strong>" + room + "</strong> " + count + " active user" + (count > 1 ? "s" : "") + "</div>";
}
}
}
document.getElementById('connections').innerHTML = total;
});
document.getElementById('connections').innerHTML = total;
});
app.enter_room('admin');
socket.emit('api:get_all_rooms');
app.enter_room('admin');
socket.emit('api:get_all_rooms');
};
}());
return Admin;
});

View File

@@ -1,7 +1,5 @@
var nodebb_admin = nodebb_admin || {};
(function() {
var plugins = {
define(function() {
var Plugins = {
init: function() {
var pluginsList = $('.plugins'),
numPlugins = pluginsList[0].querySelectorAll('li').length,
@@ -31,8 +29,5 @@ var nodebb_admin = nodebb_admin || {};
}
};
jQuery(document).ready(function() {
nodebb_admin.plugins = plugins;
nodebb_admin.plugins.init();
});
})();
return Plugins;
});

View File

@@ -0,0 +1,81 @@
define(function() {
var Settings = {};
Settings.config = {};
Settings.init = function() {
Settings.prepare();
};
Settings.prepare = function() {
// Come back in 500ms if the config isn't ready yet
if (Settings.config === undefined) {
setTimeout(function() {
Settings.prepare();
}, 500);
return;
}
// Populate the fields on the page from the config
var fields = document.querySelectorAll('#content [data-field]'),
numFields = fields.length,
saveBtn = document.getElementById('save'),
x, key, inputType;
for (x = 0; x < numFields; x++) {
key = fields[x].getAttribute('data-field');
inputType = fields[x].getAttribute('type');
if (fields[x].nodeName === 'INPUT') {
if (Settings.config[key]) {
switch (inputType) {
case 'text':
case 'textarea':
case 'number':
fields[x].value = Settings.config[key];
break;
case 'checkbox':
fields[x].checked = Settings.config[key] === '1' ? true : false;
break;
}
}
} else if (fields[x].nodeName === 'TEXTAREA') {
if (Settings.config[key]) fields[x].value = Settings.config[key];
}
}
saveBtn.addEventListener('click', function(e) {
var key, value;
e.preventDefault();
for (x = 0; x < numFields; x++) {
key = fields[x].getAttribute('data-field');
if (fields[x].nodeName === 'INPUT') {
inputType = fields[x].getAttribute('type');
switch (inputType) {
case 'text':
case 'number':
value = fields[x].value;
break;
case 'checkbox':
value = fields[x].checked ? '1' : '0';
break;
}
} else if (fields[x].nodeName === 'TEXTAREA') {
value = fields[x].value;
}
socket.emit('api:config.set', {
key: key,
value: value
});
}
});
};
Settings.remove = function(key) {
socket.emit('api:config.remove', key);
};
return Settings;
});

View File

@@ -1,8 +1,91 @@
var nodebb_admin = (function(nodebb_admin) {
define(function() {
var Themes = {};
var themes = {};
Themes.init = function() {
var scriptEl = document.createElement('script');
scriptEl.src = 'http://api.bootswatch.com/3/?callback=bootswatchListener';
document.body.appendChild(scriptEl);
themes.render = function(bootswatch) {
var bootstrapThemeContainer = document.querySelector('#bootstrap_themes'),
installedThemeContainer = document.querySelector('#installed_themes'),
themeEvent = function(e) {
if (e.target.hasAttribute('data-action')) {
switch (e.target.getAttribute('data-action')) {
case 'preview':
var cssSrc = $(e.target).parents('li').attr('data-css'),
cssEl = document.getElementById('base-theme');
cssEl.href = cssSrc;
break;
case 'use':
var parentEl = $(e.target).parents('li'),
cssSrc = parentEl.attr('data-css'),
cssName = parentEl.attr('data-theme');
socket.emit('api:config.set', {
key: 'theme:id',
value: 'bootswatch:' + cssName
});
socket.emit('api:config.set', {
key: 'theme:src',
value: cssSrc
});
break;
}
}
};
bootstrapThemeContainer.addEventListener('click', themeEvent);
installedThemeContainer.addEventListener('click', themeEvent);
var revertEl = document.getElementById('revert_theme');
revertEl.addEventListener('click', function() {
bootbox.confirm('Are you sure you wish to remove the custom theme and restore the NodeBB default theme?', function(confirm) {
if (confirm) {
require(['forum/admin/settings'], function(Settings) {
Settings.remove('theme:id');
Settings.remove('theme:src');
});
}
});
}, false);
// Installed Themes
socket.emit('api:admin.themes.getInstalled', function(themes) {
var instListEl = document.getElementById('installed_themes'),
themeFrag = document.createDocumentFragment(),
liEl = document.createElement('li');
if (themes.length > 0) {
for (var x = 0, numThemes = themes.length; x < numThemes; x++) {
liEl.setAttribute('data-theme', themes[x].id);
liEl.setAttribute('data-css', themes[x].src);
liEl.innerHTML = '<img src="' + themes[x].screenshot + '" />' +
'<div>' +
'<div class="pull-right">' +
'<button class="btn btn-primary" data-action="use">Use</button> ' +
'<button class="btn btn-default" data-action="preview">Preview</button>' +
'</div>' +
'<h4>' + themes[x].name + '</h4>' +
'<p>' +
themes[x].description +
(themes[x].url ? ' (<a href="' + themes[x].url + '">Homepage</a>)' : '') +
'</p>' +
'</div>' +
'<div class="clear">';
themeFrag.appendChild(liEl.cloneNode(true));
}
} else {
// No themes found
liEl.className = 'no-themes';
liEl.innerHTML = 'No installed themes found';
themeFrag.appendChild(liEl);
}
instListEl.innerHTML = '';
instListEl.appendChild(themeFrag);
});
}
Themes.render = function(bootswatch) {
var themeFrag = document.createDocumentFragment(),
themeEl = document.createElement('li'),
themeContainer = document.querySelector('#bootstrap_themes'),
@@ -28,91 +111,5 @@ var nodebb_admin = (function(nodebb_admin) {
themeContainer.appendChild(themeFrag);
}
nodebb_admin.themes = themes;
return nodebb_admin;
}(nodebb_admin || {}));
(function() {
var scriptEl = document.createElement('script');
scriptEl.src = 'http://api.bootswatch.com/3/?callback=nodebb_admin.themes.render';
document.body.appendChild(scriptEl);
var bootstrapThemeContainer = document.querySelector('#bootstrap_themes'),
installedThemeContainer = document.querySelector('#installed_themes'),
themeEvent = function(e) {
if (e.target.hasAttribute('data-action')) {
switch (e.target.getAttribute('data-action')) {
case 'preview':
var cssSrc = $(e.target).parents('li').attr('data-css'),
cssEl = document.getElementById('base-theme');
cssEl.href = cssSrc;
break;
case 'use':
var parentEl = $(e.target).parents('li'),
cssSrc = parentEl.attr('data-css'),
cssName = parentEl.attr('data-theme');
socket.emit('api:config.set', {
key: 'theme:id',
value: 'bootswatch:' + cssName
});
socket.emit('api:config.set', {
key: 'theme:src',
value: cssSrc
});
break;
}
}
};
bootstrapThemeContainer.addEventListener('click', themeEvent);
installedThemeContainer.addEventListener('click', themeEvent);
var revertEl = document.getElementById('revert_theme');
revertEl.addEventListener('click', function() {
bootbox.confirm('Are you sure you wish to remove the custom theme and restore the NodeBB default theme?', function(confirm) {
if (confirm) {
nodebb_admin.remove('theme:id');
nodebb_admin.remove('theme:src');
}
});
}, false);
// Installed Themes
socket.emit('api:admin.themes.getInstalled', function(themes) {
var instListEl = document.getElementById('installed_themes'),
themeFrag = document.createDocumentFragment(),
liEl = document.createElement('li');
if (themes.length > 0) {
for (var x = 0, numThemes = themes.length; x < numThemes; x++) {
liEl.setAttribute('data-theme', themes[x].id);
liEl.setAttribute('data-css', themes[x].src);
liEl.innerHTML = '<img src="' + themes[x].screenshot + '" />' +
'<div>' +
'<div class="pull-right">' +
'<button class="btn btn-primary" data-action="use">Use</button> ' +
'<button class="btn btn-default" data-action="preview">Preview</button>' +
'</div>' +
'<h4>' + themes[x].name + '</h4>' +
'<p>' +
themes[x].description +
(themes[x].url ? ' (<a href="' + themes[x].url + '">Homepage</a>)' : '') +
'</p>' +
'</div>' +
'<div class="clear">';
themeFrag.appendChild(liEl.cloneNode(true));
}
} else {
// No themes found
liEl.className = 'no-themes';
liEl.innerHTML = 'No installed themes found';
themeFrag.appendChild(liEl);
}
instListEl.innerHTML = '';
instListEl.appendChild(themeFrag);
});
})();
return Themes;
});

View File

@@ -1,127 +1,133 @@
$(document).ready(function() {
var topicsListEl = document.querySelector('.topics'),
loadMoreEl = document.getElementById('topics_loadmore');
define(function() {
var Topics = {};
$(topicsListEl).on('click', '[data-action]', function() {
var $this = $(this),
action = this.getAttribute('data-action'),
tid = $this.parents('[data-tid]').attr('data-tid');
Topics.init = function() {
var topicsListEl = document.querySelector('.topics'),
loadMoreEl = document.getElementById('topics_loadmore');
switch (action) {
case 'pin':
if (!$this.hasClass('active')) socket.emit('api:topic.pin', {
tid: tid
$(topicsListEl).on('click', '[data-action]', function() {
var $this = $(this),
action = this.getAttribute('data-action'),
tid = $this.parents('[data-tid]').attr('data-tid');
switch (action) {
case 'pin':
if (!$this.hasClass('active')) socket.emit('api:topic.pin', {
tid: tid
});
else socket.emit('api:topic.unpin', {
tid: tid
});
break;
case 'lock':
if (!$this.hasClass('active')) socket.emit('api:topic.lock', {
tid: tid
});
else socket.emit('api:topic.unlock', {
tid: tid
});
break;
case 'delete':
if (!$this.hasClass('active')) socket.emit('api:topic.delete', {
tid: tid
});
else socket.emit('api:topic.restore', {
tid: tid
});
break;
}
});
loadMoreEl.addEventListener('click', function() {
if (this.className.indexOf('disabled') === -1) {
var topics = document.querySelectorAll('.topics li[data-tid]'),
lastTid = parseInt(topics[topics.length - 1].getAttribute('data-tid'));
this.innerHTML = '<i class="icon-refresh icon-spin"></i> Retrieving topics';
socket.emit('api:admin.topics.getMore', {
limit: 10,
after: lastTid
}, function(topics) {
var btnEl = document.getElementById('topics_loadmore');
topics = JSON.parse(topics);
if (topics.length > 0) {
var html = templates.prepare(templates['admin/topics'].blocks['topics']).parse({
topics: topics
}),
topicsListEl = document.querySelector('.topics');
topicsListEl.innerHTML += html;
btnEl.innerHTML = 'Load More Topics';
} else {
// Exhausted all topics
btnEl.className += ' disabled';
btnEl.innerHTML = 'No more topics';
}
});
else socket.emit('api:topic.unpin', {
tid: tid
});
break;
case 'lock':
if (!$this.hasClass('active')) socket.emit('api:topic.lock', {
tid: tid
});
else socket.emit('api:topic.unlock', {
tid: tid
});
break;
case 'delete':
if (!$this.hasClass('active')) socket.emit('api:topic.delete', {
tid: tid
});
else socket.emit('api:topic.restore', {
tid: tid
});
break;
}
}, false);
// Resolve proper button state for all topics
var topicEls = topicsListEl.querySelectorAll('li'),
numTopics = topicEls.length;
for (var x = 0; x < numTopics; x++) {
if (topicEls[x].getAttribute('data-pinned') === '1') topicEls[x].querySelector('[data-action="pin"]').className += ' active';
if (topicEls[x].getAttribute('data-locked') === '1') topicEls[x].querySelector('[data-action="lock"]').className += ' active';
if (topicEls[x].getAttribute('data-deleted') === '1') topicEls[x].querySelector('[data-action="delete"]').className += ' active';
topicEls[x].removeAttribute('data-pinned');
topicEls[x].removeAttribute('data-locked');
topicEls[x].removeAttribute('data-deleted');
}
});
loadMoreEl.addEventListener('click', function() {
if (this.className.indexOf('disabled') === -1) {
var topics = document.querySelectorAll('.topics li[data-tid]'),
lastTid = parseInt(topics[topics.length - 1].getAttribute('data-tid'));
socket.on('api:topic.pin', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="pin"]');
this.innerHTML = '<i class="icon-refresh icon-spin"></i> Retrieving topics';
socket.emit('api:admin.topics.getMore', {
limit: 10,
after: lastTid
}, function(topics) {
var btnEl = document.getElementById('topics_loadmore');
$(btnEl).addClass('active');
}
});
topics = JSON.parse(topics);
if (topics.length > 0) {
var html = templates.prepare(templates['admin/topics'].blocks['topics']).parse({
topics: topics
}),
topicsListEl = document.querySelector('.topics');
socket.on('api:topic.unpin', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="pin"]');
topicsListEl.innerHTML += html;
btnEl.innerHTML = 'Load More Topics';
} else {
// Exhausted all topics
btnEl.className += ' disabled';
btnEl.innerHTML = 'No more topics';
}
});
}
}, false);
$(btnEl).removeClass('active');
}
});
// Resolve proper button state for all topics
var topicEls = topicsListEl.querySelectorAll('li'),
numTopics = topicEls.length;
for (var x = 0; x < numTopics; x++) {
if (topicEls[x].getAttribute('data-pinned') === '1') topicEls[x].querySelector('[data-action="pin"]').className += ' active';
if (topicEls[x].getAttribute('data-locked') === '1') topicEls[x].querySelector('[data-action="lock"]').className += ' active';
if (topicEls[x].getAttribute('data-deleted') === '1') topicEls[x].querySelector('[data-action="delete"]').className += ' active';
topicEls[x].removeAttribute('data-pinned');
topicEls[x].removeAttribute('data-locked');
topicEls[x].removeAttribute('data-deleted');
}
});
socket.on('api:topic.lock', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="lock"]');
socket.on('api:topic.pin', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="pin"]');
$(btnEl).addClass('active');
}
});
$(btnEl).addClass('active');
}
});
socket.on('api:topic.unlock', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="lock"]');
socket.on('api:topic.unpin', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="pin"]');
$(btnEl).removeClass('active');
}
});
$(btnEl).removeClass('active');
}
});
socket.on('api:topic.delete', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]');
socket.on('api:topic.lock', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="lock"]');
$(btnEl).addClass('active');
}
});
$(btnEl).addClass('active');
}
});
socket.on('api:topic.restore', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]');
socket.on('api:topic.unlock', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="lock"]');
$(btnEl).removeClass('active');
}
});
};
$(btnEl).removeClass('active');
}
});
socket.on('api:topic.delete', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]');
$(btnEl).addClass('active');
}
});
socket.on('api:topic.restore', function(response) {
if (response.status === 'ok') {
var btnEl = document.querySelector('li[data-tid="' + response.tid + '"] button[data-action="delete"]');
$(btnEl).removeClass('active');
}
return Topics;
});

View File

@@ -1,170 +1,174 @@
(function() {
define(function() {
var Users = {};
var yourid = templates.get('yourid');
Users.init = function() {
var yourid = templates.get('yourid');
function isUserAdmin(element) {
var parent = $(element).parents('.users-box');
return (parent.attr('data-admin') !== "0");
}
function isUserAdmin(element) {
var parent = $(element).parents('.users-box');
return (parent.attr('data-admin') !== "0");
}
function isUserBanned(element) {
var parent = $(element).parents('.users-box');
return (parent.attr('data-banned') !== "" && parent.attr('data-banned') !== "0");
}
function isUserBanned(element) {
var parent = $(element).parents('.users-box');
return (parent.attr('data-banned') !== "" && parent.attr('data-banned') !== "0");
}
function getUID(element) {
var parent = $(element).parents('.users-box');
return parent.attr('data-uid');
}
function getUID(element) {
var parent = $(element).parents('.users-box');
return parent.attr('data-uid');
}
function updateUserButtons() {
jQuery('.ban-btn').each(function(index, element) {
var banBtn = $(element);
var uid = getUID(banBtn);
if (isUserAdmin(banBtn) || uid === yourid)
banBtn.addClass('disabled');
else if (isUserBanned(banBtn))
banBtn.addClass('btn-warning');
else
banBtn.removeClass('btn-warning');
});
}
function initUsers() {
updateUserButtons();
$('#users-container').on('click', '.ban-btn', function() {
var banBtn = $(this);
var isAdmin = isUserAdmin(banBtn);
var isBanned = isUserBanned(banBtn);
var parent = banBtn.parents('.users-box');
var uid = getUID(banBtn);
if (!isAdmin) {
if (isBanned) {
socket.emit('api:admin.user.unbanUser', uid);
function updateUserButtons() {
jQuery('.ban-btn').each(function(index, element) {
var banBtn = $(element);
var uid = getUID(banBtn);
if (isUserAdmin(banBtn) || uid === yourid)
banBtn.addClass('disabled');
else if (isUserBanned(banBtn))
banBtn.addClass('btn-warning');
else
banBtn.removeClass('btn-warning');
parent.attr('data-banned', 0);
});
}
function initUsers() {
updateUserButtons();
$('#users-container').on('click', '.ban-btn', function() {
var banBtn = $(this);
var isAdmin = isUserAdmin(banBtn);
var isBanned = isUserBanned(banBtn);
var parent = banBtn.parents('.users-box');
var uid = getUID(banBtn);
if (!isAdmin) {
if (isBanned) {
socket.emit('api:admin.user.unbanUser', uid);
banBtn.removeClass('btn-warning');
parent.attr('data-banned', 0);
} else {
bootbox.confirm('Do you really want to ban "' + parent.attr('data-username') + '"?', function(confirm) {
if (confirm) {
socket.emit('api:admin.user.banUser', uid);
banBtn.addClass('btn-warning');
parent.attr('data-banned', 1);
}
});
}
}
return false;
});
}
jQuery('document').ready(function() {
var timeoutId = 0,
loadingMoreUsers = false;
var url = window.location.href,
parts = url.split('/'),
active = parts[parts.length - 1];
jQuery('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) {
jQuery(this.parentNode).addClass('active');
return false;
}
});
jQuery('#search-user').on('keyup', function() {
if (timeoutId !== 0) {
clearTimeout(timeoutId);
timeoutId = 0;
}
timeoutId = setTimeout(function() {
var username = $('#search-user').val();
jQuery('.icon-spinner').removeClass('none');
socket.emit('api:admin.user.search', username);
}, 250);
});
initUsers();
socket.removeAllListeners('api:admin.user.search');
socket.on('api:admin.user.search', function(data) {
var html = templates.prepare(templates['admin/users'].blocks['users']).parse({
users: data
}),
userListEl = document.querySelector('.users');
userListEl.innerHTML = html;
jQuery('.icon-spinner').addClass('none');
if (data && data.length === 0) {
$('#user-notfound-notify').html('User not found!')
.show()
.addClass('label-danger')
.removeClass('label-success');
} else {
bootbox.confirm('Do you really want to ban "' + parent.attr('data-username') + '"?', function(confirm) {
if (confirm) {
socket.emit('api:admin.user.banUser', uid);
banBtn.addClass('btn-warning');
parent.attr('data-banned', 1);
$('#user-notfound-notify').html(data.length + ' user' + (data.length > 1 ? 's' : '') + ' found!')
.show()
.addClass('label-success')
.removeClass('label-danger');
}
initUsers();
});
function onUsersLoaded(users) {
var html = templates.prepare(templates['admin/users'].blocks['users']).parse({
users: users
});
$('#users-container').append(html);
updateUserButtons();
}
function loadMoreUsers() {
var set = '';
if (active === 'latest') {
set = 'users:joindate';
} else if (active === 'sort-posts') {
set = 'users:postcount';
} else if (active === 'sort-reputation') {
set = 'users:reputation';
}
if (set) {
loadingMoreUsers = true;
socket.emit('api:users.loadMore', {
set: set,
after: $('#users-container').children().length
}, function(data) {
if (data.users.length) {
onUsersLoaded(data.users);
}
loadingMoreUsers = false;
});
}
}
return false;
});
}
$('#load-more-users-btn').on('click', loadMoreUsers);
$(window).off('scroll').on('scroll', function() {
var bottom = ($(document).height() - $(window).height()) * 0.9;
jQuery('document').ready(function() {
var timeoutId = 0,
loadingMoreUsers = false;
var url = window.location.href,
parts = url.split('/'),
active = parts[parts.length - 1];
jQuery('.nav-pills li').removeClass('active');
jQuery('.nav-pills li a').each(function() {
if (this.getAttribute('href').match(active)) {
jQuery(this.parentNode).addClass('active');
return false;
}
});
jQuery('#search-user').on('keyup', function() {
if (timeoutId !== 0) {
clearTimeout(timeoutId);
timeoutId = 0;
}
timeoutId = setTimeout(function() {
var username = $('#search-user').val();
jQuery('.icon-spinner').removeClass('none');
socket.emit('api:admin.user.search', username);
}, 250);
});
initUsers();
socket.removeAllListeners('api:admin.user.search');
socket.on('api:admin.user.search', function(data) {
var html = templates.prepare(templates['admin/users'].blocks['users']).parse({
users: data
}),
userListEl = document.querySelector('.users');
userListEl.innerHTML = html;
jQuery('.icon-spinner').addClass('none');
if (data && data.length === 0) {
$('#user-notfound-notify').html('User not found!')
.show()
.addClass('label-danger')
.removeClass('label-success');
} else {
$('#user-notfound-notify').html(data.length + ' user' + (data.length > 1 ? 's' : '') + ' found!')
.show()
.addClass('label-success')
.removeClass('label-danger');
}
initUsers();
});
function onUsersLoaded(users) {
var html = templates.prepare(templates['admin/users'].blocks['users']).parse({
users: users
if ($(window).scrollTop() > bottom && !loadingMoreUsers) {
loadMoreUsers();
}
});
$('#users-container').append(html);
updateUserButtons();
}
function loadMoreUsers() {
var set = '';
if (active === 'latest') {
set = 'users:joindate';
} else if (active === 'sort-posts') {
set = 'users:postcount';
} else if (active === 'sort-reputation') {
set = 'users:reputation';
}
if (set) {
loadingMoreUsers = true;
socket.emit('api:users.loadMore', {
set: set,
after: $('#users-container').children().length
}, function(data) {
if (data.users.length) {
onUsersLoaded(data.users);
}
loadingMoreUsers = false;
});
}
}
$('#load-more-users-btn').on('click', loadMoreUsers);
$(window).off('scroll').on('scroll', function() {
var bottom = ($(document).height() - $(window).height()) * 0.9;
if ($(window).scrollTop() > bottom && !loadingMoreUsers) {
loadMoreUsers();
}
});
};
});
}());
return Users;
});

View File

@@ -1,41 +1,86 @@
(function () {
var cid = templates.get('category_id'),
room = 'category_' + cid,
twitterEl = document.getElementById('twitter-intent'),
facebookEl = document.getElementById('facebook-share'),
googleEl = document.getElementById('google-share'),
twitter_url = templates.get('twitter-intent-url'),
facebook_url = templates.get('facebook-share-url'),
google_url = templates.get('google-share-url'),
loadingMoreTopics = false;
define(function () {
var Category = {};
app.enter_room(room);
Category.init = function() {
var cid = templates.get('category_id'),
room = 'category_' + cid,
twitterEl = document.getElementById('twitter-intent'),
facebookEl = document.getElementById('facebook-share'),
googleEl = document.getElementById('google-share'),
twitter_url = templates.get('twitter-intent-url'),
facebook_url = templates.get('facebook-share-url'),
google_url = templates.get('google-share-url'),
loadingMoreTopics = false;
twitterEl.addEventListener('click', function () {
window.open(twitter_url, '_blank', 'width=550,height=420,scrollbars=no,status=no');
return false;
}, false);
facebookEl.addEventListener('click', function () {
window.open(facebook_url, '_blank', 'width=626,height=436,scrollbars=no,status=no');
return false;
}, false);
googleEl.addEventListener('click', function () {
window.open(google_url, '_blank', 'width=500,height=570,scrollbars=no,status=no');
return false;
}, false);
app.enter_room(room);
var new_post = document.getElementById('new_post');
new_post.onclick = function () {
require(['composer'], function (cmp) {
cmp.push(0, cid);
twitterEl.addEventListener('click', function () {
window.open(twitter_url, '_blank', 'width=550,height=420,scrollbars=no,status=no');
return false;
}, false);
facebookEl.addEventListener('click', function () {
window.open(facebook_url, '_blank', 'width=626,height=436,scrollbars=no,status=no');
return false;
}, false);
googleEl.addEventListener('click', function () {
window.open(google_url, '_blank', 'width=500,height=570,scrollbars=no,status=no');
return false;
}, false);
var new_post = document.getElementById('new_post');
new_post.onclick = function () {
require(['composer'], function (cmp) {
cmp.push(0, cid);
});
}
ajaxify.register_events([
'event:new_topic'
]);
socket.on('event:new_topic', Category.onNewTopic);
socket.emit('api:categories.getRecentReplies', cid);
socket.on('api:categories.getRecentReplies', function (posts) {
if (!posts || posts.length === 0) {
return;
}
var recent_replies = document.getElementById('category_recent_replies');
recent_replies.innerHTML = '';
var frag = document.createDocumentFragment(),
li = document.createElement('li');
for (var i = 0, numPosts = posts.length; i < numPosts; i++) {
li.setAttribute('data-pid', posts[i].pid);
li.innerHTML = '<a href="/user/' + posts[i].userslug + '"><img title="' + posts[i].username + '" style="width: 48px; height: 48px; /*temporary*/" class="img-rounded" src="' + posts[i].picture + '" class="" /></a>' +
'<a href="/topic/' + posts[i].topicSlug + '#' + posts[i].pid + '">' +
'<p>' +
posts[i].content +
'</p>' +
'<p class="meta"><strong>' + posts[i].username + '</strong></span> -<span class="timeago" title="' + posts[i].relativeTime + '"></span></p>' +
'</a>';
frag.appendChild(li.cloneNode(true));
recent_replies.appendChild(frag);
}
$('#category_recent_replies span.timeago').timeago();
});
}
ajaxify.register_events([
'event:new_topic'
]);
$(window).off('scroll').on('scroll', function (ev) {
var bottom = ($(document).height() - $(window).height()) * 0.9;
function onNewTopic(data) {
if ($(window).scrollTop() > bottom && !loadingMoreTopics) {
Category.loadMoreTopics(cid);
}
});
};
Category.onNewTopic = function(data) {
var html = templates.prepare(templates['category'].blocks['topics']).parse({
topics: [data]
}),
@@ -64,40 +109,7 @@
$('#topics-container span.timeago').timeago();
}
socket.on('event:new_topic', onNewTopic);
socket.emit('api:categories.getRecentReplies', cid);
socket.on('api:categories.getRecentReplies', function (posts) {
if (!posts || posts.length === 0) {
return;
}
var recent_replies = document.getElementById('category_recent_replies');
recent_replies.innerHTML = '';
var frag = document.createDocumentFragment(),
li = document.createElement('li');
for (var i = 0, numPosts = posts.length; i < numPosts; i++) {
li.setAttribute('data-pid', posts[i].pid);
li.innerHTML = '<a href="/user/' + posts[i].userslug + '"><img title="' + posts[i].username + '" style="width: 48px; height: 48px; /*temporary*/" class="img-rounded" src="' + posts[i].picture + '" class="" /></a>' +
'<a href="/topic/' + posts[i].topicSlug + '#' + posts[i].pid + '">' +
'<p>' +
posts[i].content +
'</p>' +
'<p class="meta"><strong>' + posts[i].username + '</strong></span> -<span class="timeago" title="' + posts[i].relativeTime + '"></span></p>' +
'</a>';
frag.appendChild(li.cloneNode(true));
recent_replies.appendChild(frag);
}
$('#category_recent_replies span.timeago').timeago();
});
function onTopicsLoaded(topics) {
Category.onTopicsLoaded = function(topics) {
var html = templates.prepare(templates['category'].blocks['topics']).parse({
topics: topics
@@ -113,26 +125,18 @@
}
function loadMoreTopics(cid) {
Category.loadMoreTopics = function(cid) {
loadingMoreTopics = true;
socket.emit('api:category.loadMore', {
cid: cid,
after: $('#topics-container').children().length
}, function (data) {
if (data.topics.length) {
onTopicsLoaded(data.topics);
Category.onTopicsLoaded(data.topics);
}
loadingMoreTopics = false;
});
}
$(window).off('scroll').on('scroll', function (ev) {
var bottom = ($(document).height() - $(window).height()) * 0.9;
if ($(window).scrollTop() > bottom && !loadingMoreTopics) {
loadMoreTopics(cid);
}
});
})();
return Category;
});

View File

@@ -1,7 +1,13 @@
(function() {
$(document).ready(function() {
define(['forum/accountheader'], function(header) {
var AccountHeader = {};
AccountHeader.init = function() {
header.init();
$('.user-favourite-posts .topic-row').on('click', function() {
ajaxify.go($(this).attr('topic-url'));
});
});
}());
};
return AccountHeader;
});

View File

@@ -1,18 +1,20 @@
(function() {
define(['forum/accountheader'], function(header) {
var Followers = {};
var yourid = templates.get('yourid'),
theirid = templates.get('theirid'),
followersCount = templates.get('followersCount');
Followers.init = function() {
header.init();
$(document).ready(function() {
var yourid = templates.get('yourid'),
theirid = templates.get('theirid'),
followersCount = templates.get('followersCount');
if (parseInt(followersCount, 10) === 0) {
$('#no-followers-notice').removeClass('hide');
}
if (parseInt(followersCount, 10) === 0) {
$('#no-followers-notice').removeClass('hide');
}
app.addCommasToNumbers();
};
});
}());
return Followers;
});

View File

@@ -1,10 +1,12 @@
(function() {
define(['forum/accountheader'], function(header) {
var Following = {};
var yourid = templates.get('yourid'),
theirid = templates.get('theirid'),
followingCount = templates.get('followingCount');
Following.init = function() {
header.init();
$(document).ready(function() {
var yourid = templates.get('yourid'),
theirid = templates.get('theirid'),
followingCount = templates.get('followingCount');
if (parseInt(followingCount, 10) === 0) {
$('#no-following-notice').removeClass('hide');
@@ -34,7 +36,7 @@
}
app.addCommasToNumbers();
});
};
}());
return Following;
});

View File

@@ -1,60 +1,66 @@
(function() {
// Alternate Logins
var altLoginEl = document.querySelector('.alt-logins');
altLoginEl.addEventListener('click', function(e) {
var target;
switch (e.target.nodeName) {
case 'LI':
target = e.target;
break;
case 'I':
target = e.target.parentNode;
break;
}
if (target) {
document.location.href = target.getAttribute('data-url');
}
});
define(function() {
var Login = {};
$('#login').on('click', function() {
var loginData = {
'username': $('#username').val(),
'password': $('#password').val(),
'_csrf': $('#csrf-token').val()
};
$.ajax({
type: "POST",
url: RELATIVE_PATH + '/login',
data: loginData,
success: function(data, textStatus, jqXHR) {
if (!data.success) {
$('#login-error-notify').show();
} else {
$('#login-error-notify').hide();
if(app.previousUrl.indexOf('/reset/') != -1)
window.location.replace(RELATIVE_PATH + "/?loggedin");
else
window.location.replace(app.previousUrl + "?loggedin");
app.loadConfig();
}
},
error: function(data, textStatus, jqXHR) {
$('#login-error-notify').show();
},
dataType: 'json',
async: true,
timeout: 2000
Login.init = function() {
// Alternate Logins
var altLoginEl = document.querySelector('.alt-logins');
altLoginEl.addEventListener('click', function(e) {
var target;
switch (e.target.nodeName) {
case 'LI':
target = e.target;
break;
case 'I':
target = e.target.parentNode;
break;
}
if (target) {
document.location.href = target.getAttribute('data-url');
}
});
return false;
});
$('#login').on('click', function() {
var loginData = {
'username': $('#username').val(),
'password': $('#password').val(),
'_csrf': $('#csrf-token').val()
};
$('#login-error-notify button').on('click', function() {
$('#login-error-notify').hide();
return false;
});
$.ajax({
type: "POST",
url: RELATIVE_PATH + '/login',
data: loginData,
success: function(data, textStatus, jqXHR) {
if (!data.success) {
$('#login-error-notify').show();
} else {
$('#login-error-notify').hide();
if(app.previousUrl.indexOf('/reset/') != -1)
window.location.replace(RELATIVE_PATH + "/?loggedin");
else
window.location.replace(app.previousUrl + "?loggedin");
document.querySelector('#content input').focus();
}());
app.loadConfig();
}
},
error: function(data, textStatus, jqXHR) {
$('#login-error-notify').show();
},
dataType: 'json',
async: true,
timeout: 2000
});
return false;
});
$('#login-error-notify button').on('click', function() {
$('#login-error-notify').hide();
return false;
});
document.querySelector('#content input').focus();
};
return Login;
});

View File

@@ -1,40 +1,56 @@
(function() {
var loadingMoreTopics = false;
define(function() {
var Recent = {};
app.enter_room('recent_posts');
Recent.newTopicCount = 0;
Recent.newPostCount = 0;
Recent.loadingMoreTopics = false;
ajaxify.register_events([
'event:new_topic',
'event:new_post'
]);
Recent.init = function() {
app.enter_room('recent_posts');
var newTopicCount = 0,
newPostCount = 0;
ajaxify.register_events([
'event:new_topic',
'event:new_post'
]);
$('#new-topics-alert').on('click', function() {
$(this).hide();
});
$('#new-topics-alert').on('click', function() {
$(this).hide();
});
socket.on('event:new_topic', function(data) {
socket.on('event:new_topic', function(data) {
++newTopicCount;
updateAlertText();
++Recent.newTopicCount;
Recent.updateAlertText();
});
});
function updateAlertText() {
socket.on('event:new_post', function(data) {
++Recent.newPostCount;
Recent.updateAlertText();
});
$(window).off('scroll').on('scroll', function() {
var bottom = ($(document).height() - $(window).height()) * 0.9;
if ($(window).scrollTop() > bottom && !Recent.loadingMoreTopics) {
Recent.loadMoreTopics();
}
});
};
Recent.updateAlertText = function() {
var text = '';
if (newTopicCount > 1)
text = 'There are ' + newTopicCount + ' new topics';
else if (newTopicCount === 1)
if (Recent.newTopicCount > 1)
text = 'There are ' + Recent.newTopicCount + ' new topics';
else if (Recent.newTopicCount === 1)
text = 'There is 1 new topic';
else
text = 'There are no new topics';
if (newPostCount > 1)
text += ' and ' + newPostCount + ' new posts.';
else if (newPostCount === 1)
if (Recent.newPostCount > 1)
text += ' and ' + Recent.newPostCount + ' new posts.';
else if (Recent.newPostCount === 1)
text += ' and 1 new post.';
else
text += ' and no new posts.';
@@ -44,12 +60,7 @@
$('#new-topics-alert').html(text).fadeIn('slow');
}
socket.on('event:new_post', function(data) {
++newPostCount;
updateAlertText();
});
function onTopicsLoaded(topics) {
Recent.onTopicsLoaded = function(topics) {
var html = templates.prepare(templates['recent'].blocks['topics']).parse({
topics: topics
@@ -61,25 +72,17 @@
container.append(html);
}
function loadMoreTopics() {
loadingMoreTopics = true;
Recent.loadMoreTopics = function() {
Recent.loadingMoreTopics = true;
socket.emit('api:topics.loadMoreRecentTopics', {
after: $('#topics-container').children().length
}, function(data) {
if (data.topics && data.topics.length) {
onTopicsLoaded(data.topics);
Recent.onTopicsLoaded(data.topics);
}
loadingMoreTopics = false;
Recent.loadingMoreTopics = false;
});
}
$(window).off('scroll').on('scroll', function() {
var bottom = ($(document).height() - $(window).height()) * 0.9;
if ($(window).scrollTop() > bottom && !loadingMoreTopics) {
loadMoreTopics();
}
});
})();
return Recent;
});

View File

@@ -1,154 +1,159 @@
(function() {
var username = $('#username'),
password = $('#password'),
password_confirm = $('#password-confirm'),
register = $('#register'),
emailEl = $('#email'),
username_notify = $('#username-notify'),
email_notify = $('#email-notify'),
password_notify = $('#password-notify'),
password_confirm_notify = $('#password-confirm-notify'),
validationError = false,
successIcon = '<i class="icon icon-ok"></i>';
define(function() {
var Register = {};
$('#referrer').val(app.previousUrl);
Register.init = function() {
var username = $('#username'),
password = $('#password'),
password_confirm = $('#password-confirm'),
register = $('#register'),
emailEl = $('#email'),
username_notify = $('#username-notify'),
email_notify = $('#email-notify'),
password_notify = $('#password-notify'),
password_confirm_notify = $('#password-confirm-notify'),
validationError = false,
successIcon = '<i class="icon icon-ok"></i>';
function showError(element, msg) {
element.html(msg);
element.parent()
.removeClass('alert-success')
.addClass('alert-danger');
element.show();
validationError = true;
}
$('#referrer').val(app.previousUrl);
function showSuccess(element, msg) {
element.html(msg);
element.parent()
.removeClass('alert-danger')
.addClass('alert-success');
element.show();
}
function validateEmail() {
if (!emailEl.val()) {
function showError(element, msg) {
element.html(msg);
element.parent()
.removeClass('alert-success')
.addClass('alert-danger');
element.show();
validationError = true;
return;
}
if (!utils.isEmailValid(emailEl.val())) {
showError(email_notify, 'Invalid email address.');
} else
socket.emit('user.email.exists', {
email: emailEl.val()
});
}
emailEl.on('blur', function() {
validateEmail();
});
function validateUsername() {
if (!username.val()) {
validationError = true;
return;
function showSuccess(element, msg) {
element.html(msg);
element.parent()
.removeClass('alert-danger')
.addClass('alert-success');
element.show();
}
if (username.val().length < config.minimumUsernameLength) {
showError(username_notify, 'Username too short!');
} else if (username.val().length > config.maximumUsernameLength) {
showError(username_notify, 'Username too long!');
} else if (!utils.isUserNameValid(username.val())) {
showError(username_notify, 'Invalid username!');
} else {
socket.emit('user.exists', {
username: username.val()
});
}
}
function validateEmail() {
if (!emailEl.val()) {
validationError = true;
return;
}
username.on('keyup', function() {
jQuery('#yourUsername').html(this.value.length > 0 ? this.value : 'username');
});
username.on('blur', function() {
validateUsername();
});
function validatePassword() {
if (!password.val()) {
validationError = true;
return;
if (!utils.isEmailValid(emailEl.val())) {
showError(email_notify, 'Invalid email address.');
} else
socket.emit('user.email.exists', {
email: emailEl.val()
});
}
if (password.val().length < config.minimumPasswordLength) {
showError(password_notify, 'Password too short!');
} else if (!utils.isPasswordValid(password.val())) {
showError(password_notify, 'Invalid password!');
} else {
showSuccess(password_notify, successIcon);
emailEl.on('blur', function() {
validateEmail();
});
function validateUsername() {
if (!username.val()) {
validationError = true;
return;
}
if (username.val().length < config.minimumUsernameLength) {
showError(username_notify, 'Username too short!');
} else if (username.val().length > config.maximumUsernameLength) {
showError(username_notify, 'Username too long!');
} else if (!utils.isUserNameValid(username.val())) {
showError(username_notify, 'Invalid username!');
} else {
socket.emit('user.exists', {
username: username.val()
});
}
}
if (password.val() !== password_confirm.val() && password_confirm.val() !== '') {
showError(password_confirm_notify, 'Passwords must match!');
}
}
username.on('keyup', function() {
jQuery('#yourUsername').html(this.value.length > 0 ? this.value : 'username');
});
username.on('blur', function() {
validateUsername();
});
$(password).on('blur', function() {
validatePassword();
});
function validatePassword() {
if (!password.val()) {
validationError = true;
return;
}
function validatePasswordConfirm() {
if (!password.val() || password_notify.hasClass('alert-error')) {
return;
if (password.val().length < config.minimumPasswordLength) {
showError(password_notify, 'Password too short!');
} else if (!utils.isPasswordValid(password.val())) {
showError(password_notify, 'Invalid password!');
} else {
showSuccess(password_notify, successIcon);
}
if (password.val() !== password_confirm.val() && password_confirm.val() !== '') {
showError(password_confirm_notify, 'Passwords must match!');
}
}
if (password.val() !== password_confirm.val()) {
showError(password_confirm_notify, 'Passwords must match!');
} else {
showSuccess(password_confirm_notify, successIcon);
$(password).on('blur', function() {
validatePassword();
});
function validatePasswordConfirm() {
if (!password.val() || password_notify.hasClass('alert-error')) {
return;
}
if (password.val() !== password_confirm.val()) {
showError(password_confirm_notify, 'Passwords must match!');
} else {
showSuccess(password_confirm_notify, successIcon);
}
}
}
$(password_confirm).on('blur', function() {
validatePasswordConfirm();
});
$(password_confirm).on('blur', function() {
validatePasswordConfirm();
});
ajaxify.register_events(['user.exists', 'user.email.exists']);
ajaxify.register_events(['user.exists', 'user.email.exists']);
socket.on('user.exists', function(data) {
if (data.exists === true) {
showError(username_notify, 'Username already taken!');
} else {
showSuccess(username_notify, successIcon);
socket.on('user.exists', function(data) {
if (data.exists === true) {
showError(username_notify, 'Username already taken!');
} else {
showSuccess(username_notify, successIcon);
}
});
socket.on('user.email.exists', function(data) {
if (data.exists === true) {
showError(email_notify, 'Email address already taken!');
} else {
showSuccess(email_notify, successIcon);
}
});
// Alternate Logins
$('.alt-logins li').on('click', function(e) {
document.location.href = $(this).attr('data-url');
});
function validateForm() {
validationError = false;
validateEmail();
validateUsername();
validatePassword();
validatePasswordConfirm();
return validationError;
}
});
socket.on('user.email.exists', function(data) {
if (data.exists === true) {
showError(email_notify, 'Email address already taken!');
} else {
showSuccess(email_notify, successIcon);
}
});
register.on('click', function(e) {
if (validateForm()) e.preventDefault();
});
};
// Alternate Logins
$('.alt-logins li').on('click', function(e) {
document.location.href = $(this).attr('data-url');
});
function validateForm() {
validationError = false;
validateEmail();
validateUsername();
validatePassword();
validatePasswordConfirm();
return validationError;
}
register.on('click', function(e) {
if (validateForm()) e.preventDefault();
});
}());
return Register;
});

View File

@@ -1,41 +1,47 @@
(function() {
var inputEl = document.getElementById('email'),
errorEl = document.getElementById('error'),
errorTextEl = errorEl.querySelector('p');
define(function() {
var ResetPassword = {};
document.getElementById('reset').onclick = function() {
if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) {
socket.emit('user:reset.send', {
email: inputEl.value
});
} else {
jQuery('#success').hide();
jQuery(errorEl).show();
errorTextEl.innerHTML = 'Please enter a valid email';
}
ResetPassword.init = function() {
var inputEl = document.getElementById('email'),
errorEl = document.getElementById('error'),
errorTextEl = errorEl.querySelector('p');
document.getElementById('reset').onclick = function() {
if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) {
socket.emit('user:reset.send', {
email: inputEl.value
});
} else {
jQuery('#success').hide();
jQuery(errorEl).show();
errorTextEl.innerHTML = 'Please enter a valid email';
}
};
ajaxify.register_events(['user.send_reset']);
socket.on('user.send_reset', function(data) {
var submitEl = document.getElementById('reset');
if (data.status === 'ok') {
jQuery('#error').hide();
jQuery('#success').show();
jQuery('#success p').html('An email has been dispatched to "' + data.email + '" with instructions on setting a new password.');
inputEl.value = '';
} else {
jQuery('#success').hide();
jQuery(errorEl).show();
switch (data.message) {
case 'invalid-email':
errorTextEl.innerHTML = 'The email you put in (<span>' + data.email + '</span>) is not registered with us. Please try again.';
break;
case 'send-failed':
errorTextEl.innerHTML = 'There was a problem sending the reset code. Please try again later.';
break;
}
}
});
};
ajaxify.register_events(['user.send_reset']);
socket.on('user.send_reset', function(data) {
var submitEl = document.getElementById('reset');
if (data.status === 'ok') {
jQuery('#error').hide();
jQuery('#success').show();
jQuery('#success p').html('An email has been dispatched to "' + data.email + '" with instructions on setting a new password.');
inputEl.value = '';
} else {
jQuery('#success').hide();
jQuery(errorEl).show();
switch (data.message) {
case 'invalid-email':
errorTextEl.innerHTML = 'The email you put in (<span>' + data.email + '</span>) is not registered with us. Please try again.';
break;
case 'send-failed':
errorTextEl.innerHTML = 'There was a problem sending the reset code. Please try again later.';
break;
}
}
});
}());
return ResetPassword;
});

View File

@@ -1,52 +1,58 @@
(function() {
var reset_code = templates.get('reset_code');
define(function() {
var ResetCode = {};
var resetEl = document.getElementById('reset'),
password = document.getElementById('password'),
repeat = document.getElementById('repeat'),
noticeEl = document.getElementById('notice');
ResetCode.init = function() {
var reset_code = templates.get('reset_code');
resetEl.addEventListener('click', function() {
if (password.value.length < 6) {
$('#error').hide();
noticeEl.querySelector('strong').innerHTML = 'Invalid Password';
noticeEl.querySelector('p').innerHTML = 'The password entered is too short, please pick a different password.';
noticeEl.style.display = 'block';
} else if (password.value !== repeat.value) {
$('#error').hide();
noticeEl.querySelector('strong').innerHTML = 'Invalid Password';
noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.';
noticeEl.style.display = 'block';
} else {
socket.emit('user:reset.commit', {
code: reset_code,
password: password.value
});
}
}, false);
var resetEl = document.getElementById('reset'),
password = document.getElementById('password'),
repeat = document.getElementById('repeat'),
noticeEl = document.getElementById('notice');
// Enable the form if the code is valid
socket.emit('user:reset.valid', {
code: reset_code
});
resetEl.addEventListener('click', function() {
if (password.value.length < 6) {
$('#error').hide();
noticeEl.querySelector('strong').innerHTML = 'Invalid Password';
noticeEl.querySelector('p').innerHTML = 'The password entered is too short, please pick a different password.';
noticeEl.style.display = 'block';
} else if (password.value !== repeat.value) {
$('#error').hide();
noticeEl.querySelector('strong').innerHTML = 'Invalid Password';
noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.';
noticeEl.style.display = 'block';
} else {
socket.emit('user:reset.commit', {
code: reset_code,
password: password.value
});
}
}, false);
// Enable the form if the code is valid
socket.emit('user:reset.valid', {
code: reset_code
});
ajaxify.register_events(['user:reset.valid', 'user:reset.commit']);
socket.on('user:reset.valid', function(data) {
if ( !! data.valid) resetEl.disabled = false;
else {
var formEl = document.getElementById('reset-form');
// Show error message
$('#error').show();
formEl.parentNode.removeChild(formEl);
}
})
ajaxify.register_events(['user:reset.valid', 'user:reset.commit']);
socket.on('user:reset.valid', function(data) {
if ( !! data.valid) resetEl.disabled = false;
else {
var formEl = document.getElementById('reset-form');
// Show error message
$('#error').show();
formEl.parentNode.removeChild(formEl);
}
})
socket.on('user:reset.commit', function(data) {
if (data.status === 'ok') {
$('#error').hide();
$('#notice').hide();
$('#success').show();
}
});
}());
socket.on('user:reset.commit', function(data) {
if (data.status === 'ok') {
$('#error').hide();
$('#notice').hide();
$('#success').show();
}
});
};
return ResetCode;
});

View File

@@ -1,6 +1,7 @@
(function() {
define(function() {
var Search = {};
$(document).ready(function() {
Search.init = function() {
var searchQuery = $('#topics-container').attr('data-search-query');
$('.search-result-text').each(function() {
@@ -21,4 +22,5 @@
});
});
})();
return Search;
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,114 +1,119 @@
(function() {
var loadingMoreTopics = false;
define(function() {
var Unread = {};
app.enter_room('recent_posts');
Unread.init = function() {
var loadingMoreTopics = false;
ajaxify.register_events([
'event:new_topic',
'event:new_post'
]);
app.enter_room('recent_posts');
var newTopicCount = 0,
newPostCount = 0;
ajaxify.register_events([
'event:new_topic',
'event:new_post'
]);
$('#new-topics-alert').on('click', function() {
$(this).hide();
});
var newTopicCount = 0,
newPostCount = 0;
socket.on('event:new_topic', function(data) {
++newTopicCount;
updateAlertText();
});
function updateAlertText() {
var text = '';
if (newTopicCount > 1)
text = 'There are ' + newTopicCount + ' new topics';
else if (newTopicCount === 1)
text = 'There is 1 new topic';
else
text = 'There are no new topics';
if (newPostCount > 1)
text += ' and ' + newPostCount + ' new posts.';
else if (newPostCount === 1)
text += ' and 1 new post.';
else
text += ' and no new posts.';
text += ' Click here to reload.';
$('#new-topics-alert').html(text).fadeIn('slow');
}
socket.on('event:new_post', function(data) {
++newPostCount;
updateAlertText();
});
$('#mark-allread-btn').on('click', function() {
var btn = $(this);
socket.emit('api:topics.markAllRead', {}, function(success) {
if (success) {
btn.remove();
$('#topics-container').empty();
$('#category-no-topics').removeClass('hidden');
app.alertSuccess('All topics marked as read!');
$('#numUnreadBadge')
.removeClass('badge-important')
.addClass('badge-inverse')
.html('0');
} else {
app.alertError('There was an error marking topics read!');
}
$('#new-topics-alert').on('click', function() {
$(this).hide();
});
});
function onTopicsLoaded(topics) {
socket.on('event:new_topic', function(data) {
var html = templates.prepare(templates['unread'].blocks['topics']).parse({
topics: topics
}),
container = $('#topics-container');
++newTopicCount;
updateAlertText();
$('#category-no-topics').remove();
container.append(html);
}
function loadMoreTopics() {
loadingMoreTopics = true;
socket.emit('api:topics.loadMoreUnreadTopics', {
after: parseInt($('#topics-container').attr('data-next-start'), 10)
}, function(data) {
if (data.topics && data.topics.length) {
onTopicsLoaded(data.topics);
$('#topics-container').attr('data-next-start', data.nextStart);
} else {
$('#load-more-btn').hide();
}
loadingMoreTopics = false;
});
}
$(window).off('scroll').on('scroll', function() {
var bottom = ($(document).height() - $(window).height()) * 0.9;
function updateAlertText() {
var text = '';
if ($(window).scrollTop() > bottom && !loadingMoreTopics) {
loadMoreTopics();
if (newTopicCount > 1)
text = 'There are ' + newTopicCount + ' new topics';
else if (newTopicCount === 1)
text = 'There is 1 new topic';
else
text = 'There are no new topics';
if (newPostCount > 1)
text += ' and ' + newPostCount + ' new posts.';
else if (newPostCount === 1)
text += ' and 1 new post.';
else
text += ' and no new posts.';
text += ' Click here to reload.';
$('#new-topics-alert').html(text).fadeIn('slow');
}
});
socket.on('event:new_post', function(data) {
++newPostCount;
updateAlertText();
});
$('#mark-allread-btn').on('click', function() {
var btn = $(this);
socket.emit('api:topics.markAllRead', {}, function(success) {
if (success) {
btn.remove();
$('#topics-container').empty();
$('#category-no-topics').removeClass('hidden');
app.alertSuccess('All topics marked as read!');
$('#numUnreadBadge')
.removeClass('badge-important')
.addClass('badge-inverse')
.html('0');
} else {
app.alertError('There was an error marking topics read!');
}
});
});
function onTopicsLoaded(topics) {
var html = templates.prepare(templates['unread'].blocks['topics']).parse({
topics: topics
}),
container = $('#topics-container');
$('#category-no-topics').remove();
container.append(html);
}
function loadMoreTopics() {
loadingMoreTopics = true;
socket.emit('api:topics.loadMoreUnreadTopics', {
after: parseInt($('#topics-container').attr('data-next-start'), 10)
}, function(data) {
if (data.topics && data.topics.length) {
onTopicsLoaded(data.topics);
$('#topics-container').attr('data-next-start', data.nextStart);
} else {
$('#load-more-btn').hide();
}
loadingMoreTopics = false;
});
}
$(window).off('scroll').on('scroll', function() {
var bottom = ($(document).height() - $(window).height()) * 0.9;
if ($(window).scrollTop() > bottom && !loadingMoreTopics) {
loadMoreTopics();
}
});
if ($("body").height() <= $(window).height() && $('#topics-container').children().length >= 20)
$('#load-more-btn').show();
if ($("body").height() <= $(window).height() && $('#topics-container').children().length >= 20)
$('#load-more-btn').show();
$('#load-more-btn').on('click', function() {
loadMoreTopics();
});
$('#load-more-btn').on('click', function() {
loadMoreTopics();
});
};
})();
return Unread;
});

View File

@@ -1,6 +1,7 @@
(function() {
define(function() {
var Users = {};
$(document).ready(function() {
Users.init = function() {
var timeoutId = 0;
var loadingMoreUsers = false;
@@ -131,6 +132,7 @@
loadMoreUsers();
}
});
});
};
}());
return Users;
});

View File

@@ -97,7 +97,4 @@
<input type="hidden" template-variable="yourid" value="{yourid}" />
<input type="hidden" template-variable="theirid" value="{theirid}" />
<input type="hidden" template-type="boolean" template-variable="isFollowing" value="{isFollowing}" />
<script type="text/javascript" src="{relative_path}/src/forum/account.js"></script>
<script type="text/javascript" src="{relative_path}/src/forum/accountheader.js"></script>
<input type="hidden" template-type="boolean" template-variable="isFollowing" value="{isFollowing}" />

View File

@@ -174,9 +174,3 @@
</div>
</div>
<input type="hidden" template-variable="gravatarpicture" value="{gravatarpicture}" />
<input type="hidden" template-variable="uploadedpicture" value="{uploadedpicture}" />
<script type="text/javascript" src="{relative_path}/src/forum/accountheader.js"></script>
<script type="text/javascript" src="{relative_path}/src/forum/accountedit.js"></script>

View File

@@ -26,6 +26,3 @@
<a id="submitBtn" href="#" class="btn btn-primary">Save changes</a>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/accountheader.js"></script>
<script type="text/javascript" src="{relative_path}/src/forum/accountsettings.js"></script>

View File

@@ -101,5 +101,3 @@
<div class="col-md-3"><i class="icon-adn"></i></div><div class="col-md-3"><i class="icon-android"></i></div><div class="col-md-3"><i class="icon-apple"></i></div><div class="col-md-3"><i class="icon-bitbucket"></i></div><div class="col-md-3"><i class="icon-bitbucket-sign"></i></div><div class="col-md-3"><i class="icon-bitcoin"></i></div><div class="col-md-3"><i class="icon-btc"></i></div><div class="col-md-3"><i class="icon-css3"></i></div><div class="col-md-3"><i class="icon-dribbble"></i></div><div class="col-md-3"><i class="icon-dropbox"></i></div><div class="col-md-3"><i class="icon-facebook"></i></div><div class="col-md-3"><i class="icon-facebook-sign"></i></div><div class="col-md-3"><i class="icon-flickr"></i></div><div class="col-md-3"><i class="icon-foursquare"></i></div><div class="col-md-3"><i class="icon-github"></i></div><div class="col-md-3"><i class="icon-github-alt"></i></div><div class="col-md-3"><i class="icon-github-sign"></i></div><div class="col-md-3"><i class="icon-gittip"></i></div><div class="col-md-3"><i class="icon-google-plus"></i></div><div class="col-md-3"><i class="icon-google-plus-sign"></i></div><div class="col-md-3"><i class="icon-html5"></i></div><div class="col-md-3"><i class="icon-instagram"></i></div><div class="col-md-3"><i class="icon-linkedin"></i></div><div class="col-md-3"><i class="icon-linkedin-sign"></i></div><div class="col-md-3"><i class="icon-linux"></i></div><div class="col-md-3"><i class="icon-maxcdn"></i></div><div class="col-md-3"><i class="icon-pinterest"></i></div><div class="col-md-3"><i class="icon-pinterest-sign"></i></div><div class="col-md-3"><i class="icon-renren"></i></div><div class="col-md-3"><i class="icon-skype"></i></div><div class="col-md-3"><i class="icon-stackexchange"></i></div><div class="col-md-3"><i class="icon-trello"></i></div><div class="col-md-3"><i class="icon-tumblr"></i></div><div class="col-md-3"><i class="icon-tumblr-sign"></i></div><div class="col-md-3"><i class="icon-twitter"></i></div><div class="col-md-3"><i class="icon-twitter-sign"></i></div><div class="col-md-3"><i class="icon-vk"></i></div><div class="col-md-3"><i class="icon-weibo"></i></div><div class="col-md-3"><i class="icon-windows"></i></div><div class="col-md-3"><i class="icon-xing"></i></div><div class="col-md-3"><i class="icon-xing-sign"></i></div><div class="col-md-3"><i class="icon-youtube"></i></div><div class="col-md-3"><i class="icon-youtube-play"></i></div><div class="col-md-3"><i class="icon-youtube-sign"></i></div>
<div class="col-md-3"><i class="icon-ambulance"></i></div><div class="col-md-3"><i class="icon-h-sign"></i></div><div class="col-md-3"><i class="icon-hospital"></i></div><div class="col-md-3"><i class="icon-medkit"></i></div><div class="col-md-3"><i class="icon-plus-sign-alt"></i></div><div class="col-md-3"><i class="icon-stethoscope"></i></div><div class="col-md-3"><i class="icon-user-md"></i></div>
</div></div></div>
<script type="text/javascript" src="{relative_path}/src/forum/admin/categories.js"></script>

View File

@@ -17,10 +17,7 @@
<button class="btn btn-lg btn-primary" id="save">Save</button>
<script>
var loadDelay = setInterval(function() {
if (nodebb_admin) {
nodebb_admin.prepare();
clearInterval(loadDelay);
}
}, 500);
require(['forum/admin/settings'], function(Settings) {
Settings.prepare();
});
</script>

View File

@@ -9,7 +9,7 @@
</div>
<script type="text/javascript">
$.getScript(RELATIVE_PATH + '/src/forum/admin/footer.js');
require(['forum/admin/footer']);
</script>
</body>

View File

@@ -17,10 +17,7 @@
<button class="btn btn-lg btn-primary" id="save">Save</button>
<script>
var loadDelay = setInterval(function() {
if (nodebb_admin) {
nodebb_admin.prepare();
clearInterval(loadDelay);
}
}, 500);
require(['forum/admin/settings'], function(Settings) {
Settings.prepare();
});
</script>

View File

@@ -96,5 +96,3 @@
</div>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/admin/groups.js"></script>

View File

@@ -25,7 +25,10 @@
<script>
require.config({
baseUrl: "{relative_path}/src/modules",
waitSeconds: 3
waitSeconds: 3,
paths: {
"forum": '../forum'
}
});
</script>
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">

View File

@@ -18,5 +18,3 @@
</p>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/admin/index.js"></script>

View File

@@ -24,10 +24,7 @@
<button class="btn btn-lg btn-primary" id="save" checked>Save</button>
<script>
var loadDelay = setInterval(function() {
if (nodebb_admin) {
nodebb_admin.prepare();
clearInterval(loadDelay);
}
}, 500);
require(['forum/admin/settings'], function(Settings) {
Settings.prepare();
});
</script>

View File

@@ -21,5 +21,3 @@
Full documentation regarding plugin authoring can be found in the <a target="_blank" href="https://github.com/designcreateplay/NodeBB/wiki/Writing-Plugins-for-NodeBB">NodeBB Wiki</a>.
</p>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/admin/plugins.js"></script>

View File

@@ -83,10 +83,7 @@
<button class="btn btn-lg btn-primary" id="save">Save</button>
<script>
var loadDelay = setInterval(function() {
if (nodebb_admin) {
nodebb_admin.prepare();
clearInterval(loadDelay);
}
}, 500);
require(['forum/admin/settings'], function(Settings) {
Settings.prepare();
});
</script>

View File

@@ -23,4 +23,10 @@
<button class="btn btn-warning" id="revert_theme">Revert</button> This will remove any custom theme applied to your NodeBB, and restore the base theme.
</p>
<script type="text/javascript" src="{relative_path}/src/forum/admin/themes.js"></script>
<script>
var bootswatchListener = function(data) {
require(['forum/admin/themes'], function(t) {
t.render(data);
});
}
</script>

View File

@@ -22,5 +22,3 @@
<div class="text-center">
<button id="topics_loadmore" class="btn btn-primary btn-lg">Load More Topics</button>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/admin/topics.js"></script>

View File

@@ -17,10 +17,7 @@
<button class="btn btn-lg btn-primary" id="save">Save</button>
<script>
var loadDelay = setInterval(function() {
if (nodebb_admin) {
nodebb_admin.prepare();
clearInterval(loadDelay);
}
}, 500);
require(['forum/admin/settings'], function(Settings) {
Settings.prepare();
});
</script>

View File

@@ -42,6 +42,3 @@
<button id="load-more-users-btn" class="btn btn-primary">Load More</button>
</div>
<input type="hidden" template-variable="yourid" value="{yourid}" />
<script type="text/javascript" src="{relative_path}/src/forum/admin/users.js"></script>

View File

@@ -96,6 +96,4 @@
<input type="hidden" template-variable="category_id" value="{category_id}" />
<input type="hidden" template-variable="twitter-intent-url" value="{twitter-intent-url}" />
<input type="hidden" template-variable="facebook-share-url" value="{facebook-share-url}" />
<input type="hidden" template-variable="google-share-url" value="{google-share-url}" />
<script type="text/javascript" src="{relative_path}/src/forum/category.js"></script>
<input type="hidden" template-variable="google-share-url" value="{google-share-url}" />

View File

@@ -22,6 +22,3 @@
</div>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/accountheader.js"></script>
<script type="text/javascript" src="{relative_path}/src/forum/favourites.js"></script>

View File

@@ -34,6 +34,3 @@
<input type="hidden" template-variable="yourid" value="{yourid}" />
<input type="hidden" template-variable="theirid" value="{theirid}" />
<input type="hidden" template-variable="followersCount" value="{followersCount}" />
<script type="text/javascript" src="{relative_path}/src/forum/followers.js"></script>
<script type="text/javascript" src="{relative_path}/src/forum/accountheader.js"></script>

View File

@@ -35,6 +35,3 @@
<input type="hidden" template-variable="yourid" value="{yourid}" />
<input type="hidden" template-variable="theirid" value="{theirid}" />
<input type="hidden" template-variable="followingCount" value="{followingCount}" />
<script type="text/javascript" src="{relative_path}/src/forum/following.js"></script>
<script type="text/javascript" src="{relative_path}/src/forum/accountheader.js"></script>

View File

@@ -53,7 +53,7 @@
</footer>
<script>
$.getScript(RELATIVE_PATH + '/src/forum/footer.js');
require(['forum/footer']);
</script>
</body>

View File

@@ -15,8 +15,14 @@
<script>
require.config({
baseUrl: "{relative_path}/src/modules",
waitSeconds: 3
waitSeconds: 3,
paths: {
"forum": '../forum'
}
});
requirejs.onError = function(err) {
console.log(err);
}
</script>
<link rel="stylesheet" type="text/css" href="{relative_path}/css/nodebb.css" />

View File

@@ -60,5 +60,3 @@
</div>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/login.js"></script>

View File

@@ -49,5 +49,3 @@
</ul>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/recent.js"></script>

View File

@@ -80,5 +80,3 @@
</div>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/register.js"></script>

View File

@@ -26,5 +26,3 @@
<button class="btn btn-primary btn-block btn-lg" id="reset" type="submit">Reset Password</button>
</form>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/reset.js"></script>

View File

@@ -34,6 +34,3 @@
</form>
</div>
<input type="hidden" template-variable="reset_code" value="{reset_code}" />
<script type="text/javascript" src="{relative_path}/src/forum/reset_code.js"></script>

View File

@@ -53,5 +53,3 @@
</ul>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/search.js"></script>

View File

@@ -199,7 +199,3 @@
<input type="hidden" template-variable="pinned" value="{pinned}" />
<input type="hidden" template-variable="topic_name" value="{topic_name}" />
<input type="hidden" template-variable="postcount" value="{postcount}" />
<script type="text/javascript" src="{relative_path}/src/forum/topic.js"></script>

View File

@@ -54,5 +54,3 @@
</div>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/unread.js"></script>

View File

@@ -45,5 +45,3 @@
<button id="load-more-users-btn" class="btn btn-primary">[[users:load_more]]</button>
</div>
</div>
<script type="text/javascript" src="{relative_path}/src/forum/users.js"></script>

View File

@@ -135,22 +135,22 @@ var express = require('express'),
app.use(function (req, res, next) {
res.status(404);
// respond with html page
if (req.accepts('html')) {
if (path.dirname(req.url) === '/src/forum') {
// Handle missing client-side scripts
res.type('text/javascript').send(200, '');
} else if (req.accepts('html')) {
// respond with html page
winston.warn('Route requested but not found: ' + req.url);
res.redirect(nconf.get('relative_path') + '/404');
return;
}
// respond with json
if (req.accepts('json')) {
res.send({
} else if (req.accepts('json')) {
// respond with json
res.json({
error: 'Not found'
});
return;
} else {
// default to plain-text. send()
res.type('txt').send('Not found');
}
// default to plain-text. send()
res.type('txt').send('Not found');
});
app.use(function (err, req, res, next) {