From f0ed816edb08352c6e564942b97cb4df4fb429fa Mon Sep 17 00:00:00 2001 From: A Catty Alpaca Date: Tue, 23 Dec 2014 23:49:15 +0100 Subject: [PATCH 001/164] fix generated widgets areas glitching on small screens because columns should always be in rows --- public/src/widgets.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/src/widgets.js b/public/src/widgets.js index 9e34ba9513..2200f58d5e 100644 --- a/public/src/widgets.js +++ b/public/src/widgets.js @@ -51,12 +51,12 @@ if (!area.length && window.location.pathname.indexOf('/admin') === -1 && renderedWidgets.length) { if (location === 'footer' && !$('#content [widget-area="footer"]').length) { - $('#content').append($('
')); + $('#content').append($('
')); } else if (location === 'sidebar' && !$('#content [widget-area="sidebar"]').length) { - $('#content > *').wrapAll($('
')); - $('#content').append($('
')); + $('#content > *').wrapAll($('
')); + $('#content').append($('
')); } else if (location === 'header' && !$('#content [widget-area="header"]').length) { - $('#content').prepend($('
')); + $('#content').prepend($('
')); } area = $('#content [widget-area="' + location + '"]'); From 6fe8d25166e4d3bfe5b9cc3b7831662c7d201375 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 16 Jan 2015 12:58:31 -0500 Subject: [PATCH 002/164] add uid to filter:topic.get --- src/topics.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/topics.js b/src/topics.js index 1e9df9958f..3135fd6a88 100644 --- a/src/topics.js +++ b/src/topics.js @@ -255,7 +255,9 @@ var async = require('async'), topicData.locked = parseInt(topicData.locked, 10) === 1; topicData.pinned = parseInt(topicData.pinned, 10) === 1; - plugins.fireHook('filter:topic.get', topicData, callback); + plugins.fireHook('filter:topic.get', {topic: topicData, uid: uid}, function(err, data) { + callback(err, data ? data.topics : null); + }); }); }); }; From 236fe91e953200fae651707293c556eff16deef6 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 16 Jan 2015 13:00:50 -0500 Subject: [PATCH 003/164] fix typo --- src/topics.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/topics.js b/src/topics.js index 3135fd6a88..d206b5c211 100644 --- a/src/topics.js +++ b/src/topics.js @@ -256,7 +256,7 @@ var async = require('async'), topicData.pinned = parseInt(topicData.pinned, 10) === 1; plugins.fireHook('filter:topic.get', {topic: topicData, uid: uid}, function(err, data) { - callback(err, data ? data.topics : null); + callback(err, data ? data.topic : null); }); }); }); From b333653464458c2cd27717768f28d9a356e8c3a7 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 16 Jan 2015 23:52:51 -0500 Subject: [PATCH 004/164] prevent js crash if responseJSON is undefined --- public/src/modules/uploader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/modules/uploader.js b/public/src/modules/uploader.js index d2f7612c0e..6efdbd988c 100644 --- a/public/src/modules/uploader.js +++ b/public/src/modules/uploader.js @@ -49,7 +49,7 @@ define('uploader', ['csrf'], function(csrf) { }, error: function(xhr) { xhr = maybeParse(xhr); - showAlert('error', xhr.responseJSON.error); + showAlert('error', xhr.responseJSON ? xhr.responseJSON.error : 'error uploading, code : ' + xhr.status); }, uploadProgress: function(event, position, total, percent) { From 6ccb35576cc6811eb51d42b9f1a72dc2f8e68000 Mon Sep 17 00:00:00 2001 From: TheBronx Date: Sun, 18 Jan 2015 13:38:42 +0100 Subject: [PATCH 005/164] new filter hooks on favourite actions #2620 before a favourite action is made, fire a filter hook so plugins can modify or cancel that action before it takes place. --- src/socket.io/posts.js | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 97b8e7ea74..7d4ae8ea37 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -168,22 +168,40 @@ function favouriteCommand(socket, command, eventName, notification, data, callba return callback(new Error('[[error:post-deleted]]')); } - favourites[command](data.pid, socket.uid, function(err, result) { + /* + hooks: + filter.post.upvote + filter.post.downvote + filter.post.unvote + filter.post.favourite + filter.post.unfavourite + */ + plugins.fireHook('filter:post.' + command, data, function(err, filteredData) { if (err) { return callback(err); } - socket.emit('posts.' + command, result); + executeFavouriteCommand(socket, command, eventName, notification, filteredData, callback); + }); + }); +} - if (result && eventName) { - websockets.in(data.room_id).emit('event:' + eventName, result); - } +function executeFavouriteCommand(socket, command, eventName, notification, data, callback) { + favourites[command](data.pid, socket.uid, function(err, result) { + if (err) { + return callback(err); + } - if (notification) { - SocketPosts.sendNotificationToPostOwner(data.pid, socket.uid, notification); - } - callback(); - }); + socket.emit('posts.' + command, result); + + if (result && eventName) { + websockets.in(data.room_id).emit('event:' + eventName, result); + } + + if (notification) { + SocketPosts.sendNotificationToPostOwner(data.pid, socket.uid, notification); + } + callback(); }); } From e3cf528b57a260745b1796cbf69d7532642e54e9 Mon Sep 17 00:00:00 2001 From: TheBronx Date: Sun, 18 Jan 2015 19:09:26 +0100 Subject: [PATCH 006/164] pass also user id on fireHook pass also user id on fireHook as suggested by @barisusakli --- src/socket.io/posts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 7d4ae8ea37..a040493942 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -176,7 +176,7 @@ function favouriteCommand(socket, command, eventName, notification, data, callba filter.post.favourite filter.post.unfavourite */ - plugins.fireHook('filter:post.' + command, data, function(err, filteredData) { + plugins.fireHook('filter:post.' + command, {data: data, uid: socket.uid}, function(err, filteredData) { if (err) { return callback(err); } From 0bd48ef023b1f06517fbafdf1bf0fe1f229911ed Mon Sep 17 00:00:00 2001 From: TheBronx Date: Sun, 18 Jan 2015 19:15:59 +0100 Subject: [PATCH 007/164] fix error in previous commit fix error in previous commit --- src/socket.io/posts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index a040493942..fb67639c94 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -181,7 +181,7 @@ function favouriteCommand(socket, command, eventName, notification, data, callba return callback(err); } - executeFavouriteCommand(socket, command, eventName, notification, filteredData, callback); + executeFavouriteCommand(socket, command, eventName, notification, filteredData.data, callback); }); }); } From 093e499bf8f584b82dddc67c89a7255f4ced6216 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 20 Jan 2015 20:55:22 -0500 Subject: [PATCH 008/164] defining module name in iconSelect module --- public/src/modules/iconSelect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/modules/iconSelect.js b/public/src/modules/iconSelect.js index 88ab1903ed..f21bd76e1f 100644 --- a/public/src/modules/iconSelect.js +++ b/public/src/modules/iconSelect.js @@ -2,7 +2,7 @@ /* globals define, bootbox */ -define(function() { +define('iconSelect', function() { var iconSelect = {}; iconSelect.init = function(el, onModified) { From 2917304f6c84da2baab5766a25e9e3a96ff95fe4 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 21 Jan 2015 16:14:31 -0500 Subject: [PATCH 009/164] companion commit to nodebb/nodebb-theme-vanilla@0d17032 --- public/src/client/groups/list.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index 38d70d7c4a..36f1e0f3e7 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -5,7 +5,7 @@ define('forum/groups/list', function() { var Groups = {}; Groups.init = function() { - var groupsEl = $('.groups.row'); + var groupsEl = $('#groups-list'); groupsEl.on('click', '.list-cover', function() { var groupName = $(this).parents('[data-group]').attr('data-group'); @@ -41,7 +41,7 @@ define('forum/groups/list', function() { }; Groups.search = function(query) { - var groupsEl = $('.groups.row'); + var groupsEl = $('#groups-list'); socket.emit('groups.search', { query: query, From 78a5843ae45e7cd8cb4cbab887112f05469536f2 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 21 Jan 2015 16:33:09 -0500 Subject: [PATCH 010/164] fixed tests by removing the broken one, heh heh heh --- src/groups.js | 21 --------------------- tests/groups.js | 11 ----------- 2 files changed, 32 deletions(-) diff --git a/src/groups.js b/src/groups.js index 87e6070757..58170eeaa8 100644 --- a/src/groups.js +++ b/src/groups.js @@ -265,27 +265,6 @@ var async = require('async'), db.getSetMembers('group:' + groupName + ':members', callback); }; - Groups.search = function(query, options, callback) { - if (!query) { - return callback(null, []); - } - - db.getSetMembers('groups', function(err, groups) { - if (err) { - return callback(err); - } - groups = groups.filter(function(groupName) { - return groupName.match(new RegExp(utils.escapeRegexChars(query), 'i')); - }); - - async.map(groups, function(groupName, next) { - Groups.get(groupName, options, next); - }, function(err, groups) { - callback(err, internals.filterGroups(groups, options)); - }); - }); - }; - Groups.isMember = function(uid, groupName, callback) { if (!uid || parseInt(uid, 10) <= 0) { return callback(null, false); diff --git a/tests/groups.js b/tests/groups.js index 47da1b8bbb..0025000828 100644 --- a/tests/groups.js +++ b/tests/groups.js @@ -88,17 +88,6 @@ describe('Groups', function() { done(); }); }); - - it('should return the "Hidden" group when "showAllGroups" option is passed in', function(done) { - Groups.search('hidden', { - showAllGroups: true - }, function(err, groups) { - if (err) return done(err); - assert.equal(1, groups.length); - assert.strictEqual('Hidden', groups[0].name); - done(); - }); - }); }); describe('.isMember()', function() { From 5fb8817b3c54e9c4e86eaf9c6dbeae34b732a0c1 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 22 Jan 2015 14:13:39 -0500 Subject: [PATCH 011/164] closes #2643 --- src/user/delete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/delete.js b/src/user/delete.js index b13fa1aa97..e6cdcebb19 100644 --- a/src/user/delete.js +++ b/src/user/delete.js @@ -85,7 +85,7 @@ module.exports = function(User) { db.deleteAll(keys, next); }, function(next) { - deleteUserIps(uids, next); + deleteUserIps(uid, next); }, function(next) { deleteUserFromFollowers(uid, next); From 77216acbcc341c0572b4a7324064fb0f19492c1f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 22 Jan 2015 14:18:19 -0500 Subject: [PATCH 012/164] user.delete test --- tests/user.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/user.js b/tests/user.js index 3ef541623b..381c6f0a44 100644 --- a/tests/user.js +++ b/tests/user.js @@ -171,6 +171,28 @@ describe('User', function() { }); }); + describe('.delete()', function() { + var uid; + before(function(done) { + User.create({username: 'userToDelete', password: '123456', email: 'delete@me.com'}, function(err, newUid) { + assert.ifError(err); + uid = newUid; + done(); + }); + }); + + it('should delete a user account', function(done) { + User.delete(uid, function(err) { + assert.ifError(err); + User.exists('userToDelete', function(err, exists) { + assert.ifError(err); + assert.equal(exists, false); + done(); + }); + }); + }); + }); + after(function() { db.flushdb(); }); From d895ca6827d203abd71f9170fb24fe2daa9014b7 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 22 Jan 2015 14:19:23 -0500 Subject: [PATCH 013/164] missing semicolon --- src/user/delete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/delete.js b/src/user/delete.js index e6cdcebb19..3440e810a4 100644 --- a/src/user/delete.js +++ b/src/user/delete.js @@ -127,7 +127,7 @@ module.exports = function(User) { } db.delete('uid:' + uid + ':ip', callback); }); - }) + }); } function deleteUserFromFollowers(uid, callback) { From 72f28b7b3831bc084ef5606c5a3c2c8760f1f579 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 22 Jan 2015 14:19:59 -0500 Subject: [PATCH 014/164] closed #2641 --- public/language/en_GB/error.json | 1 + public/src/client/groups/details.js | 2 +- src/groups.js | 21 +++++++++++++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index fed0c807c9..7e21a1290a 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -66,6 +66,7 @@ "group-already-exists": "Group already exists", "group-name-change-not-allowed": "Group name change not allowed", "group-already-member": "You are already part of this group", + "group-needs-owner": "This group requires at least one owner", "post-already-deleted": "This post has already been deleted", "post-already-restored": "This post has already been restored", diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js index b667176ae9..09826fb673 100644 --- a/public/src/client/groups/details.js +++ b/public/src/client/groups/details.js @@ -34,7 +34,7 @@ define('forum/groups/details', ['iconSelect', 'vendor/colorpicker/colorpicker', if (!err) { ownerFlagEl.toggleClass('invisible'); } else { - app.alertError(err); + app.alertError(err.message); } }); break; diff --git a/src/groups.js b/src/groups.js index fbb138dce5..beeddd19a9 100644 --- a/src/groups.js +++ b/src/groups.js @@ -659,8 +659,8 @@ var async = require('async'), Groups.requestMembership = function(groupName, uid, callback) { async.parallel({ - exists: async.apply(Groups.isMember, uid, groupName), - isMember: async.apply(Groups.exists, groupName) + exists: async.apply(Groups.exists, groupName), + isMember: async.apply(Groups.isMember, uid, groupName) }, function(err, checks) { if (!checks.exists) { return callback(new Error('[[error:no-group]]')); @@ -694,7 +694,12 @@ var async = require('async'), Groups.leave = function(groupName, uid, callback) { callback = callback || function() {}; - db.sortedSetRemove('group:' + groupName + ':members', uid, function(err) { + var tasks = [ + async.apply(db.sortedSetRemove, 'group:' + groupName + ':members', uid), + async.apply(db.setRemove, 'group:' + groupName + ':owners', uid) + ]; + + async.parallel(tasks, function(err) { if (err) { return callback(err); } @@ -891,7 +896,15 @@ var async = require('async'), Groups.ownership.rescind = function(toUid, groupName, callback) { // Note: No ownership checking is done here on purpose! - db.setRemove('group:' + groupName + ':owners', toUid, callback); + + // If the owners set only contains one member, error out! + db.setCount('group:' + groupName + ':owners', function(err, numOwners) { + if (numOwners <= 1) { + return callback(new Error('[[error:group-needs-owner]]')); + } + + db.setRemove('group:' + groupName + ':owners', toUid, callback); + }); }; Groups.search = function(query, options, callback) { From 070215b05ef45fc8cab78cc334098d3ce508a12b Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 22 Jan 2015 16:08:20 -0500 Subject: [PATCH 015/164] simplified isOwner check because there's no need to check admin status as admins automatically become owners now --- src/groups.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/groups.js b/src/groups.js index e7c1eed77b..7082ba5b65 100644 --- a/src/groups.js +++ b/src/groups.js @@ -884,22 +884,13 @@ var async = require('async'), Groups.updateCoverPosition(data.groupName, data.position, callback); }); - } + }; Groups.ownership = {}; Groups.ownership.isOwner = function(uid, groupName, callback) { - // Note: All admins are also owners - async.waterfall([ - async.apply(db.isSetMember, 'group:' + groupName + ':owners', uid), - function(isOwner, next) { - if (isOwner) { - return next(null, isOwner); - } - - user.isAdministrator(uid, next); - } - ], callback); + // Note: All admins automatically become owners upon joining + db.isSetMember('group:' + groupName + ':owners', uid, callback); }; Groups.ownership.grant = function(toUid, groupName, callback) { From ab69477b24ef9d44a0fd74d40d97ce4e3c7bc64b Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 27 Jan 2015 17:37:21 -0500 Subject: [PATCH 016/164] moved filter:user,get to central function --- src/controllers/users.js | 12 +++--------- src/user.js | 8 ++++++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/controllers/users.js b/src/controllers/users.js index a1d5b84f19..0a2d4d0d67 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -44,9 +44,7 @@ usersController.getOnlineUsers = function(req, res, next) { show_anon: anonymousUserCount ? '' : 'hide' }; - plugins.fireHook('filter:userlist.get', {data: userData, uid: uid}, function(err, userData) { - res.render('users', userData.data); - }); + res.render('users', userData); }); }; @@ -76,9 +74,7 @@ usersController.getUsers = function(set, count, req, res, next) { show_anon: 'hide' }; - plugins.fireHook('filter:userlist.get', {data: userData, uid: uid}, function(err, userData) { - res.render('users', userData.data); - }); + res.render('users', userData); }); }; @@ -118,9 +114,7 @@ usersController.getUsersForSearch = function(req, res, next) { show_anon: 'hide' }; - plugins.fireHook('filter:userlist.get', {data: userData, uid: uid}, function(err, userData) { - res.render('users', userData.data); - }); + res.render('users', userData); }); }; diff --git a/src/user.js b/src/user.js index 0a83994964..5e9382efd9 100644 --- a/src/user.js +++ b/src/user.js @@ -249,8 +249,12 @@ var async = require('async'), user.banned = parseInt(user.banned, 10) === 1; user['email:confirmed'] = parseInt(user['email:confirmed'], 10) === 1; }); - - callback(null, results.userData); + plugins.fireHook('filter:userlist.get', {users: results.userData}, function(err, data) { + if (err) { + return callback(err); + } + callback(null, data.users); + }); }); }); }; From 0dc0c39f4813745ebde5d812ef0b6d1f81f81975 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 27 Jan 2015 19:58:17 -0500 Subject: [PATCH 017/164] removed li selector --- public/src/client/topic/posts.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index 8e21928498..7fd55e8bd4 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -52,7 +52,7 @@ define('forum/topic/posts', [ function removeAlreadyAddedPosts() { data.posts = data.posts.filter(function(post) { - return $('#post-container li[data-pid="' + post.pid +'"]').length === 0; + return $('#post-container [data-pid="' + post.pid +'"]').length === 0; }); } @@ -64,8 +64,8 @@ define('forum/topic/posts', [ var firstPostVotes = parseInt(data.posts[0].votes, 10); var firstPostIndex = parseInt(data.posts[0].index, 10); - var firstReply = $('#post-container li.post-row[data-index!="0"]').first(); - var lastReply = $('#post-container li.post-row[data-index!="0"]').last(); + var firstReply = $('#post-container .post-row[data-index!="0"]').first(); + var lastReply = $('#post-container .post-row[data-index!="0"]').last(); if (config.topicPostSort === 'oldest_to_newest') { if (firstPostTimestamp < parseInt(firstReply.attr('data-timestamp'), 10)) { @@ -111,7 +111,7 @@ define('forum/topic/posts', [ // Save document height and position for future reference (about 5 lines down) var height = $(document).height(), scrollTop = $(document).scrollTop(), - originalPostEl = $('li[data-index="0"]'); + originalPostEl = $('.post-row[data-index="0"]'); // Insert the new post html.insertBefore(before); @@ -186,7 +186,7 @@ define('forum/topic/posts', [ function loadPostsAfter(after) { var tid = ajaxify.variables.get('topic_id'); - if (!utils.isNumber(tid) || !utils.isNumber(after) || (after === 0 && $('#post-container li.post-row[data-index="1"]').length)) { + if (!utils.isNumber(tid) || !utils.isNumber(after) || (after === 0 && $('#post-container .post-row[data-index="1"]').length)) { return; } @@ -235,13 +235,13 @@ define('forum/topic/posts', [ }; function showBottomPostBar() { - if($('#post-container .post-row').length > 1 || !$('#post-container li[data-index="0"]').length) { + if($('#post-container .post-row').length > 1 || !$('#post-container [data-index="0"]').length) { $('.bottom-post-bar').removeClass('hide'); } } function hidePostToolsForDeletedPosts(element) { - element.find('li.deleted').each(function() { + element.find('.post-row.deleted').each(function() { postTools.toggle($(this).attr('data-pid'), true); }); } From d47cd270dfffd1a899a8c27f66e495401d71a73c Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 27 Jan 2015 23:37:47 -0500 Subject: [PATCH 018/164] some random favourite typo --- src/favourites.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/favourites.js b/src/favourites.js index 0673626f51..c07468c78a 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -274,7 +274,7 @@ var async = require('async'), } if (!isFavouriting && !results.hasFavourited) { - return callback(new Error('[[error:alrady-unfavourited]]')); + return callback(new Error('[[error:already-unfavourited]]')); } async.waterfall([ From 370a60c14fd5409e4e059dffd11d2c2d17f1d17b Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 27 Jan 2015 23:50:01 -0500 Subject: [PATCH 019/164] potential bug @barisusakli I think you changed this, just pinging you in case --- public/src/client/topic/threadTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/client/topic/threadTools.js b/public/src/client/topic/threadTools.js index 41a3d532bf..b401a850ed 100644 --- a/public/src/client/topic/threadTools.js +++ b/public/src/client/topic/threadTools.js @@ -61,7 +61,7 @@ define('forum/topic/threadTools', ['forum/topic/fork', 'forum/topic/move'], func fork.init(); $('.posts').on('click', '.follow', function() { - socket.emit('topics.follow', tid, function(err, state) { + socket.emit('topics.toggleFollow', tid, function(err, state) { if(err) { return app.alert({ type: 'danger', From 5a3c056759be7e51e1154564197a1c39e43b5397 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 27 Jan 2015 23:50:10 -0500 Subject: [PATCH 020/164] removing li specific selector --- public/src/client/topic/events.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index 90f54ec064..40217b0969 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -69,7 +69,7 @@ define('forum/topic/events', [ }; function updatePostVotesAndUserReputation(data) { - var votes = $('li[data-pid="' + data.post.pid + '"] .votes'), + var votes = $('[data-pid="' + data.post.pid + '"] .votes'), reputationElements = $('.reputation[data-uid="' + data.post.uid + '"]'); votes.html(data.post.votes).attr('data-votes', data.post.votes); @@ -77,7 +77,7 @@ define('forum/topic/events', [ } function updateFavouriteCount(data) { - $('li[data-pid="' + data.post.pid + '"] .favouriteCount').html(data.post.reputation).attr('data-favourites', data.post.reputation); + $('[data-pid="' + data.post.pid + '"] .favouriteCount').html(data.post.reputation).attr('data-favourites', data.post.reputation); } function toggleTopicDeleteState(data) { @@ -139,14 +139,14 @@ define('forum/topic/events', [ } function onPostPurged(pid) { - $('#post-container li[data-pid="' + pid + '"]').fadeOut(500, function() { + $('#post-container [data-pid="' + pid + '"]').fadeOut(500, function() { $(this).remove(); }); postTools.updatePostCount(); } function togglePostDeleteState(data) { - var postEl = $('#post-container li[data-pid="' + data.pid + '"]'); + var postEl = $('#post-container [data-pid="' + data.pid + '"]'); if (!postEl.length) { return; @@ -166,7 +166,7 @@ define('forum/topic/events', [ } function togglePostFavourite(data) { - var favBtn = $('li[data-pid="' + data.post.pid + '"] .favourite'); + var favBtn = $('[data-pid="' + data.post.pid + '"] .favourite'); if (!favBtn.length) { return; } @@ -185,7 +185,7 @@ define('forum/topic/events', [ } function togglePostVote(data) { - var post = $('li[data-pid="' + data.post.pid + '"]'); + var post = $('[data-pid="' + data.post.pid + '"]'); post.find('.upvote').toggleClass('btn-primary upvoted', data.upvote); post.find('.downvote').toggleClass('btn-primary downvoted', data.downvote); From 8bc2d973527f2eaa252e0cca28770f612e3bb5ab Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 29 Jan 2015 10:08:48 -0500 Subject: [PATCH 021/164] stringify helper for t.js --- public/src/modules/helpers.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/public/src/modules/helpers.js b/public/src/modules/helpers.js index bc40bde658..e8f77a5614 100644 --- a/public/src/modules/helpers.js +++ b/public/src/modules/helpers.js @@ -4,7 +4,7 @@ // export the class if we are in a Node-like system. if (typeof module === 'object' && module.exports === exports) { - exports = module.exports/* = SemVer*/; + exports = module.exports/* = SemVer*/; } var helpers = {}; @@ -21,6 +21,11 @@ return ''; }; + helpers.stringify = function(obj) { + // Turns the incoming object into a JSON string + return JSON.stringify(obj).replace(/&/gm,"&").replace(//gm,">").replace(/"/g, '"'); + }; + // Groups helpers helpers.membershipBtn = function(groupObj) { if (groupObj.isMember) { From 6a2c35c263bba4319603932768bc971e74e110e7 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 29 Jan 2015 15:45:31 -0500 Subject: [PATCH 022/164] latest t.js --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c46f966b43..c67d9268e6 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "socket.io-redis": "^0.1.3", "socketio-wildcard": "~0.1.1", "string": "^3.0.0", - "templates.js": "0.1.10", + "templates.js": "0.1.15", "uglify-js": "git+https://github.com/julianlam/UglifyJS2.git", "underscore": "~1.7.0", "validator": "~3.26.0", From 6ebc048f1f3a626881b600887a7b43a93ca96077 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 29 Jan 2015 16:41:48 -0500 Subject: [PATCH 023/164] searching on keyup instead of enter key --- public/src/client/groups/list.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index 9ff22d9396..a3f9394450 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -31,9 +31,7 @@ define('forum/groups/list', function() { }); // Group searching - $('#search-text').on('keydown', function(e) { - if (e.keyCode === 13) { Groups.search(e); } - }); + $('#search-text').on('keyup', Groups.search); $('#search-button').on('click', Groups.search); }; From b54f2de504880fc26d40c41f7a347103c24c77ae Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 29 Jan 2015 17:02:20 -0500 Subject: [PATCH 024/164] pass uid to getUsers and getUsersFromSets --- src/controllers/admin/users.js | 3 ++- src/controllers/groups.js | 3 ++- src/controllers/users.js | 10 +++++----- src/search.js | 6 +++--- src/socket.io/admin/categories.js | 2 +- src/socket.io/admin/user.js | 2 +- src/socket.io/user.js | 5 +++-- src/user.js | 8 ++++---- src/user/follow.js | 2 +- src/user/search.js | 9 +++++---- 10 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/controllers/admin/users.js b/src/controllers/admin/users.js index 17944b8370..283302b48e 100644 --- a/src/controllers/admin/users.js +++ b/src/controllers/admin/users.js @@ -31,7 +31,8 @@ usersController.banned = function(req, res, next) { }; function getUsers(set, req, res, next) { - user.getUsersFromSet(set, 0, 49, function(err, users) { + var uid = req.user ? parseInt(req.user.uid, 10) : 0; + user.getUsersFromSet(set, uid, 0, 49, function(err, users) { if (err) { return next(err); } diff --git a/src/controllers/groups.js b/src/controllers/groups.js index c20993a7df..18ea0cbf2d 100644 --- a/src/controllers/groups.js +++ b/src/controllers/groups.js @@ -49,12 +49,13 @@ groupsController.details = function(req, res, next) { }; groupsController.members = function(req, res, next) { + var uid = req.user ? parseInt(req.user.uid, 10) : 0; async.waterfall([ function(next) { groups.getGroupNameByGroupSlug(req.params.slug, next); }, function(groupName, next) { - user.getUsersFromSet('group:' + groupName + ':members', 0, 49, next); + user.getUsersFromSet('group:' + groupName + ':members', uid, 0, 49, next); }, ], function(err, users) { if (err) { diff --git a/src/controllers/users.js b/src/controllers/users.js index 0a2d4d0d67..81001d0f3a 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -14,7 +14,7 @@ usersController.getOnlineUsers = function(req, res, next) { async.parallel({ users: function(next) { - user.getUsersFromSet('users:online', 0, 49, next); + user.getUsersFromSet('users:online', uid, 0, 49, next); }, count: function(next) { var now = Date.now(); @@ -63,7 +63,7 @@ usersController.getUsersSortedByJoinDate = function(req, res, next) { usersController.getUsers = function(set, count, req, res, next) { var uid = req.user ? req.user.uid : 0; - getUsersAndCount(set, count, function(err, data) { + getUsersAndCount(set, uid, count, function(err, data) { if (err) { return next(err); } @@ -78,10 +78,10 @@ usersController.getUsers = function(set, count, req, res, next) { }); }; -function getUsersAndCount(set, count, callback) { +function getUsersAndCount(set, uid, count, callback) { async.parallel({ users: function(next) { - user.getUsersFromSet(set, 0, count - 1, next); + user.getUsersFromSet(set, uid, 0, count - 1, next); }, count: function(next) { db.getObjectField('global', 'userCount', next); @@ -102,7 +102,7 @@ usersController.getUsersForSearch = function(req, res, next) { var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20, uid = req.user ? req.user.uid : 0; - getUsersAndCount('users:joindate', resultsPerPage, function(err, data) { + getUsersAndCount('users:joindate', uid, resultsPerPage, function(err, data) { if (err) { return next(err); } diff --git a/src/search.js b/src/search.js index c4a830f41a..e0be3ecafd 100644 --- a/src/search.js +++ b/src/search.js @@ -40,7 +40,7 @@ search.search = function(data, callback) { if (searchIn === 'posts') { searchInPosts(query, data.postedBy, uid, done); } else if (searchIn === 'users') { - searchInUsers(query, done); + searchInUsers(query, uid, done); } else if (searchIn === 'tags') { searchInTags(query, done); } else { @@ -99,8 +99,8 @@ function searchInPosts(query, postedBy, uid, callback) { }); } -function searchInUsers(query, callback) { - user.search({query: query}, function(err, results) { +function searchInUsers(query, uid, callback) { + user.search({query: query, uid: uid}, function(err, results) { callback(err, results ? results.users : null); }); } diff --git a/src/socket.io/admin/categories.js b/src/socket.io/admin/categories.js index 2ba036d7e0..9a9ef0ea7e 100644 --- a/src/socket.io/admin/categories.js +++ b/src/socket.io/admin/categories.js @@ -36,7 +36,7 @@ Categories.search = function(socket, data, callback) { var username = data.username, cid = data.cid; - user.search({query: username}, function(err, data) { + user.search({query: username, uid: socket.uid}, function(err, data) { if (err) { return callback(err); } diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index 9189727fbb..5f7199bf29 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -175,7 +175,7 @@ User.deleteUsers = function(socket, uids, callback) { }; User.search = function(socket, data, callback) { - user.search({query: data.query, searchBy: data.searchBy, startsWith: false}, function(err, searchData) { + user.search({query: data.query, searchBy: data.searchBy, startsWith: false, uid: socket.uid}, function(err, searchData) { if (err) { return callback(err); } diff --git a/src/socket.io/user.js b/src/socket.io/user.js index d28421c383..6004bdd469 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -66,7 +66,8 @@ SocketUser.search = function(socket, data, callback) { page: data.page, searchBy: data.searchBy, sortBy: data.sortBy, - filterBy: data.filterBy + filterBy: data.filterBy, + uid: socket.uid }, callback); }; @@ -332,7 +333,7 @@ SocketUser.loadMore = function(socket, data, callback) { var start = parseInt(data.after, 10), end = start + 19; - user.getUsersFromSet(data.set, start, end, function(err, userData) { + user.getUsersFromSet(data.set, socket.uid, start, end, function(err, userData) { if (err) { return callback(err); } diff --git a/src/user.js b/src/user.js index 80f7a951db..c7d8649d22 100644 --- a/src/user.js +++ b/src/user.js @@ -219,18 +219,18 @@ var async = require('async'), } }; - User.getUsersFromSet = function(set, start, stop, callback) { + User.getUsersFromSet = function(set, uid, start, stop, callback) { async.waterfall([ function(next) { User.getUidsFromSet(set, start, stop, next); }, function(uids, next) { - User.getUsers(uids, next); + User.getUsers(uids, uid, next); } ], callback); }; - User.getUsers = function(uids, callback) { + User.getUsers = function(uids, uid, callback) { var fields = ['uid', 'username', 'userslug', 'picture', 'status', 'banned', 'postcount', 'reputation', 'email:confirmed']; plugins.fireHook('filter:users.addFields', {fields: fields}, function(err, data) { if (err) { @@ -264,7 +264,7 @@ var async = require('async'), user['email:confirmed'] = parseInt(user['email:confirmed'], 10) === 1; }); - plugins.fireHook('filter:userlist.get', {users: results.userData}, function(err, data) { + plugins.fireHook('filter:userlist.get', {users: results.userData, uid: uid}, function(err, data) { if (err) { return callback(err); } diff --git a/src/user/follow.js b/src/user/follow.js index c3e2cb340c..6b0c0a3973 100644 --- a/src/user/follow.js +++ b/src/user/follow.js @@ -59,7 +59,7 @@ module.exports = function(User) { return callback(err); } - User.getUsers(uids, callback); + User.getUsers(uids, uid, callback); }); } diff --git a/src/user/search.js b/src/user/search.js index 95130bf68f..9df346f6ec 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -14,13 +14,14 @@ module.exports = function(User) { var searchBy = data.searchBy || ['username']; var startsWith = data.hasOwnProperty('startsWith') ? data.startsWith : true; var page = data.page || 1; + var uid = data.uid || 0; if (!query) { return callback(null, {timing: 0, users: [], matchCount: 0, pages: []}); } if (searchBy.indexOf('ip') !== -1) { - return searchByIP(query, callback); + return searchByIP(query, uid, callback); } var startTime = process.hrtime(); @@ -46,7 +47,7 @@ module.exports = function(User) { matchCount = uids.length; uids = uids.slice(start, end); - User.getUsers(uids, next); + User.getUsers(uids, uid, next); }, function(userData, next) { @@ -194,14 +195,14 @@ module.exports = function(User) { } } - function searchByIP(ip, callback) { + function searchByIP(ip, uid, callback) { var start = process.hrtime(); async.waterfall([ function(next) { db.getSortedSetRevRange('ip:' + ip + ':uid', 0, -1, next); }, function(uids, next) { - User.getUsers(uids, next); + User.getUsers(uids, uid, next); }, function(users, next) { var diff = process.hrtime(start); From 530bdbbd1a375b3b51bc2f9b824af36de45c2876 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 29 Jan 2015 17:10:49 -0500 Subject: [PATCH 025/164] dont rename if key doesn't exist --- src/database/redis/main.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/database/redis/main.js b/src/database/redis/main.js index 9b08e4af65..e9bd5b2f09 100644 --- a/src/database/redis/main.js +++ b/src/database/redis/main.js @@ -105,8 +105,13 @@ module.exports = function(redisClient, module) { module.rename = function(oldKey, newKey, callback) { callback = callback || function() {}; - redisClient.rename(oldKey, newKey, function(err, res) { - callback(err); + redisClient.exist(oldKey, function(err, exists) { + if (err || !exists) { + return callback(err); + } + redisClient.rename(oldKey, newKey, function(err, res) { + callback(err); + }); }); }; From d1a1cada19af00a8247f5550aa48a394baeb06ea Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 29 Jan 2015 17:12:12 -0500 Subject: [PATCH 026/164] fix typo --- src/database/redis/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database/redis/main.js b/src/database/redis/main.js index e9bd5b2f09..efe1b7958a 100644 --- a/src/database/redis/main.js +++ b/src/database/redis/main.js @@ -105,7 +105,7 @@ module.exports = function(redisClient, module) { module.rename = function(oldKey, newKey, callback) { callback = callback || function() {}; - redisClient.exist(oldKey, function(err, exists) { + redisClient.exists(oldKey, function(err, exists) { if (err || !exists) { return callback(err); } From f3f3ca8e5008a7d5303c6e02660384ad7ba6fcce Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 29 Jan 2015 19:25:01 -0500 Subject: [PATCH 027/164] if key isn't found dont error --- src/database/redis/main.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/database/redis/main.js b/src/database/redis/main.js index efe1b7958a..ebad6ae8e6 100644 --- a/src/database/redis/main.js +++ b/src/database/redis/main.js @@ -105,13 +105,8 @@ module.exports = function(redisClient, module) { module.rename = function(oldKey, newKey, callback) { callback = callback || function() {}; - redisClient.exists(oldKey, function(err, exists) { - if (err || !exists) { - return callback(err); - } - redisClient.rename(oldKey, newKey, function(err, res) { - callback(err); - }); + redisClient.rename(oldKey, newKey, function(err, res) { + callback(err && err.message !== 'ERR no such key' ? err : null); }); }; From 3bb9c9531fb761e654953f2802292d4cdc0279be Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 30 Jan 2015 12:25:07 -0500 Subject: [PATCH 028/164] catch errors from static hook --- src/plugins/hooks.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/hooks.js b/src/plugins/hooks.js index 6a2751545a..1d6c6f8e7b 100644 --- a/src/plugins/hooks.js +++ b/src/plugins/hooks.js @@ -123,12 +123,18 @@ module.exports = function(Plugins) { next(); }, 5000); - hookObj.method(params, function() { + try { + hookObj.method(params, function() { + clearTimeout(timeoutId); + if (!timedOut) { + next.apply(null, arguments); + } + }); + } catch(err) { + winston.error('[plugins] Error executing \'' + hook + '\' in plugin \'' + hookObj.id + '\''); clearTimeout(timeoutId); - if (!timedOut) { - next.apply(null, arguments); - } - }); + next(); + } } else { next(); } From 60e052e788294d798f73f991ac7965da1290e579 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 30 Jan 2015 12:28:29 -0500 Subject: [PATCH 029/164] closes #2674 --- public/src/client/topic/threadTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/client/topic/threadTools.js b/public/src/client/topic/threadTools.js index 41a3d532bf..b401a850ed 100644 --- a/public/src/client/topic/threadTools.js +++ b/public/src/client/topic/threadTools.js @@ -61,7 +61,7 @@ define('forum/topic/threadTools', ['forum/topic/fork', 'forum/topic/move'], func fork.init(); $('.posts').on('click', '.follow', function() { - socket.emit('topics.follow', tid, function(err, state) { + socket.emit('topics.toggleFollow', tid, function(err, state) { if(err) { return app.alert({ type: 'danger', From 4f5918390a87fe9d13b8f1e30065364d210ceab5 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Fri, 30 Jan 2015 14:19:15 -0500 Subject: [PATCH 030/164] if user search is blank, return all users --- public/src/client/users.js | 5 ----- src/user/search.js | 4 ---- 2 files changed, 9 deletions(-) diff --git a/public/src/client/users.js b/public/src/client/users.js index b96f3f5501..c3f374c4ff 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -115,11 +115,6 @@ define('forum/users', function() { var username = $('#search-user').val(); var notify = $('#user-notfound-notify'); page = page || 1; - if (!username) { - notify.html(''); - notify.parent().removeClass('btn-warning label-warning btn-success label-success'); - return; - } notify.html(''); var filters = []; diff --git a/src/user/search.js b/src/user/search.js index 9df346f6ec..34140005e1 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -16,10 +16,6 @@ module.exports = function(User) { var page = data.page || 1; var uid = data.uid || 0; - if (!query) { - return callback(null, {timing: 0, users: [], matchCount: 0, pages: []}); - } - if (searchBy.indexOf('ip') !== -1) { return searchByIP(query, uid, callback); } From 4a7ec3ccc6b0b00b76c0996fa19148a957d6e163 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 15:48:17 -0500 Subject: [PATCH 031/164] added groups page to user profile --- public/src/client/groups/list.js | 4 ++-- src/controllers/accounts.js | 23 +++++++++++++++++++++++ src/routes/index.js | 1 + src/views/config.json | 1 + 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index 0410a9fa17..d0b4c69b50 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -8,9 +8,9 @@ define('forum/groups/list', function() { var groupsEl = $('#groups-list'); groupsEl.on('click', '.list-cover', function() { - var groupName = $(this).parents('[data-group]').attr('data-group'); + var groupSlug = $(this).parents('[data-slug]').attr('data-slug'); - ajaxify.go('groups/' + utils.slugify(groupName)); + ajaxify.go('groups/' + groupSlug); }); // Group creation diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js index 741de9a626..c55977a351 100644 --- a/src/controllers/accounts.js +++ b/src/controllers/accounts.js @@ -233,6 +233,29 @@ accountsController.getTopics = function(req, res, next) { getFromUserSet('account/topics', 'topics', topics.getTopicsFromSet, 'topics', req, res, next); }; +accountsController.getGroups = function(req, res, next) { + var callerUID = req.user ? parseInt(req.user.uid, 10) : 0; + + getBaseUser(req.params.userslug, callerUID, function(err, userData) { + if (err) { + return next(err); + } + + if (!userData) { + return helpers.notFound(req, res); + } + + groups.getUserGroups([userData.uid], function(err, groups) { + if (err) { + return next(err); + } + + userData.groups = groups[0]; + + res.render('account/groups', userData); + }); + }); +}; function getFromUserSet(tpl, set, method, type, req, res, next) { var callerUID = req.user ? parseInt(req.user.uid, 10) : 0; diff --git a/src/routes/index.js b/src/routes/index.js index 1af03e0930..f8012c9456 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -68,6 +68,7 @@ function accountRoutes(app, middleware, controllers) { setupPageRoute(app, '/user/:userslug/followers', middleware, middlewares, controllers.accounts.getFollowers); setupPageRoute(app, '/user/:userslug/posts', middleware, middlewares, controllers.accounts.getPosts); setupPageRoute(app, '/user/:userslug/topics', middleware, middlewares, controllers.accounts.getTopics); + setupPageRoute(app, '/user/:userslug/groups', middleware, middlewares, controllers.accounts.getGroups); setupPageRoute(app, '/user/:userslug/favourites', middleware, accountMiddlewares, controllers.accounts.getFavourites); setupPageRoute(app, '/user/:userslug/watched', middleware, accountMiddlewares, controllers.accounts.getWatchedTopics); diff --git a/src/views/config.json b/src/views/config.json index 70997cf4a8..26ae7b692c 100644 --- a/src/views/config.json +++ b/src/views/config.json @@ -14,6 +14,7 @@ "^user/.*/watched": "account/watched", "^user/.*/posts": "account/posts", "^user/.*/topics": "account/topics", + "^user/.*/groups": "account/groups", "^user/[^\/]+": "account/profile", "^reset/.*": "reset_code", "^tags/.*": "tag", From c8f87e5d363678477fa5ef33b28544dccc59adf8 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 30 Jan 2015 16:16:49 -0500 Subject: [PATCH 032/164] removed console.log --- public/src/client/account/watched.js | 1 - 1 file changed, 1 deletion(-) diff --git a/public/src/client/account/watched.js b/public/src/client/account/watched.js index bd0e8282dd..9a502b1ee8 100644 --- a/public/src/client/account/watched.js +++ b/public/src/client/account/watched.js @@ -11,7 +11,6 @@ define('forum/account/watched', ['forum/account/header', 'forum/infinitescroll'] }; function loadMore(direction) { - console.log(direction); if (direction < 0) { return; } From da0b2c84e675ec03fc4f73568c65d97afa23036e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 16:24:57 -0500 Subject: [PATCH 033/164] passing memberCount and createTime into getUserGroups --- src/groups.js | 54 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/groups.js b/src/groups.js index 4a7611c531..4eca55c05d 100644 --- a/src/groups.js +++ b/src/groups.js @@ -781,35 +781,51 @@ var async = require('async'), groupData = groupData.filter(function(group) { return parseInt(group.hidden, 10) !== 1 && !!group.userTitle; + }).map(function(group) { + group.createtimeISO = utils.toISOString(group.createtime); + return group; }); - var groupSets = groupData.map(function(group) { - group.labelColor = group.labelColor || '#000000'; + async.map(groupData, function(groupObj, next) { + Groups.getMemberCount(groupObj.name, function(err, memberCount) { + if (err) { return next(err); } - if (!group['cover:url']) { - group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; - group['cover:position'] = '50% 50%'; + groupObj.memberCount = memberCount; + next(err, groupObj); + }); + }, function(err, groupData) { + if (err) { + return callback(err); } - return 'group:' + group.name + ':members'; - }); + var groupSets = groupData.map(function(group) { + group.labelColor = group.labelColor || '#000000'; - async.map(uids, function(uid, next) { - db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { - if (err) { - return next(err); + if (!group['cover:url']) { + group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; + group['cover:position'] = '50% 50%'; } - var memberOf = []; - isMembers.forEach(function(isMember, index) { - if (isMember) { - memberOf.push(groupData[index]); + return 'group:' + group.name + ':members'; + }); + + async.map(uids, function(uid, next) { + db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { + if (err) { + return next(err); } - }); - next(null, memberOf); - }); - }, callback); + var memberOf = []; + isMembers.forEach(function(isMember, index) { + if (isMember) { + memberOf.push(groupData[index]); + } + }); + + next(null, memberOf); + }); + }, callback); + }); }); }); }; From b62337b0b90e124c9f444a54b08d2e6c10ef2921 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 16:27:29 -0500 Subject: [PATCH 034/164] fixed browser title in user groups page --- public/language/en_GB/pages.json | 1 + 1 file changed, 1 insertion(+) diff --git a/public/language/en_GB/pages.json b/public/language/en_GB/pages.json index 8b231f8a94..4095ae38a3 100644 --- a/public/language/en_GB/pages.json +++ b/public/language/en_GB/pages.json @@ -11,6 +11,7 @@ "user.followers": "People who Follow %1", "user.posts": "Posts made by %1", "user.topics": "Topics created by %1", + "user.groups": "%1's Groups", "user.favourites": "%1's Favourite Posts", "user.settings": "User Settings", From e4e9020e1f4f058f16f68de0c0de813ce406c184 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 15:48:17 -0500 Subject: [PATCH 035/164] added groups page to user profile --- public/src/client/groups/list.js | 4 ++-- src/controllers/accounts.js | 23 +++++++++++++++++++++++ src/routes/index.js | 1 + src/views/config.json | 1 + 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index 0410a9fa17..d0b4c69b50 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -8,9 +8,9 @@ define('forum/groups/list', function() { var groupsEl = $('#groups-list'); groupsEl.on('click', '.list-cover', function() { - var groupName = $(this).parents('[data-group]').attr('data-group'); + var groupSlug = $(this).parents('[data-slug]').attr('data-slug'); - ajaxify.go('groups/' + utils.slugify(groupName)); + ajaxify.go('groups/' + groupSlug); }); // Group creation diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js index 741de9a626..c55977a351 100644 --- a/src/controllers/accounts.js +++ b/src/controllers/accounts.js @@ -233,6 +233,29 @@ accountsController.getTopics = function(req, res, next) { getFromUserSet('account/topics', 'topics', topics.getTopicsFromSet, 'topics', req, res, next); }; +accountsController.getGroups = function(req, res, next) { + var callerUID = req.user ? parseInt(req.user.uid, 10) : 0; + + getBaseUser(req.params.userslug, callerUID, function(err, userData) { + if (err) { + return next(err); + } + + if (!userData) { + return helpers.notFound(req, res); + } + + groups.getUserGroups([userData.uid], function(err, groups) { + if (err) { + return next(err); + } + + userData.groups = groups[0]; + + res.render('account/groups', userData); + }); + }); +}; function getFromUserSet(tpl, set, method, type, req, res, next) { var callerUID = req.user ? parseInt(req.user.uid, 10) : 0; diff --git a/src/routes/index.js b/src/routes/index.js index 1af03e0930..f8012c9456 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -68,6 +68,7 @@ function accountRoutes(app, middleware, controllers) { setupPageRoute(app, '/user/:userslug/followers', middleware, middlewares, controllers.accounts.getFollowers); setupPageRoute(app, '/user/:userslug/posts', middleware, middlewares, controllers.accounts.getPosts); setupPageRoute(app, '/user/:userslug/topics', middleware, middlewares, controllers.accounts.getTopics); + setupPageRoute(app, '/user/:userslug/groups', middleware, middlewares, controllers.accounts.getGroups); setupPageRoute(app, '/user/:userslug/favourites', middleware, accountMiddlewares, controllers.accounts.getFavourites); setupPageRoute(app, '/user/:userslug/watched', middleware, accountMiddlewares, controllers.accounts.getWatchedTopics); diff --git a/src/views/config.json b/src/views/config.json index 70997cf4a8..26ae7b692c 100644 --- a/src/views/config.json +++ b/src/views/config.json @@ -14,6 +14,7 @@ "^user/.*/watched": "account/watched", "^user/.*/posts": "account/posts", "^user/.*/topics": "account/topics", + "^user/.*/groups": "account/groups", "^user/[^\/]+": "account/profile", "^reset/.*": "reset_code", "^tags/.*": "tag", From ecfa8f7a7df276085c0b8a6d100c46f99bc202ef Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 16:24:57 -0500 Subject: [PATCH 036/164] passing memberCount and createTime into getUserGroups --- src/groups.js | 54 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/groups.js b/src/groups.js index 4a7611c531..4eca55c05d 100644 --- a/src/groups.js +++ b/src/groups.js @@ -781,35 +781,51 @@ var async = require('async'), groupData = groupData.filter(function(group) { return parseInt(group.hidden, 10) !== 1 && !!group.userTitle; + }).map(function(group) { + group.createtimeISO = utils.toISOString(group.createtime); + return group; }); - var groupSets = groupData.map(function(group) { - group.labelColor = group.labelColor || '#000000'; + async.map(groupData, function(groupObj, next) { + Groups.getMemberCount(groupObj.name, function(err, memberCount) { + if (err) { return next(err); } - if (!group['cover:url']) { - group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; - group['cover:position'] = '50% 50%'; + groupObj.memberCount = memberCount; + next(err, groupObj); + }); + }, function(err, groupData) { + if (err) { + return callback(err); } - return 'group:' + group.name + ':members'; - }); + var groupSets = groupData.map(function(group) { + group.labelColor = group.labelColor || '#000000'; - async.map(uids, function(uid, next) { - db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { - if (err) { - return next(err); + if (!group['cover:url']) { + group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; + group['cover:position'] = '50% 50%'; } - var memberOf = []; - isMembers.forEach(function(isMember, index) { - if (isMember) { - memberOf.push(groupData[index]); + return 'group:' + group.name + ':members'; + }); + + async.map(uids, function(uid, next) { + db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { + if (err) { + return next(err); } - }); - next(null, memberOf); - }); - }, callback); + var memberOf = []; + isMembers.forEach(function(isMember, index) { + if (isMember) { + memberOf.push(groupData[index]); + } + }); + + next(null, memberOf); + }); + }, callback); + }); }); }); }; From 607e88b3c3ad28740c49b53105e39c82934db7ff Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 30 Jan 2015 16:27:29 -0500 Subject: [PATCH 037/164] fixed browser title in user groups page --- public/language/en_GB/pages.json | 1 + 1 file changed, 1 insertion(+) diff --git a/public/language/en_GB/pages.json b/public/language/en_GB/pages.json index 8b231f8a94..4095ae38a3 100644 --- a/public/language/en_GB/pages.json +++ b/public/language/en_GB/pages.json @@ -11,6 +11,7 @@ "user.followers": "People who Follow %1", "user.posts": "Posts made by %1", "user.topics": "Topics created by %1", + "user.groups": "%1's Groups", "user.favourites": "%1's Favourite Posts", "user.settings": "User Settings", From dc2a2aa98ec372c7c114dedf2904411e3c40efec Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 30 Jan 2015 22:38:42 -0500 Subject: [PATCH 038/164] store group member count in group hash yet another upgrade script --- src/groups.js | 140 ++++++++++++++++++++++++------------------------- src/upgrade.js | 37 ++++++++++++- 2 files changed, 104 insertions(+), 73 deletions(-) diff --git a/src/groups.js b/src/groups.js index 4eca55c05d..7e41b94b02 100644 --- a/src/groups.js +++ b/src/groups.js @@ -299,7 +299,7 @@ var async = require('async'), }; Groups.getMemberCount = function(groupName, callback) { - db.sortedSetCard('group:' + groupName + ':members', callback); + db.getObjectField('group:' + groupName, 'memberCount', callback); }; Groups.isMemberOfGroupList = function(uid, groupListKey, callback) { @@ -611,46 +611,56 @@ var async = require('async'), }; Groups.join = function(groupName, uid, callback) { - callback = callback || function() {}; - - Groups.exists(groupName, function(err, exists) { - if (exists) { - var tasks = [ - async.apply(db.sortedSetAdd, 'group:' + groupName + ':members', Date.now(), uid) - ]; + function join() { + var tasks = [ + async.apply(db.sortedSetAdd, 'group:' + groupName + ':members', Date.now(), uid), + async.apply(db.incrObjectField, 'group:' + groupName, 'memberCount') + ]; - user.isAdministrator(uid, function(err, isAdmin) { + async.waterfall([ + function(next) { + user.isAdministrator(uid, next); + }, + function(isAdmin, next) { if (isAdmin) { tasks.push(async.apply(db.setAdd, 'group:' + groupName + ':owners', uid)); } + async.parallel(tasks, next); + } + ], function(err, results) { + if (err) { + return callback(err); + } + plugins.fireHook('action:group.join', { + groupName: groupName, + uid: uid + }); + callback(); + }); + } - async.parallel(tasks, function(err) { - plugins.fireHook('action:group.join', { - groupName: groupName, - uid: uid - }); + callback = callback || function() {}; - callback(); - }); - }); - } else { - Groups.create({ - name: groupName, - description: '', - hidden: 1 - }, function(err) { - if (err && err.message !== '[[error:group-already-exists]]') { - winston.error('[groups.join] Could not create new hidden group: ' + err.message); - return callback(err); - } + Groups.exists(groupName, function(err, exists) { + if (err) { + return callback(err); + } - db.sortedSetAdd('group:' + groupName + ':members', Date.now(), uid, callback); - plugins.fireHook('action:group.join', { - groupName: groupName, - uid: uid - }); - }); + if (exists) { + return join(); } + + Groups.create({ + name: groupName, + description: '', + hidden: 1 + }, function(err) { + if (err && err.message !== '[[error:group-already-exists]]') { + winston.error('[groups.join] Could not create new hidden group: ' + err.message); + return callback(err); + } + join(); + }); }); }; @@ -692,9 +702,10 @@ var async = require('async'), callback = callback || function() {}; var tasks = [ - async.apply(db.sortedSetRemove, 'group:' + groupName + ':members', uid), - async.apply(db.setRemove, 'group:' + groupName + ':owners', uid) - ]; + async.apply(db.sortedSetRemove, 'group:' + groupName + ':members', uid), + async.apply(db.setRemove, 'group:' + groupName + ':owners', uid), + async.apply(db.decrObjectField, 'group:' + groupName, 'memberCount') + ]; async.parallel(tasks, function(err) { if (err) { @@ -715,7 +726,7 @@ var async = require('async'), if (group.hidden && group.memberCount === 0) { Groups.destroy(groupName, callback); } else { - return callback(); + callback(); } }); }); @@ -781,51 +792,36 @@ var async = require('async'), groupData = groupData.filter(function(group) { return parseInt(group.hidden, 10) !== 1 && !!group.userTitle; - }).map(function(group) { - group.createtimeISO = utils.toISOString(group.createtime); - return group; }); - async.map(groupData, function(groupObj, next) { - Groups.getMemberCount(groupObj.name, function(err, memberCount) { - if (err) { return next(err); } + var groupSets = groupData.map(function(group) { + group.labelColor = group.labelColor || '#000000'; + group.createtimeISO = utils.toISOString(group.createtime); - groupObj.memberCount = memberCount; - next(err, groupObj); - }); - }, function(err, groupData) { - if (err) { - return callback(err); + if (!group['cover:url']) { + group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; + group['cover:position'] = '50% 50%'; } - var groupSets = groupData.map(function(group) { - group.labelColor = group.labelColor || '#000000'; + return 'group:' + group.name + ':members'; + }); - if (!group['cover:url']) { - group['cover:url'] = nconf.get('relative_path') + '/images/cover-default.png'; - group['cover:position'] = '50% 50%'; + async.map(uids, function(uid, next) { + db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { + if (err) { + return next(err); } - return 'group:' + group.name + ':members'; - }); - - async.map(uids, function(uid, next) { - db.isMemberOfSortedSets(groupSets, uid, function(err, isMembers) { - if (err) { - return next(err); + var memberOf = []; + isMembers.forEach(function(isMember, index) { + if (isMember) { + memberOf.push(groupData[index]); } - - var memberOf = []; - isMembers.forEach(function(isMember, index) { - if (isMember) { - memberOf.push(groupData[index]); - } - }); - - next(null, memberOf); }); - }, callback); - }); + + next(null, memberOf); + }); + }, callback); }); }); }; diff --git a/src/upgrade.js b/src/upgrade.js index d433c9c06f..05a186ea69 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -21,7 +21,7 @@ var db = require('./database'), schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema - latestSchema = Date.UTC(2015, 0, 21); + latestSchema = Date.UTC(2015, 0, 30); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -773,6 +773,41 @@ Upgrade.upgrade = function(callback) { winston.info('[2015/01/21] Upgrading groups to sorted set skipped'); next(); } + }, + function(next) { + thisSchemaDate = Date.UTC(2015, 0, 30); + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.info('[2015/01/30] Adding group member counts'); + + db.getSortedSetRange('groups:createtime', 0, -1, function(err, groupNames) { + if (err) { + return next(err); + } + + var now = Date.now(); + async.each(groupNames, function(groupName, next) { + db.sortedSetCard('group:' + groupName + ':members', function(err, memberCount) { + console.log(groupName, memberCount); + if (err) { + return next(err); + } + + if (parseInt(memberCount, 10)) { + db.setObjectField('group:' + groupName, 'memberCount', memberCount, next); + } else { + next(); + } + }); + }, function(err) { + winston.info('[2015/01/30] Adding group member counts done'); + Upgrade.update(thisSchemaDate, next); + }); + }); + } else { + winston.info('[2015/01/30] Adding group member counts skipped'); + next(); + } } // Add new schema updates here From 2c033bf286eef35c1885b4da92cdde50c496e948 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 31 Jan 2015 00:00:02 -0500 Subject: [PATCH 039/164] set memberCount to 0 on creation --- src/groups.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/groups.js b/src/groups.js index 7e41b94b02..462a0854a8 100644 --- a/src/groups.js +++ b/src/groups.js @@ -448,6 +448,7 @@ var async = require('async'), createtime: now, userTitle: data.name, description: data.description || '', + memberCount: 0, deleted: '0', hidden: data.hidden || '0', system: system ? '1' : '0', From c16689503d2eee42ecff5418a98457b5d7c4a1e5 Mon Sep 17 00:00:00 2001 From: Mega Date: Sat, 31 Jan 2015 15:34:40 +0300 Subject: [PATCH 040/164] Added as argument post id in action:posts.edited --- public/src/client/topic/events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index 90f54ec064..0990be01c6 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -111,7 +111,7 @@ define('forum/topic/events', [ app.replaceSelfLinks(editedPostEl.find('a')); editedPostEl.fadeIn(250); - $(window).trigger('action:posts.edited'); + $(window).trigger('action:posts.edited', data.pid); }); if (data.tags && tagsUpdated(data.tags)) { From 2e1d1ac665471cd106d73cd160de0d48ae3901aa Mon Sep 17 00:00:00 2001 From: Mega Date: Sat, 31 Jan 2015 18:06:54 +0300 Subject: [PATCH 041/164] Uploading avatar causes crash on 0.6.1-dev --- src/user.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/user.js b/src/user.js index ccb30fecfb..79060f020b 100644 --- a/src/user.js +++ b/src/user.js @@ -162,6 +162,7 @@ var async = require('async'), }; User.setUserField = function(uid, field, value, callback) { + callback = callback || function() {}; db.setObjectField('user:' + uid, field, value, function(err) { if (err) { return callback(err) @@ -172,6 +173,7 @@ var async = require('async'), }; User.setUserFields = function(uid, data, callback) { + callback = callback || function() {}; db.setObject('user:' + uid, data, function(err) { if (err) { return callback(err); From dc0229fc73e4b53898689ea14dfd2b2ed89358fd Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 31 Jan 2015 13:10:43 -0500 Subject: [PATCH 042/164] closes #2677 --- public/src/admin/settings.js | 19 ++++++++++++------- src/sitemap.js | 5 +++++ src/socket.io/admin.js | 5 +++++ src/views/admin/settings/web-crawler.tpl | 8 ++++++-- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/public/src/admin/settings.js b/public/src/admin/settings.js index 3dca037514..98ab422b14 100644 --- a/public/src/admin/settings.js +++ b/public/src/admin/settings.js @@ -86,14 +86,19 @@ define('admin/settings', ['uploader', 'sounds'], function(uploader, sounds) { $('button[data-action="email.test"]').off('click').on('click', function() { socket.emit('admin.email.test', function(err) { - app.alert({ - alert_id: 'test_email_sent', - type: !err ? 'info' : 'danger', - title: 'Test Email Sent', - message: err ? err.message : '', - timeout: 2500 - }); + if (err) { + return app.alertError(err.message); + } + app.alertSuccess('Test Email Sent'); + }); + return false; + }); + + $('#clear-sitemap-cache').off('click').on('click', function() { + socket.emit('admin.settings.clearSitemapCache', function() { + app.alertSuccess('Sitemap Cache Cleared!'); }); + return false; }); if (typeof callback === 'function') { diff --git a/src/sitemap.js b/src/sitemap.js index ffc072b871..16452a8f30 100644 --- a/src/sitemap.js +++ b/src/sitemap.js @@ -107,6 +107,11 @@ var path = require('path'), sitemap.obj.toXML(callback); }); + }, + clearCache: function() { + if (sitemap.obj) { + sitemap.obj.clearCache(); + } } }; diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index b659397220..36efef49f9 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -175,6 +175,11 @@ SocketAdmin.settings.set = function(socket, data, callback) { meta.settings.set(data.hash, data.values, callback); }; +SocketAdmin.settings.clearSitemapCache = function(socket, data, callback) { + require('../sitemap').clearCache(); + callback(); +}; + SocketAdmin.email.test = function(socket, data, callback) { if (plugins.hasListeners('action:email.send')) { emailer.send('test', socket.uid, { diff --git a/src/views/admin/settings/web-crawler.tpl b/src/views/admin/settings/web-crawler.tpl index c8fb03b0ff..349b5f6664 100644 --- a/src/views/admin/settings/web-crawler.tpl +++ b/src/views/admin/settings/web-crawler.tpl @@ -26,8 +26,12 @@ - - +
+ + +
+ + From 7363c711809f3e326e7fb29b8e5a3be391b2b018 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 31 Jan 2015 13:37:31 -0500 Subject: [PATCH 043/164] sitemap style --- src/sitemap.js | 200 ++++++++++++++++++++++++++----------------------- 1 file changed, 106 insertions(+), 94 deletions(-) diff --git a/src/sitemap.js b/src/sitemap.js index 16452a8f30..aab7451a61 100644 --- a/src/sitemap.js +++ b/src/sitemap.js @@ -10,109 +10,121 @@ var path = require('path'), topics = require('./topics'), privileges = require('./privileges'), meta = require('./meta'), - utils = require('../public/src/utils'), - sitemap = { - obj: undefined, - getStaticUrls: function(callback) { - callback(null, [{ - url: '', - changefreq: 'weekly', - priority: '0.6' - }, { - url: '/recent', - changefreq: 'daily', - priority: '0.4' - }, { - url: '/users', - changefreq: 'daily', - priority: '0.4' - }]); - }, - getDynamicUrls: function(callback) { - var returnUrls = []; - - async.parallel({ - categoryUrls: function(next) { - var categoryUrls = []; - categories.getCategoriesByPrivilege(0, 'find', function(err, categoriesData) { - if (err) { - return next(err); - } - - categoriesData.forEach(function(category) { - if (category) { - categoryUrls.push({ - url: '/category/' + category.cid + '/' + encodeURIComponent(utils.slugify(category.name)), - changefreq: 'weekly', - priority: '0.4' - }); - } - }); + utils = require('../public/src/utils'); - next(null, categoryUrls); - }); - }, - topicUrls: function(next) { - var topicUrls = []; - - async.waterfall([ - function(next) { - db.getSortedSetRevRange('topics:recent', 0, parseInt(meta.config.sitemapTopics, 10) || -1, next); - }, - function(tids, next) { - privileges.topics.filter('read', tids, 0, next); - }, - function(tids, next) { - topics.getTopicsFields(tids, ['tid', 'title', 'lastposttime'], next); - } - ], function(err, topics) { - if (err) { - return next(err); - } - - topics.forEach(function(topic) { - if (topic) { - topicUrls.push({ - url: '/topic/' + topic.tid + '/' + encodeURIComponent(utils.slugify(topic.title)), - lastmodISO: utils.toISOString(topic.lastposttime), - changefreq: 'daily', - priority: '0.6' - }); - } - }); +var sitemap = {}; - next(null, topicUrls); - }); - } - }, function(err, data) { - if (!err) { - returnUrls = data.categoryUrls.concat(data.topicUrls); +sitemap.render = function(callback) { + if (sitemap.obj && sitemap.obj.cache.length) { + return sitemap.obj.toXML(callback); + } + + async.parallel([ + sitemap.getStaticUrls, + sitemap.getDynamicUrls + ], function(err, urls) { + if (err) { + return callback(err); + } + + urls = urls[0].concat(urls[1]); + + sitemap.obj = sm.createSitemap({ + hostname: nconf.get('url'), + cacheTime: 1000 * 60 * 60, // Cached for 1 hour + urls: urls + }); + + sitemap.obj.toXML(callback); + }); +}; + +sitemap.getStaticUrls = function(callback) { + callback(null, [{ + url: '', + changefreq: 'weekly', + priority: '0.6' + }, { + url: '/recent', + changefreq: 'daily', + priority: '0.4' + }, { + url: '/users', + changefreq: 'daily', + priority: '0.4' + }]); +}; + +sitemap.getDynamicUrls = function(callback) { + var returnUrls = []; + + async.parallel({ + categoryUrls: function(next) { + var categoryUrls = []; + categories.getCategoriesByPrivilege(0, 'find', function(err, categoriesData) { + if (err) { + return next(err); } - callback(err, returnUrls); + categoriesData.forEach(function(category) { + if (category) { + categoryUrls.push({ + url: '/category/' + category.cid + '/' + encodeURIComponent(utils.slugify(category.name)), + changefreq: 'weekly', + priority: '0.4' + }); + } + }); + + next(null, categoryUrls); }); }, - render: function(callback) { - if (sitemap.obj !== undefined && sitemap.obj.cache.length) { - return sitemap.obj.toXML(callback); - } - - async.parallel([sitemap.getStaticUrls, sitemap.getDynamicUrls], function(err, urls) { - urls = urls[0].concat(urls[1]); - sitemap.obj = sm.createSitemap({ - hostname: nconf.get('url'), - cacheTime: 1000 * 60 * 60, // Cached for 1 hour - urls: urls + topicUrls: function(next) { + var topicUrls = []; + + async.waterfall([ + function(next) { + db.getSortedSetRevRange('topics:recent', 0, parseInt(meta.config.sitemapTopics, 10) || -1, next); + }, + function(tids, next) { + privileges.topics.filter('read', tids, 0, next); + }, + function(tids, next) { + topics.getTopicsFields(tids, ['tid', 'title', 'lastposttime'], next); + } + ], function(err, topics) { + if (err) { + return next(err); + } + + topics.forEach(function(topic) { + if (topic) { + topicUrls.push({ + url: '/topic/' + topic.tid + '/' + encodeURIComponent(utils.slugify(topic.title)), + lastmodISO: utils.toISOString(topic.lastposttime), + changefreq: 'daily', + priority: '0.6' + }); + } }); - sitemap.obj.toXML(callback); + next(null, topicUrls); }); - }, - clearCache: function() { - if (sitemap.obj) { - sitemap.obj.clearCache(); - } } - }; + }, function(err, data) { + if (!err) { + returnUrls = data.categoryUrls.concat(data.topicUrls); + } + + callback(err, returnUrls); + }); +}; + + +sitemap.clearCache = function() { + if (sitemap.obj) { + sitemap.obj.clearCache(); + } +}; module.exports = sitemap; From 4d9e7fce22d7f7a5cc446941765088a663ed6be0 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 31 Jan 2015 15:42:10 -0500 Subject: [PATCH 044/164] notifyOnlineUsers helper --- src/socket.io/posts.js | 45 +++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index 71e5577178..d0f5b3b589 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -47,29 +47,34 @@ SocketPosts.reply = function(socket, data, callback) { socket.emit('event:new_post', result); - async.waterfall([ - function(next) { - user.getUidsFromSet('users:online', 0, -1, next); - }, - function(uids, next) { - privileges.categories.filterUids('read', postData.topic.cid, uids, next); - }, - function(uids, next) { - plugins.fireHook('filter:sockets.sendNewPostToUids', {uidsTo: uids, uidFrom: data.uid, type: 'newPost'}, next); - } - ], function(err, data) { - if (err) { - return winston.error(err.stack); - } + SocketPosts.notifyOnlineUsers(socket.uid, result); + }); +}; + +SocketPosts.notifyOnlineUsers = function(uid, result) { + var cid = result.posts[0].topic.cid; + async.waterfall([ + function(next) { + user.getUidsFromSet('users:online', 0, -1, next); + }, + function(uids, next) { + privileges.categories.filterUids('read', cid, uids, next); + }, + function(uids, next) { + plugins.fireHook('filter:sockets.sendNewPostToUids', {uidsTo: uids, uidFrom: uid, type: 'newPost'}, next); + } + ], function(err, data) { + if (err) { + return winston.error(err.stack); + } - var uids = data.uidsTo; + var uids = data.uidsTo; - for(var i=0; i Date: Sun, 1 Feb 2015 17:22:08 -0500 Subject: [PATCH 045/164] removed console log from upgrade script --- src/upgrade.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/upgrade.js b/src/upgrade.js index 05a186ea69..ed82dcd20a 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -788,7 +788,6 @@ Upgrade.upgrade = function(callback) { var now = Date.now(); async.each(groupNames, function(groupName, next) { db.sortedSetCard('group:' + groupName + ':members', function(err, memberCount) { - console.log(groupName, memberCount); if (err) { return next(err); } From 79083004e41056790ac5a04f5c2fe5280f3be36c Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 1 Feb 2015 17:22:40 -0500 Subject: [PATCH 046/164] added missing file --- public/src/client/account/groups.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 public/src/client/account/groups.js diff --git a/public/src/client/account/groups.js b/public/src/client/account/groups.js new file mode 100644 index 0000000000..ea70433de3 --- /dev/null +++ b/public/src/client/account/groups.js @@ -0,0 +1,21 @@ +'use strict'; + +/* globals define, app, socket, utils */ + +define('forum/account/groups', ['forum/account/header'], function(header) { + var AccountTopics = {}; + + AccountTopics.init = function() { + header.init(); + + var groupsEl = $('#groups-list'); + + groupsEl.on('click', '.list-cover', function() { + var groupSlug = $(this).parents('[data-slug]').attr('data-slug'); + + ajaxify.go('groups/' + groupSlug); + }); + }; + + return AccountTopics; +}); From 2f19f4106a626bbf4969c4803ccd433813038fec Mon Sep 17 00:00:00 2001 From: Mega Date: Mon, 2 Feb 2015 02:36:17 +0300 Subject: [PATCH 047/164] Added data argument to action:posts.edited hook --- public/src/client/topic/events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index 0990be01c6..281c63fb1e 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -111,7 +111,7 @@ define('forum/topic/events', [ app.replaceSelfLinks(editedPostEl.find('a')); editedPostEl.fadeIn(250); - $(window).trigger('action:posts.edited', data.pid); + $(window).trigger('action:posts.edited', data); }); if (data.tags && tagsUpdated(data.tags)) { From 2c8e8a1f1c6069bf3036fcb099c2b4b9d1aa5e76 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 1 Feb 2015 19:11:58 -0500 Subject: [PATCH 048/164] closes #2550, closes #2518 --- public/src/admin/advanced/events.js | 43 ++++++ src/controllers/admin.js | 8 +- src/events.js | 224 ++++++++++++---------------- src/favourites.js | 21 --- src/notifications.js | 2 - src/postTools.js | 5 +- src/routes/authentication.js | 6 +- src/socket.io/admin.js | 27 +++- src/socket.io/admin/user.js | 9 +- src/socket.io/posts.js | 50 ++++++- src/socket.io/topics.js | 17 ++- src/socket.io/user.js | 92 ++++++++++-- src/threadTools.js | 4 - src/user/auth.js | 13 +- src/user/profile.js | 43 ++---- src/user/reset.js | 1 - src/views/admin/advanced/events.tpl | 45 +++--- 17 files changed, 365 insertions(+), 245 deletions(-) create mode 100644 public/src/admin/advanced/events.js diff --git a/public/src/admin/advanced/events.js b/public/src/admin/advanced/events.js new file mode 100644 index 0000000000..039b105bcb --- /dev/null +++ b/public/src/admin/advanced/events.js @@ -0,0 +1,43 @@ +"use strict"; +/* global define, socket, app, templates */ + + +define('admin/advanced/events', ['forum/infinitescroll'], function(infinitescroll) { + var Events = {}; + + Events.init = function() { + + $('[data-action="clear"]').on('click', function() { + socket.emit('admin.deleteAllEvents', function(err) { + if (err) { + return app.alertError(err.message); + } + $('.events-list').empty(); + }); + }); + + infinitescroll.init(function(direction) { + if (direction < 0 || !$('.events').length) { + return; + } + + infinitescroll.loadMore('admin.getMoreEvents', $('[data-next]').attr('data-next'), function(data, done) { + console.log(data.events); + if (data.events && data.events.length) { + templates.parse('admin/advanced/events', 'events', {events: data.events}, function(html) { + console.log(html); + $('.events-list').append(html); + done(); + }); + + $('[data-next]').attr('data-next', data.next); + } else { + done(); + } + }); + }); + + }; + + return Events; +}); diff --git a/src/controllers/admin.js b/src/controllers/admin.js index 5ccfa3a6df..6779185f0a 100644 --- a/src/controllers/admin.js +++ b/src/controllers/admin.js @@ -174,14 +174,14 @@ adminController.database.get = function(req, res, next) { }; adminController.events.get = function(req, res, next) { - events.getLog(-1, 5000, function(err, data) { - if(err || !data) { + events.getEvents(0, 19, function(err, events) { + if(err || !events) { return next(err); } res.render('admin/advanced/events', { - eventdata: data.data, - next: data.next + events: events, + next: 20 }); }); }; diff --git a/src/events.js b/src/events.js index bab042f28e..682e9549db 100644 --- a/src/events.js +++ b/src/events.js @@ -1,154 +1,128 @@ 'use strict'; -var fs = require('fs'), - winston = require('winston'), - path = require('path'), - nconf = require('nconf'), - user = require('./user'); +var async = require('async'), + db = require('./database'), + batch = require('./batch'), + user = require('./user'), + utils = require('../public/src/utils'); -(function(events) { - var logFileName = 'logs/events.log'; - - events.logPasswordChange = function(uid) { - events.logWithUser(uid, 'changed password'); - }; - - events.logAdminChangeUserPassword = function(adminUid, theirUid, callback) { - logAdminEvent(adminUid, theirUid, 'changed password of', callback); - }; - - events.logAdminUserDelete = function(adminUid, theirUid, callback) { - logAdminEvent(adminUid, theirUid, 'deleted', callback); - }; - function logAdminEvent(adminUid, theirUid, message, callback) { - user.getMultipleUserFields([adminUid, theirUid], ['username'], function(err, userData) { - if(err) { - return winston.error('Error logging event. ' + err.message); +(function(events) { + events.log = function(data, callback) { + callback = callback || function() {}; + + async.waterfall([ + function(next) { + db.incrObjectField('global', 'nextEid', next); + }, + function(eid, next) { + data.timestamp = Date.now(); + data.eid = eid; + + async.parallel([ + function(next) { + db.sortedSetAdd('events:time', data.timestamp, eid, next); + }, + function(next) { + db.setObject('event:' + eid, data, next); + } + ], next); } - - var msg = userData[0].username + '(uid ' + adminUid + ') ' + message + ' ' + userData[1].username + '(uid ' + theirUid + ')'; - events.log(msg, callback); + ], function(err, result) { + callback(err); }); - } - - events.logPasswordReset = function(uid) { - events.logWithUser(uid, 'reset password'); - }; - - events.logEmailChange = function(uid, oldEmail, newEmail) { - events.logWithUser(uid,'changed email from "' + oldEmail + '" to "' + newEmail +'"'); - }; - - events.logUsernameChange = function(uid, oldUsername, newUsername) { - events.logWithUser(uid,'changed username from "' + oldUsername + '" to "' + newUsername +'"'); - }; - - events.logAdminLogin = function(uid) { - events.logWithUser(uid, 'logged into admin panel'); - }; - - events.logPostEdit = function(uid, pid) { - events.logWithUser(uid, 'edited post (pid ' + pid + ')'); - }; - - events.logPostDelete = function(uid, pid) { - events.logWithUser(uid, 'deleted post (pid ' + pid + ')'); - }; - - events.logPostRestore = function(uid, pid) { - events.logWithUser(uid, 'restored post (pid ' + pid + ')'); - }; - - events.logPostPurge = function(uid, pid) { - events.logWithUser(uid, 'purged post (pid ' + pid + ')'); - }; - - events.logTopicMove = function(uid, tid) { - events.logWithUser(uid, 'moved topic (tid ' + tid + ')'); }; - events.logTopicDelete = function(uid, tid) { - events.logWithUser(uid, 'deleted topic (tid ' + tid + ')'); - }; - - events.logTopicRestore = function(uid, tid) { - events.logWithUser(uid, 'restored topic (tid ' + tid + ')'); - }; - - events.logAccountLock = function(uid, until) { - var date = new Date(); - date.setTime(date.getTime() + until); - - events.logWithUser(uid, 'locked out until ' + date.toString()); - }; - - events.logWithUser = function(uid, string) { - user.getUserField(uid, 'username', function(err, username) { - if(err) { - return winston.error('Error logging event. ' + err.message); + events.getEvents = function(start, stop, callback) { + async.waterfall([ + function(next) { + db.getSortedSetRevRange('events:time', start, stop, next); + }, + function(eids, next) { + var keys = eids.map(function(eid) { + return 'event:' + eid; + }); + db.getObjects(keys, next); + }, + function(eventsData, next) { + eventsData.forEach(function(event) { + var e = utils.merge(event); + e.eid = e.uid = e.type = e.ip = undefined; + event.jsonString = JSON.stringify(e, null, 4); + event.timestampISO = new Date(parseInt(event.timestamp, 10)).toUTCString(); + }); + addUserData(eventsData, 'uid', 'user', next); + }, + function(eventsData, next) { + addUserData(eventsData, 'targetUid', 'targetUser', next); } - - var msg = username + '(uid ' + uid + ') ' + string; - events.log(msg); - }); + ], callback); }; - events.log = function(msg, callback) { - var logFile = path.join(nconf.get('base_dir'), logFileName); - - msg = '[' + new Date().toUTCString() + '] - ' + msg; - - fs.appendFile(logFile, msg + '\n', function(err) { - if(err) { - winston.error('Error logging event. ' + err.message); - if (typeof callback === 'function') { - callback(err); - } - return; - } - - if (typeof callback === 'function') { - callback(); - } + function addUserData(eventsData, field, objectName, callback) { + var uids = eventsData.map(function(event) { + return event && event[field]; + }).filter(function(uid, index, array) { + return uid && array.indexOf(uid) === index; }); - }; - events.getLog = function(end, len, callback) { - var logFile = path.join(nconf.get('base_dir'), logFileName); + if (!uids.length) { + return callback(null, eventsData); + } - fs.stat(logFile, function(err, stat) { - if (err) { - return callback(null, 'No logs found!'); + async.parallel({ + isAdmin: function(next) { + user.isAdministrator(uids, next); + }, + userData: function(next) { + user.getMultipleUserFields(uids, ['username', 'userslug', 'picture'], next); } - - var buffer = ''; - var size = stat.size; - if (end === -1) { - end = size; + }, function(err, results) { + if (err) { + return callback(err); } - end = parseInt(end, 10); - var start = Math.max(0, end - len); + var userData = results.userData; - var rs = fs.createReadStream(logFile, {start: start, end: end}); - rs.addListener('data', function(lines) { - buffer += lines.toString(); + var map = {}; + userData.forEach(function(user, index) { + user.isAdmin = results.isAdmin[index]; + map[user.uid] = user; }); - rs.addListener('end', function() { - var firstNewline = buffer.indexOf('\n'); - if (firstNewline !== -1) { - buffer = buffer.slice(firstNewline); - buffer = buffer.split('\n').reverse().join('\n'); + eventsData.forEach(function(event) { + if (map[event[field]]) { + event[objectName] = map[event[field]]; } - - callback(null, {data: buffer, next: end - buffer.length}); }); + callback(null, eventsData); }); + } + + events.deleteEvents = function(eids, callback) { + callback = callback || function() {}; + async.parallel([ + function(next) { + var keys = eids.map(function(eid) { + return 'event:' + eid; + }); + db.deleteAll(keys, next); + }, + function(next) { + db.sortedSetRemove('events:time', eids, next); + } + ], callback); + }; + + events.deleteAll = function(callback) { + callback = callback || function() {}; + batch.processSortedSet('events:time', function(eids, next) { + events.deleteEvents(eids, callback); + }, {alwaysStartAt: 0}, callback); }; + }(module.exports)); diff --git a/src/favourites.js b/src/favourites.js index 0673626f51..6de70d33f3 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -43,10 +43,6 @@ var async = require('async'), db.sortedSetAdd('users:reputation', newreputation, postData.uid); - if (type === 'downvote') { - banUserForLowReputation(postData.uid, newreputation); - } - adjustPostVotes(pid, uid, type, unvote, function(err, votes) { postData.votes = votes; callback(err, { @@ -62,23 +58,6 @@ var async = require('async'), }); } - function banUserForLowReputation(uid, newreputation) { - if (parseInt(meta.config['autoban:downvote'], 10) === 1 && newreputation < parseInt(meta.config['autoban:downvote:threshold'], 10)) { - user.getUserField(uid, 'banned', function(err, banned) { - if (err || parseInt(banned, 10) === 1) { - return; - } - var adminUser = require('./socket.io/admin/user'); - adminUser.banUser(uid, function(err) { - if (err) { - return winston.error(err.message); - } - winston.info('uid ' + uid + ' was banned for reaching ' + newreputation + ' reputation'); - }); - }); - } - } - function adjustPostVotes(pid, uid, type, unvote, callback) { var notType = (type === 'upvote' ? 'downvote' : 'upvote'); diff --git a/src/notifications.js b/src/notifications.js index 2de4ec1709..96502508f7 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -311,8 +311,6 @@ var async = require('async'), if (process.env.NODE_ENV === 'development') { winston.info('[notifications.prune] Notification pruning completed. ' + numPruned + ' expired notification' + (numPruned !== 1 ? 's' : '') + ' removed.'); } - var diff = process.hrtime(start); - events.log('Pruning '+ numPruned + ' notifications took : ' + (diff[0] * 1e3 + diff[1] / 1e6) + ' ms'); }); }); }; diff --git a/src/postTools.js b/src/postTools.js index 692878734a..c00a8a4b9c 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -106,7 +106,7 @@ var winston = require('winston'), return callback(err); } results.content = results.postData.content; - //events.logPostEdit(uid, pid); + plugins.fireHook('action:post.edit', postData); callback(null, results); }); @@ -146,7 +146,6 @@ var winston = require('winston'), return callback(err); } - events[isDelete ? 'logPostDelete' : 'logPostRestore'](uid, pid); if (isDelete) { posts.delete(pid, callback); } else { @@ -165,7 +164,7 @@ var winston = require('winston'), if (err || !canEdit) { return callback(err || new Error('[[error:no-privileges]]')); } - events.logPostPurge(uid, pid); + posts.purge(pid, callback); }); }; diff --git a/src/routes/authentication.js b/src/routes/authentication.js index 5754ee3353..649d6d87dd 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -68,7 +68,7 @@ }); }; - Auth.login = function(username, password, next) { + Auth.login = function(req, username, password, next) { if (!username || !password) { return next(new Error('[[error:invalid-password]]')); } @@ -85,7 +85,7 @@ return next(new Error('[[error:no-user]]')); } uid = _uid; - user.auth.logAttempt(uid, next); + user.auth.logAttempt(uid, req.ip, next); }, function(next) { db.getObjectFields('user:' + uid, ['password', 'banned'], next); @@ -109,7 +109,7 @@ ], next); }; - passport.use(new passportLocal(Auth.login)); + passport.use(new passportLocal({passReqToCallback: true}, Auth.login)); passport.serializeUser(function(user, done) { done(null, user.uid); diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index 36efef49f9..a770af5c53 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -49,7 +49,11 @@ SocketAdmin.before = function(socket, method, next) { }; SocketAdmin.reload = function(socket, data, callback) { - events.logWithUser(socket.uid, ' is reloading NodeBB'); + events.log({ + type: 'reload', + uid: socket.uid, + ip: socket.ip + }); if (process.send) { process.send({ action: 'reload' @@ -60,7 +64,11 @@ SocketAdmin.reload = function(socket, data, callback) { }; SocketAdmin.restart = function(socket, data, callback) { - events.logWithUser(socket.uid, ' is restarting NodeBB'); + events.log({ + type: 'restart', + uid: socket.uid, + ip: socket.ip + }); meta.restart(); }; @@ -274,10 +282,21 @@ function getMonthlyPageViews(callback) { } SocketAdmin.getMoreEvents = function(socket, next, callback) { - if (parseInt(next, 10) < 0) { + var start = parseInt(next, 10); + if (start < 0) { return callback(null, {data: [], next: next}); } - events.getLog(next, 5000, callback); + var end = next + 10; + events.getEvents(start, end, function(err, events) { + if (err) { + return callback(err); + } + callback(null, {events: events, next: end + 1}); + }); +}; + +SocketAdmin.deleteAllEvents = function(socket, data, callback) { + events.deleteAll(callback); }; SocketAdmin.dismissFlag = function(socket, pid, callback) { diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index 9189727fbb..3a194044ea 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -157,7 +157,7 @@ User.deleteUsers = function(socket, uids, callback) { async.each(uids, function(uid, next) { user.isAdministrator(uid, function(err, isAdmin) { if (err || isAdmin) { - return callback(err || new Error('[[error:cant-ban-other-admins]]')); + return callback(err || new Error('[[error:cant-delete-other-admins]]')); } user.delete(uid, function(err) { @@ -165,7 +165,12 @@ User.deleteUsers = function(socket, uids, callback) { return next(err); } - events.logAdminUserDelete(socket.uid, uid); + events.log({ + type: 'user-delete', + uid: socket.uid, + targetUid: uid, + ip: socket.ip + }); websockets.logoutUser(uid); next(); diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index d0f5b3b589..590b10da0f 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -16,6 +16,7 @@ var async = require('async'), groups = require('../groups'), user = require('../user'), websockets = require('./index'), + events = require('../events'), utils = require('../../public/src/utils'), SocketPosts = {}; @@ -138,7 +139,38 @@ SocketPosts.upvote = function(socket, data, callback) { }; SocketPosts.downvote = function(socket, data, callback) { - favouriteCommand(socket, 'downvote', 'voted', '', data, callback); + function banUserForLowReputation(uid, callback) { + if (parseInt(meta.config['autoban:downvote'], 10) === 1) { + user.getUserFields(uid, ['reputation', 'banned'], function(err, userData) { + if (err || parseInt(userData.banned, 10) === 1 || parseInt(userData.reputation) >= parseInt(meta.config['autoban:downvote:threshold'], 10)) { + return callback(err); + } + + var adminUser = require('./admin/user'); + adminUser.banUser(uid, function(err) { + if (err) { + return callback(err); + } + events.log({ + type: 'banned', + reason: 'low-reputation', + uid: socket.uid, + ip: socket.ip, + targetUid: data.uid, + reputation: userData.reputation + }); + callback(); + }); + }); + } + } + + favouriteCommand(socket, 'downvote', 'voted', '', data, function(err) { + if (err) { + return callback(err); + } + banUserForLowReputation(data.uid, callback); + }); }; SocketPosts.unvote = function(socket, data, callback) { @@ -309,9 +341,16 @@ function deleteOrRestore(command, socket, data, callback) { return callback(err); } - var eventName = command === 'restore' ? 'event:post_restored' : 'event:post_deleted'; + var eventName = command === 'delete' ? 'event:post_deleted' : 'event:post_restored'; websockets.in('topic_' + data.tid).emit(eventName, postData); + events.log({ + type: command === 'delete' ? 'post-delete' : 'post-restore', + uid: socket.uid, + pid: data.pid, + ip: socket.ip + }); + callback(); }); } @@ -327,6 +366,13 @@ SocketPosts.purge = function(socket, data, callback) { websockets.in('topic_' + data.tid).emit('event:post_purged', data.pid); + events.log({ + type: 'post-purge', + uid: socket.uid, + pid: data.pid, + ip: socket.ip + }); + callback(); }); }; diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index 9f96f17f29..687a7361a5 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -15,6 +15,7 @@ var nconf = require('nconf'), user = require('../user'), db = require('../database'), meta = require('../meta'), + events = require('../events'), utils = require('../../public/src/utils'), SocketPosts = require('./posts'), @@ -259,7 +260,21 @@ function doTopicAction(action, socket, data, callback) { } if(typeof threadTools[action] === 'function') { - threadTools[action](tid, socket.uid, next); + threadTools[action](tid, socket.uid, function(err) { + if (err) { + return next(err); + } + + if (action === 'delete' || action === 'restore' || action === 'purge') { + events.log({ + type: 'topic-' + action, + uid: socket.uid, + ip: socket.ip, + tid: tid + }); + } + next(); + }); } }); }, callback); diff --git a/src/socket.io/user.js b/src/socket.io/user.js index d28421c383..d879813bae 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -12,6 +12,7 @@ var async = require('async'), utils = require('../../public/src/utils'), websockets = require('./index'), meta = require('../meta'), + events = require('../events'), SocketUser = {}; SocketUser.exists = function(socket, data, callback) { @@ -56,7 +57,7 @@ SocketUser.emailConfirm = function(socket, data, callback) { SocketUser.search = function(socket, data, callback) { if (!data) { - return callback(new Error('[[error:invalid-data]]')) + return callback(new Error('[[error:invalid-data]]')); } if (!socket.uid) { return callback(new Error('[[error:not-logged-in]]')); @@ -87,7 +88,16 @@ SocketUser.reset.valid = function(socket, code, callback) { SocketUser.reset.commit = function(socket, data, callback) { if(data && data.code && data.password) { - user.reset.commit(data.code, data.password, callback); + user.reset.commit(data.code, data.password, function(err) { + if (err) { + return callback(err); + } + events.log({ + type: 'password-reset', + uid: socket.uid, + ip: socket.ip + }); + }); } }; @@ -109,12 +119,74 @@ SocketUser.checkStatus = function(socket, uid, callback) { }; SocketUser.changePassword = function(socket, data, callback) { - if (data && socket.uid) { - user.changePassword(socket.uid, data, callback); + if (!data || !data.uid) { + return callback(new Error('[[error:invalid-data]]')); + } + if (!socket.uid) { + return callback('[[error:invalid-uid]]'); } + + user.changePassword(socket.uid, data, function(err) { + if (err) { + return callback(err); + } + + events.log({ + type: 'password-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip + }); + }); }; SocketUser.updateProfile = function(socket, data, callback) { + function update(oldUserData) { + function done(err, userData) { + if (err) { + return callback(err); + } + + if (userData.email !== oldUserData.email) { + events.log({ + type: 'email-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip, + oldEmail: oldUserData.email, + newEmail: userData.email + }); + } + + if (userData.username !== oldUserData.username) { + events.log({ + type: 'username-change', + uid: socket.uid, + targetUid: data.uid, + ip: socket.ip, + oldUsername: oldUserData.username, + newUsername: userData.username + }); + } + } + + if (socket.uid === parseInt(data.uid, 10)) { + return user.updateProfile(socket.uid, data, done); + } + + user.isAdministrator(socket.uid, function(err, isAdmin) { + if (err) { + return callback(err); + } + + if (!isAdmin) { + return callback(new Error('[[error:no-privileges]]')); + } + + user.updateProfile(data.uid, data, done); + }); + } + if (!socket.uid) { return callback('[[error:invalid-uid]]'); } @@ -123,20 +195,12 @@ SocketUser.updateProfile = function(socket, data, callback) { return callback(new Error('[[error:invalid-data]]')); } - if (socket.uid === parseInt(data.uid, 10)) { - return user.updateProfile(socket.uid, data, callback); - } - - user.isAdministrator(socket.uid, function(err, isAdmin) { + user.getUserFields(data.uid, ['email', 'username'], function(err, oldUserData) { if (err) { return callback(err); } - if (!isAdmin) { - return callback(new Error('[[error:no-privileges]]')); - } - - user.updateProfile(data.uid, data, callback); + update(oldUserData, callback); }); }; diff --git a/src/threadTools.js b/src/threadTools.js index 1fe1369d35..077abc54e6 100644 --- a/src/threadTools.js +++ b/src/threadTools.js @@ -56,8 +56,6 @@ var winston = require('winston'), plugins.fireHook('action:topic.restore', topicData); } - events[isDelete ? 'logTopicDelete' : 'logTopicRestore'](uid, tid); - emitTo('topic_' + tid); emitTo('category_' + topicData.cid); @@ -214,8 +212,6 @@ var winston = require('winston'), topics.setTopicField(tid, 'cid', cid, callback); - events.logTopicMove(uid, tid); - plugins.fireHook('action:topic.move', { tid: tid, fromCid: oldCid, diff --git a/src/user/auth.js b/src/user/auth.js index b275882cf1..48f0c8fc2c 100644 --- a/src/user/auth.js +++ b/src/user/auth.js @@ -8,7 +8,7 @@ var async = require('async'), module.exports = function(User) { User.auth = {}; - User.auth.logAttempt = function(uid, callback) { + User.auth.logAttempt = function(uid, ip, callback) { db.exists('lockout:' + uid, function(err, exists) { if (err) { return callback(err); @@ -30,12 +30,15 @@ module.exports = function(User) { return callback(err); } var duration = 1000 * 60 * (meta.config.lockoutDuration || 60); - + db.delete('loginAttempts:' + uid); db.pexpire('lockout:' + uid, duration); - - events.logAccountLock(uid, duration); - callback(new Error('account-locked')); + events.log({ + type: 'account-locked', + uid: uid, + ip: ip + }); + callback(new Error('[[error:account-locked]]')); }); } else { db.pexpire('loginAttempts:' + uid, 1000 * 60 * 60); diff --git a/src/user/profile.js b/src/user/profile.js index 8c44b86a6f..461f1d9bb8 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -148,8 +148,6 @@ module.exports = function(User) { return callback(err); } - events.logEmailChange(uid, userData.email, newEmail); - var gravatarpicture = User.createGravatarURLFromEmail(newEmail); async.parallel([ function(next) { @@ -183,9 +181,13 @@ module.exports = function(User) { if (!newUsername) { return callback(); } + User.getUserFields(uid, ['username', 'userslug'], function(err, userData) { function update(field, object, value, callback) { - async.parallel([ + async.series([ + function(next) { + db.deleteObjectField(field + ':uid', userData[field], next); + }, function(next) { User.setUserField(uid, field, value, next); }, @@ -198,7 +200,6 @@ module.exports = function(User) { if (err) { return callback(err); } - var userslug = utils.slugify(newUsername); async.parallel([ function(next) { @@ -206,25 +207,15 @@ module.exports = function(User) { return next(); } - db.deleteObjectField('username:uid', userData.username, function(err) { - if (err) { - return next(err); - } - events.logUsernameChange(uid, userData.username, newUsername); - update('username', 'username:uid', newUsername, next); - }); + update('username', 'username:uid', newUsername, next); }, function(next) { - if (userslug === userData.userslug) { + var newUserslug = utils.slugify(newUsername); + if (newUserslug === userData.userslug) { return next(); } - db.deleteObjectField('userslug:uid', userData.userslug, function(err) { - if (err) { - return next(err); - } - update('userslug', 'userslug:uid', userslug, next); - }); + update('userslug', 'userslug:uid', newUserslug, next); } ], callback); }); @@ -261,23 +252,11 @@ module.exports = function(User) { function hashAndSetPassword(callback) { User.hashPassword(data.newPassword, function(err, hash) { - if(err) { + if (err) { return callback(err); } - User.setUserField(data.uid, 'password', hash, function(err) { - if(err) { - return callback(err); - } - - if(parseInt(uid, 10) === parseInt(data.uid, 10)) { - events.logPasswordChange(data.uid); - } else { - events.logAdminChangeUserPassword(uid, data.uid); - } - - callback(); - }); + User.setUserField(data.uid, 'password', hash, callback); }); } diff --git a/src/user/reset.js b/src/user/reset.js index 2e1a7ab80e..c65e77a570 100644 --- a/src/user/reset.js +++ b/src/user/reset.js @@ -83,7 +83,6 @@ var async = require('async'), return callback(err); } user.setUserField(uid, 'password', hash); - events.logPasswordReset(uid); db.deleteObjectField('reset:uid', code); db.deleteObjectField('reset:expiry', code); diff --git a/src/views/admin/advanced/events.tpl b/src/views/admin/advanced/events.tpl index 03e3b7f4eb..e3231b0099 100644 --- a/src/views/admin/advanced/events.tpl +++ b/src/views/admin/advanced/events.tpl @@ -1,31 +1,32 @@
-
+
Events
-
{eventdata}
+ +
There are no events
+ +
+ +
+ #{events.eid} {events.type} + {events.user.username} (uid {events.user.uid}) (IP {events.ip}) + {events.timestampISO} +

+
{events.jsonString}
+
+ +
+
+
+
+
+
+
Events Control Panel
+
+
- - \ No newline at end of file From 0bfa8d337a7942458f6bd6c39ac9b2a178781d13 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 1 Feb 2015 19:13:27 -0500 Subject: [PATCH 049/164] removed console.logs --- public/src/admin/advanced/events.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/src/admin/advanced/events.js b/public/src/admin/advanced/events.js index 039b105bcb..9075947d60 100644 --- a/public/src/admin/advanced/events.js +++ b/public/src/admin/advanced/events.js @@ -22,10 +22,8 @@ define('admin/advanced/events', ['forum/infinitescroll'], function(infinitescrol } infinitescroll.loadMore('admin.getMoreEvents', $('[data-next]').attr('data-next'), function(data, done) { - console.log(data.events); if (data.events && data.events.length) { templates.parse('admin/advanced/events', 'events', {events: data.events}, function(html) { - console.log(html); $('.events-list').append(html); done(); }); From df0e92471499645239800b511fd0ea5e62aa1d96 Mon Sep 17 00:00:00 2001 From: Mega Date: Mon, 2 Feb 2015 03:27:25 +0300 Subject: [PATCH 050/164] Change argument in action:posts.loaded --- public/src/client/home.js | 2 +- public/src/client/topic/posts.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/src/client/home.js b/public/src/client/home.js index 23049af741..f3b4e65acc 100644 --- a/public/src/client/home.js +++ b/public/src/client/home.js @@ -59,7 +59,7 @@ define('forum/home', function() { recentPosts.last().remove(); } - $(window).trigger('action:posts.loaded'); + $(window).trigger('action:posts.loaded', {pids: [post.pid]}); }); } diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index ec566d9812..1f49c6fdd0 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -130,7 +130,7 @@ define('forum/topic/posts', [ pids.push(data.posts[i].pid); } - $(window).trigger('action:posts.loaded', pids); + $(window).trigger('action:posts.loaded', {pids: pids}); onNewPostsLoaded(html, pids); callback(true); }); From 59da48dee5056fe07c7fe6163926643786b2059e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 1 Feb 2015 19:35:41 -0500 Subject: [PATCH 051/164] added too-many-messages language key --- public/language/en_GB/error.json | 1 + 1 file changed, 1 insertion(+) diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 7e21a1290a..47b0bf8938 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -83,6 +83,7 @@ "cant-chat-with-yourself": "You can't chat with yourself!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", From d284e89d6cf19738d71b86eb53e570b29cbc6c3a Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 1 Feb 2015 19:35:41 -0500 Subject: [PATCH 052/164] added too-many-messages language key --- public/language/en_GB/error.json | 1 + 1 file changed, 1 insertion(+) diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 7e21a1290a..47b0bf8938 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -83,6 +83,7 @@ "cant-chat-with-yourself": "You can't chat with yourself!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", From 5c2a70254f8799f15ecae0890ddad455a0b804a9 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 1 Feb 2015 19:37:19 -0500 Subject: [PATCH 053/164] latest translations and fallbacks --- public/language/ar/error.json | 1 + public/language/bn/error.json | 1 + public/language/cs/error.json | 1 + public/language/de/email.json | 4 ++-- public/language/de/error.json | 1 + public/language/de/groups.json | 24 ++++++++++++------------ public/language/de/topic.json | 2 +- public/language/el/error.json | 1 + public/language/en@pirate/error.json | 1 + public/language/en_US/error.json | 1 + public/language/es/email.json | 4 ++-- public/language/es/error.json | 13 +++++++------ public/language/es/global.json | 12 ++++++------ public/language/es/groups.json | 26 +++++++++++++------------- public/language/es/recent.json | 18 +++++++++--------- public/language/es/search.json | 8 ++++---- public/language/es/topic.json | 4 ++-- public/language/es/user.json | 10 +++++----- public/language/es/users.json | 6 +++--- public/language/et/error.json | 1 + public/language/fa_IR/error.json | 1 + public/language/fi/error.json | 1 + public/language/fr/email.json | 4 ++-- public/language/fr/error.json | 13 +++++++------ public/language/fr/global.json | 12 ++++++------ public/language/fr/groups.json | 28 ++++++++++++++-------------- public/language/fr/recent.json | 18 +++++++++--------- public/language/fr/search.json | 8 ++++---- public/language/fr/topic.json | 4 ++-- public/language/fr/user.json | 10 +++++----- public/language/fr/users.json | 6 +++--- public/language/he/error.json | 1 + public/language/hu/error.json | 1 + public/language/id/error.json | 1 + public/language/it/error.json | 1 + public/language/ja/error.json | 1 + public/language/ko/error.json | 1 + public/language/lt/error.json | 1 + public/language/ms/error.json | 1 + public/language/nb/email.json | 4 ++-- public/language/nb/error.json | 13 +++++++------ public/language/nb/global.json | 12 ++++++------ public/language/nb/groups.json | 26 +++++++++++++------------- public/language/nb/recent.json | 18 +++++++++--------- public/language/nb/search.json | 8 ++++---- public/language/nb/topic.json | 4 ++-- public/language/nb/user.json | 8 ++++---- public/language/nb/users.json | 6 +++--- public/language/nl/error.json | 1 + public/language/nl/groups.json | 8 ++++---- public/language/nl/recent.json | 6 +++--- public/language/nl/search.json | 6 +++--- public/language/nl/topic.json | 4 ++-- public/language/nl/user.json | 2 +- public/language/nl/users.json | 6 +++--- public/language/pl/error.json | 1 + public/language/pt_BR/email.json | 4 ++-- public/language/pt_BR/error.json | 13 +++++++------ public/language/pt_BR/global.json | 12 ++++++------ public/language/pt_BR/groups.json | 26 +++++++++++++------------- public/language/pt_BR/recent.json | 18 +++++++++--------- public/language/pt_BR/search.json | 8 ++++---- public/language/pt_BR/topic.json | 4 ++-- public/language/pt_BR/user.json | 10 +++++----- public/language/pt_BR/users.json | 6 +++--- public/language/ro/error.json | 1 + public/language/ru/error.json | 9 +++++---- public/language/ru/global.json | 4 ++-- public/language/ru/groups.json | 22 +++++++++++----------- public/language/sc/error.json | 1 + public/language/sk/error.json | 1 + public/language/sv/error.json | 1 + public/language/th/error.json | 1 + public/language/tr/error.json | 1 + public/language/vi/error.json | 1 + public/language/zh_CN/error.json | 1 + public/language/zh_TW/error.json | 1 + 77 files changed, 282 insertions(+), 248 deletions(-) diff --git a/public/language/ar/error.json b/public/language/ar/error.json index 592d7365e4..26d90ae89e 100644 --- a/public/language/ar/error.json +++ b/public/language/ar/error.json @@ -62,6 +62,7 @@ "signature-too-long": "عذرا، توقيعك يجب ألا يتجاوز %1 حرفًا", "cant-chat-with-yourself": "لايمكنك فتح محادثة مع نفسك", "chat-restricted": "هذا المستخدم عطل المحادثات الواردة عليه. يجب أن يتبعك حتى تتمكن من فتح محادثة معه.", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "نظام السمعة معطل", "downvoting-disabled": "التصويتات السلبية معطلة", "not-enough-reputation-to-downvote": "ليس لديك سمعة تكفي لإضافة صوت سلبي لهذا الموضوع", diff --git a/public/language/bn/error.json b/public/language/bn/error.json index 83aa15b6b5..ea1240c0ad 100644 --- a/public/language/bn/error.json +++ b/public/language/bn/error.json @@ -62,6 +62,7 @@ "signature-too-long": "দুঃখিত, আপনার সাক্ষর %1 অক্ষরের বেশী হতে পারবে না। ", "cant-chat-with-yourself": "আপনি নিজের সাথে চ্যাট করতে পারবেন না!", "chat-restricted": "এই সদস্য তার বার্তালাপ সংরক্ষিত রেখেছেন। এই সদস্য আপনাকে ফলো করার পরই কেবলমাত্র আপনি তার সাথে চ্যাট করতে পারবেন", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "সম্মাননা ব্যাবস্থা নিস্ক্রীয় রাখা হয়েছে", "downvoting-disabled": "ঋণাত্মক ভোট নিস্ক্রীয় রাখা হয়েছে।", "not-enough-reputation-to-downvote": "আপনার এই পোস্ট downvote করার জন্য পর্যাপ্ত সম্মাননা নেই", diff --git a/public/language/cs/error.json b/public/language/cs/error.json index d9d20cdf64..c5ae30c511 100644 --- a/public/language/cs/error.json +++ b/public/language/cs/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Pardon, ale váš podpis nemůže být delší, než-li %1 znaků.", "cant-chat-with-yourself": "Nemůžete chatovat sami se sebou!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Systém reputací je zakázán.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/de/email.json b/public/language/de/email.json index 408c511c84..4236feca0b 100644 --- a/public/language/de/email.json +++ b/public/language/de/email.json @@ -17,8 +17,8 @@ "notif.chat.subject": "Neue Chatnachricht von %1 erhalten", "notif.chat.cta": "Klicke hier, um die Unterhaltung fortzusetzen", "notif.chat.unsub.info": "Diese Chat-Benachrichtigung wurde dir aufgrund deiner Abonnement-Einstellungen gesendet.", - "notif.post.cta": "Click here to read the full topic", - "notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.", + "notif.post.cta": "Hier klicken, um das gesamte Thema zu lesen", + "notif.post.unsub.info": "Diese Mitteilung wurde wegen ihrer Abonnement-Einstellung gesendet.", "test.text1": "Dies ist eine Test-E-Mail, um zu überprüfen, ob der E-Mailer deines NodeBB korrekt eingestellt wurde.", "unsub.cta": "Klicke hier, um diese Einstellungen zu ändern.", "closing": "Danke!" diff --git a/public/language/de/error.json b/public/language/de/error.json index 67cf44ca9c..ea63e414c4 100644 --- a/public/language/de/error.json +++ b/public/language/de/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Entschuldigung, deine Signatur darf maximal %1 Zeichen enthalten.", "cant-chat-with-yourself": "Du kannst nicht mit dir selber chatten!", "chat-restricted": "Dieser Benutzer hat seine Chatfunktion eingeschränkt. Du kannst nur mit diesem Benutzer chatten, wenn er dir folgt.", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Das Reputationssystem ist deaktiviert.", "downvoting-disabled": "Downvotes sind deaktiviert.", "not-enough-reputation-to-downvote": "Deine Reputation ist zu niedrig, um diesen Beitrag negativ zu bewerten.", diff --git a/public/language/de/groups.json b/public/language/de/groups.json index 28138f6426..7da599f146 100644 --- a/public/language/de/groups.json +++ b/public/language/de/groups.json @@ -1,21 +1,21 @@ { "groups": "Gruppen", "view_group": "Gruppe betrachten", - "owner": "Group Owner", - "new_group": "Create New Group", - "no_groups_found": "There are no groups to see", + "owner": "Gruppenbesitzer", + "new_group": "Neue Gruppe erstellen", + "no_groups_found": "Es sind keine Gruppen vorhanden", "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", - "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "cover-change": "Ändern", + "cover-save": "Speichern", + "cover-saving": "Am speichern", "details.title": "Gruppendetails", "details.members": "Mitgliederliste", - "details.pending": "Pending Members", + "details.pending": "Ausstehende Mitglieder", "details.has_no_posts": "Die Mitglieder dieser Gruppe haben keine Beiträge verfasst.", "details.latest_posts": "Aktuelle Beiträge", - "details.private": "Private Group", - "details.public": "Public Group", - "details.owner_options": "Group Administration", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "details.private": "Private Gruppe", + "details.public": "Öffentliche Gruppe", + "details.owner_options": "Gruppenadministration", + "event.updated": "Gruppendetails wurden aktualisiert", + "event.deleted": "Die Gruppe \"% 1\" wurde gelöscht" } \ No newline at end of file diff --git a/public/language/de/topic.json b/public/language/de/topic.json index 23d6b0771e..e2e47d83c1 100644 --- a/public/language/de/topic.json +++ b/public/language/de/topic.json @@ -94,5 +94,5 @@ "oldest_to_newest": "Älteste zuerst", "newest_to_oldest": "Neuster zuerst", "most_votes": "Die meisten Stimmen", - "most_posts": "Most posts" + "most_posts": "Die meisten Beiträge" } \ No newline at end of file diff --git a/public/language/el/error.json b/public/language/el/error.json index ce1173a11d..e072c910f8 100644 --- a/public/language/el/error.json +++ b/public/language/el/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "Δεν μπορείς να συνομιλήσεις με τον εαυτό σου!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Το σύστημα φήμης έχει απενεργοποιηθεί.", "downvoting-disabled": "Η καταψήφιση έχει απενεργοποιηθεί", "not-enough-reputation-to-downvote": "Δεν έχεις αρκετή φήμη για να καταψηφίσεις αυτή την δημοσίευση", diff --git a/public/language/en@pirate/error.json b/public/language/en@pirate/error.json index a40a628042..6079502fae 100644 --- a/public/language/en@pirate/error.json +++ b/public/language/en@pirate/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "You can't chat with yourself!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/en_US/error.json b/public/language/en_US/error.json index a40a628042..6079502fae 100644 --- a/public/language/en_US/error.json +++ b/public/language/en_US/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "You can't chat with yourself!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/es/email.json b/public/language/es/email.json index cff3a5d025..870687c4e6 100644 --- a/public/language/es/email.json +++ b/public/language/es/email.json @@ -17,8 +17,8 @@ "notif.chat.subject": "Nuevo mensaje de chat recibido de %1", "notif.chat.cta": "Haz click aquí para continuar la conversación", "notif.chat.unsub.info": "Esta notificación de chat se te envió debido a tus ajustes de suscripción.", - "notif.post.cta": "Click here to read the full topic", - "notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.", + "notif.post.cta": "Cliquea aquí para leer la publicación completa", + "notif.post.unsub.info": "La notificación de este mensaje se te ha enviado debido a tus ajustes de subscripción.", "test.text1": "Este es un email de prueba para verificar que el envío de email está ajustado correctamente para tu NodeBB", "unsub.cta": "Haz click aquí para modificar los ajustes.", "closing": "¡Gracias!" diff --git a/public/language/es/error.json b/public/language/es/error.json index d656a309f6..70fcf2f2a8 100644 --- a/public/language/es/error.json +++ b/public/language/es/error.json @@ -18,7 +18,7 @@ "username-taken": "Nombre de usuario ocupado", "email-taken": "Correo electrónico ocupado", "email-not-confirmed": "Su cuenta de correo electrónico no ha sido confirmada aún, por favor haga click aquí para confirmarla.", - "email-not-confirmed-chat": "You are unable to chat until your email is confirmed", + "email-not-confirmed-chat": "No puedes hacer uso del chat hasta que confirmes tu email", "username-too-short": "Nombre de usuario es demasiado corto", "username-too-long": "Nombre de usuario demasiado largo", "user-banned": "Usuario baneado", @@ -44,13 +44,13 @@ "already-favourited": "Ya ha marcado esta publicación como favorita", "already-unfavourited": "Ya ha desmarcado esta publicación como favorita", "cant-ban-other-admins": "¡No puedes expulsar a otros administradores!", - "invalid-image-type": "Invalid image type. Allowed types are: %1", - "invalid-image-extension": "Invalid image extension", + "invalid-image-type": "Tipo de imagen inválido. Los tipos permitidos son: %1", + "invalid-image-extension": "Extensión de imagen inválida", "group-name-too-short": "Nombre del grupo es demasiado corto.", "group-already-exists": "El grupo ya existe.", "group-name-change-not-allowed": "El nombre del grupo deseado no está permitido.", - "group-already-member": "You are already part of this group", - "group-needs-owner": "This group requires at least one owner", + "group-already-member": "Ya formas parte de este grupo", + "group-needs-owner": "Este grupo requiere al menos un propietario", "post-already-deleted": "Este publicación ya ha sido borrada", "post-already-restored": "Esta publicación ya ha sido restaurada", "topic-already-deleted": "Este tema ya ha sido borrado", @@ -62,11 +62,12 @@ "signature-too-long": "Lo sentimos, pero tu firma no puede ser más larga de %1 caracteres.", "cant-chat-with-yourself": "¡No puedes conversar contigo mismo!", "chat-restricted": "Este usuario tiene restringidos los mensajes de chat. Los usuarios deben seguirte antes de que pueda charlar con ellos", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "El sistema de reputación está deshabilitado.", "downvoting-disabled": "La votación negativa está deshabilitada.", "not-enough-reputation-to-downvote": "No tienes suficiente reputación para votar negativo este post", "not-enough-reputation-to-flag": "No tiene suficiente reputación para poner reportar esta publicación", "reload-failed": "NodeBB encontró un problema al refrescar: \"%1\". NodeBB intentará cargar el resto de contenido, aunque deberías deshacer lo que hiciste justo antes.", "registration-error": "Error de registro", - "parse-error": "Something went wrong while parsing server response" + "parse-error": "Algo ha ido mal mientras se parseaba la respuesta del servidor" } \ No newline at end of file diff --git a/public/language/es/global.json b/public/language/es/global.json index b452d2a26f..4e2b07be05 100644 --- a/public/language/es/global.json +++ b/public/language/es/global.json @@ -3,10 +3,10 @@ "search": "Buscar", "buttons.close": "Cerrar", "403.title": "Acceso denegado", - "403.message": "You seem to have stumbled upon a page that you do not have access to.", - "403.login": "Perhaps you should try logging in?", + "403.message": "Al parecer has llegado a una página a la cual no tienes permisos para acceder.", + "403.login": "¿Quizás deberías intentar acceder?", "404.title": "No encontrado", - "404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.", + "404.message": "Al parecer has llegado a una página a la cual no tienes permisos para acceder. Volver a la página de inicio .", "500.title": "Error Interno.", "500.message": "¡Ooops! ¡Parece que algo salió mal! No te preocupes, ¡nuestros simios hiperinteligentes lo solucionarán!", "register": "Registrarse", @@ -27,7 +27,7 @@ "header.tags": "Etiquetas", "header.popular": "Popular", "header.users": "Usuarios", - "header.groups": "Groups", + "header.groups": "Grupos", "header.chats": "Chats", "header.notifications": "Notificaciones", "header.search": "Buscar", @@ -75,7 +75,7 @@ "updated.title": "Foro actualizado", "updated.message": "El foro acaba de ser actualizado a la última versión. Haz click aquí para refrescar la página.", "privacy": "Privacidad", - "follow": "Follow", - "unfollow": "Unfollow", + "follow": "Seguir", + "unfollow": "Dejar de Seguir", "delete_all": "Eliminar todo" } \ No newline at end of file diff --git a/public/language/es/groups.json b/public/language/es/groups.json index 92be20f80a..bc91648d60 100644 --- a/public/language/es/groups.json +++ b/public/language/es/groups.json @@ -1,21 +1,21 @@ { "groups": "Grupos", "view_group": "Ver Grupo", - "owner": "Group Owner", - "new_group": "Create New Group", - "no_groups_found": "There are no groups to see", - "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", - "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "owner": "Propietario del Grupo", + "new_group": "Crear Nuevo Grupo", + "no_groups_found": "No hay grupos que ver", + "cover-instructions": "Arrastra y suelta una foto, arrastra a la posición, y pulsa Guardar ", + "cover-change": "Cambiar", + "cover-save": "Guardar", + "cover-saving": "Guardando", "details.title": "Detalles de Grupo", "details.members": "Lista de Miembros", - "details.pending": "Pending Members", + "details.pending": "Miembros Pendientes", "details.has_no_posts": "Los miembros de este grupo no han hecho ninguna publicación.", "details.latest_posts": "Últimas Publicaciones", - "details.private": "Private Group", - "details.public": "Public Group", - "details.owner_options": "Group Administration", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "details.private": "Grupo Privado", + "details.public": "Grupo Público", + "details.owner_options": "Administración De Grupo", + "event.updated": "Los detalles del grupo han sido actualizados", + "event.deleted": "El grupo \"%1\" ha sido eliminado" } \ No newline at end of file diff --git a/public/language/es/recent.json b/public/language/es/recent.json index 6c8600afec..ea473a2b51 100644 --- a/public/language/es/recent.json +++ b/public/language/es/recent.json @@ -6,13 +6,13 @@ "year": "Año", "alltime": "Siempre", "no_recent_topics": "No hay publicaciones recientes.", - "there-is-a-new-topic": "There is a new topic.", - "there-is-a-new-topic-and-a-new-post": "There is a new topic and a new post.", - "there-is-a-new-topic-and-new-posts": "There is a new topic and %1 new posts.", - "there-are-new-topics": "There are %1 new topics.", - "there-are-new-topics-and-a-new-post": "There are %1 new topics and a new post.", - "there-are-new-topics-and-new-posts": "There are %1 new topics and %2 new posts.", - "there-is-a-new-post": "There is a new post.", - "there-are-new-posts": "There are %1 new posts.", - "click-here-to-reload": "Click here to reload." + "there-is-a-new-topic": "Hay una nueva publicación.", + "there-is-a-new-topic-and-a-new-post": "hay una nueva publicación y un nuevo mensaje.", + "there-is-a-new-topic-and-new-posts": "Hay una nueva publicación y %1 nuevos mensajes.", + "there-are-new-topics": "Hay %1 nuevos mensajes.", + "there-are-new-topics-and-a-new-post": "Hay %1 nuevas publicaciones y un nuevo mensaje.", + "there-are-new-topics-and-new-posts": "Hay %1 nuevas publicaciones y %2 nuevos mensajes.", + "there-is-a-new-post": "Hay un nuevo mensaje.", + "there-are-new-posts": "Hay %1 nuevos mensajes.", + "click-here-to-reload": "Cliquea aquí para recargar." } \ No newline at end of file diff --git a/public/language/es/search.json b/public/language/es/search.json index add13e50c1..769c91f354 100644 --- a/public/language/es/search.json +++ b/public/language/es/search.json @@ -1,7 +1,7 @@ { "results_matching": "%1 resuldado(s) coinciden con \"%2\". (%3 segundos)", - "no-matches": "No matches found", - "in": "In", - "by": "By", - "posted-by": "Posted by" + "no-matches": "No se encontraron coincidencias", + "in": "En", + "by": "Por", + "posted-by": "Publicado por" } \ No newline at end of file diff --git a/public/language/es/topic.json b/public/language/es/topic.json index 30563b67ae..f1a3f4221c 100644 --- a/public/language/es/topic.json +++ b/public/language/es/topic.json @@ -74,7 +74,7 @@ "fork_no_pids": "¡No has seleccionado ningún mensaje!", "fork_success": "¡Se ha creado un nuevo tema a partir del original! Haz click aquí para ir al nuevo tema.", "composer.title_placeholder": "Ingresa el título de tu tema...", - "composer.handle_placeholder": "Name", + "composer.handle_placeholder": "Nombre", "composer.discard": "Descartar", "composer.submit": "Enviar", "composer.replying_to": "En respuesta a %1", @@ -94,5 +94,5 @@ "oldest_to_newest": "Más antiguo a más nuevo", "newest_to_oldest": "Más nuevo a más antiguo", "most_votes": "Mayor número de votos", - "most_posts": "Most posts" + "most_posts": "Mayor número de mensajes" } \ No newline at end of file diff --git a/public/language/es/user.json b/public/language/es/user.json index 23976718fb..add6981c5f 100644 --- a/public/language/es/user.json +++ b/public/language/es/user.json @@ -2,8 +2,8 @@ "banned": "Baneado", "offline": "Desconectado", "username": "Nombre de usuario", - "joindate": "Join Date", - "postcount": "Post Count", + "joindate": "Fecha de Registro", + "postcount": "Número De Publicaciones", "email": "Correo electrónico", "confirm_email": "Confirmar correo electrónico", "delete_account": "Eliminar cuenta", @@ -18,7 +18,7 @@ "profile_views": "Visitas", "reputation": "Reputación", "favourites": "Favoritos", - "watched": "Watched", + "watched": "Visto", "followers": "Seguidores", "following": "Siguiendo", "signature": "Firma", @@ -59,12 +59,12 @@ "digest_weekly": "Semanalmente", "digest_monthly": "Mensualmente", "send_chat_notifications": "Enviar un email si recibo un mensaje de chat cuando no esté en línea.", - "send_post_notifications": "Send an email when replies are made to topics I am subscribed to", + "send_post_notifications": "Enviarme un email cuando se realicen contestaciones en los temas en los que estoy subscrito", "has_no_follower": "Este usuario no tiene seguidores :(", "follows_no_one": "Este miembro no sigue a nadie :(", "has_no_posts": "Este usuario aún no ha publicado nada.", "has_no_topics": "Este usuario aún no ha publicado nada.", - "has_no_watched_topics": "This user didn't watch any topics yet.", + "has_no_watched_topics": "Este usuario todavía no ha visto ninguna publicación.", "email_hidden": "Correo electrónico oculto", "hidden": "oculto", "paginate_description": "Paginar hilos y mensajes en lugar de usar desplazamiento infinito.", diff --git a/public/language/es/users.json b/public/language/es/users.json index 18b783a6c1..529a6accb5 100644 --- a/public/language/es/users.json +++ b/public/language/es/users.json @@ -6,7 +6,7 @@ "enter_username": "Ingresa el nombre de usuario que quieres buscar", "load_more": "Cargar más", "users-found-search-took": "¡%1 usuario(s) encontrados! La búsqueda tardó %2 ms.", - "filter-by": "Filter By", - "online-only": "Online only", - "picture-only": "Picture only" + "filter-by": "Filtrar Por", + "online-only": "Sólo en línea", + "picture-only": "Sólo imagen" } \ No newline at end of file diff --git a/public/language/et/error.json b/public/language/et/error.json index 0cbb8ea85f..ea2c2e9ff4 100644 --- a/public/language/et/error.json +++ b/public/language/et/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "Sa ei saa endaga vestelda!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "Sul ei ole piisavalt reputatsiooni, et anda negatiivset hinnangut sellele postitusele.", diff --git a/public/language/fa_IR/error.json b/public/language/fa_IR/error.json index 8657d58d7d..61736c18c4 100644 --- a/public/language/fa_IR/error.json +++ b/public/language/fa_IR/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "شما نمی‌توانید با خودتان گفتگو کنید!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "شما اعتبار کافی برای دادن رای منفی به این دیدگاه را ندارید.", diff --git a/public/language/fi/error.json b/public/language/fi/error.json index 0b28c1f98b..a9f843b34a 100644 --- a/public/language/fi/error.json +++ b/public/language/fi/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "Et voi keskustella itsesi kanssa!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/fr/email.json b/public/language/fr/email.json index 1ed4d80cac..0e4f57d601 100644 --- a/public/language/fr/email.json +++ b/public/language/fr/email.json @@ -17,8 +17,8 @@ "notif.chat.subject": "Nouveau message de chat reçu de %1", "notif.chat.cta": "Cliquez ici pour continuer la conversation", "notif.chat.unsub.info": "Cette notification de chat a été envoyé en raison de vos paramètres d'abonnement.", - "notif.post.cta": "Click here to read the full topic", - "notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.", + "notif.post.cta": "Cliquer ici pour lire le sujet complet", + "notif.post.unsub.info": "La notification de ce message vous a été envoyé en raison de vos paramètres d'abonnement.", "test.text1": "Ceci est un email de test pour vérifier que l'emailer est correctement configuré pour NodeBB.", "unsub.cta": "Cliquez ici pour modifier ces paramètres", "closing": "Merci !" diff --git a/public/language/fr/error.json b/public/language/fr/error.json index 28ab5566f6..6354f0e6d9 100644 --- a/public/language/fr/error.json +++ b/public/language/fr/error.json @@ -18,7 +18,7 @@ "username-taken": "Nom d’utilisateur déjà utilisé", "email-taken": "Email déjà utilisé", "email-not-confirmed": "Votre adresse email n'est pas confirmée, cliquer ici pour la valider.", - "email-not-confirmed-chat": "You are unable to chat until your email is confirmed", + "email-not-confirmed-chat": "Vous ne pouver discuter tant que votre email n'est pas confirmé", "username-too-short": "Nom d'utilisateur trop court", "username-too-long": "Nom d'utilisateur trop long", "user-banned": "Utilisateur banni", @@ -44,13 +44,13 @@ "already-favourited": "Vous avez déjà mis ce message en favoris", "already-unfavourited": "Vous avez déjà retiré ce message des favoris", "cant-ban-other-admins": "Vous ne pouvez pas bannir les autres administrateurs !", - "invalid-image-type": "Invalid image type. Allowed types are: %1", - "invalid-image-extension": "Invalid image extension", + "invalid-image-type": "Type d'image invalide. Les types autorisés sont: %1", + "invalid-image-extension": "Extension d'image invalide", "group-name-too-short": "Nom de groupe trop court", "group-already-exists": "Ce groupe existe déjà", "group-name-change-not-allowed": "Modification du nom de groupe non permise", - "group-already-member": "You are already part of this group", - "group-needs-owner": "This group requires at least one owner", + "group-already-member": "Vous faites déjà parti de ce groupe", + "group-needs-owner": "Ce groupe nécessite au moins un propriétaire", "post-already-deleted": "Message déjà supprimé", "post-already-restored": "Message déjà restauré", "topic-already-deleted": "Sujet déjà supprimé", @@ -62,11 +62,12 @@ "signature-too-long": "La signature ne peut dépasser %1 caractères !", "cant-chat-with-yourself": "Vous ne pouvez chatter avec vous même !", "chat-restricted": "Cet utilisateur a restreint les ses messages de chat. Il doit d'abord vous suivre avant de pouvoir discuter avec lui.", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Le système de réputation est désactivé", "downvoting-disabled": "Les votes négatifs ne sont pas autorisés", "not-enough-reputation-to-downvote": "Vous n'avez pas une réputation assez élevée pour noter négativement ce message", "not-enough-reputation-to-flag": "Vous n'avez pas une réputation assez élevée pour signaler ce message", "reload-failed": "NodeBB a rencontré un problème lors du rechargement : \"% 1\" . NodeBB continuera de fonctionner côté client, même si vous devez annuler ce que vous avez fait juste avant de recharger .", "registration-error": "Erreur d'enregistrement", - "parse-error": "Something went wrong while parsing server response" + "parse-error": "Une erreur est survenue en analysant la réponse du serveur" } \ No newline at end of file diff --git a/public/language/fr/global.json b/public/language/fr/global.json index 1937e5faad..bb53439c13 100644 --- a/public/language/fr/global.json +++ b/public/language/fr/global.json @@ -3,10 +3,10 @@ "search": "Recherche", "buttons.close": "Fermer", "403.title": "Accès refusé", - "403.message": "You seem to have stumbled upon a page that you do not have access to.", - "403.login": "Perhaps you should try logging in?", + "403.message": "Il semble que vous ayez atteint une page dont vous n'avez pas accès.", + "403.login": "Peut-être deviez vous essayer de vous connecter?", "404.title": "Introuvable", - "404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.", + "404.message": "Il semble que vous ayez atteint une page qui n'existe pas. Retourner à la page d'accueil.", "500.title": "Erreur interne.", "500.message": "Oops ! Il semblerait que quelque chose se soit mal passé !", "register": "S'inscrire", @@ -27,7 +27,7 @@ "header.tags": "Tags", "header.popular": "Populaire", "header.users": "Utilisateurs", - "header.groups": "Groups", + "header.groups": "Groupes", "header.chats": "Chats", "header.notifications": "Notifications", "header.search": "Recherche", @@ -75,7 +75,7 @@ "updated.title": "Forum mis à jour", "updated.message": "Ce forum a été mis à jour à la dernière version. Cliquez ici pour recharger la page.", "privacy": "Vie privée", - "follow": "Follow", - "unfollow": "Unfollow", + "follow": "S'abonner", + "unfollow": "Se désabonner", "delete_all": "Supprimer Tout" } \ No newline at end of file diff --git a/public/language/fr/groups.json b/public/language/fr/groups.json index c61f42e068..e786d08dd0 100644 --- a/public/language/fr/groups.json +++ b/public/language/fr/groups.json @@ -1,21 +1,21 @@ { "groups": "Groupes", "view_group": "Voir le groupe", - "owner": "Group Owner", - "new_group": "Create New Group", - "no_groups_found": "There are no groups to see", - "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", - "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "owner": "Propriétaire du Groupe", + "new_group": "Créer un Nouveau Groupe", + "no_groups_found": "Il n'y a aucun groupe", + "cover-instructions": "Glisser et Coller une image, ajuster la position, et cliquer sur Enregistrer", + "cover-change": "Modifier", + "cover-save": "Enregistrer", + "cover-saving": "Enregistrement", "details.title": "Informations du groupe", "details.members": "Liste des membres", - "details.pending": "Pending Members", - "details.has_no_posts": "Ce membre du groupe n'a envoyé aucun message.", + "details.pending": "Membres en attente", + "details.has_no_posts": "Les membres de ce groupe n'ont envoyé aucun message.", "details.latest_posts": "Derniers messages", - "details.private": "Private Group", - "details.public": "Public Group", - "details.owner_options": "Group Administration", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "details.private": "Groupe Privé", + "details.public": "Groupe Public", + "details.owner_options": "Administration du Groupe", + "event.updated": "Les détails du groupe ont été mis à jour", + "event.deleted": "Le groupe é%1\" a été supprimé" } \ No newline at end of file diff --git a/public/language/fr/recent.json b/public/language/fr/recent.json index f244b31c35..d2ee95b1b6 100644 --- a/public/language/fr/recent.json +++ b/public/language/fr/recent.json @@ -6,13 +6,13 @@ "year": "An", "alltime": "Toujours", "no_recent_topics": "Il n'y a aucun sujet récent.", - "there-is-a-new-topic": "There is a new topic.", - "there-is-a-new-topic-and-a-new-post": "There is a new topic and a new post.", - "there-is-a-new-topic-and-new-posts": "There is a new topic and %1 new posts.", - "there-are-new-topics": "There are %1 new topics.", - "there-are-new-topics-and-a-new-post": "There are %1 new topics and a new post.", - "there-are-new-topics-and-new-posts": "There are %1 new topics and %2 new posts.", - "there-is-a-new-post": "There is a new post.", - "there-are-new-posts": "There are %1 new posts.", - "click-here-to-reload": "Click here to reload." + "there-is-a-new-topic": "Il y a un nouveau sujet.", + "there-is-a-new-topic-and-a-new-post": "Il y a un nouveau sujet et un nouveau message.", + "there-is-a-new-topic-and-new-posts": "Il y a un nouveau sujet et %1 nouveaux messages.", + "there-are-new-topics": "Il y a %1 nouveaux sujets.", + "there-are-new-topics-and-a-new-post": "Il y a %1 nouveaux sujets et un nouveau message.", + "there-are-new-topics-and-new-posts": "Il y a %1 nouveaux sujets et %2 nouveaux messages.", + "there-is-a-new-post": "Il y a un nouveau message.", + "there-are-new-posts": "Il y a %1 nouveaux messages.", + "click-here-to-reload": "Cliquer ici pour recharger." } \ No newline at end of file diff --git a/public/language/fr/search.json b/public/language/fr/search.json index 63e5537663..b8cdfc8d2a 100644 --- a/public/language/fr/search.json +++ b/public/language/fr/search.json @@ -1,7 +1,7 @@ { "results_matching": "%1 résultat(s) correspondant(s) à \"%2\", (%3 secondes)", - "no-matches": "No matches found", - "in": "In", - "by": "By", - "posted-by": "Posted by" + "no-matches": "Aucune réponse trouvée", + "in": "Dans", + "by": "Par", + "posted-by": "Posté par" } \ No newline at end of file diff --git a/public/language/fr/topic.json b/public/language/fr/topic.json index b20ef314eb..135efce878 100644 --- a/public/language/fr/topic.json +++ b/public/language/fr/topic.json @@ -74,7 +74,7 @@ "fork_no_pids": "Aucun post sélectionné !", "fork_success": "Sujet copié avec succès! Cliquez ici pour aller au sujet copié.", "composer.title_placeholder": "Entrer le titre du sujet ici ...", - "composer.handle_placeholder": "Name", + "composer.handle_placeholder": "Nom", "composer.discard": "Abandonner", "composer.submit": "Envoyer", "composer.replying_to": "Réponse à %1", @@ -94,5 +94,5 @@ "oldest_to_newest": "Du plus ancien au plus récent", "newest_to_oldest": "Du plus récent au plus ancien", "most_votes": "Les mieux notés", - "most_posts": "Most posts" + "most_posts": "Nombre de messages" } \ No newline at end of file diff --git a/public/language/fr/user.json b/public/language/fr/user.json index 83bb6f5d9e..d2cf37feec 100644 --- a/public/language/fr/user.json +++ b/public/language/fr/user.json @@ -2,8 +2,8 @@ "banned": "Banni", "offline": "Hors-ligne", "username": "Nom d'utilisateur", - "joindate": "Join Date", - "postcount": "Post Count", + "joindate": "Date d'Adhésion", + "postcount": "Nombre de Messages", "email": "Email", "confirm_email": "Confirmer l'adresse email", "delete_account": "Supprimer le compte", @@ -18,7 +18,7 @@ "profile_views": "Vues", "reputation": "Réputation", "favourites": "Favoris", - "watched": "Watched", + "watched": "Suivis", "followers": "Abonnés", "following": "Abonnements", "signature": "Signature", @@ -59,12 +59,12 @@ "digest_weekly": "Hebdomadaire", "digest_monthly": "Mensuel", "send_chat_notifications": "Envoyer un e-mail si un nouveau message de chat arrive lorsque je ne suis pas en ligne", - "send_post_notifications": "Send an email when replies are made to topics I am subscribed to", + "send_post_notifications": "Envoyer un email lors de réponses envoyées aux sujets auxquels je suis abonné.", "has_no_follower": "Cet utilisateur n'est suivi par personne :(", "follows_no_one": "Cet utilisateur ne suit personne :(", "has_no_posts": "Ce membre n'a rien posté pour le moment", "has_no_topics": "L’utilisateur n'a pas encore créé de sujet.", - "has_no_watched_topics": "This user didn't watch any topics yet.", + "has_no_watched_topics": "Cet utilisateur ne suis encore aucun sujet.", "email_hidden": "Email masqué", "hidden": "masqué", "paginate_description": "Utiliser la pagination des sujets et des messages au lieu du défilement infini.", diff --git a/public/language/fr/users.json b/public/language/fr/users.json index 3cd259f2c5..8d2c4481ea 100644 --- a/public/language/fr/users.json +++ b/public/language/fr/users.json @@ -6,7 +6,7 @@ "enter_username": "Entrer un nom d'utilisateur pour rechercher", "load_more": "Charger la suite", "users-found-search-took": "%1 utilisateur(s) trouvé(s) ! Recherche effectuée en %2 ms.", - "filter-by": "Filter By", - "online-only": "Online only", - "picture-only": "Picture only" + "filter-by": "Filtrer Par", + "online-only": "En Ligne uniquement", + "picture-only": "Avec Image uniquement" } \ No newline at end of file diff --git a/public/language/he/error.json b/public/language/he/error.json index 28483df65e..28a5461705 100644 --- a/public/language/he/error.json +++ b/public/language/he/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "לא ניתן לעשות צ'אט עם עצמך!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "אין לך מספיק מוניטין כדי להוריד את הדירוג של פוסט זה", diff --git a/public/language/hu/error.json b/public/language/hu/error.json index c0bab322ee..705be11958 100644 --- a/public/language/hu/error.json +++ b/public/language/hu/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sajnáljuk, az aláírás nem lehet hosszabb %1 karakternél.", "cant-chat-with-yourself": "You can't chat with yourself!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/id/error.json b/public/language/id/error.json index 7b1413a957..dcce92a9bf 100644 --- a/public/language/id/error.json +++ b/public/language/id/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Maaf, tanda pengenalmu tidak dapat melebihi %1 karakter.", "cant-chat-with-yourself": "Kamu tidak dapat chat dengan akun sendiri", "chat-restricted": "Pengguna ini telah membatasi percakapa mereka. Mereka harus mengikutimu sebelum kamu dapat melakukan percakapan dengan mereka ", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Sistem reputasi ditiadakan.", "downvoting-disabled": "Downvoting ditiadakan", "not-enough-reputation-to-downvote": "Tidak cukup reputation untuk downvote post ini", diff --git a/public/language/it/error.json b/public/language/it/error.json index 12ebc50080..241f9d90ea 100644 --- a/public/language/it/error.json +++ b/public/language/it/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Spiacenti, la tua firma non può essere lunga %1 caratteri.", "cant-chat-with-yourself": "Non puoi chattare con te stesso!", "chat-restricted": "Questo utente ha ristretto i suoi messaggi in chat alle persone che segue. Per poter chattare con te ti deve prima seguire.", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Il sistema di reputazione è disabilitato.", "downvoting-disabled": "Il Downvoting è disabilitato", "not-enough-reputation-to-downvote": "Non hai i privilegi per votare negativamente questo post", diff --git a/public/language/ja/error.json b/public/language/ja/error.json index b55c713676..a7b4c90a77 100644 --- a/public/language/ja/error.json +++ b/public/language/ja/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "自分にチャットすることはできません!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/ko/error.json b/public/language/ko/error.json index 9ce8f5dd42..88c01be5d7 100644 --- a/public/language/ko/error.json +++ b/public/language/ko/error.json @@ -62,6 +62,7 @@ "signature-too-long": "죄송합니다. 서명은 최대 %1자로 제한됩니다.", "cant-chat-with-yourself": "자신과는 채팅할 수 없습니다.", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "인기도 시스템을 사용하지 않습니다.", "downvoting-disabled": "비추천 기능을 사용하지 않습니다.", "not-enough-reputation-to-downvote": "인기도가 낮아 이 게시물에 반대할 수 없습니다.", diff --git a/public/language/lt/error.json b/public/language/lt/error.json index deb7944e24..91f17b67bc 100644 --- a/public/language/lt/error.json +++ b/public/language/lt/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "Jūs negalite susirašinėti su savimi!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "Jūs neturite pakankamai reputacijos balsuoti prieš šį pranešimą", diff --git a/public/language/ms/error.json b/public/language/ms/error.json index 336f7cd580..9c50886310 100644 --- a/public/language/ms/error.json +++ b/public/language/ms/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "You can't chat with yourself!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/nb/email.json b/public/language/nb/email.json index c3c3e3f474..69fa94dcca 100644 --- a/public/language/nb/email.json +++ b/public/language/nb/email.json @@ -17,8 +17,8 @@ "notif.chat.subject": "Ny chat-melding mottatt fra %1", "notif.chat.cta": "Klikk her for å fortsette samtalen", "notif.chat.unsub.info": "Denne chat-varselen er sendt til deg basert på dine innstillinger for abonnering.", - "notif.post.cta": "Click here to read the full topic", - "notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.", + "notif.post.cta": "Trykk for å lese hele emnet", + "notif.post.unsub.info": "Dette postvarselet ble sendt til deg på grunn av dine abonnementsinnstillinger.", "test.text1": "Dette er en test-epost for å verifisere at epostsystemet i NodeBB fungerer som det skal.", "unsub.cta": "Klikk her for å endre disse innstillingene", "closing": "Takk!" diff --git a/public/language/nb/error.json b/public/language/nb/error.json index ef6f1a20b0..3703ca393c 100644 --- a/public/language/nb/error.json +++ b/public/language/nb/error.json @@ -18,7 +18,7 @@ "username-taken": "Brukernavn opptatt", "email-taken": "E-post opptatt", "email-not-confirmed": "E-posten din har ikke blitt bekreftet enda, vennligst klikk for å bekrefte din e-post.", - "email-not-confirmed-chat": "You are unable to chat until your email is confirmed", + "email-not-confirmed-chat": "Du kan ikke chatte før e-posten din har blitt bekreftet", "username-too-short": "Brukernavnet er for kort", "username-too-long": "Brukernavnet er for langt", "user-banned": "Bruker utestengt", @@ -44,13 +44,13 @@ "already-favourited": "Du har allerede favorittmerket dette innlegget", "already-unfavourited": "Du har allerede avfavorisert dette innlegget", "cant-ban-other-admins": "Du kan ikke utestenge andre administratorer!", - "invalid-image-type": "Invalid image type. Allowed types are: %1", - "invalid-image-extension": "Invalid image extension", + "invalid-image-type": "Ugyldig bildetype. Tilatte typer er: %1", + "invalid-image-extension": "Ugyldig bildefiltype", "group-name-too-short": "Gruppenavnet er for kort", "group-already-exists": "Gruppe eksisterer allerede", "group-name-change-not-allowed": "Gruppenavn ikke tillatt", - "group-already-member": "You are already part of this group", - "group-needs-owner": "This group requires at least one owner", + "group-already-member": "Du er allerede en del av denne gruppen", + "group-needs-owner": "Denne gruppen kreves minst en eier", "post-already-deleted": "Dette innlegget har blitt slettet", "post-already-restored": "Dette innlegget har allerede blitt gjenopprettet", "topic-already-deleted": "Dette emnet har allerede blitt slettet", @@ -62,11 +62,12 @@ "signature-too-long": "Beklager, signaturen din kan ikke være lengre en %1 tegn.", "cant-chat-with-yourself": "Du kan ikke chatte med deg selv!", "chat-restricted": "Denne brukeren har begrenset sine chat-meldinger. De må følge deg før du kan chatte med dem", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Ryktesystem er deaktivert.", "downvoting-disabled": "Nedstemming av deaktivert", "not-enough-reputation-to-downvote": "Du har ikke nok rykte til å nedstemme det innlegget", "not-enough-reputation-to-flag": "Du har ikke nok rykte til å flagge dette innlegget", "reload-failed": "NodeBB støtte på et problem under lasting på nytt: \"%1\". NodeBB vil fortsette å servere eksisterende klientside ressureser, selv om du burde angre endringene du gjorde før du lastet på nytt.", "registration-error": "Feil under registrering", - "parse-error": "Something went wrong while parsing server response" + "parse-error": "Noe gikk feil under analysering av serversvar" } \ No newline at end of file diff --git a/public/language/nb/global.json b/public/language/nb/global.json index 34f3d08cc4..9528d360c5 100644 --- a/public/language/nb/global.json +++ b/public/language/nb/global.json @@ -3,10 +3,10 @@ "search": "Søk", "buttons.close": "Steng", "403.title": "Adgang nektet", - "403.message": "You seem to have stumbled upon a page that you do not have access to.", - "403.login": "Perhaps you should try logging in?", + "403.message": "Du har funnet en side du ikke har tilgang til.", + "403.login": "Kanskje du skal prøve å logge inn?", "404.title": "Ikke funnet", - "404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.", + "404.message": "Du har funnet en side som ikke eksisterer. Returner til startsiden?", "500.title": "Intern feil.", "500.message": "Oops! Ser ut som noe gikk galt!", "register": "Registrer", @@ -27,7 +27,7 @@ "header.tags": "Tagger", "header.popular": "Populære", "header.users": "Brukere", - "header.groups": "Groups", + "header.groups": "Grupper", "header.chats": "Chatter", "header.notifications": "Varsler", "header.search": "Søk", @@ -75,7 +75,7 @@ "updated.title": "Forum oppdatert", "updated.message": "Dette forumet har nettopp blitt oppdatert til den nyeste versjonen. Klikk her for å laste siden på nytt.", "privacy": "Personvern", - "follow": "Follow", - "unfollow": "Unfollow", + "follow": "Følg", + "unfollow": "Avfølg", "delete_all": "Slett alle" } \ No newline at end of file diff --git a/public/language/nb/groups.json b/public/language/nb/groups.json index 3319bcb9a2..7578e96072 100644 --- a/public/language/nb/groups.json +++ b/public/language/nb/groups.json @@ -1,21 +1,21 @@ { "groups": "Grupper", "view_group": "Vis gruppe", - "owner": "Group Owner", - "new_group": "Create New Group", - "no_groups_found": "There are no groups to see", - "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", - "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "owner": "Gruppe-eier", + "new_group": "Opprett ny gruppe", + "no_groups_found": "Det er ingen grupper å se", + "cover-instructions": "Dra og slipp et bilde, dra til posisjon, og trykk Lagre", + "cover-change": "Endre", + "cover-save": "Lagre", + "cover-saving": "Lagrer", "details.title": "Gruppedetaljer", "details.members": "Medlemsliste", - "details.pending": "Pending Members", + "details.pending": "Ventende meldemmer", "details.has_no_posts": "Medlemmene i denne gruppen har ikke skrevet noen innlegg.", "details.latest_posts": "Seneste innlegg", - "details.private": "Private Group", - "details.public": "Public Group", - "details.owner_options": "Group Administration", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "details.private": "Privat grup", + "details.public": "Offentlig grup", + "details.owner_options": "Gruppeadministrasjon", + "event.updated": "Gruppedetaljer har blitt oppgradert", + "event.deleted": "Gruppen \"%1\" har blitt slettet" } \ No newline at end of file diff --git a/public/language/nb/recent.json b/public/language/nb/recent.json index 4a77aab5ab..24ece53c70 100644 --- a/public/language/nb/recent.json +++ b/public/language/nb/recent.json @@ -6,13 +6,13 @@ "year": "År", "alltime": "All tid", "no_recent_topics": "Det er ingen nye tråder.", - "there-is-a-new-topic": "There is a new topic.", - "there-is-a-new-topic-and-a-new-post": "There is a new topic and a new post.", - "there-is-a-new-topic-and-new-posts": "There is a new topic and %1 new posts.", - "there-are-new-topics": "There are %1 new topics.", - "there-are-new-topics-and-a-new-post": "There are %1 new topics and a new post.", - "there-are-new-topics-and-new-posts": "There are %1 new topics and %2 new posts.", - "there-is-a-new-post": "There is a new post.", - "there-are-new-posts": "There are %1 new posts.", - "click-here-to-reload": "Click here to reload." + "there-is-a-new-topic": "Det finnes et nytt emne.", + "there-is-a-new-topic-and-a-new-post": "Det finnes et nytt emne og et nytt innlegg.", + "there-is-a-new-topic-and-new-posts": "Det finnes et nytt emne og %1 nye innlegg.", + "there-are-new-topics": "Det finnes %1 nye emner.", + "there-are-new-topics-and-a-new-post": "Det finnes %1 nye emner og et nytt innlegg.", + "there-are-new-topics-and-new-posts": "Det finnes %1 nye emner og %2 nye innlegg", + "there-is-a-new-post": "Det finnes et nytt innlegg.", + "there-are-new-posts": "Det finnes %1 nye innlegg.", + "click-here-to-reload": "Trykk her for å laste på nytt." } \ No newline at end of file diff --git a/public/language/nb/search.json b/public/language/nb/search.json index 2e9ad3665c..8daeddcb06 100644 --- a/public/language/nb/search.json +++ b/public/language/nb/search.json @@ -1,7 +1,7 @@ { "results_matching": "%1 resultat(er) samsvarer med \"%2\", (%3 sekunder)", - "no-matches": "No matches found", - "in": "In", - "by": "By", - "posted-by": "Posted by" + "no-matches": "Ingen matcher funnet", + "in": "I", + "by": "Av", + "posted-by": "Skapt av" } \ No newline at end of file diff --git a/public/language/nb/topic.json b/public/language/nb/topic.json index 7690cd7114..49096d9f6f 100644 --- a/public/language/nb/topic.json +++ b/public/language/nb/topic.json @@ -74,7 +74,7 @@ "fork_no_pids": "Ingen innlegg valgt!", "fork_success": "Dette emnet ble delt! Klikk for å gå til delt emne.", "composer.title_placeholder": "Skriv din tråd-tittel her", - "composer.handle_placeholder": "Name", + "composer.handle_placeholder": "Navn", "composer.discard": "Forkast", "composer.submit": "Send", "composer.replying_to": "Svarer i %1", @@ -94,5 +94,5 @@ "oldest_to_newest": "Eldste til nyeste", "newest_to_oldest": "Nyeste til eldste", "most_votes": "Flest stemmer", - "most_posts": "Most posts" + "most_posts": "Flest innlegg" } \ No newline at end of file diff --git a/public/language/nb/user.json b/public/language/nb/user.json index b154436e80..f3e6523e25 100644 --- a/public/language/nb/user.json +++ b/public/language/nb/user.json @@ -2,8 +2,8 @@ "banned": "Utestengt", "offline": "Offline", "username": "Brukernavn", - "joindate": "Join Date", - "postcount": "Post Count", + "joindate": "Registereringsdato", + "postcount": "Antall innlegg", "email": "E-post", "confirm_email": "Bekfreft e-post", "delete_account": "Slett konto", @@ -18,7 +18,7 @@ "profile_views": "Profilvisninger", "reputation": "Rykte", "favourites": "Favoritter", - "watched": "Watched", + "watched": "Overvåkede", "followers": "Følgere", "following": "Følger", "signature": "Signatur", @@ -64,7 +64,7 @@ "follows_no_one": "Denne brukeren følger ingen :(", "has_no_posts": "Denne brukeren har ikke skrevet noe enda.", "has_no_topics": "Denne brukeren har ikke skrevet noen emner enda.", - "has_no_watched_topics": "This user didn't watch any topics yet.", + "has_no_watched_topics": "Denne brukeren overvåker ingen innlegg foreløpig.", "email_hidden": "E-post skjult", "hidden": "skjult", "paginate_description": "Paginer tråder og innlegg istedet for å bruke uendelig skrolling.", diff --git a/public/language/nb/users.json b/public/language/nb/users.json index e0f8363a64..a2038667ab 100644 --- a/public/language/nb/users.json +++ b/public/language/nb/users.json @@ -6,7 +6,7 @@ "enter_username": "Skriv ett brukernavn for å søke", "load_more": "Last flere", "users-found-search-took": "%1 bruker(e) funnet! Søk tok %2 ms.", - "filter-by": "Filter By", - "online-only": "Online only", - "picture-only": "Picture only" + "filter-by": "Filtrer etter", + "online-only": "Bare påloggede", + "picture-only": "Bare bilde" } \ No newline at end of file diff --git a/public/language/nl/error.json b/public/language/nl/error.json index 6e4553687a..7fa4a2f24e 100644 --- a/public/language/nl/error.json +++ b/public/language/nl/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, maar deze handtekening kan niet groter zijn dan %1 karakters!", "cant-chat-with-yourself": "Je kan niet met jezelf chatten!", "chat-restricted": "Deze gebruiker heeft beperkingen gelegd op chatfunctie. Hun moeten jouw volgen voordat je met hun kan chatten", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputatie systeem is uitgeschakeld", "downvoting-disabled": "Downvoten is uitgeschakeld", "not-enough-reputation-to-downvote": "U heeft niet de benodigde reputatie om dit bericht te downvoten", diff --git a/public/language/nl/groups.json b/public/language/nl/groups.json index 14a4023b74..a1d2ca868d 100644 --- a/public/language/nl/groups.json +++ b/public/language/nl/groups.json @@ -1,13 +1,13 @@ { "groups": "Groepen", "view_group": "Bekijk Groep", - "owner": "Group Owner", - "new_group": "Create New Group", + "owner": "Groep eigenaar", + "new_group": "Maak een nieuwe groep", "no_groups_found": "There are no groups to see", "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "cover-save": "Opslaan", + "cover-saving": "Bezig met opslaan", "details.title": "Groep Details", "details.members": "Ledenlijst", "details.pending": "Pending Members", diff --git a/public/language/nl/recent.json b/public/language/nl/recent.json index 56f3ca3288..2b1b292298 100644 --- a/public/language/nl/recent.json +++ b/public/language/nl/recent.json @@ -6,10 +6,10 @@ "year": "Jaar", "alltime": "Intussen", "no_recent_topics": "Er zijn geen recente reacties.", - "there-is-a-new-topic": "There is a new topic.", + "there-is-a-new-topic": "Er is een nieuw onderwerp", "there-is-a-new-topic-and-a-new-post": "There is a new topic and a new post.", - "there-is-a-new-topic-and-new-posts": "There is a new topic and %1 new posts.", - "there-are-new-topics": "There are %1 new topics.", + "there-is-a-new-topic-and-new-posts": "Er is een nieuwe onderwerp en %1 nieuwe berichten", + "there-are-new-topics": "Er zijn %1 nieuwe onderwerpen", "there-are-new-topics-and-a-new-post": "There are %1 new topics and a new post.", "there-are-new-topics-and-new-posts": "There are %1 new topics and %2 new posts.", "there-is-a-new-post": "There is a new post.", diff --git a/public/language/nl/search.json b/public/language/nl/search.json index 837a109e6f..60193a06b7 100644 --- a/public/language/nl/search.json +++ b/public/language/nl/search.json @@ -1,7 +1,7 @@ { "results_matching": "%1 resulta(a)ten was een match \"%2\", (%3 seconds)", - "no-matches": "No matches found", - "in": "In", - "by": "By", + "no-matches": "Geen matches gevonden", + "in": "in", + "by": "door", "posted-by": "Posted by" } \ No newline at end of file diff --git a/public/language/nl/topic.json b/public/language/nl/topic.json index c5a7af6b2f..8ab45e30d3 100644 --- a/public/language/nl/topic.json +++ b/public/language/nl/topic.json @@ -74,7 +74,7 @@ "fork_no_pids": "Geen berichten geselecteerd!", "fork_success": "Met succes het onderwerp gesplitst. klik hier om naar het nieuwe onderwerp te gaan.", "composer.title_placeholder": "Vul de titel voor het onderwerp hier in...", - "composer.handle_placeholder": "Name", + "composer.handle_placeholder": "Naam", "composer.discard": "Annuleren", "composer.submit": "Opslaan", "composer.replying_to": "Reageren op %1", @@ -94,5 +94,5 @@ "oldest_to_newest": "Oud naar Nieuw", "newest_to_oldest": "Nieuw naar Oud", "most_votes": "Meeste stemmen", - "most_posts": "Most posts" + "most_posts": "Meeste berichten" } \ No newline at end of file diff --git a/public/language/nl/user.json b/public/language/nl/user.json index fccd6ac057..0cc9df6cbe 100644 --- a/public/language/nl/user.json +++ b/public/language/nl/user.json @@ -2,7 +2,7 @@ "banned": "Verbannen", "offline": "Offline", "username": "Gebruikersnaam", - "joindate": "Join Date", + "joindate": "Datum van registratie", "postcount": "Post Count", "email": "Email", "confirm_email": "Bevestig uw email adres", diff --git a/public/language/nl/users.json b/public/language/nl/users.json index 3f19d8316f..4df6bda6f1 100644 --- a/public/language/nl/users.json +++ b/public/language/nl/users.json @@ -6,7 +6,7 @@ "enter_username": "Vul een gebruikersnaam in om te zoeken", "load_more": "Meer Laden", "users-found-search-took": "%1 gebruiker(s) gevonden! Zoekactie duurde %2 ms.", - "filter-by": "Filter By", - "online-only": "Online only", - "picture-only": "Picture only" + "filter-by": "Filter op", + "online-only": "Online ", + "picture-only": "Alleen een afbeelding" } \ No newline at end of file diff --git a/public/language/pl/error.json b/public/language/pl/error.json index d35d020cc6..8929f25bfa 100644 --- a/public/language/pl/error.json +++ b/public/language/pl/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Przepraszamy, ale podpis nie może być dłuższy niż %1 znaków.", "cant-chat-with-yourself": "Nie możesz rozmawiać ze sobą", "chat-restricted": "Ten użytkownik ograniczył swoje czaty. Musi Cię śledzić, zanim będziesz mógł z nim czatować.", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "System reputacji został wyłączony", "downvoting-disabled": "Ocena postów jest wyłączona", "not-enough-reputation-to-downvote": "Masz za mało reputacji by ocenić ten post.", diff --git a/public/language/pt_BR/email.json b/public/language/pt_BR/email.json index 4465631a3e..04e7f76246 100644 --- a/public/language/pt_BR/email.json +++ b/public/language/pt_BR/email.json @@ -17,8 +17,8 @@ "notif.chat.subject": "Nova mensagem de chat recebida de %1", "notif.chat.cta": "Clique aqui para continuar a conversa", "notif.chat.unsub.info": "Esta notificação de chat foi enviada a você devido às suas configurações de assinatura.", - "notif.post.cta": "Click here to read the full topic", - "notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.", + "notif.post.cta": "Clique aqui para ler o tópico completo", + "notif.post.unsub.info": "Esta notificação de postagem foi enviada para você devido as suas configurações de assinatura.", "test.text1": "Este é um e-mail de teste, para verificar que o enviador de emails está corretamente configurado no seu NodeBB.", "unsub.cta": "Clique aqui para alterar estas configurações", "closing": "Obrigado!" diff --git a/public/language/pt_BR/error.json b/public/language/pt_BR/error.json index 127303d653..912e6b8210 100644 --- a/public/language/pt_BR/error.json +++ b/public/language/pt_BR/error.json @@ -18,7 +18,7 @@ "username-taken": "Nome de usuário já existe", "email-taken": "Email já cadastrado", "email-not-confirmed": "O seu email ainda não foi confirmado, por favor clique aqui para confirmar seu email.", - "email-not-confirmed-chat": "You are unable to chat until your email is confirmed", + "email-not-confirmed-chat": "Você não pode usar o chat até que seu email seja confirmado", "username-too-short": "Nome de usuário muito curto", "username-too-long": "Nome de usuário muito longo", "user-banned": "Usuário banido", @@ -44,13 +44,13 @@ "already-favourited": "Você já adicionou este post aos favoritos", "already-unfavourited": "Você já removeu este post dos favoritos", "cant-ban-other-admins": "Você não pode banir outros administradores!", - "invalid-image-type": "Invalid image type. Allowed types are: %1", - "invalid-image-extension": "Invalid image extension", + "invalid-image-type": "Tipo inválido de imagem. Os tipos permitidos são: %1", + "invalid-image-extension": "Extensão de imagem inválida", "group-name-too-short": "Nome do grupo é muito curto", "group-already-exists": "O grupo já existe", "group-name-change-not-allowed": "Sem permissão para alterar nome do grupo", - "group-already-member": "You are already part of this group", - "group-needs-owner": "This group requires at least one owner", + "group-already-member": "Você já faz parte deste grupo", + "group-needs-owner": "Este grupo requer ao menos um dono", "post-already-deleted": "Este post já foi deletado", "post-already-restored": "Este post já foi restaurado", "topic-already-deleted": "Esté tópico já foi deletado", @@ -62,11 +62,12 @@ "signature-too-long": "Desculpe, sua assinatura não pode ser maior que %1 caracteres.", "cant-chat-with-yourself": "Você não pode iniciar um chat consigo mesmo!", "chat-restricted": "Este usuário restringiu suas mensagens de chat. Eles devem seguir você antes que você possa conversar com eles", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "O sistema de reputação está desabilitado.", "downvoting-disabled": "Negativação está desabilitada", "not-enough-reputation-to-downvote": "Você não possui reputação suficiente para negativar este post", "not-enough-reputation-to-flag": "Você não possui reputação suficiente para sinalizar este post", "reload-failed": "O NodeBB encontrou um problema ao recarregar: \"%1\". O NodeBB continuará a servir os assets existentes no lado do cliente, apesar de que você deve desfazer o que você fez antes de recarregar.", "registration-error": "Erro de Cadastro", - "parse-error": "Something went wrong while parsing server response" + "parse-error": "Algo deu errado ao conseguir resposta do servidor" } \ No newline at end of file diff --git a/public/language/pt_BR/global.json b/public/language/pt_BR/global.json index 88a9d803e6..d9bb14a846 100644 --- a/public/language/pt_BR/global.json +++ b/public/language/pt_BR/global.json @@ -3,10 +3,10 @@ "search": "Procurar", "buttons.close": "Fechar", "403.title": "Acesso Negado", - "403.message": "You seem to have stumbled upon a page that you do not have access to.", - "403.login": "Perhaps you should try logging in?", + "403.message": "Parece que você chegou à uma página à qual você não tem acesso.", + "403.login": "Talvez você deveria tentar logar?", "404.title": "Não Encontrado", - "404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.", + "404.message": "Parece que você chegou à uma página que não existe. Voltar para a página inicial.", "500.title": "Erro interno.", "500.message": "Oops! Parece que algo deu errado!", "register": "Cadastrar", @@ -27,7 +27,7 @@ "header.tags": "Tags", "header.popular": "Popular", "header.users": "Usuários", - "header.groups": "Groups", + "header.groups": "Grupos", "header.chats": "Chats", "header.notifications": "Notificações", "header.search": "Procurar", @@ -75,7 +75,7 @@ "updated.title": "Fórum Atualizado", "updated.message": "Este fórum foi atualizado para sua última versão. Clique aqui para atualizar a página.", "privacy": "Privacidade", - "follow": "Follow", - "unfollow": "Unfollow", + "follow": "Seguir", + "unfollow": "Deixar de seguir", "delete_all": "Deletar Tudo" } \ No newline at end of file diff --git a/public/language/pt_BR/groups.json b/public/language/pt_BR/groups.json index 1893fb87a5..09abeb8bcd 100644 --- a/public/language/pt_BR/groups.json +++ b/public/language/pt_BR/groups.json @@ -1,21 +1,21 @@ { "groups": "Grupos", "view_group": "Ver Grupo", - "owner": "Group Owner", - "new_group": "Create New Group", - "no_groups_found": "There are no groups to see", - "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", - "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "owner": "Dono do Grupo", + "new_group": "Criar Novo Grupo", + "no_groups_found": "Não há grupos para ver", + "cover-instructions": "Arraste uma foto, arraste para a posição correta e clique em Salvar", + "cover-change": "Alterar", + "cover-save": "Salvar", + "cover-saving": "Salvando", "details.title": "Detalhes do Grupo", "details.members": "Lista de Membros", - "details.pending": "Pending Members", + "details.pending": "Membros Pendentes", "details.has_no_posts": "Os membros deste grupo não fizeram quaisquer posts.", "details.latest_posts": "Últimos Posts", - "details.private": "Private Group", - "details.public": "Public Group", - "details.owner_options": "Group Administration", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "details.private": "Grupo Privado", + "details.public": "Grupo Público.", + "details.owner_options": "Administração do Grupo", + "event.updated": "Os detalhes do grupo foram atualizados", + "event.deleted": "O grupo \"%1\" foi deletado" } \ No newline at end of file diff --git a/public/language/pt_BR/recent.json b/public/language/pt_BR/recent.json index 3c3551e0c1..b0dd732602 100644 --- a/public/language/pt_BR/recent.json +++ b/public/language/pt_BR/recent.json @@ -6,13 +6,13 @@ "year": "Ano", "alltime": "Todos os Tempos", "no_recent_topics": "Não há tópicos recentes.", - "there-is-a-new-topic": "There is a new topic.", - "there-is-a-new-topic-and-a-new-post": "There is a new topic and a new post.", - "there-is-a-new-topic-and-new-posts": "There is a new topic and %1 new posts.", - "there-are-new-topics": "There are %1 new topics.", - "there-are-new-topics-and-a-new-post": "There are %1 new topics and a new post.", - "there-are-new-topics-and-new-posts": "There are %1 new topics and %2 new posts.", - "there-is-a-new-post": "There is a new post.", - "there-are-new-posts": "There are %1 new posts.", - "click-here-to-reload": "Click here to reload." + "there-is-a-new-topic": "Há um novo tópico.", + "there-is-a-new-topic-and-a-new-post": "Há um novo tópico e um novo post.", + "there-is-a-new-topic-and-new-posts": "Há um novo tópico e %1 novos posts.", + "there-are-new-topics": "Há %1 novos tópicos.", + "there-are-new-topics-and-a-new-post": "Há %1 novos tópicos e um novo post.", + "there-are-new-topics-and-new-posts": "Há %1 novos tópicos e %2 novos posts.", + "there-is-a-new-post": "Há um novo post.", + "there-are-new-posts": "Há %1 novos posts.", + "click-here-to-reload": "Clique aqui para recarregar." } \ No newline at end of file diff --git a/public/language/pt_BR/search.json b/public/language/pt_BR/search.json index 9d1e425017..f4d633ffd7 100644 --- a/public/language/pt_BR/search.json +++ b/public/language/pt_BR/search.json @@ -1,7 +1,7 @@ { "results_matching": "%1 resultado(s) contendo \"%2\", (%3 segundos)", - "no-matches": "No matches found", - "in": "In", - "by": "By", - "posted-by": "Posted by" + "no-matches": "Nenhum resultado encontrado", + "in": "Em", + "by": "Por", + "posted-by": "Postado por" } \ No newline at end of file diff --git a/public/language/pt_BR/topic.json b/public/language/pt_BR/topic.json index d93e414d45..df49f8cb20 100644 --- a/public/language/pt_BR/topic.json +++ b/public/language/pt_BR/topic.json @@ -74,7 +74,7 @@ "fork_no_pids": "Nenhum post selecionado!", "fork_success": "Tópico clonado com sucesso! Clique aqui para ir ao tópico clonado.", "composer.title_placeholder": "Digite aqui o título para o seu tópico...", - "composer.handle_placeholder": "Name", + "composer.handle_placeholder": "Nome", "composer.discard": "Descartar", "composer.submit": "Enviar", "composer.replying_to": "Respondendo para %1", @@ -94,5 +94,5 @@ "oldest_to_newest": "Mais Antigo para Mais Recente", "newest_to_oldest": "Mais Recente para Mais Antigo", "most_votes": "Mais votados", - "most_posts": "Most posts" + "most_posts": "Mais posts" } \ No newline at end of file diff --git a/public/language/pt_BR/user.json b/public/language/pt_BR/user.json index f4fe0a6602..86412afd5c 100644 --- a/public/language/pt_BR/user.json +++ b/public/language/pt_BR/user.json @@ -2,8 +2,8 @@ "banned": "Banido", "offline": "Offline", "username": "Nome de Usuário", - "joindate": "Join Date", - "postcount": "Post Count", + "joindate": "Data de Entrada", + "postcount": "Número de Posts", "email": "Email", "confirm_email": "Confirmar Email", "delete_account": "Deletar Conta", @@ -18,7 +18,7 @@ "profile_views": "Visualizações de perfil", "reputation": "Reputação", "favourites": "Favoritos", - "watched": "Watched", + "watched": "Acompanhado", "followers": "Seguidores", "following": "Seguindo", "signature": "Assinatura", @@ -59,12 +59,12 @@ "digest_weekly": "Semanalmente", "digest_monthly": "Mensalmente", "send_chat_notifications": "Enviar-me um email se uma nova mensagem de chat chegar quando eu não estiver online.", - "send_post_notifications": "Send an email when replies are made to topics I am subscribed to", + "send_post_notifications": "Enviar um email quando respostas forem dadas à tópicos que eu assino", "has_no_follower": "Este usuário não possui seguidores :(", "follows_no_one": "Este usuário não está seguindo ninguém :(", "has_no_posts": "Este usuário não postou nada ainda.", "has_no_topics": "Este usuário ainda não criou nenhum tópico.", - "has_no_watched_topics": "This user didn't watch any topics yet.", + "has_no_watched_topics": "Este usuário ainda não acompanhou quaisquer tópicos.", "email_hidden": "Email Escondido", "hidden": "escondido", "paginate_description": "Paginação de tópicos e posts ao invés de usar \"rolagem infinita\".", diff --git a/public/language/pt_BR/users.json b/public/language/pt_BR/users.json index 66ea217bd6..dc447048a0 100644 --- a/public/language/pt_BR/users.json +++ b/public/language/pt_BR/users.json @@ -6,7 +6,7 @@ "enter_username": "Digite um nome de usuário para procurar", "load_more": "Carregar Mais", "users-found-search-took": "%1 usuário(s) encontrado(s)! A pesquisa demorou %2 ms.", - "filter-by": "Filter By", - "online-only": "Online only", - "picture-only": "Picture only" + "filter-by": "Filtrar Por", + "online-only": "Apenas Online", + "picture-only": "Apenas foto" } \ No newline at end of file diff --git a/public/language/ro/error.json b/public/language/ro/error.json index ce47fad775..06cad8ebe8 100644 --- a/public/language/ro/error.json +++ b/public/language/ro/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "Nu poți conversa cu tine!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Sistemul de reputație este dezactivat.", "downvoting-disabled": "Votarea negativă este dezactivată", "not-enough-reputation-to-downvote": "Nu ai destulă reputație pentru a vota negativ acest post.", diff --git a/public/language/ru/error.json b/public/language/ru/error.json index 8570dcc524..d23bdef9b6 100644 --- a/public/language/ru/error.json +++ b/public/language/ru/error.json @@ -18,7 +18,7 @@ "username-taken": "Имя пользователя занято", "email-taken": "Email занят", "email-not-confirmed": "Ваш email не подтвержден, нажмите для подтверждения.", - "email-not-confirmed-chat": "You are unable to chat until your email is confirmed", + "email-not-confirmed-chat": "Вы не можете оставлять сообщения, пока Ваш email не подтверждён", "username-too-short": "Слишком короткое имя пользователя", "username-too-long": "Имя пользователя слишком длинное", "user-banned": "Пользователь заблокирован", @@ -45,12 +45,12 @@ "already-unfavourited": "Вы уже удалили этот пост из избранного", "cant-ban-other-admins": "Вы не можете забанить других администраторов!", "invalid-image-type": "Invalid image type. Allowed types are: %1", - "invalid-image-extension": "Invalid image extension", + "invalid-image-extension": "Недопустимое расширение файла", "group-name-too-short": "Название группы слишком короткое", "group-already-exists": "Группа уже существует", "group-name-change-not-allowed": "Изменение названия группы запрещено", - "group-already-member": "You are already part of this group", - "group-needs-owner": "This group requires at least one owner", + "group-already-member": "Вы уже состоите в этой группе", + "group-needs-owner": "У группы должен быть как минимум один владелец", "post-already-deleted": "Этот пост уже удалён", "post-already-restored": "Этот пост уже восстановлен.", "topic-already-deleted": "Тема уже удалена", @@ -62,6 +62,7 @@ "signature-too-long": "Ваша подпись не может быть длиннее %1 симв.", "cant-chat-with-yourself": "Вы не можете общаться с самим собой", "chat-restricted": "Пользователь ограничил прием сообщений. Он должен подписаться на Вас, чтобы Вы могли вести переписку с ним.", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Система репутации отключена.", "downvoting-disabled": "Понижение оценки отключено", "not-enough-reputation-to-downvote": "У Вас недостаточно репутации для понижения оценки поста", diff --git a/public/language/ru/global.json b/public/language/ru/global.json index 8a4e0ad0ec..1983e9f1ab 100644 --- a/public/language/ru/global.json +++ b/public/language/ru/global.json @@ -4,7 +4,7 @@ "buttons.close": "Закрыть", "403.title": "Доступ запрещен", "403.message": "You seem to have stumbled upon a page that you do not have access to.", - "403.login": "Perhaps you should try logging in?", + "403.login": "Возможно Вам следует войти под своим аккаунтом?", "404.title": "Страница не найдена", "404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.", "500.title": "Внутренняя ошибка.", @@ -27,7 +27,7 @@ "header.tags": "Тэги", "header.popular": "Популярные", "header.users": "Пользователи", - "header.groups": "Groups", + "header.groups": "Группы", "header.chats": "Чаты", "header.notifications": "Уведомления", "header.search": "Поиск", diff --git a/public/language/ru/groups.json b/public/language/ru/groups.json index 15bcdf5caa..55a2f35561 100644 --- a/public/language/ru/groups.json +++ b/public/language/ru/groups.json @@ -1,21 +1,21 @@ { "groups": "Группы", "view_group": "Просмотр группы", - "owner": "Group Owner", - "new_group": "Create New Group", + "owner": "Владелец группы", + "new_group": "Создать группу", "no_groups_found": "There are no groups to see", - "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", + "cover-instructions": "Перетяните сюда изображение, переместите на нужную позицию и нажмите Сохранить", "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "cover-save": "Сохранить", + "cover-saving": "Сохраняем", "details.title": "Информация о группе", "details.members": "Список пользователей", - "details.pending": "Pending Members", + "details.pending": "Заявки в группу", "details.has_no_posts": "Пользователями этой группы не публиковали никаких записей", "details.latest_posts": "Последние записи", - "details.private": "Private Group", - "details.public": "Public Group", - "details.owner_options": "Group Administration", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "details.private": "Приватная группа", + "details.public": "Открытая группа", + "details.owner_options": "Настройки группы", + "event.updated": "Настройки группы обновлены", + "event.deleted": "Группа \"%1\" удалена" } \ No newline at end of file diff --git a/public/language/sc/error.json b/public/language/sc/error.json index a40a628042..6079502fae 100644 --- a/public/language/sc/error.json +++ b/public/language/sc/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "You can't chat with yourself!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/sk/error.json b/public/language/sk/error.json index b278526244..92f07fce4c 100644 --- a/public/language/sk/error.json +++ b/public/language/sk/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "Nemôžete chatovat so samým sebou.", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/sv/error.json b/public/language/sv/error.json index 28e67f55cf..d1d82a2f0d 100644 --- a/public/language/sv/error.json +++ b/public/language/sv/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Signaturer kan tyvärr inte vara längre än %1 tecken.", "cant-chat-with-yourself": "Du kan inte chatta med dig själv.", "chat-restricted": "Denna användaren har begränsat sina chatt-meddelanden. Användaren måste följa dig innan ni kan chatta med varann", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Ryktessystemet är inaktiverat.", "downvoting-disabled": "Nedröstning är inaktiverat", "not-enough-reputation-to-downvote": "Du har inte tillräckligt förtroende för att rösta ner det här meddelandet", diff --git a/public/language/th/error.json b/public/language/th/error.json index f65481696d..55dc809071 100644 --- a/public/language/th/error.json +++ b/public/language/th/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "You can't chat with yourself!", "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", "not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post", diff --git a/public/language/tr/error.json b/public/language/tr/error.json index 4e509a438d..4ab34132fc 100644 --- a/public/language/tr/error.json +++ b/public/language/tr/error.json @@ -62,6 +62,7 @@ "signature-too-long": "İmza en fazla %1 karakter olabilir!", "cant-chat-with-yourself": "Kendinizle sohbet edemezsiniz!", "chat-restricted": "Bu kullanıcı sohbet ayarlarını kısıtlamış. Bu kişiye mesaj gönderebilmeniz için sizi takip etmeleri gerekiyor", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Saygınlık sistemi kapatılmış.", "downvoting-disabled": "Aşagı oylama kapatılmış", "not-enough-reputation-to-downvote": "Bu iletiyi aşagı oylamak için yeterince saygınlığınız yok.", diff --git a/public/language/vi/error.json b/public/language/vi/error.json index 002f910fc4..8dd065f637 100644 --- a/public/language/vi/error.json +++ b/public/language/vi/error.json @@ -62,6 +62,7 @@ "signature-too-long": "Chứ ký không được dài quá %1 ký tự", "cant-chat-with-yourself": "Bạn không thể chat với chính bạn!", "chat-restricted": "Người dùng này đã bật chế độ hạn chế tin nhắn chat. Bạn phải được anh/cô ta follow thì mới có thể gởi tin nhắn đến họ được.", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "Hệ thống tín nhiệm đã bị vô hiệu hóa.", "downvoting-disabled": "Downvote đã bị tắt", "not-enough-reputation-to-downvote": "Bạn không có đủ phiếu tín nhiệm để downvote bài này", diff --git a/public/language/zh_CN/error.json b/public/language/zh_CN/error.json index acab3971eb..eef3088946 100644 --- a/public/language/zh_CN/error.json +++ b/public/language/zh_CN/error.json @@ -62,6 +62,7 @@ "signature-too-long": "抱歉,您的签名不能超过 %1 个字符。", "cant-chat-with-yourself": "您不能和自己聊天!", "chat-restricted": "此用户限制了他的聊天消息。必须他先关注您,您才能和他聊天。", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "威望系统已禁用。", "downvoting-disabled": "反对功能已禁用", "not-enough-reputation-to-downvote": "您还没有足够的威望为此帖扣分", diff --git a/public/language/zh_TW/error.json b/public/language/zh_TW/error.json index 32fdfd6f7f..5342050972 100644 --- a/public/language/zh_TW/error.json +++ b/public/language/zh_TW/error.json @@ -62,6 +62,7 @@ "signature-too-long": "對不起,簽名檔長度不能超過 %1 字元!", "cant-chat-with-yourself": "你不能與自己聊天!", "chat-restricted": "此用戶已限制了他的聊天功能。你要在他關注你之後,才能跟他聊天", + "too-many-messages": "You have sent too many messages, please wait awhile.", "reputation-system-disabled": "信譽系統已停用。", "downvoting-disabled": "Downvoting已停用", "not-enough-reputation-to-downvote": "你沒有足夠的信譽downvote這個帖子", From a46aaf2c8752e0fd05f01d2ed67dd4e9b9786908 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 1 Feb 2015 20:01:41 -0500 Subject: [PATCH 054/164] fixed #2681 --- src/file.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/file.js b/src/file.js index 9433dfb40b..bf8aa05c02 100644 --- a/src/file.js +++ b/src/file.js @@ -18,7 +18,7 @@ file.saveFileToLocal = function(filename, folder, tempPath, callback) { is.on('end', function () { callback(null, { - url: nconf.get('upload_url') + folder + '/' + filename + url: nconf.get('url') + '/uploads/' + folder + '/' + filename }); }); From cfcfc8e0b15fcf1848bac28692b03f3d86910f78 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 1 Feb 2015 20:03:48 -0500 Subject: [PATCH 055/164] Revert "fixed #2681" This reverts commit a46aaf2c8752e0fd05f01d2ed67dd4e9b9786908. --- src/file.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/file.js b/src/file.js index bf8aa05c02..9433dfb40b 100644 --- a/src/file.js +++ b/src/file.js @@ -18,7 +18,7 @@ file.saveFileToLocal = function(filename, folder, tempPath, callback) { is.on('end', function () { callback(null, { - url: nconf.get('url') + '/uploads/' + folder + '/' + filename + url: nconf.get('upload_url') + folder + '/' + filename }); }); From 6a837632fa37d01304dbdbaff8935013b7fe2136 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 1 Feb 2015 20:10:51 -0500 Subject: [PATCH 056/164] fix first post loading when pagination is enabled --- public/src/client/topic/posts.js | 17 +++++++---------- src/controllers/topics.js | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index ec566d9812..7bd7b714ae 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -14,11 +14,11 @@ define('forum/topic/posts', [ Posts.onNewPost = function(data) { var tid = ajaxify.variables.get('topic_id'); - if(data && data.posts && data.posts.length && parseInt(data.posts[0].tid, 10) !== parseInt(tid, 10)) { + if (data && data.posts && data.posts.length && parseInt(data.posts[0].tid, 10) !== parseInt(tid, 10)) { return; } - if(config.usePagination) { + if (config.usePagination) { return onNewPostPagination(data); } @@ -32,14 +32,11 @@ define('forum/topic/posts', [ function onNewPostPagination(data) { var posts = data.posts; - socket.emit('topics.getPageCount', ajaxify.variables.get('topic_id'), function(err, newPageCount) { - - if (pagination.currentPage === pagination.pageCount) { - createNewPosts(data); - } else if(data.posts && data.posts.length && parseInt(data.posts[0].uid, 10) === parseInt(app.uid, 10)) { - pagination.loadPage(pagination.pageCount); - } - }); + if (pagination.currentPage === pagination.pageCount) { + createNewPosts(data); + } else if(data.posts && data.posts.length && parseInt(data.posts[0].uid, 10) === parseInt(app.uid, 10)) { + pagination.loadPage(pagination.pageCount); + } } function createNewPosts(data, callback) { diff --git a/src/controllers/topics.js b/src/controllers/topics.js index 6b3b42ab93..ffcca5ab46 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -54,7 +54,7 @@ topicsController.get = function(req, res, next) { var settings = results.settings; var postCount = parseInt(results.topic.postcount, 10); - var pageCount = Math.ceil((postCount - 1) / settings.postsPerPage); + var pageCount = Math.max(1, Math.ceil((postCount - 1) / settings.postsPerPage)); if (utils.isNumber(req.params.post_index)) { var url = ''; From b3278cf8e851f0ecd79d97b35f97d3e386529450 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 1 Feb 2015 20:21:18 -0500 Subject: [PATCH 057/164] fixed #2681 --- src/user/digest.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/user/digest.js b/src/user/digest.js index 62c8a11ae8..06ea1aa967 100644 --- a/src/user/digest.js +++ b/src/user/digest.js @@ -9,7 +9,8 @@ var async = require('async'), user = require('../user'), topics = require('../topics'), batch = require('../batch'), - emailer = require('../emailer'); + emailer = require('../emailer'), + utils = require('../../public/src/utils'); (function(Digest) { Digest.execute = function(interval) { @@ -31,6 +32,22 @@ var async = require('async'), return winston.error('[user/jobs] Could not send digests (' + interval + '): ' + err.message); } + // Fix relative paths in topic data + data.topics.topics = data.topics.topics.map(function(topicObj) { + if (topicObj.hasOwnProperty('teaser') && topicObj.teaser !== undefined) { + if (utils.isRelativeUrl(topicObj.teaser.user.picture)) { + topicObj.teaser.user.picture = nconf.get('url') + topicObj.teaser.user.picture; + } + } else { + if (utils.isRelativeUrl(topicObj.user.picture)) { + topicObj.user.picture = nconf.get('url') + topicObj.user.picture; + } + } + + return topicObj; + }); + return; + data.interval = interval; if (data.subscribers.length) { From 1b00d0f739ef627f3ca5811071c33d9fc05beb61 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 1 Feb 2015 20:29:57 -0500 Subject: [PATCH 058/164] fixed #2670 --- public/src/client/chats.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/public/src/client/chats.js b/public/src/client/chats.js index 56cba8c16e..607b84d4f3 100644 --- a/public/src/client/chats.js +++ b/public/src/client/chats.js @@ -18,10 +18,13 @@ define('forum/chats', ['string', 'sounds', 'forum/infinitescroll'], function(S, } Chats.addEventListeners(); - Chats.resizeMainWindow(); - Chats.scrollToBottom(containerEl); Chats.setActive(); + $(window).on('action:ajaxify.end', function() { + Chats.resizeMainWindow(); + Chats.scrollToBottom(containerEl); + }); + Chats.initialised = true; }; From cc2ab12f299b0fa8ddc0833e590e07e00b455602 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 1 Feb 2015 21:38:10 -0500 Subject: [PATCH 059/164] removed bans from downvotes and flags cleanup thread tools emits --- public/src/client/categoryTools.js | 9 +--- public/src/client/topic/events.js | 2 +- src/socket.io/posts.js | 51 +------------------ src/socket.io/topics.js | 73 +++++++++++++-------------- src/threadTools.js | 79 +++++++++++------------------- src/views/admin/settings/user.tpl | 20 -------- 6 files changed, 71 insertions(+), 163 deletions(-) diff --git a/public/src/client/categoryTools.js b/public/src/client/categoryTools.js index b94954626a..0e9bae608b 100644 --- a/public/src/client/categoryTools.js +++ b/public/src/client/categoryTools.js @@ -199,13 +199,8 @@ define('forum/categoryTools', ['forum/topic/move', 'topicSelect'], function(move getTopicEl(data.tid).remove(); } - function onTopicPurged(tids) { - if (!tids) { - return; - } - for(var i=0; i= parseInt(meta.config['autoban:downvote:threshold'], 10)) { - return callback(err); - } - - var adminUser = require('./admin/user'); - adminUser.banUser(uid, function(err) { - if (err) { - return callback(err); - } - events.log({ - type: 'banned', - reason: 'low-reputation', - uid: socket.uid, - ip: socket.ip, - targetUid: data.uid, - reputation: userData.reputation - }); - callback(); - }); - }); - } - } - - favouriteCommand(socket, 'downvote', 'voted', '', data, function(err) { - if (err) { - return callback(err); - } - banUserForLowReputation(data.uid, callback); - }); + favouriteCommand(socket, 'downvote', 'voted', '', data, callback); }; SocketPosts.unvote = function(socket, data, callback) { @@ -480,23 +449,7 @@ SocketPosts.flag = function(socket, pid, callback) { return next(); } - db.setAdd('uid:' + post.uid + ':flagged_by', socket.uid, function(err) { - if (err) { - return next(err); - } - db.setCount('uid:' + post.uid + ':flagged_by', function(err, count) { - if (err) { - return next(err); - } - - if (count >= (meta.config.flagsForBan || 3) && parseInt(meta.config.flagsForBan, 10) !== 0) { - var adminUser = require('./admin/user'); - adminUser.banUser(post.uid, next); - return; - } - next(); - }); - }); + db.setAdd('uid:' + post.uid + ':flagged_by', socket.uid, next); } ], callback); }; diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index 687a7361a5..5cc6cb3bad 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -21,6 +21,7 @@ var nconf = require('nconf'), SocketTopics = {}; + SocketTopics.post = function(socket, data, callback) { if(!data) { return callback(new Error('[[error:invalid-data]]')); @@ -204,44 +205,34 @@ SocketTopics.markAsUnreadForAll = function(socket, tids, callback) { }; SocketTopics.delete = function(socket, data, callback) { - doTopicAction('delete', socket, data, callback); + doTopicAction('delete', 'event:topic_deleted', socket, data, callback); }; SocketTopics.restore = function(socket, data, callback) { - doTopicAction('restore', socket, data, callback); + doTopicAction('restore', 'event:topic_restored', socket, data, callback); }; SocketTopics.purge = function(socket, data, callback) { - doTopicAction('purge', socket, data, function(err) { - if (err) { - return callback(err); - } - - websockets.in('category_' + data.cid).emit('event:topic_purged', data.tids); - async.each(data.tids, function(tid, next) { - websockets.in('topic_' + tid).emit('event:topic_purged', tid); - next(); - }, callback); - }); + doTopicAction('purge', 'event:topic_purged', socket, data, callback); }; SocketTopics.lock = function(socket, data, callback) { - doTopicAction('lock', socket, data, callback); + doTopicAction('lock', 'event:topic_locked', socket, data, callback); }; SocketTopics.unlock = function(socket, data, callback) { - doTopicAction('unlock', socket, data, callback); + doTopicAction('unlock', 'event:topic_unlocked', socket, data, callback); }; SocketTopics.pin = function(socket, data, callback) { - doTopicAction('pin', socket, data, callback); + doTopicAction('pin', 'event:topic_pinned', socket, data, callback); }; SocketTopics.unpin = function(socket, data, callback) { - doTopicAction('unpin', socket, data, callback); + doTopicAction('unpin', 'event:topic_unpinned', socket, data, callback); }; -function doTopicAction(action, socket, data, callback) { +function doTopicAction(action, event, socket, data, callback) { if (!socket.uid) { return; } @@ -251,35 +242,45 @@ function doTopicAction(action, socket, data, callback) { async.each(data.tids, function(tid, next) { privileges.topics.canEdit(tid, socket.uid, function(err, canEdit) { - if(err) { + if (err) { return next(err); } - if(!canEdit) { + if (!canEdit) { return next(new Error('[[error:no-privileges]]')); } - if(typeof threadTools[action] === 'function') { - threadTools[action](tid, socket.uid, function(err) { - if (err) { - return next(err); - } - - if (action === 'delete' || action === 'restore' || action === 'purge') { - events.log({ - type: 'topic-' + action, - uid: socket.uid, - ip: socket.ip, - tid: tid - }); - } - next(); - }); + if (typeof threadTools[action] !== 'function') { + return next(); } + + threadTools[action](tid, socket.uid, function(err, data) { + if (err) { + return next(err); + } + + emitToTopicAndCategory(event, data); + + if (action === 'delete' || action === 'restore' || action === 'purge') { + events.log({ + type: 'topic-' + action, + uid: socket.uid, + ip: socket.ip, + tid: tid + }); + } + + next(); + }); }); }, callback); } +function emitToTopicAndCategory(event, data) { + websockets.in('topic_' + data.tid).emit(event, data); + websockets.in('category_' + data.cid).emit(event, data); +} + SocketTopics.createTopicFromPosts = function(socket, data, callback) { if(!socket.uid) { return callback(new Error('[[error:not-logged-in]]')); diff --git a/src/threadTools.js b/src/threadTools.js index 077abc54e6..1a62564434 100644 --- a/src/threadTools.js +++ b/src/threadTools.js @@ -11,7 +11,6 @@ var winston = require('winston'), notifications = require('./notifications'), posts = require('./posts'), meta = require('./meta'), - websockets = require('./socket.io'), events = require('./events'), plugins = require('./plugins'), batch = require('./batch'); @@ -39,12 +38,6 @@ var winston = require('winston'), } topics[isDelete ? 'delete' : 'restore'](tid, function(err) { - function emitTo(room) { - websockets.in(room).emit(isDelete ? 'event:topic_deleted' : 'event:topic_restored', { - tid: tid, - isDelete: isDelete - }); - } if (err) { return callback(err); } @@ -56,17 +49,20 @@ var winston = require('winston'), plugins.fireHook('action:topic.restore', topicData); } - emitTo('topic_' + tid); - emitTo('category_' + topicData.cid); + var data = { + tid: tid, + cid: topicData.cid, + isDelete: isDelete, + uid: uid + }; - callback(null, { - tid: tid - }); + callback(null, data); }); }); } ThreadTools.purge = function(tid, uid, callback) { + var topic; async.waterfall([ function(next) { topics.exists(tid, next); @@ -80,13 +76,17 @@ var winston = require('winston'), }, {alwaysStartAt: 0}, next); }, function(next) { - topics.getTopicField(tid, 'mainPid', next); + topics.getTopicFields(tid, ['mainPid', 'cid'], next); }, - function(mainPid, next) { - posts.purge(mainPid, next); + function(_topic, next) { + topic = _topic; + posts.purge(topic.mainPid, next); }, function(next) { topics.purge(tid, next); + }, + function(next) { + next(null, {tid: tid, cid: topic.cid, uid: uid}); } ], callback); }; @@ -100,35 +100,24 @@ var winston = require('winston'), }; function toggleLock(tid, uid, lock, callback) { + callback = callback || function() {}; topics.getTopicField(tid, 'cid', function(err, cid) { - function emitTo(room) { - websockets.in(room).emit(lock ? 'event:topic_locked' : 'event:topic_unlocked', { - tid: tid, - isLocked: lock - }); - } - - if (err && typeof callback === 'function') { + if (err) { return callback(err); } topics.setTopicField(tid, 'locked', lock ? 1 : 0); - plugins.fireHook('action:topic.lock', { + var data = { tid: tid, isLocked: lock, - uid: uid - }); + uid: uid, + cid: cid + }; - emitTo('topic_' + tid); - emitTo('category_' + cid); + plugins.fireHook('action:topic.lock', data); - if (typeof callback === 'function') { - callback(null, { - tid: tid, - isLocked: lock - }); - } + callback(null, data); }); } @@ -142,13 +131,6 @@ var winston = require('winston'), function togglePin(tid, uid, pin, callback) { topics.getTopicFields(tid, ['cid', 'lastposttime'], function(err, topicData) { - function emitTo(room) { - websockets.in(room).emit(pin ? 'event:topic_pinned' : 'event:topic_unpinned', { - tid: tid, - isPinned: pin - }); - } - if (err) { return callback(err); } @@ -156,19 +138,16 @@ var winston = require('winston'), topics.setTopicField(tid, 'pinned', pin ? 1 : 0); db.sortedSetAdd('cid:' + topicData.cid + ':tids', pin ? Math.pow(2, 53) : topicData.lastposttime, tid); - plugins.fireHook('action:topic.pin', { + var data = { tid: tid, isPinned: pin, - uid: uid - }); + uid: uid, + cid: topicData.cid + }; - emitTo('topic_' + tid); - emitTo('category_' + topicData.cid); + plugins.fireHook('action:topic.pin', data); - callback(null, { - tid: tid, - isPinned: pin - }); + callback(null, data); }); } diff --git a/src/views/admin/settings/user.tpl b/src/views/admin/settings/user.tpl index 5f1bfd11f9..b44884ae81 100644 --- a/src/views/admin/settings/user.tpl +++ b/src/views/admin/settings/user.tpl @@ -97,26 +97,6 @@
-
-
User Bans
-
-
-
- - -
-
-
- -
- - -
-
-
-
User Registration
From 28c57b6635bbdf8a5270f651e2465ee070bcf965 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 2 Feb 2015 15:56:29 -0500 Subject: [PATCH 060/164] removed unused requires --- src/threadTools.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/threadTools.js b/src/threadTools.js index 1a62564434..96d8198291 100644 --- a/src/threadTools.js +++ b/src/threadTools.js @@ -1,17 +1,11 @@ 'use strict'; -var winston = require('winston'), - nconf = require('nconf'), - async = require('async'), +var async = require('async'), db = require('./database'), topics = require('./topics'), categories = require('./categories'), - user = require('./user'), - notifications = require('./notifications'), posts = require('./posts'), - meta = require('./meta'), - events = require('./events'), plugins = require('./plugins'), batch = require('./batch'); From 255f50343c50717f93e821a3fdec7661b757f9dc Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 3 Feb 2015 16:13:09 -0500 Subject: [PATCH 061/164] closes #2685 --- install/data/defaults.json | 4 ++++ public/language/en_GB/error.json | 1 + public/src/modules/composer.js | 2 ++ src/controllers/api.js | 1 + src/socket.io/posts.js | 2 ++ src/topics/create.js | 2 ++ src/views/admin/settings/post.tpl | 4 ++++ 7 files changed, 16 insertions(+) diff --git a/install/data/defaults.json b/install/data/defaults.json index 5507ad0822..778dee3838 100644 --- a/install/data/defaults.json +++ b/install/data/defaults.json @@ -27,6 +27,10 @@ "field": "minimumPostLength", "value": 8 }, + { + "field": "maximumPostLength", + "value": 32767 + }, { "field": "allowGuestSearching", "value": 0 diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 47b0bf8938..0258b28154 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -46,6 +46,7 @@ "still-uploading": "Please wait for uploads to complete.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.", "invalid-title": "Invalid title!", diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index 5a80616517..2836967416 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -406,6 +406,8 @@ define('composer', [ return composerAlert('[[error:invalid-title]]'); } else if (bodyEl.val().length < parseInt(config.minimumPostLength, 10)) { return composerAlert('[[error:content-too-short, ' + config.minimumPostLength + ']]'); + } else if (bodyEl.val().length > parseInt(config.maximumPostLength, 10)) { + return composerAlert('[[error:content-too-long, ' + config.maximumPostLength + ']]'); } var composerData = {}, action; diff --git a/src/controllers/api.js b/src/controllers/api.js index be4d8b2347..a3412e0d1d 100644 --- a/src/controllers/api.js +++ b/src/controllers/api.js @@ -23,6 +23,7 @@ apiController.getConfig = function(req, res, next) { config.minimumTitleLength = meta.config.minimumTitleLength; config.maximumTitleLength = meta.config.maximumTitleLength; config.minimumPostLength = meta.config.minimumPostLength; + config.minimumPostLength = meta.config.maximumPostLength; config.hasImageUploadPlugin = plugins.hasListeners('filter:uploadImage'); config.maximumProfileImageSize = meta.config.maximumProfileImageSize; config.minimumUsernameLength = meta.config.minimumUsernameLength; diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index d9f673067c..5baa38e9cb 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -261,6 +261,8 @@ SocketPosts.edit = function(socket, data, callback) { return callback(new Error('[[error:title-too-long, ' + meta.config.maximumTitleLength + ']]')); } else if (!data.content || data.content.length < parseInt(meta.config.minimumPostLength, 10)) { return callback(new Error('[[error:content-too-short, ' + meta.config.minimumPostLength + ']]')); + } else if (data.content.length > parseInt(meta.config.maximumPostLength, 10)) { + return callback(new Error('[[error:content-too-long, ' + meta.config.maximumPostLength + ']]')); } // uid, pid, title, content, options diff --git a/src/topics/create.js b/src/topics/create.js index b3038911c1..2eb882da80 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -289,6 +289,8 @@ module.exports = function(Topics) { function checkContentLength(content, callback) { if (!content || content.length < parseInt(meta.config.miminumPostLength, 10)) { return callback(new Error('[[error:content-too-short, ' + meta.config.minimumPostLength + ']]')); + } else if (content.length > parseInt(meta.config.maximumPostLength, 10)) { + return callback(new Error('[[error:content-too-long, ' + meta.config.maximumPostLength + ']]')); } callback(); } diff --git a/src/views/admin/settings/post.tpl b/src/views/admin/settings/post.tpl index 15f65ef531..3cb55eac0e 100644 --- a/src/views/admin/settings/post.tpl +++ b/src/views/admin/settings/post.tpl @@ -49,6 +49,10 @@
+
+ + +
+ +
+ +
From d3aa353d73d474ca26d5592e0451107f4360fc7f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 5 Feb 2015 20:38:43 -0500 Subject: [PATCH 084/164] dont crash if html is not string --- src/widgets.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/widgets.js b/src/widgets.js index 047befa8c2..c0234b2a28 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -44,6 +44,10 @@ var async = require('async'), return next(err); } + if (typeof html !== 'string') { + html = ''; + } + if (widget.data.container && widget.data.container.match('{body}')) { html = templates.parse(widget.data.container, { title: widget.data.title, From 9487f3a028843dd04310d4a790d763e93feadb35 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 5 Feb 2015 20:51:25 -0500 Subject: [PATCH 085/164] qs module changes categories param --- public/src/client/search.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/src/client/search.js b/public/src/client/search.js index e832e6f6c6..974d9f1ab0 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -19,8 +19,8 @@ define('forum/search', ['search'], function(searchModule) { $('#posted-by-user').val(params.by); } - if (params && params['categories[]']) { - $('#posted-in-categories').val(params['categories[]']); + if (params && (params['categories[]'] || params.categories)) { + $('#posted-in-categories').val((params['categories[]'] || params.categories)); } if (params && params.searchChildren) { From d65546a34dc88b6901cc70e1387c86fa599db04a Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 5 Feb 2015 21:08:52 -0500 Subject: [PATCH 086/164] search form fix --- public/src/client/search.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/src/client/search.js b/public/src/client/search.js index 974d9f1ab0..7350d0b068 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -13,6 +13,7 @@ define('forum/search', ['search'], function(searchModule) { var searchIn = $('#advanced-search #search-in'); if (params && params.in) { searchIn.val(params.in); + $('.post-search-item').toggleClass('hide', params.in !== 'posts'); } if (params && params.by) { @@ -20,7 +21,7 @@ define('forum/search', ['search'], function(searchModule) { } if (params && (params['categories[]'] || params.categories)) { - $('#posted-in-categories').val((params['categories[]'] || params.categories)); + $('#posted-in-categories').val(params['categories[]'] || params.categories); } if (params && params.searchChildren) { @@ -34,7 +35,6 @@ define('forum/search', ['search'], function(searchModule) { searchIn.on('change', function() { $('.post-search-item').toggleClass('hide', searchIn.val() !== 'posts'); - }); highlightMatches(searchQuery); From 92c869e8861d47bddc810480b94bd3e10a71aaa5 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 5 Feb 2015 23:18:53 -0500 Subject: [PATCH 087/164] try to get ip from x-forwarded-for first --- src/socket.io/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 9274f72222..8144fbc835 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -40,7 +40,7 @@ Sockets.init = function(server) { }; function onConnection(socket) { - socket.ip = socket.request.connection.remoteAddress; + socket.ip = socket.request.headers['x-forwarded-for'] || socket.request.connection.remoteAddress; logger.io_one(socket, socket.uid); From 652e247d1bc7b4ee12155c01267afa8de1f00c71 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 5 Feb 2015 23:21:31 -0500 Subject: [PATCH 088/164] fix username change event log --- src/user/profile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/profile.js b/src/user/profile.js index 461f1d9bb8..829c143505 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -100,7 +100,7 @@ module.exports = function(User) { return callback(err); } plugins.fireHook('action:user.updateProfile', {data: data, uid: uid}); - User.getUserFields(uid, ['email', 'userslug', 'picture', 'gravatarpicture'], callback); + User.getUserFields(uid, ['email', 'username', 'userslug', 'picture', 'gravatarpicture'], callback); }); }); From ba6af71150ad8c8192f144f85c688f2f67bd0019 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 5 Feb 2015 23:37:11 -0500 Subject: [PATCH 089/164] fix profile update --- src/socket.io/user.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/socket.io/user.js b/src/socket.io/user.js index d879813bae..b1e1512526 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -168,6 +168,7 @@ SocketUser.updateProfile = function(socket, data, callback) { newUsername: userData.username }); } + callback(null, userData); } if (socket.uid === parseInt(data.uid, 10)) { @@ -175,12 +176,8 @@ SocketUser.updateProfile = function(socket, data, callback) { } user.isAdministrator(socket.uid, function(err, isAdmin) { - if (err) { - return callback(err); - } - - if (!isAdmin) { - return callback(new Error('[[error:no-privileges]]')); + if (err || !isAdmin) { + return callback(err || new Error('[[error:no-privileges]]')); } user.updateProfile(data.uid, data, done); From 722b6295725e088309ad1c352e305b691290e92f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 6 Feb 2015 14:16:33 -0500 Subject: [PATCH 090/164] closes #2703 --- src/plugins/hooks.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/hooks.js b/src/plugins/hooks.js index 1d6c6f8e7b..00f6cc9f00 100644 --- a/src/plugins/hooks.js +++ b/src/plugins/hooks.js @@ -132,6 +132,7 @@ module.exports = function(Plugins) { }); } catch(err) { winston.error('[plugins] Error executing \'' + hook + '\' in plugin \'' + hookObj.id + '\''); + winston.error(err); clearTimeout(timeoutId); next(); } From 38dd3d428192e63ebb3202bef7c83fce0b2d8741 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 6 Feb 2015 19:47:27 -0500 Subject: [PATCH 091/164] search newer/older than and better pagination --- public/language/en_GB/search.json | 13 ++- public/src/client/search.js | 59 ++++++---- public/src/modules/search.js | 5 + src/controllers/categories.js | 3 +- src/controllers/search.js | 12 +- src/controllers/topics.js | 7 +- src/pagination.js | 13 +-- src/search.js | 175 +++++++++++++++++++++++++++--- src/user/search.js | 2 +- 9 files changed, 229 insertions(+), 60 deletions(-) diff --git a/public/language/en_GB/search.json b/public/language/en_GB/search.json index c68ead290b..4f099ef554 100644 --- a/public/language/en_GB/search.json +++ b/public/language/en_GB/search.json @@ -8,5 +8,16 @@ "search-child-categories": "Search child categories", "reply-count": "Reply Count", "at-least": "At least", - "at-most": "At most" + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year" } diff --git a/public/src/client/search.js b/public/src/client/search.js index 7350d0b068..029f7b811a 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -9,29 +9,10 @@ define('forum/search', ['search'], function(searchModule) { var searchQuery = $('#results').attr('data-search-query'); $('#advanced-search #search-input').val(searchQuery); - var params = utils.params(); - var searchIn = $('#advanced-search #search-in'); - if (params && params.in) { - searchIn.val(params.in); - $('.post-search-item').toggleClass('hide', params.in !== 'posts'); - } - - if (params && params.by) { - $('#posted-by-user').val(params.by); - } - - if (params && (params['categories[]'] || params.categories)) { - $('#posted-in-categories').val(params['categories[]'] || params.categories); - } - if (params && params.searchChildren) { - $('#search-children').prop('checked', true); - } + var searchIn = $('#advanced-search #search-in'); - if (params && params.replies) { - $('#reply-count').val(params.replies); - $('#reply-count-filter').val(params.repliesFilter); - } + fillOutFormFromQueryParams(); searchIn.on('change', function() { $('.post-search-item').toggleClass('hide', searchIn.val() !== 'posts'); @@ -50,7 +31,9 @@ define('forum/search', ['search'], function(searchModule) { categories: $(this).find('#posted-in-categories').val(), searchChildren: $(this).find('#search-children').is(':checked'), replies: $(this).find('#reply-count').val(), - repliesFilter: $(this).find('#reply-count-filter').val() + repliesFilter: $(this).find('#reply-count-filter').val(), + timeFilter: $(this).find('#post-time-filter').val(), + timeRange: $(this).find('#post-time-range').val() }, function() { input.val(''); }); @@ -59,6 +42,38 @@ define('forum/search', ['search'], function(searchModule) { enableAutoComplete(); }; + function fillOutFormFromQueryParams() { + var params = utils.params(); + if (params) { + if (params.in) { + $('#search-in').val(params.in); + $('.post-search-item').toggleClass('hide', params.in !== 'posts'); + } + + if (params.by) { + $('#posted-by-user').val(params.by); + } + + if ((params['categories[]'] || params.categories)) { + $('#posted-in-categories').val(params['categories[]'] || params.categories); + } + + if (params.searchChildren) { + $('#search-children').prop('checked', true); + } + + if (params.replies) { + $('#reply-count').val(params.replies); + $('#reply-count-filter').val(params.repliesFilter); + } + + if (params.timeRange) { + $('#post-time-range').val(params.timeRange); + $('#post-time-filter').val(params.timeFilter); + } + } + } + function highlightMatches(searchQuery) { var searchTerms = searchQuery.split(' '); var regexes = []; diff --git a/public/src/modules/search.js b/public/src/modules/search.js index b8f4eb6607..2b90ab290a 100644 --- a/public/src/modules/search.js +++ b/public/src/modules/search.js @@ -40,6 +40,11 @@ define('search', ['navigator'], function(nav) { query.repliesFilter = data.repliesFilter || 'atleast'; } + if (data.timeRange) { + query.timeRange = data.timeRange; + query.timeFilter = data.timeFilter || 'newer'; + } + ajaxify.go('search/' + term + '?' + decodeURIComponent($.param(query))); callback(); } else { diff --git a/src/controllers/categories.js b/src/controllers/categories.js index 1783fd69b3..25690a6810 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -260,8 +260,7 @@ categoriesController.get = function(req, res, next) { data.currentPage = page; data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; data['rssFeedUrl'] = nconf.get('relative_path') + '/category/' + data.cid + '.rss'; - - pagination.create(data.currentPage, data.pageCount, data); + data.pagination = pagination.create(data.currentPage, data.pageCount); data.pagination.rel.forEach(function(rel) { res.locals.linkTags.push(rel); diff --git a/src/controllers/search.js b/src/controllers/search.js index d21977b69d..2c0222a6b3 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -37,6 +37,7 @@ searchController.search = function(req, res, next) { } req.params.term = validator.escape(req.params.term); + var page = Math.max(1, parseInt(req.query.page, 10)) || 1; search.search({ query: req.params.term, @@ -46,18 +47,17 @@ searchController.search = function(req, res, next) { searchChildren: req.query.searchChildren, replies: req.query.replies, repliesFilter: req.query.repliesFilter, + timeRange: req.query.timeRange, + timeFilter: req.query.timeFilter, + page: page, uid: uid }, function(err, results) { if (err) { return next(err); } - var currentPage = Math.max(1, parseInt(req.query.page, 10)) || 1; - var pageCount = Math.max(1, Math.ceil(results.matchCount / 10)); - var searchIn = req.query.in || 'posts'; - var start = Math.max(0, (currentPage - 1)) * 10; - results[searchIn] = results[searchIn].slice(start, start + 10); - pagination.create(currentPage, pageCount, results, req.query); + var pageCount = Math.max(1, Math.ceil(results.matchCount / 10)); + results.pagination = pagination.create(page, pageCount, req.query); results.breadcrumbs = breadcrumbs; results.categories = categories; diff --git a/src/controllers/topics.js b/src/controllers/topics.js index ffcca5ab46..f470cfc6d1 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -256,15 +256,12 @@ topicsController.get = function(req, res, next) { data['downvote:disabled'] = parseInt(meta.config['downvote:disabled'], 10) === 1; data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; data['rssFeedUrl'] = nconf.get('relative_path') + '/topic/' + data.tid + '.rss'; - - topics.increaseViewCount(tid); - - pagination.create(data.currentPage, data.pageCount, data); - + data.pagination = pagination.create(data.currentPage, data.pageCount); data.pagination.rel.forEach(function(rel) { res.locals.linkTags.push(rel); }); + topics.increaseViewCount(tid); res.render('topic', data); }); }; diff --git a/src/pagination.js b/src/pagination.js index 9fadfceab4..d3a3ca9dd9 100644 --- a/src/pagination.js +++ b/src/pagination.js @@ -4,15 +4,14 @@ var qs = require('querystring'); var pagination = {}; -pagination.create = function(currentPage, pageCount, data, queryObj) { +pagination.create = function(currentPage, pageCount, queryObj) { if (pageCount <= 1) { - data.pagination = { + return { prev: {page: 1, active: currentPage > 1}, next: {page: 1, active: currentPage < pageCount}, rel: [], pages: [] }; - return; } var pagesToShow = [1]; @@ -43,7 +42,7 @@ pagination.create = function(currentPage, pageCount, data, queryObj) { return {page: page, active: page === currentPage, qs: qs.stringify(queryObj)}; }); - data.pagination = { + var data = { prev: {page: previous, active: currentPage > 1}, next: {page: next, active: currentPage < pageCount}, rel: [], @@ -51,19 +50,19 @@ pagination.create = function(currentPage, pageCount, data, queryObj) { }; if (currentPage < pageCount) { - data.pagination.rel.push({ + data.rel.push({ rel: 'next', href: '?page=' + next }); } if (currentPage > 1) { - data.pagination.rel.push({ + data.rel.push({ rel: 'prev', href: '?page=' + previous }); } - + return data; }; diff --git a/src/search.js b/src/search.js index 9f260cd7cc..86f39f6b52 100644 --- a/src/search.js +++ b/src/search.js @@ -1,6 +1,8 @@ 'use strict'; var async = require('async'), + + db = require('./database'), posts = require('./posts'), topics = require('./topics'), categories = require('./categories'), @@ -19,8 +21,8 @@ search.search = function(data, callback) { } result.search_query = query; - result[searchIn] = data; - result.matchCount = data.length; + result[searchIn] = data.matches; + result.matchCount = data.matchCount; result.hidePostedBy = searchIn !== 'posts'; result.time = (process.elapsedTimeSince(start) / 1000).toFixed(2); callback(null, result); @@ -65,8 +67,9 @@ function searchInPosts(query, data, callback) { return callback(err); } + var matchCount = 0; if (!results || (!results.pids.length && !results.tids.length)) { - return callback(null, []); + return callback(null, {matches: [], matchCount: matchCount}); } async.waterfall([ @@ -82,31 +85,162 @@ function searchInPosts(query, data, callback) { privileges.posts.filter('read', mainPids, data.uid, next); }, function(pids, next) { + filterAndSort(pids, data, results.searchCategories, next); + }, + function(pids, next) { + matchCount = pids.length; + if (data.page) { + var start = Math.max(0, (data.page - 1)) * 10; + pids = pids.slice(start, start + 10); + } + posts.getPostSummaryByPids(pids, data.uid, {stripTags: true, parse: false}, next); }, function(posts, next) { - posts = filterPosts(data, results.searchCategories, posts); - next(null, posts); + next(null, {matches: posts, matchCount: matchCount}); } ], callback); }); } -function filterPosts(data, searchCategories, posts) { - var postedBy = data.postedBy; - var isAtLeast = data.repliesFilter === 'atleast'; - data.replies = parseInt(data.replies, 10); - if (postedBy || searchCategories.length || data.replies) { +function filterAndSort(pids, data, searchCategories, callback) { + var postFields = ['pid', 'tid', 'timestamp']; + var topicFields = []; + + if (data.postedBy) { + postFields.push('uid'); + } + + if (searchCategories.length) { + topicFields.push('cid'); + } + + if (data.replies) { + topicFields.push('postcount'); + } + + async.parallel({ + posts: function(next) { + getMatchedPosts(pids, postFields, topicFields, next); + }, + postedByUid: function(next) { + if (data.postedBy) { + user.getUidByUsername(data.postedBy, next); + } else { + next(); + } + } + }, function(err, results) { + if (err) { + return callback(err); + } + if (!results.posts) { + return callback(null, pids); + } + var posts = results.posts.filter(Boolean); + + posts = filterByUser(posts, results.postedByUid); + posts = filterByCategories(posts, searchCategories); + posts = filterByPostcount(posts, data.replies, data.repliesFilter); + posts = filterByTimerange(posts, data.timeRange, data.timeFilter); + + sortPosts(posts, data); + + pids = posts.map(function(post) { + return post && post.pid; + }); + + callback(null, pids); + }); +} + +function getMatchedPosts(pids, postFields, topicFields, callback) { + var keys = pids.map(function(pid) { + return 'post:' + pid; + }); + var posts; + async.waterfall([ + function(next) { + db.getObjectsFields(keys, postFields, next); + }, + function(_posts, next) { + posts = _posts; + if (!topicFields.length) { + return callback(null, posts); + } + var topicKeys = posts.map(function(post) { + return 'topic:' + post.tid; + }); + db.getObjectsFields(topicKeys, topicFields, next); + }, + function(topics, next) { + posts.forEach(function(post, index) { + post.topic = topics[index]; + }); + + next(null, posts); + } + ], callback); +} + +function filterByUser(posts, postedByUid) { + if (postedByUid) { + postedByUid = parseInt(postedByUid, 10); + posts = posts.filter(function(post) { + return parseInt(post.uid, 10) === postedByUid; + }); + } + return posts; +} + +function filterByCategories(posts, searchCategories) { + if (searchCategories.length) { posts = posts.filter(function(post) { - return post && - (postedBy ? post.user && (post.user.username === postedBy) : true) && - (searchCategories.length ? (post.category && searchCategories.indexOf(post.category.cid) !== -1) : true) && - (data.replies ? (isAtLeast ? post.topic.postcount >= data.replies : post.topic.postcount <= data.replies) : true); + return post.topic && searchCategories.indexOf(post.topic.cid) !== -1; }); } return posts; } +function filterByPostcount(posts, postCount, repliesFilter) { + postCount = parseInt(postCount, 10); + if (postCount) { + if (repliesFilter === 'atleast') { + posts = posts.filter(function(post) { + return post.topic && post.topic.postcount >= postCount; + }); + } else { + posts = posts.filter(function(post) { + return post.topic && post.topic.postcount <= postCount; + }); + } + } + return posts; +} + +function filterByTimerange(posts, timeRange, timeFilter) { + timeRange = parseInt(timeRange) * 1000; + if (timeRange) { + var time = Date.now() - timeRange; + if (timeFilter === 'newer') { + posts = posts.filter(function(post) { + return post.timestamp >= time; + }); + } else { + posts = posts.filter(function(post) { + return post.timestamp <= time; + }); + } + } + return posts; +} + +function sortPosts(posts, data) { + posts.sort(function(p1, p2) { + return p2.timestamp - p1.timestamp; + }); +} + function getSearchCategories(data, callback) { if (!Array.isArray(data.categories) || !data.categories.length || data.categories.indexOf('all') !== -1) { return callback(null, []); @@ -159,12 +293,21 @@ function getChildrenCids(cids, uid, callback) { function searchInUsers(query, callback) { user.search({query: query}, function(err, results) { - callback(err, results ? results.users : null); + if (err) { + return callback(err); + } + callback(null, {matches: results.users, matchCount: results.matchCount}); }); } function searchInTags(query, callback) { - topics.searchAndLoadTags({query: query}, callback); + topics.searchAndLoadTags({query: query}, function(err, tags) { + if (err) { + return callback(err); + } + + callback(null, {matches: tags, matchCount: tags.length}); + }); } function getMainPids(tids, callback) { diff --git a/src/user/search.js b/src/user/search.js index 95130bf68f..ebfb08551f 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -60,7 +60,7 @@ module.exports = function(User) { var currentPage = Math.max(1, Math.ceil((start + 1) / resultsPerPage)); pageCount = Math.ceil(matchCount / resultsPerPage); - pagination.create(currentPage, pageCount, data); + data.pagination = pagination.create(currentPage, pageCount); next(null, data); } From ff5eeb3a853e5e6b10280e33de4268f0a39ba35c Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 6 Feb 2015 20:42:20 -0500 Subject: [PATCH 092/164] fixed #2704 --- src/controllers/groups.js | 42 ++++++++++++++++++++++----------------- src/groups.js | 4 ++++ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/controllers/groups.js b/src/controllers/groups.js index c5d430b28d..de8af88e07 100644 --- a/src/controllers/groups.js +++ b/src/controllers/groups.js @@ -27,26 +27,32 @@ groupsController.list = function(req, res, next) { groupsController.details = function(req, res, next) { var uid = req.user ? parseInt(req.user.uid, 10) : 0; - async.parallel({ - group: function(next) { - groups.getByGroupslug(req.params.slug, { - expand: true, - uid: uid - }, next); - }, - posts: function(next) { - groups.getLatestMemberPosts(req.params.slug, 10, uid, next); - } - }, function(err, results) { - if (err) { - return next(err); - } + groups.existsBySlug(req.params.slug, function(err, exists) { + if (exists) { + async.parallel({ + group: function(next) { + groups.getByGroupslug(req.params.slug, { + expand: true, + uid: uid + }, next); + }, + posts: function(next) { + groups.getLatestMemberPosts(req.params.slug, 10, uid, next); + } + }, function(err, results) { + if (err) { + return next(err); + } - if (!results.group) { - return helpers.notFound(req, res); - } + if (!results.group) { + return helpers.notFound(req, res); + } - res.render('groups/details', results); + res.render('groups/details', results); + }); + } else { + return res.locals.isAPI ? res.status(302).json('/groups') : res.redirect('/groups'); + } }); }; diff --git a/src/groups.js b/src/groups.js index 38c8704813..54b1332a4b 100644 --- a/src/groups.js +++ b/src/groups.js @@ -422,6 +422,10 @@ var async = require('async'), } }; + Groups.existsBySlug = function(slug, callback) { + db.isObjectField('groupslug:groupname', slug, callback); + }; + Groups.create = function(data, callback) { if (data.name.length === 0) { return callback(new Error('[[error:group-name-too-short]]')); From c85958626990ab0e1cf9795e9697f9ef7d63df55 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 00:12:47 -0500 Subject: [PATCH 093/164] calculate topic post indices instead of querying db --- src/controllers/topics.js | 8 +++----- src/topics.js | 30 ++++++++++-------------------- src/topics/posts.js | 36 +++++++++++++++++++++++++++++------- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/controllers/topics.js b/src/controllers/topics.js index f470cfc6d1..83d873b583 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -116,15 +116,13 @@ topicsController.get = function(req, res, next) { } topicData.pageCount = pageCount; - topicData.currentPage = page; - if(page > 1) { + + if (page > 1) { topicData.posts.splice(0, 1); } - plugins.fireHook('filter:controllers.topic.get', topicData, function(err, topicData) { - next(null, topicData); - }); + plugins.fireHook('filter:controllers.topic.get', topicData, next); }); }, function (topicData, next) { diff --git a/src/topics.js b/src/topics.js index 1e9df9958f..692088ec52 100644 --- a/src/topics.js +++ b/src/topics.js @@ -215,25 +215,11 @@ var async = require('async'), } async.parallel({ + mainPost: function(next) { + Topics.getMainPost(tid, uid, next); + }, posts: function(next) { - posts.getPidsFromSet(set, start, end, reverse, function(err, pids) { - if (err) { - return next(err); - } - - pids = topicData.mainPid ? [topicData.mainPid].concat(pids) : pids; - - if (!pids.length) { - return next(null, []); - } - posts.getPostsByPids(pids, uid, function(err, posts) { - if (err) { - return next(err); - } - - Topics.addPostData(posts, uid, next); - }); - }); + Topics.getTopicPosts(tid, set, start, end, uid, reverse, next); }, category: async.apply(Topics.getCategoryData, tid), threadTools: async.apply(plugins.fireHook, 'filter:topic.thread_tools', []), @@ -244,7 +230,7 @@ var async = require('async'), return callback(err); } - topicData.posts = results.posts; + topicData.posts = results.mainPost ? [results.mainPost].concat(results.posts) : results.posts; topicData.category = results.category; topicData.thread_tools = results.threadTools; topicData.tags = results.tags; @@ -280,7 +266,11 @@ var async = require('async'), if (err) { return callback(err); } - + postData.forEach(function(post) { + if (post) { + post.index = 0; + } + }); Topics.addPostData(postData, uid, callback); }); }); diff --git a/src/topics/posts.js b/src/topics/posts.js index d4809f2a79..6d4cd9be8f 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -29,15 +29,28 @@ module.exports = function(Topics) { ], callback); }; - Topics.getTopicPosts = function(tid, set, start, end, uid, reverse, callback) { callback = callback || function() {}; - posts.getPostsByTid(tid, set, start, end, uid, reverse, function(err, postData) { + async.parallel({ + posts: function(next) { + posts.getPostsByTid(tid, set, start, end, uid, reverse, next); + }, + postCount: function(next) { + Topics.getTopicField(tid, 'postcount', next); + } + }, function(err, results) { if (err) { return callback(err); } - Topics.addPostData(postData, uid, callback); + var indices = Topics.calculatePostIndices(start, end, results.postCount, reverse); + results.posts.forEach(function(post, index) { + if (post) { + post.index = indices[index]; + } + }); + + Topics.addPostData(results.posts, uid, callback); }); }; @@ -103,9 +116,6 @@ module.exports = function(Topics) { }, privileges: function(next) { privileges.posts.get(pids, uid, next); - }, - indices: function(next) { - posts.getPostIndices(postData, uid, next); } }, function(err, results) { if (err) { @@ -114,7 +124,6 @@ module.exports = function(Topics) { postData.forEach(function(postObj, i) { if (postObj) { - postObj.index = results.indices[i]; postObj.deleted = parseInt(postObj.deleted, 10) === 1; postObj.user = parseInt(postObj.uid, 10) ? results.userData[postObj.uid] : _.clone(results.userData[postObj.uid]); postObj.editor = postObj.editor ? results.editors[postObj.editor] : null; @@ -141,6 +150,19 @@ module.exports = function(Topics) { }); }; + Topics.calculatePostIndices = function(start, end, postCount, reverse) { + var indices = []; + var count = end - start + 1; + for(var i=0; i Date: Sat, 7 Feb 2015 00:19:22 -0500 Subject: [PATCH 094/164] pass on mainPid --- src/topics.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/topics.js b/src/topics.js index 692088ec52..a0aeed33db 100644 --- a/src/topics.js +++ b/src/topics.js @@ -216,7 +216,7 @@ var async = require('async'), async.parallel({ mainPost: function(next) { - Topics.getMainPost(tid, uid, next); + getMainPosts([topicData.mainPid], uid, next); }, posts: function(next) { Topics.getTopicPosts(tid, set, start, end, uid, reverse, next); @@ -230,7 +230,7 @@ var async = require('async'), return callback(err); } - topicData.posts = results.mainPost ? [results.mainPost].concat(results.posts) : results.posts; + topicData.posts = Array.isArray(results.mainPost) && results.mainPost.length ? [results.mainPost[0]].concat(results.posts) : results.posts; topicData.category = results.category; topicData.thread_tools = results.threadTools; topicData.tags = results.tags; @@ -262,19 +262,23 @@ var async = require('async'), return topic ? topic.mainPid : null; }); - posts.getPostsByPids(mainPids, uid, function(err, postData) { - if (err) { - return callback(err); + getMainPosts(mainPids, uid, callback); + }); + }; + + function getMainPosts(mainPids, uid, callback) { + posts.getPostsByPids(mainPids, uid, function(err, postData) { + if (err) { + return callback(err); + } + postData.forEach(function(post) { + if (post) { + post.index = 0; } - postData.forEach(function(post) { - if (post) { - post.index = 0; - } - }); - Topics.addPostData(postData, uid, callback); }); + Topics.addPostData(postData, uid, callback); }); - }; + } Topics.getTopicField = function(tid, field, callback) { db.getObjectField('topic:' + tid, field, callback); From 8bbd7d971b83371c1d61d7e9f47c1a4b41c99f7c Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 00:52:53 -0500 Subject: [PATCH 095/164] fix index to post if sorting is by votes and pagination is used --- src/controllers/topics.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/controllers/topics.js b/src/controllers/topics.js index 83d873b583..498a3d81db 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -89,17 +89,23 @@ topicsController.get = function(req, res, next) { var postIndex = 0; page = parseInt(req.query.page, 10) || 1; req.params.post_index = parseInt(req.params.post_index, 10) || 0; + if (reverse && req.params.post_index === 1) { + req.params.post_index = 0; + } if (!settings.usePagination) { if (reverse) { - if (req.params.post_index === 1) { - req.params.post_index = 0; - } - postIndex = Math.max(postCount - (req.params.post_index || postCount) - (settings.postsPerPage - 1), 0); + postIndex = Math.max(0, postCount - (req.params.post_index || postCount) - (settings.postsPerPage - 1)); } else { - postIndex = Math.max((req.params.post_index || 1) - (settings.postsPerPage + 1), 0); + postIndex = Math.max(0, (req.params.post_index || 1) - (settings.postsPerPage + 1)); } } else if (!req.query.page) { - var index = Math.max(req.params.post_index - 1, 0) || 0; + var index = 0; + if (reverse) { + index = Math.max(0, postCount - (req.params.post_index || postCount)); + } else { + index = Math.max(0, req.params.post_index - 1) || 0; + } + page = Math.max(1, Math.ceil(index / settings.postsPerPage)); } From eff1256dfbde2e2721766e661fe386593e87928a Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 20:00:07 -0500 Subject: [PATCH 096/164] search sort, search in posts, titles, posts& titles --- public/language/en_GB/search.json | 15 +- public/src/app.js | 2 +- public/src/client/search.js | 41 +++-- public/src/modules/search.js | 58 ++++--- src/controllers/search.js | 3 +- src/search.js | 244 +++++++++++++++++++++++++----- 6 files changed, 286 insertions(+), 77 deletions(-) diff --git a/public/language/en_GB/search.json b/public/language/en_GB/search.json index 4f099ef554..b8a970d6a9 100644 --- a/public/language/en_GB/search.json +++ b/public/language/en_GB/search.json @@ -3,6 +3,8 @@ "no-matches": "No matches found", "in": "In", "by": "By", + "titles": "Titles", + "titles-posts": "Titles and Posts", "posted-by": "Posted by", "in-categories": "In Categories", "search-child-categories": "Search child categories", @@ -19,5 +21,16 @@ "one-month": "One month", "three-months": "Three months", "six-months": "Six months", - "one-year": "One year" + "one-year": "One year", + "sort-by": "Sort by", + "post-time": "Post time", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } diff --git a/public/src/app.js b/public/src/app.js index 35037c8033..1e5b92cf4d 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -436,7 +436,7 @@ app.uid = null; e.preventDefault(); var input = $(this).find('input'); - search.query({term: input.val(), in: 'posts'}, function() { + search.query({term: input.val()}, function() { input.val(''); }); }); diff --git a/public/src/client/search.js b/public/src/client/search.js index 029f7b811a..691ab51281 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -15,26 +15,31 @@ define('forum/search', ['search'], function(searchModule) { fillOutFormFromQueryParams(); searchIn.on('change', function() { - $('.post-search-item').toggleClass('hide', searchIn.val() !== 'posts'); + updateFormItemVisiblity(searchIn.val()); }); highlightMatches(searchQuery); $('#advanced-search').off('submit').on('submit', function(e) { e.preventDefault(); - var input = $(this).find('#search-input'); + var $this = $(this) + var input = $this.find('#search-input'); - searchModule.query({ + var searchData = { term: input.val(), - in: $(this).find('#search-in').val(), - by: $(this).find('#posted-by-user').val(), - categories: $(this).find('#posted-in-categories').val(), - searchChildren: $(this).find('#search-children').is(':checked'), - replies: $(this).find('#reply-count').val(), - repliesFilter: $(this).find('#reply-count-filter').val(), - timeFilter: $(this).find('#post-time-filter').val(), - timeRange: $(this).find('#post-time-range').val() - }, function() { + in: $this.find('#search-in').val(), + by: $this.find('#posted-by-user').val(), + categories: $this.find('#posted-in-categories').val(), + searchChildren: $this.find('#search-children').is(':checked'), + replies: $this.find('#reply-count').val(), + repliesFilter: $this.find('#reply-count-filter').val(), + timeFilter: $this.find('#post-time-filter').val(), + timeRange: $this.find('#post-time-range').val(), + sortBy: $this.find('#post-sort-by').val(), + sortDirection: $this.find('#post-sort-direction').val() + }; + + searchModule.query(searchData, function() { input.val(''); }); }); @@ -42,12 +47,17 @@ define('forum/search', ['search'], function(searchModule) { enableAutoComplete(); }; + function updateFormItemVisiblity(searchIn) { + var hide = searchIn.indexOf('posts') === -1 && searchIn.indexOf('titles') === -1; + $('.post-search-item').toggleClass('hide', hide); + } + function fillOutFormFromQueryParams() { var params = utils.params(); if (params) { if (params.in) { $('#search-in').val(params.in); - $('.post-search-item').toggleClass('hide', params.in !== 'posts'); + updateFormItemVisiblity(params.in); } if (params.by) { @@ -71,6 +81,11 @@ define('forum/search', ['search'], function(searchModule) { $('#post-time-range').val(params.timeRange); $('#post-time-filter').val(params.timeFilter); } + + if (params.sortBy) { + $('#post-sort-by').val(params.sortBy); + $('#post-sort-direction').val(params.sortDirection); + } } } diff --git a/public/src/modules/search.js b/public/src/modules/search.js index 2b90ab290a..9b896b0394 100644 --- a/public/src/modules/search.js +++ b/public/src/modules/search.js @@ -9,8 +9,6 @@ define('search', ['navigator'], function(nav) { Search.query = function(data, callback) { var term = data.term; - var searchIn = data.in || 'posts'; - var postedBy = data.by || ''; // Detect if a tid was specified var topicSearch = term.match(/in:topic-([\d]+)/); @@ -23,29 +21,8 @@ define('search', ['navigator'], function(nav) { } catch(e) { return app.alertError('[[error:invalid-search-term]]'); } - var query = {in: searchIn}; - if (postedBy && searchIn === 'posts') { - query.by = postedBy; - } - - if (data.categories && data.categories.length) { - query.categories = data.categories; - if (data.searchChildren) { - query.searchChildren = data.searchChildren; - } - } - - if (parseInt(data.replies, 10) > 0) { - query.replies = data.replies; - query.repliesFilter = data.repliesFilter || 'atleast'; - } - if (data.timeRange) { - query.timeRange = data.timeRange; - query.timeFilter = data.timeFilter || 'newer'; - } - - ajaxify.go('search/' + term + '?' + decodeURIComponent($.param(query))); + ajaxify.go('search/' + term + '?' + createQueryString(data)); callback(); } else { var cleanedTerm = term.replace(topicSearch[0], ''), @@ -55,6 +32,39 @@ define('search', ['navigator'], function(nav) { } }; + function createQueryString(data) { + var searchIn = data.in || 'titlesposts'; + var postedBy = data.by || ''; + var query = {in: searchIn}; + + if (postedBy && (searchIn === 'posts' || searchIn === 'titles' || searchIn === 'titlesposts')) { + query.by = postedBy; + } + + if (data.categories && data.categories.length) { + query.categories = data.categories; + if (data.searchChildren) { + query.searchChildren = data.searchChildren; + } + } + + if (parseInt(data.replies, 10) > 0) { + query.replies = data.replies; + query.repliesFilter = data.repliesFilter || 'atleast'; + } + + if (data.timeRange) { + query.timeRange = data.timeRange; + query.timeFilter = data.timeFilter || 'newer'; + } + + if (data.sortBy) { + query.sortBy = data.sortBy; + query.sortDirection = data.sortDirection; + } + return decodeURIComponent($.param(query)); + } + Search.queryTopic = function(tid, term, callback) { socket.emit('topics.search', { tid: tid, diff --git a/src/controllers/search.js b/src/controllers/search.js index 2c0222a6b3..f5f93f6874 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -28,7 +28,6 @@ searchController.search = function(req, res, next) { time: 0, search_query: '', posts: [], - topics: [], users: [], tags: [], categories: categories, @@ -49,6 +48,8 @@ searchController.search = function(req, res, next) { repliesFilter: req.query.repliesFilter, timeRange: req.query.timeRange, timeFilter: req.query.timeFilter, + sortBy: req.query.sortBy, + sortDirection: req.query.sortDirection, page: page, uid: uid }, function(err, results) { diff --git a/src/search.js b/src/search.js index b8f8ffa849..6e70cfa1bc 100644 --- a/src/search.js +++ b/src/search.js @@ -8,7 +8,8 @@ var async = require('async'), categories = require('./categories'), user = require('./user'), plugins = require('./plugins'), - privileges = require('./privileges'); + privileges = require('./privileges'), + utils = require('../public/src/utils'); var search = {}; @@ -21,6 +22,9 @@ search.search = function(data, callback) { } result.search_query = query; + if (searchIn === 'titles' || searchIn === 'titlesposts') { + searchIn = 'posts'; + } result[searchIn] = data.matches; result.matchCount = data.matchCount; result.hidePostedBy = searchIn !== 'posts'; @@ -31,7 +35,7 @@ search.search = function(data, callback) { var start = process.hrtime(); var query = data.query; - var searchIn = data.searchIn || 'posts'; + var searchIn = data.searchIn || 'titlesposts'; var result = { posts: [], @@ -39,8 +43,8 @@ search.search = function(data, callback) { tags: [] }; - if (searchIn === 'posts') { - searchInPosts(query, data, done); + if (searchIn === 'posts' || searchIn === 'titles' || searchIn === 'titlesposts') { + searchInContent(query, data, done); } else if (searchIn === 'users') { searchInUsers(query, data.uid, done); } else if (searchIn === 'tags') { @@ -50,14 +54,22 @@ search.search = function(data, callback) { } }; -function searchInPosts(query, data, callback) { +function searchInContent(query, data, callback) { data.uid = data.uid || 0; async.parallel({ pids: function(next) { - searchQuery('post', query, next); + if (data.searchIn === 'posts' || data.searchIn === 'titlesposts') { + searchQuery('post', query, next); + } else { + next(null, []); + } }, tids: function(next) { - searchQuery('topic', query, next); + if (data.searchIn === 'titles' || data.searchIn === 'titlesposts') { + searchQuery('topic', query, next); + } else { + next(null, []); + } }, searchCategories: function(next) { getSearchCategories(data, next); @@ -104,24 +116,9 @@ function searchInPosts(query, data, callback) { } function filterAndSort(pids, data, searchCategories, callback) { - var postFields = ['pid', 'tid', 'timestamp']; - var topicFields = []; - - if (data.postedBy) { - postFields.push('uid'); - } - - if (searchCategories.length) { - topicFields.push('cid'); - } - - if (data.replies) { - topicFields.push('postcount'); - } - async.parallel({ posts: function(next) { - getMatchedPosts(pids, postFields, topicFields, next); + getMatchedPosts(pids, data, searchCategories, next); }, postedByUid: function(next) { if (data.postedBy) { @@ -154,28 +151,130 @@ function filterAndSort(pids, data, searchCategories, callback) { }); } -function getMatchedPosts(pids, postFields, topicFields, callback) { - var keys = pids.map(function(pid) { - return 'post:' + pid; - }); +function getMatchedPosts(pids, data, searchCategories, callback) { + var postFields = ['pid', 'tid', 'timestamp']; + var topicFields = []; + var categoryFields = []; + + if (data.postedBy) { + postFields.push('uid'); + } + + if (searchCategories.length || (data.sortBy && data.sortBy.startsWith('category.'))) { + topicFields.push('cid'); + } + + if (data.replies) { + topicFields.push('postcount'); + } + + if (data.sortBy) { + if (data.sortBy.startsWith('topic.')) { + topicFields.push(data.sortBy.split('.')[1]); + } else if (data.sortBy.startsWith('user.')) { + postFields.push('uid'); + } else if (data.sortBy.startsWith('category.')) { + categoryFields.push(data.sortBy.split('.')[1]); + } else if (data.sortBy.startsWith('teaser')) { + topicFields.push('teaserPid'); + } + } + var posts; async.waterfall([ function(next) { + var keys = pids.map(function(pid) { + return 'post:' + pid; + }); db.getObjectsFields(keys, postFields, next); }, function(_posts, next) { posts = _posts; - if (!topicFields.length) { - return callback(null, posts); - } - var topicKeys = posts.map(function(post) { - return 'topic:' + post.tid; - }); - db.getObjectsFields(topicKeys, topicFields, next); + + async.parallel({ + users: function(next) { + if (data.sortBy && data.sortBy.startsWith('user')) { + var uids = posts.map(function(post) { + return post.uid; + }); + user.getMultipleUserFields(uids, ['username'], next); + } else { + next(); + } + }, + topics: function(next) { + if (!topicFields.length) { + return next(); + } + + var topics; + async.waterfall([ + function(next) { + var topicKeys = posts.map(function(post) { + return 'topic:' + post.tid; + }); + db.getObjectsFields(topicKeys, topicFields, next); + }, + function(_topics, next) { + topics = _topics; + + async.parallel({ + teasers: function(next) { + if (topicFields.indexOf('teaserPid') !== -1) { + var teaserKeys = topics.map(function(topic) { + return 'post:' + topic.teaserPid; + }); + db.getObjectsFields(teaserKeys, ['timestamp'], next); + } else { + next(); + } + }, + categories: function(next) { + if (!categoryFields.length) { + return next(); + } + var cids = topics.map(function(topic) { + return 'category:' + topic.cid; + }); + db.getObjectsFields(cids, categoryFields, next); + } + }, next); + } + ], function(err, results) { + if (err) { + return next(err); + } + + topics.forEach(function(topic, index) { + if (topic && results.categories && results.categories[index]) { + topic.category = results.categories[index]; + } + if (topic && results.teasers && results.teasers[index]) { + topic.teaser = results.teasers[index]; + } + }); + + next(null, topics); + }); + } + }, next); }, - function(topics, next) { + function(results, next) { + posts.forEach(function(post, index) { - post.topic = topics[index]; + if (results.topics && results.topics[index]) { + post.topic = results.topics[index]; + if (results.topics[index].category) { + post.category = results.topics[index].category; + } + if (results.topics[index].teaser) { + post.teaser = results.topics[index].teaser; + } + } + + if (results.users && results.users[index]) { + post.user = results.users[index]; + } }); next(null, posts); @@ -236,8 +335,75 @@ function filterByTimerange(posts, timeRange, timeFilter) { } function sortPosts(posts, data) { + if (!posts.length) { + return; + } + data.sortBy = data.sortBy || 'timestamp'; + data.sortDirection = data.sortDirection || 'desc'; + if (data.sortBy === 'timestamp') { + if (data.sortDirection === 'desc') { + posts.sort(function(p1, p2) { + return p2.timestamp - p1.timestamp; + }); + } else { + posts.sort(function(p1, p2) { + return p1.timestamp - p2.timestamp; + }); + } + + return; + } + + var firstPost = posts[0]; + var fields = data.sortBy.split('.'); + + if (!fields || fields.length !== 2 || !firstPost[fields[0]] || !firstPost[fields[0]][fields[1]]) { + return; + } + + var value = firstPost[fields[0]][fields[1]]; + var isNumeric = utils.isNumber(value); + + if (isNumeric) { + if (data.sortDirection === 'desc') { + sortDescendingNumeric(posts, fields); + } else { + sortAscendingNumeric(posts, fields); + } + } else { + if (data.sortDirection === 'desc') { + sortDescendingAlpha(posts, fields); + } else { + sortAscendingAlpha(posts, fields); + } + } +} + +function sortAscendingNumeric(posts, fields) { + posts.sort(function(p1, p2) { + return p1[fields[0]][fields[1]] - p2[fields[0]][fields[1]]; + }); +} + +function sortDescendingNumeric(posts, fields) { posts.sort(function(p1, p2) { - return p2.timestamp - p1.timestamp; + return p2[fields[0]][fields[1]] - p1[fields[0]][fields[1]]; + }); +} + +function sortAscendingAlpha(posts, fields) { + posts.sort(function(p1, p2) { + if (p1[fields[0]][fields[1]] > p2[fields[0]][fields[1]]) return -1; + if (p1[fields[0]][fields[1]] < p2[fields[0]][fields[1]]) return 1; + return 0; + }); +} + +function sortDescendingAlpha(posts, fields) { + posts.sort(function(p1, p2) { + if (p1[fields[0]][fields[1]] < p2[fields[0]][fields[1]]) return -1; + if (p1[fields[0]][fields[1]] > p2[fields[0]][fields[1]]) return 1; + return 0; }); } @@ -311,6 +477,10 @@ function searchInTags(query, callback) { } function getMainPids(tids, callback) { + if (!Array.isArray(tids) || !tids.length) { + return callback(null, []); + } + topics.getTopicsFields(tids, ['mainPid'], function(err, topics) { if (err) { return callback(err); From 4d342410728a305a77607b71009f7f94774eaab0 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 20:02:21 -0500 Subject: [PATCH 097/164] missing semicolon --- public/src/client/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/client/search.js b/public/src/client/search.js index 691ab51281..c1761b20cd 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -22,7 +22,7 @@ define('forum/search', ['search'], function(searchModule) { $('#advanced-search').off('submit').on('submit', function(e) { e.preventDefault(); - var $this = $(this) + var $this = $(this); var input = $this.find('#search-input'); var searchData = { From d96e4ec22af83638a663abe7aeaf4ec8c3d6f014 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 20:30:03 -0500 Subject: [PATCH 098/164] fix category filter and pagination, strip marquee --- public/src/utils.js | 10 +++++++++- src/controllers/search.js | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/public/src/utils.js b/public/src/utils.js index b58984a20e..3b82573c9b 100644 --- a/public/src/utils.js +++ b/public/src/utils.js @@ -204,7 +204,15 @@ tags : ['a', 'abbr', 'acronym', 'address', 'applet', 'area', 'article', 'aside', 'audio', 'b', 'base', 'basefont', 'bdi', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'map', 'mark', 'menu', 'meta', 'meter', 'nav', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr'], - stripTags : ['abbr', 'acronym', 'address', 'applet', 'area', 'article', 'aside', 'audio', 'base', 'basefont', 'bdi', 'bdo', 'big', 'body', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hr', 'html', 'iframe', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'map', 'mark', 'menu', 'meta', 'meter', 'nav', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'param', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'section', 'select', 'source', 'span', 'strike', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr'], + stripTags : ['abbr', 'acronym', 'address', 'applet', 'area', 'article', 'aside', 'audio', 'base', 'basefont', + 'bdi', 'bdo', 'big', 'blink', 'body', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', + 'command', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'embed', + 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'head', 'header', 'hr', 'html', 'iframe', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', + 'map', 'mark', 'marquee', 'menu', 'meta', 'meter', 'nav', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', + 'output', 'param', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'section', 'select', + 'source', 'span', 'strike', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', + 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr'], escapeRegexChars: function(text) { return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); diff --git a/src/controllers/search.js b/src/controllers/search.js index f5f93f6874..d9e6bc9f3a 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -37,6 +37,9 @@ searchController.search = function(req, res, next) { req.params.term = validator.escape(req.params.term); var page = Math.max(1, parseInt(req.query.page, 10)) || 1; + if (req.query.categories && !Array.isArray(req.query.categories)) { + req.query.categories = [req.query.categories]; + } search.search({ query: req.params.term, From 5cc728994b0cc300dbcd39b0fb45f4f10371c9b4 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 20:55:57 -0500 Subject: [PATCH 099/164] dont need hidePostedBy --- src/search.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/search.js b/src/search.js index 6e70cfa1bc..e26cb75f70 100644 --- a/src/search.js +++ b/src/search.js @@ -27,7 +27,6 @@ search.search = function(data, callback) { } result[searchIn] = data.matches; result.matchCount = data.matchCount; - result.hidePostedBy = searchIn !== 'posts'; result.time = (process.elapsedTimeSince(start) / 1000).toFixed(2); callback(null, result); } From 4d63a7c0206e9459734c699e1b7b0e4f9904d00c Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 23:00:58 -0500 Subject: [PATCH 100/164] closes ##2705 --- src/topics.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/topics.js b/src/topics.js index 8ad164df1f..a9514dabba 100644 --- a/src/topics.js +++ b/src/topics.js @@ -222,7 +222,7 @@ var async = require('async'), Topics.getTopicPosts(tid, set, start, end, uid, reverse, next); }, category: async.apply(Topics.getCategoryData, tid), - threadTools: async.apply(plugins.fireHook, 'filter:topic.thread_tools', []), + threadTools: async.apply(plugins.fireHook, 'filter:topic.thread_tools', {topic: topicData, uid: uid, tools: []}), tags: async.apply(Topics.getTopicTagsObjects, tid), isFollowing: async.apply(Topics.isFollowing, [tid], uid) }, function(err, results) { @@ -232,7 +232,7 @@ var async = require('async'), topicData.posts = Array.isArray(results.mainPost) && results.mainPost.length ? [results.mainPost[0]].concat(results.posts) : results.posts; topicData.category = results.category; - topicData.thread_tools = results.threadTools; + topicData.thread_tools = results.threadTools.tools; topicData.tags = results.tags; topicData.isFollowing = results.isFollowing[0]; From 138a13f1b25060d7b3fbc1cd20a6f2d3e8cab7c6 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 23:10:54 -0500 Subject: [PATCH 101/164] dont crash if searchQuery is falsy --- public/src/client/search.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/src/client/search.js b/public/src/client/search.js index c1761b20cd..42bf7dd4fe 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -90,6 +90,9 @@ define('forum/search', ['search'], function(searchModule) { } function highlightMatches(searchQuery) { + if (!searchQuery) { + return; + } var searchTerms = searchQuery.split(' '); var regexes = []; for (var i=0; i Date: Sat, 7 Feb 2015 23:32:42 -0500 Subject: [PATCH 102/164] show seconds like search page --- public/language/en_GB/users.json | 2 +- src/notifications.js | 10 ---------- src/user/search.js | 5 +---- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/public/language/en_GB/users.json b/public/language/en_GB/users.json index 683ad7e155..0f3687c9ed 100644 --- a/public/language/en_GB/users.json +++ b/public/language/en_GB/users.json @@ -5,7 +5,7 @@ "search": "Search", "enter_username": "Enter a username to search", "load_more": "Load More", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/src/notifications.js b/src/notifications.js index 96502508f7..5d10686212 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -270,12 +270,6 @@ var async = require('async'), }; Notifications.prune = function() { - var start = process.hrtime(); - - if (process.env.NODE_ENV === 'development') { - winston.info('[notifications.prune] Removing expired notifications from the database.'); - } - var week = 604800000, numPruned = 0; @@ -307,10 +301,6 @@ var async = require('async'), if (err) { return winston.error('Encountered error pruning notifications: ' + err.message); } - - if (process.env.NODE_ENV === 'development') { - winston.info('[notifications.prune] Notification pruning completed. ' + numPruned + ' expired notification' + (numPruned !== 1 ? 's' : '') + ' removed.'); - } }); }); }; diff --git a/src/user/search.js b/src/user/search.js index a593258f11..20bbec2258 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -46,11 +46,8 @@ module.exports = function(User) { User.getUsers(uids, uid, next); }, function(userData, next) { - - var diff = process.hrtime(startTime); - var timing = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(1); var data = { - timing: timing, + timing: (process.elapsedTimeSince(startTime) / 1000).toFixed(2), users: userData, matchCount: matchCount }; From 10928ed11b9eb431da72987f484fe2b0db7d946e Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 7 Feb 2015 23:51:25 -0500 Subject: [PATCH 103/164] escape post content --- src/posts/summary.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/posts/summary.js b/src/posts/summary.js index dd537ce8d6..962a51aaa6 100644 --- a/src/posts/summary.js +++ b/src/posts/summary.js @@ -82,6 +82,7 @@ module.exports = function(Posts) { if (options.stripTags) { post.content = stripTags(post.content); } + post.content = post.content ? validator.escape(post.content) : post.content; return next(null, post); } From 7f6518e4a60797e2747ac0aaff520177e845ace4 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 8 Feb 2015 13:38:42 -0500 Subject: [PATCH 104/164] private plugin link fix --- public/src/client/account/header.js | 12 ++++++++---- src/middleware/middleware.js | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index f0a0c112fa..6dcc0b27e4 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -1,3 +1,6 @@ +'use strict'; +/* globals define, app, ajaxify */ + define('forum/account/header', function() { var AccountHeader = {}; @@ -7,10 +10,11 @@ define('forum/account/header', function() { }; function displayAccountMenus() { - $('.account-sub-links .plugin-link').each(function() { - var $this = $(this); - $this.toggleClass('hide', $this.hasClass('private')); - }); + if (!app.user.uid || app.user.uid !== parseInt(ajaxify.variables.get('theirid'), 10)) { + $('.account-sub-links .plugin-link.private').each(function() { + $(this).addClass('hide'); + }); + } } function selectActivePill() { diff --git a/src/middleware/middleware.js b/src/middleware/middleware.js index 111b0b1ceb..f95c70e3ac 100644 --- a/src/middleware/middleware.js +++ b/src/middleware/middleware.js @@ -340,6 +340,7 @@ middleware.renderHeader = function(req, res, callback) { return; } results.user.isAdmin = results.isAdmin || false; + results.user.uid = parseInt(results.user.uid, 10); results.user['email:confirmed'] = parseInt(results.user['email:confirmed'], 10) === 1; templateValues.browserTitle = results.title; From 1843d0364e586eae05bd1ea8723175d1b6eda3e8 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 8 Feb 2015 21:06:38 -0500 Subject: [PATCH 105/164] closed #2708 --- public/language/en_GB/email.json | 4 ++ public/language/en_GB/reset_password.json | 4 +- public/src/client/reset_code.js | 47 +++++++++------------ src/controllers/index.js | 9 ++-- src/socket.io/user.js | 27 +++++++++--- src/upgrade.js | 22 +++++++++- src/user/reset.js | 17 +++----- src/views/emails/reset_notify.tpl | 10 +++++ src/views/emails/reset_notify_plaintext.tpl | 8 ++++ 9 files changed, 98 insertions(+), 50 deletions(-) create mode 100644 src/views/emails/reset_notify.tpl create mode 100644 src/views/emails/reset_notify_plaintext.tpl diff --git a/public/language/en_GB/email.json b/public/language/en_GB/email.json index efee400748..33fd28377b 100644 --- a/public/language/en_GB/email.json +++ b/public/language/en_GB/email.json @@ -13,6 +13,10 @@ "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", + "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/en_GB/reset_password.json b/public/language/en_GB/reset_password.json index 27537ffdf2..96ba318a8a 100644 --- a/public/language/en_GB/reset_password.json +++ b/public/language/en_GB/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Please enter your email address and we will send you an email with instructions on how to reset your account.", "enter_email_address": "Enter Email Address", "password_reset_sent": "Password Reset Sent", - "invalid_email": "Invalid Email / Email does not exist!" + "invalid_email": "Invalid Email / Email does not exist!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } diff --git a/public/src/client/reset_code.js b/public/src/client/reset_code.js index 9a7fc80075..f690a2b152 100644 --- a/public/src/client/reset_code.js +++ b/public/src/client/reset_code.js @@ -11,44 +11,39 @@ define('forum/reset_code', function() { resetEl.on('click', function() { if (password.val().length < 6) { - $('#error').addClass('hide').hide(); - noticeEl.find('strong').html('Invalid Password'); - noticeEl.find('p').html('The password entered is too short, please pick a different password.'); - noticeEl.removeClass('hide').css({display: 'block'}); - } else if (password.value !== repeat.value) { - $('#error').hide(); - noticeEl.find('strong').html('Invalid Password'); - noticeEl.find('p').html('The two passwords you\'ve entered do not match.'); - noticeEl.removeClass('hide').css({display: 'block'}); + app.alertError('[[reset_password:password_too_short]]'); + } else if (password.val() !== repeat.val()) { + app.alertError('[[reset_password:passwords_do_not_match]]'); } else { + resetEl.prop('disabled', true).html(' Changing Password'); socket.emit('user.reset.commit', { code: reset_code, password: password.val() }, function(err) { - if(err) { + if (err) { + ajaxify.refresh(); return app.alertError(err.message); } - $('#error').addClass('hide').hide(); - $('#notice').addClass('hide').hide(); - $('#success').removeClass('hide').addClass('show').show(); + + window.location.href = RELATIVE_PATH + '/login'; }); } }); - socket.emit('user.reset.valid', reset_code, function(err, valid) { - if(err) { - return app.alertError(err.message); - } + // socket.emit('user.reset.valid', reset_code, function(err, valid) { + // if(err) { + // return app.alertError(err.message); + // } - if (valid) { - resetEl.prop('disabled', false); - } else { - var formEl = $('#reset-form'); - // Show error message - $('#error').show(); - formEl.remove(); - } - }); + // if (valid) { + // resetEl.prop('disabled', false); + // } else { + // var formEl = $('#reset-form'); + // // Show error message + // $('#error').show(); + // formEl.remove(); + // } + // }); }; return ResetCode; diff --git a/src/controllers/index.js b/src/controllers/index.js index 797d30e22d..ff337250f4 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -106,9 +106,12 @@ Controllers.home = function(req, res, next) { Controllers.reset = function(req, res, next) { if (req.params.code) { - res.render('reset_code', { - reset_code: req.params.code ? req.params.code : null, - breadcrumbs: helpers.buildBreadcrumbs([{text: '[[reset_password:reset_password]]', url: '/reset'}, {text: '[[reset_password:update_password]]'}]) + user.reset.validate(req.params.code, function(err, valid) { + res.render('reset_code', { + valid: valid, + reset_code: req.params.code ? req.params.code : null, + breadcrumbs: helpers.buildBreadcrumbs([{text: '[[reset_password:reset_password]]', url: '/reset'}, {text: '[[reset_password:update_password]]'}]) + }); }); } else { res.render('reset', { diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 28feb5616f..4df8915994 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -13,6 +13,8 @@ var async = require('async'), websockets = require('./index'), meta = require('../meta'), events = require('../events'), + emailer = require('../emailer'), + db = require('../database'), SocketUser = {}; SocketUser.exists = function(socket, data, callback) { @@ -81,23 +83,34 @@ SocketUser.reset.send = function(socket, email, callback) { } }; -SocketUser.reset.valid = function(socket, code, callback) { - if (code) { - user.reset.validate(code, callback); - } -}; - SocketUser.reset.commit = function(socket, data, callback) { if(data && data.code && data.password) { - user.reset.commit(data.code, data.password, function(err) { + async.series([ + async.apply(db.getObjectField, 'reset:uid', data.code), + async.apply(user.reset.commit, data.code, data.password) + ], function(err, data) { if (err) { return callback(err); } + + var uid = data[0], + now = new Date(), + parsedDate = now.getFullYear() + '/' + (now.getMonth()+1) + '/' + now.getDate(); + + user.getUserField(uid, 'username', function(err, username) { + emailer.send('reset_notify', uid, { + username: username, + date: parsedDate, + site_title: meta.config.title || 'NodeBB', + subject: '[[email:reset.notify.subject]]' + }); + }); events.log({ type: 'password-reset', uid: socket.uid, ip: socket.ip }); + callback(); }); } }; diff --git a/src/upgrade.js b/src/upgrade.js index ed82dcd20a..52347bcb40 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -21,7 +21,7 @@ var db = require('./database'), schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema - latestSchema = Date.UTC(2015, 0, 30); + latestSchema = Date.UTC(2015, 1, 8); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -807,6 +807,26 @@ Upgrade.upgrade = function(callback) { winston.info('[2015/01/30] Adding group member counts skipped'); next(); } + }, + function(next) { + thisSchemaDate = Date.UTC(2015, 1, 8); + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.info('[2015/02/08] Clearing reset tokens'); + + db.deleteAll(['reset:expiry', 'reset:uid'], function(err) { + if (err) { + winston.error('[2015/02/08] Error encountered while Clearing reset tokens'); + return next(err); + } + + winston.info('[2015/02/08] Clearing reset tokens done'); + Upgrade.update(thisSchemaDate, next); + }); + } else { + winston.info('[2015/02/08] Clearing reset tokens skipped'); + next(); + } } // Add new schema updates here diff --git a/src/user/reset.js b/src/user/reset.js index c65e77a570..e49c077180 100644 --- a/src/user/reset.js +++ b/src/user/reset.js @@ -1,4 +1,3 @@ - 'use strict'; var async = require('async'), @@ -21,19 +20,13 @@ var async = require('async'), return callback(err, false); } - db.getObjectField('reset:expiry', code, function(err, expiry) { + db.sortedSetScore('reset:issueDate', code, function(err, issueDate) { + // db.getObjectField('reset:expiry', code, function(err, expiry) { if (err) { return callback(err); } - if (parseInt(expiry, 10) >= Date.now() / 1000) { - callback(null, true); - } else { - // Expired, delete from db - db.deleteObjectField('reset:uid', code); - db.deleteObjectField('reset:expiry', code); - callback(null, false); - } + callback(null, parseInt(issueDate, 10) > (Date.now() - (1000*60*120))); }); }); }; @@ -46,7 +39,7 @@ var async = require('async'), var reset_code = utils.generateUUID(); db.setObjectField('reset:uid', reset_code, uid); - db.setObjectField('reset:expiry', reset_code, (60 * 60) + Math.floor(Date.now() / 1000)); + db.sortedSetAdd('reset:issueDate', Date.now(), reset_code); var reset_link = nconf.get('url') + '/reset/' + reset_code; @@ -85,7 +78,7 @@ var async = require('async'), user.setUserField(uid, 'password', hash); db.deleteObjectField('reset:uid', code); - db.deleteObjectField('reset:expiry', code); + db.sortedSetRemove('reset:issueDate', code); user.auth.resetLockout(uid, callback); }); diff --git a/src/views/emails/reset_notify.tpl b/src/views/emails/reset_notify.tpl new file mode 100644 index 0000000000..34c26aa481 --- /dev/null +++ b/src/views/emails/reset_notify.tpl @@ -0,0 +1,10 @@ +

[[email:greeting_with_name, {username}]],

+ +

[[email:reset.notify.text1, {date}]]

+ +

[[email:reset.notify.text2]]

+ +

+ [[email:closing]]
+ {site_title} +

\ No newline at end of file diff --git a/src/views/emails/reset_notify_plaintext.tpl b/src/views/emails/reset_notify_plaintext.tpl new file mode 100644 index 0000000000..788618f9d5 --- /dev/null +++ b/src/views/emails/reset_notify_plaintext.tpl @@ -0,0 +1,8 @@ +[[email:greeting_with_name, {username}]], + +[[email:reset.notify.text1, {date}]] + +[[email:reset.notify.text2]] + +[[email:closing]] +{site_title} \ No newline at end of file From c35126116522ed753a164879001d5f69d2528cf7 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 8 Feb 2015 22:02:13 -0500 Subject: [PATCH 106/164] added daily cleaning of reset tokens #2708 --- src/notifications.js | 4 +--- src/user/jobs.js | 3 ++- src/user/reset.js | 18 +++++++++++++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/notifications.js b/src/notifications.js index 5d10686212..dc3aae7ea2 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -18,9 +18,7 @@ var async = require('async'), (function(Notifications) { Notifications.init = function() { - if (process.env.NODE_ENV === 'development') { - winston.verbose('[notifications.init] Registering jobs.'); - } + winston.verbose('[notifications.init] Registering jobs.'); new cron('*/30 * * * *', Notifications.prune, null, true); }; diff --git a/src/user/jobs.js b/src/user/jobs.js index 506f0d388b..16f6bd4ce8 100644 --- a/src/user/jobs.js +++ b/src/user/jobs.js @@ -4,7 +4,6 @@ var winston = require('winston'), cronJob = require('cron').CronJob, - user = require('../user'), meta = require('../meta'); module.exports = function(User) { @@ -23,6 +22,8 @@ module.exports = function(User) { winston.verbose('[user.startJobs] Digest job (monthly) started.'); User.digest.execute('month'); }, null, true); + + new cronJob('0 0 0 * * *', User.reset.clean, null, true); }; }; diff --git a/src/user/reset.js b/src/user/reset.js index e49c077180..3ce2f86cf8 100644 --- a/src/user/reset.js +++ b/src/user/reset.js @@ -2,6 +2,7 @@ var async = require('async'), nconf = require('nconf'), + winston = require('winston'), user = require('../user'), utils = require('../../public/src/utils'), @@ -13,7 +14,6 @@ var async = require('async'), emailer = require('../emailer'); (function(UserReset) { - UserReset.validate = function(code, callback) { db.getObjectField('reset:uid', code, function(err, uid) { if (err || !uid) { @@ -86,4 +86,20 @@ var async = require('async'), }); }; + UserReset.clean = function(callback) { + // Locate all codes that have expired, and remove them from the set/hash + async.waterfall([ + async.apply(db.getSortedSetRangeByScore, 'reset:issueDate', 0, -1, -1, +new Date()-(1000*60*120)), + function(tokens, next) { + if (!tokens.length) { return next(); } + + winston.verbose('[UserReset.clean] Removing ' + tokens.length + ' reset tokens from database'); + async.parallel([ + async.apply(db.deleteObjectField, 'reset:uid', tokens), + async.apply(db.sortedSetRemove, 'reset:issueDate', tokens) + ], next); + } + ], callback); + }; + }(exports)); From b1340b74c631edec1b33be3e0f2ca494cf7e8575 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 9 Feb 2015 13:41:21 -0500 Subject: [PATCH 107/164] updating vanilla minver --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 22c2570b1a..b5812a425d 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "nodebb-plugin-soundpack-default": "~0.1.1", "nodebb-plugin-spam-be-gone": "^0.4.0", "nodebb-theme-lavender": "^0.2.0", - "nodebb-theme-vanilla": "^0.2.0", + "nodebb-theme-vanilla": "^1.0.0", "nodebb-widget-essentials": "~0.2.0", "npm": "^2.1.4", "passport": "^0.2.1", From 9b451093498f0781fdcb69eb146c73ad354783b8 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 9 Feb 2015 14:49:43 -0500 Subject: [PATCH 108/164] updating development version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b5812a425d..cb00f143cc 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "nodebb", "license": "GPLv3 or later", "description": "NodeBB Forum", - "version": "0.6.1-dev", + "version": "0.7.0-dev", "homepage": "http://www.nodebb.org", "repository": { "type": "git", From be92f07ab929a050df635d048499b2fd3165f684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Mon, 9 Feb 2015 15:32:35 -0500 Subject: [PATCH 109/164] save/clear search preferences --- public/language/en_GB/search.json | 6 ++- public/src/client/search.js | 68 +++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/public/language/en_GB/search.json b/public/language/en_GB/search.json index b8a970d6a9..75749d4e06 100644 --- a/public/language/en_GB/search.json +++ b/public/language/en_GB/search.json @@ -32,5 +32,9 @@ "username": "Username", "category": "Category", "descending": "In descending order", - "ascending": "In ascending order" + "ascending": "In ascending order", + "save-preferences": "Save preferences", + "clear-preferences": "Clear preferences", + "search-preferences-saved": "Search preferences saved", + "search-preferences-cleared": "Search preferences cleared" } diff --git a/public/src/client/search.js b/public/src/client/search.js index 42bf7dd4fe..01637dd429 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -12,7 +12,7 @@ define('forum/search', ['search'], function(searchModule) { var searchIn = $('#advanced-search #search-in'); - fillOutFormFromQueryParams(); + fillOutForm(); searchIn.on('change', function() { updateFormItemVisiblity(searchIn.val()); @@ -22,38 +22,49 @@ define('forum/search', ['search'], function(searchModule) { $('#advanced-search').off('submit').on('submit', function(e) { e.preventDefault(); - var $this = $(this); - var input = $this.find('#search-input'); - - var searchData = { - term: input.val(), - in: $this.find('#search-in').val(), - by: $this.find('#posted-by-user').val(), - categories: $this.find('#posted-in-categories').val(), - searchChildren: $this.find('#search-children').is(':checked'), - replies: $this.find('#reply-count').val(), - repliesFilter: $this.find('#reply-count-filter').val(), - timeFilter: $this.find('#post-time-filter').val(), - timeRange: $this.find('#post-time-range').val(), - sortBy: $this.find('#post-sort-by').val(), - sortDirection: $this.find('#post-sort-direction').val() - }; + + var input = $(this).find('#search-input'); + + var searchData = getSearchData(); + searchData.term = input.val(); searchModule.query(searchData, function() { input.val(''); }); }); + handleSavePreferences(); + enableAutoComplete(); }; + function getSearchData() { + var form = $('#advanced-search'); + var searchData = { + in: form.find('#search-in').val(), + by: form.find('#posted-by-user').val(), + categories: form.find('#posted-in-categories').val(), + searchChildren: form.find('#search-children').is(':checked'), + replies: form.find('#reply-count').val(), + repliesFilter: form.find('#reply-count-filter').val(), + timeFilter: form.find('#post-time-filter').val(), + timeRange: form.find('#post-time-range').val(), + sortBy: form.find('#post-sort-by').val(), + sortDirection: form.find('#post-sort-direction').val() + }; + return searchData; + } + function updateFormItemVisiblity(searchIn) { var hide = searchIn.indexOf('posts') === -1 && searchIn.indexOf('titles') === -1; $('.post-search-item').toggleClass('hide', hide); } - function fillOutFormFromQueryParams() { + function fillOutForm() { var params = utils.params(); + var searchData = getSearchPreferences(); + params = utils.merge(searchData, params); + if (params) { if (params.in) { $('#search-in').val(params.in); @@ -110,6 +121,27 @@ define('forum/search', ['search'], function(searchModule) { }); } + function handleSavePreferences() { + $('#save-preferences').on('click', function() { + localStorage.setItem('search-preferences', JSON.stringify(getSearchData())); + app.alertSuccess('[[search:search-preferences-saved]]'); + return false; + }); + + $('#clear-preferences').on('click', function() { + localStorage.removeItem('search-preferences'); + app.alertSuccess('[[search:search-preferences-cleared]]'); + return false; + }); + } + + function getSearchPreferences() { + try { + return JSON.parse(localStorage.getItem('search-preferences')); + } catch(e) { + return {}; + } + } function enableAutoComplete() { var input = $('#posted-by-user'); From c98720ee4c3461da46fe846f4ac21533ecad3c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Mon, 9 Feb 2015 17:02:47 -0500 Subject: [PATCH 110/164] show results as WIP --- public/language/en_GB/search.json | 3 ++- public/src/client/search.js | 10 +++++++++- public/src/modules/search.js | 4 ++++ src/controllers/search.js | 3 ++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/public/language/en_GB/search.json b/public/language/en_GB/search.json index 75749d4e06..8c73511bda 100644 --- a/public/language/en_GB/search.json +++ b/public/language/en_GB/search.json @@ -36,5 +36,6 @@ "save-preferences": "Save preferences", "clear-preferences": "Clear preferences", "search-preferences-saved": "Search preferences saved", - "search-preferences-cleared": "Search preferences cleared" + "search-preferences-cleared": "Search preferences cleared", + "show-results-as": "Show results as" } diff --git a/public/src/client/search.js b/public/src/client/search.js index 01637dd429..96f2640ca0 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -50,7 +50,8 @@ define('forum/search', ['search'], function(searchModule) { timeFilter: form.find('#post-time-filter').val(), timeRange: form.find('#post-time-range').val(), sortBy: form.find('#post-sort-by').val(), - sortDirection: form.find('#post-sort-direction').val() + sortDirection: form.find('#post-sort-direction').val(), + showAs: form.find('#show-as-topics').is(':checked') ? 'topics' : 'posts' }; return searchData; } @@ -97,6 +98,13 @@ define('forum/search', ['search'], function(searchModule) { $('#post-sort-by').val(params.sortBy); $('#post-sort-direction').val(params.sortDirection); } + + if (params.showAs) { + var isTopic = params.showAs === 'topics'; + var ispost = params.showAs === 'posts'; + $('#show-as-topics').prop('checked', isTopic).parent().toggleClass('active', isTopic); + $('#show-as-posts').prop('checked', isPost).parent().toggleClass('active', isPost); + } } } diff --git a/public/src/modules/search.js b/public/src/modules/search.js index 9b896b0394..eedf0b76b9 100644 --- a/public/src/modules/search.js +++ b/public/src/modules/search.js @@ -62,6 +62,10 @@ define('search', ['navigator'], function(nav) { query.sortBy = data.sortBy; query.sortDirection = data.sortDirection; } + + if (data.showAs) { + query.showAs = data.showAs; + } return decodeURIComponent($.param(query)); } diff --git a/src/controllers/search.js b/src/controllers/search.js index d9e6bc9f3a..5c38c3f79b 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -62,7 +62,8 @@ searchController.search = function(req, res, next) { var pageCount = Math.max(1, Math.ceil(results.matchCount / 10)); results.pagination = pagination.create(page, pageCount, req.query); - + results.showAsPosts = !req.query.showAs || req.query.showAs === 'posts'; + results.showAsTopics = req.query.showAs === 'topics'; results.breadcrumbs = breadcrumbs; results.categories = categories; res.render('search', results); From 6cd615ee45aa814758022e1e6be05e4b0f2e2807 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 9 Feb 2015 17:45:35 -0500 Subject: [PATCH 111/164] dont add post/topic query params if searching for users/tags --- public/src/client/search.js | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/public/src/client/search.js b/public/src/client/search.js index 96f2640ca0..a8924ce8f9 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -22,7 +22,7 @@ define('forum/search', ['search'], function(searchModule) { $('#advanced-search').off('submit').on('submit', function(e) { e.preventDefault(); - + var input = $(this).find('#search-input'); var searchData = getSearchData(); @@ -41,18 +41,22 @@ define('forum/search', ['search'], function(searchModule) { function getSearchData() { var form = $('#advanced-search'); var searchData = { - in: form.find('#search-in').val(), - by: form.find('#posted-by-user').val(), - categories: form.find('#posted-in-categories').val(), - searchChildren: form.find('#search-children').is(':checked'), - replies: form.find('#reply-count').val(), - repliesFilter: form.find('#reply-count-filter').val(), - timeFilter: form.find('#post-time-filter').val(), - timeRange: form.find('#post-time-range').val(), - sortBy: form.find('#post-sort-by').val(), - sortDirection: form.find('#post-sort-direction').val(), - showAs: form.find('#show-as-topics').is(':checked') ? 'topics' : 'posts' + in: form.find('#search-in').val() }; + + if (searchData.in === 'posts' || searchData.in === 'titlespost' || searchData.in === 'titles') { + searchData.by = form.find('#posted-by-user').val(); + searchData.categories = form.find('#posted-in-categories').val(); + searchData.searchChildren = form.find('#search-children').is(':checked'); + searchData.replies = form.find('#reply-count').val(); + searchData.repliesFilter = form.find('#reply-count-filter').val(); + searchData.timeFilter = form.find('#post-time-filter').val(); + searchData.timeRange = form.find('#post-time-range').val(); + searchData.sortBy = form.find('#post-sort-by').val(); + searchData.sortDirection = form.find('#post-sort-direction').val(); + searchData.showAs = form.find('#show-as-topics').is(':checked') ? 'topics' : 'posts'; + } + return searchData; } @@ -65,7 +69,7 @@ define('forum/search', ['search'], function(searchModule) { var params = utils.params(); var searchData = getSearchPreferences(); params = utils.merge(searchData, params); - + if (params) { if (params.in) { $('#search-in').val(params.in); @@ -101,8 +105,8 @@ define('forum/search', ['search'], function(searchModule) { if (params.showAs) { var isTopic = params.showAs === 'topics'; - var ispost = params.showAs === 'posts'; - $('#show-as-topics').prop('checked', isTopic).parent().toggleClass('active', isTopic); + var isPost = params.showAs === 'posts'; + $('#show-as-topics').prop('checked', isTopic).parent().toggleClass('active', isTopic); $('#show-as-posts').prop('checked', isPost).parent().toggleClass('active', isPost); } } @@ -130,7 +134,7 @@ define('forum/search', ['search'], function(searchModule) { } function handleSavePreferences() { - $('#save-preferences').on('click', function() { + $('#save-preferences').on('click', function() { localStorage.setItem('search-preferences', JSON.stringify(getSearchData())); app.alertSuccess('[[search:search-preferences-saved]]'); return false; From 5e7bf7a27245a6bf160a9a4a1390205e5bbb71e9 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 9 Feb 2015 17:50:19 -0500 Subject: [PATCH 112/164] default search in posts --- src/controllers/search.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controllers/search.js b/src/controllers/search.js index 5c38c3f79b..0a26822699 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -41,6 +41,7 @@ searchController.search = function(req, res, next) { req.query.categories = [req.query.categories]; } + req.query.in = req.query.in || 'posts'; search.search({ query: req.params.term, searchIn: req.query.in, From b6125b1674d0ae8de7b8368497c05513dbe43cae Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 9 Feb 2015 18:00:02 -0500 Subject: [PATCH 113/164] toString pid --- src/search.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/search.js b/src/search.js index e26cb75f70..5cab307a98 100644 --- a/src/search.js +++ b/src/search.js @@ -89,7 +89,7 @@ function searchInContent(query, data, callback) { }, function(mainPids, next) { results.pids.forEach(function(pid) { - if (mainPids.indexOf(pid) === -1) { + if (mainPids.indexOf(pid.toString()) === -1) { mainPids.push(pid); } }); @@ -485,7 +485,7 @@ function getMainPids(tids, callback) { return callback(err); } topics = topics.map(function(topic) { - return topic && topic.mainPid; + return topic && topic.mainPid && topic.mainPid.toString(); }).filter(Boolean); callback(null, topics); }); From 15e6c5154147ffc3b1d3db43df950e97c64b4671 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 10 Feb 2015 10:53:19 -0500 Subject: [PATCH 114/164] latest translations --- public/language/ar/email.json | 3 + public/language/ar/error.json | 1 + public/language/ar/pages.json | 1 + public/language/ar/reset_password.json | 4 +- public/language/ar/search.json | 30 +++++- public/language/ar/users.json | 2 +- public/language/bn/email.json | 3 + public/language/bn/error.json | 1 + public/language/bn/pages.json | 1 + public/language/bn/reset_password.json | 4 +- public/language/bn/search.json | 30 +++++- public/language/bn/users.json | 2 +- public/language/cs/email.json | 3 + public/language/cs/error.json | 1 + public/language/cs/pages.json | 1 + public/language/cs/reset_password.json | 4 +- public/language/cs/search.json | 30 +++++- public/language/cs/users.json | 2 +- public/language/de/category.json | 2 +- public/language/de/email.json | 3 + public/language/de/error.json | 3 +- public/language/de/pages.json | 1 + public/language/de/reset_password.json | 4 +- public/language/de/search.json | 30 +++++- public/language/el/email.json | 3 + public/language/el/error.json | 1 + public/language/el/pages.json | 1 + public/language/el/reset_password.json | 4 +- public/language/el/search.json | 30 +++++- public/language/el/users.json | 2 +- public/language/en@pirate/email.json | 3 + public/language/en@pirate/error.json | 1 + public/language/en@pirate/pages.json | 1 + public/language/en@pirate/reset_password.json | 4 +- public/language/en@pirate/search.json | 30 +++++- public/language/en@pirate/users.json | 2 +- public/language/en_US/email.json | 3 + public/language/en_US/error.json | 1 + public/language/en_US/pages.json | 1 + public/language/en_US/reset_password.json | 4 +- public/language/en_US/search.json | 30 +++++- public/language/en_US/users.json | 2 +- public/language/es/email.json | 3 + public/language/es/error.json | 1 + public/language/es/pages.json | 1 + public/language/es/reset_password.json | 4 +- public/language/es/search.json | 30 +++++- public/language/es/users.json | 2 +- public/language/et/email.json | 3 + public/language/et/error.json | 1 + public/language/et/pages.json | 1 + public/language/et/reset_password.json | 4 +- public/language/et/search.json | 30 +++++- public/language/et/users.json | 2 +- public/language/fa_IR/email.json | 3 + public/language/fa_IR/error.json | 1 + public/language/fa_IR/pages.json | 1 + public/language/fa_IR/reset_password.json | 4 +- public/language/fa_IR/search.json | 30 +++++- public/language/fa_IR/users.json | 2 +- public/language/fi/email.json | 3 + public/language/fi/error.json | 1 + public/language/fi/pages.json | 1 + public/language/fi/reset_password.json | 4 +- public/language/fi/search.json | 30 +++++- public/language/fi/users.json | 2 +- public/language/fr/email.json | 3 + public/language/fr/error.json | 1 + public/language/fr/pages.json | 1 + public/language/fr/reset_password.json | 4 +- public/language/fr/search.json | 30 +++++- public/language/fr/users.json | 2 +- public/language/he/category.json | 2 +- public/language/he/email.json | 49 +++++----- public/language/he/error.json | 77 ++++++++-------- public/language/he/global.json | 16 ++-- public/language/he/groups.json | 38 ++++---- public/language/he/modules.json | 20 ++-- public/language/he/notifications.json | 42 ++++----- public/language/he/pages.json | 7 +- public/language/he/recent.json | 22 ++--- public/language/he/reset_password.json | 4 +- public/language/he/search.json | 38 +++++++- public/language/he/tags.json | 2 +- public/language/he/topic.json | 92 +++++++++---------- public/language/he/user.json | 42 ++++----- public/language/he/users.json | 8 +- public/language/hu/email.json | 3 + public/language/hu/error.json | 1 + public/language/hu/pages.json | 1 + public/language/hu/reset_password.json | 4 +- public/language/hu/search.json | 30 +++++- public/language/hu/users.json | 2 +- public/language/id/email.json | 3 + public/language/id/error.json | 1 + public/language/id/pages.json | 1 + public/language/id/reset_password.json | 4 +- public/language/id/search.json | 30 +++++- public/language/id/users.json | 2 +- public/language/it/email.json | 3 + public/language/it/error.json | 1 + public/language/it/pages.json | 1 + public/language/it/reset_password.json | 4 +- public/language/it/search.json | 30 +++++- public/language/it/users.json | 2 +- public/language/ja/email.json | 3 + public/language/ja/error.json | 1 + public/language/ja/pages.json | 1 + public/language/ja/reset_password.json | 4 +- public/language/ja/search.json | 30 +++++- public/language/ja/users.json | 2 +- public/language/ko/email.json | 3 + public/language/ko/error.json | 1 + public/language/ko/pages.json | 1 + public/language/ko/reset_password.json | 4 +- public/language/ko/search.json | 30 +++++- public/language/ko/users.json | 2 +- public/language/lt/email.json | 3 + public/language/lt/error.json | 1 + public/language/lt/pages.json | 1 + public/language/lt/reset_password.json | 4 +- public/language/lt/search.json | 30 +++++- public/language/lt/users.json | 2 +- public/language/ms/email.json | 3 + public/language/ms/error.json | 1 + public/language/ms/pages.json | 1 + public/language/ms/reset_password.json | 4 +- public/language/ms/search.json | 30 +++++- public/language/ms/users.json | 2 +- public/language/nb/email.json | 3 + public/language/nb/error.json | 1 + public/language/nb/pages.json | 1 + public/language/nb/reset_password.json | 4 +- public/language/nb/search.json | 30 +++++- public/language/nb/users.json | 2 +- public/language/nl/email.json | 3 + public/language/nl/error.json | 1 + public/language/nl/pages.json | 1 + public/language/nl/reset_password.json | 4 +- public/language/nl/search.json | 30 +++++- public/language/nl/users.json | 2 +- public/language/pl/email.json | 3 + public/language/pl/error.json | 1 + public/language/pl/pages.json | 1 + public/language/pl/reset_password.json | 4 +- public/language/pl/search.json | 30 +++++- public/language/pl/users.json | 2 +- public/language/pt_BR/email.json | 3 + public/language/pt_BR/error.json | 1 + public/language/pt_BR/pages.json | 1 + public/language/pt_BR/reset_password.json | 4 +- public/language/pt_BR/search.json | 30 +++++- public/language/pt_BR/users.json | 2 +- public/language/ro/email.json | 3 + public/language/ro/error.json | 1 + public/language/ro/pages.json | 1 + public/language/ro/reset_password.json | 4 +- public/language/ro/search.json | 30 +++++- public/language/ro/users.json | 2 +- public/language/ru/email.json | 3 + public/language/ru/error.json | 1 + public/language/ru/pages.json | 1 + public/language/ru/reset_password.json | 4 +- public/language/ru/search.json | 32 ++++++- public/language/ru/users.json | 2 +- public/language/sc/email.json | 3 + public/language/sc/error.json | 1 + public/language/sc/pages.json | 1 + public/language/sc/reset_password.json | 4 +- public/language/sc/search.json | 30 +++++- public/language/sc/users.json | 2 +- public/language/sk/email.json | 3 + public/language/sk/error.json | 1 + public/language/sk/pages.json | 1 + public/language/sk/reset_password.json | 4 +- public/language/sk/search.json | 30 +++++- public/language/sk/users.json | 2 +- public/language/sv/email.json | 3 + public/language/sv/error.json | 1 + public/language/sv/pages.json | 1 + public/language/sv/reset_password.json | 4 +- public/language/sv/search.json | 30 +++++- public/language/sv/users.json | 2 +- public/language/th/email.json | 3 + public/language/th/error.json | 1 + public/language/th/pages.json | 1 + public/language/th/reset_password.json | 4 +- public/language/th/search.json | 30 +++++- public/language/th/users.json | 2 +- public/language/tr/category.json | 2 +- public/language/tr/email.json | 7 +- public/language/tr/error.json | 15 +-- public/language/tr/global.json | 12 +-- public/language/tr/groups.json | 26 +++--- public/language/tr/pages.json | 1 + public/language/tr/recent.json | 18 ++-- public/language/tr/reset_password.json | 4 +- public/language/tr/search.json | 36 +++++++- public/language/tr/topic.json | 4 +- public/language/tr/user.json | 10 +- public/language/tr/users.json | 8 +- public/language/vi/email.json | 3 + public/language/vi/error.json | 1 + public/language/vi/pages.json | 1 + public/language/vi/reset_password.json | 4 +- public/language/vi/search.json | 30 +++++- public/language/vi/users.json | 2 +- public/language/zh_CN/email.json | 3 + public/language/zh_CN/error.json | 1 + public/language/zh_CN/pages.json | 1 + public/language/zh_CN/reset_password.json | 4 +- public/language/zh_CN/search.json | 30 +++++- public/language/zh_CN/users.json | 2 +- public/language/zh_TW/email.json | 3 + public/language/zh_TW/error.json | 1 + public/language/zh_TW/pages.json | 1 + public/language/zh_TW/reset_password.json | 4 +- public/language/zh_TW/search.json | 32 ++++++- public/language/zh_TW/users.json | 2 +- 219 files changed, 1555 insertions(+), 365 deletions(-) diff --git a/public/language/ar/email.json b/public/language/ar/email.json index f2820e0600..98cb9c0b0d 100644 --- a/public/language/ar/email.json +++ b/public/language/ar/email.json @@ -9,6 +9,9 @@ "reset.text1": "لقد توصلنا بطلب إعادة تعيين كلمة السرالخاصة بك، ربما لكونك قد نسيتها, إن لم يكن الأمر كذلك، المرجو تجاهل هذه الرسالة.", "reset.text2": "لمواصلة طلب إعاة تعيين كلمة السر، المرجو تتبع هذا الرابط.", "reset.cta": "انقر هنا لإعادة تعيين كلمة السر الخاصة بك.", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "لديك تنبيهات غير مقروءة من طرف %1:", "digest.latest_topics": "آخر المستجدات من %1", "digest.cta": "انقر هنا لمشاهدة %1", diff --git a/public/language/ar/error.json b/public/language/ar/error.json index 26d90ae89e..73eb289378 100644 --- a/public/language/ar/error.json +++ b/public/language/ar/error.json @@ -35,6 +35,7 @@ "topic-locked": "الموضوع مقفول", "still-uploading": "الرجاء انتظار الرفع", "content-too-short": "المرجو إدخال موضوع أطول من هذا. يجب أن تتوفر المواضيع على %1 حروف على الأقل.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "المرجو إدخال عنوان أطول من هذا. يجب أن تتوفر العناوين على %1 حروف على الأقل.", "title-too-long": "المرجو إدخال عنوان أقصر من هذا. يجب ألا تتجاوز العناوين %1 حرفًا.", "too-many-posts": "يمكنك إنشاء المواضيع بمعدل موضوع واحد كل %1 ثانية - المرجو الانتظار قليلا.", diff --git a/public/language/ar/pages.json b/public/language/ar/pages.json index 0dc17e025a..15e8209928 100644 --- a/public/language/ar/pages.json +++ b/public/language/ar/pages.json @@ -11,6 +11,7 @@ "user.followers": "المستخدمون الذين يتبعون %1", "user.posts": "ردود %1", "user.topics": "مواضيع %1", + "user.groups": "%1's Groups", "user.favourites": "مفضلات %1", "user.settings": "خيارات المستخدم", "maintenance.text": "جاري صيانة %1. المرجو العودة لاحقًا.", diff --git a/public/language/ar/reset_password.json b/public/language/ar/reset_password.json index 603f117b7e..b4f95dd780 100644 --- a/public/language/ar/reset_password.json +++ b/public/language/ar/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "يرجى إدخال عنوان البريد الإلكتروني الخاص بك وسوف نرسل لك رسالة بالبريد الالكتروني مع تعليمات حول كيفية إستعادة حسابك.", "enter_email_address": "ادخل عنوان البريد الإلكتروني", "password_reset_sent": "إعادة تعيين كلمة السر أرسلت", - "invalid_email": "بريد إلكتروني غير صالح أو غير موجود" + "invalid_email": "بريد إلكتروني غير صالح أو غير موجود", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/ar/search.json b/public/language/ar/search.json index 581a791905..50b985d452 100644 --- a/public/language/ar/search.json +++ b/public/language/ar/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/ar/users.json b/public/language/ar/users.json index b37bca619f..a842def62b 100644 --- a/public/language/ar/users.json +++ b/public/language/ar/users.json @@ -5,7 +5,7 @@ "search": "بحث", "enter_username": "أدخل اسم مستخدم للبحث", "load_more": "حمل المزيد", - "users-found-search-took": "تم إيجاد %1 مستخدمـ(ين)! استغرق البحث %2 ميليثانية.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/bn/email.json b/public/language/bn/email.json index b151164f2f..91169e5549 100644 --- a/public/language/bn/email.json +++ b/public/language/bn/email.json @@ -9,6 +9,9 @@ "reset.text1": "আমরা আপনার পাসওয়ার্ড রিসেট করার অনুরোধ পেয়েছি, সম্ভবত আপনি আপনার পাসওয়ার্ড ভুলে গিয়েছেন বলেই। তবে যদি তা না হয়ে থাকে, তাহলে এই মেইলকে উপেক্ষা করতে পারেন।", "reset.text2": "পাসওয়ার্ড রিসেট করতে নিচের লিংকে ক্লিক করুন", "reset.cta": "পাসওয়ার্ড রিসেট করতে এখানে ক্লিক করুন", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "%1 থেকে আনরিড নোটিফিকেশন আছে।", "digest.latest_topics": "%1 এর সর্বশেষ টপিকসমূহ", "digest.cta": "%1 ভিজিট করতে এখানে ক্লিক করুন", diff --git a/public/language/bn/error.json b/public/language/bn/error.json index ea1240c0ad..d1abf066d9 100644 --- a/public/language/bn/error.json +++ b/public/language/bn/error.json @@ -35,6 +35,7 @@ "topic-locked": "টপিক বন্ধ", "still-uploading": "আপলোড সম্পূর্ণ জন্য অনুগ্রহ করে অপেক্ষা করুন", "content-too-short": "অনুগ্রহকরে অপেক্ষকৃত বড় পোষ্ট করুন। একটি পোষ্টে নূন্যতম %1 অক্ষর থাকতে হবে।", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "অনুগ্রহপূর্বক বড় শিরোনাম ব্যাবহার করুন। শিরোনামের জন্য নূন্যতম %1 অক্ষর ব্যাবহার করতে হবে।", "title-too-long": "অনুগ্রহ করে সংক্ষিপ্ত শিরোনাম লিখুন। শিরোনাম %1 অক্ষরের বেশি হতে পারবে না।", "too-many-posts": "আপনি প্রতি %1 সেকেন্ডে একবার পোষ্ট করতে পারবেন। পরবর্তী পোষ্ট করার জন্য অপেক্ষা করুন। ", diff --git a/public/language/bn/pages.json b/public/language/bn/pages.json index 1e28db3a2d..4ab90a11a2 100644 --- a/public/language/bn/pages.json +++ b/public/language/bn/pages.json @@ -11,6 +11,7 @@ "user.followers": "যারা %1 কে অনুসরণ করেন", "user.posts": "%1 এর পোস্ট সমুহ", "user.topics": "%1 এর টপিক সমুহ", + "user.groups": "%1's Groups", "user.favourites": "%1'র প্রিয় পোস্টগুলো", "user.settings": "সদস্য সেটিংস", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/bn/reset_password.json b/public/language/bn/reset_password.json index d4aa6415c1..5643e1c427 100644 --- a/public/language/bn/reset_password.json +++ b/public/language/bn/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "অনুগ্রহপূর্বক আপনার ইমেইল এড্রেস প্রদান করুন, আমরা আপনাকে আপনার পাসওয়ার্ড রিসেট সম্পর্কিত তথ্যাবলী ইমেইলে পাঠিয়ে দিবো। ", "enter_email_address": "আপনার ইমেইল এড্রেস", "password_reset_sent": "পাসওয়ার্ড রিসেট মেইল পাঠানো হয়েছে", - "invalid_email": "ভুল ইমেইল / ইমেইল ডেটাবেইজে নেই" + "invalid_email": "ভুল ইমেইল / ইমেইল ডেটাবেইজে নেই", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/bn/search.json b/public/language/bn/search.json index eafce184ec..0038567599 100644 --- a/public/language/bn/search.json +++ b/public/language/bn/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/bn/users.json b/public/language/bn/users.json index 5d7dbd5cec..402aa33c27 100644 --- a/public/language/bn/users.json +++ b/public/language/bn/users.json @@ -5,7 +5,7 @@ "search": "খুঁজুন", "enter_username": "ইউজারনেম এর ভিত্তিতে সার্চ করুন", "load_more": "আরো লোড করুন", - "users-found-search-took": "%1 সদস্য(দের) খুঁজে পাওয়া গিয়েছে! সময় লেগেছে %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/cs/email.json b/public/language/cs/email.json index 27a2f06198..a259648e70 100644 --- a/public/language/cs/email.json +++ b/public/language/cs/email.json @@ -9,6 +9,9 @@ "reset.text1": "Obdrželi jsme požadavek na obnovu hesla, pravděpodobně kvůli tomu, že jste ho zapomněli. Pokud to není tento případ, ignorujte, prosím, tento email.", "reset.text2": "Přejete-li si pokračovat v obnově vašeho hesla, klikněte, prosím, na následující odkaz:", "reset.cta": "Klikněte zde, chcete-li obnovit vaše heslo", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Máte tu nepřečtená oznámení od %1:", "digest.latest_topics": "Nejnovější témata od %1", "digest.cta": "Kliknutím zde navštívíte %1", diff --git a/public/language/cs/error.json b/public/language/cs/error.json index c5ae30c511..f858b2b15f 100644 --- a/public/language/cs/error.json +++ b/public/language/cs/error.json @@ -35,6 +35,7 @@ "topic-locked": "Téma uzamčeno", "still-uploading": "Vyčkejte, prosím, nežli se vše kompletně nahraje.", "content-too-short": "Vložte, prosím, delší příspěvek. Příspěvky by měly obsahovat nejméně %1 znaků.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Vložte, prosím, delší titulek. Titulky by měly obsahovat nejméně %1 znaků.", "title-too-long": "Vložte, prosím, kratší titulek. Titulky by neměly být delší, než-li %1 znaků.", "too-many-posts": "Své příspěvky můžete odesílat po %1 sekundách - vyčkejte, prosím, před dalším odesláním", diff --git a/public/language/cs/pages.json b/public/language/cs/pages.json index b77b6411ba..15386435af 100644 --- a/public/language/cs/pages.json +++ b/public/language/cs/pages.json @@ -11,6 +11,7 @@ "user.followers": "People who Follow %1", "user.posts": "Posts made by %1", "user.topics": "Topics created by %1", + "user.groups": "%1's Groups", "user.favourites": "%1's Favourite Posts", "user.settings": "User Settings", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/cs/reset_password.json b/public/language/cs/reset_password.json index 41dce1549f..ba87244661 100644 --- a/public/language/cs/reset_password.json +++ b/public/language/cs/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Zadejte svou emailovou adresu a my Vám pošleme informace, jak můžete obnovit své heslo.", "enter_email_address": "Zadejte emailovou adresu", "password_reset_sent": "Obnova hesla odeslána", - "invalid_email": "Špatný email / Email neexistuje!" + "invalid_email": "Špatný email / Email neexistuje!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/cs/search.json b/public/language/cs/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/cs/search.json +++ b/public/language/cs/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/cs/users.json b/public/language/cs/users.json index fe3e7cb9b7..22b698a8c0 100644 --- a/public/language/cs/users.json +++ b/public/language/cs/users.json @@ -5,7 +5,7 @@ "search": "Vyhledávat", "enter_username": "Zadej uživatelské jméno k hledání", "load_more": "Načíst další", - "users-found-search-took": "Nazelezeno: %1 uživetel(ů)! Vyhledání trvalo %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/de/category.json b/public/language/de/category.json index f455b1604b..e3d45d3af8 100644 --- a/public/language/de/category.json +++ b/public/language/de/category.json @@ -1,6 +1,6 @@ { "new_topic_button": "Neues Thema", - "no_topics": "Es gibt noch keine Themen in dieser Kategorie.
Warum beginnst du nicht das erste?", + "no_topics": "Es gibt noch keine Themen in dieser Kategorie.
Warum beginnst du nicht eins?", "browsing": "Aktiv", "no_replies": "Niemand hat geantwortet", "share_this_category": "Teile diese Kategorie", diff --git a/public/language/de/email.json b/public/language/de/email.json index 4236feca0b..b60e620dd8 100644 --- a/public/language/de/email.json +++ b/public/language/de/email.json @@ -9,6 +9,9 @@ "reset.text1": "Wir haben eine Anfrage auf Zurücksetzung deines Passworts erhalten, wahrscheinlich, weil du es vergessen hast. Falls dies nicht der Fall ist, ignoriere bitte diese E-Mail.", "reset.text2": "Klicke bitte auf den folgenden Link, um mit der Zurücksetzung deines Passworts fortzufahren:", "reset.cta": "Klicke hier, um dein Passwort zurückzusetzen", + "reset.notify.subject": "Passwort erfolgreich geändert", + "reset.notify.text1": "Wir benachrichtigen dich das am %1, dein Passwort erfolgreich geändert wurde.", + "reset.notify.text2": "Wenn du das nicht autorisiert hast, bitte benachrichtige umgehend einen Administrator.", "digest.notifications": "Du hast ungelesene Benachrichtigungen von %1:", "digest.latest_topics": "Aktuellste Themen vom %1", "digest.cta": "Klicke hier, um %1 zu besuchen", diff --git a/public/language/de/error.json b/public/language/de/error.json index 376b75f62d..b2deb8a2d3 100644 --- a/public/language/de/error.json +++ b/public/language/de/error.json @@ -2,7 +2,7 @@ "invalid-data": "Daten ungültig", "not-logged-in": "Du bist nicht angemeldet.", "account-locked": "Dein Account wurde vorübergehend gesperrt.", - "search-requires-login": "Die Suche erfordert ein Konto! Bitte log dich ein oder registrieren dich!", + "search-requires-login": "Die Suche erfordert ein Konto! Bitte log dich ein oder registriere dich!", "invalid-cid": "Ungültige Kategorie-ID", "invalid-tid": "Ungültige Themen-ID", "invalid-pid": "Ungültige Beitrags-ID", @@ -35,6 +35,7 @@ "topic-locked": "Thema ist gesperrt", "still-uploading": "Bitte warte bis der Vorgang abgeschlossen ist.", "content-too-short": "Bitte gib einen längeren Beitrag ein. Beiträge sollten mindestens %1 Zeichen enthalten.", + "content-too-long": "Bitte schreibe einen kürzeren Beitrag. Beiträge können nicht mehr als %1 Zeichen enthalten.", "title-too-short": "Bitte gib einen längeren Titel ein. Titel sollten mindestens %1 Zeichen enthalten.", "title-too-long": "Der Titel darf maximal %1 Zeichen enthalten.", "too-many-posts": "Du kannst maximal alle %1 Sekunden einen Beitrag erstellen - bitte warte, bevor du einen neuen Beitrag erstellst", diff --git a/public/language/de/pages.json b/public/language/de/pages.json index 277678114f..78b7c7469d 100644 --- a/public/language/de/pages.json +++ b/public/language/de/pages.json @@ -11,6 +11,7 @@ "user.followers": "Nutzer, die %1 folgen", "user.posts": "Beiträge von %1", "user.topics": "Themen von %1", + "user.groups": "%1's Gruppen", "user.favourites": "Von %1 favorisierte Beiträge", "user.settings": "Benutzer-Einstellungen", "maintenance.text": "%1 befindet sich derzeit in der Wartung. Bitte komm später wieder.", diff --git a/public/language/de/reset_password.json b/public/language/de/reset_password.json index bbbfae1249..02d9329f7d 100644 --- a/public/language/de/reset_password.json +++ b/public/language/de/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Bitte gib Deine E-Mail Adresse ein und wir senden Dir eine Anleitung, wie Du Dein Passwort zurücksetzen kannst.", "enter_email_address": "E-Mail Adresse eingeben", "password_reset_sent": "Passwortzurücksetzung beantragt.", - "invalid_email": "Ungültige E-Mail / Adresse existiert nicht!" + "invalid_email": "Ungültige E-Mail / Adresse existiert nicht!", + "password_too_short": "Das eingegebene Passwort ist zu kurz, bitte wähle ein anderes Passwort.", + "passwords_do_not_match": "Die eingegebenen Passwörter stimmen nicht überein." } \ No newline at end of file diff --git a/public/language/de/search.json b/public/language/de/search.json index 80f5d100a7..d817f2aa7f 100644 --- a/public/language/de/search.json +++ b/public/language/de/search.json @@ -3,5 +3,33 @@ "no-matches": "Keine Ergebnisse gefunden", "in": "In", "by": "Bei", - "posted-by": "Geschrieben von" + "titles": "Titel", + "titles-posts": "Titel und Beiträge", + "posted-by": "Geschrieben von", + "in-categories": "In Kategorien", + "search-child-categories": "Suche in Unterkategorien", + "reply-count": "Antwort Anzahl", + "at-least": "Mindestens", + "at-most": "Höchstens", + "post-time": "Beitrags Zeit", + "newer-than": "Neuer als", + "older-than": "Älter als", + "any-date": "Jeder Zeitpunkt", + "yesterday": "Gestern", + "one-week": "Eine Woche", + "two-weeks": "Zwei Wochen", + "one-month": "Ein Monat", + "three-months": "Drei Monate", + "six-months": "Sechs Monate", + "one-year": "Ein Jahr", + "sort-by": "Sortieren nach", + "last-reply-time": "Letzter Antwort Zeitpunkt", + "topic-title": "Thementitel", + "number-of-replies": "Anzahl von Antworten", + "number-of-views": "Anzahl der Aufrufe", + "topic-start-date": "Thema Startdatum", + "username": "Benutzername", + "category": "Kategorie", + "descending": "In absteigender Reihenfolge", + "ascending": "In aufsteigender Reihenfolge" } \ No newline at end of file diff --git a/public/language/el/email.json b/public/language/el/email.json index 6563d675d5..c4a52f1ffa 100644 --- a/public/language/el/email.json +++ b/public/language/el/email.json @@ -9,6 +9,9 @@ "reset.text1": "Λάβαμε ένα αίτημα για επαναφορά του κωδικού σου, πιθανότατα γιατί τον ξέχασες. Αν δεν έκανες εσύ αυτό το αίτημα, αγνόησε αυτό το email.", "reset.text2": "Για να κάνεις την επαναφορά του κωδικού σου, παρακαλώ πάτα στο παρακάτω σύνδεσμο:", "reset.cta": "Κάνε κλικ εδώ για να επαναφέρεις τον κωδικό σου", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Πρόσφατα θέματα στο %1", "digest.cta": "Κάνε κλικ εδώ για να επισκεφτείς το %1", diff --git a/public/language/el/error.json b/public/language/el/error.json index e072c910f8..9cadac2731 100644 --- a/public/language/el/error.json +++ b/public/language/el/error.json @@ -35,6 +35,7 @@ "topic-locked": "Το θέμα έχει κλειδωθεί", "still-uploading": "Παρακαλώ περίμενε να τελειώσει το ανέβασμα των αρχείων.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Παρακαλώ γράψε έναν μικρότερο τίτλο. Δεν μπορεί να είναι μεγαλύτερος από %1 χαρακτήρες.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/el/pages.json b/public/language/el/pages.json index 04301ee967..0b9a89746e 100644 --- a/public/language/el/pages.json +++ b/public/language/el/pages.json @@ -11,6 +11,7 @@ "user.followers": "Άτομα που ακολουθούν τον/την %1", "user.posts": "Δημοσιεύσεις από τον/την %1", "user.topics": "Θέματα από τον/την %1", + "user.groups": "%1's Groups", "user.favourites": "Οι αγαπημένες δημοσιεύσεις του/της %1", "user.settings": "Επιλογές Χρήστη", "maintenance.text": "Το %1 αυτή την στιγμή συντηρείται. Παρακαλώ έλα αργότερα.", diff --git a/public/language/el/reset_password.json b/public/language/el/reset_password.json index e088a5bd9f..1ceecfd014 100644 --- a/public/language/el/reset_password.json +++ b/public/language/el/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Παρακαλώ γράψε την διεύθυνση email σου και θα σου στείλουμε ένα email με οδηγίες για το πως να επαναφέρεις τον λογαριασμό σου.", "enter_email_address": "Εισαγωγή Διεύθυνσης Email", "password_reset_sent": "Η Επαναφορά Κωδικού Εστάλη", - "invalid_email": "Άκυρο Email / Το email δεν υπάρχει!" + "invalid_email": "Άκυρο Email / Το email δεν υπάρχει!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/el/search.json b/public/language/el/search.json index fd5d9fa97e..eb08d6b538 100644 --- a/public/language/el/search.json +++ b/public/language/el/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/el/users.json b/public/language/el/users.json index 7a668b12a8..aae33e825c 100644 --- a/public/language/el/users.json +++ b/public/language/el/users.json @@ -5,7 +5,7 @@ "search": "Αναζήτηση", "enter_username": "Γράψε ένα όνομα χρήστη προς αναζήτηση", "load_more": "Φόρτωση περισσότερων", - "users-found-search-took": "%1 χρήστης(ες) βρέθηκαν! Η αναζήτηση πήρε %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/en@pirate/email.json b/public/language/en@pirate/email.json index e3199a9b14..f290435e75 100644 --- a/public/language/en@pirate/email.json +++ b/public/language/en@pirate/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/en@pirate/error.json b/public/language/en@pirate/error.json index 6079502fae..9bbcf03247 100644 --- a/public/language/en@pirate/error.json +++ b/public/language/en@pirate/error.json @@ -35,6 +35,7 @@ "topic-locked": "Topic Locked", "still-uploading": "Please wait for uploads to complete.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/en@pirate/pages.json b/public/language/en@pirate/pages.json index b77b6411ba..15386435af 100644 --- a/public/language/en@pirate/pages.json +++ b/public/language/en@pirate/pages.json @@ -11,6 +11,7 @@ "user.followers": "People who Follow %1", "user.posts": "Posts made by %1", "user.topics": "Topics created by %1", + "user.groups": "%1's Groups", "user.favourites": "%1's Favourite Posts", "user.settings": "User Settings", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/en@pirate/reset_password.json b/public/language/en@pirate/reset_password.json index dcdf4e76b6..ba9f012ea6 100644 --- a/public/language/en@pirate/reset_password.json +++ b/public/language/en@pirate/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Please enter your email address and we will send you an email with instructions on how to reset your account.", "enter_email_address": "Enter Email Address", "password_reset_sent": "Password Reset Sent", - "invalid_email": "Invalid Email / Email does not exist!" + "invalid_email": "Invalid Email / Email does not exist!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/en@pirate/search.json b/public/language/en@pirate/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/en@pirate/search.json +++ b/public/language/en@pirate/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/en@pirate/users.json b/public/language/en@pirate/users.json index adbfee83cc..daabbb899c 100644 --- a/public/language/en@pirate/users.json +++ b/public/language/en@pirate/users.json @@ -5,7 +5,7 @@ "search": "Search", "enter_username": "Gimme y'er handle", "load_more": "Load More", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/en_US/email.json b/public/language/en_US/email.json index e3199a9b14..f290435e75 100644 --- a/public/language/en_US/email.json +++ b/public/language/en_US/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/en_US/error.json b/public/language/en_US/error.json index 6079502fae..9bbcf03247 100644 --- a/public/language/en_US/error.json +++ b/public/language/en_US/error.json @@ -35,6 +35,7 @@ "topic-locked": "Topic Locked", "still-uploading": "Please wait for uploads to complete.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/en_US/pages.json b/public/language/en_US/pages.json index d96ee1a8e6..c6d577d2f5 100644 --- a/public/language/en_US/pages.json +++ b/public/language/en_US/pages.json @@ -11,6 +11,7 @@ "user.followers": "People who Follow %1", "user.posts": "Posts made by %1", "user.topics": "Topics created by %1", + "user.groups": "%1's Groups", "user.favourites": "%1's Favorite Posts", "user.settings": "User Settings", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/en_US/reset_password.json b/public/language/en_US/reset_password.json index dcdf4e76b6..ba9f012ea6 100644 --- a/public/language/en_US/reset_password.json +++ b/public/language/en_US/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Please enter your email address and we will send you an email with instructions on how to reset your account.", "enter_email_address": "Enter Email Address", "password_reset_sent": "Password Reset Sent", - "invalid_email": "Invalid Email / Email does not exist!" + "invalid_email": "Invalid Email / Email does not exist!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/en_US/search.json b/public/language/en_US/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/en_US/search.json +++ b/public/language/en_US/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/en_US/users.json b/public/language/en_US/users.json index a06aee2734..0038dcffc4 100644 --- a/public/language/en_US/users.json +++ b/public/language/en_US/users.json @@ -5,7 +5,7 @@ "search": "Search", "enter_username": "Enter a username to search", "load_more": "Load More", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/es/email.json b/public/language/es/email.json index 870687c4e6..fd42293e1b 100644 --- a/public/language/es/email.json +++ b/public/language/es/email.json @@ -9,6 +9,9 @@ "reset.text1": "Recibimos una solicitud para reiniciar tu contraseña, posiblemente porque la olvidaste. Si no es así, por favor ignora este email.", "reset.text2": "Para continuar con el reinicio de contraseña, por favor cliquea en el siguiente vínculo:", "reset.cta": "Cliquea aquí para reiniciar tu contraseña", + "reset.notify.subject": "Se ha modificado correctamente la contraseña.", + "reset.notify.text1": "Te estamos notificando que a a %1, tu contraseña ha sido cambiado correctamente.", + "reset.notify.text2": "Si no has sido tu, por favor notifica al administrador inmediatamente.", "digest.notifications": "Tiene notificaciones sin leer de %1:", "digest.latest_topics": "Últimos temas de %1", "digest.cta": "Cliquea aquí para visitar %1", diff --git a/public/language/es/error.json b/public/language/es/error.json index 1c4f54397b..7a79b28ba4 100644 --- a/public/language/es/error.json +++ b/public/language/es/error.json @@ -35,6 +35,7 @@ "topic-locked": "Tema bloqueado", "still-uploading": "Por favor, espera a que terminen las subidas.", "content-too-short": "Por favor introduzca una publicación más larga. Las publicaciones deben contener al menos %1 caracteres.", + "content-too-long": "Por favor introduzca un mensaje más corto. Los mensajes no pueden exceder los %1 caracteres.", "title-too-short": "Por favor introduzca un título más largo. Los títulos deben contener al menos %1 caracteres.", "title-too-long": "Por favor, introduce un título más corto, que no sobrepase los %1 caracteres.", "too-many-posts": "Solo puedes publicar una vez cada %1 segundos - por favor espere antes de volver a publicar", diff --git a/public/language/es/pages.json b/public/language/es/pages.json index 27d9ca8f67..4cd102fdf0 100644 --- a/public/language/es/pages.json +++ b/public/language/es/pages.json @@ -11,6 +11,7 @@ "user.followers": "Seguidores de %1", "user.posts": "Mensajes de %1", "user.topics": "Temas creados por %1", + "user.groups": "%1's Grupos", "user.favourites": "Publicaciones favoritas de %1 ", "user.settings": "Preferencias de usuario", "maintenance.text": "%1 está en mantenimiento actualmente. Por favor vuelva en otro momento.", diff --git a/public/language/es/reset_password.json b/public/language/es/reset_password.json index ea8e2b1fac..da269f5448 100644 --- a/public/language/es/reset_password.json +++ b/public/language/es/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Por favor ingresa tu correo electrónico y te enviaremos un mensaje con indicaciones para restablecer tu cuenta.", "enter_email_address": "Introduce tu correo electrónico", "password_reset_sent": "Restablecimiento de contraseña enviado", - "invalid_email": "¡Correo electrónico no válido o inexistente!" + "invalid_email": "¡Correo electrónico no válido o inexistente!", + "password_too_short": "La contraseña introducida es demasiado corta, por favor introduzca una contraseña diferente.", + "passwords_do_not_match": "Las dos contraseñas introducidas no concuerdan." } \ No newline at end of file diff --git a/public/language/es/search.json b/public/language/es/search.json index 769c91f354..e23eea6ba8 100644 --- a/public/language/es/search.json +++ b/public/language/es/search.json @@ -3,5 +3,33 @@ "no-matches": "No se encontraron coincidencias", "in": "En", "by": "Por", - "posted-by": "Publicado por" + "titles": "Títulos", + "titles-posts": "Títulos y publicaciones", + "posted-by": "Publicado por", + "in-categories": "En categorías", + "search-child-categories": "Buscar categorías hijas", + "reply-count": "Número de Respuestas", + "at-least": "De mínimo", + "at-most": "De máximo", + "post-time": "Fecha de publicación", + "newer-than": "Más reciente que", + "older-than": "Más antiguo que", + "any-date": "Cualquier fecha", + "yesterday": "Ayer", + "one-week": "Una semana", + "two-weeks": "Dos semanas", + "one-month": "Un mes", + "three-months": "Tres meses", + "six-months": "Seis meses", + "one-year": "Un año", + "sort-by": "Ordenar por", + "last-reply-time": "Fecha de última respuesta", + "topic-title": "Título de tema", + "number-of-replies": "Número de respuestas", + "number-of-views": "Número de visualizaciones", + "topic-start-date": "Fecha de inicio del tema", + "username": "Usuario", + "category": "Categoría", + "descending": "En orden descendente", + "ascending": "En orden ascendente" } \ No newline at end of file diff --git a/public/language/es/users.json b/public/language/es/users.json index 529a6accb5..81668516cf 100644 --- a/public/language/es/users.json +++ b/public/language/es/users.json @@ -5,7 +5,7 @@ "search": "Buscar", "enter_username": "Ingresa el nombre de usuario que quieres buscar", "load_more": "Cargar más", - "users-found-search-took": "¡%1 usuario(s) encontrados! La búsqueda tardó %2 ms.", + "users-found-search-took": "¡%1 usuario(s) encontrado! La búsqueda ha llevado %2 segundos.", "filter-by": "Filtrar Por", "online-only": "Sólo en línea", "picture-only": "Sólo imagen" diff --git a/public/language/et/email.json b/public/language/et/email.json index e3199a9b14..f290435e75 100644 --- a/public/language/et/email.json +++ b/public/language/et/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/et/error.json b/public/language/et/error.json index ea2c2e9ff4..277568c591 100644 --- a/public/language/et/error.json +++ b/public/language/et/error.json @@ -35,6 +35,7 @@ "topic-locked": "Teema lukustatud", "still-uploading": "Palun oota, kuni üleslaadimised on laetud.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Palun sisesta lühem pealkiri. Pealkirjad ei saa olla pikemad kui %1 tähemärki.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/et/pages.json b/public/language/et/pages.json index be7537527b..4a8ef6408f 100644 --- a/public/language/et/pages.json +++ b/public/language/et/pages.json @@ -11,6 +11,7 @@ "user.followers": "Kasutajad, kes jälgivad %1", "user.posts": "Postitused, mis on tehtud kasutaja %1 poolt", "user.topics": "Teemad on kirjutanud %1", + "user.groups": "%1's Groups", "user.favourites": "%1's lemmikud postitused", "user.settings": "Kasutaja sätted", "maintenance.text": "%1 foorumil on käimas hooldustööd. Palun külastage meid mõne aja pärast uuesti.", diff --git a/public/language/et/reset_password.json b/public/language/et/reset_password.json index c504ed9296..98e4fe4fae 100644 --- a/public/language/et/reset_password.json +++ b/public/language/et/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Palun sisesta oma emaili aadress ja me saadame sulle emaili koos õpetusega, kuidas oma parooli vahetada.", "enter_email_address": "Sisesta emaili aadress", "password_reset_sent": "Saadetud", - "invalid_email": "Vigane emaili aadress / emaili aadressi ei ekisteeri!" + "invalid_email": "Vigane emaili aadress / emaili aadressi ei ekisteeri!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/et/search.json b/public/language/et/search.json index 840538a793..448f45b055 100644 --- a/public/language/et/search.json +++ b/public/language/et/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/et/users.json b/public/language/et/users.json index 4782d131f5..ac83e6b160 100644 --- a/public/language/et/users.json +++ b/public/language/et/users.json @@ -5,7 +5,7 @@ "search": "Otsi", "enter_username": "Sisesta kasutajanimi, keda soovid otsida", "load_more": "Lae veel", - "users-found-search-took": "%1kasutaja(t) leiti! Otsing kestis %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/fa_IR/email.json b/public/language/fa_IR/email.json index 79cf1e91cf..206fe1823b 100644 --- a/public/language/fa_IR/email.json +++ b/public/language/fa_IR/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "برای تنظیم مجدد گذرواژه‌ی خود اینجا کلیک کنید", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "برای دیدن 1% اینجا کلیک کنید", diff --git a/public/language/fa_IR/error.json b/public/language/fa_IR/error.json index 61736c18c4..e99118134c 100644 --- a/public/language/fa_IR/error.json +++ b/public/language/fa_IR/error.json @@ -35,6 +35,7 @@ "topic-locked": "جستار بسته شد.", "still-uploading": "خواهشمندیم تا پایان بارگذاری‌ها شکیبا باشید.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "خواهشمندیم عنوان کوتاه‌تری بنویسید. عنوان‌ها نمی‌توانند بیش‌تر از %1 نویسه داشته باشند.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/fa_IR/pages.json b/public/language/fa_IR/pages.json index ec3b4e6800..42dacfa193 100644 --- a/public/language/fa_IR/pages.json +++ b/public/language/fa_IR/pages.json @@ -11,6 +11,7 @@ "user.followers": "کاربرانی که %1 را دنبال می‌کنند", "user.posts": "دیدگاه‌های %1", "user.topics": "%1 این جستار را ساخت.", + "user.groups": "%1's Groups", "user.favourites": "دیدگاه‌های پسندیدهٔ %1", "user.settings": "تنظیمات کاربر", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/fa_IR/reset_password.json b/public/language/fa_IR/reset_password.json index a0171f831c..5e6ea61461 100644 --- a/public/language/fa_IR/reset_password.json +++ b/public/language/fa_IR/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "لطفا نشانی رایانامهٔ خود را بنویسید و ما دستورکار بازیابی شناسه‌تان را به این رایانامه می‌فرستیم.", "enter_email_address": "نوشتن نشانی رایانامه", "password_reset_sent": "رایانامهٔ بازیابی گذرواژه فرستاده شد", - "invalid_email": "رایانامهٔ نامعتبر / رایانامه وجود ندارد!" + "invalid_email": "رایانامهٔ نامعتبر / رایانامه وجود ندارد!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/fa_IR/search.json b/public/language/fa_IR/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/fa_IR/search.json +++ b/public/language/fa_IR/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/fa_IR/users.json b/public/language/fa_IR/users.json index aec64b6020..b164bd0839 100644 --- a/public/language/fa_IR/users.json +++ b/public/language/fa_IR/users.json @@ -5,7 +5,7 @@ "search": "جستجو", "enter_username": "یک نام کاربری برای جستجو وارد کنید", "load_more": "بارگذاری بیش‌تر", - "users-found-search-took": "%1 کاربر() در مدت زمان %2 میلی ثانیه یافت شد!", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/fi/email.json b/public/language/fi/email.json index e3199a9b14..f290435e75 100644 --- a/public/language/fi/email.json +++ b/public/language/fi/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/fi/error.json b/public/language/fi/error.json index a9f843b34a..813f7896e2 100644 --- a/public/language/fi/error.json +++ b/public/language/fi/error.json @@ -35,6 +35,7 @@ "topic-locked": "Aihe lukittu", "still-uploading": "Ole hyvä ja odota tiedostojen lähettämisen valmistumista.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Otsikkosi on liian pitkä. Otsikoiden pituuden tulee olla enintään %1 merkkiä.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/fi/pages.json b/public/language/fi/pages.json index 22b1b20306..07d941a4dc 100644 --- a/public/language/fi/pages.json +++ b/public/language/fi/pages.json @@ -11,6 +11,7 @@ "user.followers": "Käyttäjät, jotka seuraavat käyttäjää %1", "user.posts": "Käyttäjän %1 kirjoittamat viestit", "user.topics": "Käyttäjän %1 aloittamat aiheet", + "user.groups": "%1's Groups", "user.favourites": "Käyttäjän %1 suosikkiviestit", "user.settings": "Käyttäjän asetukset", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/fi/reset_password.json b/public/language/fi/reset_password.json index 071287708d..9d78c5f372 100644 --- a/public/language/fi/reset_password.json +++ b/public/language/fi/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Syötä sähköpostiosoitteesi, niin me lähetämme sinulle sähköpostilla ohjeet käyttäjätilisi palauttamiseksi.", "enter_email_address": "Syötä sähköpostiosoite", "password_reset_sent": "Salasanan palautuskoodi lähetetty", - "invalid_email": "Virheellinen sähköpostiosoite / Sähköpostiosoitetta ei ole olemassa!" + "invalid_email": "Virheellinen sähköpostiosoite / Sähköpostiosoitetta ei ole olemassa!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/fi/search.json b/public/language/fi/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/fi/search.json +++ b/public/language/fi/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/fi/users.json b/public/language/fi/users.json index 67556152ae..f1cca4ea56 100644 --- a/public/language/fi/users.json +++ b/public/language/fi/users.json @@ -5,7 +5,7 @@ "search": "Hae", "enter_username": "Syötä käyttäjätunnus hakeaksesi", "load_more": "Lataa lisää", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/fr/email.json b/public/language/fr/email.json index 0e4f57d601..a3b80ecd21 100644 --- a/public/language/fr/email.json +++ b/public/language/fr/email.json @@ -9,6 +9,9 @@ "reset.text1": "Nous avons reçu une demande de réinitialisation de votre mot de passe, probablement parce que vous l'avez oublié. Si ce n'est pas le cas, veuillez ignorer cet email.", "reset.text2": "Pour confirmer la réinitialisation de votre mot de passe, veuillez cliquer sur le lien suivant :", "reset.cta": "Cliquez ici pour réinitialiser votre mot de passe", + "reset.notify.subject": "Mot de Passe modifié", + "reset.notify.text1": "Nous vous informons que le %1, votre mot de passe a été modifié.", + "reset.notify.text2": "Si vous n'avez pas autorisé ceci, veuillez contacter immédiatement un administrateur.", "digest.notifications": "Vous avez des notifications non-lues de %1 :", "digest.latest_topics": "Derniers sujets de %1 :", "digest.cta": "Cliquez ici pour aller sur %1", diff --git a/public/language/fr/error.json b/public/language/fr/error.json index 50507ebd02..bfa70c579c 100644 --- a/public/language/fr/error.json +++ b/public/language/fr/error.json @@ -35,6 +35,7 @@ "topic-locked": "Sujet verrouillé", "still-uploading": "Veuillez patienter pendant le téléchargement.", "content-too-short": "Veuillez entrer un message plus long. %1 caractères minimum.", + "content-too-long": "Veuillez poster un message plus cours. Les messages ne peuvent être plus long que %1 caractères.", "title-too-short": "Veuillez entrer un titre plus long. %1 caractères minimum.", "title-too-long": "Veuillez entrer un titre plus court. Les titres ne peuvent excéder %1 caractères.", "too-many-posts": "Vous ne pouvez poster que toutes les %1 secondes.", diff --git a/public/language/fr/pages.json b/public/language/fr/pages.json index 1085bcfc21..7698a55986 100644 --- a/public/language/fr/pages.json +++ b/public/language/fr/pages.json @@ -11,6 +11,7 @@ "user.followers": "Personnes qui suivent %1", "user.posts": "Message écrit par %1", "user.topics": "Sujets créés par %1", + "user.groups": "Les Groupes de %1", "user.favourites": "Messages favoris de %1", "user.settings": "Préférences utilisateur", "maintenance.text": "%1 est en maintenance. Veuillez revenir un peu plus tard.", diff --git a/public/language/fr/reset_password.json b/public/language/fr/reset_password.json index 00e531a9c4..f21186c870 100644 --- a/public/language/fr/reset_password.json +++ b/public/language/fr/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Veuillez entrer votre adresse email pour recevoir un email contenant les instructions permettant de réinitialiser votre compte.", "enter_email_address": "Entrer votre adresse email", "password_reset_sent": "La demande de réinitialisation du mot de passe a bien été envoyée", - "invalid_email": "Email invalide / L'email n'existe pas !" + "invalid_email": "Email invalide / L'email n'existe pas !", + "password_too_short": "Le mot de passe est trop court, veuillez entre un mot de passe différent.", + "passwords_do_not_match": "Les deux mots de passe saisient ne correspondent pas." } \ No newline at end of file diff --git a/public/language/fr/search.json b/public/language/fr/search.json index b8cdfc8d2a..20e22d2fa0 100644 --- a/public/language/fr/search.json +++ b/public/language/fr/search.json @@ -3,5 +3,33 @@ "no-matches": "Aucune réponse trouvée", "in": "Dans", "by": "Par", - "posted-by": "Posté par" + "titles": "Titres", + "titles-posts": "Titres et Messages", + "posted-by": "Posté par", + "in-categories": "Dans les catégories", + "search-child-categories": "Chercher les sous catégories", + "reply-count": "Nombre de réponses", + "at-least": "Au moins", + "at-most": "Au plus", + "post-time": "Date de message", + "newer-than": "Plus récent que", + "older-than": "Plus vieux que", + "any-date": "Toute date", + "yesterday": "Hier", + "one-week": "Une semaine", + "two-weeks": "Deux semaines", + "one-month": "Un mois", + "three-months": "Trois mois", + "six-months": "Six mois", + "one-year": "Un an", + "sort-by": "Trier par", + "last-reply-time": "Date de dernière réponse", + "topic-title": "Titre de sujet", + "number-of-replies": "Nombre de réponses", + "number-of-views": "Nombre de vues", + "topic-start-date": "Date de création du sujet", + "username": "Nom d'utilisateur", + "category": "Catgorie", + "descending": "Par ordre décroissant", + "ascending": "Par ordre croissant" } \ No newline at end of file diff --git a/public/language/fr/users.json b/public/language/fr/users.json index 8d2c4481ea..1028292a9b 100644 --- a/public/language/fr/users.json +++ b/public/language/fr/users.json @@ -5,7 +5,7 @@ "search": "Rechercher", "enter_username": "Entrer un nom d'utilisateur pour rechercher", "load_more": "Charger la suite", - "users-found-search-took": "%1 utilisateur(s) trouvé(s) ! Recherche effectuée en %2 ms.", + "users-found-search-took": "%1 utilisateur(s) trouvé(s)! La recherche a pris %2 secondes.", "filter-by": "Filtrer Par", "online-only": "En Ligne uniquement", "picture-only": "Avec Image uniquement" diff --git a/public/language/he/category.json b/public/language/he/category.json index bc5e530729..86292076b6 100644 --- a/public/language/he/category.json +++ b/public/language/he/category.json @@ -4,5 +4,5 @@ "browsing": "צופים בנושא זה כעת", "no_replies": "אין תגובות", "share_this_category": "שתף קטגוריה זו", - "ignore": "Ignore" + "ignore": "התעלם" } \ No newline at end of file diff --git a/public/language/he/email.json b/public/language/he/email.json index e3199a9b14..8743ba21d8 100644 --- a/public/language/he/email.json +++ b/public/language/he/email.json @@ -1,25 +1,28 @@ { - "password-reset-requested": "Password Reset Requested - %1!", - "welcome-to": "Welcome to %1", - "greeting_no_name": "Hello", - "greeting_with_name": "Hello %1", - "welcome.text1": "Thank you for registering with %1!", - "welcome.text2": "To fully activate your account, we need to verify that you own the email address you registered with.", - "welcome.cta": "Click here to confirm your email address", - "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", - "reset.text2": "To continue with the password reset, please click on the following link:", - "reset.cta": "Click here to reset your password", - "digest.notifications": "You have unread notifications from %1:", - "digest.latest_topics": "Latest topics from %1", - "digest.cta": "Click here to visit %1", - "digest.unsub.info": "This digest was sent to you due to your subscription settings.", - "digest.no_topics": "There have been no active topics in the past %1", - "notif.chat.subject": "New chat message received from %1", - "notif.chat.cta": "Click here to continue the conversation", - "notif.chat.unsub.info": "This chat notification was sent to you due to your subscription settings.", - "notif.post.cta": "Click here to read the full topic", - "notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.", - "test.text1": "This is a test email to verify that the emailer is set up correctly for your NodeBB.", - "unsub.cta": "Click here to alter those settings", - "closing": "Thanks!" + "password-reset-requested": "בקשת איפוס הסיסמה נשלחה - %1!", + "welcome-to": "ברוכים הבאים ל%1", + "greeting_no_name": "שלום", + "greeting_with_name": "שלום %1", + "welcome.text1": "תודה שנרשמת ל%1!", + "welcome.text2": "על מנת להפעיל את החשבון שלך, אנו צריכים לוודא שאתה בעל חשבון המייל שנרשמת איתו.", + "welcome.cta": "לחץ כאן על מנת לאשר את כתובת המייל שלך.", + "reset.text1": "קיבלנו בקשה לאפס את הסיסמה לחשבון שלך, כנראה מפני ששכחת אותה. אם לא ביקשת לאפס את הסיסמה, אנא התעלם ממייל זה.", + "reset.text2": "על מנת להמשיך עם תהליך איפוס הסיסמה, אנא לחץ על הלינק הבא:", + "reset.cta": "לחץ כאן לאפס את הסיסמה שלך.", + "reset.notify.subject": "הסיסמה שונתה בהצלחה.", + "reset.notify.text1": "אנו מודיעים לך שב%1, סיסמתך שונתה בהצלחה.", + "reset.notify.text2": "אם לא אישרת בקשה זו, אנא הודע למנהל מיד.", + "digest.notifications": "יש לך התראה שלא נקראה מ%1:", + "digest.latest_topics": "נושאים אחרונים מ%1", + "digest.cta": "לחץ כאן כדי לבקר ב %1", + "digest.unsub.info": "תקציר זה נשלח אליך על-פי הגדרות החשבון שלך.", + "digest.no_topics": "אין נושאים פעילים ב%1 האחרון/ים", + "notif.chat.subject": "הודעת צ'אט חדשה התקבלה מ%1", + "notif.chat.cta": "לחץ כאן כדי להמשיך את השיחה", + "notif.chat.unsub.info": "התראה הצ'אט הזו נשלחה אליך על-פי הגדרות החשבון שלך.", + "notif.post.cta": "לחץ כאן בשביל לקרוא את כל הנושא", + "notif.post.unsub.info": "התראת הפוסט הזו נשלחה אליך על-פי הגדרות החשבון שלך.", + "test.text1": "זהו אימייל ניסיון על מנת לוודא שהגדרות המייל בוצעו כהלכה בהגדרות NodeBB.", + "unsub.cta": "לחץ כאן לשנות הגדרות אלו", + "closing": "תודה!" } \ No newline at end of file diff --git a/public/language/he/error.json b/public/language/he/error.json index 28a5461705..23d21ee1ae 100644 --- a/public/language/he/error.json +++ b/public/language/he/error.json @@ -12,62 +12,63 @@ "invalid-title": "כותרת שגויה", "invalid-user-data": "מידע משתמש שגוי", "invalid-password": "סיסמא שגויה", - "invalid-username-or-password": "Please specify both a username and password", - "invalid-search-term": "Invalid search term", + "invalid-username-or-password": "אנא הגדר שם משתמש וסיסמה", + "invalid-search-term": "מילת חיפוש לא תקינה", "invalid-pagination-value": "ערך דפדוף שגוי", "username-taken": "שם משתמש תפוס", "email-taken": "כתובת אימייל תפוסה", - "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", - "email-not-confirmed-chat": "You are unable to chat until your email is confirmed", + "email-not-confirmed": "כתובת המייל שלך עוד לא אושרה, לחץ כאן על-מנת לאשר את המייל שלך.", + "email-not-confirmed-chat": "לא תוכל לדבר בצ'אט עד שלא תאשר את כתובת המייל שלך", "username-too-short": "שם משתמש קצר מדי", - "username-too-long": "Username too long", + "username-too-long": "שם משתמש ארוך מדי", "user-banned": "המשתמש חסום", - "user-too-new": "Sorry, you are required to wait %1 seconds before making your first post", - "no-category": "Category does not exist", - "no-topic": "Topic does not exist", - "no-post": "Post does not exist", - "no-group": "Group does not exist", - "no-user": "User does not exist", - "no-teaser": "Teaser does not exist", - "no-privileges": "You do not have enough privileges for this action.", - "no-emailers-configured": "No email plugins were loaded, so a test email could not be sent", + "user-too-new": "מצטערים, אתה צריך לחכות %1 שניות לפני שתוכל לפרסם את הפוסט הראשון שלך", + "no-category": "קטגוריה אינה קיימת", + "no-topic": "נושא אינו קיים", + "no-post": "פוסט אינו קיים", + "no-group": "קבוצה אינה קיימת", + "no-user": "משתמש אינו קיים", + "no-teaser": "תקציר אינו קיים", + "no-privileges": "ההרשאות שלך אינן מספיקות לביצוע פעולה זו", + "no-emailers-configured": "לא נמצאו פלאגינים למייל, לכן אין אפשרות לשלוח מייל ניסיון.", "category-disabled": "קטגוריה לא פעילה", "topic-locked": "נושא נעול", "still-uploading": "אנא המתן לסיום ההעלאות", - "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", - "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", + "content-too-short": "יש להכניס פוסט ארוך יותר. פוסטים חייבים להכיל לפחות %1 תווים.", + "content-too-long": "יש לקצר את הפוסט. פוסטים אינם יכולים להיות ארוכים מ %1 תווים.", + "title-too-short": "יש להכניס כותרת ארוכה יותר. כותרות חייבות להכיל לפחות %1 תווים.", "title-too-long": "יש לקצר את הכותרת. כותרות אינן יכולות להיות ארוכות מ %1 תווים.", - "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", - "too-many-posts-newbie": "As a new user, you can only post once every %1 seconds until you have earned %2 reputation - please wait before posting again", - "file-too-big": "Maximum allowed file size is %1 kbs - please upload a smaller file", + "too-many-posts": "אתה יכול להעלות פוסט כל %1 שניות בלבד - אנא המתן.", + "too-many-posts-newbie": "כמשתמש חדש, אתה יכול להעלות פוסט כל %1 שניות עד שצברת %2 מוניטין - אנא המתן.", + "file-too-big": "גודל קובץ מקסימלי הינו %1 קילובייט - אנא העלה קובץ קטן יותר.", "cant-vote-self-post": "לא ניתן להצביע לפוסט שלך", - "already-favourited": "You have already favourited this post", - "already-unfavourited": "You have already unfavourited this post", + "already-favourited": "כבר הוספת פוסט זה למועדפים", + "already-unfavourited": "כבר הסרת פוסט זה מהמועדפים", "cant-ban-other-admins": "אינך יכול לחסום מנהלים אחרים!", - "invalid-image-type": "Invalid image type. Allowed types are: %1", - "invalid-image-extension": "Invalid image extension", + "invalid-image-type": "פורמט תמונה לא תקין. הפורמטים המורשים הם: %1", + "invalid-image-extension": "פורמט תמונה לא תקין", "group-name-too-short": "שם הקבוצה קצר מדי", "group-already-exists": "הקבוצה כבר קיימת", "group-name-change-not-allowed": "לא ניתן לשנות את שם הקבוצה", - "group-already-member": "You are already part of this group", - "group-needs-owner": "This group requires at least one owner", - "post-already-deleted": "This post has already been deleted", - "post-already-restored": "This post has already been restored", - "topic-already-deleted": "This topic has already been deleted", - "topic-already-restored": "This topic has already been restored", + "group-already-member": "אתה כבר חבר בקבוצה זו", + "group-needs-owner": "קבוצה זו חייבת לפחות מנהל אחד", + "post-already-deleted": "פוסט זה כבר נמחק", + "post-already-restored": "פוסט זה כבר שוחזר", + "topic-already-deleted": "נושא זה כבר נמחק", + "topic-already-restored": "נושא זה כבר שוחזר", "topic-thumbnails-are-disabled": "תמונות ממוזערות לנושא אינן מאופשרות.", "invalid-file": "קובץ לא תקין", "uploads-are-disabled": "העלאת קבצים אינה מאופשרת", "upload-error": "שגיאה בהעלאה : %1", - "signature-too-long": "Sorry, your signature cannot be longer than %1 characters.", + "signature-too-long": "מצטערים, אורך החתימה המקסימלי הוא %1 תווים.", "cant-chat-with-yourself": "לא ניתן לעשות צ'אט עם עצמך!", - "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", - "too-many-messages": "You have sent too many messages, please wait awhile.", - "reputation-system-disabled": "Reputation system is disabled.", - "downvoting-disabled": "Downvoting is disabled", + "chat-restricted": "משתמש זה חסם את הודעות הצ'אט שלו ממשתמשים זרים. המשתמש חייב לעקוב אחריך לפני שתוכל לשוחח איתו בצ'אט", + "too-many-messages": "שלחת יותר מדי הודעות, אנא המתן לזמן מה.", + "reputation-system-disabled": "מערכת המוניטין לא פעילה.", + "downvoting-disabled": "היכולת להצביע נגד לא פעילה", "not-enough-reputation-to-downvote": "אין לך מספיק מוניטין כדי להוריד את הדירוג של פוסט זה", - "not-enough-reputation-to-flag": "You do not have enough reputation to flag this post", - "reload-failed": "NodeBB encountered a problem while reloading: \"%1\". NodeBB will continue to serve the existing client-side assets, although you should undo what you did just prior to reloading.", - "registration-error": "Registration Error", - "parse-error": "Something went wrong while parsing server response" + "not-enough-reputation-to-flag": "אין לך מוניטין מספק על מנת לסמן את הפוסט הזה", + "reload-failed": "אירעה תקלה ב NodeBB בזמן הטעינה של: \"%1\". המערכת תמשיך להגיש דפים קיימים, אבל כדאי שתשחזר את הפעולות שלך מהפעם האחרונה שהמערכת עבדה כראוי.", + "registration-error": "שגיאה בהרשמה", + "parse-error": "אירעה שגיאה בעת בעת ניתוח תגובת השרת" } \ No newline at end of file diff --git a/public/language/he/global.json b/public/language/he/global.json index 7a5d014492..da7f284644 100644 --- a/public/language/he/global.json +++ b/public/language/he/global.json @@ -3,10 +3,10 @@ "search": "חיפוש", "buttons.close": "סגור", "403.title": "גישה נדחתה", - "403.message": "You seem to have stumbled upon a page that you do not have access to.", - "403.login": "Perhaps you should try logging in?", + "403.message": "נראה שהגעת לעמוד שאין לך הרשאה לצפות בו", + "403.login": "נסה להתחבר.", "404.title": "לא נמצא", - "404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.", + "404.message": "נראה שהגעת לעמוד שלא קיים. חזור לעמוד הבית", "500.title": "שגיאה פנימית.", "500.message": "אופס! נראה שמשהו השתבש!", "register": "הרשמה", @@ -27,7 +27,7 @@ "header.tags": "תגיות", "header.popular": "פופולרי", "header.users": "משתמשים", - "header.groups": "Groups", + "header.groups": "קבוצות", "header.chats": "צ'אטים", "header.notifications": "התראות", "header.search": "חיפוש", @@ -74,8 +74,8 @@ "guests": "אורחים", "updated.title": "הפורום עודכן", "updated.message": "הפורום עודכן לגרסא האחרונה. נא ללחוץ כאן לעדכון הדף.", - "privacy": "Privacy", - "follow": "Follow", - "unfollow": "Unfollow", - "delete_all": "Delete All" + "privacy": "פרטיות", + "follow": "עקוב", + "unfollow": "הפסק לעקוב", + "delete_all": "מחק הכל" } \ No newline at end of file diff --git a/public/language/he/groups.json b/public/language/he/groups.json index 6dfd71256b..54f7936c08 100644 --- a/public/language/he/groups.json +++ b/public/language/he/groups.json @@ -1,21 +1,21 @@ { - "groups": "Groups", - "view_group": "View Group", - "owner": "Group Owner", - "new_group": "Create New Group", - "no_groups_found": "There are no groups to see", - "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", - "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", - "details.title": "Group Details", - "details.members": "Member List", - "details.pending": "Pending Members", - "details.has_no_posts": "This group's members have not made any posts.", - "details.latest_posts": "Latest Posts", - "details.private": "Private Group", - "details.public": "Public Group", - "details.owner_options": "Group Administration", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "groups": "קבוצות", + "view_group": "צפה בקבוצה", + "owner": "מנהל הקבוצה", + "new_group": "צור קבוצה חדשה", + "no_groups_found": "אין קבוצות לצפייה", + "cover-instructions": "גרור תמונה, הזז למיקום הרצוי ואז לחץ על שמור", + "cover-change": "שנה", + "cover-save": "שמור", + "cover-saving": "שומר", + "details.title": "פרטי הקבוצה", + "details.members": "רשימת חברי הקבוצה", + "details.pending": "חברי קבוצה הממתינים לאישור", + "details.has_no_posts": "חברי הקבוצה הזו לא העלו אף פוסט.", + "details.latest_posts": "פוסטים אחרונים", + "details.private": "קבוצה פרטית", + "details.public": "קבוצה פומבית", + "details.owner_options": "ניהול הקבוצה", + "event.updated": "פרטי הקבוצה עודכנו", + "event.deleted": "קבוצת \"%1\" נמחקה" } \ No newline at end of file diff --git a/public/language/he/modules.json b/public/language/he/modules.json index 521915ec96..43bf264e7b 100644 --- a/public/language/he/modules.json +++ b/public/language/he/modules.json @@ -1,20 +1,20 @@ { "chat.chatting_with": "שוחח עם ", - "chat.placeholder": "Type chat message here, press enter to send", + "chat.placeholder": "הקלד את הודעת הצ'אט כאן, לחץ אנטר לשליחה", "chat.send": "שלח", "chat.no_active": "אין לך צ'אטים פעילים", "chat.user_typing": "%1 מקליד ...", "chat.user_has_messaged_you": "ל%1 יש הודעה עבורך.", "chat.see_all": "צפה בכל הצ'אטים", - "chat.no-messages": "Please select a recipient to view chat message history", - "chat.recent-chats": "Recent Chats", - "chat.contacts": "Contacts", - "chat.message-history": "Message History", - "chat.pop-out": "Pop out chat", - "chat.maximize": "Maximize", - "chat.seven_days": "7 Days", - "chat.thirty_days": "30 Days", - "chat.three_months": "3 Months", + "chat.no-messages": "אנא בחר נמען על מנת לראות את היסטוריית הצ'אט איתו", + "chat.recent-chats": "צ'אטים אחרונים", + "chat.contacts": "אנשי קשר", + "chat.message-history": "היסטוריית הודעות", + "chat.pop-out": "הוצא את חלון הצ'אט", + "chat.maximize": "הרחב", + "chat.seven_days": "7 ימים", + "chat.thirty_days": "30 ימים", + "chat.three_months": "3 חודשים", "composer.user_said_in": "%1 אמר ב%2:", "composer.user_said": "%1 אמר:", "composer.discard": "האם למחוק פוסט זה?" diff --git a/public/language/he/notifications.json b/public/language/he/notifications.json index 9bc2d9c5d8..515b890810 100644 --- a/public/language/he/notifications.json +++ b/public/language/he/notifications.json @@ -2,26 +2,26 @@ "title": "התראות", "no_notifs": "אין התראות", "see_all": "צפה בכל ההתראות", - "back_to_home": "Back to %1", + "back_to_home": "חזרה ל%1", "outgoing_link": "לינק", - "outgoing_link_message": "You are now leaving %1.", - "continue_to": "Continue to %1", - "return_to": "Return to %1", - "new_notification": "New Notification", - "you_have_unread_notifications": "You have unread notifications.", - "new_message_from": "New message from %1", - "upvoted_your_post_in": "%1 has upvoted your post in %2.", - "moved_your_post": "%1 has moved your post.", - "moved_your_topic": "%1 has moved your topic.", - "favourited_your_post_in": "%1 has favourited your post in %2.", - "user_flagged_post_in": "%1 flagged a post in %2", - "user_posted_to": "%1 has posted a reply to: %2", - "user_posted_topic": "%1 has posted a new topic: %2", - "user_mentioned_you_in": "%1 mentioned you in %2", - "user_started_following_you": "%1 started following you.", - "email-confirmed": "Email Confirmed", - "email-confirmed-message": "Thank you for validating your email. Your account is now fully activated.", - "email-confirm-error": "An error occurred...", - "email-confirm-error-message": "There was a problem validating your email address. Perhaps the code was invalid or has expired.", - "email-confirm-sent": "Confirmation email sent." + "outgoing_link_message": "אתה כעת עוזב את %1.", + "continue_to": "המשך ל %1", + "return_to": "חזור ל %1", + "new_notification": "התראה חדשה", + "you_have_unread_notifications": "יש לך התראות שלא נקראו.", + "new_message_from": "הודעה חדשה מ %1", + "upvoted_your_post_in": "%1 הצביע בעד הפוסט שלך ב %2", + "moved_your_post": "%1 העביר את הפוסט שלך.", + "moved_your_topic": "%1 הזיז את הנושא שלך.", + "favourited_your_post_in": "%1 הוסיף את הפוסט שלך ב %2 למועדפים שלו.", + "user_flagged_post_in": "%1 דיווח על פוסט ב %2", + "user_posted_to": "%1 פרסם תגובה ל: %2", + "user_posted_topic": "%1 העלה נושא חדש: %2", + "user_mentioned_you_in": "%1 הזכיר אותך ב %2", + "user_started_following_you": "%1 התחיל לעקוב אחריך.", + "email-confirmed": "כתובת המייל אושרה", + "email-confirmed-message": "תודה שאישרת את כתובת המייל שלך. החשבון שלך פעיל כעת.", + "email-confirm-error": "אירעה שגיאה...", + "email-confirm-error-message": "אירעה שגיאה בעת אישור המייל שלך. ייתכן כי הקוד היה שגוי או פג תוקף.", + "email-confirm-sent": "מייל אישור נשלח." } \ No newline at end of file diff --git a/public/language/he/pages.json b/public/language/he/pages.json index 46544cf924..aaeb1fcac5 100644 --- a/public/language/he/pages.json +++ b/public/language/he/pages.json @@ -5,14 +5,15 @@ "recent": "נושאים אחרונים", "users": "משתמשים רשומים", "notifications": "התראות", - "tags": "Topics tagged under \"%1\"", + "tags": "נושאים שתויגו תחת \"%1\"", "user.edit": "עורך את %1", "user.following": "אנשים ש%1 עוקב אחריהם", "user.followers": "אנשים שעוקבים אחרי %1", "user.posts": "פוסטים שהועלו על ידי %1", "user.topics": "נושאים שנוצרו על ידי %1", + "user.groups": "הקבוצות של %1", "user.favourites": "הפוסטים המועדפים על %1", "user.settings": "הגדרות משתמש", - "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", - "maintenance.messageIntro": "Additionally, the administrator has left this message:" + "maintenance.text": "%1 כרגע תחת עבודות תחזוקה. אנא חזור בזמן מאוחר יותר.", + "maintenance.messageIntro": "בנוסף, המנהל השאיר את ההודעה הזו:" } \ No newline at end of file diff --git a/public/language/he/recent.json b/public/language/he/recent.json index 6e1cd5f811..44960c78f7 100644 --- a/public/language/he/recent.json +++ b/public/language/he/recent.json @@ -3,16 +3,16 @@ "day": "יום", "week": "שבוע", "month": "חודש", - "year": "Year", - "alltime": "All Time", + "year": "שנה", + "alltime": "כל הזמן", "no_recent_topics": "אין נושאים חדשים", - "there-is-a-new-topic": "There is a new topic.", - "there-is-a-new-topic-and-a-new-post": "There is a new topic and a new post.", - "there-is-a-new-topic-and-new-posts": "There is a new topic and %1 new posts.", - "there-are-new-topics": "There are %1 new topics.", - "there-are-new-topics-and-a-new-post": "There are %1 new topics and a new post.", - "there-are-new-topics-and-new-posts": "There are %1 new topics and %2 new posts.", - "there-is-a-new-post": "There is a new post.", - "there-are-new-posts": "There are %1 new posts.", - "click-here-to-reload": "Click here to reload." + "there-is-a-new-topic": "יש נושא חדש.", + "there-is-a-new-topic-and-a-new-post": "יש נושא ופוסט חדש.", + "there-is-a-new-topic-and-new-posts": "יש נושא ו%1 פוסטים חדשים.", + "there-are-new-topics": "יש %1 נושאים חדשים.", + "there-are-new-topics-and-a-new-post": "יש %1 נושאים ופוסט חדש.", + "there-are-new-topics-and-new-posts": "יש %1 נושאים ו %2 פוסטים חדשים.", + "there-is-a-new-post": "יש פוסט חדש.", + "there-are-new-posts": "יש %1 פוסטים חדשים.", + "click-here-to-reload": "לחץ כאן על מנת לטעון מחדש." } \ No newline at end of file diff --git a/public/language/he/reset_password.json b/public/language/he/reset_password.json index 7aa44652cd..2ed1435b18 100644 --- a/public/language/he/reset_password.json +++ b/public/language/he/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "אנא הקלד את כתובת האימייל שלך ואנו נשלח לך הוראות כיצד לאפס את חשבונך", "enter_email_address": "הכנס כתובת אימייל", "password_reset_sent": "קוד איפוס סיסמה נשלח", - "invalid_email": "מייל שגוי / כתובת מייל לא נמצאה" + "invalid_email": "מייל שגוי / כתובת מייל לא נמצאה", + "password_too_short": "הסיסמה שבחרת קצרה מדי, אנא בחר סיסמה שונה.", + "passwords_do_not_match": "הסיסמאות שהזנת אינן תואמות." } \ No newline at end of file diff --git a/public/language/he/search.json b/public/language/he/search.json index c89241d382..fec789c3be 100644 --- a/public/language/he/search.json +++ b/public/language/he/search.json @@ -1,7 +1,35 @@ { - "results_matching": "%1 result(s) matching \"%2\", (%3 seconds)", - "no-matches": "No matches found", - "in": "In", - "by": "By", - "posted-by": "Posted by" + "results_matching": "נמצאו %1 תוצאות עבור החיפוש \"%2\", (%3 שניות)", + "no-matches": "לא נמצאו תוצאות", + "in": "ב", + "by": "על ידי", + "titles": "כותרות", + "titles-posts": "כותרות ופוסטים", + "posted-by": "פורסם על-ידי", + "in-categories": "בקטגוריות", + "search-child-categories": "חפש בתת קטגוריות", + "reply-count": "כמות תגובות", + "at-least": "לפחות", + "at-most": "לכל היותר", + "post-time": "זמן הפוסט", + "newer-than": "חדש מ", + "older-than": "ישן מ", + "any-date": "כל תאריך", + "yesterday": "אתמול", + "one-week": "שבוע אחד", + "two-weeks": "שבועיים", + "one-month": "חודש אחד", + "three-months": "שלושה חודשים", + "six-months": "שישה חודשים", + "one-year": "שנה אחת", + "sort-by": "סדר על-פי", + "last-reply-time": "תאריך תגובה אחרון", + "topic-title": "כותרת הנושא", + "number-of-replies": "מספר התגובות", + "number-of-views": "מספר הצפיות", + "topic-start-date": "זמן תחילת הנושא", + "username": "שם משתמש", + "category": "קטגוריה", + "descending": "בסדר יורד", + "ascending": "בסדר עולה" } \ No newline at end of file diff --git a/public/language/he/tags.json b/public/language/he/tags.json index 94d002603f..13912500cb 100644 --- a/public/language/he/tags.json +++ b/public/language/he/tags.json @@ -2,6 +2,6 @@ "no_tag_topics": "אין פוסטים עם תגית זו.", "tags": "תגיות", "enter_tags_here": "יש להכניס כאן את התגיות. לחץ אנטר אחרי כל תגית.", - "enter_tags_here_short": "Enter tags...", + "enter_tags_here_short": "הכנס תגיות", "no_tags": "אין עדיין תגיות." } \ No newline at end of file diff --git a/public/language/he/topic.json b/public/language/he/topic.json index 2e0d4a0d2e..e16ebc08cf 100644 --- a/public/language/he/topic.json +++ b/public/language/he/topic.json @@ -1,61 +1,61 @@ { "topic": "נושא", - "topic_id": "Topic ID", - "topic_id_placeholder": "Enter topic ID", + "topic_id": "מזהה נושא", + "topic_id_placeholder": "הכנס מזהה נושא", "no_topics_found": "לא נמצאו נושאים!", "no_posts_found": "לא נמצאו פוסטים!", - "post_is_deleted": "This post is deleted!", + "post_is_deleted": "פוסט זה נמחק!", "profile": "פרופיל", "posted_by": "הפוסט הועלה על ידי %1", - "posted_by_guest": "Posted by Guest", + "posted_by_guest": "פורסם על-ידי אורח", "chat": "צ'אט", "notify_me": "קבל התראה כאשר יש תגובות חדשות בנושא זה", "quote": "ציטוט", "reply": "תגובה", "edit": "עריכה", "delete": "מחק", - "purge": "Purge", - "restore": "Restore", + "purge": "מחק הכל", + "restore": "שחזר", "move": "הזז", "fork": "פורק", "link": "לינק", "share": "Share", "tools": "כלים", "flag": "דווח", - "locked": "Locked", - "bookmark_instructions": "Click here to return to your last position or close to discard.", + "locked": "נעול", + "bookmark_instructions": "לחץ כאן על-מנת לחזור למיקום האחרון או סגור למחיקה.", "flag_title": "דווח על פוסט זה למנהל", - "flag_confirm": "Are you sure you want to flag this post?", - "flag_success": "This post has been flagged for moderation.", - "deleted_message": "This topic has been deleted. Only users with topic management privileges can see it.", + "flag_confirm": "אתה בטוח שאתה רוצה לדווח על הפוסט הזה?", + "flag_success": "התקבל דיווח על פוסט זה.", + "deleted_message": "נושא זה נמחק. רק משתמשים עם ההרשאות המתאימות יכולים לצפות בו.", "following_topic.message": "מעתה, תקבל הודעות כאשר מישהו יעלה פוסט לנושא זה.", "not_following_topic.message": "לא תקבל הודעות נוספות בנושא זה.", - "login_to_subscribe": "Please register or log in in order to subscribe to this topic.", - "markAsUnreadForAll.success": "Topic marked as unread for all.", + "login_to_subscribe": "אנא הרשם או התחבר על-מנת לעקוב אחר נושא זה.", + "markAsUnreadForAll.success": "נושא זה סומן כלא נקרא לכולם.", "watch": "עקוב", - "unwatch": "Unwatch", - "watch.title": "Be notified of new replies in this topic", - "unwatch.title": "Stop watching this topic", + "unwatch": "הפסק לעקוב", + "watch.title": "קבל התראה כאשר יש תגובות חדשות בנושא זה", + "unwatch.title": "הפסק לעקוב אחר נושא זה", "share_this_post": "שתף פוסט זה", - "thread_tools.title": "Topic Tools", + "thread_tools.title": "כלי נושא", "thread_tools.markAsUnreadForAll": "סמן כלא נקרא", "thread_tools.pin": "נעץ נושא", "thread_tools.unpin": "הסר נעץ", "thread_tools.lock": "נעל נושא", "thread_tools.unlock": "הסר נעילה", "thread_tools.move": "הזז נושא", - "thread_tools.move_all": "Move All", + "thread_tools.move_all": "הזז הכל", "thread_tools.fork": "שכפל נושא", "thread_tools.delete": "מחק נושא", - "thread_tools.delete_confirm": "Are you sure you want to delete this topic?", + "thread_tools.delete_confirm": "אתה בטוח שאתה רוצה למחוק את הנושא הזה?", "thread_tools.restore": "שחזר נושא", - "thread_tools.restore_confirm": "Are you sure you want to restore this topic?", - "thread_tools.purge": "Purge Topic", - "thread_tools.purge_confirm": "Are you sure you want to purge this topic?", - "topic_move_success": "This topic has been successfully moved to %1", - "post_delete_confirm": "Are you sure you want to delete this post?", - "post_restore_confirm": "Are you sure you want to restore this post?", - "post_purge_confirm": "Are you sure you want to purge this post?", + "thread_tools.restore_confirm": "אתה בטוח שאתה רוצה לשחזר את הנושא הזה?", + "thread_tools.purge": "מחק נושא", + "thread_tools.purge_confirm": "אתה בטוח שאתה רוצה למחוק את הנושא הזה?", + "topic_move_success": "נושא זה הועבר בהצלחה ל %1", + "post_delete_confirm": "אתה בטוח שאתה רוצה למחוק את הפוסט הזה?", + "post_restore_confirm": "אתה בטוח שאתה רוצה לשחזר את הפוסט הזה?", + "post_purge_confirm": "אתה בטוח שאתה רוצה למחוק את הפוסט הזה?", "load_categories": "טוען קטגוריות", "disabled_categories_note": "קטגוריות מבוטלות צבועות באפור", "confirm_move": "הזז", @@ -65,34 +65,34 @@ "favourites.has_no_favourites": "אין לך כרגע פוסטים מועדפים, סמן מספר פוסטים כמועדפים על מנת לראות אותם כאן!", "loading_more_posts": "טוען פוסטים נוספים", "move_topic": "הזז נושא", - "move_topics": "Move Topics", + "move_topics": "הזז נושאים", "move_post": "הזז פוסט", - "post_moved": "Post moved!", + "post_moved": "הפוסט הועבר!", "fork_topic": "שכפל נושא", "topic_will_be_moved_to": "נושא זה יועבר לקטגוריה", "fork_topic_instruction": "לחץ על הפוסטים שברצונך לשכפל", "fork_no_pids": "לא בחרת אף פוסט!", - "fork_success": "Successfully forked topic! Click here to go to the forked topic.", + "fork_success": "הפוסט שוכפל בהצלחה! לחץ כאן על מנת לעבור לפוסט המשוכפל.", "composer.title_placeholder": "הכנס את כותרת הנושא כאן...", - "composer.handle_placeholder": "Name", + "composer.handle_placeholder": "שם", "composer.discard": "מחק", "composer.submit": "שלח", - "composer.replying_to": "Replying to %1", + "composer.replying_to": "מגיב ל %1", "composer.new_topic": "נושא חדש", - "composer.uploading": "uploading...", - "composer.thumb_url_label": "Paste a topic thumbnail URL", - "composer.thumb_title": "Add a thumbnail to this topic", + "composer.uploading": "מעלה...", + "composer.thumb_url_label": "הדבק את כתובת ה URL לתמונה המוקטנת עבור הנושא", + "composer.thumb_title": "הוסף תמונה מוקטנת לנושא זה", "composer.thumb_url_placeholder": "http://example.com/thumb.png", - "composer.thumb_file_label": "Or upload a file", - "composer.thumb_remove": "Clear fields", - "composer.drag_and_drop_images": "Drag and Drop Images Here", - "more_users_and_guests": "%1 more user(s) and %2 guest(s)", - "more_users": "%1 more user(s)", - "more_guests": "%1 more guest(s)", - "users_and_others": "%1 and %2 others", - "sort_by": "Sort by", - "oldest_to_newest": "Oldest to Newest", - "newest_to_oldest": "Newest to Oldest", - "most_votes": "Most votes", - "most_posts": "Most posts" + "composer.thumb_file_label": "או העלה קובץ", + "composer.thumb_remove": "נקה שדות", + "composer.drag_and_drop_images": "גרור תמונות לכאן", + "more_users_and_guests": "%1 משתמשים ו%2 אורחים נוספים", + "more_users": "%1 משתמשים נוספים", + "more_guests": "%1 אורחים נוספים", + "users_and_others": "%1 ו%2 אחרים", + "sort_by": "סדר על-פי", + "oldest_to_newest": "מהישן לחדש", + "newest_to_oldest": "מהחדש לישן", + "most_votes": "הכי הרבה הצבעות", + "most_posts": "הכי הרבה פוסטים" } \ No newline at end of file diff --git a/public/language/he/user.json b/public/language/he/user.json index ec3d0e5b7a..e8b3a5d3a7 100644 --- a/public/language/he/user.json +++ b/public/language/he/user.json @@ -2,12 +2,12 @@ "banned": "מורחק", "offline": "לא מחובר", "username": "שם משתמש", - "joindate": "Join Date", - "postcount": "Post Count", + "joindate": "תאריך הצטרפות", + "postcount": "כמות פוסטים", "email": "כתובת אימייל", - "confirm_email": "Confirm Email", - "delete_account": "Delete Account", - "delete_account_confirm": "Are you sure you want to delete your account?
This action is irreversible and you will not be able to recover any of your data

Enter your username to confirm that you wish to destroy this account.", + "confirm_email": "אשר מייל", + "delete_account": "מחק חשבון", + "delete_account_confirm": "אתה בטוח שאתה רוצה למחוק את חשבונך?
פעולה זו לא ניתנת לשחזור ולא תוכל לגשת למידע שלך

הזן את שם המשתמש שלך על מנת לאשר שברצונך למחוק את חשבונך.", "fullname": "שם מלא", "website": "אתר", "location": "מיקום", @@ -18,7 +18,7 @@ "profile_views": "צפיות בפרופיל", "reputation": "מוניטין", "favourites": "מועדפים", - "watched": "Watched", + "watched": "נצפה", "followers": "עוקבים", "following": "עוקב אחרי", "signature": "חתימה", @@ -32,7 +32,7 @@ "edit": "ערוך", "uploaded_picture": "התמונה הועלתה", "upload_new_picture": "העלה תמונה חדשה", - "upload_new_picture_from_url": "Upload New Picture From URL", + "upload_new_picture_from_url": "העלה תמונה חדשה מ URL", "current_password": "סיסמה נוכחית", "change_password": "שנה סיסמה", "change_password_error": "סיסמה אינה תקינה!", @@ -43,28 +43,28 @@ "change_password_success": "הסיסמה שלך עודכנה!", "confirm_password": "אמת סיסמה", "password": "סיסמה", - "username_taken_workaround": "The username you requested was already taken, so we have altered it slightly. You are now known as %1", + "username_taken_workaround": "שם המשתמש שבחרת כבר תפוס, אז שינינו אותו מעט. שם המשתמש שלך כעת הוא %1", "upload_picture": "העלה תמונה", "upload_a_picture": "העלה תמונה", "image_spec": "ניתן להעלות תמונות בפורמט PNG, JPG או GIF בלבד", "max": "מקסימום", "settings": "הגדרות", "show_email": "פרסם את כתובת האימייל שלי", - "show_fullname": "Show My Full Name", - "restrict_chats": "Only allow chat messages from users I follow", - "digest_label": "Subscribe to Digest", - "digest_description": "Subscribe to email updates for this forum (new notifications and topics) according to a set schedule", - "digest_off": "Off", + "show_fullname": "הצג את שמי המלא", + "restrict_chats": "אשר הודעות צ'אט ממשתמשים שאני עוקב אחריהם בלבד", + "digest_label": "הרשם לקבלת תקציר", + "digest_description": "הרשם לקבלת עדכונים מפורום זה (התראות ונושאים חדשים) על-פי לוח זמנים קבוע מראש.", + "digest_off": "כבוי", "digest_daily": "יומי", "digest_weekly": "שבועי", "digest_monthly": "חודשי", - "send_chat_notifications": "Send an email if a new chat message arrives and I am not online", - "send_post_notifications": "Send an email when replies are made to topics I am subscribed to", + "send_chat_notifications": "שלח לי הודעה למייל כאשר הודעת צ'אט נשלחה אלי בזמן שאיני מחובר", + "send_post_notifications": "שלח לי הודעה למייל כאשר תגובות חדשות פורסמו לנושאים שאני עוקב אחריהם", "has_no_follower": "למשתמש זה אין עוקבים :(", "follows_no_one": "משתמש זה אינו עוקב אחרי אחרים :(", "has_no_posts": "המשתמש הזה עוד לא פרסם כלום.", "has_no_topics": "המשתמש טרם יצר נושאים כלשהם.", - "has_no_watched_topics": "This user didn't watch any topics yet.", + "has_no_watched_topics": "משתמש זה לא עקב אחרי אף נושא עדיין.", "email_hidden": "כתובת אימייל מוסתרת", "hidden": "מוסתר", "paginate_description": "צור עימוד לנושאים במקום לטעון את כל התוכן בעמוד אחד.", @@ -72,9 +72,9 @@ "posts_per_page": "כמות פוסטים בעמוד", "notification_sounds": "השמע צליל כאשר מתקבלת הודעה עבורך.", "browsing": "הגדרות צפייה", - "open_links_in_new_tab": "Open outgoing links in new tab?", - "enable_topic_searching": "Enable In-Topic Searching", - "topic_search_help": "If enabled, in-topic searching will override the browser's default page search behaviour and allow you to search through the entire topic, instead of what is only shown on screen.", - "follow_topics_you_reply_to": "Follow topics that you reply to.", - "follow_topics_you_create": "Follow topics you create." + "open_links_in_new_tab": "פתח לינקים חיצוניים בטאב חדש?", + "enable_topic_searching": "הפעל חיפוש בתוך נושא", + "topic_search_help": "אם מופעל, חיפוש בתוך נושא יעקוף את מנגנון החיפוש הרגיל של הדפדפן שלך על מנת לאפשר לך לחפש בתוך כל הנושא ולא רק מה שמוצג כרגע בעמוד.", + "follow_topics_you_reply_to": "עקוב אחר נושאים שהגבת עליהם.", + "follow_topics_you_create": "עקוב אחר נושאים שיצרת." } \ No newline at end of file diff --git a/public/language/he/users.json b/public/language/he/users.json index c37d6e3609..5b996d5f5d 100644 --- a/public/language/he/users.json +++ b/public/language/he/users.json @@ -5,8 +5,8 @@ "search": "חיפוש", "enter_username": "הכנס שם משתמש לחיפוש", "load_more": "טען עוד", - "users-found-search-took": "נמצאו %1 משתמש(ים)! החיפוש ארך %2 מילי שניות.", - "filter-by": "Filter By", - "online-only": "Online only", - "picture-only": "Picture only" + "users-found-search-took": "%1 משתמשים נמצאו! החיפוש ערך %2 שניות.", + "filter-by": "פלטר על-פי", + "online-only": "אונליין בלבד", + "picture-only": "תמונה בלבד" } \ No newline at end of file diff --git a/public/language/hu/email.json b/public/language/hu/email.json index eaf8595c79..8430b8ff27 100644 --- a/public/language/hu/email.json +++ b/public/language/hu/email.json @@ -9,6 +9,9 @@ "reset.text1": "Kaptunk egy kérést jelszava visszaállításához, valószínűleg azért, mert elfelejtette azt. Ha ez nem így van, hagyja figyelmen kívül ezt a levelet.", "reset.text2": "Ha szeretné, hogy továbbra alaphelyzetbe a jelszavát, kérjük kattintson az alábbi linkre:", "reset.cta": "Kattints ide a jelszavad visszaállításához", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Olvasatlan értesítéseid vannak a következőtől: %1", "digest.latest_topics": "Legutóbbi témák a következőből: %1", "digest.cta": "Kattints ide, hogy meglátogasd a következőt: %1", diff --git a/public/language/hu/error.json b/public/language/hu/error.json index 705be11958..821145775e 100644 --- a/public/language/hu/error.json +++ b/public/language/hu/error.json @@ -35,6 +35,7 @@ "topic-locked": "Téma lezárva", "still-uploading": "Please wait for uploads to complete.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/hu/pages.json b/public/language/hu/pages.json index 9dfa18ac9a..f8d1c20484 100644 --- a/public/language/hu/pages.json +++ b/public/language/hu/pages.json @@ -11,6 +11,7 @@ "user.followers": "Tagok akik követik %1 -t", "user.posts": "Hozzászólások által %1", "user.topics": "%1 által létrehozott témák", + "user.groups": "%1's Groups", "user.favourites": "%1 Kedvenc Hozzászólásai", "user.settings": "Felhasználói Beállítások", "maintenance.text": "%1 jelenleg karbantartás alatt van. Kérlek nézz vissza késöbb!", diff --git a/public/language/hu/reset_password.json b/public/language/hu/reset_password.json index d0efcfda44..3f5721d6d6 100644 --- a/public/language/hu/reset_password.json +++ b/public/language/hu/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Kérlek add meg az e-mail címedet, ahová elküldjük a további teendőket a jelszavad visszaállításával kapcsolatban.", "enter_email_address": "Email cím megadása", "password_reset_sent": "Jelszó-visszaállítás elküldve", - "invalid_email": "Helytelen E-mail cím / Nem létező E-mail cím!" + "invalid_email": "Helytelen E-mail cím / Nem létező E-mail cím!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/hu/search.json b/public/language/hu/search.json index f5df223660..6cae8bb926 100644 --- a/public/language/hu/search.json +++ b/public/language/hu/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/hu/users.json b/public/language/hu/users.json index 2f992c73b2..95e721a4d7 100644 --- a/public/language/hu/users.json +++ b/public/language/hu/users.json @@ -5,7 +5,7 @@ "search": "Keresés", "enter_username": "Írj be egy nicknevet a kereséshez", "load_more": "Több betöltése", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/id/email.json b/public/language/id/email.json index 86557a5832..481f412f23 100644 --- a/public/language/id/email.json +++ b/public/language/id/email.json @@ -9,6 +9,9 @@ "reset.text1": "Kami menerima permintan untuk mengatur ulang kata sandi anda, Ini dikarenakan anda telah lupa akan kata sandi anda. Tolong abaikan email ini jika sebaliknya.", "reset.text2": "Mohon klik link berikut untuk mengatur ulang kata sandi anda.", "reset.cta": "Klik di sini untuk mengatur ulang kata sandi anda", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Anda mempunyai notifikasi yang belum terbaca dari %1:", "digest.latest_topics": "Topik-topik terbaru dari %1", "digest.cta": "Klik di sini untuk mengunjungi %1", diff --git a/public/language/id/error.json b/public/language/id/error.json index dcce92a9bf..ce802296e2 100644 --- a/public/language/id/error.json +++ b/public/language/id/error.json @@ -35,6 +35,7 @@ "topic-locked": "Topik dikunci", "still-uploading": "Tunggu proses upload sampai selesai", "content-too-short": "Mohon masukkan posting yang lebih panjang. Posting harus memuat setidaknya %1 karakter.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Mohon masukkan judul yang lebih panjang. Judul harus memuat setidaknya %1 karakter.", "title-too-long": "Mohon masukkan judul yang lebih pendek. Judul tidak dapat melebihi %1 karakter.", "too-many-posts": "Kamu hanya dapat melakukan posting satu kali setiap %1 detik - mohon tunggu beberapa saat sebelum melakukan posting kembali", diff --git a/public/language/id/pages.json b/public/language/id/pages.json index bfedbfaa27..83b55a2b22 100644 --- a/public/language/id/pages.json +++ b/public/language/id/pages.json @@ -11,6 +11,7 @@ "user.followers": "Pengguna yang mengikuti %1", "user.posts": "Posting dibuat oleh %1", "user.topics": "Topik dibuat oleh %1", + "user.groups": "%1's Groups", "user.favourites": "Posting Favorit %1", "user.settings": "Pengaturan Pengguna", "maintenance.text": "%1 saat ini sedang dalam masa pemeliharaan. Silahkan kembali lain waktu.", diff --git a/public/language/id/reset_password.json b/public/language/id/reset_password.json index 7ae5b9e8d7..ec65c5ca68 100644 --- a/public/language/id/reset_password.json +++ b/public/language/id/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Mohon masukkan alamat emailmu dan kami akan mengirimkan mu sebuah email dengan instruksi mengenai cara pengaturan ulang akunmu.", "enter_email_address": "Masukkan Alamat Email", "password_reset_sent": "Pengaturan Kembali Kata Sandi telah DIkirim", - "invalid_email": "Email Salah / Email tidak ada!" + "invalid_email": "Email Salah / Email tidak ada!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/id/search.json b/public/language/id/search.json index af974065ab..5eb7f1f851 100644 --- a/public/language/id/search.json +++ b/public/language/id/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/id/users.json b/public/language/id/users.json index 4f7636a9c3..783d9478f3 100644 --- a/public/language/id/users.json +++ b/public/language/id/users.json @@ -5,7 +5,7 @@ "search": "Pencarian", "enter_username": "Masukkan nama pengguna untuk mencari", "load_more": "Tampilkan Lebih Banyak", - "users-found-search-took": "%1 pengguna ditemukan! Pencarian butuh waktu %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/it/email.json b/public/language/it/email.json index 8c0a1666c2..d54cf8c4cd 100644 --- a/public/language/it/email.json +++ b/public/language/it/email.json @@ -9,6 +9,9 @@ "reset.text1": "Abbiamo ricevuto una richiesta di reset della tua password, probabilmente perché l'hai dimenticata. Se non è così si prega di ignorare questa email.", "reset.text2": "Per confermare il reset della password per favore clicca il seguente link:", "reset.cta": "Clicca qui per resettare la tua password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Hai una notifica non letta da %1:", "digest.latest_topics": "Ultimi argomenti su %1", "digest.cta": "Clicca qui per visitare %1", diff --git a/public/language/it/error.json b/public/language/it/error.json index 241f9d90ea..fe207d0502 100644 --- a/public/language/it/error.json +++ b/public/language/it/error.json @@ -35,6 +35,7 @@ "topic-locked": "Discussione Bloccata", "still-uploading": "Per favore attendere il completamento degli uploads.", "content-too-short": "Inserisci un post più lungo. Il Messaggio deve contenere almeno %1 caratteri.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Inserisci un titolo più lungo. I titoli devono contenere almeno %1 caratteri.", "title-too-long": "Per favore inserire un titolo più corto, non può essere più lungo di %1 caratteri.", "too-many-posts": "È possibile inserire un Post ogni %1 secondi - si prega di attendere prima di postare di nuovo", diff --git a/public/language/it/pages.json b/public/language/it/pages.json index 38c22f82b7..72d2a3e042 100644 --- a/public/language/it/pages.json +++ b/public/language/it/pages.json @@ -11,6 +11,7 @@ "user.followers": "Persone che seguono %1", "user.posts": "Post creati da %1", "user.topics": "Discussioni create da %1", + "user.groups": "%1's Groups", "user.favourites": "Post Favoriti da %1", "user.settings": "Impostazioni Utente", "maintenance.text": "%1 è attualmente in manutenzione. Per favore ritorna più tardi.", diff --git a/public/language/it/reset_password.json b/public/language/it/reset_password.json index 9340714167..4789b7f1c1 100644 --- a/public/language/it/reset_password.json +++ b/public/language/it/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Inserisci il tuo indirizzo email e ti invieremo un'email con le istruzioni per resettare il tuo account.", "enter_email_address": "Inserisci l'Indirizzo Email", "password_reset_sent": "Password Reset Inviata", - "invalid_email": "Email invalida / L'email non esiste!" + "invalid_email": "Email invalida / L'email non esiste!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/it/search.json b/public/language/it/search.json index 6b1250cf39..9d021ec7c5 100644 --- a/public/language/it/search.json +++ b/public/language/it/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/it/users.json b/public/language/it/users.json index 3faed8adbb..44f4b4f916 100644 --- a/public/language/it/users.json +++ b/public/language/it/users.json @@ -5,7 +5,7 @@ "search": "Cerca", "enter_username": "Inserisci il nome utente da cercare", "load_more": "Carica altri", - "users-found-search-took": "%1 utente(i) trovati! La ricerca ha impiegato %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/ja/email.json b/public/language/ja/email.json index e3199a9b14..f290435e75 100644 --- a/public/language/ja/email.json +++ b/public/language/ja/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/ja/error.json b/public/language/ja/error.json index a7b4c90a77..2a4a1ebac9 100644 --- a/public/language/ja/error.json +++ b/public/language/ja/error.json @@ -35,6 +35,7 @@ "topic-locked": "スレッドがロックされた", "still-uploading": "アップロードが完成するまでお待ちください。", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "タイトルに最大 %1 文字の制限があります。", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/ja/pages.json b/public/language/ja/pages.json index e4534d567d..eb5274c6f1 100644 --- a/public/language/ja/pages.json +++ b/public/language/ja/pages.json @@ -11,6 +11,7 @@ "user.followers": "%1のフォロワー", "user.posts": "%1が作成したポスト", "user.topics": "%1が作成したスレッド", + "user.groups": "%1's Groups", "user.favourites": "%1のお気に入りポスト", "user.settings": "ユーザー設定", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/ja/reset_password.json b/public/language/ja/reset_password.json index c732e9e159..7e31c22720 100644 --- a/public/language/ja/reset_password.json +++ b/public/language/ja/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "メールアドレスを入力してください.パスワードリセットの指示をメールでご送付します。", "enter_email_address": "メールアドレスを入力してください", "password_reset_sent": "パスワードリセットのメールを送信しました", - "invalid_email": "このメールアドレスは存在しません" + "invalid_email": "このメールアドレスは存在しません", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/ja/search.json b/public/language/ja/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/ja/search.json +++ b/public/language/ja/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/ja/users.json b/public/language/ja/users.json index 9bf3d7a0d9..6d73cf0513 100644 --- a/public/language/ja/users.json +++ b/public/language/ja/users.json @@ -5,7 +5,7 @@ "search": "検索", "enter_username": "検索するユーザー名を入力してください", "load_more": "もっと表示", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/ko/email.json b/public/language/ko/email.json index a7e4ea2cfc..1c5032db35 100644 --- a/public/language/ko/email.json +++ b/public/language/ko/email.json @@ -9,6 +9,9 @@ "reset.text1": "패스워드 재설정 요청을 받았습니다. 패스워드를 분실해서 요청한 것이 아니라면 이 메일을 무시하셔도 좋습니다.", "reset.text2": "패스워드를 재설정하려면 다음 링크를 클릭하세요.", "reset.cta": "패스워드를 재설정하려면 여기를 클릭하세요.", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "%1에 읽지 않은 게시물이 있습니다.", "digest.latest_topics": "%1의 최근 주제", "digest.cta": "%1에 방문하시려면 클릭하세요.", diff --git a/public/language/ko/error.json b/public/language/ko/error.json index 88c01be5d7..fcca053185 100644 --- a/public/language/ko/error.json +++ b/public/language/ko/error.json @@ -35,6 +35,7 @@ "topic-locked": "잠긴 주제입니다.", "still-uploading": "업로드가 끝날 때까지 기다려 주세요.", "content-too-short": "게시물의 내용이 너무 짧습니다. 최소 %1자 이상이어야 합니다.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "제목이 너무 짧습니다. 최소 %1자 이상이어야 합니다.", "title-too-long": "제목은 최대 %1자로 제한됩니다.", "too-many-posts": "새 게시물 작성은 %1초 간격으로 제한됩니다 - 잠시 기다렸다가 작성해주세요.", diff --git a/public/language/ko/pages.json b/public/language/ko/pages.json index 570f5b22f5..ce1f9e5a05 100644 --- a/public/language/ko/pages.json +++ b/public/language/ko/pages.json @@ -11,6 +11,7 @@ "user.followers": "%1님을 팔로우하는 사용자", "user.posts": "%1님이 작성한 게시물", "user.topics": "%1님이 생성한 주제", + "user.groups": "%1's Groups", "user.favourites": "%1님이 좋아하는 게시물", "user.settings": "설정", "maintenance.text": "%1 사이트는 현재 점검 중입니다. 나중에 다시 방문해주세요.", diff --git a/public/language/ko/reset_password.json b/public/language/ko/reset_password.json index d229a5a931..60fe18c8e5 100644 --- a/public/language/ko/reset_password.json +++ b/public/language/ko/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "이메일 주소를 입력하면 비밀번호를 초기화하는 방법을 메일로 알려드립니다.", "enter_email_address": "여기에 이메일 주소를 입력하세요.", "password_reset_sent": "이메일이 발송되었습니다.", - "invalid_email": "올바르지 않거나 가입되지 않은 이메일입니다." + "invalid_email": "올바르지 않거나 가입되지 않은 이메일입니다.", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/ko/search.json b/public/language/ko/search.json index 391a7477ee..3905534515 100644 --- a/public/language/ko/search.json +++ b/public/language/ko/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/ko/users.json b/public/language/ko/users.json index 14f0b96551..9135621eb6 100644 --- a/public/language/ko/users.json +++ b/public/language/ko/users.json @@ -5,7 +5,7 @@ "search": "검색", "enter_username": "검색할 사용자 이름을 입력하세요.", "load_more": "더 보기", - "users-found-search-took": "%1명의 사용자를 찾았습니다! 검색에 %2 ms가 소요되었습니다.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/lt/email.json b/public/language/lt/email.json index e3199a9b14..f290435e75 100644 --- a/public/language/lt/email.json +++ b/public/language/lt/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/lt/error.json b/public/language/lt/error.json index 91f17b67bc..1951d21778 100644 --- a/public/language/lt/error.json +++ b/public/language/lt/error.json @@ -35,6 +35,7 @@ "topic-locked": "Tema užrakinta", "still-uploading": "Prašome palaukti kol bus baigti visi kėlimai į serverį", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Pavadinimas turėtų būti trumpesnis. Maksimalus leistinas ilgis- %1 simbolių.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/lt/pages.json b/public/language/lt/pages.json index 1551e325f2..338cd346f5 100644 --- a/public/language/lt/pages.json +++ b/public/language/lt/pages.json @@ -11,6 +11,7 @@ "user.followers": "Žmonės, kurie seka %1", "user.posts": "Pranešimai, kuriuos parašė %1", "user.topics": "Temos, kurias sukūrė %1", + "user.groups": "%1's Groups", "user.favourites": "Vartotojo %1 mėgstami pranešimai", "user.settings": "Vartotojo nustatymai", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/lt/reset_password.json b/public/language/lt/reset_password.json index 66192d423f..104f75e6e3 100644 --- a/public/language/lt/reset_password.json +++ b/public/language/lt/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Prašome įrašyti el. pašto adresą ir mes atsiųsime jums instrukciją, kaip atstatyti jūsų paskyrą.", "enter_email_address": "Įrašykite el. pašto adresą", "password_reset_sent": "Slaptažodžio atstatymas išsiųstas", - "invalid_email": "Klaidingas arba neegzistuojantis el. pašto adresas!" + "invalid_email": "Klaidingas arba neegzistuojantis el. pašto adresas!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/lt/search.json b/public/language/lt/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/lt/search.json +++ b/public/language/lt/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/lt/users.json b/public/language/lt/users.json index 58f5d1793e..043ca55bcc 100644 --- a/public/language/lt/users.json +++ b/public/language/lt/users.json @@ -5,7 +5,7 @@ "search": "Ieškoti", "enter_username": "Įrašykite vartotojo vardą paieškai", "load_more": "Įkelti daugiau", - "users-found-search-took": "%1 paskyra(-os)! Paieška užtruko %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/ms/email.json b/public/language/ms/email.json index 6e765e9f0b..4c5ca1adde 100644 --- a/public/language/ms/email.json +++ b/public/language/ms/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/ms/error.json b/public/language/ms/error.json index 9c50886310..3c68a1d7e5 100644 --- a/public/language/ms/error.json +++ b/public/language/ms/error.json @@ -35,6 +35,7 @@ "topic-locked": "Topic Locked", "still-uploading": "Please wait for uploads to complete.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/ms/pages.json b/public/language/ms/pages.json index 6ce4a94980..dc7c0385e9 100644 --- a/public/language/ms/pages.json +++ b/public/language/ms/pages.json @@ -11,6 +11,7 @@ "user.followers": "Pengguna yang Mengikuti %1", "user.posts": "Kiriman dibuat oleh %1", "user.topics": "Topik dibuat oleh %1", + "user.groups": "%1's Groups", "user.favourites": "Mesej Kegemaran %1", "user.settings": "Tetapan pengguna", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/ms/reset_password.json b/public/language/ms/reset_password.json index 20c519aa55..2951ed5007 100644 --- a/public/language/ms/reset_password.json +++ b/public/language/ms/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Sila masukkan alamat emel dan kami akan menghantar arahan untuk penetapan semula akaun anda", "enter_email_address": "Masukkan alamat emel", "password_reset_sent": "Penetapan semula password telah dihantar", - "invalid_email": "Emel yang tidak sah / Emel tidak wujud" + "invalid_email": "Emel yang tidak sah / Emel tidak wujud", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/ms/search.json b/public/language/ms/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/ms/search.json +++ b/public/language/ms/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/ms/users.json b/public/language/ms/users.json index 3e1a3f089b..26475bd746 100644 --- a/public/language/ms/users.json +++ b/public/language/ms/users.json @@ -5,7 +5,7 @@ "search": "Cari", "enter_username": "Masukkan nama pengguna untuk carian", "load_more": "Muat lagi", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/nb/email.json b/public/language/nb/email.json index 69fa94dcca..65e1accaee 100644 --- a/public/language/nb/email.json +++ b/public/language/nb/email.json @@ -9,6 +9,9 @@ "reset.text1": "Vi har blir bedt om å tilbakestille passordet ditt, muligens fordi du har glemt det. Hvis dette ikke stemmer kan du ignorere denne eposten.", "reset.text2": "For å fortsette med tilbakestillingen, vennligst klikk på følgende lenke:", "reset.cta": "Klikk her for å tilbakestille passordet ditt", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Du har uleste varsler fra %1:", "digest.latest_topics": "Siste emner fra %1", "digest.cta": "Klikk her for å besøke %1", diff --git a/public/language/nb/error.json b/public/language/nb/error.json index 3703ca393c..a19bdad64d 100644 --- a/public/language/nb/error.json +++ b/public/language/nb/error.json @@ -35,6 +35,7 @@ "topic-locked": "Emne låst", "still-uploading": "Vennligst vent til opplastingene blir fullført.", "content-too-short": "Vennligst skriv et lengere innlegg. Innlegg må inneholde minst %1 tegn.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Vennligst skriv en lengere tittel. Titler må inneholde minst %1 tegn.", "title-too-long": "Vennligst skriv en kortere tittel. Titler må inneholde minst %1 tegn.", "too-many-posts": "Du kan bare poste et innlegg hvert %1 sekund - vennligst vent før du poster igjen", diff --git a/public/language/nb/pages.json b/public/language/nb/pages.json index 151b1c7a79..1d657bd759 100644 --- a/public/language/nb/pages.json +++ b/public/language/nb/pages.json @@ -11,6 +11,7 @@ "user.followers": "Personer som følger %1", "user.posts": "Innlegg laget av %1", "user.topics": "Emner opprettet av %1", + "user.groups": "%1's Groups", "user.favourites": "%1 sine favoritt-innlegg", "user.settings": "Brukerinnstillinger", "maintenance.text": "%1 er for tiden under vedlikehold. Kom tilbake en annen gang.", diff --git a/public/language/nb/reset_password.json b/public/language/nb/reset_password.json index d8aab92154..ed6659abdf 100644 --- a/public/language/nb/reset_password.json +++ b/public/language/nb/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Vennligst skriv din e-post-adresse og vi vil sende den en e-post med instruksjoner om hvordan du tilbakestiller din konto.", "enter_email_address": "Skriv e-post", "password_reset_sent": "Passord-tilbakestilling sendt", - "invalid_email": "Ugyldig e-post / e-post eksisterer ikke" + "invalid_email": "Ugyldig e-post / e-post eksisterer ikke", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/nb/search.json b/public/language/nb/search.json index 8daeddcb06..053950fd9e 100644 --- a/public/language/nb/search.json +++ b/public/language/nb/search.json @@ -3,5 +3,33 @@ "no-matches": "Ingen matcher funnet", "in": "I", "by": "Av", - "posted-by": "Skapt av" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Skapt av", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/nb/users.json b/public/language/nb/users.json index a2038667ab..661479fbf1 100644 --- a/public/language/nb/users.json +++ b/public/language/nb/users.json @@ -5,7 +5,7 @@ "search": "Søk", "enter_username": "Skriv ett brukernavn for å søke", "load_more": "Last flere", - "users-found-search-took": "%1 bruker(e) funnet! Søk tok %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filtrer etter", "online-only": "Bare påloggede", "picture-only": "Bare bilde" diff --git a/public/language/nl/email.json b/public/language/nl/email.json index ec4296182c..a1f26cd2ea 100644 --- a/public/language/nl/email.json +++ b/public/language/nl/email.json @@ -9,6 +9,9 @@ "reset.text1": "Wij ontvingen een verzoek van u om uw wachtwoord te resetten. Als dat niet het geval is, kunt u deze mail negeren ", "reset.text2": "Om uw wachtwoord te resetten, klik op de volgende link", "reset.cta": "Klik hier om u wachtwoord te resetten", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "U heeft ongelezen notificaties van %1:", "digest.latest_topics": "De laatste onderwerpen van %1", "digest.cta": "Klik hier om deze website te bezoeken %1 ", diff --git a/public/language/nl/error.json b/public/language/nl/error.json index 7fa4a2f24e..8b2c37d5a1 100644 --- a/public/language/nl/error.json +++ b/public/language/nl/error.json @@ -35,6 +35,7 @@ "topic-locked": "Onderwerp gesloten", "still-uploading": "Heb even geduld totdat de alle bestanden geüpload zijn", "content-too-short": "Maak de bericht alsjeblieft wat langer. Op z'n minst %1 karakters", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Maak de titel wat langer. Op z'n minst %1 karakters", "title-too-long": "Maak de titel wat korter. Het kan niet langer zijn dan %1 karakters", "too-many-posts": "Je kan eens in de %1 seconden een bericht aanmaken. Wacht alstublieft.", diff --git a/public/language/nl/pages.json b/public/language/nl/pages.json index b567e526d1..09cda815b9 100644 --- a/public/language/nl/pages.json +++ b/public/language/nl/pages.json @@ -11,6 +11,7 @@ "user.followers": "Mensen die %1 Volgen", "user.posts": "Berichten geplaatst door %1", "user.topics": "Topics gecreëerd door %1", + "user.groups": "%1's Groups", "user.favourites": "%1's Favoriete Berichten", "user.settings": "Gebruikersinstellingen", "maintenance.text": "%1 is momenteel in onderhoud modus. Probeer later opnieuw", diff --git a/public/language/nl/reset_password.json b/public/language/nl/reset_password.json index a529b6b8f8..2bac7d3849 100644 --- a/public/language/nl/reset_password.json +++ b/public/language/nl/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Vul a.u.b. je email address in en we versturen je een email met de stappen hoe je je account reset.", "enter_email_address": "Vul uw Email Adres in", "password_reset_sent": "Wachtwoord Reset Verzonden", - "invalid_email": "Fout Email Adres / Email Adres bestaat niet!" + "invalid_email": "Fout Email Adres / Email Adres bestaat niet!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/nl/search.json b/public/language/nl/search.json index 60193a06b7..168dde5142 100644 --- a/public/language/nl/search.json +++ b/public/language/nl/search.json @@ -3,5 +3,33 @@ "no-matches": "Geen matches gevonden", "in": "in", "by": "door", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/nl/users.json b/public/language/nl/users.json index 4df6bda6f1..315b86fe31 100644 --- a/public/language/nl/users.json +++ b/public/language/nl/users.json @@ -5,7 +5,7 @@ "search": "Zoeken", "enter_username": "Vul een gebruikersnaam in om te zoeken", "load_more": "Meer Laden", - "users-found-search-took": "%1 gebruiker(s) gevonden! Zoekactie duurde %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter op", "online-only": "Online ", "picture-only": "Alleen een afbeelding" diff --git a/public/language/pl/email.json b/public/language/pl/email.json index 04816f6185..d1f327d90a 100644 --- a/public/language/pl/email.json +++ b/public/language/pl/email.json @@ -9,6 +9,9 @@ "reset.text1": "Otrzymaliśmy żądanie przywrócenia Twojego hasła. Jeśli nie żądałeś przywrócenia hasła, zignoruj ten e-mail.", "reset.text2": "Aby przywrócić swoje hasło, skorzystaj z poniższego linku:", "reset.cta": "Kliknij tu, by przywrócić swoje hasło", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Masz nowe powiadomienia od %1:", "digest.latest_topics": "Ostatnie tematy z %1", "digest.cta": "Kliknij, by odwiedzić %1", diff --git a/public/language/pl/error.json b/public/language/pl/error.json index 8929f25bfa..119a9ca553 100644 --- a/public/language/pl/error.json +++ b/public/language/pl/error.json @@ -35,6 +35,7 @@ "topic-locked": "Temat zamknięty", "still-uploading": "Poczekaj na pełne załadowanie", "content-too-short": "Proszę wpisać dłuższy post. Posty powinny zawierać co najmniej %1 znaków.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Proszę podać dłuższy tytuł. Tytuły powinny zawierać co najmniej %1 znaków.", "title-too-long": "Wpisz krótszy tytuł, nie może być dłuższy niż %1 znaków.", "too-many-posts": "Możesz wysyłać posty co %1 sekund - proszę poczekać", diff --git a/public/language/pl/pages.json b/public/language/pl/pages.json index f8afb878f5..4aad8f6c6d 100644 --- a/public/language/pl/pages.json +++ b/public/language/pl/pages.json @@ -11,6 +11,7 @@ "user.followers": "Obserwujący %1", "user.posts": "Posty napisane przez %1", "user.topics": "Wątki stworzone przez %1", + "user.groups": "%1's Groups", "user.favourites": "Ulubione posty %1", "user.settings": "Ustawienia użytkownika", "maintenance.text": "Obecnie trwają prace konserwacyjne nad %1. Proszę wrócić później.", diff --git a/public/language/pl/reset_password.json b/public/language/pl/reset_password.json index fa0affeab6..99b7518a97 100644 --- a/public/language/pl/reset_password.json +++ b/public/language/pl/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Podaj swój adres e-mail i wyślemy ci wiadomość z instrukcjami jak zresetować hasło.", "enter_email_address": "Wpisz swój adres e-mail", "password_reset_sent": "Instrukcje zostały wysłane", - "invalid_email": "Niepoprawny adres e-mail." + "invalid_email": "Niepoprawny adres e-mail.", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/pl/search.json b/public/language/pl/search.json index 472b6bf10c..c8775e8c66 100644 --- a/public/language/pl/search.json +++ b/public/language/pl/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/pl/users.json b/public/language/pl/users.json index 38ff75b928..2df9600a30 100644 --- a/public/language/pl/users.json +++ b/public/language/pl/users.json @@ -5,7 +5,7 @@ "search": "Szukaj", "enter_username": "Wpisz nazwę użytkownika", "load_more": "Więcej", - "users-found-search-took": "Znaleziono %1 użytkowników. Szukanie zajęło %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/pt_BR/email.json b/public/language/pt_BR/email.json index 04e7f76246..250bf39788 100644 --- a/public/language/pt_BR/email.json +++ b/public/language/pt_BR/email.json @@ -9,6 +9,9 @@ "reset.text1": "Nós recebemos um pedido para reconfigurar sua senha, possivelmente porque você a esqueceu. Se este não é o caso, por favor ignore este email.", "reset.text2": "Para continuar com a reconfiguração de senha, por favor clique no seguinte link:", "reset.cta": "Clique aqui para reconfigurar sua senha", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Você tem notificações não lidas de %1:", "digest.latest_topics": "Últimos tópicos de %1", "digest.cta": "Clique aqui para visitar %1", diff --git a/public/language/pt_BR/error.json b/public/language/pt_BR/error.json index c1ab421cb3..51d9f13502 100644 --- a/public/language/pt_BR/error.json +++ b/public/language/pt_BR/error.json @@ -35,6 +35,7 @@ "topic-locked": "Tópico Trancado", "still-uploading": "Aguarde a conclusão dos uploads.", "content-too-short": "Por favor digite um post mais longo. Posts devem conter no mínimo %1 caracteres.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Por favor digite um título mais longo. Títulos devem conter no mínimo %1 caracteres.", "title-too-long": "Por favor entre com um título mais curto; Títulos não podem ser maiores que %1 caracteres.", "too-many-posts": "Você pode postar apenas uma vez a cada %1 segundos - por favor aguarde antes de postar novamente", diff --git a/public/language/pt_BR/pages.json b/public/language/pt_BR/pages.json index a65c95781b..ae42c35f0f 100644 --- a/public/language/pt_BR/pages.json +++ b/public/language/pt_BR/pages.json @@ -11,6 +11,7 @@ "user.followers": "Pessoas que Seguem %1", "user.posts": "Posts feitos por %1", "user.topics": "Tópicos criados por %1", + "user.groups": "%1's Groups", "user.favourites": "Posts Favoritos de %1", "user.settings": "Configurações de Usuário", "maintenance.text": "%1 está atualmente sob manutenção. Por favor retorne em outro momento.", diff --git a/public/language/pt_BR/reset_password.json b/public/language/pt_BR/reset_password.json index 7646899cd1..bf96416678 100644 --- a/public/language/pt_BR/reset_password.json +++ b/public/language/pt_BR/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Por favor digite seu endereço de email e nós iremos lhe enviar em email com instruções de como reconfigurar a sua conta.", "enter_email_address": "Digite seu Email", "password_reset_sent": "Reconfiguração de Senha Enviada", - "invalid_email": "Email Inválido / Email não existe!" + "invalid_email": "Email Inválido / Email não existe!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/pt_BR/search.json b/public/language/pt_BR/search.json index f4d633ffd7..9f10c0970b 100644 --- a/public/language/pt_BR/search.json +++ b/public/language/pt_BR/search.json @@ -3,5 +3,33 @@ "no-matches": "Nenhum resultado encontrado", "in": "Em", "by": "Por", - "posted-by": "Postado por" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Postado por", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/pt_BR/users.json b/public/language/pt_BR/users.json index dc447048a0..32edc568f5 100644 --- a/public/language/pt_BR/users.json +++ b/public/language/pt_BR/users.json @@ -5,7 +5,7 @@ "search": "Procurar", "enter_username": "Digite um nome de usuário para procurar", "load_more": "Carregar Mais", - "users-found-search-took": "%1 usuário(s) encontrado(s)! A pesquisa demorou %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filtrar Por", "online-only": "Apenas Online", "picture-only": "Apenas foto" diff --git a/public/language/ro/email.json b/public/language/ro/email.json index 0e3a1da8ab..25f9723466 100644 --- a/public/language/ro/email.json +++ b/public/language/ro/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "Pentru a continua cu resetarea parolei, te rugăm sa apeși pe următorul link:", "reset.cta": "Apasă aici pentru a-ți reseta parola", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Ultimele mesaje de la %1", "digest.cta": "Apasă aici pentru a vizita %1", diff --git a/public/language/ro/error.json b/public/language/ro/error.json index 06cad8ebe8..1e7de8b50b 100644 --- a/public/language/ro/error.json +++ b/public/language/ro/error.json @@ -35,6 +35,7 @@ "topic-locked": "Subiect Închis", "still-uploading": "Te rugăm să aștepți până se termină uploadul.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Te rugăm să introduci un titlu mai scurt. Titlurile nu pot fi mai lungi de %1 caractere.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/ro/pages.json b/public/language/ro/pages.json index c3b65dfd23..141c5fb1df 100644 --- a/public/language/ro/pages.json +++ b/public/language/ro/pages.json @@ -11,6 +11,7 @@ "user.followers": "Utilizatori care îl urmăresc pe %1", "user.posts": "Mesaje postate de %1", "user.topics": "Subiecte create de %1", + "user.groups": "%1's Groups", "user.favourites": "Mesajele favorite ale lui %1", "user.settings": "Setări Utilizator", "maintenance.text": "%1 este momentan în mentenanță. Întoarce-te în curând!", diff --git a/public/language/ro/reset_password.json b/public/language/ro/reset_password.json index b4ae4564f8..d9edc5c856 100644 --- a/public/language/ro/reset_password.json +++ b/public/language/ro/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Te rugăm sa introduci adresa ta de email și îți vom trimite un email cu instrucțiuni pentru a îți reseta contul tău de utilizator.", "enter_email_address": "Introdu adresă de email", "password_reset_sent": "Emailul pentru resetarea parolei a fost trimis", - "invalid_email": "Adresă de email invalidă / Adresa de email nu există!" + "invalid_email": "Adresă de email invalidă / Adresa de email nu există!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/ro/search.json b/public/language/ro/search.json index 35c5b72b74..cdae3636ce 100644 --- a/public/language/ro/search.json +++ b/public/language/ro/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/ro/users.json b/public/language/ro/users.json index 065d2b07e2..4ef70026a8 100644 --- a/public/language/ro/users.json +++ b/public/language/ro/users.json @@ -5,7 +5,7 @@ "search": "Căutare", "enter_username": "Introdu un nume de utilizator pentru a căuta", "load_more": "Încarcă mai multe", - "users-found-search-took": "%1 utilizator(i) găsit! Căutarea a durat %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/ru/email.json b/public/language/ru/email.json index 9b070ed2b2..eed54608d0 100644 --- a/public/language/ru/email.json +++ b/public/language/ru/email.json @@ -9,6 +9,9 @@ "reset.text1": "Мы получили запрос на сброс Вашего пароля. Если Вы не подавали запрос, пожалуйста, проигнорируйте это сообщение.", "reset.text2": "Для продолжения процедуры изменения пароля, пожалуйста, перейдите по ссылке:", "reset.cta": "Кликните здесь для изменения пароля", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "У Вас непрочитанные уведомления от %1:", "digest.latest_topics": "Последние темы %1", "digest.cta": "Кликните здесь для просмотра %1", diff --git a/public/language/ru/error.json b/public/language/ru/error.json index d6ac5e2d25..5683d863d1 100644 --- a/public/language/ru/error.json +++ b/public/language/ru/error.json @@ -35,6 +35,7 @@ "topic-locked": "Тема закрыта", "still-uploading": "Пожалуйста, подождите завершения загрузки.", "content-too-short": "Пост должен содержать минимум %1 симв.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Заголовок должен содержать минимум %1 симв.", "title-too-long": "Заголовок не может быть длиннее %1 символов.", "too-many-posts": "Вы можете делать пост один раз в %1 сек.", diff --git a/public/language/ru/pages.json b/public/language/ru/pages.json index 85348af836..f8a014193b 100644 --- a/public/language/ru/pages.json +++ b/public/language/ru/pages.json @@ -11,6 +11,7 @@ "user.followers": "Читают %1", "user.posts": "Пост написан %1", "user.topics": "Темы созданы %1", + "user.groups": "%1's Groups", "user.favourites": "Избранные сообщения %1", "user.settings": "Настройки", "maintenance.text": "%1 в настоящее время на обслуживании. Пожалуйста, возвращайтесь позже.", diff --git a/public/language/ru/reset_password.json b/public/language/ru/reset_password.json index fdcb497d10..c9b523cf2e 100644 --- a/public/language/ru/reset_password.json +++ b/public/language/ru/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Пожалуйста введите ваш email адрес и мы отправим Вам письмо с инструкцией восстановления пароля.", "enter_email_address": "Введите Email адрес", "password_reset_sent": "Пароль Отправлен", - "invalid_email": "Неверный Email / Email не существует!" + "invalid_email": "Неверный Email / Email не существует!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/ru/search.json b/public/language/ru/search.json index aeb1235df2..f6ecb8d611 100644 --- a/public/language/ru/search.json +++ b/public/language/ru/search.json @@ -1,7 +1,35 @@ { "results_matching": "%1 результатов по фразе \"%2\", (%3 секунды) ", - "no-matches": "No matches found", + "no-matches": "Совпадений не найдено", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/ru/users.json b/public/language/ru/users.json index 78251703d2..e4253bcf62 100644 --- a/public/language/ru/users.json +++ b/public/language/ru/users.json @@ -5,7 +5,7 @@ "search": "Поиск", "enter_username": "Введите имя пользователя для поиска", "load_more": "Загрузить еще", - "users-found-search-took": "Нашел %1 пользователя(ей)! Поиск занял %2 мс.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/sc/email.json b/public/language/sc/email.json index e3199a9b14..f290435e75 100644 --- a/public/language/sc/email.json +++ b/public/language/sc/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/sc/error.json b/public/language/sc/error.json index 6079502fae..9bbcf03247 100644 --- a/public/language/sc/error.json +++ b/public/language/sc/error.json @@ -35,6 +35,7 @@ "topic-locked": "Topic Locked", "still-uploading": "Please wait for uploads to complete.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/sc/pages.json b/public/language/sc/pages.json index 4ccd57cfd2..0f846179c3 100644 --- a/public/language/sc/pages.json +++ b/public/language/sc/pages.json @@ -11,6 +11,7 @@ "user.followers": "Gente chi Sighit %1", "user.posts": "Arresonos fatos dae %1", "user.topics": "Topics created by %1", + "user.groups": "%1's Groups", "user.favourites": "Arresonos Preferidos de %1", "user.settings": "Sèberos de Impitadore", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/sc/reset_password.json b/public/language/sc/reset_password.json index 877f9c716e..d86b716c31 100644 --- a/public/language/sc/reset_password.json +++ b/public/language/sc/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Pro praghere pone s'indiritzu email tuo e t'amus a imbiare un'email cun is istrutziones pro torrare a assentare s'intrada tua.", "enter_email_address": "Pone s'Indiritzu Email", "password_reset_sent": "Còdighe pro Torrare a Assentare sa Password Imbiadu", - "invalid_email": "Email Non Bàlida / Email chi no esistit!" + "invalid_email": "Email Non Bàlida / Email chi no esistit!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/sc/search.json b/public/language/sc/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/sc/search.json +++ b/public/language/sc/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/sc/users.json b/public/language/sc/users.json index 56b67f30f8..19e6cfe95f 100644 --- a/public/language/sc/users.json +++ b/public/language/sc/users.json @@ -5,7 +5,7 @@ "search": "Chirca", "enter_username": "Pone unu nùmene de impitadore de chircare", "load_more": "Càrriga de prus", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/sk/email.json b/public/language/sk/email.json index e3199a9b14..f290435e75 100644 --- a/public/language/sk/email.json +++ b/public/language/sk/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "To continue with the password reset, please click on the following link:", "reset.cta": "Click here to reset your password", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "You have unread notifications from %1:", "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", diff --git a/public/language/sk/error.json b/public/language/sk/error.json index 92f07fce4c..0ca1924e76 100644 --- a/public/language/sk/error.json +++ b/public/language/sk/error.json @@ -35,6 +35,7 @@ "topic-locked": "Uzamknutá téma", "still-uploading": "Prosím čakajte na dokončenie nahrávania", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Prosím uvedťe kratší názov. Názov nesmie byť dlhší ako 1 % znakov", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/sk/pages.json b/public/language/sk/pages.json index bcc524ed0d..c54ac7e71f 100644 --- a/public/language/sk/pages.json +++ b/public/language/sk/pages.json @@ -11,6 +11,7 @@ "user.followers": "Užívatelia následujúci %1", "user.posts": "Príspevky od %1", "user.topics": "Téma vytvorená %1\n", + "user.groups": "%1's Groups", "user.favourites": "%1's obľubených príspevkov", "user.settings": "Užívatelské nadstavenie", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/sk/reset_password.json b/public/language/sk/reset_password.json index bceaea8148..2391c09cae 100644 --- a/public/language/sk/reset_password.json +++ b/public/language/sk/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Zadajte svoju emailovú adresu a my Vám pošleme informácie, ako môžete obnoviť svoje heslo.", "enter_email_address": "Zadajte e-mail", "password_reset_sent": "Obnova hesla odoslaná", - "invalid_email": "Zlý email / Email neexistuje!" + "invalid_email": "Zlý email / Email neexistuje!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/sk/search.json b/public/language/sk/search.json index c89241d382..a04eb4fc1e 100644 --- a/public/language/sk/search.json +++ b/public/language/sk/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/sk/users.json b/public/language/sk/users.json index 56188b953e..819f861de7 100644 --- a/public/language/sk/users.json +++ b/public/language/sk/users.json @@ -5,7 +5,7 @@ "search": "Vyhľadávať", "enter_username": "Zadaj užívateľské meno k hľadaniu", "load_more": "Načítať dalšie", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/sv/email.json b/public/language/sv/email.json index b6ef31353f..808c73caa8 100644 --- a/public/language/sv/email.json +++ b/public/language/sv/email.json @@ -9,6 +9,9 @@ "reset.text1": "Vi fick en förfrågan om att återställa ditt lösenord, möjligen för att du har glömt det. Om detta inte är fallet, så kan du bortse från det här epostmeddelandet. ", "reset.text2": "För att fortsätta med återställning av lösenordet så kan du klicka på följande länk:", "reset.cta": "Klicka här för att återställa ditt lösenord", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Du har olästa notiser från %1:", "digest.latest_topics": "Senaste ämnen från %1", "digest.cta": "Klicka här för att besöka %1", diff --git a/public/language/sv/error.json b/public/language/sv/error.json index d1d82a2f0d..bf9769aa41 100644 --- a/public/language/sv/error.json +++ b/public/language/sv/error.json @@ -35,6 +35,7 @@ "topic-locked": "Ämnet låst", "still-uploading": "Vänta medan uppladdningen slutförs.", "content-too-short": "Skriv ett längre inlägg. Inlägget måste ha minst %1 tecken.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Skriv en längre rubrik. Rubriken måste ha minst %1 tecken.", "title-too-long": "Skriv in en kortare rubrik. Rubriker får inte vara längre än %1 tecken.", "too-many-posts": "Du kan endast skapa inlägg var %1:e sekund - vänta ett tag innan du försöker skapa ett nytt inlägg", diff --git a/public/language/sv/pages.json b/public/language/sv/pages.json index 2082249d8c..f7a4904a84 100644 --- a/public/language/sv/pages.json +++ b/public/language/sv/pages.json @@ -11,6 +11,7 @@ "user.followers": "Personer som följer %1", "user.posts": "Inlägg skapat av %1", "user.topics": "Ämnen skapade av %1", + "user.groups": "%1's Groups", "user.favourites": "%1's favorit-inlägg", "user.settings": "Avnändarinställningar", "maintenance.text": "%1 genomgår underhåll just nu. Vänligen kom tillbaka lite senare.", diff --git a/public/language/sv/reset_password.json b/public/language/sv/reset_password.json index 03682d812e..a3771a31b4 100644 --- a/public/language/sv/reset_password.json +++ b/public/language/sv/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Var god fyll i din epost-adress så får du snart en epost med instruktioner hur du återsätller ditt konto.", "enter_email_address": "Skriv in epostadress", "password_reset_sent": "Lösenordsåterställning skickad", - "invalid_email": "Felaktig epost / Epost finns inte!" + "invalid_email": "Felaktig epost / Epost finns inte!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/sv/search.json b/public/language/sv/search.json index 193ea99480..0e4e831f93 100644 --- a/public/language/sv/search.json +++ b/public/language/sv/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/sv/users.json b/public/language/sv/users.json index 2b370c1146..591a32c344 100644 --- a/public/language/sv/users.json +++ b/public/language/sv/users.json @@ -5,7 +5,7 @@ "search": "Sök", "enter_username": "Ange ett användarnamn för att söka", "load_more": "Ladda fler", - "users-found-search-took": "%1 användare hittades! Sökningen tog %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/th/email.json b/public/language/th/email.json index 18bf7c5d1f..d91ba43963 100644 --- a/public/language/th/email.json +++ b/public/language/th/email.json @@ -9,6 +9,9 @@ "reset.text1": "We received a request to reset your password, possibly because you have forgotten it. If this is not the case, please ignore this email.", "reset.text2": "เพื่อดำเนินการตั้งรหัสผ่านใหม่ต่อไป, โปรดกดที่ลิ้งค์นี้:", "reset.cta": "กดตรงนี้เพื่อตั้งรหัสผ่านใหม่", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "คุณมีข้อความแจ้งเตือนที่ยังไม่ได้อ่านจาก %1:", "digest.latest_topics": "หัวข้อสนทนาล่าสุดจาก %1", "digest.cta": "กดตรงนี้เพื่อเข้าดู %1", diff --git a/public/language/th/error.json b/public/language/th/error.json index 55dc809071..05985e9b49 100644 --- a/public/language/th/error.json +++ b/public/language/th/error.json @@ -35,6 +35,7 @@ "topic-locked": "Topic Locked", "still-uploading": "Please wait for uploads to complete.", "content-too-short": "Please enter a longer post. Posts should contain at least %1 characters.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Please enter a longer title. Titles should contain at least %1 characters.", "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", diff --git a/public/language/th/pages.json b/public/language/th/pages.json index a227f62340..44f8b127e1 100644 --- a/public/language/th/pages.json +++ b/public/language/th/pages.json @@ -11,6 +11,7 @@ "user.followers": "ผู้ใช้ที่ติดตาม %1", "user.posts": "กระทู้โดย %1", "user.topics": "Topics created by %1", + "user.groups": "%1's Groups", "user.favourites": "กระทู้ที่ %1 ชอบ", "user.settings": "ตั้งค่าผู้ใช้", "maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.", diff --git a/public/language/th/reset_password.json b/public/language/th/reset_password.json index 2b12834604..499f2f7136 100644 --- a/public/language/th/reset_password.json +++ b/public/language/th/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "กรุณาใส่อีเมลของคุณ เราจะส่งอีเมลให้คุณพร้อมคำแนะนำเกี่ยวกับวิธีการรีเซ็ตบัญชีของคุณ", "enter_email_address": "ใส่อีเมล์", "password_reset_sent": "รหัสรีเซ็ตถูกส่งออกไปแล้ว", - "invalid_email": "อีเมล์ไม่ถูกต้อง / อีเมล์ไม่มีอยู่!" + "invalid_email": "อีเมล์ไม่ถูกต้อง / อีเมล์ไม่มีอยู่!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/th/search.json b/public/language/th/search.json index 973ff03e13..4e865998e1 100644 --- a/public/language/th/search.json +++ b/public/language/th/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/th/users.json b/public/language/th/users.json index a3dddb41fd..542689e182 100644 --- a/public/language/th/users.json +++ b/public/language/th/users.json @@ -5,7 +5,7 @@ "search": "ค้นหา", "enter_username": "ใส่ชื่อผู้ใช้เพื่อค้นหา", "load_more": "โหลดเพิ่มเติม", - "users-found-search-took": "%1 user(s) found! Search took %2 ms.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/tr/category.json b/public/language/tr/category.json index f29f0c81d0..ba1c4f34ef 100644 --- a/public/language/tr/category.json +++ b/public/language/tr/category.json @@ -1,7 +1,7 @@ { "new_topic_button": "Yeni Başlık", "no_topics": " Bu kategoride hiç konu yok.
Yeni bir konu açmak istemez misiniz?", - "browsing": "dolaşıyor", + "browsing": "gözden geçiriliyor", "no_replies": "Kimse yanıtlamadı", "share_this_category": "Bu kategoriyi paylaş", "ignore": "Yoksay" diff --git a/public/language/tr/email.json b/public/language/tr/email.json index c69e7d0c8f..350df09f81 100644 --- a/public/language/tr/email.json +++ b/public/language/tr/email.json @@ -9,6 +9,9 @@ "reset.text1": "Şifrenizi değiştirmek istediğinize dair bir ileti aldık. Eğer böyle bir istek göndermediyseniz, lütfen bu e-postayı görmezden gelin.", "reset.text2": "Parola değiştirme işlemine devam etmek için aşağıdaki bağlantıya tıklayın:", "reset.cta": "Parolanızı değiştirmek için buraya tıklayın", + "reset.notify.subject": "Şifre başarıyla değiştirildi", + "reset.notify.text1": "Şifrenizin %1 zamanında başarı ile değiştirildiğini bildirmek isteriz.", + "reset.notify.text2": "Bunu siz yetkilendirmediyseniz, lütfen hiç vakit kaybetmeden site yöneticisine bu durumu bildiriniz.", "digest.notifications": "Okunmamış bazı bildirimleriniz var", "digest.latest_topics": "En güncel konular", "digest.cta": "Ziyaret etmek için buraya tıklayın", @@ -17,8 +20,8 @@ "notif.chat.subject": "Okunmamış bazı iletileriniz var", "notif.chat.cta": "Sohbete devam etmek için buraya tıklayın", "notif.chat.unsub.info": "Bu bildirim şectiğiniz ayarlar yüzünden gönderildi.", - "notif.post.cta": "Click here to read the full topic", - "notif.post.unsub.info": "This post notification was sent to you due to your subscription settings.", + "notif.post.cta": "Konunun tamamını okumak için buraya tıklayın", + "notif.post.unsub.info": "Bu yazı bildirimi size abonelik ayarlarınız nedeni ile gönderilmiştir.", "test.text1": "Bu ileti NodeBB e-posta ayarlarınızın doğru çalışıp çalışmadığını kontrol etmek için gönderildi.", "unsub.cta": "Buraya tıklayarak ayarlarınızı değiştirebilirsiniz.", "closing": "Teşekkürler!" diff --git a/public/language/tr/error.json b/public/language/tr/error.json index 4ab34132fc..a18f42652b 100644 --- a/public/language/tr/error.json +++ b/public/language/tr/error.json @@ -18,7 +18,7 @@ "username-taken": "Kullanıcı İsmi Alınmış", "email-taken": "E-posta Alınmış", "email-not-confirmed": "E-postanız onaylanmamış, onaylamak için lütfen buraya tıklayın.", - "email-not-confirmed-chat": "You are unable to chat until your email is confirmed", + "email-not-confirmed-chat": "Email adresiniz doğrulanmadan sohbet edemezsiniz.", "username-too-short": "Kullanıcı ismi çok kısa", "username-too-long": "Kullanıcı ismi çok uzun.", "user-banned": "Kullanıcı Yasaklı", @@ -35,6 +35,7 @@ "topic-locked": "Başlık Kilitli", "still-uploading": "Lütfen yüklemelerin bitmesini bekleyin.", "content-too-short": "Lütfen daha uzun bir ileti girin. En az %1 karakter.", + "content-too-long": "Lütfen daha kısa bir yayın girin. Yayınlar %1 karakterden uzun olamaz.", "title-too-short": "Lütfen daha uzun bir başlık girin. En az %1 karakter.", "title-too-long": "Lütfen daha kısa bir başlık girin. Başlıklar %1 karakterden uzun olamaz.", "too-many-posts": "Sadece %1 saniyede bir ileti gönderebilirsiniz.", @@ -44,13 +45,13 @@ "already-favourited": "Bu iletiyi zaten favorilerinize eklediniz", "already-unfavourited": "Bu iletiyi zaten favorilerinizden çıkardınız", "cant-ban-other-admins": "Başka yöneticileri yasaklayamazsınız!", - "invalid-image-type": "Invalid image type. Allowed types are: %1", - "invalid-image-extension": "Invalid image extension", + "invalid-image-type": "Geçersiz resim uzantısı. Izin verilen uzantılar: %1", + "invalid-image-extension": "Geçersiz resim uzantısı", "group-name-too-short": "Grup ismi çok kısa", "group-already-exists": "Grup zaten var", "group-name-change-not-allowed": "Grup ismini değiştiremezsiniz", - "group-already-member": "You are already part of this group", - "group-needs-owner": "This group requires at least one owner", + "group-already-member": "Bu grubun zaten bir parçasısınız.", + "group-needs-owner": "Bu grubu en az bir kişi sahiplenmesi gerekiyor", "post-already-deleted": "İleti zaten silinmiş", "post-already-restored": "İleti zaten geri getirilmiş", "topic-already-deleted": "Başlık zaten silinmiş", @@ -62,12 +63,12 @@ "signature-too-long": "İmza en fazla %1 karakter olabilir!", "cant-chat-with-yourself": "Kendinizle sohbet edemezsiniz!", "chat-restricted": "Bu kullanıcı sohbet ayarlarını kısıtlamış. Bu kişiye mesaj gönderebilmeniz için sizi takip etmeleri gerekiyor", - "too-many-messages": "You have sent too many messages, please wait awhile.", + "too-many-messages": "Ardı ardına çok fazla mesaj yolladınız, lütfen biraz bekleyiniz.", "reputation-system-disabled": "Saygınlık sistemi kapatılmış.", "downvoting-disabled": "Aşagı oylama kapatılmış", "not-enough-reputation-to-downvote": "Bu iletiyi aşagı oylamak için yeterince saygınlığınız yok.", "not-enough-reputation-to-flag": "Bu iletiyi bayraklamak için yeterince saygınlığınız yok", "reload-failed": "NodeBB tekrar yüklenirken bir sorunla karşılaştı: “%1“. NodeBB varolan dosyaları servis etmeye devam edecek.", "registration-error": "Kayıt Hatası", - "parse-error": "Something went wrong while parsing server response" + "parse-error": "Sunucu yanıtı çözümlemesi sırasında bir şeyler ters gitti" } \ No newline at end of file diff --git a/public/language/tr/global.json b/public/language/tr/global.json index 152aba5d0e..cd2e8e18c9 100644 --- a/public/language/tr/global.json +++ b/public/language/tr/global.json @@ -3,10 +3,10 @@ "search": "Arama", "buttons.close": "Kapat", "403.title": "Erişim Engellendi", - "403.message": "You seem to have stumbled upon a page that you do not have access to.", - "403.login": "Perhaps you should try logging in?", + "403.message": "Erişim izniniz olmayan bir sayfaya denk gelmiş gibisiniz.", + "403.login": "Belki de tekrar giriş yapmayı denersiniz?", "404.title": "Bulunamadı", - "404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.", + "404.message": "Erişim izniniz olmayan bir sayfaya denk gelmiş gibisiniz.Anasayfaya geri dönün.", "500.title": "Dahili hata.", "500.message": "Ups! Bir şeyler ters gitti sanki!", "register": "Kayıt Ol", @@ -27,7 +27,7 @@ "header.tags": "Etiketler", "header.popular": "Popüler", "header.users": "Kullanıcılar", - "header.groups": "Groups", + "header.groups": "Gruplar", "header.chats": "Sohbetler", "header.notifications": "Bildirimler", "header.search": "Arama", @@ -75,7 +75,7 @@ "updated.title": "Forum güncellendi", "updated.message": "Bu forum şu anda güncellendi. Sayfayı tekrar yüklemek için buraya tıklayın.", "privacy": "Gizlilik", - "follow": "Follow", - "unfollow": "Unfollow", + "follow": "Takip et", + "unfollow": "Takip etmeyi bırak", "delete_all": "Hepsini Sil" } \ No newline at end of file diff --git a/public/language/tr/groups.json b/public/language/tr/groups.json index d2c411228d..e174ef10ab 100644 --- a/public/language/tr/groups.json +++ b/public/language/tr/groups.json @@ -1,21 +1,21 @@ { "groups": "Guruplar", "view_group": "Grubu Gör", - "owner": "Group Owner", - "new_group": "Create New Group", - "no_groups_found": "There are no groups to see", - "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", - "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "owner": "Grup Kurucusu", + "new_group": "Yeni Grup Oluştur", + "no_groups_found": "Henüz hiç grup yok", + "cover-instructions": "Bir fotoğrafı Sürükleyin ve Bırakın, uygun yere sürükleyip Kaydet'e tıklayın.", + "cover-change": "Değiştir", + "cover-save": "Kaydet", + "cover-saving": "Kaydediliyor", "details.title": "Grup Detayları", "details.members": "Üye Listesi", - "details.pending": "Pending Members", + "details.pending": "Üyeler bekleniyor", "details.has_no_posts": "Bu grubun üyeleri henüz bir ileti göndermedi.", "details.latest_posts": "En son iletiler", - "details.private": "Private Group", - "details.public": "Public Group", - "details.owner_options": "Group Administration", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "details.private": "Özel Grup", + "details.public": "Herkese Açık Grup", + "details.owner_options": "Grup Yöneticisi", + "event.updated": "Grup detayları güncellenmiştir", + "event.deleted": "\"%1\" grubu silinmiş" } \ No newline at end of file diff --git a/public/language/tr/pages.json b/public/language/tr/pages.json index e3d1cf9cf8..5171f4232f 100644 --- a/public/language/tr/pages.json +++ b/public/language/tr/pages.json @@ -11,6 +11,7 @@ "user.followers": "%1 takip edenler", "user.posts": "%1 tarafından gönderilen iletiler", "user.topics": "%1 tarafından gönderilen başlıklar", + "user.groups": "%1 Kişisine Ait Gruplar", "user.favourites": "%1'in Favori İletileri", "user.settings": "Kullanıcı Ayarları", "maintenance.text": "%1 şu anda bakımda. Lütfen bir süre sonra tekrar deneyin.", diff --git a/public/language/tr/recent.json b/public/language/tr/recent.json index 4773c22dfd..a1af8adb56 100644 --- a/public/language/tr/recent.json +++ b/public/language/tr/recent.json @@ -6,13 +6,13 @@ "year": "Yıl", "alltime": "Hepsi", "no_recent_topics": "Güncel konular yok.", - "there-is-a-new-topic": "There is a new topic.", - "there-is-a-new-topic-and-a-new-post": "There is a new topic and a new post.", - "there-is-a-new-topic-and-new-posts": "There is a new topic and %1 new posts.", - "there-are-new-topics": "There are %1 new topics.", - "there-are-new-topics-and-a-new-post": "There are %1 new topics and a new post.", - "there-are-new-topics-and-new-posts": "There are %1 new topics and %2 new posts.", - "there-is-a-new-post": "There is a new post.", - "there-are-new-posts": "There are %1 new posts.", - "click-here-to-reload": "Click here to reload." + "there-is-a-new-topic": "Yeni bir konu mevcut.", + "there-is-a-new-topic-and-a-new-post": "Yeni bir konu ve yayın mevcut.", + "there-is-a-new-topic-and-new-posts": "Bir adet yeni konu ve %1 adet yeni yayın var.", + "there-are-new-topics": "%1 adet yeni konu mevcut.", + "there-are-new-topics-and-a-new-post": "%1 adet yeni konu ve bir adet yeni yayın mevcut.", + "there-are-new-topics-and-new-posts": "%1 adet yeni konu %2 adet yeni yayın mevcut.", + "there-is-a-new-post": "Yeni bir yayın mevcut.", + "there-are-new-posts": "%1 adet yeni yayın mevcut.", + "click-here-to-reload": "Yenilemek için buraya tıklayın." } \ No newline at end of file diff --git a/public/language/tr/reset_password.json b/public/language/tr/reset_password.json index 0eb0497ee3..60f0346516 100644 --- a/public/language/tr/reset_password.json +++ b/public/language/tr/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Lütfen e-posta adresinizi girin , size hesabınızı nasıl sıfırlayacağınızı anlatan bir e-posta gönderelim", "enter_email_address": "E-posta Adresinizi girin", "password_reset_sent": "Şifre Yenilemesi Gönderildi", - "invalid_email": "Geçersiz E-posta / E-posta mevcut değil!" + "invalid_email": "Geçersiz E-posta / E-posta mevcut değil!", + "password_too_short": "Girdiğiniz şifre çok kısa, lütfen farklı bir şifre seçiniz.", + "passwords_do_not_match": "Girdiğiniz iki şifre birbirine uymuyor." } \ No newline at end of file diff --git a/public/language/tr/search.json b/public/language/tr/search.json index d3c5da5c91..0d079ffe4a 100644 --- a/public/language/tr/search.json +++ b/public/language/tr/search.json @@ -1,7 +1,35 @@ { "results_matching": "%1 tane “%2“ bulundu (%3 saniye)", - "no-matches": "No matches found", - "in": "In", - "by": "By", - "posted-by": "Posted by" + "no-matches": "Hiç eşleşme bulunamadı", + "in": "Konum:", + "by": "Kim Tarafından :", + "titles": "Başlıklar", + "titles-posts": "Başlıklar ve Yayınlar", + "posted-by": "Gönderen", + "in-categories": "Kategorilerde", + "search-child-categories": "Alt kategorilerde arat", + "reply-count": "Cevap Sayısı", + "at-least": "En az", + "at-most": "En fazla", + "post-time": "Yayınlama zamanı", + "newer-than": "Daha yeni", + "older-than": "Daha eski", + "any-date": "Herhangi bir tarih", + "yesterday": "Dün", + "one-week": "Bir hafta", + "two-weeks": "İki hafta", + "one-month": "Bir ay", + "three-months": "Üç ay", + "six-months": "Altı ay", + "one-year": "Bir yıl", + "sort-by": "Şuna göre filtrele", + "last-reply-time": "En son cevaplama süresi", + "topic-title": "Konu başlığı", + "number-of-replies": "Cevap sayısı", + "number-of-views": "Görüntüleme sayısı", + "topic-start-date": "Başlık açılma tarihi", + "username": "Kullanıcı Adı", + "category": "Kategori", + "descending": "Azalan düzene göre", + "ascending": "Artan düzene göre" } \ No newline at end of file diff --git a/public/language/tr/topic.json b/public/language/tr/topic.json index aa6aa90855..6cd2424e0f 100644 --- a/public/language/tr/topic.json +++ b/public/language/tr/topic.json @@ -74,7 +74,7 @@ "fork_no_pids": "Hiç bir ileti seçilmedi!", "fork_success": "Başlık başarıyla ayrıldı!", "composer.title_placeholder": "Başlık ismini buraya girin...", - "composer.handle_placeholder": "Name", + "composer.handle_placeholder": "İsim", "composer.discard": "Vazgeç", "composer.submit": "Gönder", "composer.replying_to": "Yanıtlanan Konu %1", @@ -94,5 +94,5 @@ "oldest_to_newest": "En eskiden en yeniye", "newest_to_oldest": "En yeniden en eskiye", "most_votes": "En çok oy", - "most_posts": "Most posts" + "most_posts": "En sık yayın" } \ No newline at end of file diff --git a/public/language/tr/user.json b/public/language/tr/user.json index 90bd5eb06b..8fa7b4c5c9 100644 --- a/public/language/tr/user.json +++ b/public/language/tr/user.json @@ -2,8 +2,8 @@ "banned": "Yasaklı", "offline": "Çevrimdışı", "username": "Kullanıcı Adı", - "joindate": "Join Date", - "postcount": "Post Count", + "joindate": "Katılım Tarihi", + "postcount": "Yayın Sayısı", "email": "E-posta", "confirm_email": "E-posta onayla", "delete_account": "Hesabı Sil", @@ -18,7 +18,7 @@ "profile_views": "Profil Görüntülemeleri", "reputation": "Saygınlık", "favourites": "Favoriler", - "watched": "Watched", + "watched": "İzlendi", "followers": "Takipçiler", "following": "Takip Ediyor", "signature": "İmza", @@ -59,12 +59,12 @@ "digest_weekly": "Haftalık", "digest_monthly": "Aylık", "send_chat_notifications": "Çevrimiçi değilken gelen iletileri e-posta olarak gönder", - "send_post_notifications": "Send an email when replies are made to topics I am subscribed to", + "send_post_notifications": "Abone olduğum konulara cevap gelince bana eposta yolla", "has_no_follower": "Bu kullanıcının hiç takipçisi yok :(", "follows_no_one": "Bu kullanıcı kimseyi takip etmiyor :(", "has_no_posts": "Bu kullanıcı henüz birşey göndermedi.", "has_no_topics": "Bu kullanıcı henüz bir konu yaratmadı.", - "has_no_watched_topics": "This user didn't watch any topics yet.", + "has_no_watched_topics": "Bu kullanıcı henüz hiçbir konuyu izlemedi.", "email_hidden": "E-posta gizli", "hidden": "gizli", "paginate_description": "Sonsuz yükleme yerine konu ve iletileri sayfalara böl.", diff --git a/public/language/tr/users.json b/public/language/tr/users.json index 8858e75ddd..9e38f04530 100644 --- a/public/language/tr/users.json +++ b/public/language/tr/users.json @@ -5,8 +5,8 @@ "search": "Ara", "enter_username": "Aramak için bir kullanıcı adı girin", "load_more": "Daha Fazla Yükle", - "users-found-search-took": "%1 kullanıcı bulundu! Arama %2 ms sürdü.", - "filter-by": "Filter By", - "online-only": "Online only", - "picture-only": "Picture only" + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", + "filter-by": "Şu şekilde filtrele", + "online-only": "Sadece çevrimiçi", + "picture-only": "Sadece resim" } \ No newline at end of file diff --git a/public/language/vi/email.json b/public/language/vi/email.json index 97bd7549e8..d0d376eb34 100644 --- a/public/language/vi/email.json +++ b/public/language/vi/email.json @@ -9,6 +9,9 @@ "reset.text1": "Chúng tôi nhận được yêu cầu khởi tạo lại mật khẩu của bạn, rất có thể vì bạn đã quên mất nó. Nếu bạn không gởi yêu cầu, hãy bỏ qua email này.", "reset.text2": "Để đặt lại mật khẩu, hãy click vào liên kết sau:", "reset.cta": "Click vào đây để khởi tạo lại mật khẩu", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "Bạn có thông báo chưa đọc từ %1", "digest.latest_topics": "Chủ đề mới nhất từ %1", "digest.cta": "Click vào đây để truy cập %1", diff --git a/public/language/vi/error.json b/public/language/vi/error.json index 8dd065f637..e8da82c330 100644 --- a/public/language/vi/error.json +++ b/public/language/vi/error.json @@ -35,6 +35,7 @@ "topic-locked": "Chủ đề bị khóa", "still-uploading": "Vui lòng chờ upload", "content-too-short": "Vui lòng tạo bài viết dài hơn. Bài viết phải có ít nhất %1 ký tự.", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "Vui lòng nhập tiêu đề dài hơn. Tiêu đề phải có ít nhất %1 ký tự", "title-too-long": "Yêu cầu tiêu đề ngắn hơn. Không dài quá %1 ký tự", "too-many-posts": "Bạn chỉ có thể gửi một bài viết mỗi %1 giây - Xin chờ trong giây lát trước khi gửi lại.", diff --git a/public/language/vi/pages.json b/public/language/vi/pages.json index 697490930b..153a1f31d8 100644 --- a/public/language/vi/pages.json +++ b/public/language/vi/pages.json @@ -11,6 +11,7 @@ "user.followers": "Người đang theo dõi %1", "user.posts": "Các bài được %1 viết", "user.topics": "Các chủ đề được %1 tạo", + "user.groups": "%1's Groups", "user.favourites": "Các bài gửi yêu thích của %1", "user.settings": "Thiết lập cho người dùng", "maintenance.text": "%1 đang được bảo trì. Xin vui lòng quay lại sau.", diff --git a/public/language/vi/reset_password.json b/public/language/vi/reset_password.json index edc196ba6c..32db56aab3 100644 --- a/public/language/vi/reset_password.json +++ b/public/language/vi/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "Xin hãy nhập địa chỉ email của bạn và chúng tôi sẽ gửi một email hướng dẫn cách thiết lập lại tài khoản cho bạn", "enter_email_address": "Nhập địa chỉ Email", "password_reset_sent": "Đã gửi mật khẩu được thiết lập lại", - "invalid_email": "Email không đúng / Email không tồn tại!" + "invalid_email": "Email không đúng / Email không tồn tại!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/vi/search.json b/public/language/vi/search.json index 254873ed38..a6450e408b 100644 --- a/public/language/vi/search.json +++ b/public/language/vi/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/vi/users.json b/public/language/vi/users.json index 405c9de32b..5e08193fd4 100644 --- a/public/language/vi/users.json +++ b/public/language/vi/users.json @@ -5,7 +5,7 @@ "search": "Tìm kiếm", "enter_username": "Gõ tên người dùng để tìm kiếm", "load_more": "Tải thêm", - "users-found-search-took": "%1 tài khoản(s) tìm thấy! Tìm trong %2 mili giây.", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/zh_CN/email.json b/public/language/zh_CN/email.json index 341874ec67..e81b810a9a 100644 --- a/public/language/zh_CN/email.json +++ b/public/language/zh_CN/email.json @@ -9,6 +9,9 @@ "reset.text1": "我们收到了重置您帐户密码的申请,可能是因为您遗忘了密码。如果不是,请忽略这封邮件。", "reset.text2": "如需继续重置密码,请点击下面的链接:", "reset.cta": "点击这里重置您的密码", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "您有来自 %1 的未读通知:", "digest.latest_topics": "来自 %1 的最新主题", "digest.cta": "点击这里访问 %1", diff --git a/public/language/zh_CN/error.json b/public/language/zh_CN/error.json index eef3088946..cfcb33aee8 100644 --- a/public/language/zh_CN/error.json +++ b/public/language/zh_CN/error.json @@ -35,6 +35,7 @@ "topic-locked": "主题已锁定", "still-uploading": "请等待上传完成", "content-too-short": "请再输入一些内容,帖子至少要有 %1 个字符。", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "请再输入一些内容,标题至少要有 %1 个字符。", "title-too-long": "请输入更短的标题。不超过 %1 字。", "too-many-posts": "发帖间隔至少要 %1 秒 - 请稍候再发帖", diff --git a/public/language/zh_CN/pages.json b/public/language/zh_CN/pages.json index 924e8bdfa4..36d10c1cb3 100644 --- a/public/language/zh_CN/pages.json +++ b/public/language/zh_CN/pages.json @@ -11,6 +11,7 @@ "user.followers": "关注 %1 的人", "user.posts": "%1 发布的帖子", "user.topics": "%1 创建的主题", + "user.groups": "%1's Groups", "user.favourites": "%1 收藏的帖子", "user.settings": "用户设置", "maintenance.text": "%1 正在进行维护。请稍后再来。", diff --git a/public/language/zh_CN/reset_password.json b/public/language/zh_CN/reset_password.json index 701651dfb6..ca294f9dc7 100644 --- a/public/language/zh_CN/reset_password.json +++ b/public/language/zh_CN/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "请输入您的电子邮箱地址,我们会发送一份邮件指导您重置密码。", "enter_email_address": "输入邮箱地址", "password_reset_sent": "密码重置邮件已发送。", - "invalid_email": "无效的电子邮箱/电子邮箱不存在!" + "invalid_email": "无效的电子邮箱/电子邮箱不存在!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/zh_CN/search.json b/public/language/zh_CN/search.json index 338db4e61b..25cc3605e5 100644 --- a/public/language/zh_CN/search.json +++ b/public/language/zh_CN/search.json @@ -3,5 +3,33 @@ "no-matches": "No matches found", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/zh_CN/users.json b/public/language/zh_CN/users.json index bd19c53fa9..f56a4fb88e 100644 --- a/public/language/zh_CN/users.json +++ b/public/language/zh_CN/users.json @@ -5,7 +5,7 @@ "search": "搜索", "enter_username": "输入用户名搜索", "load_more": "加载更多", - "users-found-search-took": "找到 %1 位用户!搜索耗时 %2 毫秒。", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" diff --git a/public/language/zh_TW/email.json b/public/language/zh_TW/email.json index 6a5e3ef124..1062070b96 100644 --- a/public/language/zh_TW/email.json +++ b/public/language/zh_TW/email.json @@ -9,6 +9,9 @@ "reset.text1": "我們收到一個重設密碼的請求,你忘掉了密碼嗎?如果不是,請忽略這封郵件。", "reset.text2": "要繼續重置密碼,請點擊以下鏈接:", "reset.cta": "點擊這裡重置密碼", + "reset.notify.subject": "Password successfully changed", + "reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.", + "reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.", "digest.notifications": "你有來自$1的未讀通知:", "digest.latest_topics": "來自%1的最新話題", "digest.cta": "點擊這裡訪問%1", diff --git a/public/language/zh_TW/error.json b/public/language/zh_TW/error.json index 5342050972..cb254c35aa 100644 --- a/public/language/zh_TW/error.json +++ b/public/language/zh_TW/error.json @@ -35,6 +35,7 @@ "topic-locked": "該主題已被鎖定", "still-uploading": "請等待上傳完成。", "content-too-short": "請輸入一個較長的帖子。 帖子需至少有 %1 個字。", + "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 characters.", "title-too-short": "請輸入一個較長的標題。 標題需至少有 %1 個字。", "title-too-long": "請輸入一個較短的主題名稱。 標題不能超過 %1 個字元。", "too-many-posts": "你必須間隔 %1 秒後才能發表文章-請稍後", diff --git a/public/language/zh_TW/pages.json b/public/language/zh_TW/pages.json index deaa502ffe..bcb655c3e2 100644 --- a/public/language/zh_TW/pages.json +++ b/public/language/zh_TW/pages.json @@ -11,6 +11,7 @@ "user.followers": "People who Follow %1", "user.posts": "文章由 %1 所張貼", "user.topics": "主題由 %1 所創建", + "user.groups": "%1's Groups", "user.favourites": "%1's 最喜愛的文章", "user.settings": "使用者設定", "maintenance.text": "%1目前正在進行維修。請稍後再來。", diff --git a/public/language/zh_TW/reset_password.json b/public/language/zh_TW/reset_password.json index b4c454d4da..9f0ab67aa1 100644 --- a/public/language/zh_TW/reset_password.json +++ b/public/language/zh_TW/reset_password.json @@ -10,5 +10,7 @@ "enter_email": "請輸入您的Email地址,我們會發送郵件告訴您如何重設密碼。", "enter_email_address": "輸入郵箱地址", "password_reset_sent": "密碼重設郵件已發送。", - "invalid_email": "非法的郵箱地址/郵箱不存在!" + "invalid_email": "非法的郵箱地址/郵箱不存在!", + "password_too_short": "The password entered is too short, please pick a different password.", + "passwords_do_not_match": "The two passwords you've entered do not match." } \ No newline at end of file diff --git a/public/language/zh_TW/search.json b/public/language/zh_TW/search.json index 426fa932b4..9fa8e84f2a 100644 --- a/public/language/zh_TW/search.json +++ b/public/language/zh_TW/search.json @@ -1,7 +1,35 @@ { "results_matching": "有%1個跟\"%2\"匹配的結果(%3秒)", - "no-matches": "No matches found", + "no-matches": "沒有找到匹配的主題", "in": "In", "by": "By", - "posted-by": "Posted by" + "titles": "Titles", + "titles-posts": "Titles and Posts", + "posted-by": "Posted by", + "in-categories": "In Categories", + "search-child-categories": "Search child categories", + "reply-count": "Reply Count", + "at-least": "At least", + "at-most": "At most", + "post-time": "Post time", + "newer-than": "Newer than", + "older-than": "Older than", + "any-date": "Any date", + "yesterday": "Yesterday", + "one-week": "One week", + "two-weeks": "Two weeks", + "one-month": "One month", + "three-months": "Three months", + "six-months": "Six months", + "one-year": "One year", + "sort-by": "Sort by", + "last-reply-time": "Last reply time", + "topic-title": "Topic title", + "number-of-replies": "Number of replies", + "number-of-views": "Number of views", + "topic-start-date": "Topic start date", + "username": "Username", + "category": "Category", + "descending": "In descending order", + "ascending": "In ascending order" } \ No newline at end of file diff --git a/public/language/zh_TW/users.json b/public/language/zh_TW/users.json index 249b34d36f..b3c22fb165 100644 --- a/public/language/zh_TW/users.json +++ b/public/language/zh_TW/users.json @@ -5,7 +5,7 @@ "search": "搜尋", "enter_username": "輸入想找的使用者帳號", "load_more": "載入更多", - "users-found-search-took": "找到%1個用戶!搜索時間%2毫秒。", + "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", "online-only": "Online only", "picture-only": "Picture only" From 57d45518bdc71e50654802116e189680ac478d16 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 10 Feb 2015 11:16:24 -0500 Subject: [PATCH 115/164] added a preventDefault when href="#" or data-ajaxify="false", so page doesn't send user back to top (which is kind of annoying), but not sure if this may introduce side-effects. @barisusakli @psychobunny --- public/src/ajaxify.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index cc7c0cbff1..d2af431176 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -276,7 +276,7 @@ $(document).ready(function() { // Enhancing all anchors to ajaxify... $(document.body).on('click', 'a', function (e) { if (hrefEmpty(this.href) || this.target !== '' || this.protocol === 'javascript:' || $(this).attr('data-ajaxify') === 'false') { - return; + return e.preventDefault(); } if (!window.location.pathname.match(/\/(403|404)$/g)) { From f16c37eeaf84a22ed27fbdbc929e5ddcc83f80b3 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 10 Feb 2015 11:17:25 -0500 Subject: [PATCH 116/164] #2692 --- public/src/client/groups/details.js | 13 +++++++++++++ src/socket.io/groups.js | 20 +++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js index 09826fb673..b40957af8a 100644 --- a/public/src/client/groups/details.js +++ b/public/src/client/groups/details.js @@ -39,6 +39,19 @@ define('forum/groups/details', ['iconSelect', 'vendor/colorpicker/colorpicker', }); break; + case 'kick': + socket.emit('groups.kick', { + uid: uid, + groupName: ajaxify.variables.get('group_name') + }, function(err) { + if (!err) { + userRow.slideUp().remove(); + } else { + app.alertError(err.message); + } + }); + break; + case 'update': Details.update(); break; diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index a99112eded..ba35e128c4 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -102,7 +102,7 @@ SocketGroups.reject = function(socket, data, callback) { }; SocketGroups.update = function(socket, data, callback) { - if(!data) { + if (!data) { return callback(new Error('[[error:invalid-data]]')); } @@ -130,7 +130,7 @@ SocketGroups.create = function(socket, data, callback) { }; SocketGroups.delete = function(socket, data, callback) { - if(!data) { + if (!data) { return callback(new Error('[[error:invalid-data]]')); } @@ -156,6 +156,20 @@ SocketGroups.search = function(socket, data, callback) { groups.search(data.query || '', data.options || {}, callback); }; +SocketGroups.kick = function(socket, data, callback) { + if (!data) { + return callback(new Error('[[error:invalid-data]]')); + } + + groups.ownership.isOwner(socket.uid, data.groupName, function(err, isOwner) { + if (!isOwner) { + return callback(new Error('[[error:no-privileges]]')); + } + + groups.leave(data.groupName, data.uid, callback); + }); +}; + SocketGroups.cover = {}; SocketGroups.cover.get = function(socket, data, callback) { @@ -163,7 +177,7 @@ SocketGroups.cover.get = function(socket, data, callback) { }; SocketGroups.cover.update = function(socket, data, callback) { - if(!data) { + if (!data) { return callback(new Error('[[error:invalid-data]]')); } else if (socket.uid === 0) { return callback(new Error('[[error:no-privileges]]')); From 9bfb7585ee9451f71e21f4ab6770dfaa630bc81c Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 10 Feb 2015 11:21:14 -0500 Subject: [PATCH 117/164] bundling emoji-extended with all installs, @frissdiegurke --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index cb00f143cc..013480d14d 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "morgan": "^1.3.2", "nconf": "~0.7.1", "nodebb-plugin-dbsearch": "^0.1.0", + "nodebb-plugin-emoji-extended": "^0.4.1-4", "nodebb-plugin-markdown": "^0.8.0", "nodebb-plugin-mentions": "^0.9.0", "nodebb-plugin-soundpack-default": "~0.1.1", From 0d9d9bf110d5a0a3f625261ac38cd56c74c57361 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 10 Feb 2015 11:24:11 -0500 Subject: [PATCH 118/164] added two new language strings --- public/language/en_GB/groups.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/language/en_GB/groups.json b/public/language/en_GB/groups.json index eb9a45f994..964b5f42c6 100644 --- a/public/language/en_GB/groups.json +++ b/public/language/en_GB/groups.json @@ -17,6 +17,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", From 47964e8ff4408f6f66faa3133197ac05cf20ab95 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 10 Feb 2015 11:24:44 -0500 Subject: [PATCH 119/164] latest fallbacks --- public/language/ar/groups.json | 2 ++ public/language/bn/groups.json | 2 ++ public/language/cs/groups.json | 2 ++ public/language/de/groups.json | 2 ++ public/language/el/groups.json | 2 ++ public/language/en@pirate/groups.json | 2 ++ public/language/en_US/groups.json | 2 ++ public/language/es/groups.json | 2 ++ public/language/et/groups.json | 2 ++ public/language/fa_IR/groups.json | 2 ++ public/language/fi/groups.json | 2 ++ public/language/fr/groups.json | 2 ++ public/language/he/groups.json | 2 ++ public/language/hu/groups.json | 2 ++ public/language/id/groups.json | 2 ++ public/language/it/groups.json | 2 ++ public/language/ja/groups.json | 2 ++ public/language/ko/groups.json | 2 ++ public/language/lt/groups.json | 2 ++ public/language/ms/groups.json | 2 ++ public/language/nb/groups.json | 2 ++ public/language/nl/groups.json | 2 ++ public/language/pl/groups.json | 2 ++ public/language/pt_BR/groups.json | 2 ++ public/language/ro/groups.json | 2 ++ public/language/ru/groups.json | 2 ++ public/language/sc/groups.json | 2 ++ public/language/sk/groups.json | 2 ++ public/language/sv/groups.json | 2 ++ public/language/th/groups.json | 2 ++ public/language/tr/groups.json | 2 ++ public/language/vi/groups.json | 2 ++ public/language/zh_CN/groups.json | 2 ++ public/language/zh_TW/groups.json | 2 ++ 34 files changed, 68 insertions(+) diff --git a/public/language/ar/groups.json b/public/language/ar/groups.json index 5ca494a696..b006f74391 100644 --- a/public/language/ar/groups.json +++ b/public/language/ar/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "آخر المشاركات", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/bn/groups.json b/public/language/bn/groups.json index a9f9207a2f..fe8c9fed1d 100644 --- a/public/language/bn/groups.json +++ b/public/language/bn/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "সর্বশেষ পোষ্টসমূহ", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/cs/groups.json b/public/language/cs/groups.json index 980b41e1b7..95d083451f 100644 --- a/public/language/cs/groups.json +++ b/public/language/cs/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Nejnovější příspěvky", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/de/groups.json b/public/language/de/groups.json index 812b309dc3..375e09d9b5 100644 --- a/public/language/de/groups.json +++ b/public/language/de/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Aktuelle Beiträge", "details.private": "Private Gruppe", "details.public": "Öffentliche Gruppe", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Gruppenadministration", "event.updated": "Gruppendetails wurden aktualisiert", "event.deleted": "Die Gruppe \"% 1\" wurde gelöscht" diff --git a/public/language/el/groups.json b/public/language/el/groups.json index 5fa5a25877..9ad8583476 100644 --- a/public/language/el/groups.json +++ b/public/language/el/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Τελευταίες δημοσιεύσεις.", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/en@pirate/groups.json b/public/language/en@pirate/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/en@pirate/groups.json +++ b/public/language/en@pirate/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/en_US/groups.json b/public/language/en_US/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/en_US/groups.json +++ b/public/language/en_US/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/es/groups.json b/public/language/es/groups.json index bc91648d60..999550b671 100644 --- a/public/language/es/groups.json +++ b/public/language/es/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Últimas Publicaciones", "details.private": "Grupo Privado", "details.public": "Grupo Público", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Administración De Grupo", "event.updated": "Los detalles del grupo han sido actualizados", "event.deleted": "El grupo \"%1\" ha sido eliminado" diff --git a/public/language/et/groups.json b/public/language/et/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/et/groups.json +++ b/public/language/et/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/fa_IR/groups.json b/public/language/fa_IR/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/fa_IR/groups.json +++ b/public/language/fa_IR/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/fi/groups.json b/public/language/fi/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/fi/groups.json +++ b/public/language/fi/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/fr/groups.json b/public/language/fr/groups.json index e786d08dd0..d8c81570df 100644 --- a/public/language/fr/groups.json +++ b/public/language/fr/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Derniers messages", "details.private": "Groupe Privé", "details.public": "Groupe Public", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Administration du Groupe", "event.updated": "Les détails du groupe ont été mis à jour", "event.deleted": "Le groupe é%1\" a été supprimé" diff --git a/public/language/he/groups.json b/public/language/he/groups.json index 54f7936c08..6754a5611c 100644 --- a/public/language/he/groups.json +++ b/public/language/he/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "פוסטים אחרונים", "details.private": "קבוצה פרטית", "details.public": "קבוצה פומבית", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "ניהול הקבוצה", "event.updated": "פרטי הקבוצה עודכנו", "event.deleted": "קבוצת \"%1\" נמחקה" diff --git a/public/language/hu/groups.json b/public/language/hu/groups.json index 3d8cddf1c1..09324055a0 100644 --- a/public/language/hu/groups.json +++ b/public/language/hu/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Legújabb bejegyzések", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/id/groups.json b/public/language/id/groups.json index bca990761d..3bae971661 100644 --- a/public/language/id/groups.json +++ b/public/language/id/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Posting Terkini", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/it/groups.json b/public/language/it/groups.json index 51f67ec593..f4e5f32787 100644 --- a/public/language/it/groups.json +++ b/public/language/it/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Ultimi Post", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/ja/groups.json b/public/language/ja/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/ja/groups.json +++ b/public/language/ja/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/ko/groups.json b/public/language/ko/groups.json index 8a788bebb2..344c35078b 100644 --- a/public/language/ko/groups.json +++ b/public/language/ko/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "최근 게시물", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/lt/groups.json b/public/language/lt/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/lt/groups.json +++ b/public/language/lt/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/ms/groups.json b/public/language/ms/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/ms/groups.json +++ b/public/language/ms/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/nb/groups.json b/public/language/nb/groups.json index 7578e96072..894bbc0a12 100644 --- a/public/language/nb/groups.json +++ b/public/language/nb/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Seneste innlegg", "details.private": "Privat grup", "details.public": "Offentlig grup", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Gruppeadministrasjon", "event.updated": "Gruppedetaljer har blitt oppgradert", "event.deleted": "Gruppen \"%1\" har blitt slettet" diff --git a/public/language/nl/groups.json b/public/language/nl/groups.json index a1d2ca868d..59681475d1 100644 --- a/public/language/nl/groups.json +++ b/public/language/nl/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Nieuwste Berichten", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/pl/groups.json b/public/language/pl/groups.json index 9fdd6d6c79..0cd285b938 100644 --- a/public/language/pl/groups.json +++ b/public/language/pl/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Ostatnie posty", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/pt_BR/groups.json b/public/language/pt_BR/groups.json index 09abeb8bcd..4095f4c3ce 100644 --- a/public/language/pt_BR/groups.json +++ b/public/language/pt_BR/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Últimos Posts", "details.private": "Grupo Privado", "details.public": "Grupo Público.", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Administração do Grupo", "event.updated": "Os detalhes do grupo foram atualizados", "event.deleted": "O grupo \"%1\" foi deletado" diff --git a/public/language/ro/groups.json b/public/language/ro/groups.json index 816af582ea..03cacf8b36 100644 --- a/public/language/ro/groups.json +++ b/public/language/ro/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Ultimele Mesaje", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/ru/groups.json b/public/language/ru/groups.json index 55a2f35561..4b86076056 100644 --- a/public/language/ru/groups.json +++ b/public/language/ru/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Последние записи", "details.private": "Приватная группа", "details.public": "Открытая группа", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Настройки группы", "event.updated": "Настройки группы обновлены", "event.deleted": "Группа \"%1\" удалена" diff --git a/public/language/sc/groups.json b/public/language/sc/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/sc/groups.json +++ b/public/language/sc/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/sk/groups.json b/public/language/sk/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/sk/groups.json +++ b/public/language/sk/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/sv/groups.json b/public/language/sv/groups.json index 92a4eeb90b..fdba1db1b1 100644 --- a/public/language/sv/groups.json +++ b/public/language/sv/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Senaste inlägg", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/th/groups.json b/public/language/th/groups.json index 6dfd71256b..950fe6dca3 100644 --- a/public/language/th/groups.json +++ b/public/language/th/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Latest Posts", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/tr/groups.json b/public/language/tr/groups.json index e174ef10ab..3b765a2f7b 100644 --- a/public/language/tr/groups.json +++ b/public/language/tr/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "En son iletiler", "details.private": "Özel Grup", "details.public": "Herkese Açık Grup", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Grup Yöneticisi", "event.updated": "Grup detayları güncellenmiştir", "event.deleted": "\"%1\" grubu silinmiş" diff --git a/public/language/vi/groups.json b/public/language/vi/groups.json index c3a1d060d0..b649073d9b 100644 --- a/public/language/vi/groups.json +++ b/public/language/vi/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "Bài mới nhất", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/zh_CN/groups.json b/public/language/zh_CN/groups.json index 10a70d94c2..5a4bdd5b1f 100644 --- a/public/language/zh_CN/groups.json +++ b/public/language/zh_CN/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "最新帖子", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" diff --git a/public/language/zh_TW/groups.json b/public/language/zh_TW/groups.json index 7e9ba9f239..a6c0d93c19 100644 --- a/public/language/zh_TW/groups.json +++ b/public/language/zh_TW/groups.json @@ -15,6 +15,8 @@ "details.latest_posts": "最新帖子", "details.private": "Private Group", "details.public": "Public Group", + "details.grant": "Grant/Rescind Ownership", + "details.kick": "Kick", "details.owner_options": "Group Administration", "event.updated": "Group details have been updated", "event.deleted": "The group \"%1\" has been deleted" From 34c1d69ed33fcc843f06291c4029c995667e1209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 10 Feb 2015 13:12:08 -0500 Subject: [PATCH 120/164] added filter:tags.search --- src/topics/tags.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/topics/tags.js b/src/topics/tags.js index be01380ef5..14982b4e1e 100644 --- a/src/topics/tags.js +++ b/src/topics/tags.js @@ -271,8 +271,10 @@ module.exports = function(Topics) { matches = matches.slice(0, 20).sort(function(a, b) { return a > b; }); - - callback(null, matches); + + plugins.fireHook('filter:tags.search', {data: data, matches: matches}, function(err, data) { + callback(err, data ? data.matches : []); + }); }); }; From b40b87dd360c28d7df0e6f49274a36cfdda7d0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 10 Feb 2015 13:45:29 -0500 Subject: [PATCH 121/164] dont add relative_path to uploads it is added on the way out --- app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.js b/app.js index acb1a3baca..dcdf8e1819 100644 --- a/app.js +++ b/app.js @@ -116,7 +116,7 @@ function start() { nconf.set('use_port', !!urlObject.port); nconf.set('relative_path', relativePath); nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || 4567); - nconf.set('upload_url', relativePath + '/uploads/'); + nconf.set('upload_url', '/uploads/'); if (nconf.get('isPrimary') === 'true') { winston.info('Time: %s', (new Date()).toString()); From 57d6bb3b4c2a52668757ca3a067b0fd98e851cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 10 Feb 2015 14:30:01 -0500 Subject: [PATCH 122/164] filter:search.build hook --- src/controllers/search.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/controllers/search.js b/src/controllers/search.js index 0a26822699..93a7eccdc5 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -41,10 +41,9 @@ searchController.search = function(req, res, next) { req.query.categories = [req.query.categories]; } - req.query.in = req.query.in || 'posts'; - search.search({ + var data = { query: req.params.term, - searchIn: req.query.in, + searchIn: req.query.in || 'posts', postedBy: req.query.by, categories: req.query.categories, searchChildren: req.query.searchChildren, @@ -56,7 +55,9 @@ searchController.search = function(req, res, next) { sortDirection: req.query.sortDirection, page: page, uid: uid - }, function(err, results) { + }; + + search.search(data, function(err, results) { if (err) { return next(err); } @@ -67,7 +68,13 @@ searchController.search = function(req, res, next) { results.showAsTopics = req.query.showAs === 'topics'; results.breadcrumbs = breadcrumbs; results.categories = categories; - res.render('search', results); + + plugins.fireHook('filter:search.build', {data: data, results: results}, function(err, data) { + if (err) { + return next(err); + } + res.render('search', data.results); + }); }); }); }; From 6a55cdfbaf8b552e60cba21c6eb3a00a6f5fea06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 10 Feb 2015 14:47:01 -0500 Subject: [PATCH 123/164] fix relative_path image url for sub installs --- src/controllers/accounts.js | 2 +- src/user.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js index 84b0f96ad5..77cbe1008b 100644 --- a/src/controllers/accounts.js +++ b/src/controllers/accounts.js @@ -438,7 +438,7 @@ accountsController.uploadPicture = function (req, res, next) { user.setUserFields(updateUid, {uploadedpicture: image.url, picture: image.url}); - res.json([{name: userPhoto.name, url: image.url}]); + res.json([{name: userPhoto.name, url: nconf.get('relative_path') + image.url}]); } if (err) { diff --git a/src/user.js b/src/user.js index bd781432a0..035933154a 100644 --- a/src/user.js +++ b/src/user.js @@ -119,7 +119,7 @@ var async = require('async'), if (user.picture) { if (user.picture === user.uploadedpicture) { - user.picture = user.picture.indexOf('http') === -1 ? nconf.get('relative_path') + user.picture : user.picture; + user.picture = user.uploadedpicture = user.picture.indexOf('http') === -1 ? nconf.get('relative_path') + user.picture : user.picture; } else { user.picture = User.createGravatarURLFromEmail(user.email); } From 2c86ca59e6c75c7107b6d5c768cbb89987051f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 10 Feb 2015 15:23:11 -0500 Subject: [PATCH 124/164] fire filter:serch.build if query is empty --- src/controllers/search.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/controllers/search.js b/src/controllers/search.js index 93a7eccdc5..2020612094 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -24,7 +24,7 @@ searchController.search = function(req, res, next) { } if (!req.params.term) { - return res.render('search', { + var results = { time: 0, search_query: '', posts: [], @@ -32,7 +32,14 @@ searchController.search = function(req, res, next) { tags: [], categories: categories, breadcrumbs: breadcrumbs + }; + plugins.fireHook('filter:search.build', {data: {}, results: results}, function(err, data) { + if (err) { + return next(err); + } + res.render('search', data.results); }); + return; } req.params.term = validator.escape(req.params.term); From a0e98d5957e162bcec84fdbbe7d5368ac6386974 Mon Sep 17 00:00:00 2001 From: Timothy Fike Date: Tue, 10 Feb 2015 19:47:06 -0500 Subject: [PATCH 125/164] Make widget headers clickable anywhere. --- public/src/admin/extend/widgets.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/src/admin/extend/widgets.js b/public/src/admin/extend/widgets.js index 1bf4a043ec..9632bbfa68 100644 --- a/public/src/admin/extend/widgets.js +++ b/public/src/admin/extend/widgets.js @@ -46,8 +46,6 @@ define('admin/extend/widgets', function() { appendToggle(ui.item); }, connectWith: "div" - }).on('click', '.toggle-widget', function() { - $(this).parents('.widget-panel').children('.panel-body').toggleClass('hidden'); }).on('click', '.delete-widget', function() { var panel = $(this).parents('.widget-panel'); @@ -56,8 +54,10 @@ define('admin/extend/widgets', function() { panel.remove(); } }); - }).on('dblclick', '.panel-heading', function() { - $(this).parents('.widget-panel').children('.panel-body').toggleClass('hidden'); + }).on('mouseup', '.panel-heading', function(evt) { + if ( !( $(this).parents('.widget-panel').is('.ui-sortable-helper') || $(evt.target).closest('.delete-widget').length ) ) { + $(this).parents('.widget-panel').children('.panel-body').toggleClass('hidden'); + } }); $('#widgets .save').on('click', saveWidgets); From a5029d148ccd8ca45223a06c189a5c5c649d1e0a Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 10 Feb 2015 20:20:52 -0500 Subject: [PATCH 126/164] open user links in new tab --- src/views/admin/advanced/events.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/admin/advanced/events.tpl b/src/views/admin/advanced/events.tpl index e3231b0099..7eb2997ba5 100644 --- a/src/views/admin/advanced/events.tpl +++ b/src/views/admin/advanced/events.tpl @@ -10,7 +10,7 @@
#{events.eid} {events.type} - {events.user.username} (uid {events.user.uid}) (IP {events.ip}) + {events.user.username} (uid {events.user.uid}) (IP {events.ip}) {events.timestampISO}

{events.jsonString}
From 104393f5f7df13e6f0b178ccd411748c6f5e8c53 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 10 Feb 2015 21:54:35 -0500 Subject: [PATCH 127/164] closes #2712 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 013480d14d..8de4dbc58c 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "nodebb-plugin-mentions": "^0.9.0", "nodebb-plugin-soundpack-default": "~0.1.1", "nodebb-plugin-spam-be-gone": "^0.4.0", - "nodebb-theme-lavender": "^0.2.0", + "nodebb-theme-lavender": "^1.0.0", "nodebb-theme-vanilla": "^1.0.0", "nodebb-widget-essentials": "~0.2.0", "npm": "^2.1.4", From 1142f7700f2c1337fefaa417f65fb67843e5802f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 10 Feb 2015 23:34:06 -0500 Subject: [PATCH 128/164] closes #2714 --- src/plugins.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/plugins.js b/src/plugins.js index bd00bb8b0a..0c8a4ba394 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -343,16 +343,18 @@ var fs = require('fs'), }).reduce(function(prev, cur) { return prev.concat(cur); }); - next(null, paths); - } - ], function(err, paths) { - for (var x=0,numPaths=paths.length;x Date: Tue, 10 Feb 2015 21:34:19 -0700 Subject: [PATCH 129/164] Make ACP sidebar fixed If you want to implement some kind of replacement for the CSS calc I used, go ahead and do it yourself. I'm hoping webmasters can either deal with a tad bit of overlap or have a modern browser. --- public/less/admin/admin.less | 12 +++++++++++- src/views/admin/advanced/events.tpl | 3 +-- src/views/admin/advanced/logs.tpl | 2 +- src/views/admin/appearance/skins.tpl | 4 ++-- src/views/admin/development/logger.tpl | 2 +- src/views/admin/extend/plugins.tpl | 4 ++-- src/views/admin/general/languages.tpl | 4 ++-- src/views/admin/general/sounds.tpl | 4 ++-- src/views/admin/manage/categories.tpl | 4 ++-- src/views/admin/manage/flags.tpl | 4 +--- src/views/admin/manage/groups.tpl | 2 +- src/views/admin/manage/tags.tpl | 14 +++++++------- src/views/admin/manage/users.tpl | 4 ++-- src/views/admin/settings/footer.tpl | 4 ++-- 14 files changed, 37 insertions(+), 30 deletions(-) diff --git a/public/less/admin/admin.less b/public/less/admin/admin.less index 2e5b868048..6beb1525fd 100644 --- a/public/less/admin/admin.less +++ b/public/less/admin/admin.less @@ -266,4 +266,14 @@ // See: https://github.com/twbs/bootstrap/commit/8e2348e9eda51296eb680192379ab37f10355ca3 .navbar-brand > img { display: inline-block; -} \ No newline at end of file +} + +@media (min-width: 768px) { + .acp-sidebar { + position: fixed; + top: 70px; + right: 15px; + width: initial; + max-width: calc( ~"(100% - 200px)/4" ); + } +} diff --git a/src/views/admin/advanced/events.tpl b/src/views/admin/advanced/events.tpl index e3231b0099..eb22fb13db 100644 --- a/src/views/admin/advanced/events.tpl +++ b/src/views/admin/advanced/events.tpl @@ -20,7 +20,7 @@
-
+
Events Control Panel
@@ -29,4 +29,3 @@
- diff --git a/src/views/admin/advanced/logs.tpl b/src/views/admin/advanced/logs.tpl index 0311573d25..24f91ce60b 100644 --- a/src/views/admin/advanced/logs.tpl +++ b/src/views/admin/advanced/logs.tpl @@ -7,7 +7,7 @@
-
+
Logs Control Panel
diff --git a/src/views/admin/appearance/skins.tpl b/src/views/admin/appearance/skins.tpl index e3e91680af..10211893f5 100644 --- a/src/views/admin/appearance/skins.tpl +++ b/src/views/admin/appearance/skins.tpl @@ -12,7 +12,7 @@
-
+
Revert to Default
@@ -29,4 +29,4 @@ t.render(data); }); }; - \ No newline at end of file + diff --git a/src/views/admin/development/logger.tpl b/src/views/admin/development/logger.tpl index 826f9e5bcc..6e9a932230 100644 --- a/src/views/admin/development/logger.tpl +++ b/src/views/admin/development/logger.tpl @@ -40,7 +40,7 @@
-
+
Logger Control Panel
diff --git a/src/views/admin/extend/plugins.tpl b/src/views/admin/extend/plugins.tpl index eb709885a2..b44c2461bc 100644 --- a/src/views/admin/extend/plugins.tpl +++ b/src/views/admin/extend/plugins.tpl @@ -79,7 +79,7 @@
-
+
Plugin Search
@@ -96,4 +96,4 @@
-
\ No newline at end of file +
diff --git a/src/views/admin/general/languages.tpl b/src/views/admin/general/languages.tpl index bc75b2fee4..b2365e91a3 100644 --- a/src/views/admin/general/languages.tpl +++ b/src/views/admin/general/languages.tpl @@ -25,7 +25,7 @@
-
+
Languages Control Panel
@@ -37,4 +37,4 @@ \ No newline at end of file + diff --git a/src/views/admin/general/sounds.tpl b/src/views/admin/general/sounds.tpl index 3556bcbb7d..fb43c138aa 100644 --- a/src/views/admin/general/sounds.tpl +++ b/src/views/admin/general/sounds.tpl @@ -58,7 +58,7 @@
-
+
Sounds Control Panel
@@ -66,4 +66,4 @@
-
\ No newline at end of file +
diff --git a/src/views/admin/manage/categories.tpl b/src/views/admin/manage/categories.tpl index 2c0dcf48da..711cdbce72 100644 --- a/src/views/admin/manage/categories.tpl +++ b/src/views/admin/manage/categories.tpl @@ -132,7 +132,7 @@
-
+
Categories Control Panel
@@ -153,4 +153,4 @@
-
\ No newline at end of file +
diff --git a/src/views/admin/manage/flags.tpl b/src/views/admin/manage/flags.tpl index 929fd6674d..23a5d6f796 100644 --- a/src/views/admin/manage/flags.tpl +++ b/src/views/admin/manage/flags.tpl @@ -41,7 +41,7 @@
-
+
Flags Control Panel
@@ -52,5 +52,3 @@
- - diff --git a/src/views/admin/manage/groups.tpl b/src/views/admin/manage/groups.tpl index 69f8bad37b..26fe157dac 100644 --- a/src/views/admin/manage/groups.tpl +++ b/src/views/admin/manage/groups.tpl @@ -37,7 +37,7 @@
-
+
Groups Control Panel
diff --git a/src/views/admin/manage/tags.tpl b/src/views/admin/manage/tags.tpl index afacffb2d4..1b8c687b00 100644 --- a/src/views/admin/manage/tags.tpl +++ b/src/views/admin/manage/tags.tpl @@ -1,11 +1,11 @@
- -
- Your forum does not have any topics with tags yet! -
-
+ +
+ Your forum does not have any topics with tags yet! +
+
Tag Management
@@ -34,7 +34,7 @@
-
+
Modify Tag
@@ -52,4 +52,4 @@
-
\ No newline at end of file +
diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl index 1e034474b8..e68cef75ee 100644 --- a/src/views/admin/manage/users.tpl +++ b/src/views/admin/manage/users.tpl @@ -123,7 +123,7 @@
-
+
Users Control Panel
@@ -132,4 +132,4 @@
-
\ No newline at end of file +
diff --git a/src/views/admin/settings/footer.tpl b/src/views/admin/settings/footer.tpl index 77b495e33c..78e62335c5 100644 --- a/src/views/admin/settings/footer.tpl +++ b/src/views/admin/settings/footer.tpl @@ -1,6 +1,6 @@
-
+
Save Settings
@@ -14,4 +14,4 @@ require(['admin/settings'], function(Settings) { Settings.prepare(); }); - \ No newline at end of file + From 081462983a2bb82452a15127b87bf70d4dd5c2fe Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 11 Feb 2015 11:34:33 -0500 Subject: [PATCH 130/164] refactored the groups update method a bit, and now if a group has pending members and it becomes a public group, those users become members --- src/groups.js | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/groups.js b/src/groups.js index 7567c662f5..f82e452b96 100644 --- a/src/groups.js +++ b/src/groups.js @@ -503,7 +503,11 @@ var async = require('async'), 'private': values.private === false ? '0' : '1' }; - db.setObject('group:' + groupName, payload, function(err) { + async.series([ + async.apply(updatePrivacy, groupName, values.private), + async.apply(db.setObject, 'group:' + groupName, payload), + async.apply(renameGroup, groupName, values.name) + ], function(err) { if (err) { return callback(err); } @@ -512,11 +516,37 @@ var async = require('async'), name: groupName, values: values }); - renameGroup(groupName, values.name, callback); + callback(); }); }); }; + function updatePrivacy(groupName, newValue, callback) { + // Grab the group's current privacy value + Groups.getGroupFields(groupName, ['private'], function(err, currentValue) { + currentValue = currentValue.private === '1'; // Now a Boolean + + if (currentValue !== newValue && currentValue === true) { + // Group is now public, so all pending users are automatically considered members + db.getSetMembers('group:' + groupName + ':pending', function(err, uids) { + if (err) { return callback(err); } + else if (!uids) { return callback(); } // No pending users, we're good to go + + var now = Date.now(), + scores = uids.map(function() { return now; }); // There's probably a better way to initialise an Array of size x with the same value... + + winston.verbose('[groups.update] Group is now public, automatically adding ' + uids.length + ' new members, who were pending prior.'); + async.series([ + async.apply(db.sortedSetAdd, 'group:' + groupName + ':members', scores, uids), + async.apply(db.delete, 'group:' + groupName + ':pending') + ], callback); + }); + } else { + callback(); + } + }); + } + function renameGroup(oldName, newName, callback) { if (oldName === newName || !newName || newName.length === 0) { return callback(); From 749ce5f8e5a9848c9fb462679a689f0da66df431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Feb 2015 12:01:46 -0500 Subject: [PATCH 131/164] dont crash if callback isnt supplied to list methods --- src/database/redis/list.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/database/redis/list.js b/src/database/redis/list.js index 115a56a767..7ebc068d53 100644 --- a/src/database/redis/list.js +++ b/src/database/redis/list.js @@ -2,34 +2,40 @@ module.exports = function(redisClient, module) { module.listPrepend = function(key, value, callback) { + callback = callback || function() {}; redisClient.lpush(key, value, function(err, res) { callback(err); }); }; module.listAppend = function(key, value, callback) { + callback = callback || function() {}; redisClient.rpush(key, value, function(err, res) { callback(err); }); }; module.listRemoveLast = function(key, callback) { + callback = callback || function() {}; redisClient.rpop(key, callback); }; module.listRemoveAll = function(key, value, callback) { + callback = callback || function() {}; redisClient.lrem(key, 0, value, function(err, res) { callback(err); }); }; module.listTrim = function(key, start, stop, callback) { + callback = callback || function() {}; redisClient.ltrim(key, start, stop, function(err, res) { callback(err); }); }; module.getListRange = function(key, start, stop, callback) { + callback = callback || function() {}; redisClient.lrange(key, start, stop, callback); }; }; \ No newline at end of file From f3d1e96c24554e04710a46cc462a9c010a5f8830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Feb 2015 12:12:37 -0500 Subject: [PATCH 132/164] filter deleted topics on popular --- src/topics/popular.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/topics/popular.js b/src/topics/popular.js index ce2182cabf..a1149914fc 100644 --- a/src/topics/popular.js +++ b/src/topics/popular.js @@ -34,10 +34,12 @@ module.exports = function(Topics) { function getTopics(tids, uid, count, callback) { async.waterfall([ function(next) { - Topics.getTopicsFields(tids, ['tid', 'postcount'], next); + Topics.getTopicsFields(tids, ['tid', 'postcount', 'deleted'], next); }, function(topics, next) { - tids = topics.sort(function(a, b) { + tids = topics.filter(function(topic) { + return topic && parseInt(topic.deleted, 10) !== 1; + }).sort(function(a, b) { return b.postcount - a.postcount; }).slice(0, count).map(function(topic) { return topic.tid; From 0c5c0bf08ab46d0a4de435c204f6fbda28bfe955 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 11 Feb 2015 12:23:11 -0500 Subject: [PATCH 133/164] making userRow selector less specific, in group details.js --- public/src/client/groups/details.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js index b40957af8a..1d651fad27 100644 --- a/public/src/client/groups/details.js +++ b/public/src/client/groups/details.js @@ -19,7 +19,7 @@ define('forum/groups/details', ['iconSelect', 'vendor/colorpicker/colorpicker', detailsPage.on('click', '[data-action]', function() { var btnEl = $(this), - userRow = btnEl.parents('tr'), + userRow = btnEl.parents('[data-uid]'), ownerFlagEl = userRow.find('.member-name i'), isOwner = !ownerFlagEl.hasClass('invisible') ? true : false, uid = userRow.attr('data-uid'), From 8a581ed1ddce50872b9d6f70be6603127f9c2ebc Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 11 Feb 2015 12:30:48 -0500 Subject: [PATCH 134/164] fixes #2711 :rage2: --- public/src/ajaxify.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index d2af431176..cd87159420 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -275,7 +275,9 @@ $(document).ready(function() { // Enhancing all anchors to ajaxify... $(document.body).on('click', 'a', function (e) { - if (hrefEmpty(this.href) || this.target !== '' || this.protocol === 'javascript:' || $(this).attr('data-ajaxify') === 'false') { + if (this.target !== '') { + return; + } else if (hrefEmpty(this.href) || this.protocol === 'javascript:' || $(this).attr('data-ajaxify') === 'false') { return e.preventDefault(); } From d20628a8d4458e3dbde79c24fac82f7c15d452e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Feb 2015 12:54:54 -0500 Subject: [PATCH 135/164] closes #2539 --- public/src/app.js | 29 ++++++++------------------ public/src/client/account/edit.js | 4 ++-- public/src/client/account/settings.js | 2 +- public/src/client/chats.js | 2 +- public/src/client/footer.js | 2 +- public/src/client/topic.js | 2 +- public/src/client/topic/browsing.js | 2 +- public/src/client/topic/events.js | 2 +- public/src/client/topic/posts.js | 10 ++++----- public/src/client/topic/threadTools.js | 2 +- public/src/modules/chat.js | 2 +- public/src/modules/composer.js | 14 ++++++------- src/socket.io/index.js | 27 +++++++----------------- 13 files changed, 38 insertions(+), 62 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index 1e5b92cf4d..5010ead25d 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -10,10 +10,6 @@ app.currentRoom = null; app.widgets = {}; app.cacheBuster = null; -// TODO: deprecate in 0.7.0, use app.user -app.username = null; -app.uid = null; - (function () { var showWelcomeMessage = false; var reconnecting = false; @@ -29,14 +25,7 @@ app.uid = null; socket = io.connect(config.websocketAddress, ioParams); reconnecting = false; - socket.on('event:connect', function (data) { - // TODO : deprecate in 0.7.0, use app.user - app.username = data.username; - app.userslug = data.userslug; - app.picture = data.picture; - app.uid = data.uid; - app.isAdmin = data.isAdmin; - + socket.on('event:connect', function () { app.showLoginMessage(); app.replaceSelfLinks(); $(window).trigger('action:connected'); @@ -182,9 +171,9 @@ app.uid = null; socket.emit('meta.rooms.enter', { enter: room, - username: app.username, - userslug: app.userslug, - picture: app.picture + username: app.user.username, + userslug: app.user.userslug, + picture: app.user.picture }); app.currentRoom = room; @@ -232,8 +221,8 @@ app.uid = null; selector = selector || $('a'); selector.each(function() { var href = $(this).attr('href'); - if (href && app.userslug && href.indexOf('user/_self_') !== -1) { - $(this).attr('href', href.replace(/user\/_self_/g, 'user/' + app.userslug)); + if (href && app.user.userslug && href.indexOf('user/_self_') !== -1) { + $(this).attr('href', href.replace(/user\/_self_/g, 'user/' + app.user.userslug)); } }); }; @@ -261,7 +250,7 @@ app.uid = null; function showAlert() { app.alert({ type: 'success', - title: '[[global:welcome_back]] ' + app.username + '!', + title: '[[global:welcome_back]] ' + app.user.username + '!', message: '[[global:you_have_successfully_logged_in]]', timeout: 5000 }); @@ -278,11 +267,11 @@ app.uid = null; }; app.openChat = function (username, touid) { - if (username === app.username) { + if (username === app.user.username) { return app.alertError('[[error:cant-chat-with-yourself]]'); } - if (!app.uid) { + if (!app.user.uid) { return app.alertError('[[error:not-logged-in]]'); } diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js index f85e00951c..dc8bfaeaf1 100644 --- a/public/src/client/account/edit.js +++ b/public/src/client/account/edit.js @@ -152,7 +152,7 @@ define('forum/account/edit', ['forum/account/header', 'uploader'], function(head return; } - if ($('#confirm-username').val() !== app.username) { + if ($('#confirm-username').val() !== app.user.username) { app.alertError('[[error:invalid-username]]'); return false; } else { @@ -266,7 +266,7 @@ define('forum/account/edit', ['forum/account/header', 'uploader'], function(head password_confirm.on('blur', onPasswordConfirmChanged); $('#changePasswordBtn').on('click', function() { - if ((passwordvalid && passwordsmatch) || app.isAdmin) { + if ((passwordvalid && passwordsmatch) || app.user.isAdmin) { socket.emit('user.changePassword', { 'currentPassword': currentPassword.val(), 'newPassword': password.val(), diff --git a/public/src/client/account/settings.js b/public/src/client/account/settings.js index 0b4bbbd00f..fef95fc495 100644 --- a/public/src/client/account/settings.js +++ b/public/src/client/account/settings.js @@ -44,7 +44,7 @@ define('forum/account/settings', ['forum/account/header'], function(header) { } app.exposeConfigToTemplates(); - if (parseInt(app.uid, 10) === parseInt(ajaxify.variables.get('theirid'), 10)) { + if (parseInt(app.user.uid, 10) === parseInt(ajaxify.variables.get('theirid'), 10)) { ajaxify.refresh(); } }); diff --git a/public/src/client/chats.js b/public/src/client/chats.js index 607b84d4f3..994ddeb47a 100644 --- a/public/src/client/chats.js +++ b/public/src/client/chats.js @@ -193,7 +193,7 @@ define('forum/chats', ['string', 'sounds', 'forum/infinitescroll'], function(S, Chats.notifyTyping = function(toUid, typing) { socket.emit('modules.chats.user' + (typing ? 'Start' : 'Stop') + 'Typing', { touid: toUid, - fromUid: app.uid + fromUid: app.user.uid }); }; diff --git a/public/src/client/footer.js b/public/src/client/footer.js index 775686aaa2..ff44f25e1e 100644 --- a/public/src/client/footer.js +++ b/public/src/client/footer.js @@ -31,7 +31,7 @@ define('forum/footer', ['notifications', 'chat'], function(Notifications, Chat) if (data && data.posts && data.posts.length) { var post = data.posts[0]; - if (parseInt(post.uid, 10) !== parseInt(app.uid, 10) && !unreadTopics[post.topic.tid]) { + if (parseInt(post.uid, 10) !== parseInt(app.user.uid, 10) && !unreadTopics[post.topic.tid]) { increaseUnreadCount(); markTopicsUnread(post.topic.tid); unreadTopics[post.topic.tid] = true; diff --git a/public/src/client/topic.js b/public/src/client/topic.js index 621521eaed..f5627a02d5 100644 --- a/public/src/client/topic.js +++ b/public/src/client/topic.js @@ -59,7 +59,7 @@ define('forum/topic', [ $(window).trigger('action:topic.loaded'); - if (app.uid) { + if (app.user.uid) { socket.emit('topics.enter', tid, function(err, data) { if (err) { return app.alertError(err.message); diff --git a/public/src/client/topic/browsing.js b/public/src/client/topic/browsing.js index 6541cdf68a..dd768391e1 100644 --- a/public/src/client/topic/browsing.js +++ b/public/src/client/topic/browsing.js @@ -74,7 +74,7 @@ define('forum/topic/browsing', function() { } var activeEl = $('.thread_active_users'); var userEl = createUserIcon(user.uid, user.picture, user.userslug, user.username); - var isSelf = parseInt(user.uid, 10) === parseInt(app.uid, 10); + var isSelf = parseInt(user.uid, 10) === parseInt(app.user.uid, 10); if (isSelf) { activeEl.prepend(userEl); } else { diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index f4c69a121e..c90dd149b5 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -156,7 +156,7 @@ define('forum/topic/events', [ var isDeleted = postEl.hasClass('deleted'); postTools.toggle(data.pid, isDeleted); - if (!app.isAdmin && parseInt(data.uid, 10) !== parseInt(app.uid, 10)) { + if (!app.user.isAdmin && parseInt(data.uid, 10) !== parseInt(app.user.uid, 10)) { if (isDeleted) { postEl.find('.post-content').translateHtml('[[topic:post_is_deleted]]'); } else { diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index 05bc505ae2..57bf5a1e15 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -34,7 +34,7 @@ define('forum/topic/posts', [ var posts = data.posts; if (pagination.currentPage === pagination.pageCount) { createNewPosts(data); - } else if(data.posts && data.posts.length && parseInt(data.posts[0].uid, 10) === parseInt(app.uid, 10)) { + } else if(data.posts && data.posts.length && parseInt(data.posts[0].uid, 10) === parseInt(app.user.uid, 10)) { pagination.loadPage(pagination.pageCount); } } @@ -134,7 +134,7 @@ define('forum/topic/posts', [ } function onNewPostsLoaded(html, pids) { - if (app.uid) { + if (app.user.uid) { socket.emit('posts.getPrivileges', pids, function(err, privileges) { if(err) { return app.alertError(err.message); @@ -163,8 +163,8 @@ define('forum/topic/posts', [ postEl.find('.move').remove(); } postEl.find('.reply, .quote').toggleClass('hidden', !$('.post_reply').length); - var isSelfPost = parseInt(postEl.attr('data-uid'), 10) === parseInt(app.uid, 10); - postEl.find('.chat, .flag').toggleClass('hidden', isSelfPost || !app.uid); + var isSelfPost = parseInt(postEl.attr('data-uid'), 10) === parseInt(app.user.uid, 10); + postEl.find('.chat, .flag').toggleClass('hidden', isSelfPost || !app.user.uid); } Posts.loadMorePosts = function(direction) { @@ -202,7 +202,7 @@ define('forum/topic/posts', [ done(); }); } else { - if (app.uid) { + if (app.user.uid) { socket.emit('topics.markAsRead', [tid]); } navigator.update(); diff --git a/public/src/client/topic/threadTools.js b/public/src/client/topic/threadTools.js index b401a850ed..c3923e2720 100644 --- a/public/src/client/topic/threadTools.js +++ b/public/src/client/topic/threadTools.js @@ -99,7 +99,7 @@ define('forum/topic/threadTools', ['forum/topic/fork', 'forum/topic/move'], func ThreadTools.setLockedState = function(data) { var threadEl = $('#post-container'); if (parseInt(data.tid, 10) === parseInt(threadEl.attr('data-tid'), 10)) { - var isLocked = data.isLocked && !app.isAdmin; + var isLocked = data.isLocked && !app.user.isAdmin; $('.lock_thread').translateHtml(' [[topic:thread_tools.' + (data.isLocked ? 'un': '') + 'lock]]'); diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 02fcbba02e..06e8c75c7d 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -74,7 +74,7 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, } var username = data.message.fromUser.username; - var isSelf = parseInt(data.message.fromUser.uid, 10) === parseInt(app.uid, 10); + var isSelf = parseInt(data.message.fromUser.uid, 10) === parseInt(app.user.uid, 10); data.message.self = data.self; if (isSelf) { username = data.message.toUser.username; diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index 2836967416..088cafe260 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -68,13 +68,13 @@ define('composer', [ }); // Construct a save_id - if (0 !== parseInt(app.uid, 10)) { + if (0 !== parseInt(app.user.uid, 10)) { if (post.hasOwnProperty('cid')) { - post.save_id = ['composer', app.uid, 'cid', post.cid].join(':'); + post.save_id = ['composer', app.user.uid, 'cid', post.cid].join(':'); } else if (post.hasOwnProperty('tid')) { - post.save_id = ['composer', app.uid, 'tid', post.tid].join(':'); + post.save_id = ['composer', app.user.uid, 'tid', post.tid].join(':'); } else if (post.hasOwnProperty('pid')) { - post.save_id = ['composer', app.uid, 'pid', post.pid].join(':'); + post.save_id = ['composer', app.user.uid, 'pid', post.pid].join(':'); } } @@ -183,7 +183,7 @@ define('composer', [ function emit() { socket.emit('modules.composer.notifyTyping', { tid: postData.tid, - uid: app.uid + uid: app.user.uid }); } @@ -203,7 +203,7 @@ define('composer', [ } socket.emit('modules.composer.stopNotifyTyping', { tid: postData.tid, - uid: app.uid + uid: app.user.uid }); } @@ -219,7 +219,7 @@ define('composer', [ isTopic = composer.posts[post_uuid] ? !!composer.posts[post_uuid].cid : false, isMain = composer.posts[post_uuid] ? !!composer.posts[post_uuid].isMain : false, isEditing = composer.posts[post_uuid] ? !!composer.posts[post_uuid].pid : false, - isGuestPost = composer.posts[post_uuid] ? composer.posts[post_uuid].uid === '0' : null; + isGuestPost = composer.posts[post_uuid] ? parseInt(composer.posts[post_uuid].uid, 10) === 0 : null; composer.bsEnvironment = utils.findBootstrapEnvironment(); diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 8144fbc835..98d1d6e2e8 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -66,32 +66,19 @@ function onConnect(socket) { socket.join('uid_' + socket.uid); socket.join('online_users'); - async.parallel({ - user: function(next) { - user.getUserFields(socket.uid, ['username', 'userslug', 'picture', 'status', 'email:confirmed'], next); - }, - isAdmin: function(next) { - user.isAdministrator(socket.uid, next); - } - }, function(err, userData) { - if (err || !userData.user) { + user.getUserFields(socket.uid, ['status'], function(err, userData) { + if (err || !userData) { return; } - userData.user.uid = socket.uid; - userData.user.isAdmin = userData.isAdmin; - userData.user['email:confirmed'] = parseInt(userData.user['email:confirmed'], 10) === 1; - socket.emit('event:connect', userData.user); - if (userData.user.status !== 'offline') { - socket.broadcast.emit('event:user_status_change', {uid: socket.uid, status: userData.user.status || 'online'}); + + socket.emit('event:connect'); + if (userData.status !== 'offline') { + socket.broadcast.emit('event:user_status_change', {uid: socket.uid, status: userData.status || 'online'}); } }); } else { socket.join('online_guests'); - socket.emit('event:connect', { - username: '[[global:guest]]', - isAdmin: false, - uid: 0 - }); + socket.emit('event:connect'); } } From 7d963e52cf4fcf45c7aa737942c8e9ad06385632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Feb 2015 13:44:54 -0500 Subject: [PATCH 136/164] closes #2686 --- public/src/client/account/profile.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/src/client/account/profile.js b/public/src/client/account/profile.js index 421fc006ef..89a555a702 100644 --- a/public/src/client/account/profile.js +++ b/public/src/client/account/profile.js @@ -41,6 +41,9 @@ define('forum/account/profile', ['forum/account/header', 'forum/infinitescroll'] function processPage() { $('.user-recent-posts img, .post-signature img').addClass('img-responsive'); + + $('.user-recent-posts blockquote').prev('p').remove(); + $('.user-recent-posts blockquote').remove(); } function updateButtons() { From 329343686752d501dd18e735aa8cb2acc47b09e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Feb 2015 14:44:56 -0500 Subject: [PATCH 137/164] closes #2640 --- public/src/admin/manage/users.js | 13 +++++++++++++ src/emailer.js | 1 + src/socket.io/admin/user.js | 29 +++++++++++++++++++++++++++-- src/user/email.js | 15 ++++++++++++--- src/views/admin/manage/users.tpl | 1 + 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index fdd63556e4..dad64e35af 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -134,6 +134,19 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable) return false; }); + $('.send-validation-email').on('click', function() { + var uids = getSelectedUids(); + if (!uids.length) { + return; + } + socket.emit('admin.user.sendValidationEmail', uids, function(err) { + if (err) { + return app.alertError(err.message); + } + app.alertSuccess('[[notifications:email-confirm-sent]]'); + }); + }) + $('.password-reset-email').on('click', function() { var uids = getSelectedUids(); if (!uids.length) { diff --git a/src/emailer.js b/src/emailer.js index e7c92fa812..557de96f6e 100644 --- a/src/emailer.js +++ b/src/emailer.js @@ -64,6 +64,7 @@ var fs = require('fs'), uid: uid, pid: params.pid }); + callback(); } else { winston.warn('[emailer] No active email plugin found!'); callback(); diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index aab9eb02e8..0fa583d742 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -1,12 +1,13 @@ "use strict"; -var db = require('../../database'), +var async = require('async'), + db = require('../../database'), groups = require('../../groups'), user = require('../../user'), events = require('../../events'), + meta = require('../../meta'), websockets = require('../index'), - async = require('async'), User = {}; @@ -127,6 +128,30 @@ User.validateEmail = function(socket, uids, callback) { }, callback); }; +User.sendValidationEmail = function(socket, uids, callback) { + if (!Array.isArray(uids)) { + return callback(new Error('[[error:invalid-data]]')); + } + + if (parseInt(meta.config.requireEmailConfirmation, 10) !== 1) { + return callback(new Error('[[error:email-confirmations-are-disabled]]')); + } + + user.getMultipleUserFields(uids, ['uid', 'email'], function(err, usersData) { + if (err) { + return callback(err); + } + + async.eachLimit(usersData, 50, function(userData, next) { + if (userData.email && userData.uid) { + user.email.verify(userData.uid, userData.email, next); + } else { + next(); + } + }, callback); + }); +}; + User.sendPasswordResetEmail = function(socket, uids, callback) { if (!Array.isArray(uids)) { return callback(new Error('[[error:invalid-data]]')); diff --git a/src/user/email.js b/src/user/email.js index 9a4fd2cd73..74b86c0cfe 100644 --- a/src/user/email.js +++ b/src/user/email.js @@ -27,11 +27,16 @@ var async = require('async'), }); }; - UserEmail.verify = function(uid, email) { + UserEmail.verify = function(uid, email, callback) { + callback = callback || function() {}; var confirm_code = utils.generateUUID(), confirm_link = nconf.get('url') + '/confirm/' + confirm_code; plugins.fireHook('filter:user.verify.code', confirm_code, function(err, confirm_code) { + if (err) { + return callback(err); + } + async.series([ function(next) { db.setObject('confirm:' + confirm_code, { @@ -43,7 +48,9 @@ var async = require('async'), db.expireAt('confirm:' + confirm_code, Math.floor(Date.now() / 1000 + 60 * 60 * 2), next); } ], function(err) { - + if (err) { + return callback(err); + } user.getUserField(uid, 'username', function(err, username) { if (err) { return winston.error(err.stack); @@ -64,10 +71,12 @@ var async = require('async'), if (plugins.hasListeners('action:user.verify')) { plugins.fireHook('action:user.verify', {uid: uid, data: data}); + callback(); } else if (plugins.hasListeners('action:email.send')) { - emailer.send('welcome', uid, data); + emailer.send('welcome', uid, data, callback); } else { winston.warn('No emailer to send verification email!'); + callback(); } }); }); diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl index 1e034474b8..13aa80caa4 100644 --- a/src/views/admin/manage/users.tpl +++ b/src/views/admin/manage/users.tpl @@ -18,6 +18,7 @@
  • Remove Admin
  • Validate Email
  • +
  • Send Validation Email
  • Send Password Reset Email
  • Ban User
  • From 3f31098144c278b2834a2e7389f0e0c98a327dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Feb 2015 16:16:32 -0500 Subject: [PATCH 138/164] closes #2619 --- src/controllers/accounts.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js index 77cbe1008b..13055ca852 100644 --- a/src/controllers/accounts.js +++ b/src/controllers/accounts.js @@ -521,9 +521,10 @@ accountsController.getChats = function(req, res, next) { async.waterfall([ async.apply(user.getUidByUserslug, req.params.userslug), function(toUid, next) { - if (!toUid) { + if (!toUid || parseInt(toUid, 10) === parseInt(req.user.uid, 10)) { return helpers.notFound(req, res); } + async.parallel({ toUser: async.apply(user.getUserFields, toUid, ['uid', 'username']), messages: async.apply(messaging.getMessages, req.user.uid, toUid, 'recent', false), From a583f9d77adf1e666cc6bd56e82a51ff3a2e83c3 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Wed, 11 Feb 2015 14:56:57 -0700 Subject: [PATCH 139/164] Fixed sidebar overlay issue on window width Had the wrong `min-width` --- public/less/admin/admin.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/less/admin/admin.less b/public/less/admin/admin.less index 6beb1525fd..8a508db2e0 100644 --- a/public/less/admin/admin.less +++ b/public/less/admin/admin.less @@ -268,7 +268,7 @@ display: inline-block; } -@media (min-width: 768px) { +@media (min-width: 1200px) { .acp-sidebar { position: fixed; top: 70px; From 2b9d1ee3dd638092df8fc9e5d07895a888488985 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Wed, 11 Feb 2015 16:05:05 -0700 Subject: [PATCH 140/164] Translate ACP pages I fixed it --- src/middleware/middleware.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/middleware/middleware.js b/src/middleware/middleware.js index 111b0b1ceb..b8b5885424 100644 --- a/src/middleware/middleware.js +++ b/src/middleware/middleware.js @@ -409,7 +409,10 @@ middleware.processRender = function(req, res, next) { }); } else if (res.locals.adminHeader) { str = res.locals.adminHeader + str; - fn(err, str); + var language = res.locals.config ? res.locals.config.userLang || 'en_GB' : 'en_GB'; + translator.translate(str, language, function(translated) { + fn(err, translated); + }); } else { fn(err, str); } From 06b2a6ff68d55200dec66d050f3ad49deb83c917 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 11 Feb 2015 21:09:43 -0500 Subject: [PATCH 141/164] closes #2717 --- public/src/widgets.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/public/src/widgets.js b/public/src/widgets.js index 2200f58d5e..936ce9cd95 100644 --- a/public/src/widgets.js +++ b/public/src/widgets.js @@ -53,8 +53,7 @@ if (location === 'footer' && !$('#content [widget-area="footer"]').length) { $('#content').append($('
    ')); } else if (location === 'sidebar' && !$('#content [widget-area="sidebar"]').length) { - $('#content > *').wrapAll($('
    ')); - $('#content').append($('
    ')); + $('#content > *').wrapAll($('
    ')); } else if (location === 'header' && !$('#content [widget-area="header"]').length) { $('#content').prepend($('
    ')); } @@ -69,11 +68,11 @@ ajaxify.widgets.reposition(location); } - $('#content [widget-area] img:not(.user-img)').addClass('img-responsive'); + $('#content [widget-area] img:not(.user-img)').addClass('img-responsive'); } - + $(window).trigger('action:widgets.loaded', {}); - + if (typeof callback === 'function') { callback(); } From 5dfafff421ab377f466ac10056ea919b62c7e0db Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 11 Feb 2015 21:26:26 -0500 Subject: [PATCH 142/164] call callback on password update --- public/src/client/account/edit.js | 3 +++ src/socket.io/user.js | 1 + 2 files changed, 4 insertions(+) diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js index dc8bfaeaf1..86e5d1f66d 100644 --- a/public/src/client/account/edit.js +++ b/public/src/client/account/edit.js @@ -266,12 +266,15 @@ define('forum/account/edit', ['forum/account/header', 'uploader'], function(head password_confirm.on('blur', onPasswordConfirmChanged); $('#changePasswordBtn').on('click', function() { + var btn = $(this); if ((passwordvalid && passwordsmatch) || app.user.isAdmin) { + btn.addClass('disabled').find('i').removeClass('hide'); socket.emit('user.changePassword', { 'currentPassword': currentPassword.val(), 'newPassword': password.val(), 'uid': ajaxify.variables.get('theirid') }, function(err) { + btn.removeClass('disabled').find('i').addClass('hide'); currentPassword.val(''); password.val(''); password_confirm.val(''); diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 4df8915994..5f844650a6 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -151,6 +151,7 @@ SocketUser.changePassword = function(socket, data, callback) { targetUid: data.uid, ip: socket.ip }); + callback(); }); }; From a62a3647a0bf74eabb5d7a64fcbe0ce3ca66575a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 11 Feb 2015 21:53:53 -0500 Subject: [PATCH 143/164] use uid, socket.uid is always 0 here --- src/socket.io/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 5f844650a6..f2af4eeccd 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -107,7 +107,7 @@ SocketUser.reset.commit = function(socket, data, callback) { }); events.log({ type: 'password-reset', - uid: socket.uid, + uid: uid, ip: socket.ip }); callback(); From f99c3a310dc0074abd2c26575e6669d93340f9ad Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 11 Feb 2015 21:54:20 -0500 Subject: [PATCH 144/164] use uid instead of socket.uid --- src/socket.io/user.js | 53 +++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 5f844650a6..fd23405758 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -84,35 +84,38 @@ SocketUser.reset.send = function(socket, email, callback) { }; SocketUser.reset.commit = function(socket, data, callback) { - if(data && data.code && data.password) { - async.series([ - async.apply(db.getObjectField, 'reset:uid', data.code), - async.apply(user.reset.commit, data.code, data.password) - ], function(err, data) { - if (err) { - return callback(err); - } + if (!data || !data.code || !data.password) { + return callback(new Error('[[error:invalid-data]]')); + } - var uid = data[0], - now = new Date(), - parsedDate = now.getFullYear() + '/' + (now.getMonth()+1) + '/' + now.getDate(); + async.parallel({ + uid: async.apply(db.getObjectField, 'reset:uid', data.code), + reset: async.apply(user.reset.commit, data.code, data.password) + }, function(err, results) { + if (err) { + return callback(err); + } - user.getUserField(uid, 'username', function(err, username) { - emailer.send('reset_notify', uid, { - username: username, - date: parsedDate, - site_title: meta.config.title || 'NodeBB', - subject: '[[email:reset.notify.subject]]' - }); - }); - events.log({ - type: 'password-reset', - uid: socket.uid, - ip: socket.ip + var uid = results.uid, + now = new Date(), + parsedDate = now.getFullYear() + '/' + (now.getMonth()+1) + '/' + now.getDate(); + + user.getUserField(uid, 'username', function(err, username) { + emailer.send('reset_notify', uid, { + username: username, + date: parsedDate, + site_title: meta.config.title || 'NodeBB', + subject: '[[email:reset.notify.subject]]' }); - callback(); }); - } + + events.log({ + type: 'password-reset', + uid: uid, + ip: socket.ip + }); + callback(); + }); }; SocketUser.checkStatus = function(socket, uid, callback) { From 5cebcfba7a341f2d79e014aa23557d4f6c9e305a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 12 Feb 2015 11:49:26 -0500 Subject: [PATCH 145/164] update validator ver --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8de4dbc58c..a7907757e8 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "templates.js": "^0.1.15", "uglify-js": "git+https://github.com/julianlam/UglifyJS2.git", "underscore": "~1.7.0", - "validator": "~3.28.0", + "validator": "^3.30.0", "winston": "^0.9.0", "xregexp": "~2.0.0" }, From cdd5847b399c1f51d36c5d447c75e9177efad897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 12 Feb 2015 12:23:13 -0500 Subject: [PATCH 146/164] closes #2664 --- src/user.js | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/user.js b/src/user.js index 035933154a..109e67a3f0 100644 --- a/src/user.js +++ b/src/user.js @@ -7,6 +7,7 @@ var async = require('async'), plugins = require('./plugins'), db = require('./database'), meta = require('./meta'), + topics = require('./topics'), groups = require('./groups'), Password = require('./password'); @@ -147,25 +148,31 @@ var async = require('async'), User.updateOnlineUsers = function(uid, callback) { callback = callback || function() {}; - db.sortedSetScore('users:online', uid, function(err, score) { - var now = Date.now(); - if (err || now - parseInt(score, 10) < 300000) { - return callback(err); - } - db.sortedSetAdd('users:online', now, uid, function(err) { - if (err) { - return callback(err); + + var now = Date.now(); + async.waterfall([ + function(next) { + db.sortedSetScore('users:online', uid, next); + }, + function(userOnlineTime, next) { + if (now - parseInt(userOnlineTime, 10) < 300000) { + return callback(); } + db.sortedSetAdd('users:online', now, uid, next); + }, + function(next) { + topics.pushUnreadCount(uid); plugins.fireHook('action:user.online', {uid: uid, timestamp: now}); - }); - }); + next(); + } + ], callback); }; User.setUserField = function(uid, field, value, callback) { callback = callback || function() {}; db.setObjectField('user:' + uid, field, value, function(err) { if (err) { - return callback(err) + return callback(err); } plugins.fireHook('action:user.set', {uid: uid, field: field, value: value, type: 'set'}); callback(); From 0421b6ef06dc01daaa8949d8cb421b53df4fa5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 12 Feb 2015 13:04:49 -0500 Subject: [PATCH 147/164] closes #2639 --- public/language/en_GB/error.json | 2 + public/language/en_GB/tags.json | 2 +- public/src/modules/composer.js | 2 + public/src/modules/composer/tags.js | 12 +- .../bootstrap-tagsinput.css | 1 + .../bootstrap-tagsinput.min.js | 511 +----------------- .../bootstrap-tagsinput.min.js.map | 1 + src/controllers/api.js | 2 + 8 files changed, 26 insertions(+), 507 deletions(-) create mode 100644 public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 0258b28154..bf4e7229fd 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -52,6 +52,8 @@ "invalid-title": "Invalid title!", "too-many-posts": "You can only post once every %1 seconds - please wait before posting again", "too-many-posts-newbie": "As a new user, you can only post once every %1 seconds until you have earned %2 reputation - please wait before posting again", + "tag-too-short": "Please enter a longer tag. Tags should contain at least %1 characters", + "tag-too-long": "Please enter a shorter tag. Tags can't be longer than %1 characters", "file-too-big": "Maximum allowed file size is %1 kbs - please upload a smaller file", "cant-vote-self-post": "You cannot vote for your own post", diff --git a/public/language/en_GB/tags.json b/public/language/en_GB/tags.json index f67b2ca7b5..a3f75bb2e6 100644 --- a/public/language/en_GB/tags.json +++ b/public/language/en_GB/tags.json @@ -1,7 +1,7 @@ { "no_tag_topics": "There are no topics with this tag.", "tags": "Tags", - "enter_tags_here": "Enter tags here. Press enter after each tag.", + "enter_tags_here": "Enter tags here. %1-%2 characters. Press enter after each tag.", "enter_tags_here_short": "Enter tags...", "no_tags": "There are no tags yet." } \ No newline at end of file diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index 088cafe260..29154d1523 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -228,6 +228,8 @@ define('composer', [ var data = { allowTopicsThumbnail: allowTopicsThumbnail, showTags: isTopic || isMain, + minimumTagLength: config.minimumTagLength, + maximumTagLength: config.maximumTagLength, isTopic: isTopic, showHandleInput: (app.user.uid === 0 || (isEditing && isGuestPost && app.user.isAdmin)) && config.allowGuestHandles, handle: composer.posts[post_uuid] ? composer.posts[post_uuid].handle || '' : undefined diff --git a/public/src/modules/composer/tags.js b/public/src/modules/composer/tags.js index 93b33fbb38..f074a5abc2 100644 --- a/public/src/modules/composer/tags.js +++ b/public/src/modules/composer/tags.js @@ -14,7 +14,17 @@ define('composer/tags', function() { tagEl.tagsinput({ maxTags: config.tagsPerTopic, - confirmKeys: [13, 44] + confirmKeys: [13, 44], + trimValue: true + }); + + tagEl.on('beforeItemAdd', function(event) { + event.cancel = event.item.length < config.minimumTagLength || event.item.length > config.maximumTagLength; + if (event.item.length < config.minimumTagLength) { + app.alertError('[[error:tag-too-short, ' + config.minimumTagLength + ']]'); + } else if (event.item.length > config.maximumTagLength) { + app.alertError('[[error:tag-too-long, ' + config.maximumTagLength + ']]'); + } }); tagEl.on('itemAdded', function(event) { diff --git a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css index 98cfa7f3c1..55f7c09df0 100644 --- a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css +++ b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css @@ -10,6 +10,7 @@ border-radius: 4px; max-width: 100%; line-height: 22px; + cursor: text; } .bootstrap-tagsinput input { border: none; diff --git a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js index aff7ea6cb8..16be0abb93 100644 --- a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js +++ b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js @@ -1,506 +1,7 @@ -(function ($) { - "use strict"; +/* + * bootstrap-tagsinput v0.4.2 by Tim Schlechter + * + */ - var defaultOptions = { - tagClass: function(item) { - return 'label label-info'; - }, - itemValue: function(item) { - return item ? item.toString() : item; - }, - itemText: function(item) { - return this.itemValue(item); - }, - freeInput: true, - maxTags: undefined, - confirmKeys: [13], - onTagExists: function(item, $tag) { - $tag.hide().fadeIn(); - } - }; - - /** - * Constructor function - */ - function TagsInput(element, options) { - this.itemsArray = []; - - this.$element = $(element); - this.$element.hide(); - - this.isSelect = (element.tagName === 'SELECT'); - this.multiple = (this.isSelect && element.hasAttribute('multiple')); - this.objectItems = options && options.itemValue; - this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; - this.inputSize = Math.max(1, this.placeholderText.length); - - this.$container = $('
    '); - this.$input = $('').appendTo(this.$container); - - this.$element.after(this.$container); - - this.build(options); - } - - TagsInput.prototype = { - constructor: TagsInput, - - /** - * Adds the given item as a new tag. Pass true to dontPushVal to prevent - * updating the elements val() - */ - add: function(item, dontPushVal) { - var self = this; - - if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) - return; - - // Ignore falsey values, except false - if (item !== false && !item) - return; - - // Throw an error when trying to add an object while the itemValue option was not set - if (typeof item === "object" && !self.objectItems) - throw("Can't add objects when itemValue option is not set"); - - // Ignore strings only containg whitespace - if (item.toString().match(/^\s*$/)) - return; - - // If SELECT but not multiple, remove current tag - if (self.isSelect && !self.multiple && self.itemsArray.length > 0) - self.remove(self.itemsArray[0]); - - if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { - var items = item.split(','); - if (items.length > 1) { - for (var i = 0; i < items.length; i++) { - this.add(items[i], true); - } - - if (!dontPushVal) - self.pushVal(); - return; - } - } - - var itemValue = self.options.itemValue(item), - itemText = self.options.itemText(item), - tagClass = self.options.tagClass(item); - - // Ignore items allready added - var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; - if (existing) { - // Invoke onTagExists - if (self.options.onTagExists) { - var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); - self.options.onTagExists(item, $existingTag); - } - return; - } - - // register item in internal array and map - self.itemsArray.push(item); - - // add a tag element - var $tag = $('' + htmlEncode(itemText) + ''); - $tag.data('item', item); - self.findInputWrapper().before($tag); - $tag.after(' '); - - // add
    ")}}))}if(e.options.typeaheadjs){var j=e.options.typeaheadjs||{};e.$input.typeahead(null,j).on("typeahead:selected",a.proxy(function(a,b){e.add(j.valueKey?b[j.valueKey]:b),e.$input.typeahead("val","")},e))}e.$container.on("click",a.proxy(function(){e.$element.attr("disabled")||e.$input.removeAttr("disabled"),e.$input.focus()},e)),e.options.addOnBlur&&e.options.freeInput&&e.$input.on("focusout",a.proxy(function(){0===a(".typeahead, .twitter-typeahead",e.$container).length&&(e.add(e.$input.val()),e.$input.val(""))},e)),e.$container.on("keydown","input",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g&&e.remove(g.data("item"))}break;case 46:if(0===f(c[0])){var h=d.next();h&&e.remove(h.data("item"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus())}{var k=c.val().length;Math.ceil(k/5)}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("keypress","input",a.proxy(function(b){var c=a(b.target);if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");var d=c.val(),f=e.options.maxChars&&d.length>=e.options.maxChars;e.options.freeInput&&(g(b,e.options.confirmKeys)||f)&&(e.add(f?d.substr(0,e.options.maxChars):d),c.val(""),b.preventDefault());{var h=c.val().length;Math.ceil(h/5)}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("click","[data-role=remove]",a.proxy(function(b){e.$element.attr("disabled")||e.remove(a(b.target).closest(".tag").data("item"))},e)),e.options.itemValue===h.itemValue&&("INPUT"===e.$element[0].tagName?e.add(e.$element.val()):a("option",e.$element).each(function(){e.add(a(this).attr("value"),!0)}))},destroy:function(){var a=this;a.$container.off("keypress","input"),a.$container.off("click","[role=remove]"),a.$container.remove(),a.$element.removeData("tagsinput"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d){var e=[];return this.each(function(){var f=a(this).data("tagsinput");if(f)if(c||d){if(void 0!==f[c]){var g=f[c](d);void 0!==g&&e.push(g)}}else e.push(f);else f=new b(this,c),a(this).data("tagsinput",f),e.push(f),"SELECT"===this.tagName&&a("option",a(this)).attr("selected","selected"),a(this).val(a(this).val())}),"string"==typeof c?e.length>1?e:e[0]:e},a.fn.tagsinput.Constructor=b;var i=a("
    ");a(function(){a("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput()})}(window.jQuery); +//# sourceMappingURL=bootstrap-tagsinput.min.js.map \ No newline at end of file diff --git a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map new file mode 100644 index 0000000000..a0d198d16b --- /dev/null +++ b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dist/bootstrap-tagsinput-angular.min.js","sources":["src/bootstrap-tagsinput-angular.js"],"names":["angular","module","directive","getItemProperty","scope","property","isFunction","$parent","item","undefined","restrict","model","template","replace","link","element","attrs","$","isArray","select","typeaheadSourceArray","typeaheadSource","split","length","tagsinput","options","typeahead","source","itemValue","itemvalue","itemText","itemtext","confirmKeys","confirmkeys","JSON","parse","tagClass","tagclass","i","on","event","indexOf","push","idx","splice","prev","slice","$watch","added","filter","removed"],"mappings":";;;;;AAAAA,QAAQC,OAAO,0BACdC,UAAU,sBAAuB,WAEhC,QAASC,GAAgBC,EAAOC,GAC9B,MAAKA,GAGDL,QAAQM,WAAWF,EAAMG,QAAQF,IAC5BD,EAAMG,QAAQF,GAEhB,SAASG,GACd,MAAOA,GAAKH,IANLI,OAUX,OACEC,SAAU,KACVN,OACEO,MAAO,YAETC,SAAU,6BACVC,SAAS,EACTC,KAAM,SAASV,EAAOW,EAASC,GAC7BC,EAAE,WACKjB,QAAQkB,QAAQd,EAAMO,SACzBP,EAAMO,SAER,IAAIQ,GAASF,EAAE,SAAUF,GACrBK,EAAuBJ,EAAMK,gBAAkBL,EAAMK,gBAAgBC,MAAM,KAAO,KAClFD,EAAkBD,EACjBA,EAAqBG,OAAS,EAC3BnB,EAAMG,QAAQa,EAAqB,IAAIA,EAAqB,IAC1DhB,EAAMG,QAAQa,EAAqB,IACvC,IAEND,GAAOK,UAAUpB,EAAMG,QAAQS,EAAMS,SAAW,MAC9CC,WACEC,OAAW3B,QAAQM,WAAWe,GAAmBA,EAAkB,MAErEO,UAAWzB,EAAgBC,EAAOY,EAAMa,WACxCC,SAAW3B,EAAgBC,EAAOY,EAAMe,UACxCC,YAAc7B,EAAgBC,EAAOY,EAAMiB,aAAeC,KAAKC,MAAMnB,EAAMiB,cAAgB,IAC3FG,SAAWpC,QAAQM,WAAWF,EAAMG,QAAQS,EAAMqB,WAAajC,EAAMG,QAAQS,EAAMqB,UAAY,WAAiB,MAAOrB,GAAMqB,WAG/H,KAAK,GAAIC,GAAI,EAAGA,EAAIlC,EAAMO,MAAMY,OAAQe,IACtCnB,EAAOK,UAAU,MAAOpB,EAAMO,MAAM2B,GAGtCnB,GAAOoB,GAAG,YAAa,SAASC,GACU,KAApCpC,EAAMO,MAAM8B,QAAQD,EAAMhC,OAC5BJ,EAAMO,MAAM+B,KAAKF,EAAMhC,QAG3BW,EAAOoB,GAAG,cAAe,SAASC,GAChC,GAAIG,GAAMvC,EAAMO,MAAM8B,QAAQD,EAAMhC,KACxB,MAARmC,GACFvC,EAAMO,MAAMiC,OAAOD,EAAK,IAK5B,IAAIE,GAAOzC,EAAMO,MAAMmC,OACvB1C,GAAM2C,OAAO,QAAS,WACpB,GAEIT,GAFAU,EAAQ5C,EAAMO,MAAMsC,OAAO,SAASX,GAAI,MAA2B,KAApBO,EAAKJ,QAAQH,KAC5DY,EAAUL,EAAKI,OAAO,SAASX,GAAI,MAAkC,KAA3BlC,EAAMO,MAAM8B,QAAQH,IAMlE,KAHAO,EAAOzC,EAAMO,MAAMmC,QAGdR,EAAI,EAAGA,EAAIY,EAAQ3B,OAAQe,IAC9BnB,EAAOK,UAAU,SAAU0B,EAAQZ,GAOrC,KAHAnB,EAAOK,UAAU,WAGZc,EAAI,EAAGA,EAAIU,EAAMzB,OAAQe,IAC5BnB,EAAOK,UAAU,MAAOwB,EAAMV,MAE/B"} \ No newline at end of file diff --git a/src/controllers/api.js b/src/controllers/api.js index ae112b9bd6..c335cdf272 100644 --- a/src/controllers/api.js +++ b/src/controllers/api.js @@ -43,6 +43,8 @@ apiController.getConfig = function(req, res, next) { config.maxReconnectionAttempts = meta.config.maxReconnectionAttempts || 5; config.reconnectionDelay = meta.config.reconnectionDelay || 200; config.tagsPerTopic = meta.config.tagsPerTopic || 5; + config.minimumTagLength = meta.config.minimumTagLength || 3; + config.maximumTagLength = meta.config.maximumTagLength || 15; config.topicsPerPage = meta.config.topicsPerPage || 20; config.postsPerPage = meta.config.postsPerPage || 20; config.maximumFileSize = meta.config.maximumFileSize; From f4c587c530fd42a40cae5b1cf80dc74c894be250 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 12 Feb 2015 13:10:09 -0500 Subject: [PATCH 148/164] move hardcoded initial welcome text into welcome.md --- install/data/welcome.md | 10 ++++++++++ src/install.js | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 install/data/welcome.md diff --git a/install/data/welcome.md b/install/data/welcome.md new file mode 100644 index 0000000000..399850e6e2 --- /dev/null +++ b/install/data/welcome.md @@ -0,0 +1,10 @@ +# Welcome to your brand new NodeBB forum! + +This is what a topic and post looks like. As an administator, you can edit the post\'s title and content. +To customise your forum, go to the [Administrator Control Panel](../../admin). You can modify all aspects of your forum there, including installation of third-party plugins. + +## Additional Resources + +* [NodeBB Documentation](https://docs.nodebb.org) +* [Community Support Forum](https://community.nodebb.org) +* [Project repository](https://github.com/nodebb/nodebb) \ No newline at end of file diff --git a/src/install.js b/src/install.js index 54fb075ced..61f4bc56c0 100644 --- a/src/install.js +++ b/src/install.js @@ -389,13 +389,23 @@ function createWelcomePost(next) { var db = require('./database'), Topics = require('./topics'); - db.sortedSetCard('topics:tid', function(err, numTopics) { + async.parallel([ + function(next) { + fs.readFile(path.join(__dirname, '../', 'install/data/welcome.md'), next); + }, + function(next) { + db.sortedSetCard('topics:tid', next); + } + ], function(err, results) { + var content = results[0], + numTopics = results[1]; + if (numTopics === 0) { Topics.post({ uid: 1, cid: 2, title: 'Welcome to your NodeBB!', - content: '# Welcome to your brand new NodeBB forum!\n\nThis is what a topic and post looks like. As an administator, you can edit the post\'s title and content.\n\nTo customise your forum, go to the [Administrator Control Panel](../../admin). You can modify all aspects of your forum there, including installation of third-party plugins.\n\n## Additional Resources\n\n* [NodeBB Documentation](https://docs.nodebb.org)\n* [Community Support Forum](https://community.nodebb.org)\n* [Project repository](https://github.com/nodebb/nodebb)' + content: content.toString() }, next); } else { next(); From 429d7cbfa25f15a77bc670ab3dcb3f5cdced0a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 12 Feb 2015 13:23:12 -0500 Subject: [PATCH 149/164] added filter:category.get --- src/categories.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/categories.js b/src/categories.js index 22c7807c96..a4b6ce2092 100644 --- a/src/categories.js +++ b/src/categories.js @@ -64,7 +64,9 @@ var async = require('async'), category.isIgnored = results.isIgnored[0]; category.topic_row_size = 'col-md-9'; - callback(null, category); + plugins.fireHook('filter:category.get', {category: category, uid: data.uid}, function(err, data) { + callback(err, data ? data.category : null); + }); }); }); }; From 0d84486187b9475af47128bb2e6e2cb0b17d9a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 12 Feb 2015 13:38:19 -0500 Subject: [PATCH 150/164] closes #2585 --- src/postTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/postTools.js b/src/postTools.js index c00a8a4b9c..fc18277912 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -34,7 +34,7 @@ var winston = require('winston'), }, function(postData, next) { postData.content = data.content; - plugins.fireHook('filter:post.save', postData, next); + plugins.fireHook('filter:post.edit', {post: postData, uid: data.uid}, next); } ], function(err, postData) { if (err) { From 8cbb9aa3108488cc58c534b429c3918abd75b3bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 12 Feb 2015 13:42:45 -0500 Subject: [PATCH 151/164] #2585 --- src/postTools.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/postTools.js b/src/postTools.js index fc18277912..09fa75330a 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -36,11 +36,11 @@ var winston = require('winston'), postData.content = data.content; plugins.fireHook('filter:post.edit', {post: postData, uid: data.uid}, next); } - ], function(err, postData) { + ], function(err, data) { if (err) { return callback(err); } - + var postData = data.post; async.parallel({ post: function(next) { var d = { From 09b26bc950689e45db9d89f5e681a35db5dbe907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 12 Feb 2015 14:37:01 -0500 Subject: [PATCH 152/164] if code isnt validated return error --- src/user/reset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/reset.js b/src/user/reset.js index 3ce2f86cf8..60ff820dbf 100644 --- a/src/user/reset.js +++ b/src/user/reset.js @@ -63,7 +63,7 @@ var async = require('async'), } if (!validated) { - return; + return callback(new Error('[[error:reset-code-not-valid]]')); } db.getObjectField('reset:uid', code, function(err, uid) { From d09a53197ecbefe3655ae57847920a195cba0bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 12 Feb 2015 15:03:46 -0500 Subject: [PATCH 153/164] closes #2570 --- install/data/footer.json | 10 ++++++++++ src/install.js | 26 +++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 install/data/footer.json diff --git a/install/data/footer.json b/install/data/footer.json new file mode 100644 index 0000000000..69d55448ac --- /dev/null +++ b/install/data/footer.json @@ -0,0 +1,10 @@ +[ + { + "widget": "html", + "data" : { + "html": "", + "title":"", + "container":"" + } + } +] \ No newline at end of file diff --git a/src/install.js b/src/install.js index 61f4bc56c0..45d44d75ad 100644 --- a/src/install.js +++ b/src/install.js @@ -394,13 +394,13 @@ function createWelcomePost(next) { fs.readFile(path.join(__dirname, '../', 'install/data/welcome.md'), next); }, function(next) { - db.sortedSetCard('topics:tid', next); + db.getObjectField('global', 'topicCount', next); } ], function(err, results) { var content = results[0], numTopics = results[1]; - if (numTopics === 0) { + if (!parseInt(numTopics, 10)) { Topics.post({ uid: 1, cid: 2, @@ -430,12 +430,24 @@ function enableDefaultPlugins(next) { function setCopyrightWidget(next) { var db = require('./database'); - - db.init(function(err) { - if (!err) { - db.setObjectField('widgets:global', 'footer', "[{\"widget\":\"html\",\"data\":{\"html\":\"\",\"title\":\"\",\"container\":\"\"}}]", next); + async.parallel({ + footerJSON: function(next) { + fs.readFile(path.join(__dirname, '../', 'install/data/footer.json'), next); + }, + footer: function(next) { + db.getObjectField('widgets:global', 'footer', next); } - }); + }, function(err, results) { + if (err) { + return next(err); + } + + if (!results.footer && results.footerJSON) { + db.setObjectField('widgets:global', 'footer', results.footerJSON.toString(), next); + } else { + next(); + } + }); } install.setup = function (callback) { From 1029b6c2f327db2c48e5f5353bc93598fa1e2c34 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 12 Feb 2015 16:15:28 -0500 Subject: [PATCH 154/164] some prep for #2499 --- src/plugins.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins.js b/src/plugins.js index 0c8a4ba394..730377c673 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -6,6 +6,7 @@ var fs = require('fs'), winston = require('winston'), semver = require('semver'), express = require('express'), + nconf = require('nconf'), db = require('./database'), emitter = require('./emitter'), @@ -13,6 +14,7 @@ var fs = require('fs'), translator = require('../public/src/translator'), utils = require('../public/src/utils'), hotswap = require('./hotswap'), + pkg = require('../package.json'), controllers = require('./controllers'), app, middleware; @@ -169,7 +171,7 @@ var fs = require('fs'), Plugins.getAll = function(callback) { var request = require('request'); - request('https://packages.nodebb.org/api/v1/plugins', function(err, res, body) { + request((nconf.get('registry') || 'https://packages.nodebb.org') + '/api/v1/plugins/' + pkg.version, function(err, res, body) { var plugins = []; try { @@ -184,8 +186,9 @@ var fs = require('fs'), plugins[i].id = plugins[i].name; plugins[i].installed = false; plugins[i].active = false; - plugins[i].url = plugins[i].repository ? plugins[i].repository.url : ''; + plugins[i].url = plugins[i].url ? plugins[i].url : plugins[i].repository ? plugins[i].repository.url : ''; plugins[i].latest = getLatestVersion(plugins[i].versions); + // plugins[i].latest = plugins[i].latest; pluginMap[plugins[i].name] = plugins[i]; } @@ -261,7 +264,7 @@ var fs = require('fs'), function(dirs, next) { dirs = dirs.filter(function(dir){ - return dir.substr(0, 14) === 'nodebb-plugin-' || dir.substr(0, 14) === 'nodebb-widget-'; + return dir.startsWith('nodebb-plugin-') || dir.startsWith('nodebb-widget-') || dir.startsWith('nodebb-theme-') }).map(function(dir){ return path.join(npmPluginPath, dir); }); From c4509928828de1dabb9c293a2d76ac7bc94f1854 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 13 Feb 2015 15:13:16 -0500 Subject: [PATCH 155/164] closes #2722 --- src/postTools.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/postTools.js b/src/postTools.js index 09fa75330a..0fe8be23f8 100644 --- a/src/postTools.js +++ b/src/postTools.js @@ -36,11 +36,12 @@ var winston = require('winston'), postData.content = data.content; plugins.fireHook('filter:post.edit', {post: postData, uid: data.uid}, next); } - ], function(err, data) { + ], function(err, result) { if (err) { return callback(err); } - var postData = data.post; + + var postData = result.post; async.parallel({ post: function(next) { var d = { From b2fc4d5dc4855d7ef0d74b49044a76d3ed00c80d Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 13 Feb 2015 18:16:36 -0500 Subject: [PATCH 156/164] #2002 --- src/controllers/categories.js | 71 +++++++++++++++++- src/controllers/index.js | 108 ++++++--------------------- src/controllers/templates.js | 90 ++++++++++++++++++++++ src/routes/api.js | 64 +--------------- src/routes/index.js | 1 + src/views/admin/settings/general.tpl | 14 ++++ 6 files changed, 200 insertions(+), 148 deletions(-) create mode 100644 src/controllers/templates.js diff --git a/src/controllers/categories.js b/src/controllers/categories.js index 25690a6810..9ef288272c 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -3,6 +3,7 @@ var categoriesController = {}, async = require('async'), nconf = require('nconf'), + validator = require('validator'), privileges = require('../privileges'), user = require('../user'), categories = require('../categories'), @@ -22,7 +23,7 @@ categoriesController.recent = function(req, res, next) { } data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; - data['rssFeedUrl'] = nconf.get('relative_path') + '/recent.rss'; + data.rssFeedUrl = nconf.get('relative_path') + '/recent.rss'; data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[recent:title]]'}]); res.render('recent', data); }); @@ -92,6 +93,72 @@ categoriesController.unreadTotal = function(req, res, next) { }); }; +categoriesController.list = function(req, res, next) { + async.parallel({ + header: function (next) { + res.locals.metaTags = [{ + name: "title", + content: validator.escape(meta.config.title || 'NodeBB') + }, { + name: "description", + content: validator.escape(meta.config.description || '') + }, { + property: 'og:title', + content: 'Index | ' + validator.escape(meta.config.title || 'NodeBB') + }, { + property: 'og:type', + content: 'website' + }]; + + if(meta.config['brand:logo']) { + res.locals.metaTags.push({ + property: 'og:image', + content: meta.config['brand:logo'] + }); + } + + next(null); + }, + categories: function (next) { + var uid = req.user ? req.user.uid : 0; + categories.getCategoriesByPrivilege(uid, 'find', function (err, categoryData) { + if (err) { + return next(err); + } + var childCategories = []; + + for(var i=categoryData.length - 1; i>=0; --i) { + + if (Array.isArray(categoryData[i].children) && categoryData[i].children.length) { + childCategories.push.apply(childCategories, categoryData[i].children); + } + + if (categoryData[i].parent && categoryData[i].parent.cid) { + categoryData.splice(i, 1); + } + } + + async.parallel([ + function(next) { + categories.getRecentTopicReplies(categoryData, uid, next); + }, + function(next) { + categories.getRecentTopicReplies(childCategories, uid, next); + } + ], function(err) { + next(err, categoryData); + }); + }); + } + }, function (err, data) { + if (err) { + return next(err); + } + // TODO: template should be called categories.tpl + res.render('home', data); + }); +}; + categoriesController.get = function(req, res, next) { var cid = req.params.category_id, page = req.query.page || 1, @@ -259,7 +326,7 @@ categoriesController.get = function(req, res, next) { data.currentPage = page; data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; - data['rssFeedUrl'] = nconf.get('relative_path') + '/category/' + data.cid + '.rss'; + data.rssFeedUrl = nconf.get('relative_path') + '/category/' + data.cid + '.rss'; data.pagination = pagination.create(data.currentPage, data.pageCount); data.pagination.rel.forEach(function(rel) { diff --git a/src/controllers/index.js b/src/controllers/index.js index ff337250f4..805ba52d20 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -1,21 +1,10 @@ "use strict"; -var topicsController = require('./topics'), - categoriesController = require('./categories'), - tagsController = require('./tags'), - searchController = require('./search'), - usersController = require('./users'), - groupsController = require('./groups'), - accountsController = require('./accounts'), - staticController = require('./static'), - apiController = require('./api'), - adminController = require('./admin'), - helpers = require('./helpers'), - - async = require('async'), +var async = require('async'), nconf = require('nconf'), validator = require('validator'), winston = require('winston'), + auth = require('../routes/authentication'), meta = require('../meta'), user = require('../user'), @@ -23,85 +12,32 @@ var topicsController = require('./topics'), topics = require('../topics'), plugins = require('../plugins'), categories = require('../categories'), - privileges = require('../privileges'); + privileges = require('../privileges'), + helpers = require('./helpers'); var Controllers = { - topics: topicsController, - categories: categoriesController, - tags: tagsController, - search: searchController, - users: usersController, - groups: groupsController, - accounts: accountsController, - static: staticController, - api: apiController, - admin: adminController + topics: require('./topics'), + categories: require('./categories'), + tags: require('./tags'), + search: require('./search'), + users: require('./users'), + groups: require('./groups'), + accounts: require('./accounts'), + static: require('./static'), + api: require('./api'), + admin: require('./admin'), }; Controllers.home = function(req, res, next) { - async.parallel({ - header: function (next) { - res.locals.metaTags = [{ - name: "title", - content: validator.escape(meta.config.title || 'NodeBB') - }, { - name: "description", - content: validator.escape(meta.config.description || '') - }, { - property: 'og:title', - content: 'Index | ' + validator.escape(meta.config.title || 'NodeBB') - }, { - property: 'og:type', - content: 'website' - }]; - - if(meta.config['brand:logo']) { - res.locals.metaTags.push({ - property: 'og:image', - content: meta.config['brand:logo'] - }); - } - - next(null); - }, - categories: function (next) { - var uid = req.user ? req.user.uid : 0; - categories.getCategoriesByPrivilege(uid, 'find', function (err, categoryData) { - if (err) { - return next(err); - } - var childCategories = []; - - for(var i=categoryData.length - 1; i>=0; --i) { - - if (Array.isArray(categoryData[i].children) && categoryData[i].children.length) { - childCategories.push.apply(childCategories, categoryData[i].children); - } - - if (categoryData[i].parent && categoryData[i].parent.cid) { - categoryData.splice(i, 1); - } - } - - async.parallel([ - function(next) { - categories.getRecentTopicReplies(categoryData, uid, next); - }, - function(next) { - categories.getRecentTopicReplies(childCategories, uid, next); - } - ], function(err) { - next(err, categoryData); - }); - }); - } - }, function (err, data) { - if (err) { - return next(err); - } - res.render('home', data); - }); + var route = meta.config.homePageRoute || 'home'; + if (route === 'home') { + return Controllers.categories.list(req, res, next); + } else if (route === 'recent') { + Controllers.categories.recent(req, res, next); + } else if (route === 'popular') { + Controllers.categories.popular(req, res, next); + } }; Controllers.reset = function(req, res, next) { diff --git a/src/controllers/templates.js b/src/controllers/templates.js new file mode 100644 index 0000000000..311f1d37a7 --- /dev/null +++ b/src/controllers/templates.js @@ -0,0 +1,90 @@ +"use strict"; + +var async = require('async'), + nconf = require('nconf'), + fs = require('fs'), + path = require('path'), + meta = require('../meta'), + plugins = require('../plugins'), + utils = require('../../public/src/utils'), + templatesController = {}; + + +var availableTemplatesCache = null; +var configCache = null; + +templatesController.getTemplatesListing = function(req, res, next) { + async.parallel({ + availableTemplates: function(next) { + getAvailableTemplates(next); + }, + templatesConfig: function(next) { + async.waterfall([ + function(next) { + readConfigFile(next); + }, + function(config, next) { + config.custom_mapping['^/?$'] = meta.config.homePageRoute || 'home'; + + plugins.fireHook('filter:templates.get_config', config, next); + } + ], next); + }, + }, function(err, results) { + if (err) { + return next(err); + } + + res.json(results); + }); +}; + +function readConfigFile(callback) { + if (configCache) { + return callback(null, configCache); + } + fs.readFile(path.join(nconf.get('views_dir'), 'config.json'), function(err, config) { + if (err) { + return callback(err); + } + try { + config = JSON.parse(config.toString()); + } catch (err) { + return callback(err); + } + configCache = config; + callback(null, config); + }); +} + +function getAvailableTemplates(callback) { + if (availableTemplatesCache) { + return callback(null, availableTemplatesCache); + } + + async.parallel({ + views: function(next) { + utils.walk(nconf.get('views_dir'), next); + }, + extended: function(next) { + plugins.fireHook('filter:templates.get_virtual', [], next); + } + }, function(err, results) { + if (err) { + return callback(err); + } + var availableTemplates = results.views.filter(function(value, index, self) { + return value && self.indexOf(value) === index; + }).map(function(el) { + return el && el.replace(nconf.get('views_dir') + '/', ''); + }); + + availableTemplatesCache = availableTemplates = availableTemplates.concat(results.extended); + callback(null, availableTemplates) + }); + +} + + + +module.exports = templatesController; diff --git a/src/routes/api.js b/src/routes/api.js index da281280cc..47632ccce7 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -1,17 +1,11 @@ "use strict"; -var path = require('path'), - async = require('async'), - fs = require('fs'), - nconf = require('nconf'), - express = require('express'), +var express = require('express'), posts = require('../posts'), categories = require('../categories'), - plugins = require('../plugins'), - utils = require('../../public/src/utils'), - uploadsController = require('../controllers/uploads'); - + uploadsController = require('../controllers/uploads'), + templatesController = require('../controllers/templates'); module.exports = function(app, middleware, controllers) { @@ -22,7 +16,7 @@ module.exports = function(app, middleware, controllers) { router.get('/widgets/render', controllers.api.renderWidgets); router.get('/user/uid/:uid', middleware.checkGlobalPrivacySettings, controllers.accounts.getUserByUID); - router.get('/get_templates_listing', getTemplatesListing); + router.get('/get_templates_listing', templatesController.getTemplatesListing); router.get('/categories/:cid/moderators', getModerators); router.get('/recent/posts/:term?', getRecentPosts); @@ -40,56 +34,6 @@ function getModerators(req, res, next) { }); } -var templatesListingCache = {}; - -function getTemplatesListing(req, res, next) { - if (templatesListingCache.availableTemplates && templatesListingCache.templatesConfig) { - return res.json(templatesListingCache); - } - - async.parallel({ - views: function(next) { - utils.walk(nconf.get('views_dir'), next); - }, - extended: function(next) { - plugins.fireHook('filter:templates.get_virtual', [], next); - }, - config: function(next) { - fs.readFile(path.join(nconf.get('views_dir'), 'config.json'), function(err, config) { - if (err) { - return next(err); - } - - try { - config = JSON.parse(config.toString()); - } catch (err) { - return next(err); - } - - plugins.fireHook('filter:templates.get_config', config, next); - }); - }, - }, function(err, results) { - if (err) { - return next(err); - } - - var data = results.views.filter(function(value, index, self) { - return value && self.indexOf(value) === index; - }).map(function(el) { - return el && el.replace(nconf.get('views_dir') + '/', ''); - }); - - data = data.concat(results.extended); - - templatesListingCache = { - availableTemplates: data, - templatesConfig: results.config - }; - - res.json(templatesListingCache); - }); -} function getRecentPosts(req, res, next) { var uid = (req.user) ? req.user.uid : 0; diff --git a/src/routes/index.js b/src/routes/index.js index f8012c9456..94767dcc36 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -50,6 +50,7 @@ function tagRoutes(app, middleware, controllers) { } function categoryRoutes(app, middleware, controllers) { + setupPageRoute(app, '/categories', middleware, [], controllers.categories.list); setupPageRoute(app, '/popular/:term?', middleware, [], controllers.categories.popular); setupPageRoute(app, '/recent', middleware, [], controllers.categories.recent); setupPageRoute(app, '/unread', middleware, [middleware.authenticate], controllers.categories.unread); diff --git a/src/views/admin/settings/general.tpl b/src/views/admin/settings/general.tpl index 5c35ea8542..66a27dee61 100644 --- a/src/views/admin/settings/general.tpl +++ b/src/views/admin/settings/general.tpl @@ -28,6 +28,20 @@
    +
    +
    Home Page
    +
    +
    + + +
    +
    +
    +
    Site Logo
    From d152254bcb5018f7a9d5190be2a41e68f30b03a2 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 13 Feb 2015 18:26:25 -0500 Subject: [PATCH 157/164] removed availableTemplates assign --- src/controllers/templates.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/templates.js b/src/controllers/templates.js index 311f1d37a7..0d686a1455 100644 --- a/src/controllers/templates.js +++ b/src/controllers/templates.js @@ -79,8 +79,8 @@ function getAvailableTemplates(callback) { return el && el.replace(nconf.get('views_dir') + '/', ''); }); - availableTemplatesCache = availableTemplates = availableTemplates.concat(results.extended); - callback(null, availableTemplates) + availableTemplatesCache = availableTemplates.concat(results.extended); + callback(null, availableTemplatesCache); }); } From 16be6d33822e116c2c9e1b12039e9ffa63769bae Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 13 Feb 2015 18:34:03 -0500 Subject: [PATCH 158/164] increase group search results to 20 items --- public/src/admin/manage/groups.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/src/admin/manage/groups.js b/public/src/admin/manage/groups.js index 7b8f8cb5b4..b2ae0c0afb 100644 --- a/public/src/admin/manage/groups.js +++ b/public/src/admin/manage/groups.js @@ -154,8 +154,8 @@ define('admin/manage/groups', [ socket.emit('admin.user.search', {query: searchText}, function(err, results) { if (!err && results && results.users.length > 0) { var numResults = results.users.length, x; - if (numResults > 4) { - numResults = 4; + if (numResults > 20) { + numResults = 20; } groupDetailsSearchResults.empty(); From e3ba6716d16c81554ccd3b0565f41638c7ec2dd2 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 13 Feb 2015 20:28:37 -0500 Subject: [PATCH 159/164] closes #2723 --- .../jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js | 3 +-- .../jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map diff --git a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js index 16be0abb93..d9047ac1ec 100644 --- a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js +++ b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js @@ -1,7 +1,6 @@ /* * bootstrap-tagsinput v0.4.2 by Tim Schlechter - * + * */ !function(a){"use strict";function b(b,c){this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect="SELECT"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute("multiple"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute("placeholder")?this.$element.attr("placeholder"):"",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('
    '),this.$input=a('').appendTo(this.$container),this.$element.after(this.$container);var d=(this.inputSize<3?3:this.inputSize)+"em";this.$input.get(0).style.cssText="width: "+d+" !important;",this.build(c)}function c(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?i.text(a).html():""}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart("character",-a.value.length),b=c.text.length}else(a.selectionStart||"0"==a.selectionStart)&&(b=a.selectionStart);return b}function g(b,c){var d=!1;return a.each(c,function(a,c){if("number"==typeof c&&b.which===c)return d=!0,!1;if(b.which===c.which){var e=!c.hasOwnProperty("altKey")||b.altKey===c.altKey,f=!c.hasOwnProperty("shiftKey")||b.shiftKey===c.shiftKey,g=!c.hasOwnProperty("ctrlKey")||b.ctrlKey===c.ctrlKey;if(e&&f&&g)return d=!0,!1}}),d}var h={tagClass:function(){return"label label-info"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},freeInput:!0,addOnBlur:!0,maxTags:void 0,maxChars:void 0,confirmKeys:[13,44],onTagExists:function(a,b){b.hide().fadeIn()},trimValue:!1,allowDuplicates:!1};b.prototype={constructor:b,add:function(b,c){var d=this;if(!(d.options.maxTags&&d.itemsArray.length>=d.options.maxTags||b!==!1&&!b)){if("string"==typeof b&&d.options.trimValue&&(b=a.trim(b)),"object"==typeof b&&!d.objectItems)throw"Can't add objects when itemValue option is not set";if(!b.toString().match(/^\s*$/)){if(d.isSelect&&!d.multiple&&d.itemsArray.length>0&&d.remove(d.itemsArray[0]),"string"==typeof b&&"INPUT"===this.$element[0].tagName){var f=b.split(",");if(f.length>1){for(var g=0;gd.options.maxInputLength)){var l=a.Event("beforeItemAdd",{item:b,cancel:!1});if(d.$element.trigger(l),!l.cancel){d.itemsArray.push(b);var m=a(''+e(i)+'');if(m.data("item",b),d.findInputWrapper().before(m),m.after(" "),d.isSelect&&!a('option[value="'+encodeURIComponent(h)+'"]',d.$element)[0]){var n=a("");n.data("item",b),n.attr("value",h),d.$element.append(n)}c||d.pushVal(),(d.options.maxTags===d.itemsArray.length||d.items().toString().length===d.options.maxInputLength)&&d.$container.addClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemAdded",{item:b}))}}}else if(d.options.onTagExists){var o=a(".tag",d.$container).filter(function(){return a(this).data("item")===k});d.options.onTagExists(b,o)}}}},remove:function(b,c){var d=this;if(d.objectItems&&(b="object"==typeof b?a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==d.options.itemValue(b)}):a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==b}),b=b[b.length-1]),b){var e=a.Event("beforeItemRemove",{item:b,cancel:!1});if(d.$element.trigger(e),e.cancel)return;a(".tag",d.$container).filter(function(){return a(this).data("item")===b}).remove(),a("option",d.$element).filter(function(){return a(this).data("item")===b}).remove(),-1!==a.inArray(b,d.itemsArray)&&d.itemsArray.splice(a.inArray(b,d.itemsArray),1)}c||d.pushVal(),d.options.maxTags>d.itemsArray.length&&d.$container.removeClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemRemoved",{item:b}))},removeAll:function(){var b=this;for(a(".tag",b.$container).remove(),a("option",b.$element).remove();b.itemsArray.length>0;)b.itemsArray.pop();b.pushVal()},refresh:function(){var b=this;a(".tag",b.$container).each(function(){var c=a(this),d=c.data("item"),f=b.options.itemValue(d),g=b.options.itemText(d),h=b.options.tagClass(d);if(c.attr("class",null),c.addClass("tag "+e(h)),c.contents().filter(function(){return 3==this.nodeType})[0].nodeValue=e(g),b.isSelect){var i=a("option",b.$element).filter(function(){return a(this).data("item")===d});i.attr("value",f)}})},items:function(){return this.itemsArray},pushVal:function(){var b=this,c=a.map(b.items(),function(a){return b.options.itemValue(a).toString()});b.$element.val(c,!0).trigger("change")},build:function(b){var e=this;if(e.options=a.extend({},h,b),e.objectItems&&(e.options.freeInput=!1),c(e.options,"itemValue"),c(e.options,"itemText"),d(e.options,"tagClass"),e.options.typeahead){var i=e.options.typeahead||{};d(i,"source"),e.$input.typeahead(a.extend({},i,{source:function(b,c){function d(a){for(var b=[],d=0;d$1
    ")}}))}if(e.options.typeaheadjs){var j=e.options.typeaheadjs||{};e.$input.typeahead(null,j).on("typeahead:selected",a.proxy(function(a,b){e.add(j.valueKey?b[j.valueKey]:b),e.$input.typeahead("val","")},e))}e.$container.on("click",a.proxy(function(){e.$element.attr("disabled")||e.$input.removeAttr("disabled"),e.$input.focus()},e)),e.options.addOnBlur&&e.options.freeInput&&e.$input.on("focusout",a.proxy(function(){0===a(".typeahead, .twitter-typeahead",e.$container).length&&(e.add(e.$input.val()),e.$input.val(""))},e)),e.$container.on("keydown","input",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g&&e.remove(g.data("item"))}break;case 46:if(0===f(c[0])){var h=d.next();h&&e.remove(h.data("item"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus())}{var k=c.val().length;Math.ceil(k/5)}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("keypress","input",a.proxy(function(b){var c=a(b.target);if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");var d=c.val(),f=e.options.maxChars&&d.length>=e.options.maxChars;e.options.freeInput&&(g(b,e.options.confirmKeys)||f)&&(e.add(f?d.substr(0,e.options.maxChars):d),c.val(""),b.preventDefault());{var h=c.val().length;Math.ceil(h/5)}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("click","[data-role=remove]",a.proxy(function(b){e.$element.attr("disabled")||e.remove(a(b.target).closest(".tag").data("item"))},e)),e.options.itemValue===h.itemValue&&("INPUT"===e.$element[0].tagName?e.add(e.$element.val()):a("option",e.$element).each(function(){e.add(a(this).attr("value"),!0)}))},destroy:function(){var a=this;a.$container.off("keypress","input"),a.$container.off("click","[role=remove]"),a.$container.remove(),a.$element.removeData("tagsinput"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d){var e=[];return this.each(function(){var f=a(this).data("tagsinput");if(f)if(c||d){if(void 0!==f[c]){var g=f[c](d);void 0!==g&&e.push(g)}}else e.push(f);else f=new b(this,c),a(this).data("tagsinput",f),e.push(f),"SELECT"===this.tagName&&a("option",a(this)).attr("selected","selected"),a(this).val(a(this).val())}),"string"==typeof c?e.length>1?e:e[0]:e},a.fn.tagsinput.Constructor=b;var i=a("
    ");a(function(){a("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput()})}(window.jQuery); -//# sourceMappingURL=bootstrap-tagsinput.min.js.map \ No newline at end of file diff --git a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map b/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map deleted file mode 100644 index a0d198d16b..0000000000 --- a/public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"dist/bootstrap-tagsinput-angular.min.js","sources":["src/bootstrap-tagsinput-angular.js"],"names":["angular","module","directive","getItemProperty","scope","property","isFunction","$parent","item","undefined","restrict","model","template","replace","link","element","attrs","$","isArray","select","typeaheadSourceArray","typeaheadSource","split","length","tagsinput","options","typeahead","source","itemValue","itemvalue","itemText","itemtext","confirmKeys","confirmkeys","JSON","parse","tagClass","tagclass","i","on","event","indexOf","push","idx","splice","prev","slice","$watch","added","filter","removed"],"mappings":";;;;;AAAAA,QAAQC,OAAO,0BACdC,UAAU,sBAAuB,WAEhC,QAASC,GAAgBC,EAAOC,GAC9B,MAAKA,GAGDL,QAAQM,WAAWF,EAAMG,QAAQF,IAC5BD,EAAMG,QAAQF,GAEhB,SAASG,GACd,MAAOA,GAAKH,IANLI,OAUX,OACEC,SAAU,KACVN,OACEO,MAAO,YAETC,SAAU,6BACVC,SAAS,EACTC,KAAM,SAASV,EAAOW,EAASC,GAC7BC,EAAE,WACKjB,QAAQkB,QAAQd,EAAMO,SACzBP,EAAMO,SAER,IAAIQ,GAASF,EAAE,SAAUF,GACrBK,EAAuBJ,EAAMK,gBAAkBL,EAAMK,gBAAgBC,MAAM,KAAO,KAClFD,EAAkBD,EACjBA,EAAqBG,OAAS,EAC3BnB,EAAMG,QAAQa,EAAqB,IAAIA,EAAqB,IAC1DhB,EAAMG,QAAQa,EAAqB,IACvC,IAEND,GAAOK,UAAUpB,EAAMG,QAAQS,EAAMS,SAAW,MAC9CC,WACEC,OAAW3B,QAAQM,WAAWe,GAAmBA,EAAkB,MAErEO,UAAWzB,EAAgBC,EAAOY,EAAMa,WACxCC,SAAW3B,EAAgBC,EAAOY,EAAMe,UACxCC,YAAc7B,EAAgBC,EAAOY,EAAMiB,aAAeC,KAAKC,MAAMnB,EAAMiB,cAAgB,IAC3FG,SAAWpC,QAAQM,WAAWF,EAAMG,QAAQS,EAAMqB,WAAajC,EAAMG,QAAQS,EAAMqB,UAAY,WAAiB,MAAOrB,GAAMqB,WAG/H,KAAK,GAAIC,GAAI,EAAGA,EAAIlC,EAAMO,MAAMY,OAAQe,IACtCnB,EAAOK,UAAU,MAAOpB,EAAMO,MAAM2B,GAGtCnB,GAAOoB,GAAG,YAAa,SAASC,GACU,KAApCpC,EAAMO,MAAM8B,QAAQD,EAAMhC,OAC5BJ,EAAMO,MAAM+B,KAAKF,EAAMhC,QAG3BW,EAAOoB,GAAG,cAAe,SAASC,GAChC,GAAIG,GAAMvC,EAAMO,MAAM8B,QAAQD,EAAMhC,KACxB,MAARmC,GACFvC,EAAMO,MAAMiC,OAAOD,EAAK,IAK5B,IAAIE,GAAOzC,EAAMO,MAAMmC,OACvB1C,GAAM2C,OAAO,QAAS,WACpB,GAEIT,GAFAU,EAAQ5C,EAAMO,MAAMsC,OAAO,SAASX,GAAI,MAA2B,KAApBO,EAAKJ,QAAQH,KAC5DY,EAAUL,EAAKI,OAAO,SAASX,GAAI,MAAkC,KAA3BlC,EAAMO,MAAM8B,QAAQH,IAMlE,KAHAO,EAAOzC,EAAMO,MAAMmC,QAGdR,EAAI,EAAGA,EAAIY,EAAQ3B,OAAQe,IAC9BnB,EAAOK,UAAU,SAAU0B,EAAQZ,GAOrC,KAHAnB,EAAOK,UAAU,WAGZc,EAAI,EAAGA,EAAIU,EAAMzB,OAAQe,IAC5BnB,EAAOK,UAAU,MAAOwB,EAAMV,MAE/B"} \ No newline at end of file From 16c5c18165d75c9030f9b361a4d25ff0d0153497 Mon Sep 17 00:00:00 2001 From: Mega Date: Mon, 16 Feb 2015 10:43:56 +0300 Subject: [PATCH 160/164] Update arguments in action:posts.loaded --- public/src/client/home.js | 2 +- public/src/client/topic/posts.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/src/client/home.js b/public/src/client/home.js index f3b4e65acc..9b1a1862cb 100644 --- a/public/src/client/home.js +++ b/public/src/client/home.js @@ -59,7 +59,7 @@ define('forum/home', function() { recentPosts.last().remove(); } - $(window).trigger('action:posts.loaded', {pids: [post.pid]}); + $(window).trigger('action:posts.loaded', {posts: [post]}); }); } diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index 1f49c6fdd0..8137cdb8ab 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -130,7 +130,7 @@ define('forum/topic/posts', [ pids.push(data.posts[i].pid); } - $(window).trigger('action:posts.loaded', {pids: pids}); + $(window).trigger('action:posts.loaded', {posts: data.posts}); onNewPostsLoaded(html, pids); callback(true); }); From bd553eb05d6fe34ddc00ea47768bc3c7b1c09034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 17 Feb 2015 13:25:13 -0500 Subject: [PATCH 161/164] closes #2002 --- public/src/client/{home.js => categories.js} | 27 ++++++++++---------- src/controllers/categories.js | 4 +-- src/controllers/index.js | 6 +++-- src/controllers/templates.js | 3 ++- src/views/admin/settings/general.tpl | 2 +- src/views/config.json | 2 +- 6 files changed, 23 insertions(+), 21 deletions(-) rename public/src/client/{home.js => categories.js} (70%) diff --git a/public/src/client/home.js b/public/src/client/categories.js similarity index 70% rename from public/src/client/home.js rename to public/src/client/categories.js index 9b1a1862cb..6840f69e89 100644 --- a/public/src/client/home.js +++ b/public/src/client/categories.js @@ -2,35 +2,34 @@ /* globals define, socket, app, templates, translator, ajaxify*/ -define('forum/home', function() { - var home = {}; +define('forum/categories', function() { + var categories = {}; $(window).on('action:ajaxify.start', function(ev, data) { - if (data.tpl_url !== 'home') { - socket.removeListener('event:new_post', home.onNewPost); + if (data.tpl_url !== 'categories') { + socket.removeListener('event:new_post', categories.onNewPost); } }); + categories.init = function() { + app.enterRoom('categories'); - home.init = function() { - app.enterRoom('home'); + socket.removeListener('event:new_post', categories.onNewPost); + socket.on('event:new_post', categories.onNewPost); - socket.removeListener('event:new_post', home.onNewPost); - socket.on('event:new_post', home.onNewPost); - - $('.home .category-header').tooltip({ + $('.category-header').tooltip({ placement: 'bottom' }); }; - home.onNewPost = function(data) { + categories.onNewPost = function(data) { if (data && data.posts && data.posts.length && data.posts[0].topic) { renderNewPost(data.posts[0].topic.cid, data.posts[0]); } }; function renderNewPost(cid, post) { - var category = $('.home .category-item[data-cid="' + cid + '"]'); + var category = $('.category-item[data-cid="' + cid + '"]'); if (!category.length) { return; } @@ -64,7 +63,7 @@ define('forum/home', function() { } function parseAndTranslate(posts, callback) { - templates.parse('home', 'posts', {categories: {posts: posts}}, function(html) { + templates.parse('categories', 'posts', {categories: {posts: posts}}, function(html) { translator.translate(html, function(translatedHTML) { translatedHTML = $(translatedHTML); translatedHTML.find('img').addClass('img-responsive'); @@ -74,5 +73,5 @@ define('forum/home', function() { }); } - return home; + return categories; }); diff --git a/src/controllers/categories.js b/src/controllers/categories.js index 9ef288272c..187653268d 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -154,8 +154,8 @@ categoriesController.list = function(req, res, next) { if (err) { return next(err); } - // TODO: template should be called categories.tpl - res.render('home', data); + + res.render('categories', data); }); }; diff --git a/src/controllers/index.js b/src/controllers/index.js index 805ba52d20..c8511c7c61 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -30,13 +30,15 @@ var Controllers = { Controllers.home = function(req, res, next) { - var route = meta.config.homePageRoute || 'home'; - if (route === 'home') { + var route = meta.config.homePageRoute || 'categories'; + if (route === 'categories') { return Controllers.categories.list(req, res, next); } else if (route === 'recent') { Controllers.categories.recent(req, res, next); } else if (route === 'popular') { Controllers.categories.popular(req, res, next); + } else { + next(); } }; diff --git a/src/controllers/templates.js b/src/controllers/templates.js index 0d686a1455..7cbe6728e9 100644 --- a/src/controllers/templates.js +++ b/src/controllers/templates.js @@ -24,7 +24,8 @@ templatesController.getTemplatesListing = function(req, res, next) { readConfigFile(next); }, function(config, next) { - config.custom_mapping['^/?$'] = meta.config.homePageRoute || 'home'; + console.log(meta.config.homePageRoute); + config.custom_mapping['^/?$'] = meta.config.homePageRoute || 'categories'; plugins.fireHook('filter:templates.get_config', config, next); } diff --git a/src/views/admin/settings/general.tpl b/src/views/admin/settings/general.tpl index 66a27dee61..b403835994 100644 --- a/src/views/admin/settings/general.tpl +++ b/src/views/admin/settings/general.tpl @@ -34,7 +34,7 @@
    diff --git a/src/views/config.json b/src/views/config.json index 26ae7b692c..f8a04fa620 100644 --- a/src/views/config.json +++ b/src/views/config.json @@ -1,6 +1,6 @@ { "custom_mapping": { - "^\/?$": "home", + "^\/?$": "categories", "^admin?$": "admin/general/dashboard", "^users/sort-posts": "users", "^users/latest": "users", From 8f6b577bad5e82ed54ec3147b9522146112b12aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 17 Feb 2015 14:50:08 -0500 Subject: [PATCH 162/164] Update package.json --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index a7907757e8..b6a70902e4 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,9 @@ "nodebb-plugin-mentions": "^0.9.0", "nodebb-plugin-soundpack-default": "~0.1.1", "nodebb-plugin-spam-be-gone": "^0.4.0", - "nodebb-theme-lavender": "^1.0.0", - "nodebb-theme-vanilla": "^1.0.0", - "nodebb-widget-essentials": "~0.2.0", + "nodebb-theme-lavender": "^1.0.4", + "nodebb-theme-vanilla": "^1.0.5", + "nodebb-widget-essentials": "~0.2.11", "npm": "^2.1.4", "passport": "^0.2.1", "passport-local": "1.0.0", From 0611b7e1eac8e25228bcd58fd78ffdbb5fde5787 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 17 Feb 2015 15:12:31 -0500 Subject: [PATCH 163/164] closes #2733 --- src/controllers/admin/uploads.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/admin/uploads.js b/src/controllers/admin/uploads.js index 9ba3ad049c..81a98ed151 100644 --- a/src/controllers/admin/uploads.js +++ b/src/controllers/admin/uploads.js @@ -30,7 +30,7 @@ uploadsController.uploadFavicon = function(req, res, next) { var uploadedFile = req.files.files[0]; var allowedTypes = ['image/x-icon', 'image/vnd.microsoft.icon']; - if (validateUpload(res, req, next, uploadedFile, allowedTypes)) { + if (validateUpload(req, res, next, uploadedFile, allowedTypes)) { file.saveFileToLocal('favicon.ico', 'files', uploadedFile.path, function(err, image) { fs.unlink(uploadedFile.path); if (err) { @@ -63,7 +63,7 @@ function validateUpload(req, res, next, uploadedFile, allowedTypes) { if (allowedTypes.indexOf(uploadedFile.type) === -1) { fs.unlink(uploadedFile.path); - next(new Error('[[error:invalid-image-type, ' + allowedTypes.join(', ') + ']]')); + res.json({error: '[[error:invalid-image-type, ' + allowedTypes.join(', ') + ']]'}); return false; } From 276cd51836fbba54187f948fab31ec18279e3f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 17 Feb 2015 15:13:58 -0500 Subject: [PATCH 164/164] closes #2467 --- public/language/en_GB/notifications.json | 1 + public/src/client/notifications.js | 2 +- public/src/modules/notifications.js | 79 ++++++++++-------------- src/controllers/templates.js | 1 - src/socket.io/modules.js | 10 --- src/socket.io/notifications.js | 10 ++- 6 files changed, 45 insertions(+), 58 deletions(-) diff --git a/public/language/en_GB/notifications.json b/public/language/en_GB/notifications.json index 54c926a597..96aef60183 100644 --- a/public/language/en_GB/notifications.json +++ b/public/language/en_GB/notifications.json @@ -2,6 +2,7 @@ "title": "Notifications", "no_notifs": "You have no new notifications", "see_all": "See all Notifications", + "mark_all_read": "Mark all notifications read", "back_to_home": "Back to %1", "outgoing_link": "Outgoing Link", diff --git a/public/src/client/notifications.js b/public/src/client/notifications.js index b0fbb4619f..024fe6715c 100644 --- a/public/src/client/notifications.js +++ b/public/src/client/notifications.js @@ -10,7 +10,7 @@ define('forum/notifications', function() { $('span.timeago').timeago(); $('.notifications .delete').on('click', function() { - socket.emit('notifications.deleteAll', function(err) { + socket.emit('notifications.markAllRead', function(err) { if (err) { return app.alertError(err.message); } diff --git a/public/src/modules/notifications.js b/public/src/modules/notifications.js index 319d88041f..8ce107f20a 100644 --- a/public/src/modules/notifications.js +++ b/public/src/modules/notifications.js @@ -2,7 +2,6 @@ /* globals define, socket, translator, utils, config, app, ajaxify, Tinycon*/ - define('notifications', ['sounds'], function(sound) { var Notifications = {}; @@ -14,54 +13,44 @@ define('notifications', ['sounds'], function(sound) { notifTrigger.on('click', function(e) { e.preventDefault(); - if (!notifContainer.hasClass('open')) { - - socket.emit('notifications.get', null, function(err, data) { - - function createNotification(notification, callback) { - if (notification.image) { - image = ''; - } else { - image = ''; - } - - return '
  • ' + image + '' + $.timeago(new Date(parseInt(notification.datetime, 10))) + '' + notification.bodyShort + '
  • '; - } - - var x, html = ''; - - // Switch to shorthand - translator.toggleTimeagoShorthand(); - - if (!err && (data.read.length + data.unread.length) > 0) { - var image = ''; - for (x = 0; x < data.unread.length; x++) { - html += createNotification(data.unread[x]); - } - - for (x = 0; x < data.read.length; x++) { - html += createNotification(data.read[x]); - } - } else { - html += '
  • [[notifications:no_notifs]]
  • '; - } - - // Switch back to original timeago strings - translator.toggleTimeagoShorthand(); - - html += ''; + if (notifContainer.hasClass('open')) { + return; + } + socket.emit('notifications.get', null, function(err, data) { + if (err) { + return app.alertError(err.message); + } + + var notifs = data.unread.concat(data.read); + + translator.toggleTimeagoShorthand(); + for(var i=0; i