From ad7b561dd4208b375d0face3f4ce67d1d7e66ca2 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sun, 3 May 2015 23:36:23 -0600 Subject: [PATCH 001/237] Fixed translator backwards compatibility issue Also removed the _clearMenus global object because populating the global namespace is bad, bad, bad --- public/src/modules/translator.js | 6 +++-- public/src/overrides.js | 42 +++++++++++++++++--------------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/public/src/modules/translator.js b/public/src/modules/translator.js index ac3be2728e..df8ac5d5ef 100644 --- a/public/src/modules/translator.js +++ b/public/src/modules/translator.js @@ -295,11 +295,13 @@ if (typeof define === 'function' && define.amd) { define('translator', translator); + var _translator = translator; + // Expose a global `translator` object for backwards compatibility window.translator = { translate: function() { console.warn('[translator] Global invocation of the translator is now deprecated, please `require` the module instead.'); - translator.translate.apply(translator, arguments); + _translator.translate.apply(_translator, arguments); } } } @@ -307,4 +309,4 @@ typeof exports === 'object' ? exports : typeof define === 'function' && define.amd ? {} : translator = {} -); \ No newline at end of file +); diff --git a/public/src/overrides.js b/public/src/overrides.js index 8c0e492cce..dde1b55dd3 100644 --- a/public/src/overrides.js +++ b/public/src/overrides.js @@ -79,25 +79,27 @@ if ('undefined' !== typeof window) { })(jQuery || {fn:{}}); - - // FIX FOR #1245 - https://github.com/NodeBB/NodeBB/issues/1245 - // from http://stackoverflow.com/questions/15931962/bootstrap-dropdown-disappear-with-right-click-on-firefox - // obtain a reference to the original handler - var _clearMenus = $._data(document, "events").click.filter(function (el) { - return el.namespace === 'bs.data-api.dropdown' && el.selector === undefined; - }); - - if(_clearMenus.length) { - _clearMenus = _clearMenus[0].handler; - } - - // disable the old listener - $(document) - .off('click.data-api.dropdown', _clearMenus) - .on('click.data-api.dropdown', function (e) { - // call the handler only when not right-click - if (e.button !== 2) { - _clearMenus(); - } + (function(){ + // FIX FOR #1245 - https://github.com/NodeBB/NodeBB/issues/1245 + // from http://stackoverflow.com/questions/15931962/bootstrap-dropdown-disappear-with-right-click-on-firefox + // obtain a reference to the original handler + var _clearMenus = $._data(document, "events").click.filter(function (el) { + return el.namespace === 'bs.data-api.dropdown' && el.selector === undefined; }); + + if(_clearMenus.length) { + _clearMenus = _clearMenus[0].handler; + } + + // disable the old listener + $(document) + .off('click.data-api.dropdown', _clearMenus) + .on('click.data-api.dropdown', function (e) { + // call the handler only when not right-click + if (e.button !== 2) { + _clearMenus(); + } + }); + })(); + } From da56681f7376b377906d4de47c5dc9702e0ba9ab Mon Sep 17 00:00:00 2001 From: Andrea Cardinale Date: Tue, 12 May 2015 23:56:27 +0200 Subject: [PATCH 002/237] Revert "Extra class in Topic list" This reverts commit 5f0531e66a3ef347b19445c43066dee8ab82d864. --- public/src/modules/helpers.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/public/src/modules/helpers.js b/public/src/modules/helpers.js index b0f48d6f15..7d79265b84 100644 --- a/public/src/modules/helpers.js +++ b/public/src/modules/helpers.js @@ -102,10 +102,6 @@ style.push('unread'); } - if (topic.extraClass) { - style.push(topic.extraClass); - } - return style.join(' '); }; From 35c426ee1c0cf51be51156fb1ac5f70a09465703 Mon Sep 17 00:00:00 2001 From: Aziz Khoury Date: Wed, 13 May 2015 13:02:00 -0400 Subject: [PATCH 003/237] guard against NULL mids/messages I've seen them few times during import testing. In case the conversation does not exists. --- src/messaging.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/messaging.js b/src/messaging.js index cd3e1f96e2..2cb1fedf1d 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -211,14 +211,14 @@ var db = require('./database'), } }, function(mids, next) { - if (typeof mids !== 'boolean') { + if (typeof mids !== 'boolean' && mids && mids.length) { db.getObjects(['message:' + mids[0], 'message:' + mids[1]], next); } else { next(null, mids); } }, function(messages, next) { - if (typeof messages !== 'boolean') { + if (typeof messages !== 'boolean' && messages && messages.length) { next(null, parseInt(messages[1].timestamp, 10) > parseInt(messages[0].timestamp, 10) + (1000*60*5)); } else { next(null, messages); From 4124370efef6e3d630325f0efe8924f19bbf9812 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Wed, 13 May 2015 15:50:31 -0400 Subject: [PATCH 004/237] tjs 0.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0428d04687..278141c507 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "socket.io-redis": "^0.1.3", "socketio-wildcard": "~0.1.1", "string": "^3.0.0", - "templates.js": "^0.2.2", + "templates.js": "^0.2.3", "uglify-js": "git+https://github.com/julianlam/UglifyJS2.git", "underscore": "~1.8.3", "validator": "^3.30.0", From 68ceaadad12d9e499944dbf93a492d1fc452ca20 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 13 May 2015 17:22:44 -0400 Subject: [PATCH 005/237] removed static 404/403/500 routes --- src/controllers/index.js | 1 - src/controllers/static.js | 23 ----------------------- src/routes/index.js | 9 +-------- 3 files changed, 1 insertion(+), 32 deletions(-) delete mode 100644 src/controllers/static.js diff --git a/src/controllers/index.js b/src/controllers/index.js index 7a2f225290..59bf03994c 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -24,7 +24,6 @@ var Controllers = { users: require('./users'), groups: require('./groups'), accounts: require('./accounts'), - static: require('./static'), api: require('./api'), admin: require('./admin') }; diff --git a/src/controllers/static.js b/src/controllers/static.js deleted file mode 100644 index a2355ef8dd..0000000000 --- a/src/controllers/static.js +++ /dev/null @@ -1,23 +0,0 @@ -"use strict"; - -var staticController = {}; - -createStatic('404'); -createStatic('403'); -createStatic('500'); - -function createStatic(statusCode) { - staticController[statusCode] = function(req, res) { - if (!res.locals.isAPI) { - res.statusCode = parseInt(statusCode, 10); - } - - res.render(statusCode, { - errorMessage: req.flash('errorMessage')[0] || undefined - }); - }; -} - -module.exports = staticController; - - diff --git a/src/routes/index.js b/src/routes/index.js index 2ebf77d53e..437f19359d 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -32,12 +32,6 @@ function mainRoutes(app, middleware, controllers) { setupPageRoute(app, '/tos', middleware, [], controllers.termsOfUse); } -function staticRoutes(app, middleware, controllers) { - setupPageRoute(app, '/404', middleware, [], controllers.static['404']); - setupPageRoute(app, '/403', middleware, [], controllers.static['403']); - setupPageRoute(app, '/500', middleware, [], controllers.static['500']); -} - function topicRoutes(app, middleware, controllers) { app.get('/api/topic/teaser/:topic_id', controllers.topics.teaser); @@ -134,7 +128,6 @@ module.exports = function(app, middleware) { */ mainRoutes(router, middleware, controllers); - staticRoutes(router, middleware, controllers); topicRoutes(router, middleware, controllers); tagRoutes(router, middleware, controllers); categoryRoutes(router, middleware, controllers); @@ -199,7 +192,7 @@ function handle404(app, middleware) { res.status(404); if (res.locals.isAPI) { - return res.json({path: req.path, error: 'not-found'}); + return res.json({path: req.path}); } middleware.buildHeader(req, res, function() { From 9c2a98486af52760ef06ab91bff059e88ec77144 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Wed, 13 May 2015 18:31:16 -0400 Subject: [PATCH 006/237] fixed tag topic count color in ACP --- public/less/admin/manage/tags.less | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/less/admin/manage/tags.less b/public/less/admin/manage/tags.less index f26fa00327..e034d3b3f6 100644 --- a/public/less/admin/manage/tags.less +++ b/public/less/admin/manage/tags.less @@ -31,7 +31,6 @@ .tag-topic-count { border: solid 1px lighten(@brand-primary, 20%); background-color: lighten(@brand-primary, 20%); - color: #FFFFFF; padding: .2em .6em .3em; font-size: 75%; font-weight: 700; @@ -41,5 +40,9 @@ padding-left: 5px; border-bottom-right-radius: 5px; border-top-right-radius: 5px; + + a { + color: #FFFFFF; + } } } \ No newline at end of file From 36853f4ad86e7e41a049db658a7ed6d76a23617a Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 13 May 2015 18:31:38 -0400 Subject: [PATCH 007/237] filter priv/registered-users/guests in groups.list --- src/controllers/admin.js | 7 ++++--- src/groups.js | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/controllers/admin.js b/src/controllers/admin.js index 50c8deb009..926e30d7e1 100644 --- a/src/controllers/admin.js +++ b/src/controllers/admin.js @@ -389,9 +389,10 @@ adminController.groups.get = function(req, res, next) { isAdmin: true, showSystemGroups: true }, function(err, groups) { - groups = groups.filter(function(group) { - return group.name !== 'registered-users' && group.name !== 'guests' && group.name.indexOf(':privileges:') === -1; - }); + if (err) { + return next(err); + } + res.render('admin/manage/groups', { groups: groups, yourid: req.user.uid diff --git a/src/groups.js b/src/groups.js index 4f52d2bc9f..e12b09e66c 100644 --- a/src/groups.js +++ b/src/groups.js @@ -76,7 +76,10 @@ var async = require('async'), if (err) { return callback(err); } - groupNames = groupNames.concat(ephemeralGroups); + + groupNames = groupNames.filter(function(groupName) { + return groupName && groupName.indexOf(':privileges:') === -1 && groupName !== 'registered-users' && groupName !== 'guests'; + }); async.parallel({ groups: async.apply(async.map, groupNames, function (groupName, next) { From 10de7a92e4164bf61a78d4cb44bb5cc9770557de Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 14 May 2015 13:53:02 -0400 Subject: [PATCH 008/237] dont let joining other uid rooms --- public/src/app.js | 10 +++++++--- src/socket.io/meta.js | 5 +++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index c2c1f179f0..c09f8c6cd4 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -169,7 +169,8 @@ app.cacheBuster = null; }); }; - app.enterRoom = function (room) { + app.enterRoom = function (room, callback) { + callback = callback || function() {}; if (socket) { if (app.currentRoom === room) { return; @@ -180,9 +181,12 @@ app.cacheBuster = null; username: app.user.username, userslug: app.user.userslug, picture: app.user.picture + }, function(err) { + if (err) { + app.alertError(err.message); + } + app.currentRoom = room; }); - - app.currentRoom = room; } }; diff --git a/src/socket.io/meta.js b/src/socket.io/meta.js index 12ac8279c8..d6fdea73cb 100644 --- a/src/socket.io/meta.js +++ b/src/socket.io/meta.js @@ -54,10 +54,15 @@ SocketMeta.rooms.enter = function(socket, data, callback) { if (!socket.uid) { return; } + if (!data) { return callback(new Error('[[error:invalid-data]]')); } + if (data.enter && data.enter.startsWith('uid_') && data.enter !== 'uid_' + socket.uid) { + return callback(new Error('[[error:not-allowed]]')); + } + if (socket.currentRoom) { rooms.leave(socket, socket.currentRoom); if (socket.currentRoom.indexOf('topic') !== -1) { From d9af2242a7c7fc92318a83bd46e4f849094960f2 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 14 May 2015 22:04:53 -0400 Subject: [PATCH 009/237] store id as int --- src/database/mongo/main.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/database/mongo/main.js b/src/database/mongo/main.js index 7ba58499d3..9d8fae3b65 100644 --- a/src/database/mongo/main.js +++ b/src/database/mongo/main.js @@ -7,6 +7,10 @@ module.exports = function(db, module) { module.searchIndex = function(key, data, id, callback) { callback = callback || function() {}; + id = parseInt(id, 10); + if (!id) { + return callback(); + } var setData = { id: id }; @@ -17,7 +21,7 @@ module.exports = function(db, module) { } db.collection('search' + key).update({id: id}, {$set: setData}, {upsert:true, w: 1}, function(err) { - if(err) { + if (err) { winston.error('Error indexing ' + err.message); } callback(err); @@ -66,9 +70,11 @@ module.exports = function(db, module) { module.searchRemove = function(key, id, callback) { callback = callback || helpers.noop; + id = parseInt(id, 10); if (!id) { return callback(); } + db.collection('search' + key).remove({id: id}, function(err, res) { callback(err); }); From 30a9b66b316ac6f5e16039a1daeb53a9e1b4162b Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 15 May 2015 00:02:59 -0400 Subject: [PATCH 010/237] fix room enter --- public/src/app.js | 1 + src/socket.io/meta.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/public/src/app.js b/public/src/app.js index c09f8c6cd4..5484d9de50 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -184,6 +184,7 @@ app.cacheBuster = null; }, function(err) { if (err) { app.alertError(err.message); + return; } app.currentRoom = room; }); diff --git a/src/socket.io/meta.js b/src/socket.io/meta.js index d6fdea73cb..890a40c3e0 100644 --- a/src/socket.io/meta.js +++ b/src/socket.io/meta.js @@ -52,7 +52,7 @@ SocketMeta.buildTitle = function(socket, text, callback) { SocketMeta.rooms.enter = function(socket, data, callback) { if (!socket.uid) { - return; + return callback(); } if (!data) { @@ -83,6 +83,7 @@ SocketMeta.rooms.enter = function(socket, data, callback) { websockets.in(data.enter).emit('event:user_enter', data); } } + callback(); }; SocketMeta.rooms.getAll = function(socket, data, callback) { From fc1b0c8d2426521d92b55bfe0adac11d9eaca0b0 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 15 May 2015 09:47:39 -0400 Subject: [PATCH 011/237] allowing topic, post, and user creation to specify a timestamp for insertion into the past --- src/groups.js | 8 ++++---- src/posts/create.js | 1 + src/topics/create.js | 11 ++++++----- src/user/create.js | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/groups.js b/src/groups.js index e12b09e66c..6cff59ded0 100644 --- a/src/groups.js +++ b/src/groups.js @@ -514,13 +514,13 @@ var async = require('async'), if (exists) { return callback(new Error('[[error:group-already-exists]]')); } - var now = Date.now(); + var timestamp = data.timestamp || Date.now(); var slug = utils.slugify(data.name), groupData = { name: data.name, slug: slug, - createtime: now, + createtime: timestamp, userTitle: data.name, description: data.description || '', memberCount: 0, @@ -530,13 +530,13 @@ var async = require('async'), private: data.private || '1' }, tasks = [ - async.apply(db.sortedSetAdd, 'groups:createtime', now, data.name), + async.apply(db.sortedSetAdd, 'groups:createtime', timestamp, data.name), async.apply(db.setObject, 'group:' + data.name, groupData) ]; if (data.hasOwnProperty('ownerUid')) { tasks.push(async.apply(db.setAdd, 'group:' + data.name + ':owners', data.ownerUid)); - tasks.push(async.apply(db.sortedSetAdd, 'group:' + data.name + ':members', now, data.ownerUid)); + tasks.push(async.apply(db.sortedSetAdd, 'group:' + data.name + ':members', timestamp, data.ownerUid)); tasks.push(async.apply(db.setObjectField, 'group:' + data.name, 'memberCount', 1)); groupData.ownerUid = data.ownerUid; diff --git a/src/posts/create.js b/src/posts/create.js index 4e4aa5433a..4589e6ae9f 100644 --- a/src/posts/create.js +++ b/src/posts/create.js @@ -12,6 +12,7 @@ var async = require('async'), module.exports = function(Posts) { Posts.create = function(data, callback) { + // This is an internal method, consider using Topics.reply instead var uid = data.uid, tid = data.tid, content = data.content.toString(), diff --git a/src/topics/create.js b/src/topics/create.js index 5f5ea7b129..1aee41e01a 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -15,6 +15,7 @@ var async = require('async'), module.exports = function(Topics) { Topics.create = function(data, callback) { + // This is an interal method, consider using Topics.post instead var uid = data.uid, title = data.title, cid = data.cid, @@ -26,7 +27,7 @@ module.exports = function(Topics) { } var slug = utils.slugify(title), - timestamp = Date.now(); + timestamp = data.timestamp || Date.now(); if (!slug.length) { return callback(new Error('[[error:invalid-title]]')); @@ -136,10 +137,10 @@ module.exports = function(Topics) { }, function(filteredData, next) { content = filteredData.content || data.content; - Topics.create({uid: uid, title: title, cid: cid, thumb: data.thumb, tags: tags}, next); + Topics.create({ uid: uid, title: title, cid: cid, thumb: data.thumb, tags: tags, timestamp: data.timestamp }, next); }, function(tid, next) { - Topics.reply({uid:uid, tid:tid, handle: data.handle, content:content, req: data.req}, next); + Topics.reply({ uid:uid, tid:tid, handle: data.handle, content:content, timestamp: data.timestamp, req: data.req }, next); }, function(postData, next) { async.parallel({ @@ -230,7 +231,7 @@ module.exports = function(Topics) { checkContentLength(content, next); }, function(next) { - posts.create({uid: uid, tid: tid, handle: data.handle, content: content, toPid: data.toPid, ip: data.req ? data.req.ip : null}, next); + posts.create({uid: uid, tid: tid, handle: data.handle, content: content, toPid: data.toPid, timestamp: data.timestamp, ip: data.req ? data.req.ip : null}, next); }, function(data, next) { postData = data; @@ -278,7 +279,7 @@ module.exports = function(Topics) { postData.selfPost = false; postData.relativeTime = utils.toISOString(postData.timestamp); - if (parseInt(uid, 10)) { + if (parseInt(uid, 10) && data.req) { Topics.notifyFollowers(postData, uid); } diff --git a/src/user/create.js b/src/user/create.js index d4a3f51adb..2580a738f1 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -25,7 +25,7 @@ module.exports = function(User) { return callback(err); } var gravatar = User.createGravatarURLFromEmail(data.email); - var timestamp = Date.now(); + var timestamp = data.timestamp || Date.now(); var userData = { 'username': data.username, From 220b42706f0288782bf5db1a10e8059b8d863e86 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 15 May 2015 14:14:20 -0400 Subject: [PATCH 012/237] adding a check so that websocket method in notif pushing isn't called if the socket server isn't initialised --- src/notifications.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/notifications.js b/src/notifications.js index 3aafdb346d..67d7b68695 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -197,8 +197,10 @@ var async = require('async'), plugins.fireHook('action:notification.pushed', {notification: notification, uids: uids}); var websockets = require('./socket.io'); - for(var i=0; i Date: Fri, 15 May 2015 14:46:37 -0400 Subject: [PATCH 013/237] fix user.csv data --- src/upgrade.js | 4 ++-- src/user/admin.js | 7 +++++-- src/views/admin/manage/users.tpl | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/upgrade.js b/src/upgrade.js index 686c7a1f88..47fd8badc0 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -1050,13 +1050,13 @@ Upgrade.upgrade = function(callback) { updatesMade = true; winston.info('[2015/05/11] Updating widgets to tjs 0.2x'); - require('./widgets/admin').get(function(err, data) { + require('./widgets/admin').get(function(err, data) { async.each(data.areas, function(area, next) { require('./widgets').getArea(area.template, area.location, function(err, widgets) { if (err) { return next(err); } - + for (var w in widgets) { if (widgets.hasOwnProperty(w)) { widgets[w].data.container = widgets[w].data.container diff --git a/src/user/admin.js b/src/user/admin.js index 615a765f6a..2ffbad9512 100644 --- a/src/user/admin.js +++ b/src/user/admin.js @@ -32,9 +32,12 @@ module.exports = function(User) { async.waterfall([ function(next) { - db.getSortedSetRange('username:uid', 0, -1, next); + db.getSortedSetRangeWithScores('username:uid', 0, -1, next); }, - function(uids, next) { + function(users, next) { + var uids = users.map(function(user) { + return user.score; + }); User.getMultipleUserFields(uids, ['uid', 'email', 'username'], next); }, function(usersData, next) { diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl index 37b993dba7..c5762f637e 100644 --- a/src/views/admin/manage/users.tpl +++ b/src/views/admin/manage/users.tpl @@ -129,7 +129,7 @@
Users Control Panel
- Download CSV + Download CSV
From e6beeb62cf357670817dfea757018fa60c6ce48a Mon Sep 17 00:00:00 2001 From: psychobunny Date: Fri, 15 May 2015 15:00:48 -0400 Subject: [PATCH 014/237] {config.relative_path} instead of {relative_path} --- src/views/403.tpl | 2 +- src/views/404.tpl | 2 +- src/views/admin/manage/flags.tpl | 8 ++++---- src/views/admin/manage/tags.tpl | 2 +- src/views/admin/manage/users.tpl | 12 ++++++------ src/views/admin/settings/general.tpl | 4 ++-- src/views/admin/settings/user.tpl | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/views/403.tpl b/src/views/403.tpl index 8234c7558d..e6800ed72d 100644 --- a/src/views/403.tpl +++ b/src/views/403.tpl @@ -7,6 +7,6 @@ -

[[global:403.login, {relative_path}]]

+

[[global:403.login, {config.relative_path}]]

\ No newline at end of file diff --git a/src/views/404.tpl b/src/views/404.tpl index 93b114716a..2a0a645bc8 100644 --- a/src/views/404.tpl +++ b/src/views/404.tpl @@ -3,6 +3,6 @@

{error}

-

[[global:404.message, {relative_path}]]

+

[[global:404.message, {config.relative_path}]]

\ No newline at end of file diff --git a/src/views/admin/manage/flags.tpl b/src/views/admin/manage/flags.tpl index f463d829d2..1679f4087f 100644 --- a/src/views/admin/manage/flags.tpl +++ b/src/views/admin/manage/flags.tpl @@ -38,11 +38,11 @@
diff --git a/src/views/admin/manage/tags.tpl b/src/views/admin/manage/tags.tpl index 1b8c687b00..49072e43af 100644 --- a/src/views/admin/manage/tags.tpl +++ b/src/views/admin/manage/tags.tpl @@ -14,7 +14,7 @@
- {tags.value}{tags.score} + {tags.value}{tags.score}
@@ -45,7 +45,7 @@


- +
diff --git a/src/views/admin/settings/user.tpl b/src/views/admin/settings/user.tpl index c2832c530a..94c3b536fc 100644 --- a/src/views/admin/settings/user.tpl +++ b/src/views/admin/settings/user.tpl @@ -73,7 +73,7 @@

- +
From 20983c43f48e456e60a9e6516d55c789940a54f7 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 15 May 2015 15:20:06 -0400 Subject: [PATCH 015/237] fix user privileges --- src/views/admin/partials/categories/privileges.tpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/views/admin/partials/categories/privileges.tpl b/src/views/admin/partials/categories/privileges.tpl index d18329753e..7e1f97b580 100644 --- a/src/views/admin/partials/categories/privileges.tpl +++ b/src/views/admin/partials/categories/privileges.tpl @@ -8,10 +8,10 @@ - - - {username} - {function.spawnPrivilegeStates, username, privileges} + + + {privileges.users.username} + {function.spawnPrivilegeStates, privileges.users.username, privileges} From 48b5d90a9e135e91eca27a550c7815ad410a8403 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sun, 17 May 2015 15:53:42 -0400 Subject: [PATCH 016/237] closes #3150 --- src/categories.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/categories.js b/src/categories.js index 6112c5dc58..134a671744 100644 --- a/src/categories.js +++ b/src/categories.js @@ -159,7 +159,11 @@ var async = require('async'), category.disabled = parseInt(category.disabled, 10) === 1; category.icon = category.icon || 'hidden'; if (category.hasOwnProperty('post_count')) { - category.post_count = category.post_count || 0; + category.post_count = category.totalPostCount = category.post_count || 0; + } + + if (category.hasOwnProperty('topic_count')) { + category.topic_count = category.totalTopicCount = category.topic_count || 0; } if (category.description) { @@ -250,18 +254,23 @@ var async = require('async'), }; function calculateTopicPostCount(category) { - if (!Array.isArray(category.children) || !category.children.length) { + if (!category) { return; } var postCount = parseInt(category.post_count, 10) || 0; var topicCount = parseInt(category.topic_count, 10) || 0; + if (!Array.isArray(category.children) || !category.children.length) { + category.totalPostCount = postCount; + category.totalTopicCount = topicCount; + return; + } category.children.forEach(function(child) { postCount += parseInt(child.post_count, 10) || 0; topicCount += parseInt(child.topic_count, 10) || 0; }); - category.post_count = postCount; - category.topic_count = topicCount; + category.totalPostCount = postCount; + category.totalTopicCount = topicCount; } Categories.getParents = function(cids, callback) { From de71910f4c0c62d3c312302a4ffd3b85273b5141 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 18 May 2015 15:25:45 -0400 Subject: [PATCH 017/237] documentation is actually at docs portal, not wiki --- src/views/admin/extend/plugins.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/admin/extend/plugins.tpl b/src/views/admin/extend/plugins.tpl index 90611e6d47..252a56c7a4 100644 --- a/src/views/admin/extend/plugins.tpl +++ b/src/views/admin/extend/plugins.tpl @@ -105,7 +105,7 @@
Interested in writing plugins for NodeBB?

- Full documentation regarding plugin authoring can be found in the NodeBB Wiki. + Full documentation regarding plugin authoring can be found in the NodeBB Docs Portal.

From ec91efdd2dcf8c8a5bc5a4f1d30c2e647b6db259 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 18 May 2015 15:56:37 -0400 Subject: [PATCH 018/237] latest translations and fallbacks --- public/language/ar/error.json | 6 +- public/language/ar/global.json | 6 +- public/language/ar/groups.json | 6 +- public/language/ar/modules.json | 4 +- public/language/ar/notifications.json | 2 +- public/language/ar/pages.json | 4 +- public/language/ar/recent.json | 20 ++-- public/language/ar/register.json | 4 +- public/language/ar/search.json | 46 ++++---- public/language/ar/topic.json | 10 +- public/language/ar/unread.json | 2 +- public/language/ar/user.json | 26 ++--- public/language/ar/users.json | 6 +- public/language/de/error.json | 2 +- public/language/de/user.json | 2 +- public/language/fa_IR/email.json | 2 +- public/language/fa_IR/error.json | 14 +-- public/language/fa_IR/global.json | 2 +- public/language/fa_IR/groups.json | 4 +- public/language/fa_IR/pages.json | 2 +- public/language/fa_IR/search.json | 2 +- public/language/fa_IR/success.json | 2 +- public/language/hu/search.json | 14 +-- public/language/ms/global.json | 20 ++-- public/language/ms/user.json | 2 +- public/language/nl/category.json | 4 +- public/language/nl/email.json | 38 +++--- public/language/nl/error.json | 134 +++++++++++----------- public/language/nl/global.json | 62 +++++----- public/language/nl/groups.json | 44 +++---- public/language/nl/login.json | 12 +- public/language/nl/modules.json | 30 ++--- public/language/nl/notifications.json | 32 +++--- public/language/nl/pages.json | 24 ++-- public/language/nl/reset_password.json | 28 ++--- public/language/nl/search.json | 20 ++-- public/language/nl/success.json | 6 +- public/language/nl/tags.json | 6 +- public/language/nl/topic.json | 118 +++++++++---------- public/language/nl/unread.json | 4 +- public/language/nl/user.json | 86 +++++++------- public/language/nl/users.json | 8 +- public/language/ru/error.json | 34 +++--- public/language/zh_TW/category.json | 10 +- public/language/zh_TW/error.json | 20 ++-- public/language/zh_TW/global.json | 4 +- public/language/zh_TW/groups.json | 54 ++++----- public/language/zh_TW/login.json | 6 +- public/language/zh_TW/pages.json | 8 +- public/language/zh_TW/recent.json | 14 +-- public/language/zh_TW/reset_password.json | 6 +- public/language/zh_TW/user.json | 24 ++-- public/language/zh_TW/users.json | 6 +- 53 files changed, 526 insertions(+), 526 deletions(-) diff --git a/public/language/ar/error.json b/public/language/ar/error.json index 4273f07874..2071baf252 100644 --- a/public/language/ar/error.json +++ b/public/language/ar/error.json @@ -25,7 +25,7 @@ "username-too-short": "اسم المستخدم قصير.", "username-too-long": "اسم المستخدم طويل", "user-banned": "المستخدم محظور", - "user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post", + "user-too-new": "عذرا, يجب أن تنتظر 1% ثواني قبل قيامك بأول مشاركة", "no-category": "قائمة غير موجودة", "no-topic": "موضوع غير موجود", "no-post": "رد غير موجود", @@ -78,6 +78,6 @@ "reload-failed": "المنتدى واجه مشكلة أثناء إعادة التحميل: \"%1\". سيواصل المنتدى خدمة العملاء السابقين لكن يجب عليك إلغاء أي تغيير قمت به قبل إعادة التحميل.", "registration-error": "حدث خطأ أثناء التسجيل", "parse-error": "Something went wrong while parsing server response", - "wrong-login-type-email": "Please use your email to login", - "wrong-login-type-username": "Please use your username to login" + "wrong-login-type-email": "الرجاء استعمال بريدك اﻹلكتروني للدخول", + "wrong-login-type-username": "الرجاء استعمال اسم المستخدم الخاص بك للدخول" } \ No newline at end of file diff --git a/public/language/ar/global.json b/public/language/ar/global.json index 1671e2806f..15275ddc39 100644 --- a/public/language/ar/global.json +++ b/public/language/ar/global.json @@ -27,7 +27,7 @@ "header.tags": "وسم", "header.popular": "الأكثر شهرة", "header.users": "المستخدمين", - "header.groups": "Groups", + "header.groups": "المجموعات", "header.chats": "المحادثات", "header.notifications": "التنبيهات", "header.search": "بحث", @@ -75,7 +75,7 @@ "updated.title": "تم تحديث المنتدى", "updated.message": "لقد تم تحديث المنتدى إلى آخر نسخة للتو. المرجو إعادة تحميل الصفحة.", "privacy": "الخصوصية", - "follow": "Follow", - "unfollow": "Unfollow", + "follow": "متابعة", + "unfollow": "إلغاء المتابعة", "delete_all": "حذف الكل" } \ No newline at end of file diff --git a/public/language/ar/groups.json b/public/language/ar/groups.json index 9e5c9fa799..c67f95ef8b 100644 --- a/public/language/ar/groups.json +++ b/public/language/ar/groups.json @@ -18,10 +18,10 @@ "details.private": "خاص", "details.grant": "منح/سحب المِلكية", "details.kick": "طرد", - "details.owner_options": "تدبير المجموعة", + "details.owner_options": "إدارة المجموعة", "details.group_name": "اسم المجموعة", - "details.member_count": "Member Count", - "details.creation_date": "Creation Date", + "details.member_count": "عدد اﻷعضاء", + "details.creation_date": "تاريخ الإنشاء", "details.description": "الوصف", "details.badge_preview": "معاينة الوسام", "details.change_icon": "تغيير الأيقونة", diff --git a/public/language/ar/modules.json b/public/language/ar/modules.json index 3fdf629895..061fc4430c 100644 --- a/public/language/ar/modules.json +++ b/public/language/ar/modules.json @@ -16,8 +16,8 @@ "chat.thirty_days": "30 يومًا", "chat.three_months": "3 أشهر", "composer.compose": "Compose", - "composer.show_preview": "Show Preview", - "composer.hide_preview": "Hide Preview", + "composer.show_preview": "عرض المعاينة", + "composer.hide_preview": "إخفاء المعاينة", "composer.user_said_in": "%1 كتب في %2", "composer.user_said": "%1 كتب:", "composer.discard": "هل أنت متأكد أنك تريد التخلي عن التغييرات؟", diff --git a/public/language/ar/notifications.json b/public/language/ar/notifications.json index 98890331a5..2e87be20cd 100644 --- a/public/language/ar/notifications.json +++ b/public/language/ar/notifications.json @@ -1,5 +1,5 @@ { - "title": "تنبيهات", + "title": "التنبيهات", "no_notifs": "ليس لديك أية تنبيهات جديدة", "see_all": "معاينة كل التنبيهات", "mark_all_read": "اجعل كل التنبيهات مقروءة", diff --git a/public/language/ar/pages.json b/public/language/ar/pages.json index 793e2fd1dd..a767ba893f 100644 --- a/public/language/ar/pages.json +++ b/public/language/ar/pages.json @@ -1,9 +1,9 @@ { "home": "الصفحة الرئيسية", - "unread": "المواضيع غير المقروءة", + "unread": "المواضيع الغير مقروءة", "popular": "المواضيع الأكثر شهرة", "recent": "المواضيع الحديثة", - "users": "المستخدمون المسجلون", + "users": "اﻷعضاء المسجلون", "notifications": "التنبيهات", "tags": "Tags", "tag": "Topics tagged under \"%1\"", diff --git a/public/language/ar/recent.json b/public/language/ar/recent.json index 02003e5d81..4fc13736d0 100644 --- a/public/language/ar/recent.json +++ b/public/language/ar/recent.json @@ -5,15 +5,15 @@ "month": "شهر", "year": "سنة", "alltime": "دائمًا", - "no_recent_topics": "لاوجود لمشاركات جديدة", + "no_recent_topics": "لايوجد مواضيع جديدة", "no_popular_topics": "There are no popular 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/ar/register.json b/public/language/ar/register.json index 89ba850356..d456c82572 100644 --- a/public/language/ar/register.json +++ b/public/language/ar/register.json @@ -13,6 +13,6 @@ "confirm_password_placeholder": "تأكيد كلمة السر", "register_now_button": "قم بالتسجيل الآن", "alternative_registration": "طريقة تسجيل بديلة", - "terms_of_use": "قوانين الاستخدام", - "agree_to_terms_of_use": "أوافق على قوانين الاستخدام" + "terms_of_use": "شروط الاستخدام", + "agree_to_terms_of_use": "أوافق على شروط الاستخدام" } \ No newline at end of file diff --git a/public/language/ar/search.json b/public/language/ar/search.json index ba8bb5da76..f51edaba8a 100644 --- a/public/language/ar/search.json +++ b/public/language/ar/search.json @@ -1,10 +1,10 @@ { "results_matching": "%1 نتيجة (نتائج) موافقة ل \"%2\", (%3 ثواني)", "no-matches": "No matches found", - "advanced-search": "Advanced Search", - "in": "In", - "titles": "Titles", - "titles-posts": "Titles and Posts", + "advanced-search": "بحث متقدم", + "in": "في", + "titles": "العناوين", + "titles-posts": "العناوين والمشاركات", "posted-by": "Posted by", "in-categories": "In Categories", "search-child-categories": "Search child categories", @@ -12,29 +12,29 @@ "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", + "newer-than": "أحدث من", + "older-than": "أقدم من", + "any-date": "أي وقت", + "yesterday": "أمس", + "one-week": "أسبوع", + "two-weeks": "أسبوعان", + "one-month": "شهر", + "three-months": "ثلاثة أشهر", + "six-months": "ستة أشهر", + "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", + "last-reply-time": "تاريخ آخر رد", + "topic-title": "عنوان الموضوع", + "number-of-replies": "عدد الردود", + "number-of-views": "عدد المشاهدات", + "topic-start-date": "تاريخ بدأ الموضوع", + "username": "اسم المستخدم", "category": "Category", "descending": "In descending order", "ascending": "In ascending order", - "save-preferences": "Save preferences", + "save-preferences": "حفظ التفضيلات", "clear-preferences": "Clear preferences", - "search-preferences-saved": "Search preferences saved", + "search-preferences-saved": "تم حفظ تفضيلات البحث", "search-preferences-cleared": "Search preferences cleared", - "show-results-as": "Show results as" + "show-results-as": "عرض النتائج كـ" } \ No newline at end of file diff --git a/public/language/ar/topic.json b/public/language/ar/topic.json index c63f32e61c..0ac8738c9f 100644 --- a/public/language/ar/topic.json +++ b/public/language/ar/topic.json @@ -12,21 +12,21 @@ "notify_me": "تلق تنبيهات بالردود الجديدة في هذا الموضوع", "quote": "اقتبس", "reply": "رد", - "guest-login-reply": "Log in to reply", + "guest-login-reply": "يجب عليك تسجيل الدخول للرد", "edit": "تعديل", "delete": "حذف", "purge": "تطهير", "restore": "استعادة", - "move": "انقل", + "move": "نقل", "fork": "فرع", "link": "رابط", "share": "نشر", "tools": "أدوات", - "flag": "اشعار بمشاركة مخلة", + "flag": "تبليغ", "locked": "مقفل", - "bookmark_instructions": "انقر هنا للإكمال أو أغلق للإلغاء.", + "bookmark_instructions": "إضغط هنا للعودة إلى آخر موضع أو غلق للإلغاء", "flag_title": "إشعار بمشاركة مخلة.", - "flag_confirm": "هل تريد حقًّا أن تشعر بهذه المشاركة على أنها مخلة؟", + "flag_confirm": "هل تريد حقًّا التبليغ بهذه المشاركة؟", "flag_success": "تم الإشعار بهذه المشاركة على أنها مخلة", "deleted_message": "هذه المشاركة محذوفة. فقط من لهم صلاحية الإشراف على ا لمشاركات يمكنهم معاينتها.", "following_topic.message": "ستستلم تنبيها عند كل مشاركة جديدة في هذا الموضوع.", diff --git a/public/language/ar/unread.json b/public/language/ar/unread.json index 6495771c72..9abf80b1e9 100644 --- a/public/language/ar/unread.json +++ b/public/language/ar/unread.json @@ -3,7 +3,7 @@ "no_unread_topics": "ليس هناك أي موضوع غير مقروء", "load_more": "حمل المزيد", "mark_as_read": "حدد غير مقروء", - "selected": "المختارة", + "selected": "المحددة", "all": "الكل", "topics_marked_as_read.success": "تم تحديد المواضيع على أنها مقروءة!" } \ No newline at end of file diff --git a/public/language/ar/user.json b/public/language/ar/user.json index 58faafe2e8..613bade9ce 100644 --- a/public/language/ar/user.json +++ b/public/language/ar/user.json @@ -1,9 +1,9 @@ { "banned": "محظور", - "offline": "ليس موجود حالياً", + "offline": "غير متصل", "username": "إسم المستخدم", - "joindate": "Join Date", - "postcount": "Post Count", + "joindate": "تاريخ الإنضمام", + "postcount": "عدد المشاركات", "email": "البريد الإلكتروني", "confirm_email": "تأكيد عنوان البريد الإلكتروني", "delete_account": "حذف الحساب", @@ -15,10 +15,10 @@ "joined": "تاريخ التسجيل", "lastonline": "تاريخ آخر دخول", "profile": "الملف الشخصي", - "profile_views": "عدد مشاهدات الملف الشخصي", + "profile_views": "عدد المشاهدات", "reputation": "السمعة", - "favourites": "المفضلات", - "watched": "Watched", + "favourites": "التفضيلات", + "watched": "متابع", "followers": "المتابعون", "following": "يتابع", "signature": "توقيع", @@ -27,13 +27,13 @@ "chat": "محادثة", "follow": "تابع", "unfollow": "إلغاء المتابعة", - "more": "More", + "more": "المزيد", "profile_update_success": "تم تحديث الملف الشخصي بنجاح", "change_picture": "تغيير الصورة", "edit": "تعديل", "uploaded_picture": "الصورة المرفوعة", "upload_new_picture": "رفع صورة جديدة", - "upload_new_picture_from_url": "رفع صورة جديدة بواسطة رابط", + "upload_new_picture_from_url": "رفع صورة جديدة من رابط", "current_password": "كلمة السر الحالية", "change_password": "تغيير كلمة السر", "change_password_error": "كلمة سر غير صحيحة", @@ -60,7 +60,7 @@ "digest_monthly": "شهريًّا", "send_chat_notifications": "استلام رسالة إلكترونية عند ورود محادثة وأنا غير متصل.", "send_post_notifications": "Send an email when replies are made to topics I am subscribed to", - "settings-require-reload": "Some setting changes require a reload. Click here to reload the page.", + "settings-require-reload": "تغيير بعض اﻹعدادات يتطلب تحديث الصفحة. إضغط هنا لتحديث الصفحة", "has_no_follower": "هذا المستخدم ليس لديه أي متابع :(", "follows_no_one": "هذا المستخدم لا يتابع أحد :(", "has_no_posts": "هذا المستخدم لم يكتب أي شيء بعد.", @@ -71,13 +71,13 @@ "paginate_description": "Paginate topics and posts instead of using infinite scroll", "topics_per_page": "المواضيع في كل صفحة", "posts_per_page": "الردود في كل صفحة", - "notification_sounds": "Play a sound when you receive a notification", + "notification_sounds": "تشغيل صوت عند تلقي تنبيه", "browsing": "خيارات التصفح", - "open_links_in_new_tab": "Open outgoing links in new tab", + "open_links_in_new_tab": "فتح الروابط الخارجية في نافدة جديدة", "enable_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", + "follow_topics_you_reply_to": "متابعة المواضيع التي تقوم بالرد فيها", + "follow_topics_you_create": "متابعة المواضيع التي تنشئها", "grouptitle": "Select the group title you would like to display", "no-group-title": "No group title" } \ No newline at end of file diff --git a/public/language/ar/users.json b/public/language/ar/users.json index a842def62b..e49f5e1b79 100644 --- a/public/language/ar/users.json +++ b/public/language/ar/users.json @@ -1,12 +1,12 @@ { - "latest_users": "أحدث المستخدمين", - "top_posters": "أكثر المشتركين", + "latest_users": "أحدث الأعضاء", + "top_posters": "اﻷكثر مشاركة", "most_reputation": "أعلى سمعة", "search": "بحث", "enter_username": "أدخل اسم مستخدم للبحث", "load_more": "حمل المزيد", "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", "filter-by": "Filter By", - "online-only": "Online only", + "online-only": "المتصلون فقط", "picture-only": "Picture only" } \ No newline at end of file diff --git a/public/language/de/error.json b/public/language/de/error.json index 3c1248097a..1d5935080d 100644 --- a/public/language/de/error.json +++ b/public/language/de/error.json @@ -67,7 +67,7 @@ "topic-thumbnails-are-disabled": "Vorschaubilder für Themen sind deaktiviert", "invalid-file": "Datei ungültig", "uploads-are-disabled": "Uploads sind deaktiviert", - "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "signature-too-long": "Deine Signatur darf %1 Zeichen nicht überschreiten.", "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": "Du hast zu viele Nachrichten versandt, bitte warte eine Weile.", diff --git a/public/language/de/user.json b/public/language/de/user.json index 14772d4a2d..2661df0091 100644 --- a/public/language/de/user.json +++ b/public/language/de/user.json @@ -75,7 +75,7 @@ "browsing": "Stöbereinstellungen", "open_links_in_new_tab": "Ausgehende Links in neuem Tab öffnen", "enable_topic_searching": "Suchen innerhalb von Themen aktivieren", - "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", + "topic_search_help": "Wenn aktiviert, ersetzt die im-Thema-Suche die Standardsuche des Browsers. Dadurch kannst du im ganzen Thema suchen, nicht nur im sichtbaren Abschnitt.", "follow_topics_you_reply_to": "Themen folgen, in denen auf dich geantwortet wird", "follow_topics_you_create": "Themen folgen, die du erstellst", "grouptitle": "Wähle den anzuzeigenden Gruppen Titel aus", diff --git a/public/language/fa_IR/email.json b/public/language/fa_IR/email.json index 1ed97a0d8c..146d6ebb0d 100644 --- a/public/language/fa_IR/email.json +++ b/public/language/fa_IR/email.json @@ -1,5 +1,5 @@ { - "password-reset-requested": "درخواست گذرواژه مجدد- %1!", + "password-reset-requested": "درخواست بازیابی گذرواژه- %1!", "welcome-to": "به 1% خوش آمدید", "greeting_no_name": "سلام", "greeting_with_name": "سلام 1%", diff --git a/public/language/fa_IR/error.json b/public/language/fa_IR/error.json index b7e7237c4a..693ac564de 100644 --- a/public/language/fa_IR/error.json +++ b/public/language/fa_IR/error.json @@ -1,5 +1,5 @@ { - "invalid-data": "اطلاعات نامعتبر است.", + "invalid-data": "داده(های) نامعتبر", "not-logged-in": "به نظر میرسد که با حساب کاربری وارد نشده اید.", "account-locked": "حساب کاربری شما موقتاً مسدود شده است.", "search-requires-login": "جستجو نیاز به حساب کاربری دارد! لطفا وارد شوید و یا ثبت نام کنید!", @@ -21,11 +21,11 @@ "email-not-confirmed-chat": "شما تا قبل از تایید رایانامه قادر به گفتگو نیستید، لطفا برای تایید رایانامه خود اینجا کلیک کنید", "no-email-to-confirm": "این انجمن نیاز به تایید رایانامه دارد، لطفا برای وارد کردن رایانامه اینجا کلیک کنید", "email-confirm-failed": "ما نتوانستیم رایانامه شما را تایید کنیم، لطفا بعدا دوباره سعی کنید", - "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", + "confirm-email-already-sent": "رایانامه فعال‌سازی پیش‌تر فرستاده شده، لطفا %1 دقیقه صبر کنید تا رایانامه دیگری بفرستید.", "username-too-short": "نام کاربری خیلی کوتاه است.", "username-too-long": "نام کاربری بسیار طولانیست", "user-banned": "کاربر محروم شد.", - "user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post", + "user-too-new": "با عرض پوزش، شما باید %1 ثانیه پیش از فرستادن دیدگاه نخست خود صبر کنید", "no-category": "دسته بندی وجود ندارد", "no-topic": "جستار وجود ندارد.", "no-post": "دیدگاه وجود ندارد", @@ -36,9 +36,9 @@ "no-emailers-configured": "افزونه ایمیلی بارگیری نشده است، پس رایانامه امتحانی نمیتواند فرستاده شود", "category-disabled": "دسته غیر‌فعال شد.", "topic-locked": "جستار بسته شد.", - "post-edit-duration-expired": "You are only allowed to edit posts for %1 second(s) after posting", + "post-edit-duration-expired": "شما تنها می توانید %1 ثانیه پس از فرستادن دیدگاه آن‌را ویرایش کنید", "still-uploading": "خواهشمندیم تا پایان بارگذاری‌ها شکیبا باشید.", - "content-too-short": "Please enter a longer post. Posts should contain at least %1 character(s).", + "content-too-short": "خواهشمندیم دیدگاه بلندتری بنویسید. دیدگاه‌ها دست‌کم باید 1% نویسه داشته باشند.", "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 character(s).", "title-too-short": "Please enter a longer title. Titles should contain at least %1 character(s).", "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 character(s).", @@ -63,11 +63,11 @@ "post-already-restored": "دیدگاه پیش‌تر بازگردانی شده است.", "topic-already-deleted": "جستار پیش‌تر حذف شده است", "topic-already-restored": "جستار پیش‌تر بازگردانی شده است", - "cant-purge-main-post": "You can't purge the main post, please delete the topic instead", + "cant-purge-main-post": "شما نمی‌توانید دیدگاه اصلی را پاک کنید، لطفا جستار را به جای آن پاک کنید.", "topic-thumbnails-are-disabled": "چهرک‌های جستار غیرفعال شده است.", "invalid-file": "فایل نامعتبر است.", "uploads-are-disabled": "امکان بارگذاری غیرفعال شده است.", - "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "signature-too-long": "پوزش می‌خواهیم، امضای شما نمی‌تواند بیش‌تر از %1 نویسه داشته باشد.", "cant-chat-with-yourself": "شما نمی‌توانید با خودتان گفتگو کنید!", "chat-restricted": "این کاربر پیام های گفتگوی خود را محدود کرده است . آنها بایدشما را دنبال کنند تا اینکه شما بتوانید به آنها پیامی بفرستید", "too-many-messages": "شما پیامهای خیلی زیادی فرستاده اید، لطفا مدتی صبر نمایید", diff --git a/public/language/fa_IR/global.json b/public/language/fa_IR/global.json index b68c1d212d..f3594f29d3 100644 --- a/public/language/fa_IR/global.json +++ b/public/language/fa_IR/global.json @@ -27,7 +27,7 @@ "header.tags": "برچسب‌ها", "header.popular": "دوست‌داشتنی‌ها", "header.users": "کاربران", - "header.groups": "گروه ها", + "header.groups": "گروه‌ها", "header.chats": "گفتگوها", "header.notifications": "آگاه‌سازی‌ها", "header.search": "جستجو", diff --git a/public/language/fa_IR/groups.json b/public/language/fa_IR/groups.json index f16a3f3200..3f4d7d1c2c 100644 --- a/public/language/fa_IR/groups.json +++ b/public/language/fa_IR/groups.json @@ -1,5 +1,5 @@ { - "groups": "گروه ها", + "groups": "گروه‌ها", "view_group": "مشاهده گروه", "owner": "مالک گروه", "new_group": "ساخت گروه جدید", @@ -30,7 +30,7 @@ "details.userTitleEnabled": "نمایش نشان", "details.private_help": "اگر فعال باشد، پیوستن به گروه مستلزم موافقت صاحب گروه است", "details.hidden": "پنهان", - "details.hidden_help": "اگر فعال باشد، ایم گروه در فهرست گروه ها پیدا نمیشود، و کاربر باید دستی دعوت شود", + "details.hidden_help": "اگر فعال باشد، این گروه در فهرست گروه‌ها پیدا نمی‌شود و کاربران باید دستی فراخوانده شوند", "event.updated": "جزییات گروه با موفقیت به روز گردید", "event.deleted": "گروه \"%1\" حدف شد" } \ No newline at end of file diff --git a/public/language/fa_IR/pages.json b/public/language/fa_IR/pages.json index 18fa275e86..cf7accc690 100644 --- a/public/language/fa_IR/pages.json +++ b/public/language/fa_IR/pages.json @@ -12,7 +12,7 @@ "user.followers": "کاربرانی که %1 را دنبال می‌کنند", "user.posts": "دیدگاه‌های %1", "user.topics": "%1 این جستار را ساخت.", - "user.groups": "گروه های %1", + "user.groups": "گروه‌های %1", "user.favourites": "دیدگاه‌های پسندیدهٔ %1", "user.settings": "تنظیمات کاربر", "user.watched": "جستارهای پاییده شده توسط %1", diff --git a/public/language/fa_IR/search.json b/public/language/fa_IR/search.json index 52bcdc087a..6fe0ae4e0e 100644 --- a/public/language/fa_IR/search.json +++ b/public/language/fa_IR/search.json @@ -1,5 +1,5 @@ { - "results_matching": "%1 نتیجه (ها) مطابق با \"%2\" ,(%3 ثانیه)", + "results_matching": "%1 نتیجهٔ هم‌خوان با \"%2\"، (%3 ثانیه)", "no-matches": "هیچ موردی یافت نشد", "advanced-search": "جستجوی پیشرفته", "in": "در", diff --git a/public/language/fa_IR/success.json b/public/language/fa_IR/success.json index bfebde56e2..01984621ce 100644 --- a/public/language/fa_IR/success.json +++ b/public/language/fa_IR/success.json @@ -1,5 +1,5 @@ { - "success": "موفقیت", + "success": "موفقیت‌آمیز", "topic-post": "دیدگاه شما باموفقیت فرستاده شد.", "authentication-successful": "اعتبارسنجی موفق", "settings-saved": "تنظیمات اندوخته شد." diff --git a/public/language/hu/search.json b/public/language/hu/search.json index d3df716f81..5309e9ec32 100644 --- a/public/language/hu/search.json +++ b/public/language/hu/search.json @@ -1,14 +1,14 @@ { "results_matching": "%1 eredmény(ek) erre \"%2\" (%3 másodperc alatt)", "no-matches": "No matches found", - "advanced-search": "Advanced Search", + "advanced-search": "Bővített keresés", "in": "In", - "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", + "titles": "Címek", + "titles-posts": "Címek és Bejegyzések", + "posted-by": "Szerző", + "in-categories": "Kategória", + "search-child-categories": "Keresés az alkategóriák közt", + "reply-count": "Válaszok száma", "at-least": "At least", "at-most": "At most", "post-time": "Post time", diff --git a/public/language/ms/global.json b/public/language/ms/global.json index 5b1c91d6bb..1f8a8ffba5 100644 --- a/public/language/ms/global.json +++ b/public/language/ms/global.json @@ -11,7 +11,7 @@ "500.message": "Oops! Macam ada yang tidak kena", "register": "Daftar", "login": "Log Masuk", - "please_log_in": "Sila daftar masuk", + "please_log_in": "Sila log masuk", "logout": "Log Keluar", "posting_restriction_info": "Kiriman terhad kepada pengguna berdaftar sahaja, Sila click disini untuk daftar masuk", "welcome_back": "Selamat kembali", @@ -37,19 +37,19 @@ "motd.welcome": "Selamat datang ke NodeBB, platfom perbincangan masa hadapan", "previouspage": "Laman sebelum", "nextpage": "Laman berikut", - "alert.success": "berjaya", - "alert.error": "ralat", + "alert.success": "Berjaya", + "alert.error": "Ralat", "alert.banned": "Diharamkan", "alert.banned.message": "Amda baru sahaja diharamkan, anda sekarang akan di log keluar.", "alert.unfollow": "Anda tidak lagi mengikuti %1", "alert.follow": "Anda sekarang mengikuti %1", - "online": "dalam talian", + "online": "Dalam talian", "users": "Pengguna", "topics": "Topik", "posts": "Kiriman", - "views": "Paparan", + "views": "Lihat", "reputation": "Reputasi", - "read_more": "baca lafi", + "read_more": "baca lagi", "posted_ago_by_guest": "dikirim %1 oleh pelawat", "posted_ago_by": "dikirim %1 oleh %2", "posted_ago": "dikirim %1", @@ -64,16 +64,16 @@ "norecenttopics": "Tiada topik terkini", "recentposts": "Kiriman terkini", "recentips": "IP berdaftar terkini", - "away": "jauh", - "dnd": "jangan ganggu", + "away": "Jauh", + "dnd": "Jangan ganggu", "invisible": "Halimunan", - "offline": "Tidak ditalian", + "offline": "Luar talian", "email": "Emel", "language": "Bahasa", "guest": "Pelawat", "guests": "Pelawat", "updated.title": "Forum Dikemaskini", - "updated.message": "Forum ini baru dshsjs dikemaskini ke versi terkini. Klik sini untuk segar semula halaman.", + "updated.message": "Forum ini baru sahaja dikemaskini ke versi terkini. Klik sini untuk segar semula halaman.", "privacy": "Privasi", "follow": "Ikut", "unfollow": "Nyah-ikut", diff --git a/public/language/ms/user.json b/public/language/ms/user.json index 305f15bdb8..87c7c02d94 100644 --- a/public/language/ms/user.json +++ b/public/language/ms/user.json @@ -1,6 +1,6 @@ { "banned": "Diharamkan", - "offline": "Tidak ditalian", + "offline": "Luar talian", "username": "Nama pengguna", "joindate": "Tarikh Mula", "postcount": "Jumlah Kiriman", diff --git a/public/language/nl/category.json b/public/language/nl/category.json index afb8eb21c8..9070eb6ba4 100644 --- a/public/language/nl/category.json +++ b/public/language/nl/category.json @@ -7,6 +7,6 @@ "share_this_category": "Deel deze categorie", "watch": "Volgen", "ignore": "Negeren", - "watch.message": "Je krijgt nu updates binnen van deze categorie", - "ignore.message": "Je krijgt geen updates meer binnen van deze categorie" + "watch.message": "Van deze categorie worden nu meldingen ontvangen", + "ignore.message": "Er worden geen meldingen van deze categorie ontvangen" } \ No newline at end of file diff --git a/public/language/nl/email.json b/public/language/nl/email.json index 18d7ab4a97..6eeb3de7f6 100644 --- a/public/language/nl/email.json +++ b/public/language/nl/email.json @@ -1,28 +1,28 @@ { - "password-reset-requested": "Wachtwoord Reset Aangevraagd - %1!", + "password-reset-requested": "Om wachtwoordherstel verzocht - %1!", "welcome-to": "Welkom bij %1", "greeting_no_name": "Hallo", "greeting_with_name": "Hallo %1", - "welcome.text1": "Bedank voor het registreren met %1!", - "welcome.text2": "Om u account volledig te activeren, moet u op de link klikken die u heeft ontvangen in uw inbox", - "welcome.cta": "Klik hier om te bevestigen met uw email adres", - "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": "Wachtwoord succesvol veranderd", - "reset.notify.text1": "Wij brengen u bij deze op de hoogte that uw wachtwoord succesvol is gewijzigd op %1.", - "reset.notify.text2": "Neem contact op met een administrator als u hier geen toestemming voor gegeven heeft.", - "digest.notifications": "U heeft ongelezen notificaties van %1:", - "digest.latest_topics": "De laatste onderwerpen van %1", + "welcome.text1": "Bedank voor het registreren bij %1!", + "welcome.text2": "Om de account volledig te activeren, dienen de instructies uit het bevestigingsbericht opgevolgd te worden. Controleer daarom nu eerst de e-mail inbox voor de activeringscode en volg de link in het bericht.", + "welcome.cta": "Klik hier voor bevestigen van het e-mailadres", + "reset.text1": "Wij ontvingen zojuist een verzoek om het wachtwoord van de account, bij onze website bekend als gekoppeld aan dit e-mailadres, te herstellen. Is dit verzoek niet bekend en geautoriseerd, dan kan dit bericht genegeerd worden.", + "reset.text2": "Om het wachtwoord opnieuw in te stellen, klik op deze link:", + "reset.cta": "Klik hier voor wachtwoordherstel", + "reset.notify.subject": "Wachtwoord succesvol gewijzigd", + "reset.notify.text1": "Op %1 is het wachtwoord van de bij ons geregistreerde gebruikersaccount succesvol gewijzigd.", + "reset.notify.text2": "Neem onmiddellijk contact met een beheerder op wanneer geen toestemming voor deze actie gegeven is en deze niet vanuit hier aangevraagd is.", + "digest.notifications": "Er zijn ongelezen notificaties van %1:", + "digest.latest_topics": "De meest recente onderwerpen van %1", "digest.cta": "Klik hier om deze website te bezoeken %1 ", - "digest.unsub.info": "Deze overzicht was verzonden naar jou vanwege je abbonement instellingen", - "digest.no_topics": "Er zijn geen actieve onderwerpen in de afgelopen dagen %1", - "notif.chat.subject": "U heeft een chatbericht ontvangen van %1", + "digest.unsub.info": "Deze samenvatting is vanwege instellingen voor abonnementen van de gebruikersaccount door ons verzonden.", + "digest.no_topics": "Er zijn geen actieve onderwerpen geweest %1", + "notif.chat.subject": "Nieuw chatbericht ontvangen van %1", "notif.chat.cta": "Klik hier om het gesprek te hervatten", - "notif.chat.unsub.info": "Deze chat notificatie was verzonden naar jou vanwege je abbonement instellingen", + "notif.chat.unsub.info": "Deze notificatie is verzonden vanwege de gebruikersinstellingen voor abonnementen.", "notif.post.cta": "Klik hier om het volledige bericht te lezen", - "notif.post.unsub.info": "Deze bericht notificatie werd naar u verstuurd wegens uw abonnement instellingen.", - "test.text1": "Dit is een test email om te verifiëren dat de email service correct is opgezet voor jou NodeBB", - "unsub.cta": "Klik hier om u instellingen te wijzigen", + "notif.post.unsub.info": "Deze notificatie is door ons verzonden vanwege gebruikersinstellingen voor abonnementen en berichten.", + "test.text1": "Dit is een testbericht om te verifiëren dat NodeBB de e-mailberichtservice correct heeft opgezet.", + "unsub.cta": "Klik hier om deze instellingen te wijzigen", "closing": "Bedankt!" } \ No newline at end of file diff --git a/public/language/nl/error.json b/public/language/nl/error.json index 984ed8e4a1..8fc4f46971 100644 --- a/public/language/nl/error.json +++ b/public/language/nl/error.json @@ -1,83 +1,83 @@ { "invalid-data": "Ongeldige Data", - "not-logged-in": "Het lijkt dat je niet bent ingelogd.", - "account-locked": "U account is tijdelijk geblockt", - "search-requires-login": "Het zoeken naar berichten of topics vereist een account. Registreer een account of meld u aan.", - "invalid-cid": "Ongeldig Categorie ID", - "invalid-tid": "Ongeldig Onderwerp ID", - "invalid-pid": "Ongeldig Bericht ID", - "invalid-uid": "Ongeldig Gebruikers ID", - "invalid-username": "Ongeldig Gebruikersnaam", - "invalid-email": "Ongeldig Email Adres", - "invalid-title": "Ongeldige Titel!", - "invalid-user-data": "Ongeldig Gebruikersdata", + "not-logged-in": "De account lijkt op dit moment niet aangemeld te zijn.", + "account-locked": "De account is tijdelijk vergrendeld", + "search-requires-login": "Zoekfunctionaliteit gebruiker vereist een account. Registreer daarom snel, of log in op een bestaande gebruikersaccount.", + "invalid-cid": "Ongeldig categoriesleutel", + "invalid-tid": "Ongeldig id voor onderwerp", + "invalid-pid": "Ongeldig berichtkenmerk", + "invalid-uid": "Ongeldig gebruikerskenmerk", + "invalid-username": "Ongeldige gebruikersnaam", + "invalid-email": "Ongeldig e-mailadres", + "invalid-title": "Ongeldige titel", + "invalid-user-data": "Ongeldige gebruikersgegevens", "invalid-password": "Ongeldig wachtwoord", - "invalid-username-or-password": "Geef alsjeblieft een gebruikersnaam en wachtwoord op", - "invalid-search-term": "Ongeldig zoekterm", - "invalid-pagination-value": "Ongeldig pagineringswaarde", - "username-taken": "Gebruikersnaam is al bezet", - "email-taken": "Email adres is al gebruikt", - "email-not-confirmed": "U email adres is niet bevestigd, Klik hier om uw email adres te bevestigen", - "email-not-confirmed-chat": "U kunt helaas geen gebruik maken van chats tot uw email adres bevestigd is.", - "no-email-to-confirm": "Dit forum vereist email bevestiging, klikt u alstublieft hier om uw email te vermelden", - "email-confirm-failed": "Uw email kon helaas niet bevestigd worden, probeert u het alstublieft later nog eens.", - "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", - "username-too-short": "Gebruikersnaam is te kort", - "username-too-long": "Gebruikersnaam is te lang", + "invalid-username-or-password": "Geef zowel een gebruikersnaam als wachtwoord op", + "invalid-search-term": "Ongeldig zoekopdracht, een of meerdere termen", + "invalid-pagination-value": "Ongeldig waarde voor paginering", + "username-taken": "Gebruikersnaam is al in gebruik bij een andere account", + "email-taken": "E-mailadres is al eens eerder gebruikt", + "email-not-confirmed": "Het e-mailadres van deze account is nog niet bevestigd. Klik hier om het e-mailadres te bevestigen en de registratie af te ronden.", + "email-not-confirmed-chat": "Het gebruik van chatfunctionaliteit is pas toegestaan na validatie van het e-mailadres.", + "no-email-to-confirm": "Dit berichtenforum vereist bevestiging per e-mail, klik hier om een e-mailadres te registreren", + "email-confirm-failed": "Helaas kon het e-mailadres niet bevestigd worden, probeert het later nog eens.", + "confirm-email-already-sent": "Bevestigingsbericht per e-mail al zojuist verzonden, wacht even een %1 tal minuutjes voordat opnieuw een bericht verzonden wordt. ", + "username-too-short": "Gebruikersnaam bevat niet voldoende tekens", + "username-too-long": "Gebruikersnaam bevat meer dan het toegestane aantal tekens", "user-banned": "Gebruiker verbannen", - "user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post", + "user-too-new": "Helaas, maar het is een vereiste om %1 seconde(n) te wachten voordat het eerste bericht geplaatst kan worden.", "no-category": "Categorie bestaat niet", - "no-topic": "Topic bestaat niet", + "no-topic": "Onderwerp bestaat niet", "no-post": "Bericht bestaat niet", "no-group": "Groep bestaat niet", "no-user": "Gebruiker bestaat niet", - "no-teaser": "Dit kort bericht bestaat niet", - "no-privileges": "U heeft niet voldoende rechten om deze actie te doen", - "no-emailers-configured": "Er zijn geen email plugins geladen, een test email kan dus niet verzonden worden", + "no-teaser": "Dit voorproefje bestaat niet", + "no-privileges": "Onvoldoende rechten om deze actie uit te voeren", + "no-emailers-configured": "Er zijn geen e-mailplugins geladen, een testbericht kan dus niet verzonden worden", "category-disabled": "Categorie uitgeschakeld", "topic-locked": "Onderwerp gesloten", - "post-edit-duration-expired": "You are only allowed to edit posts for %1 second(s) after posting", - "still-uploading": "Heb even geduld totdat de alle bestanden geüpload zijn", - "content-too-short": "Please enter a longer post. Posts should contain at least %1 character(s).", - "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 character(s).", - "title-too-short": "Please enter a longer title. Titles should contain at least %1 character(s).", - "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 character(s).", - "too-many-posts": "You can only post once every %1 second(s) - please wait before posting again", - "too-many-posts-newbie": "As a new user, you can only post once every %1 second(s) 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 character(s)", - "tag-too-long": "Please enter a shorter tag. Tags can't be longer than %1 character(s)", - "file-too-big": "Maximum allowed file size is %1 kB - please upload a smaller file", - "cant-vote-self-post": "Je kan niet op je eigen berichten stemmen", - "already-favourited": "U heeft al dit bericht in uw favorieten staan", - "already-unfavourited": "U heeft al dit bericht uit uw favorieten gehaald", - "cant-ban-other-admins": "U kunt niet de andere admins bannen!", - "invalid-image-type": "Dit foto bestandstype is niet toegestaan. Toegestane foto bestandstypen zijn: %1", - "invalid-image-extension": "Ongeldige foto bestandsextensie", - "invalid-file-type": "Dit bestandstype is niet toegestaan. Toegestane bestandstypen zijn: %1", - "group-name-too-short": "De groepsnaam is te kort", - "group-already-exists": "Deze groep bestaat al", + "post-edit-duration-expired": "Het is slechts toegestaan om binnen %1 seconde(n) na plaatsen van het bericht, deze te bewerken.", + "still-uploading": "Een moment geduld tot alle bestanden overgebracht zijn...", + "content-too-short": "Geef wat meer volume, inhoud aan een bericht! Berichten dienen uit minimaal %1 teken(s) te bestaan.", + "content-too-long": "Kort het bericht wat in, het aantal gebruikte tekens overschrijdt het ingestelde limiet want berichten mogen niet meer dan %1 teken(s) bevatten.", + "title-too-short": "Geef een titel op die uit meer tekens bestaat. Titels dienen ten minste uit %1 teken(s) te bestaan.", + "title-too-long": "Geef een kortere titel op. Titels mogen uit niet meer dan %1 teken(s) bestaan.", + "too-many-posts": "Het is slechts toegestaan iedere %1 seconde(n) een bericht te plaatsen - wacht even voordat opnieuw een bericht verzonden wordt", + "too-many-posts-newbie": "Nieuwe gebruikersaccounts zoals deze zijn begrensd en mogen slechts iedere %1 seconde(n) berichten plaatsen, tot het moment dat %2 reputatie verdiend is - wacht daarom even met opnieuw een bericht te plaatsten", + "tag-too-short": "Geef een tag op die uit meer tekens bestaat. Tags dienen uit minimaal %1 teken(s) te bestaan.", + "tag-too-long": "Geef een kortere tag op. Tags mogen niet langer dan %1 teken(s) zijn", + "file-too-big": "Maximum toegestane bestandsgrootte is %1 kB - probeer een kleiner bestand te verzenden", + "cant-vote-self-post": "Het is niet mogelijk op eigen berichten te stemmen", + "already-favourited": "Dit bericht staat al tussen de favorieten", + "already-unfavourited": "Dit bericht is al uit favorieten verwijderd", + "cant-ban-other-admins": "Het is niet toegestaan andere beheerders te verbannen!", + "invalid-image-type": "Ongeldig bestandstype afbeelding. Deze afbeelding is van een bestandstype dat niet ondersteund wordt. Toegestane bestandstypes voor afbeeldingsbestanden zijn: %1", + "invalid-image-extension": "Ongeldige bestandstype afbeelding", + "invalid-file-type": "Dit bestandstype wordt niet ondersteund. Toegestane bestandstypen zijn: %1", + "group-name-too-short": "De groepsnaam bevat niet genoeg tekens", + "group-already-exists": "Een groep met deze naam bestaat al", "group-name-change-not-allowed": "Het veranderen van de groepsnaam is niet toegestaan!", - "group-already-member": "U bent al lid van deze groep", - "group-needs-owner": "Deze groep vereist minimaal 1 eigenaar", + "group-already-member": "Groepslidmaatschap al aanwezig", + "group-needs-owner": "De groep vereist ten minste 1 eigenaar", "post-already-deleted": "Dit bericht is al verwijderd", "post-already-restored": "Dit bericht is al hersteld", - "topic-already-deleted": "Deze topic is al verwijderd", - "topic-already-restored": "Deze topic is al hersteld", - "cant-purge-main-post": "Je kan het beginbericht niet verwijderen. Verwijder het onderwerp hiervoor.", - "topic-thumbnails-are-disabled": "Onderwerp thumbnails zijn uitgeschakeld", + "topic-already-deleted": "Dit onderwerp is al verwijderd", + "topic-already-restored": "Dit onderwerp is al hersteld", + "cant-purge-main-post": "Het is niet mogelijk het eerste bericht te verwijderen. Hiervoor dient het gehele onderwerp verwijderd te worden.", + "topic-thumbnails-are-disabled": "Miniatuurweergaven bij onderwerpen uitgeschakeld. ", "invalid-file": "Ongeldig bestand", "uploads-are-disabled": "Uploads zijn uitgeschakeld", - "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", - "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": "U heeft teveel berichten verstuurd in een korte tijd. Wacht u alstublieft even.", - "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", - "not-enough-reputation-to-flag": "U heeft niet de benodigde reputatie om dit bericht te melden aan de admins", - "reload-failed": "NodeBB heeft een probleem geconstateerd tijdens het laden van: \"%1\".\nNodeBB blijft verder draaien. Het is wel verstandig om de actie wat u daarvoor heeft gedaan ongedaan te maken door te herladen.", - "registration-error": "Registratie fout", - "parse-error": "Er is iets fout gegaan tijdens het parsen van de server response", - "wrong-login-type-email": "Gebruikt u alstublieft uw email om in te loggen", - "wrong-login-type-username": "Gebruikt u alstublieft uw gebruikersnaam om in te loggen" + "signature-too-long": "Helaas, maar de handtekening mag uit niet meer dan %1 teken(s) bestaan.", + "cant-chat-with-yourself": "Het is niet mogelijk met jezelf een chatgesprek te houden.", + "chat-restricted": "Deze gebruiker heeft beperkingen aan de chatfunctie opgelegd waardoor deze eerst iemand moet volgen voordat deze persoon een nieuwe chat mag initiëren.", + "too-many-messages": "Er zijn in korte tijd teveel berichten verzonden, een moment geduld.", + "reputation-system-disabled": "Reputatie systeem is uitgeschakeld.", + "downvoting-disabled": "Negatief stemmen staat uitgeschakeld.", + "not-enough-reputation-to-downvote": "Deze gebruikersaccount beschikt over onvoldoende reputatie om een negatieve stem uit te mogen brengen.", + "not-enough-reputation-to-flag": "Onvoldoende reputatie om dit bericht aan beheerders te mogen melden.", + "reload-failed": "Tijdens het herladen van \"%1\" is NodeBB een fout of probleem tegen gekomen. NodeBB blijft operationeel echter het is verstandig om de oorzaak te onderzoeken en wellicht de vorige actie, voor het herladen, ongedaan te maken.", + "registration-error": "Fout tijdens registratie", + "parse-error": "Tijdens het verwerken van het antwoord van de server is iets misgegaan.", + "wrong-login-type-email": "Gebruik het e-mailadres voor aanmelden", + "wrong-login-type-username": "Geef de gebruikersnaam voor aanmelden" } \ No newline at end of file diff --git a/public/language/nl/global.json b/public/language/nl/global.json index bea96ad2b4..9d0b5c6b2a 100644 --- a/public/language/nl/global.json +++ b/public/language/nl/global.json @@ -2,26 +2,26 @@ "home": "Home", "search": "Zoeken", "buttons.close": "Sluiten", - "403.title": "Toegang Geweigerd", - "403.message": "Het lijkt er op dat u op een pagina bent beland waar u geen toegang tot heeft.", - "403.login": "Misschien moet u proberen in te loggen?", - "404.title": "Niet Gevonden", - "404.message": "Het lijkt er op dat u op een pagina bent beland die niet bestaat. Ga terug naar de home pagina.", + "403.title": "Geen toegang", + "403.message": "Deze account heeft onvoldoende systeemrechten om toegang tot de pagina te krijgen.", + "403.login": "Wellicht proberen aan te melden?", + "404.title": "Niet gevonden", + "404.message": "Deze pagina bestaat niet. Klik hier om naar de hoofdpagina van deze website te navigeren.", "500.title": "Interne fout.", - "500.message": "Oeps! Het lijkt erop dat iets is fout gegaan!", + "500.message": "Oeps! Ziet er naar uit dat iets fout ging!", "register": "Registeren", - "login": "Inloggen", - "please_log_in": "Log a.u.b. In", - "logout": "Uitloggen", - "posting_restriction_info": "Reageren is momenteel beperkt tot geregistreerde leden, klik hier om in te loggen.", - "welcome_back": "Welkom Terug", - "you_have_successfully_logged_in": "Je bent succesvol ingelogd", - "save_changes": "Aanpassingen Opslaan", + "login": "Login", + "please_log_in": "Aanmelden", + "logout": "Afmelden", + "posting_restriction_info": "Momenteel mogen alleen geregistreerde leden reageren. Klik om naar de aanmeldpagina te gaan.", + "welcome_back": "Welkom terug", + "you_have_successfully_logged_in": "Aanmelden succesvol", + "save_changes": "Wijzigingen opslaan", "close": "Sluiten", "pagination": "Paginering", "pagination.out_of": "%1 van %2", "pagination.enter_index": "Vul index in", - "header.admin": "Admin", + "header.admin": "Beheer", "header.recent": "Recent", "header.unread": "Ongelezen", "header.tags": "Tags", @@ -32,22 +32,22 @@ "header.notifications": "Notificaties", "header.search": "Zoeken", "header.profile": "Profiel", - "notifications.loading": "Notificaties Laden", - "chats.loading": "Chats Laden", + "notifications.loading": "Notificaties laden", + "chats.loading": "Chats laden", "motd.welcome": "Welkom bij NodeBB, het discussie platform van de toekomst.", - "previouspage": "Vorige Pagina", - "nextpage": "Volgende Pagina", + "previouspage": "Vorige pagina", + "nextpage": "Volgende pagina", "alert.success": "Succes", "alert.error": "Fout", "alert.banned": "Verbannen", - "alert.banned.message": "U bent verbannen en zal automatisch worden uitgelogd.", - "alert.unfollow": "Je volgt niet langer %1!", - "alert.follow": "Je volgt nu %1!", + "alert.banned.message": "Deze account is verbannen en wordt automatisch afgemeld.", + "alert.unfollow": "%1 wordt niet langer gevolgd!", + "alert.follow": "%1 wordt nu gevolgd!", "online": "Online", "users": "Gebruikers", - "topics": "Topics", + "topics": "Onderwerpen", "posts": "Berichten", - "views": "Weergaven", + "views": "Gezien", "reputation": "Reputatie", "read_more": "Lees meer", "posted_ago_by_guest": "geplaatst %1 door gast", @@ -60,20 +60,20 @@ "user_posted_ago": "%1 plaatste %2", "guest_posted_ago": "Gast plaatste %1", "last_edited_by_ago": "voor het laatst aangepast door %1 %2", - "norecentposts": "Geen Recente Berichten", - "norecenttopics": "Geen Recente Onderwerpen", - "recentposts": "Recente Berichten", - "recentips": "Recente Ingelogde IPs", + "norecentposts": "Geen recente berichten", + "norecenttopics": "Geen recente onderwerpen", + "recentposts": "Recente berichten", + "recentips": "IP-adressen van recente gebruikers", "away": "Afwezig", - "dnd": "Niet Storen", + "dnd": "Niet storen", "invisible": "Onzichtbaar", "offline": "Offline", - "email": "Email Adres", + "email": "E-mailadres", "language": "Taal", "guest": "Gast", "guests": "Gasten", - "updated.title": "Forum geüpdatet", - "updated.message": "Dit forum is zojuist geüpdatet naar de laatste versie. Klik hier om de pagina te verversen", + "updated.title": "Site update", + "updated.message": "Deze site heeft zojuist een update ontvangen. Klik hier om de pagina te verversen.", "privacy": "Privé", "follow": "Volgen", "unfollow": "Ontvolgen", diff --git a/public/language/nl/groups.json b/public/language/nl/groups.json index 8fbbbee137..3ee0fccb73 100644 --- a/public/language/nl/groups.json +++ b/public/language/nl/groups.json @@ -1,36 +1,36 @@ { "groups": "Groepen", - "view_group": "Bekijk Groep", - "owner": "Groep eigenaar", - "new_group": "Maak een nieuwe groep", - "no_groups_found": "Er zijn geen groepen om weer te geven", + "view_group": "Weergeven groep", + "owner": "Groepseigenaar", + "new_group": "Nieuwe groep", + "no_groups_found": "Geen groepen voor weergave", "pending.accept": "Accepteer", "pending.reject": "Afwijzen", - "cover-instructions": "Sleep een foto, positioneer en klik op Opslaan", - "cover-change": "Aanpassen", + "cover-instructions": "Sleep een afbeelding, sleep om te positioneren en klik tenslotte op Opslaan", + "cover-change": "Bewerken", "cover-save": "Opslaan", "cover-saving": "Bezig met opslaan", - "details.title": "Groep Details", + "details.title": "Groepsdetails", "details.members": "Ledenlijst", - "details.pending": "Afwachtende leden", + "details.pending": "Nog niet geaccepteerde leden", "details.has_no_posts": "Deze groepleden hebben nog geen berichten geplaatst", - "details.latest_posts": "Nieuwste Berichten", + "details.latest_posts": "Meest recente berichten", "details.private": "Prive", - "details.grant": "Toekennen/Herroepen van eigenaarschap", - "details.kick": "Verwijder", - "details.owner_options": "Groeps Administratie", + "details.grant": "Toekennen/herroepen van eigendom", + "details.kick": "Schoppen", + "details.owner_options": "Groepsadministratie", "details.group_name": "Groepsnaam", - "details.member_count": "Leden telling", - "details.creation_date": "Datum van het creëeren", + "details.member_count": "Ledentelling", + "details.creation_date": "Aangemaakt op", "details.description": "Beschrijving", - "details.badge_preview": "Badge Voorvertoning", - "details.change_icon": "Icoon veranderen", - "details.change_colour": "Kleur veranderen", - "details.badge_text": "Badge tekst", - "details.userTitleEnabled": "Badge tonen", - "details.private_help": "Indien geactiveerd, zal er goedkeuring moeten worden verleend door een groepseigenaar voor het toetreden van groepen", - "details.hidden": "Verborgen", + "details.badge_preview": "Draaginsigne voorvertoning", + "details.change_icon": "Wijzig icoon", + "details.change_colour": "Wijzig kleur", + "details.badge_text": "Draaginsigne tekst", + "details.userTitleEnabled": "Draaginsignes weergeven", + "details.private_help": "Wanneer ingeschakeld, zal eerst een groepseigenaar goedkeuring moeten verlenen voordat nieuwe leden kunnen toetreden", + "details.hidden": "Niet getoond", "details.hidden_help": "Indien geactiveerd zal deze groep niet getoond worden in de groepslijst en zullen gebruikers handmatig uitgenodigd moeten worden.", - "event.updated": "Groepsdetails zijn geupdate", + "event.updated": "Groepsdetails zijn bijgewerkt", "event.deleted": "De groep \"%1\" is verwijderd" } \ No newline at end of file diff --git a/public/language/nl/login.json b/public/language/nl/login.json index fa1c5bf8eb..0e2a65a11a 100644 --- a/public/language/nl/login.json +++ b/public/language/nl/login.json @@ -2,10 +2,10 @@ "username-email": "Gebruikersnaam / Email", "username": "Gebruikersnaam", "email": "Email", - "remember_me": "Mij Onthouden?", - "forgot_password": "Wachtwoord Vergeten?", - "alternative_logins": "Alternatieve Loginmethodes", - "failed_login_attempt": "Mislukte inlog poging, probeer het later opnieuw.", - "login_successful": "Je bent succesvol ingelogd!", - "dont_have_account": "Heeft u nog geen account?" + "remember_me": "Aangemeld blijven?", + "forgot_password": "Wachtwoord vergeten?", + "alternative_logins": "Andere manieren van aanmelden", + "failed_login_attempt": "Aanmelden niet geslaagd. Probeer het nog eens.", + "login_successful": "Aanmelden geslaagd!", + "dont_have_account": "Geen gebruikersaccount?" } \ No newline at end of file diff --git a/public/language/nl/modules.json b/public/language/nl/modules.json index 76dd6413a9..26f89112ba 100644 --- a/public/language/nl/modules.json +++ b/public/language/nl/modules.json @@ -1,26 +1,26 @@ { "chat.chatting_with": "Chat met ", - "chat.placeholder": "Type chat bericht hier, druk op enter om te verzenden", + "chat.placeholder": "Typ een chatbericht hier, toets enter om te verzenden", "chat.send": "Verzenden", - "chat.no_active": "Je hebt geen actieve chats.", + "chat.no_active": "Er zijn geen actieve chats.", "chat.user_typing": "%1 is aan het typen ...", - "chat.user_has_messaged_you": "%1 heeft een bericht naar u gestuurd", + "chat.user_has_messaged_you": "%1 heeft een bericht gestuurd", "chat.see_all": "Bekijk alle gesprekken", - "chat.no-messages": "Selecteer een ontvanger om de geschiedenis van het gesprek te bekijken", - "chat.recent-chats": "Recente Gesprekken", + "chat.no-messages": "Selecteer een ontvanger om de chatgeschiedenis in te zien", + "chat.recent-chats": "Recent gevoerde gesprekken", "chat.contacts": "Contacten", - "chat.message-history": "Berichten Geschiedenis", - "chat.pop-out": "tevoorschijn halen gesprek", + "chat.message-history": "Berichtengeschiedenis", + "chat.pop-out": "Chatvenster opbrengen bij chat", "chat.maximize": "Maximaliseren", - "chat.seven_days": "7 Dagen", - "chat.thirty_days": "30 Dagen", - "chat.three_months": "3 Maanden", - "composer.compose": "samenstellen", - "composer.show_preview": "Laat voorbeeld zien", + "chat.seven_days": "7 dagen", + "chat.thirty_days": "30 dagen", + "chat.three_months": "3 maanden", + "composer.compose": "Samenstellen", + "composer.show_preview": "Voorbeeldweergave", "composer.hide_preview": "Verberg voorbeeld", "composer.user_said_in": "%1 zegt in %2:", "composer.user_said": "%1 zegt:", - "composer.discard": "Weet u het zeker dat u dit bericht niet wilt plaatsen?", - "composer.submit_and_lock": "Plaatsen en vergrendelen", - "composer.toggle_dropdown": "pin menu" + "composer.discard": "Bericht plaatsen annuleren?", + "composer.submit_and_lock": "Plaats een bericht en vergrendel direct het onderwerp", + "composer.toggle_dropdown": "Keuzelijst schakelen" } \ No newline at end of file diff --git a/public/language/nl/notifications.json b/public/language/nl/notifications.json index 4e5a599896..fc2e904d90 100644 --- a/public/language/nl/notifications.json +++ b/public/language/nl/notifications.json @@ -1,27 +1,27 @@ { "title": "Notificaties", "no_notifs": "Je hebt geen nieuwe notificaties", - "see_all": "Bekijk alle Notificaties", - "mark_all_read": "Markeer alle meldingen als gelezen", + "see_all": "Bekijk alle notificaties", + "mark_all_read": "Markeer alles als gelezen", "back_to_home": "Terug naar %1", "outgoing_link": "Uitgaande Link", "outgoing_link_message": "Je verlaat nu %1", - "continue_to": "Doorgaan naar %1", - "return_to": "Teruggaan naar %1", - "new_notification": "een nieuwe notificatie", - "you_have_unread_notifications": "U heeft ongelezen notificaties", + "continue_to": "Door naar %1", + "return_to": "Terug naar %1", + "new_notification": "Nieuwe melding", + "you_have_unread_notifications": "Ongelezen berichten", "new_message_from": "Nieuw bericht van %1", - "upvoted_your_post_in": "%1 heeft uw bericht geupvote in %2.", - "moved_your_post": "%1 heeft uw bericht verplaatst", - "moved_your_topic": "%1 heeft uw onderwerp verplaatst.", - "favourited_your_post_in": "%1 heeft uw bericht gefavoriet in %2.", + "upvoted_your_post_in": "%1 heeft voor een bericht gestemd in %2.", + "moved_your_post": "%1 heeft het bericht verplaatst.", + "moved_your_topic": "%1 heeft het onderwerp verplaatst.", + "favourited_your_post_in": "%1 heeft een van onze berichten in %2 aan de favorieten toegevoegd.", "user_flagged_post_in": "%1 rapporteerde een bericht in %2", "user_posted_to": "%1 heeft een reactie op het bericht gegeven aan %2", "user_posted_topic": "%1 heeft een nieuw onderwerp geplaatst: %2", - "user_mentioned_you_in": "%1 heeft u genoemd in %2", - "user_started_following_you": "%1 volgt u nu.", - "email-confirmed": "Email adres bevestigd", - "email-confirmed-message": "Bedankt voor het bevestigen van uw email adres. Uw account is nu volledig actief.", - "email-confirm-error-message": "Er was een probleem met het bevestigen van uw email adres. Misschien was de code niet goed of was door de tijd verstreken.", - "email-confirm-sent": "Bevestigings email verstuurd" + "user_mentioned_you_in": "Onze naam is genoemd door %1 in %2.", + "user_started_following_you": "%1 volgt ons nu.", + "email-confirmed": "E-mailadres bevestigd", + "email-confirmed-message": "Bedankt voor het bevestigen van het e-mailadres. Deze account is nu volledig geactiveerd.", + "email-confirm-error-message": "Er was een probleem met het bevestigen van dit e-mailadres. Misschien is de code niet goed ingevoerd of was de beschikbare tijd inmiddels verstreken.", + "email-confirm-sent": "Bevestigingmail verstuurd" } \ No newline at end of file diff --git a/public/language/nl/pages.json b/public/language/nl/pages.json index f9db18bd4c..d4ac82cc54 100644 --- a/public/language/nl/pages.json +++ b/public/language/nl/pages.json @@ -1,21 +1,21 @@ { "home": "Home", - "unread": "Ongelezen Onderwerpen", - "popular": "Populaire Onderwerpen", - "recent": "Recente Onderwerpen", - "users": "Geregistreerde Gebruikers", + "unread": "Ongelezen onderwerpen", + "popular": "Populaire onderwerpen", + "recent": "Recente onderwerpen", + "users": "Geregistreerde gebruikers", "notifications": "Notificaties", "tags": "Tags", - "tag": "Onderwerpen getagd onder \"%1\"", + "tag": "Onderwerpen geplaatst onder \"%1\"", "user.edit": "\"%1\" aanpassen", - "user.following": "Mensen %1 Volgt", - "user.followers": "Mensen die %1 Volgen", + "user.following": "Door %1 gevolgd", + "user.followers": "Die %1 volgen", "user.posts": "Berichten geplaatst door %1", - "user.topics": "Topics gecreëerd door %1", + "user.topics": "Onderwerpen begonnen door %1", "user.groups": "%1's groepen", - "user.favourites": "%1's Favoriete Berichten", + "user.favourites": "Favoriete berichten van %1", "user.settings": "Gebruikersinstellingen", - "user.watched": "Berichten die worden bekeken door %1", - "maintenance.text": "%1 is momenteel in onderhoud modus. Probeer later opnieuw", - "maintenance.messageIntro": "daarnaast heeft de administrator het volgende bericht achtergelaten:" + "user.watched": "Berichten die door %1 bekeken worden", + "maintenance.text": "%1 is momenteel in onderhoud. Excuses voor het ongemak en probeer het later nog eens", + "maintenance.messageIntro": "Daarnaast heeft de beheerder het volgende bericht achtergelaten:" } \ No newline at end of file diff --git a/public/language/nl/reset_password.json b/public/language/nl/reset_password.json index 87a167b975..9849338c56 100644 --- a/public/language/nl/reset_password.json +++ b/public/language/nl/reset_password.json @@ -1,17 +1,17 @@ { "reset_password": "Wachtwoord opnieuw instellen", - "update_password": "Wachtwoord Updaten", - "password_changed.title": "Wachtwoord Veranderd", - "password_changed.message": "

Wachtwoord is met succes gereset, log a.u.b. opnieuw in.", - "wrong_reset_code.title": "Incorrecte Reset Code", - "wrong_reset_code.message": "De ontvangen reset code is incorrect. Probeer het opnieuw, of vraag een nieuwe code aan.", - "new_password": "Nieuw Wachtwoord", - "repeat_password": "Bevestig Wachtwoord", - "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!", - "password_too_short": "Het ingegeven wachtwoord is te kort. Kiest u alstublieft een ander wachtwoord.", - "passwords_do_not_match": "De twee wachtwoorden die u heeft ingegeven komen niet overeen.", - "password_expired": "U wachtwoord is verlopen, kies een nieuw wachtwoord" + "update_password": "Wachtwoord bijwerken", + "password_changed.title": "Wachtwoord gewijzigd", + "password_changed.message": "

Wachtwoord met succes hersteld. Log nu eerst opnieuw in.", + "wrong_reset_code.title": "Onjuiste herstelcode", + "wrong_reset_code.message": "Opgegeven code voor wachtwoordherstel is niet juist. Probeer het opnieuw of vraag een andere code aan.", + "new_password": "Nieuw wachtwoord", + "repeat_password": "Bevestiging wachtwoord", + "enter_email": "Geef het e-mailadres op dat tijdens registratie gebruikt is, en we versturen je een bericht met vervolginstructies voor het ontgrendelen van de account.", + "enter_email_address": "Geef het e-mailadres op", + "password_reset_sent": "Het bericht met daarin een link en de vervolgstappen voor het wachtwoordherstel, is verzonden", + "invalid_email": "Onbekend e-mailadres!", + "password_too_short": "Het opgegeven wachtwoord bevat te weinig tekens. Kies een veiliger wachtwoord met meer tekens.", + "passwords_do_not_match": "De twee opgegeven wachtwoorden komen niet overeen`", + "password_expired": "Het huidige wachtwoord is verlopen en er dient een nieuwe gekozen te worden" } \ No newline at end of file diff --git a/public/language/nl/search.json b/public/language/nl/search.json index 91d52f12a2..7b558be954 100644 --- a/public/language/nl/search.json +++ b/public/language/nl/search.json @@ -1,20 +1,20 @@ { - "results_matching": "%1 resulta(a)ten was een match \"%2\", (%3 seconds)", - "no-matches": "Geen matches gevonden", - "advanced-search": "Geavanceerd Zoeken", + "results_matching": "%1 overeenkomstige resultaten \"%2\", (%3 seconds)", + "no-matches": "Geen overeenkomstige resultaten gevonden", + "advanced-search": "Geavanceerde zoekfunctie", "in": "in", "titles": "Titels", - "titles-posts": "Titels en Berichten", + "titles-posts": "Titels en berichten", "posted-by": "Geplaatst door", "in-categories": "In categorieën", - "search-child-categories": "Doorzoek sub categorieën ", + "search-child-categories": "Doorzoek subcategorieën ", "reply-count": "Aantal reacties", "at-least": "Minimaal", "at-most": "Maximaal", - "post-time": "Tijd van plaatsing", + "post-time": "Geplaatst op", "newer-than": "Nieuwer dan", "older-than": "Ouder dan", - "any-date": "Iedere datum", + "any-date": "Elke datum", "yesterday": "Gisteren", "one-week": "Eén week", "two-weeks": "Twee weken", @@ -22,12 +22,12 @@ "three-months": "Drie maanden", "six-months": "Zes maanden", "one-year": "Eén jaar", - "sort-by": "Gesorteerd op", + "sort-by": "Sorteer op", "last-reply-time": "Laatste keer geantwoord", "topic-title": "Onderwerp", "number-of-replies": "Aantal antwoorden", - "number-of-views": "Aantal weergaven", - "topic-start-date": "Onderwerp aanmaakdatum", + "number-of-views": "Aantal keer bekeken", + "topic-start-date": "Onderwerp gestart op datum", "username": "Gebruikersnaam", "category": "Categorie", "descending": "In aflopende volgorde", diff --git a/public/language/nl/success.json b/public/language/nl/success.json index f8fd81d695..be632b25e4 100644 --- a/public/language/nl/success.json +++ b/public/language/nl/success.json @@ -1,6 +1,6 @@ { - "success": "Success", - "topic-post": "U heeft succesvol een bericht geplaatst", - "authentication-successful": "Het inloggen is succesvol", + "success": "Geslaagd", + "topic-post": "Bericht succesvol geplaatst", + "authentication-successful": "Aanmelden geslaagd", "settings-saved": "Instellingen opgeslagen!" } \ No newline at end of file diff --git a/public/language/nl/tags.json b/public/language/nl/tags.json index ec028f3248..f4665e87c3 100644 --- a/public/language/nl/tags.json +++ b/public/language/nl/tags.json @@ -1,7 +1,7 @@ { "no_tag_topics": "Er zijn geen onderwerpen met deze tag", "tags": "Tags", - "enter_tags_here": "Voegt u hier tags toe, tussen de %1 en %2 karakters per stuk.", - "enter_tags_here_short": "Voer uw tags in...", - "no_tags": "Er zijn nog geen tags te vinden" + "enter_tags_here": "Voeg hier tags toe, tussen de %1 en %2 tekens per stuk.", + "enter_tags_here_short": "Voer tags in...", + "no_tags": "Er zijn nog geen tags geplaatst" } \ No newline at end of file diff --git a/public/language/nl/topic.json b/public/language/nl/topic.json index 35679bccfd..4b8c7ca531 100644 --- a/public/language/nl/topic.json +++ b/public/language/nl/topic.json @@ -7,93 +7,93 @@ "post_is_deleted": "Dit bericht is verwijderd!", "profile": "Profiel", "posted_by": "Geplaatst door %1", - "posted_by_guest": "Geplaatst door Gast", + "posted_by_guest": "Geplaatst door gast", "chat": "Chat", - "notify_me": "Krijg notificaties van nieuwe reacties op dit onderwerp", + "notify_me": "Krijg een melding wanneer nieuwe reacties volgen", "quote": "Citeren", "reply": "Reageren", - "guest-login-reply": "Log in om een reactie te plaatsen", + "guest-login-reply": "Aanmelden om te reageren", "edit": "Aanpassen", "delete": "Verwijderen", - "purge": "weggooien", + "purge": "Opschonen", "restore": "Herstellen", "move": "Verplaatsen", "fork": "Afsplitsen", "link": "Link", "share": "Delen", - "tools": "Gereedschap", + "tools": "Extra", "flag": "Markeren", - "locked": "gesloten", - "bookmark_instructions": "Klik hier om terug te gaan naar je laatste positie of sluiten om te annuleren.", - "flag_title": "Dit bericht markeren voor moderatie", - "flag_confirm": "Weet u het zeker dat u dit bericht wilt rapporteren?", - "flag_success": "Dit bericht is gerapporteerd aan de admins", - "deleted_message": "Dit onderwerp is verwijderd. Alleen gebruikers met onderwerp management privileges kunnen dit onderwerp zien.", - "following_topic.message": "Je zult nu notificaties ontvangen wanneer iemand reageert op dit onderwerp.", - "not_following_topic.message": "Je zult niet langer notificaties ontvangen van dit onderwerp.", - "login_to_subscribe": "Log a.u.b. in om op dit onderwerp te abonneren.", - "markAsUnreadForAll.success": "Onderwerp gemarkeerd als gelezen voor iedereen.", + "locked": "Gesloten", + "bookmark_instructions": "Klik hier om naar de vorige positie terug te keren of sluit af om te verwerpen.", + "flag_title": "Bericht aan beheerders melden", + "flag_confirm": "Is het echt de bedoeling dit bericht aan beheerders te rapporteren?", + "flag_success": "Het bericht is gerapporteerd aan beheer.", + "deleted_message": "Dit onderwerp is verwijderd. Alleen gebruikers met beheerrechten op onderwerpniveau kunnen dit inzien.", + "following_topic.message": "Vanaf nu worden meldingen ontvangen zodra iemand een reactie op dit onderwerp geeft.", + "not_following_topic.message": "Er worden niet langer meldingen ontvangen over dit onderwerp.", + "login_to_subscribe": "Aanmelden om op dit onderwerp te abonneren", + "markAsUnreadForAll.success": "Onderwerp is voor iedereen als 'gelezen' gemarkeerd.", "watch": "Volgen", "unwatch": "Niet volgen", - "watch.title": "Krijg notificaties van nieuwe reacties op dit onderwerp", - "unwatch.title": "Stop met dit onderwerp te volgen", - "share_this_post": "Deel dit Bericht", - "thread_tools.title": "Onderwerp Gereedschap", - "thread_tools.markAsUnreadForAll": "Ongelezen Markeren", - "thread_tools.pin": "Onderwerp Vastmaken", - "thread_tools.unpin": "Onderwerp Losmaken", - "thread_tools.lock": "Onderwerp Sluiten", - "thread_tools.unlock": "Onderwerp Openen", - "thread_tools.move": "Onderwerp Verplaatsen", + "watch.title": "Krijg meldingen van nieuwe reacties op dit onderwerp", + "unwatch.title": "Dit onderwerp niet langer volgen", + "share_this_post": "Deel dit bericht", + "thread_tools.title": "Acties", + "thread_tools.markAsUnreadForAll": "Ongelezen markeren", + "thread_tools.pin": "Onderwerp vastpinnen", + "thread_tools.unpin": "Onderwerp losmaken", + "thread_tools.lock": "Onderwerp op slot zetten", + "thread_tools.unlock": "Onderwerp openen", + "thread_tools.move": "Onderwerp verplaatsen", "thread_tools.move_all": "Verplaats alles", - "thread_tools.fork": "Onderwerp Afsplitsen", - "thread_tools.delete": "Onderwerp Verwijderen", - "thread_tools.delete_confirm": "Weet u het zeker dat u dit onderwerp wilt verwijderen?", - "thread_tools.restore": "Onderwerp Herstellen", - "thread_tools.restore_confirm": "Weet u het zeker dat u het onderwerp wilt herstellen?", - "thread_tools.purge": "Wis Onderwerp ", - "thread_tools.purge_confirm": "Weet u het zeker dat u dit onderwerp wilt weggooien?", - "topic_move_success": "Deze onderwerp is succesvol verplaatst naar %1", - "post_delete_confirm": "Weet u het zeker dat u dit bericht wilt verwijderen?", - "post_restore_confirm": "Weet u het zeker dat u dit bericht wilt herstellen?", - "post_purge_confirm": "Weet u het zeker dat u dit bericht wilt weggooien?", - "load_categories": "Categorieën Laden", - "disabled_categories_note": "Uitgeschakelde Categorieën zijn grijs", + "thread_tools.fork": "Onderwerp afsplitsen", + "thread_tools.delete": "Onderwerp verwijderen", + "thread_tools.delete_confirm": "Is het echt de bedoeling dit onderwerp te verwijderen?", + "thread_tools.restore": "Onderwerp erstellen", + "thread_tools.restore_confirm": "Zeker weten dit onderwerp te herstellen?", + "thread_tools.purge": "Wis onderwerp ", + "thread_tools.purge_confirm": "Is het echt de bedoeling dit onderwerp definitief te wissen?", + "topic_move_success": "Verplaatsen van onderwerp naar %1 succesvol", + "post_delete_confirm": "Is het absoluut de bedoeling dit bericht te verwijderen?", + "post_restore_confirm": "Is het de bedoeling dit bericht te herstellen?", + "post_purge_confirm": "Is het absoluut zeker dat dit bericht volledig verwijderd kan worden?", + "load_categories": "Categorieën laden", + "disabled_categories_note": "Uitgeschakelde categorieën zijn grijs", "confirm_move": "Verplaatsen", "confirm_fork": "Splits", "favourite": "Favoriet", "favourites": "Favorieten", - "favourites.has_no_favourites": "Je hebt geen favorieten, sla een aantal berichten op als favoriet om ze hier te zien!", - "loading_more_posts": "Meer Berichten Laden", - "move_topic": "Onderwerp Verplaatsen", + "favourites.has_no_favourites": "Er zijn momenteel nog geen favorieten, markeer eerst enkele berichten om ze hier te kunnen zien.", + "loading_more_posts": "Meer berichten...", + "move_topic": "Onderwerp verplaatsen", "move_topics": "Verplaats onderwerpen", - "move_post": "Bericht Verplaatsen", + "move_post": "Bericht verplaatsen", "post_moved": "Bericht verplaatst!", - "fork_topic": "Afgesplitste Onderwerp ", - "topic_will_be_moved_to": "Dit onderwerp zal verplaatst worden naar de categorie", - "fork_topic_instruction": "Klik op de berichten die je wilt forken", + "fork_topic": "Afgesplitst onderwerp ", + "topic_will_be_moved_to": "Dit onderwerp zal naar de categorie verplaatst worden", + "fork_topic_instruction": "Klik op de berichten die afgesplitst moeten worden", "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...", + "fork_success": "Onderwerp is succesvol afgesplitst. Klik hier om het nieuwe onderwerp te zien.", + "composer.title_placeholder": "Voer hier de titel van het onderwerp in...", "composer.handle_placeholder": "Naam", "composer.discard": "Annuleren", - "composer.submit": "Opslaan", - "composer.replying_to": "Reageren op %1", - "composer.new_topic": "Nieuw Onderwerp", + "composer.submit": "Verzenden", + "composer.replying_to": "Reactie op %1", + "composer.new_topic": "Nieuw onderwerp", "composer.uploading": "uploaden...", - "composer.thumb_url_label": "Plak een onderwerp thumbnail URL", - "composer.thumb_title": "Voeg een thumbnail toe aan dit onderwerp", + "composer.thumb_url_label": "Plak een URL naar een miniatuurweergave voor dit onderwerp", + "composer.thumb_title": "Voeg een miniatuurweergave toe aan dit onderwerp", "composer.thumb_url_placeholder": "http://example.com/thumb.png", "composer.thumb_file_label": "Of upload een bestand", - "composer.thumb_remove": "Velden leegmaken", - "composer.drag_and_drop_images": "Sleep en Zet Afbeeldingen Hier", + "composer.thumb_remove": "Velden legen", + "composer.drag_and_drop_images": "Sleep en zet afbeeldingen hier", "more_users_and_guests": "%1 of meerdere gebruiker(s) en %2 gast(en)", "more_users": "%1 meer gebruiker(s)", "more_guests": "%1 of meerdere gast(en)", "users_and_others": "%1 en %2 anderen", - "sort_by": "gesorteerd op", - "oldest_to_newest": "Oud naar Nieuw", - "newest_to_oldest": "Nieuw naar Oud", - "most_votes": "Meeste stemmen", - "most_posts": "Meeste berichten" + "sort_by": "Indeling", + "oldest_to_newest": "Oudste berichten bovenaan", + "newest_to_oldest": "Meest recente berichten bovenaan", + "most_votes": "Meeste aantal stemmen", + "most_posts": "Meeste aantal reacties" } \ No newline at end of file diff --git a/public/language/nl/unread.json b/public/language/nl/unread.json index 35938c3a72..3149f079ad 100644 --- a/public/language/nl/unread.json +++ b/public/language/nl/unread.json @@ -1,8 +1,8 @@ { "title": "Ongelezen", "no_unread_topics": "Er zijn geen ongelezen onderwerpen", - "load_more": "Meer Laden", - "mark_as_read": "Markeer als Gelezen", + "load_more": "Meer laden...", + "mark_as_read": "Markeer als gelezen", "selected": "Geselecteerd", "all": "Alles", "topics_marked_as_read.success": "Onderwerp gemarkeerd als gelezen!" diff --git a/public/language/nl/user.json b/public/language/nl/user.json index d30ff024a9..723bc04f72 100644 --- a/public/language/nl/user.json +++ b/public/language/nl/user.json @@ -4,18 +4,18 @@ "username": "Gebruikersnaam", "joindate": "Datum van registratie", "postcount": "Aantal geplaatste berichten", - "email": "Email", - "confirm_email": "Bevestig uw email adres", - "delete_account": "Account Verwijderen", - "delete_account_confirm": "Weet u het zeker dat je dit account wilt verwijderen?
Deze actie kan niet ongedaan worden gemaakt en uw kan niet meer uw data herstellen

Typ hier uw gebruikersnaam om te bevestigen dat u dit account wilt verwijderen.", - "fullname": "Volledige Naam", + "email": "E-mail", + "confirm_email": "Bevestig e-mail", + "delete_account": "Account verwijderen", + "delete_account_confirm": "Controleer of dat het zeker is dat deze account verwijderd moet worden.
Deze actie kan niet ongedaan gemaakt worden en herstellen van gebruiker- of profielgegevens is niet mogelijk

Typ hier de gebruikersnaam als extra controle om te bevestigen dat deze account verwijderd moet worden.", + "fullname": "Volledige naam", "website": "Website", "location": "Locatie", "age": "Leeftijd", "joined": "Geregistreerd", - "lastonline": "Laatst Online", + "lastonline": "Laatste keer online gezien", "profile": "Profiel", - "profile_views": "Profiel weergaven", + "profile_views": "Bekeken", "reputation": "Reputatie", "favourites": "Favorieten", "watched": "Bekeken", @@ -28,56 +28,56 @@ "follow": "Volgen", "unfollow": "Ontvolgen", "more": "Meer", - "profile_update_success": "Uw profiel is succesvol geüpdatet", - "change_picture": "Afbeelding Aanpassen", - "edit": "Aanpassen", - "uploaded_picture": "Afbeelding Uploaden", - "upload_new_picture": "Nieuwe Afbeelding Uploaden", - "upload_new_picture_from_url": "Nieuwe Afbeelding Uploaden vanaf een URL", - "current_password": "Huidige Wachtwoord", - "change_password": "Wachtwoord Aanpassen", + "profile_update_success": "Het gebruikersprofiel is met succes gewijzigd", + "change_picture": "Bewerk afbeelding", + "edit": "Bewerken", + "uploaded_picture": "Opgehaalde afbeelding", + "upload_new_picture": "Nieuwe afbeelding opsturen", + "upload_new_picture_from_url": "Nieuwe afbeelding vanaf een URL toevoegen", + "current_password": "Huidige wachtwoord", + "change_password": "Wijzig wachtwoord", "change_password_error": "Ongeldig wachtwoord!", - "change_password_error_wrong_current": "Uw huidige wachtwoord is niet correct!", - "change_password_error_length": "Wachtwoord is te kort!", - "change_password_error_match": "Het wachtwoord wat uw eerder heeft opgegeven moet matchen!", - "change_password_error_privileges": "Uw heeft niet de bevoegdheden om dit wachtwoord te veranderen", - "change_password_success": "Uw wachtwoord is geüpdatet!", - "confirm_password": "Bevestig Wachtwoord", + "change_password_error_wrong_current": "Het opgegeven huidige wachtwoord is onjuist!", + "change_password_error_length": "Wachtwoord bevat te weinig tekens!", + "change_password_error_match": "Het eerder opgegeven wachtwoord komt niet overeen!", + "change_password_error_privileges": "Niet geautoriseerd om dit wachtwoord te mogen wijzigen.", + "change_password_success": "Het wachtwoord is gewijzigd!", + "confirm_password": "Bevestig wachtwoord", "password": "Wachtwoord", - "username_taken_workaround": "Gebruikersnaam dat u wilde is al in gebruik, dus hebben we het een beetje aangepast naar %1", - "upload_picture": "Afbeelding Uploaden", + "username_taken_workaround": "Helaas, de gewenste gebruikersnaam is al door iemand in gebruik genomen dus vandaar een kleine aanpassing naar %1 doorgevoerd", + "upload_picture": "Upload afbeelding", "upload_a_picture": "Upload een afbeelding", - "image_spec": "Je mag alleen PNG, JPG, of GIF bestanden uploaden.", + "image_spec": "Alleen afbeeldingsbestanden van het type PNG, JPG/JPEG, of GIF worden ondersteund.", "settings": "Instellingen", - "show_email": "Laat Mijn Email Zien", + "show_email": "Inschakelen weergave van e-mailadres op profielpagina", "show_fullname": "Laat mijn volledige naam zien", - "restrict_chats": "Sta alleen chatsessies toe van gebruikers die ik volg", - "digest_label": "Abonneer op de overzicht", - "digest_description": "Abonneer op de email updates van dit forum ( nieuwe notificaties en onderwerpen) volgens een tijdsschema", + "restrict_chats": "Sta alleen chatsessies toe van gebruikers die ik zelf volg", + "digest_label": "Abonneer op een samenvatting", + "digest_description": "Abonneer op periodieke e-mail updates van onderwerpen in dit forum", "digest_off": "Uit", "digest_daily": "Dagelijks", - "digest_weekly": "Weekelijks", + "digest_weekly": "Wekelijks", "digest_monthly": "Maandelijks", - "send_chat_notifications": "Verstuur mij een email als iemand een chatbericht stuurt terwijl ik niet online ben", - "send_post_notifications": "Stuur een email als er een reactie wordt geplaatst in een topic waarop ik geabonneerd ben", - "settings-require-reload": "Sommige veranderingen vereisen het om de pagina te herladen. Klik hier om te herladen.", + "send_chat_notifications": "Meld het mij per e-mail als iemand een chatbericht verstuurt wanneer ik niet online ben", + "send_post_notifications": "Meld het mij per e-mail wanneer er reacties volgen op onderwerpen waarop geabonneerd is", + "settings-require-reload": "Sommige veranderingen vereisen het herladen van de pagina: klik hier om de pagina te herladen.", "has_no_follower": "Deze gebruiker heeft geen volgers :(", "follows_no_one": "Deze gebruiker volgt niemand :(", "has_no_posts": "Deze gebruiker heeft nog geen berichten geplaatst", "has_no_topics": "Deze gebruiker heeft nog geen berichten geplaatst", "has_no_watched_topics": "Deze gebruiker heeft nog geen berichten bekeken", - "email_hidden": "Email Verborgen", + "email_hidden": "E-mail niet beschikbaar", "hidden": "verborgen", "paginate_description": "Blader door onderwerpen en berichten in plaats van oneindig scrollen.", - "topics_per_page": "Onderwerpen per Pagina", - "posts_per_page": "Berichten per Pagina", - "notification_sounds": "Speel een geluid af wanneer ik een notificatie ontvang.", - "browsing": "Zoek Instellingen", - "open_links_in_new_tab": "Open de uitgaande links in een nieuw tabblad", - "enable_topic_searching": "Zet zoeken in het onderwerp aan", - "topic_search_help": "Als het is ingeschakeld, dan zal het standaard zoeken overschrijven en zal je vanaf nu het gehele onderwerp kunnen doorzoeken ipv wat je standaard ziet.", - "follow_topics_you_reply_to": "Volg de onderwerpen waarop u gereageerd heeft.", - "follow_topics_you_create": "Volg de onderwerpen die u gecreëerd heeft.", - "grouptitle": "Selecteer de groepstitel die u wilt weergeven ", + "topics_per_page": "Onderwerpen per pagina", + "posts_per_page": "Berichten per pagina", + "notification_sounds": "Speel een geluid af wanneer ik een notificatie ontvang", + "browsing": "Instellingen voor bladeren", + "open_links_in_new_tab": "Open uitgaande links naar een externe site in een nieuw tabblad", + "enable_topic_searching": "Inschakelen mogelijkheid op onderwerp te kunnen zoeken", + "topic_search_help": "Wanneer ingeschakeld zal de standaard zoekfunctie, met een aangepaste methode voor onderwerpen, overschreven worden", + "follow_topics_you_reply_to": "Volg de onderwerpen waarop ik gereageerd heb", + "follow_topics_you_create": "Volg de onderwerpen waarvan ik de oorspronkelijke auteur ben", + "grouptitle": "Selecteer de groepstitel voor weergave", "no-group-title": "Geen groepstitel" } \ No newline at end of file diff --git a/public/language/nl/users.json b/public/language/nl/users.json index 93e723d7b1..32692839eb 100644 --- a/public/language/nl/users.json +++ b/public/language/nl/users.json @@ -1,10 +1,10 @@ { - "latest_users": "Nieuwste Gebruikers", - "top_posters": "Meest Actief", - "most_reputation": "Meeste Reputatie", + "latest_users": "Meest recente gebruikers", + "top_posters": "Meest actieve leden", + "most_reputation": "Meeste reputatie", "search": "Zoeken", "enter_username": "Vul een gebruikersnaam in om te zoeken", - "load_more": "Meer Laden", + "load_more": "Meer laden...", "users-found-search-took": "%1 gebruiker(s) gevonden! Zoekactie duurde %2 seconden.", "filter-by": "Filter op", "online-only": "Online ", diff --git a/public/language/ru/error.json b/public/language/ru/error.json index 99d893e336..6e038fcdc8 100644 --- a/public/language/ru/error.json +++ b/public/language/ru/error.json @@ -21,11 +21,11 @@ "email-not-confirmed-chat": "Вы не можете оставлять сообщения, пока Ваш email не подтверждён. Нажмите на это сообщение чтобы получить письмо повторно.", "no-email-to-confirm": "Этот форум требует подтверждения по E-mail. Нажмите здесь для ввода E-mail.", "email-confirm-failed": "Мы не можем подтвердить Ваш E-mail, попробуйте позже.", - "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", + "confirm-email-already-sent": "Сообщение для подтверждения уже выслано на E-mail. Повторная отправка возможна через %1 мин.", "username-too-short": "Слишком короткое имя пользователя", "username-too-long": "Имя пользователя слишком длинное", "user-banned": "Пользователь заблокирован", - "user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post", + "user-too-new": "Вы можете написать свой первый пост через %1 сек.", "no-category": "Категория не существует", "no-topic": "Тема не существует", "no-post": "Сообщение не существует", @@ -36,40 +36,40 @@ "no-emailers-configured": "Не подключен ни один плагин для отправки почты, поэтому тестовый email не может быть отправлен", "category-disabled": "Категория отключена", "topic-locked": "Тема закрыта", - "post-edit-duration-expired": "You are only allowed to edit posts for %1 second(s) after posting", + "post-edit-duration-expired": "Сообщения можно редактировать только в течение %1 секунд(ы) после опубликования", "still-uploading": "Пожалуйста, подождите завершения загрузки.", - "content-too-short": "Please enter a longer post. Posts should contain at least %1 character(s).", - "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 character(s).", - "title-too-short": "Please enter a longer title. Titles should contain at least %1 character(s).", - "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 character(s).", - "too-many-posts": "You can only post once every %1 second(s) - please wait before posting again", - "too-many-posts-newbie": "As a new user, you can only post once every %1 second(s) 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 character(s)", - "tag-too-long": "Please enter a shorter tag. Tags can't be longer than %1 character(s)", - "file-too-big": "Maximum allowed file size is %1 kB - please upload a smaller file", + "content-too-short": "Слишком короткий пост. Минимум символов: %1.", + "content-too-long": "Слишком длинный пост. Максимум символов: %1.", + "title-too-short": "Слишком короткий заголовок. Минимум символов: %1.", + "title-too-long": "Слишком длинный заголовок. Максимум символов: %1.", + "too-many-posts": "Вы можете делать пост только один раз в %1 сек.", + "too-many-posts-newbie": "Вы новый пользователь, поэтому можете делать пост раз в %1 сек., пока не заработаете %2 п. репутации.", + "tag-too-short": "Слишком короткий тэг. Минимум символов: %1.", + "tag-too-long": "Слишком длинный тэг. Максимум символов: %1.", + "file-too-big": "Слишком большой файл. Максимальный размер: %1 Кбайт.", "cant-vote-self-post": "Вы не можете проголосовать за Ваш пост", "already-favourited": "Вы уже добавили этот пост в избранное", "already-unfavourited": "Вы уже удалили этот пост из избранного", "cant-ban-other-admins": "Вы не можете забанить других администраторов!", "invalid-image-type": "Неверный формат изображения. Поддерживаемые форматы: %1", "invalid-image-extension": "Недопустимое расширение файла", - "invalid-file-type": "Неверный формат фаила. Поддерживаемые форматы : %1", + "invalid-file-type": "Неверный формат файла. Поддерживаемые форматы: %1", "group-name-too-short": "Название группы слишком короткое", "group-already-exists": "Группа уже существует", "group-name-change-not-allowed": "Изменение названия группы запрещено", "group-already-member": "Вы уже состоите в этой группе", "group-needs-owner": "У группы должен быть как минимум один владелец", "post-already-deleted": "Этот пост уже удалён", - "post-already-restored": "Этот пост уже восстановлен.", + "post-already-restored": "Этот пост уже восстановлен", "topic-already-deleted": "Тема уже удалена", "topic-already-restored": "Тема уже восстановлена", "cant-purge-main-post": "Вы не можете удалить главное сообщение темы, вместо этого, пожалуйста, удалите топик", "topic-thumbnails-are-disabled": "Иконки для темы запрещены", - "invalid-file": "Файл испорчен", + "invalid-file": "Неверный файл", "uploads-are-disabled": "Загрузка запрещена", - "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "signature-too-long": "Максимальная длина подписи: %1 симв.", "cant-chat-with-yourself": "Вы не можете общаться с самим собой", - "chat-restricted": "Пользователь ограничил прием сообщений. Он должен подписаться на Вас, чтобы Вы могли вести переписку с ним.", + "chat-restricted": "Пользователь ограничил прием сообщений. Он должен быть подписан на Вас, чтобы Вы могли вести переписку с ним.", "too-many-messages": "Вы отправили слишком много сообщений, подождите немного.", "reputation-system-disabled": "Система репутации отключена.", "downvoting-disabled": "Понижение оценки отключено", diff --git a/public/language/zh_TW/category.json b/public/language/zh_TW/category.json index b018f21e89..0dff52556a 100644 --- a/public/language/zh_TW/category.json +++ b/public/language/zh_TW/category.json @@ -1,12 +1,12 @@ { "new_topic_button": "新主題", - "guest-login-post": "Log in to post", - "no_topics": "這個版面還沒有任何內容。
趕緊來發文章吧!", + "guest-login-post": "登錄後才能發表", + "no_topics": "這個類別還沒有任何主題。
為何不來發點東西呢?", "browsing": "正在瀏覽", "no_replies": "還沒有回覆", "share_this_category": "分享這類別", - "watch": "Watch", + "watch": "觀看", "ignore": "忽略", - "watch.message": "You are now watching updates from this category", - "ignore.message": "You are now ignoring updates from this category" + "watch.message": "您正觀看著此類別的更新", + "ignore.message": "您已忽略此類別的更新" } \ No newline at end of file diff --git a/public/language/zh_TW/error.json b/public/language/zh_TW/error.json index 5fa681cee7..5c3e212270 100644 --- a/public/language/zh_TW/error.json +++ b/public/language/zh_TW/error.json @@ -22,10 +22,10 @@ "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", - "username-too-short": "用戶名太短", - "username-too-long": "用戶名太長", + "username-too-short": "使用者名稱太簡短", + "username-too-long": "使用者名稱太長", "user-banned": "該使用者已被停用", - "user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post", + "user-too-new": "抱歉,發表您第一篇文章須要等待 %1 秒", "no-category": "類別並不存在", "no-topic": "主題並不存在", "no-post": "文章並不存在", @@ -33,7 +33,7 @@ "no-user": "使用者並不存在", "no-teaser": "Teaser 並不存在", "no-privileges": "您似乎沒有執行這個行為的權限!", - "no-emailers-configured": "未加載電郵插件,所以無法發送測試郵件", + "no-emailers-configured": "未載入電子郵件套件,所以無法寄送測試郵件", "category-disabled": "該類別已被關閉", "topic-locked": "該主題已被鎖定", "post-edit-duration-expired": "You are only allowed to edit posts for %1 second(s) after posting", @@ -50,10 +50,10 @@ "cant-vote-self-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-file-type": "Invalid file type. Allowed types are: %1", + "cant-ban-other-admins": "您無法禁止其他的管理員!", + "invalid-image-type": "無效的圖像類型。允許的類型:%1", + "invalid-image-extension": "無效的圖像擴充元件", + "invalid-file-type": "無效的檔案類型。允許的類型:%1", "group-name-too-short": "群組名稱太短了", "group-already-exists": "群組名稱已存在", "group-name-change-not-allowed": "變更群組名稱不被允許", @@ -78,6 +78,6 @@ "reload-failed": "NodeBB重載\"%1\"時遇到了問題。 NodeBB將繼續提供現有的客戶端資源,但請你撤消重載前的動作。", "registration-error": "註冊錯誤", "parse-error": "Something went wrong while parsing server response", - "wrong-login-type-email": "Please use your email to login", - "wrong-login-type-username": "Please use your username to login" + "wrong-login-type-email": "請使用您的電子郵件進行登錄", + "wrong-login-type-username": "請使用您的使用者名稱進行登錄" } \ No newline at end of file diff --git a/public/language/zh_TW/global.json b/public/language/zh_TW/global.json index f0a81aed7a..6014f8c4ac 100644 --- a/public/language/zh_TW/global.json +++ b/public/language/zh_TW/global.json @@ -1,6 +1,6 @@ { "home": "首頁", - "search": "搜索", + "search": "搜尋", "buttons.close": "關閉", "403.title": "禁止存取", "403.message": "你沒有該頁面的存取權限", @@ -30,7 +30,7 @@ "header.groups": "群組", "header.chats": "聊天", "header.notifications": "通知", - "header.search": "搜索", + "header.search": "搜尋", "header.profile": "設置", "notifications.loading": "消息載入中", "chats.loading": "聊天載入中···", diff --git a/public/language/zh_TW/groups.json b/public/language/zh_TW/groups.json index caaab4b118..d4ac57f556 100644 --- a/public/language/zh_TW/groups.json +++ b/public/language/zh_TW/groups.json @@ -1,36 +1,36 @@ { "groups": "群組", "view_group": "查看群組", - "owner": "Group Owner", - "new_group": "Create New Group", - "no_groups_found": "There are no groups to see", - "pending.accept": "Accept", - "pending.reject": "Reject", - "cover-instructions": "Drag and Drop a photo, drag to position, and hit Save", - "cover-change": "Change", - "cover-save": "Save", - "cover-saving": "Saving", + "owner": "群組擁有者", + "new_group": "建立新群組", + "no_groups_found": "這裡看不到任何群組", + "pending.accept": "接受", + "pending.reject": "拒絕", + "cover-instructions": "拖拉一本相簿,並拖到此位置,以及點擊 儲存", + "cover-change": "變更", + "cover-save": "儲存", + "cover-saving": "儲存中", "details.title": "群組詳細信息", "details.members": "成員列表", - "details.pending": "Pending Members", + "details.pending": "待審成員", "details.has_no_posts": "這個群組的成員還未發出任何帖子。", - "details.latest_posts": "最新帖子", - "details.private": "Private", - "details.grant": "Grant/Rescind Ownership", - "details.kick": "Kick", - "details.owner_options": "Group Administration", - "details.group_name": "Group Name", - "details.member_count": "Member Count", - "details.creation_date": "Creation Date", - "details.description": "Description", - "details.badge_preview": "Badge Preview", - "details.change_icon": "Change Icon", - "details.change_colour": "Change Colour", - "details.badge_text": "Badge Text", - "details.userTitleEnabled": "Show Badge", + "details.latest_posts": "最新文章", + "details.private": "私人", + "details.grant": "准許/撤銷 所有權", + "details.kick": "剔除", + "details.owner_options": "群組管理員", + "details.group_name": "群組名稱", + "details.member_count": "成員數", + "details.creation_date": "建立日期", + "details.description": "簡介", + "details.badge_preview": "徽章預覽", + "details.change_icon": "變更圖標", + "details.change_colour": "變更顏色", + "details.badge_text": "徽章字串", + "details.userTitleEnabled": "顯示徽章", "details.private_help": "If enabled, joining of groups requires approval from a group owner", - "details.hidden": "Hidden", + "details.hidden": "隱藏", "details.hidden_help": "If enabled, this group will not be found in the groups listing, and users will have to be invited manually", - "event.updated": "Group details have been updated", - "event.deleted": "The group \"%1\" has been deleted" + "event.updated": "群組詳細訊息已被更新", + "event.deleted": "此 \"%1\" 群組已被刪除了" } \ No newline at end of file diff --git a/public/language/zh_TW/login.json b/public/language/zh_TW/login.json index f93286b21a..4ffc8773e6 100644 --- a/public/language/zh_TW/login.json +++ b/public/language/zh_TW/login.json @@ -1,7 +1,7 @@ { - "username-email": "Username / Email", - "username": "Username", - "email": "Email", + "username-email": "用戶名稱 / 電子郵件", + "username": "用戶名稱", + "email": "電子郵件", "remember_me": "記住我?", "forgot_password": "忘記密碼?", "alternative_logins": "其他登錄方式", diff --git a/public/language/zh_TW/pages.json b/public/language/zh_TW/pages.json index 43825b4004..d004a0f742 100644 --- a/public/language/zh_TW/pages.json +++ b/public/language/zh_TW/pages.json @@ -5,7 +5,7 @@ "recent": "近期的主題", "users": "已註冊的使用者", "notifications": "新訊息通知", - "tags": "Tags", + "tags": "標籤", "tag": "Topics tagged under \"%1\"", "user.edit": "編輯中 \"%1\"", "user.following": "People %1 Follows", @@ -15,7 +15,7 @@ "user.groups": "%1 的群組", "user.favourites": "%1's 最喜愛的文章", "user.settings": "使用者設定", - "user.watched": "Topics watched by %1", - "maintenance.text": "%1目前正在進行維修。請稍後再來。", - "maintenance.messageIntro": "此外,管理員有以下信息:" + "user.watched": "主題由 %1 所觀看", + "maintenance.text": "目前 %1 正在進行維修。請稍後再來。", + "maintenance.messageIntro": "此外,管理員有以下訊息:" } \ No newline at end of file diff --git a/public/language/zh_TW/recent.json b/public/language/zh_TW/recent.json index 476bc25844..cf46a366d3 100644 --- a/public/language/zh_TW/recent.json +++ b/public/language/zh_TW/recent.json @@ -1,12 +1,12 @@ { "title": "最近", - "day": "今日", - "week": "本周", - "month": "本月", - "year": "全年", + "day": "日", + "week": "周", + "month": "月", + "year": "年", "alltime": "所有時間", - "no_recent_topics": "最近沒新主題.", - "no_popular_topics": "There are no popular topics.", + "no_recent_topics": "最近沒有新的主題。", + "no_popular_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.", @@ -15,5 +15,5 @@ "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." + "click-here-to-reload": "點擊這裡進行重整。" } \ No newline at end of file diff --git a/public/language/zh_TW/reset_password.json b/public/language/zh_TW/reset_password.json index af7cbce277..5c2964579c 100644 --- a/public/language/zh_TW/reset_password.json +++ b/public/language/zh_TW/reset_password.json @@ -7,10 +7,10 @@ "wrong_reset_code.message": "您輸入的驗証碼有誤,請重新輸入,或申請新的驗証碼。", "new_password": "輸入新的密碼", "repeat_password": "再次確認新密碼", - "enter_email": "請輸入您的Email地址,我們會發送郵件告訴您如何重設密碼。", - "enter_email_address": "輸入郵箱地址", + "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.", "password_expired": "Your password has expired, please choose a new password" diff --git a/public/language/zh_TW/user.json b/public/language/zh_TW/user.json index a177bfb876..55163c4259 100644 --- a/public/language/zh_TW/user.json +++ b/public/language/zh_TW/user.json @@ -3,32 +3,32 @@ "offline": "下線", "username": "使用者名稱", "joindate": "加入時間", - "postcount": "Post數量", - "email": "Email", + "postcount": "文章數量", + "email": "電子郵件", "confirm_email": "確認電郵", "delete_account": "刪除帳戶", - "delete_account_confirm": "你確定要刪除自己的帳戶?
此操作不能復原,您將無法恢復任何數據的

輸入您的用戶名,以確認您希望刪除這個帳戶。", - "fullname": "姓名", + "delete_account_confirm": "你確定要刪除自己的帳戶?
此操作不能復原,您將無法恢復任何數據

輸入您的使用者名稱,以確認您希望刪除這個帳戶。", + "fullname": "全名", "website": "網站", "location": "地址", "age": "年齡", "joined": "加入時間", - "lastonline": "最后在線", + "lastonline": "最後上線", "profile": "個人資料", "profile_views": "資料被查看", - "reputation": "聲望", + "reputation": "聲譽", "favourites": "我的最愛", - "watched": "Watched", + "watched": "觀看者", "followers": "跟隨者", "following": "正在關注", "signature": "簽名", "gravatar": "Gravatar頭像", "birthday": "生日", "chat": "聊天", - "follow": "關注", - "unfollow": "取消關注", - "more": "More", - "profile_update_success": "您的個人資料已更新成功!", + "follow": "跟隨", + "unfollow": "取消跟隨", + "more": "更多", + "profile_update_success": "您的個人資料已更新成功!", "change_picture": "改變頭像", "edit": "編輯", "uploaded_picture": "已有頭像", @@ -79,5 +79,5 @@ "follow_topics_you_reply_to": "Follow topics that you reply to", "follow_topics_you_create": "Follow topics you create", "grouptitle": "Select the group title you would like to display", - "no-group-title": "No group title" + "no-group-title": "無此群組標題" } \ No newline at end of file diff --git a/public/language/zh_TW/users.json b/public/language/zh_TW/users.json index b3c22fb165..34f7db93c9 100644 --- a/public/language/zh_TW/users.json +++ b/public/language/zh_TW/users.json @@ -5,8 +5,8 @@ "search": "搜尋", "enter_username": "輸入想找的使用者帳號", "load_more": "載入更多", - "users-found-search-took": "%1 user(s) found! Search took %2 seconds.", + "users-found-search-took": "發現 %1 用戶!搜尋只用 %2 秒。", "filter-by": "Filter By", - "online-only": "Online only", - "picture-only": "Picture only" + "online-only": "線上僅有", + "picture-only": "圖片僅有" } \ No newline at end of file From 8bc5330e8916236baaab56e3bb18f33afb35521e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 18 May 2015 16:01:40 -0400 Subject: [PATCH 019/237] some minor cleanup in the async tree... --- src/favourites.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/favourites.js b/src/favourites.js index 58a945e211..549b308de3 100644 --- a/src/favourites.js +++ b/src/favourites.js @@ -306,20 +306,22 @@ var async = require('async'), function(count, next) { results.postData.reputation = count; posts.setPostField(pid, 'reputation', count, next); - }, - function(next) { - plugins.fireHook('action:post.' + type, { - pid: pid, - uid: uid, - }, next); - }, - function(next) { - next(null, { - post: results.postData, - isFavourited: isFavouriting - }); } - ], callback); + ], function(err) { + if (err) { + return callback(err); + } + + plugins.fireHook('action:post.' + type, { + pid: pid, + uid: uid, + }); + + callback(null, { + post: results.postData, + isFavourited: isFavouriting + }); + }); }); } From 8aac4bdfa10bfbc9684f02b8608d002bc58b32bc Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 19 May 2015 00:06:37 -0400 Subject: [PATCH 020/237] fixed issue where Groups.getUserGroups called getGroupsData on all groups, resulting in a very unscalable method if called on forum with thousands of groups --- src/groups.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/groups.js b/src/groups.js index 6cff59ded0..b46b23aca5 100644 --- a/src/groups.js +++ b/src/groups.js @@ -981,13 +981,13 @@ var async = require('async'), return groupName !== 'registered-users' && groupName.indexOf(':privileges:') === -1; }); - Groups.getGroupsData(groupNames, function(err, groupData) { + Groups.getMultipleGroupFields(groupNames, ['name', 'hidden'], function(err, groupData) { if (err) { return callback(err); } groupData = groupData.filter(function(group) { - return group && !group.hidden; + return group && !parseInt(group.hidden, 10); }); var groupSets = groupData.map(function(group) { @@ -1003,11 +1003,11 @@ var async = require('async'), var memberOf = []; isMembers.forEach(function(isMember, index) { if (isMember) { - memberOf.push(groupData[index]); + memberOf.push(groupData[index].name); } }); - next(null, memberOf); + Groups.getGroupsData(memberOf, next); }); }, callback); }); From 56e5f505a0212a600346eefa827c3c89c9cb244c Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 19 May 2015 13:27:02 -0400 Subject: [PATCH 021/237] no need to yell! :p --- public/language/en@pirate/error.json | 2 +- public/language/en_GB/error.json | 2 +- public/language/en_US/error.json | 2 +- public/language/ja/error.json | 2 +- public/language/sc/error.json | 2 +- public/language/sk/error.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/public/language/en@pirate/error.json b/public/language/en@pirate/error.json index 867f331c3c..71c02b3dc5 100644 --- a/public/language/en@pirate/error.json +++ b/public/language/en@pirate/error.json @@ -2,7 +2,7 @@ "invalid-data": "Invalid Data", "not-logged-in": "You don't seem to be logged in.", "account-locked": "Your account has been locked temporarily", - "search-requires-login": "Searching requires an account! Please login or register!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Invalid Category ID", "invalid-tid": "Invalid Topic ID", "invalid-pid": "Invalid Post ID", diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 40975c69b0..d587e80dd0 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -3,7 +3,7 @@ "not-logged-in": "You don't seem to be logged in.", "account-locked": "Your account has been locked temporarily", - "search-requires-login": "Searching requires an account! Please login or register!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Invalid Category ID", "invalid-tid": "Invalid Topic ID", diff --git a/public/language/en_US/error.json b/public/language/en_US/error.json index 867f331c3c..71c02b3dc5 100644 --- a/public/language/en_US/error.json +++ b/public/language/en_US/error.json @@ -2,7 +2,7 @@ "invalid-data": "Invalid Data", "not-logged-in": "You don't seem to be logged in.", "account-locked": "Your account has been locked temporarily", - "search-requires-login": "Searching requires an account! Please login or register!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Invalid Category ID", "invalid-tid": "Invalid Topic ID", "invalid-pid": "Invalid Post ID", diff --git a/public/language/ja/error.json b/public/language/ja/error.json index f4edefb38f..6bae1800ba 100644 --- a/public/language/ja/error.json +++ b/public/language/ja/error.json @@ -2,7 +2,7 @@ "invalid-data": "無効なデータ", "not-logged-in": "ログインしていていないようです。", "account-locked": "Your account has been locked temporarily", - "search-requires-login": "Searching requires an account! Please login or register!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "無効な板ID", "invalid-tid": "無効なスレッドID", "invalid-pid": "無効なポストID", diff --git a/public/language/sc/error.json b/public/language/sc/error.json index 867f331c3c..71c02b3dc5 100644 --- a/public/language/sc/error.json +++ b/public/language/sc/error.json @@ -2,7 +2,7 @@ "invalid-data": "Invalid Data", "not-logged-in": "You don't seem to be logged in.", "account-locked": "Your account has been locked temporarily", - "search-requires-login": "Searching requires an account! Please login or register!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Invalid Category ID", "invalid-tid": "Invalid Topic ID", "invalid-pid": "Invalid Post ID", diff --git a/public/language/sk/error.json b/public/language/sk/error.json index aac7aeee03..079f0712d0 100644 --- a/public/language/sk/error.json +++ b/public/language/sk/error.json @@ -2,7 +2,7 @@ "invalid-data": "Nesprávne údaje", "not-logged-in": "Nie ste prihlásený", "account-locked": "Váš účet bol dočasne uzamknutý.", - "search-requires-login": "Searching requires an account! Please login or register!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Nesprávne ID kategórie", "invalid-tid": "Nesprávne ID témy", "invalid-pid": "Nesprávne IČ príspevku", From 297b5906edf819eda7a23612498e82ea9ae7de4b Mon Sep 17 00:00:00 2001 From: pentode Date: Tue, 19 May 2015 14:55:06 -0400 Subject: [PATCH 022/237] add feature to define mongo client connect options via config.json --- package.json | 1 + src/database/mongo.js | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/package.json b/package.json index 278141c507..dabfe11799 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "templates.js": "^0.2.3", "uglify-js": "git+https://github.com/julianlam/UglifyJS2.git", "underscore": "~1.8.3", + "underscore.deep": "^0.5.1", "validator": "^3.30.0", "winston": "^0.9.0", "xregexp": "~2.0.0" diff --git a/src/database/mongo.js b/src/database/mongo.js index cc9bacec1c..9b0cd64842 100644 --- a/src/database/mongo.js +++ b/src/database/mongo.js @@ -7,8 +7,11 @@ async = require('async'), nconf = require('nconf'), session = require('express-session'), + _ = require('underscore'), db, mongoClient; + _.mixin(require('underscore.deep')); + module.questions = [ { name: 'mongo:host', @@ -88,6 +91,9 @@ poolSize: parseInt(nconf.get('mongo:poolSize'), 10) || 10 } }; + + connOptions = _.deepExtend((nconf.get('mongo:options') || {}), connOptions); + mongoClient.connect(connString, connOptions, function(err, _db) { if (err) { winston.error("NodeBB could not connect to your Mongo database. Mongo returned the following error: " + err.message); From 1550f826525e662f41812907b4482cd531396c26 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 19 May 2015 14:56:39 -0400 Subject: [PATCH 023/237] closes #2928 --- src/views/admin/general/navigation.tpl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/views/admin/general/navigation.tpl b/src/views/admin/general/navigation.tpl index fe956cc5bc..36c7ac2ce7 100644 --- a/src/views/admin/general/navigation.tpl +++ b/src/views/admin/general/navigation.tpl @@ -25,6 +25,21 @@ + +


+ Properties: +
+ +
+
+ +
+ +
From 60f9fc17ae904634787ade64c0a13a906cedd834 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 19 May 2015 14:57:05 -0400 Subject: [PATCH 024/237] #2928 --- public/src/admin/general/navigation.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/public/src/admin/general/navigation.js b/public/src/admin/general/navigation.js index c98b9fa7be..e725e39ad1 100644 --- a/public/src/admin/general/navigation.js +++ b/public/src/admin/general/navigation.js @@ -49,18 +49,31 @@ define('admin/general/navigation', ['translator'], function(translator) { $('#enabled li').each(function() { var form = $(this).find('form').serializeArray(), - data = {}; + data = {}, + properties = {}; form.forEach(function(input) { - data[input.name] = translator.escape(input.value); + if (input.name.slice(0, 9) === 'property:' && input.value === 'on') { + properties[input.name.slice(9)] = true; + } else { + data[input.name] = translator.escape(input.value); + } }); + data.properties = {}; + available.forEach(function(item) { if (item.route.match(data.route)) { - data.properties = item.properties; + data.properties = item.properties || {}; } }); + for (var prop in properties) { + if (properties.hasOwnProperty(prop)) { + data.properties[prop] = properties[prop]; + } + } + nav.push(data); }); From 93170ca10647e6aa64e0245459f8af5bb0daf68f Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 19 May 2015 15:31:51 -0400 Subject: [PATCH 025/237] closes #3147 --- src/topics/create.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/topics/create.js b/src/topics/create.js index 1aee41e01a..81d86793fe 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -281,6 +281,7 @@ module.exports = function(Topics) { if (parseInt(uid, 10) && data.req) { Topics.notifyFollowers(postData, uid); + user.updateLastOnlineTime(uid); } if (postData.index > 0) { From 9cdc2e5a2d3db1f5f4c2cb5da79aa14f2465e331 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Tue, 19 May 2015 15:46:23 -0400 Subject: [PATCH 026/237] closes #3147 properly --- src/topics/create.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/topics/create.js b/src/topics/create.js index 81d86793fe..75422ff40b 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -281,7 +281,7 @@ module.exports = function(Topics) { if (parseInt(uid, 10) && data.req) { Topics.notifyFollowers(postData, uid); - user.updateLastOnlineTime(uid); + user.setUserField(uid, 'lastonline', Date.now()); } if (postData.index > 0) { From 05049946d482d8b1fb5307c74212f8cae0e79ff2 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 19 May 2015 16:59:38 -0400 Subject: [PATCH 027/237] updated error strings --- public/language/en_GB/error.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index d587e80dd0..73bd2ce7db 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -88,8 +88,8 @@ "invalid-file": "Invalid File", "uploads-are-disabled": "Uploads are disabled", - "signature-too-long" : "Sorry, your signature cannot be longer than %1 characters.", - "about-me-too-long" : "Sorry, your about me cannot be longer than %1 characters.", + "signature-too-long" : "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long" : "Sorry, your about me cannot be longer than %1 character(s).", "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", From 93df7f14d88bd40f88e78c5a39b04975b28b751e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 19 May 2015 17:45:23 -0400 Subject: [PATCH 028/237] latest translations and fallbacks --- public/language/ar/error.json | 3 ++- public/language/ar/topic.json | 1 + public/language/ar/user.json | 1 + public/language/bg/error.json | 5 +++-- public/language/bg/topic.json | 1 + public/language/bg/user.json | 1 + public/language/bn/error.json | 3 ++- public/language/bn/topic.json | 1 + public/language/bn/user.json | 1 + public/language/cs/error.json | 3 ++- public/language/cs/topic.json | 1 + public/language/cs/user.json | 1 + public/language/de/error.json | 5 +++-- public/language/de/topic.json | 1 + public/language/de/user.json | 1 + public/language/el/error.json | 3 ++- public/language/el/topic.json | 1 + public/language/el/user.json | 1 + public/language/en@pirate/error.json | 1 + public/language/en@pirate/topic.json | 1 + public/language/en@pirate/user.json | 1 + public/language/en_US/error.json | 1 + public/language/en_US/topic.json | 1 + public/language/en_US/user.json | 1 + public/language/es/error.json | 3 ++- public/language/es/topic.json | 1 + public/language/es/user.json | 1 + public/language/et/error.json | 3 ++- public/language/et/topic.json | 1 + public/language/et/user.json | 1 + public/language/fa_IR/error.json | 5 +++-- public/language/fa_IR/language.json | 2 +- public/language/fa_IR/topic.json | 1 + public/language/fa_IR/user.json | 1 + public/language/fi/error.json | 3 ++- public/language/fi/topic.json | 1 + public/language/fi/user.json | 1 + public/language/fr/error.json | 5 +++-- public/language/fr/topic.json | 1 + public/language/fr/user.json | 1 + public/language/he/error.json | 3 ++- public/language/he/topic.json | 1 + public/language/he/user.json | 1 + public/language/hu/error.json | 3 ++- public/language/hu/topic.json | 1 + public/language/hu/user.json | 1 + public/language/id/error.json | 3 ++- public/language/id/topic.json | 1 + public/language/id/user.json | 1 + public/language/it/error.json | 3 ++- public/language/it/topic.json | 1 + public/language/it/user.json | 1 + public/language/ja/error.json | 1 + public/language/ja/topic.json | 1 + public/language/ja/user.json | 1 + public/language/ko/error.json | 3 ++- public/language/ko/topic.json | 1 + public/language/ko/user.json | 1 + public/language/lt/error.json | 3 ++- public/language/lt/topic.json | 1 + public/language/lt/user.json | 1 + public/language/ms/error.json | 5 +++-- public/language/ms/topic.json | 1 + public/language/ms/user.json | 1 + public/language/nb/error.json | 3 ++- public/language/nb/topic.json | 1 + public/language/nb/user.json | 1 + public/language/nl/error.json | 5 +++-- public/language/nl/topic.json | 1 + public/language/nl/user.json | 1 + public/language/pl/error.json | 3 ++- public/language/pl/topic.json | 1 + public/language/pl/user.json | 1 + public/language/pt_BR/error.json | 3 ++- public/language/pt_BR/topic.json | 1 + public/language/pt_BR/user.json | 1 + public/language/ro/error.json | 3 ++- public/language/ro/topic.json | 1 + public/language/ro/user.json | 1 + public/language/ru/error.json | 5 +++-- public/language/ru/topic.json | 1 + public/language/ru/user.json | 1 + public/language/sc/error.json | 1 + public/language/sc/topic.json | 1 + public/language/sc/user.json | 1 + public/language/sk/error.json | 1 + public/language/sk/topic.json | 1 + public/language/sk/user.json | 1 + public/language/sv/error.json | 3 ++- public/language/sv/topic.json | 1 + public/language/sv/user.json | 1 + public/language/th/error.json | 3 ++- public/language/th/topic.json | 1 + public/language/th/user.json | 1 + public/language/tr/error.json | 3 ++- public/language/tr/topic.json | 1 + public/language/tr/user.json | 1 + public/language/vi/error.json | 3 ++- public/language/vi/topic.json | 1 + public/language/vi/user.json | 1 + public/language/zh_CN/error.json | 3 ++- public/language/zh_CN/topic.json | 1 + public/language/zh_CN/user.json | 1 + public/language/zh_TW/error.json | 3 ++- public/language/zh_TW/topic.json | 1 + public/language/zh_TW/user.json | 1 + 106 files changed, 143 insertions(+), 38 deletions(-) diff --git a/public/language/ar/error.json b/public/language/ar/error.json index 2071baf252..4c10a8cf38 100644 --- a/public/language/ar/error.json +++ b/public/language/ar/error.json @@ -2,7 +2,7 @@ "invalid-data": "بيانات غير صالحة", "not-logged-in": "لم تقم بتسجيل الدخول", "account-locked": "تم إقفال حسابكم مؤقتًا.", - "search-requires-login": "البحث في المنتدى يستلزم توفرك على حساب! المرجو تسجيل دخولك أو إنشاء حساب!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "قائمة غير موجودة", "invalid-tid": "موضوع غير متواجد", "invalid-pid": "رد غير موجود", @@ -68,6 +68,7 @@ "invalid-file": "ملف غير مقبول", "uploads-are-disabled": "رفع الملفات غير مفعل", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "لايمكنك فتح محادثة مع نفسك", "chat-restricted": "هذا المستخدم عطل المحادثات الواردة عليه. يجب أن يتبعك حتى تتمكن من فتح محادثة معه.", "too-many-messages": "You have sent too many messages, please wait awhile.", diff --git a/public/language/ar/topic.json b/public/language/ar/topic.json index 0ac8738c9f..fa8064880c 100644 --- a/public/language/ar/topic.json +++ b/public/language/ar/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "لا توجد مواضيع !", "no_posts_found": "لا توجد مشاركات!", "post_is_deleted": "هذه المشاركة محذوفة!", + "topic_is_deleted": "This topic is deleted!", "profile": "الملف الشخصي", "posted_by": "كتب من طرف %1", "posted_by_guest": "كتب من طرف زائر", diff --git a/public/language/ar/user.json b/public/language/ar/user.json index 613bade9ce..acc500eabf 100644 --- a/public/language/ar/user.json +++ b/public/language/ar/user.json @@ -21,6 +21,7 @@ "watched": "متابع", "followers": "المتابعون", "following": "يتابع", + "aboutme": "About me", "signature": "توقيع", "gravatar": "Gravatar", "birthday": "عيد ميلاد", diff --git a/public/language/bg/error.json b/public/language/bg/error.json index 17907c8815..ce39acb82d 100644 --- a/public/language/bg/error.json +++ b/public/language/bg/error.json @@ -2,7 +2,7 @@ "invalid-data": "Невалидни данни", "not-logged-in": "Изглежда не сте влезли в системата.", "account-locked": "Вашият акаунт беше заключен временно", - "search-requires-login": "Търсенето изисква регистриран акаунт! Моля, влезте или се регистрирайте!", + "search-requires-login": "Търсенето изисква акаунт – моля, влезте или се регистрирайте.", "invalid-cid": "Невалиден идентификатор на категория", "invalid-tid": "Невалиден идентификатор на тема", "invalid-pid": "Невалиден идентификатор на публикация", @@ -67,7 +67,8 @@ "topic-thumbnails-are-disabled": "Иконките на темите са изключени.", "invalid-file": "Грешен файл", "uploads-are-disabled": "Качването не е разрешено", - "signature-too-long": "Съжаляваме, но подписът Ви трябва да съдържа не повече от %1 символ(а).", + "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "Не можете да пишете чат съобщение на себе си!", "chat-restricted": "Този потребител е ограничил чат съобщенията до себе си. Той трябва първо да Ви последва, преди да можете да си пишете с него.", "too-many-messages": "Изпратили сте твърде много съобщения. Моля, изчакайте малко.", diff --git a/public/language/bg/topic.json b/public/language/bg/topic.json index 03062d7e70..492bf1bccf 100644 --- a/public/language/bg/topic.json +++ b/public/language/bg/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Няма открити теми!", "no_posts_found": "Няма открити публикации!", "post_is_deleted": "Тази публикация е изтрита!", + "topic_is_deleted": "Тази тема е изтрита!", "profile": "Профил", "posted_by": "Публикувано от %1", "posted_by_guest": "Публикувано от гост", diff --git a/public/language/bg/user.json b/public/language/bg/user.json index f6b68145f1..dee62ac943 100644 --- a/public/language/bg/user.json +++ b/public/language/bg/user.json @@ -21,6 +21,7 @@ "watched": "Наблюдавани", "followers": "Последователи", "following": "Следва", + "aboutme": "За мен", "signature": "Подпис", "gravatar": "Граватар", "birthday": "Рождена дата", diff --git a/public/language/bn/error.json b/public/language/bn/error.json index 40b8dc44d7..979dca250b 100644 --- a/public/language/bn/error.json +++ b/public/language/bn/error.json @@ -2,7 +2,7 @@ "invalid-data": "ভুল তথ্য", "not-logged-in": "আপনি লগিন করেননি", "account-locked": "আপনার অ্যাকাউন্ট সাময়িকভাবে লক করা হয়েছে", - "search-requires-login": "অনুসন্ধান করার জন্য একটি অ্যাকাউন্ট প্রয়োজন! অনুগ্রহপূর্বক প্রবেশ করুন অথবা নিবন্ধন করুন!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "ভুল বিভাগ নাম্বার", "invalid-tid": "ভুল টপিক নাম্বার", "invalid-pid": "ভুল পোস্ট নাম্বার", @@ -68,6 +68,7 @@ "invalid-file": "ভুল ফাইল", "uploads-are-disabled": "আপলোড নিষ্ক্রিয় করা", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "আপনি নিজের সাথে চ্যাট করতে পারবেন না!", "chat-restricted": "এই সদস্য তার বার্তালাপ সংরক্ষিত রেখেছেন। এই সদস্য আপনাকে ফলো করার পরই কেবলমাত্র আপনি তার সাথে চ্যাট করতে পারবেন", "too-many-messages": "You have sent too many messages, please wait awhile.", diff --git a/public/language/bn/topic.json b/public/language/bn/topic.json index 3b0835cf2e..92466f18c8 100644 --- a/public/language/bn/topic.json +++ b/public/language/bn/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "কোন টপিক পাওয়া যায়নি!", "no_posts_found": "কোন পোস্ট পাওয়া যায়নি", "post_is_deleted": "এই পোস্টটি মুছে ফেলা হয়েছে!", + "topic_is_deleted": "This topic is deleted!", "profile": "প্রোফাইল ", "posted_by": "পোস্ট করেছেন %1", "posted_by_guest": "অতিথি পোস্ট ", diff --git a/public/language/bn/user.json b/public/language/bn/user.json index 5107df1fa7..96b8943a2d 100644 --- a/public/language/bn/user.json +++ b/public/language/bn/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "যাদের অনুসরণ করছেন", "following": "যারা আপনাকে অনুসরণ করছে", + "aboutme": "About me", "signature": "স্বাক্ষর", "gravatar": "গ্রাভাতার", "birthday": "জন্মদিন", diff --git a/public/language/cs/error.json b/public/language/cs/error.json index 1a82707bd9..60418d0ef0 100644 --- a/public/language/cs/error.json +++ b/public/language/cs/error.json @@ -2,7 +2,7 @@ "invalid-data": "Neplatná data", "not-logged-in": "Zdá se, že nejste přihlášen(a)", "account-locked": "Váš účet byl dočasně uzamčen", - "search-requires-login": "Chcete-li vyhledávat, musíte mít účet. Přihlašte se nebo zaregistrujte, prosím.", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Neplatné ID kategorie", "invalid-tid": "Neplatné ID tématu", "invalid-pid": "Neplatné ID příspěvku", @@ -68,6 +68,7 @@ "invalid-file": "Neplatný soubor", "uploads-are-disabled": "Nahrávání je zakázáno", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/cs/topic.json b/public/language/cs/topic.json index 4f20b6e6db..7e930cfc23 100644 --- a/public/language/cs/topic.json +++ b/public/language/cs/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Nebyla nalezena žádná témata!", "no_posts_found": "Nebyly nalezeny žádné příspěvky!", "post_is_deleted": "Tento příspěvek je vymazán!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Posted by %1", "posted_by_guest": "Posted by Guest", diff --git a/public/language/cs/user.json b/public/language/cs/user.json index 171ed20163..b41192c56f 100644 --- a/public/language/cs/user.json +++ b/public/language/cs/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Sledují ho", "following": "Sleduje", + "aboutme": "About me", "signature": "Podpis", "gravatar": "Gravatar", "birthday": "Datum narození", diff --git a/public/language/de/error.json b/public/language/de/error.json index 1d5935080d..61cb1fa3f9 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 registriere dich!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Ungültige Kategorie-ID", "invalid-tid": "Ungültige Themen-ID", "invalid-pid": "Ungültige Beitrags-ID", @@ -67,7 +67,8 @@ "topic-thumbnails-are-disabled": "Vorschaubilder für Themen sind deaktiviert", "invalid-file": "Datei ungültig", "uploads-are-disabled": "Uploads sind deaktiviert", - "signature-too-long": "Deine Signatur darf %1 Zeichen nicht überschreiten.", + "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Du hast zu viele Nachrichten versandt, bitte warte eine Weile.", diff --git a/public/language/de/topic.json b/public/language/de/topic.json index c4fe7732d8..43d59ecb73 100644 --- a/public/language/de/topic.json +++ b/public/language/de/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Keine passenden Themen gefunden.", "no_posts_found": "Keine Beiträge gefunden!", "post_is_deleted": "Dieser Beitrag wurde gelöscht!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Geschrieben von %1", "posted_by_guest": "Verfasst von einem Gast", diff --git a/public/language/de/user.json b/public/language/de/user.json index 2661df0091..d1677c7609 100644 --- a/public/language/de/user.json +++ b/public/language/de/user.json @@ -21,6 +21,7 @@ "watched": "Beobachtet", "followers": "Folger", "following": "Folgt", + "aboutme": "About me", "signature": "Signatur", "gravatar": "Gravatar", "birthday": "Geburtstag", diff --git a/public/language/el/error.json b/public/language/el/error.json index 5749bd7156..2cb627fbc4 100644 --- a/public/language/el/error.json +++ b/public/language/el/error.json @@ -2,7 +2,7 @@ "invalid-data": "Άκυρα Δεδομένα", "not-logged-in": "Φαίνεται πως δεν είσαι συνδεδεμένος/η.", "account-locked": "Ο λογαριασμός σου έχει κλειδωθεί προσωρινά", - "search-requires-login": "Πρέπει να είσαι συνδεδεμένος/η για να αναζητήσεις! Παρακαλώ συνδέσου ή εγγράψου!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Άκυρο ID Κατηγορίας", "invalid-tid": "Άκυρο ID Θέματος", "invalid-pid": "Άκυρο ID Δημοσίευσης", @@ -68,6 +68,7 @@ "invalid-file": "Άκυρο Αρχείο", "uploads-are-disabled": "Το ανέβασμα αρχείων έχει απενεργοποιηθεί", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/el/topic.json b/public/language/el/topic.json index 5e93f49db9..2a905bf786 100644 --- a/public/language/el/topic.json +++ b/public/language/el/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Δεν βρέθηκαν θέματα!", "no_posts_found": "Δεν βρέθηκαν δημοσιεύσεις!", "post_is_deleted": "Αυτή η δημοσίευση έχει διαγραφεί!", + "topic_is_deleted": "This topic is deleted!", "profile": "Προφίλ", "posted_by": "Δημοσιεύτηκε από τον/την %1", "posted_by_guest": "Δημοσιεύτηκε από Επισκέπτη", diff --git a/public/language/el/user.json b/public/language/el/user.json index 984400744f..9524d5a529 100644 --- a/public/language/el/user.json +++ b/public/language/el/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Ακόλουθοι", "following": "Ακολουθά", + "aboutme": "About me", "signature": "Υπογραφή", "gravatar": "Gravatar", "birthday": "Γενέθλια", diff --git a/public/language/en@pirate/error.json b/public/language/en@pirate/error.json index 71c02b3dc5..ac2457e250 100644 --- a/public/language/en@pirate/error.json +++ b/public/language/en@pirate/error.json @@ -68,6 +68,7 @@ "invalid-file": "Invalid File", "uploads-are-disabled": "Uploads are disabled", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/en@pirate/topic.json b/public/language/en@pirate/topic.json index 88cd2e2328..641e8f0346 100644 --- a/public/language/en@pirate/topic.json +++ b/public/language/en@pirate/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "No topics found!", "no_posts_found": "No posts found!", "post_is_deleted": "This post is deleted!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profile", "posted_by": "Posted by %1", "posted_by_guest": "Posted by Guest", diff --git a/public/language/en@pirate/user.json b/public/language/en@pirate/user.json index d93872539c..49ecb754ac 100644 --- a/public/language/en@pirate/user.json +++ b/public/language/en@pirate/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Followers", "following": "Following", + "aboutme": "About me", "signature": "Signature", "gravatar": "Gravatar", "birthday": "Birthday", diff --git a/public/language/en_US/error.json b/public/language/en_US/error.json index 71c02b3dc5..ac2457e250 100644 --- a/public/language/en_US/error.json +++ b/public/language/en_US/error.json @@ -68,6 +68,7 @@ "invalid-file": "Invalid File", "uploads-are-disabled": "Uploads are disabled", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/en_US/topic.json b/public/language/en_US/topic.json index 750ce2694a..d9742f2eda 100644 --- a/public/language/en_US/topic.json +++ b/public/language/en_US/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "No topics found!", "no_posts_found": "No posts found!", "post_is_deleted": "This post is deleted!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profile", "posted_by": "Posted by %1", "posted_by_guest": "Posted by Guest", diff --git a/public/language/en_US/user.json b/public/language/en_US/user.json index ddfb4ac04a..c3ebec37a2 100644 --- a/public/language/en_US/user.json +++ b/public/language/en_US/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Followers", "following": "Following", + "aboutme": "About me", "signature": "Signature", "gravatar": "Gravatar", "birthday": "Birthday", diff --git a/public/language/es/error.json b/public/language/es/error.json index 12132c317d..cd90a8470b 100644 --- a/public/language/es/error.json +++ b/public/language/es/error.json @@ -2,7 +2,7 @@ "invalid-data": "Datos no válidos", "not-logged-in": "No has iniciado sesión.", "account-locked": "Tu cuenta ha sido bloqueada temporalmente.", - "search-requires-login": "¡Buscar requiere estar registrado! Por favor, entra o regístrate.", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Identificador de categoría no válido", "invalid-tid": "Identificador de tema no válido", "invalid-pid": "Identificador de publicación no válido", @@ -68,6 +68,7 @@ "invalid-file": "Archivo no válido", "uploads-are-disabled": "Las subidas están deshabilitadas.", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Has enviado demasiados mensajes, por favor espera un poco.", diff --git a/public/language/es/topic.json b/public/language/es/topic.json index 1938b05c7d..edf271b351 100644 --- a/public/language/es/topic.json +++ b/public/language/es/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "¡No se encontraron temas!", "no_posts_found": "¡No se encontraron publicaciones!", "post_is_deleted": "¡Esta publicación está eliminada!", + "topic_is_deleted": "This topic is deleted!", "profile": "Perfil", "posted_by": "Publicado por %1", "posted_by_guest": "Publicado por Invitado", diff --git a/public/language/es/user.json b/public/language/es/user.json index 09782de1b5..44baffb856 100644 --- a/public/language/es/user.json +++ b/public/language/es/user.json @@ -21,6 +21,7 @@ "watched": "Visto", "followers": "Seguidores", "following": "Siguiendo", + "aboutme": "About me", "signature": "Firma", "gravatar": "Gravatar", "birthday": "Cumpleaños", diff --git a/public/language/et/error.json b/public/language/et/error.json index 776586b76c..bceffa41e1 100644 --- a/public/language/et/error.json +++ b/public/language/et/error.json @@ -2,7 +2,7 @@ "invalid-data": "Vigased andmed", "not-logged-in": "Sa ei ole sisse logitud", "account-locked": "Su kasutaja on ajutiselt lukustatud", - "search-requires-login": "Foorumis otsimiseks on vaja kasutajat! Palun logi sisse või registreeru kasutajaks!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Vigane kategooria ID", "invalid-tid": "Vigane teema ID", "invalid-pid": "Vigane postituse ID", @@ -68,6 +68,7 @@ "invalid-file": "Vigane fail", "uploads-are-disabled": "Üleslaadimised on keelatud", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "Sa ei saa endaga vestelda!", "chat-restricted": "Kasutaja on piiranud sõnumite saatmist. Privaatsõnumi saatmiseks peab kasutaja sind jälgima", "too-many-messages": "Oled saatnud liiga palju sõnumeid, oota natukene.", diff --git a/public/language/et/topic.json b/public/language/et/topic.json index f5d72479c9..4359384ac4 100644 --- a/public/language/et/topic.json +++ b/public/language/et/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Teemasid ei leitud!", "no_posts_found": "Postitusi ei leitud!", "post_is_deleted": "See postitus on kustutatud!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profiil", "posted_by": "Postitas %1", "posted_by_guest": "Postitatud külalise ppolt", diff --git a/public/language/et/user.json b/public/language/et/user.json index 6c015502db..5cd87ac9a2 100644 --- a/public/language/et/user.json +++ b/public/language/et/user.json @@ -21,6 +21,7 @@ "watched": "Vaadatud", "followers": "Jälgijad", "following": "Jälgimised", + "aboutme": "About me", "signature": "Allkiri", "gravatar": "Gravatar", "birthday": "Sünnipäev", diff --git a/public/language/fa_IR/error.json b/public/language/fa_IR/error.json index 693ac564de..37e2a353b3 100644 --- a/public/language/fa_IR/error.json +++ b/public/language/fa_IR/error.json @@ -2,7 +2,7 @@ "invalid-data": "داده(های) نامعتبر", "not-logged-in": "به نظر میرسد که با حساب کاربری وارد نشده اید.", "account-locked": "حساب کاربری شما موقتاً مسدود شده است.", - "search-requires-login": "جستجو نیاز به حساب کاربری دارد! لطفا وارد شوید و یا ثبت نام کنید!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "شناسه دسته نامعتبر است.", "invalid-tid": "شناسه جستار نامعتبر است.", "invalid-pid": "شناسه دیدگاه نامعتبر است.", @@ -67,7 +67,8 @@ "topic-thumbnails-are-disabled": "چهرک‌های جستار غیرفعال شده است.", "invalid-file": "فایل نامعتبر است.", "uploads-are-disabled": "امکان بارگذاری غیرفعال شده است.", - "signature-too-long": "پوزش می‌خواهیم، امضای شما نمی‌تواند بیش‌تر از %1 نویسه داشته باشد.", + "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "شما نمی‌توانید با خودتان گفتگو کنید!", "chat-restricted": "این کاربر پیام های گفتگوی خود را محدود کرده است . آنها بایدشما را دنبال کنند تا اینکه شما بتوانید به آنها پیامی بفرستید", "too-many-messages": "شما پیامهای خیلی زیادی فرستاده اید، لطفا مدتی صبر نمایید", diff --git a/public/language/fa_IR/language.json b/public/language/fa_IR/language.json index de83f729fb..c387007d53 100644 --- a/public/language/fa_IR/language.json +++ b/public/language/fa_IR/language.json @@ -1,5 +1,5 @@ { - "name": "Persian (Iran)", + "name": "فارسی", "code": "fa_IR", "dir": "rtl" } \ No newline at end of file diff --git a/public/language/fa_IR/topic.json b/public/language/fa_IR/topic.json index 2ed30ffa38..3a26922060 100644 --- a/public/language/fa_IR/topic.json +++ b/public/language/fa_IR/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "هیچ جستاری یافت نشد!", "no_posts_found": "دیدگاهی یافت نشد!", "post_is_deleted": "این دیدگاه پاک شده!", + "topic_is_deleted": "This topic is deleted!", "profile": "نمایه", "posted_by": "ارسال شده توسط %1", "posted_by_guest": "ارسال شده توسط مهمان", diff --git a/public/language/fa_IR/user.json b/public/language/fa_IR/user.json index e3722d684c..2758770015 100644 --- a/public/language/fa_IR/user.json +++ b/public/language/fa_IR/user.json @@ -21,6 +21,7 @@ "watched": "پاییده شده", "followers": "دنبال‌کننده‌ها", "following": "دنبال‌شونده‌ها", + "aboutme": "About me", "signature": "امضا", "gravatar": "گراواتار", "birthday": "روز تولد", diff --git a/public/language/fi/error.json b/public/language/fi/error.json index 6001a3f211..0c38939c8c 100644 --- a/public/language/fi/error.json +++ b/public/language/fi/error.json @@ -2,7 +2,7 @@ "invalid-data": "Virheellinen data", "not-logged-in": "Et taida olla kirjautuneena sisään.", "account-locked": "Käyttäjätilisi on lukittu väliaikaisesti", - "search-requires-login": "Hakeminen vaatii käyttäjätilin! Kirjaudu sisään tai rekisteröidy!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Virheellinen kategorian ID", "invalid-tid": "Virheellinen aiheen ID", "invalid-pid": "Virheellinen viestin ID", @@ -68,6 +68,7 @@ "invalid-file": "Virheellinen tiedosto", "uploads-are-disabled": "Et voi lähettää tiedostoa", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/fi/topic.json b/public/language/fi/topic.json index d6812a7fa4..ec87d3db17 100644 --- a/public/language/fi/topic.json +++ b/public/language/fi/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Aiheita ei löytynyt!", "no_posts_found": "Viestejä ei löytynyt!", "post_is_deleted": "Tämä viesti poistettiin!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profiili", "posted_by": "%1 kirjoitti", "posted_by_guest": "Vieras kirjoitti", diff --git a/public/language/fi/user.json b/public/language/fi/user.json index 3a4c176679..302f503beb 100644 --- a/public/language/fi/user.json +++ b/public/language/fi/user.json @@ -21,6 +21,7 @@ "watched": "Seurattu", "followers": "Seuraajat", "following": "Seuratut", + "aboutme": "About me", "signature": "Allekirjoitus", "gravatar": "Gravatar", "birthday": "Syntymäpäivä", diff --git a/public/language/fr/error.json b/public/language/fr/error.json index 880c9ce132..dd79c11b72 100644 --- a/public/language/fr/error.json +++ b/public/language/fr/error.json @@ -2,7 +2,7 @@ "invalid-data": "Données invalides", "not-logged-in": "Vous ne semblez pas être connecté.", "account-locked": "Votre compte a été temporairement suspendu", - "search-requires-login": "Vous devez avoir un compte pour effectuer une recherche ! Veuillez vous identifier ou vous inscrire !", + "search-requires-login": "Rechercher nécessite d'avoir un compte. Veuillez vous identifier ou vous enregistrer.", "invalid-cid": "ID de catégorie invalide", "invalid-tid": "ID de sujet invalide", "invalid-pid": "ID de message invalide", @@ -67,7 +67,8 @@ "topic-thumbnails-are-disabled": "Les miniatures de sujet sont désactivés", "invalid-file": "Fichier invalide", "uploads-are-disabled": "Les envois sont désactivés", - "signature-too-long": "La signature ne peut dépasser %1 caractère(s).", + "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Vous avez envoyé trop de messages, veuillez patienter un instant.", diff --git a/public/language/fr/topic.json b/public/language/fr/topic.json index 8248eb2580..7a3649951c 100644 --- a/public/language/fr/topic.json +++ b/public/language/fr/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Aucun sujet n'a été trouvé !", "no_posts_found": "Aucun message trouvé !", "post_is_deleted": "Ce message a été supprimé !", + "topic_is_deleted": "Ce sujet a été supprimé !", "profile": "Profil", "posted_by": "Posté par %1", "posted_by_guest": "Posté par un invité", diff --git a/public/language/fr/user.json b/public/language/fr/user.json index b2e6c5a902..486ee48178 100644 --- a/public/language/fr/user.json +++ b/public/language/fr/user.json @@ -21,6 +21,7 @@ "watched": "Suivis", "followers": "Abonnés", "following": "Abonnements", + "aboutme": "À propos de moi", "signature": "Signature", "gravatar": "Gravatar", "birthday": "Anniversaire", diff --git a/public/language/he/error.json b/public/language/he/error.json index d3171986cc..ebe39d885d 100644 --- a/public/language/he/error.json +++ b/public/language/he/error.json @@ -2,7 +2,7 @@ "invalid-data": "נתונים שגויים", "not-logged-in": "נראה שאינך מחובר למערכת.", "account-locked": "חשבונך נחסם באופן זמני", - "search-requires-login": "החיפוש דורש משתמש רשום! יש להיכנס למערכת או להירשם!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "זהוי קטגוריה שגוי", "invalid-tid": "זהוי נושא שגוי", "invalid-pid": "זהוי פוסט שגוי", @@ -68,6 +68,7 @@ "invalid-file": "קובץ לא תקין", "uploads-are-disabled": "העלאת קבצים אינה מאופשרת", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "לא ניתן לעשות צ'אט עם עצמך!", "chat-restricted": "משתמש זה חסם את הודעות הצ'אט שלו ממשתמשים זרים. המשתמש חייב לעקוב אחריך לפני שתוכל לשוחח איתו בצ'אט", "too-many-messages": "שלחת יותר מדי הודעות, אנא המתן לזמן מה.", diff --git a/public/language/he/topic.json b/public/language/he/topic.json index 3ff27d0a8a..62724d03a3 100644 --- a/public/language/he/topic.json +++ b/public/language/he/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "לא נמצאו נושאים!", "no_posts_found": "לא נמצאו פוסטים!", "post_is_deleted": "פוסט זה נמחק!", + "topic_is_deleted": "This topic is deleted!", "profile": "פרופיל", "posted_by": "הפוסט הועלה על ידי %1", "posted_by_guest": "פורסם על-ידי אורח", diff --git a/public/language/he/user.json b/public/language/he/user.json index c2989b6233..6011356044 100644 --- a/public/language/he/user.json +++ b/public/language/he/user.json @@ -21,6 +21,7 @@ "watched": "נצפה", "followers": "עוקבים", "following": "עוקב אחרי", + "aboutme": "About me", "signature": "חתימה", "gravatar": "אווטר", "birthday": "יום הולדת", diff --git a/public/language/hu/error.json b/public/language/hu/error.json index e84486eb06..4f6a148af5 100644 --- a/public/language/hu/error.json +++ b/public/language/hu/error.json @@ -2,7 +2,7 @@ "invalid-data": "Érvénytelen adat", "not-logged-in": "Úgy tűnik, nem vagy bejelentkezve.", "account-locked": "A fiókod ideiglenesen zárolva lett.", - "search-requires-login": "A kereső használatához szükséges egy fiók! Kérlek jelenltkezz be vagy regisztrálj!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Érvénytelen kategória azonosító", "invalid-tid": "Érvénytelen téma azonosító", "invalid-pid": "Érvénytelen hozzászólás azonosító", @@ -68,6 +68,7 @@ "invalid-file": "Érvénytelen fájl", "uploads-are-disabled": "A feltöltés nem engedélyezett", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "Nem cseveghetsz magaddal!", "chat-restricted": "Ez a felhasználó korlátozta a chat beállításait. Csak akkor cseveghetsz vele, miután felvett a követettek közé téged", "too-many-messages": "Túl sok üzenetet küldtél, kérlek várj egy picit.", diff --git a/public/language/hu/topic.json b/public/language/hu/topic.json index 30bf3ab2f8..bb467f2c5c 100644 --- a/public/language/hu/topic.json +++ b/public/language/hu/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Téma nem található!", "no_posts_found": "Hozzászólások nem találhatóak!", "post_is_deleted": "A bejegyzés törlésre került!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Szerző %1", "posted_by_guest": "Szerző Vendég", diff --git a/public/language/hu/user.json b/public/language/hu/user.json index f35879c80e..b6f9906710 100644 --- a/public/language/hu/user.json +++ b/public/language/hu/user.json @@ -21,6 +21,7 @@ "watched": "Megfigyeli", "followers": "Követők", "following": "Követve", + "aboutme": "About me", "signature": "Aláírás", "gravatar": "Gravatar", "birthday": "Szülinap", diff --git a/public/language/id/error.json b/public/language/id/error.json index 508ebfcc6b..531b335a78 100644 --- a/public/language/id/error.json +++ b/public/language/id/error.json @@ -2,7 +2,7 @@ "invalid-data": "Data Salah", "not-logged-in": "Kamu terlihat belum login", "account-locked": "Akun kamu dikunci sementara", - "search-requires-login": "Pencarian butuh sebuah akun, silakan login atau register terlebih dulu", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "ID Kategori Salah", "invalid-tid": "ID Topik Salah", "invalid-pid": "ID Post Salah", @@ -68,6 +68,7 @@ "invalid-file": "File Salah", "uploads-are-disabled": "Upload ditiadakan", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/id/topic.json b/public/language/id/topic.json index c47b9612be..5f119c3e80 100644 --- a/public/language/id/topic.json +++ b/public/language/id/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Tidak topik yang ditemukan!", "no_posts_found": "Tidak ada posting yang ditemukan!", "post_is_deleted": "Posting ini telah dihapus!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Dibuat oleh %1", "posted_by_guest": "Dibuat oleh Tamu", diff --git a/public/language/id/user.json b/public/language/id/user.json index 5faa4375a1..74cfa9f7d6 100644 --- a/public/language/id/user.json +++ b/public/language/id/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Pengikut", "following": "Mengikuti", + "aboutme": "About me", "signature": "Tanda Pengenal", "gravatar": "Gravatar", "birthday": "Hari Lahir", diff --git a/public/language/it/error.json b/public/language/it/error.json index fc59c81e2c..7577b34f43 100644 --- a/public/language/it/error.json +++ b/public/language/it/error.json @@ -2,7 +2,7 @@ "invalid-data": "Dati non validi", "not-logged-in": "Non sembri essere loggato.", "account-locked": "Il tuo account è stato bloccato temporaneamente", - "search-requires-login": "La ricerca richiede un account! Si prega di loggarsi o registrarsi!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "ID Categoria non valido", "invalid-tid": "ID Topic non valido", "invalid-pid": "ID Post non valido", @@ -68,6 +68,7 @@ "invalid-file": "File non valido", "uploads-are-disabled": "Uploads disabilitati", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Hai inviato troppi messaggi, aspetta un attimo.", diff --git a/public/language/it/topic.json b/public/language/it/topic.json index e53ac5c6f2..d442472c00 100644 --- a/public/language/it/topic.json +++ b/public/language/it/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Nessuna discussione trovata!", "no_posts_found": "Nessun post trovato!", "post_is_deleted": "Questo post è eliminato!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profilo", "posted_by": "scritto da %1", "posted_by_guest": "Scritto da Ospite", diff --git a/public/language/it/user.json b/public/language/it/user.json index ec6779bccc..38e2565652 100644 --- a/public/language/it/user.json +++ b/public/language/it/user.json @@ -21,6 +21,7 @@ "watched": "Osservati", "followers": "Da chi è seguito", "following": "Chi segue", + "aboutme": "About me", "signature": "Firma", "gravatar": "Gravatar", "birthday": "Data di nascita", diff --git a/public/language/ja/error.json b/public/language/ja/error.json index 6bae1800ba..631406319a 100644 --- a/public/language/ja/error.json +++ b/public/language/ja/error.json @@ -68,6 +68,7 @@ "invalid-file": "無効なファイル", "uploads-are-disabled": "アップロードが無効された", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/ja/topic.json b/public/language/ja/topic.json index 680b10b702..cd7dace96d 100644 --- a/public/language/ja/topic.json +++ b/public/language/ja/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "スレッドが見つかりません!", "no_posts_found": "ポストはありません!", "post_is_deleted": "このポストが削除されます!", + "topic_is_deleted": "This topic is deleted!", "profile": "プロフィール", "posted_by": "%1 のポスト", "posted_by_guest": "Posted by Guest", diff --git a/public/language/ja/user.json b/public/language/ja/user.json index a480f54f67..55e52d7cb0 100644 --- a/public/language/ja/user.json +++ b/public/language/ja/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "フォロワー", "following": "フォロー中", + "aboutme": "About me", "signature": "署名", "gravatar": "Gravatar", "birthday": "誕生日", diff --git a/public/language/ko/error.json b/public/language/ko/error.json index c9f81d74db..5bfcca4262 100644 --- a/public/language/ko/error.json +++ b/public/language/ko/error.json @@ -2,7 +2,7 @@ "invalid-data": "올바르지 않은 정보입니다.", "not-logged-in": "로그인하지 않았습니다.", "account-locked": "임시로 잠긴 계정입니다.", - "search-requires-login": "검색을 위해서는 계정이 필요합니다. 로그인하거나 회원가입 해 주십시오.", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "올바르지 않은 카테고리 ID입니다.", "invalid-tid": "올바르지 않은 주제 ID입니다.", "invalid-pid": "올바르지 않은 게시물 ID입니다.", @@ -68,6 +68,7 @@ "invalid-file": "올바르지 않은 파일입니다.", "uploads-are-disabled": "업로드는 비활성화되어 있습니다.", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/ko/topic.json b/public/language/ko/topic.json index 56714d7a0a..9e113910a1 100644 --- a/public/language/ko/topic.json +++ b/public/language/ko/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "주제를 찾을 수 없습니다.", "no_posts_found": "게시물을 찾을 수 없습니다.", "post_is_deleted": "이 게시물은 삭제되었습니다.", + "topic_is_deleted": "This topic is deleted!", "profile": "프로필", "posted_by": "%1님이 작성했습니다.", "posted_by_guest": "익명 사용자가 작성했습니다.", diff --git a/public/language/ko/user.json b/public/language/ko/user.json index 70ce30520a..324eccb26f 100644 --- a/public/language/ko/user.json +++ b/public/language/ko/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "이 사용자를 팔로우", "following": "이 사용자가 팔로우", + "aboutme": "About me", "signature": "서명", "gravatar": "그라바타", "birthday": "생일", diff --git a/public/language/lt/error.json b/public/language/lt/error.json index b87aac771c..49023f88aa 100644 --- a/public/language/lt/error.json +++ b/public/language/lt/error.json @@ -2,7 +2,7 @@ "invalid-data": "Klaidingi duomenys", "not-logged-in": "Atrodo, kad jūs neesate prisijungęs.", "account-locked": "Jūsų paskyra buvo laikinai užrakinta", - "search-requires-login": "Norint naudotis paieška, būtina paskyra! Prašome prisijungti arba užsiregistruoti.", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Klaidingas kategorijos ID", "invalid-tid": "Klaidingas temos ID", "invalid-pid": "Klaidingas pranešimo ID", @@ -68,6 +68,7 @@ "invalid-file": "Klaidingas failas", "uploads-are-disabled": "Įkėlimai neleidžiami", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Išsiuntėte per daug pranešimų, kurį laiką prašome palaukti.", diff --git a/public/language/lt/topic.json b/public/language/lt/topic.json index e79c869a1b..5969a8727b 100644 --- a/public/language/lt/topic.json +++ b/public/language/lt/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Temų nerasta!", "no_posts_found": "Įrašų nerasta!", "post_is_deleted": "Šis įrašas ištrintas!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profilis", "posted_by": "Parašė %1", "posted_by_guest": "Parašė svečias", diff --git a/public/language/lt/user.json b/public/language/lt/user.json index 4924eb3b4d..147e525aa5 100644 --- a/public/language/lt/user.json +++ b/public/language/lt/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Sekėjai", "following": "Seka", + "aboutme": "About me", "signature": "Parašas", "gravatar": "Gravatar", "birthday": "Gimimo diena", diff --git a/public/language/ms/error.json b/public/language/ms/error.json index b0cc688b16..e9eefc19a6 100644 --- a/public/language/ms/error.json +++ b/public/language/ms/error.json @@ -2,7 +2,7 @@ "invalid-data": "Data Tak Sah", "not-logged-in": "Anda tidak log masuk.", "account-locked": "Akaun anda telah dikunci untuk seketika", - "search-requires-login": "Pencarian perlukan akaun! Log masuk atau daftar!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Kategori ID Tak Sah", "invalid-tid": "Topik ID Tak Sah", "invalid-pid": "Kiriman ID Tak Sah", @@ -67,7 +67,8 @@ "topic-thumbnails-are-disabled": "Topik kecil dilumpuhkan.", "invalid-file": "Fail tak sah", "uploads-are-disabled": "Muatnaik dilumpuhkan", - "signature-too-long": "Maaf, tandatangan tidak boleh lebih daripada %1 aksara().", + "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "Anda tidak boleh sembang dengan diri sendiri!", "chat-restricted": "Pengguna ini menyekat ruangan sembangnya. Dia hendaklah mengikut anda sebelum kalian dapat bersembang", "too-many-messages": "Anda menghantar terlalu banyak pesanan, sila tunggu seketika.", diff --git a/public/language/ms/topic.json b/public/language/ms/topic.json index fc1c334a0d..0b73e10449 100644 --- a/public/language/ms/topic.json +++ b/public/language/ms/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Tiada topik yang ditemui", "no_posts_found": "Tiada kirim yang dijumpai", "post_is_deleted": "Kiriman ini di padam!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Dikirim oleh %1", "posted_by_guest": "Dikirim oleh pelawat", diff --git a/public/language/ms/user.json b/public/language/ms/user.json index 87c7c02d94..a9f7b41dd1 100644 --- a/public/language/ms/user.json +++ b/public/language/ms/user.json @@ -21,6 +21,7 @@ "watched": "Melihat", "followers": "Pengikut", "following": "Mengikuti", + "aboutme": "About me", "signature": "Tandatangan", "gravatar": "Gravatar", "birthday": "Tarikh lahir", diff --git a/public/language/nb/error.json b/public/language/nb/error.json index a03b17a6b4..fad46d11e6 100644 --- a/public/language/nb/error.json +++ b/public/language/nb/error.json @@ -2,7 +2,7 @@ "invalid-data": "Ugyldig data", "not-logged-in": "Du ser ikke ut til å være logget inn.", "account-locked": "Kontoen din har blitt midlertidig låst", - "search-requires-login": "Søking krever en konto! Vennligst registrer deg eller logg inn!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Ugyldig kategori-ID", "invalid-tid": "Ugyldig emne-ID", "invalid-pid": "Ugyldig innlegg-ID", @@ -68,6 +68,7 @@ "invalid-file": "Ugyldig fil", "uploads-are-disabled": "Opplastninger er deaktivert", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Du har sendt for mange meldinger, vennligst vent en stund.", diff --git a/public/language/nb/topic.json b/public/language/nb/topic.json index 8a599b7942..3863fd48ae 100644 --- a/public/language/nb/topic.json +++ b/public/language/nb/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Ingen emner funnet!", "no_posts_found": "Ingen innlegg funnet!", "post_is_deleted": "Dette innlegget er slettet!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Skapt av %1", "posted_by_guest": "Skapt av Gjest", diff --git a/public/language/nb/user.json b/public/language/nb/user.json index edb5f3d27d..be80c50470 100644 --- a/public/language/nb/user.json +++ b/public/language/nb/user.json @@ -21,6 +21,7 @@ "watched": "Overvåkede", "followers": "Følgere", "following": "Følger", + "aboutme": "About me", "signature": "Signatur", "gravatar": "Gravatar", "birthday": "Bursdag", diff --git a/public/language/nl/error.json b/public/language/nl/error.json index 8fc4f46971..95f7d04f1d 100644 --- a/public/language/nl/error.json +++ b/public/language/nl/error.json @@ -2,7 +2,7 @@ "invalid-data": "Ongeldige Data", "not-logged-in": "De account lijkt op dit moment niet aangemeld te zijn.", "account-locked": "De account is tijdelijk vergrendeld", - "search-requires-login": "Zoekfunctionaliteit gebruiker vereist een account. Registreer daarom snel, of log in op een bestaande gebruikersaccount.", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Ongeldig categoriesleutel", "invalid-tid": "Ongeldig id voor onderwerp", "invalid-pid": "Ongeldig berichtkenmerk", @@ -67,7 +67,8 @@ "topic-thumbnails-are-disabled": "Miniatuurweergaven bij onderwerpen uitgeschakeld. ", "invalid-file": "Ongeldig bestand", "uploads-are-disabled": "Uploads zijn uitgeschakeld", - "signature-too-long": "Helaas, maar de handtekening mag uit niet meer dan %1 teken(s) bestaan.", + "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "Het is niet mogelijk met jezelf een chatgesprek te houden.", "chat-restricted": "Deze gebruiker heeft beperkingen aan de chatfunctie opgelegd waardoor deze eerst iemand moet volgen voordat deze persoon een nieuwe chat mag initiëren.", "too-many-messages": "Er zijn in korte tijd teveel berichten verzonden, een moment geduld.", diff --git a/public/language/nl/topic.json b/public/language/nl/topic.json index 4b8c7ca531..38593ecca8 100644 --- a/public/language/nl/topic.json +++ b/public/language/nl/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Geen onderwerpen gevonden!", "no_posts_found": "Geen berichten gevonden!", "post_is_deleted": "Dit bericht is verwijderd!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profiel", "posted_by": "Geplaatst door %1", "posted_by_guest": "Geplaatst door gast", diff --git a/public/language/nl/user.json b/public/language/nl/user.json index 723bc04f72..4822209b05 100644 --- a/public/language/nl/user.json +++ b/public/language/nl/user.json @@ -21,6 +21,7 @@ "watched": "Bekeken", "followers": "Volgers", "following": "Volgend", + "aboutme": "About me", "signature": "Handtekening", "gravatar": "Gravatar", "birthday": "Verjaardag", diff --git a/public/language/pl/error.json b/public/language/pl/error.json index ca267996bc..80678e8121 100644 --- a/public/language/pl/error.json +++ b/public/language/pl/error.json @@ -2,7 +2,7 @@ "invalid-data": "Błędne dane", "not-logged-in": "Nie jesteś zalogowany/a.", "account-locked": "Twoje konto zostało tymczasowo zablokowane.", - "search-requires-login": "Wyszukiwanie wymaga konta! Zaloguj się lub zarejestruj!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Błędne ID kategorii.", "invalid-tid": "Błędne ID tematu", "invalid-pid": "Błędne ID postu", @@ -68,6 +68,7 @@ "invalid-file": "Błędny plik", "uploads-are-disabled": "Uploadowanie jest wyłączone", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Wysłałeś zbyt wiele wiadomości, proszę poczekaj chwilę.", diff --git a/public/language/pl/topic.json b/public/language/pl/topic.json index f27171c5fa..496c38ba51 100644 --- a/public/language/pl/topic.json +++ b/public/language/pl/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Nie znaleziono żadnych wątków.", "no_posts_found": "Nie znaleziono żadnych postów.", "post_is_deleted": "Ten post jest usunięty", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Napisane przez %1", "posted_by_guest": "Wysłany przez Gościa", diff --git a/public/language/pl/user.json b/public/language/pl/user.json index e8e495ae0c..30593edb85 100644 --- a/public/language/pl/user.json +++ b/public/language/pl/user.json @@ -21,6 +21,7 @@ "watched": "Obserwowane", "followers": "Obserwujących", "following": "Obserwowanych", + "aboutme": "About me", "signature": "Sygnatura", "gravatar": "Gravatar", "birthday": "Urodziny", diff --git a/public/language/pt_BR/error.json b/public/language/pt_BR/error.json index a2518e7d1d..f51b91c38c 100644 --- a/public/language/pt_BR/error.json +++ b/public/language/pt_BR/error.json @@ -2,7 +2,7 @@ "invalid-data": "Dados Inválidos", "not-logged-in": "Você não parece estar logado.", "account-locked": "Sua conta foi temporariamente bloqueada ", - "search-requires-login": "É necessário ter uma conta para realizar buscas! Efetue o login ou Crie uma nova conta.", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "ID de Categoria Inválido", "invalid-tid": "ID de Tópico Inválido", "invalid-pid": "ID de Post Inválido", @@ -68,6 +68,7 @@ "invalid-file": "Arquivo Inválido", "uploads-are-disabled": "Uploads estão desativados", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Você enviou muitas mensagens, por favor aguarde um momento.", diff --git a/public/language/pt_BR/topic.json b/public/language/pt_BR/topic.json index 2c15fac095..0887a1402a 100644 --- a/public/language/pt_BR/topic.json +++ b/public/language/pt_BR/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Nenhum tópico encontrado!", "no_posts_found": "Nenhum post encontrado!", "post_is_deleted": "Este post está deletado!", + "topic_is_deleted": "This topic is deleted!", "profile": "Perfil", "posted_by": "Postado por %1", "posted_by_guest": "Postado por Visitante", diff --git a/public/language/pt_BR/user.json b/public/language/pt_BR/user.json index 677358d58d..ae241a4edc 100644 --- a/public/language/pt_BR/user.json +++ b/public/language/pt_BR/user.json @@ -21,6 +21,7 @@ "watched": "Acompanhado", "followers": "Seguidores", "following": "Seguindo", + "aboutme": "About me", "signature": "Assinatura", "gravatar": "Gravatar", "birthday": "Aniversário", diff --git a/public/language/ro/error.json b/public/language/ro/error.json index 29d8d514b7..c7595f1509 100644 --- a/public/language/ro/error.json +++ b/public/language/ro/error.json @@ -2,7 +2,7 @@ "invalid-data": "Date invalide", "not-logged-in": "Se pare ca nu ești logat.", "account-locked": "Contul tău a fost blocat temporar", - "search-requires-login": "Ca să poți cauta ai nevoie de un cont! Te rugăm să te autentifici sau să te înregistrezi!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "ID Categorie Invalid", "invalid-tid": "ID Subiect Invalid", "invalid-pid": "ID Mesaj Invalid", @@ -68,6 +68,7 @@ "invalid-file": "Fișier invalid", "uploads-are-disabled": "Uploadurile sunt dezactivate", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/ro/topic.json b/public/language/ro/topic.json index 590dfed6d5..f6a2d86eef 100644 --- a/public/language/ro/topic.json +++ b/public/language/ro/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Nu a fost găsit nici un subiect!", "no_posts_found": "Nu a fost găsit nici un mesaj!", "post_is_deleted": "Acest mesaj a fost șters!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Postat de %1", "posted_by_guest": "Postat de Vizitator", diff --git a/public/language/ro/user.json b/public/language/ro/user.json index c9c3554b44..90724690b1 100644 --- a/public/language/ro/user.json +++ b/public/language/ro/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Urmărit de", "following": "Îi urmărește pe", + "aboutme": "About me", "signature": "Semnătură", "gravatar": "Gravatar", "birthday": "Zi de naștere", diff --git a/public/language/ru/error.json b/public/language/ru/error.json index 6e038fcdc8..b4668f3588 100644 --- a/public/language/ru/error.json +++ b/public/language/ru/error.json @@ -2,7 +2,7 @@ "invalid-data": "Неверные данные", "not-logged-in": "Вы не вошли в свой аккаунт.", "account-locked": "Ваш аккаунт временно заблокирован", - "search-requires-login": "Поиск доступен зарегистрированным пользователям! Пожалуйста, войдите или зарегистрируйтесь!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Неверный ID категории", "invalid-tid": "Неверный ID темы", "invalid-pid": "Неверный ID поста", @@ -67,7 +67,8 @@ "topic-thumbnails-are-disabled": "Иконки для темы запрещены", "invalid-file": "Неверный файл", "uploads-are-disabled": "Загрузка запрещена", - "signature-too-long": "Максимальная длина подписи: %1 симв.", + "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "Вы не можете общаться с самим собой", "chat-restricted": "Пользователь ограничил прием сообщений. Он должен быть подписан на Вас, чтобы Вы могли вести переписку с ним.", "too-many-messages": "Вы отправили слишком много сообщений, подождите немного.", diff --git a/public/language/ru/topic.json b/public/language/ru/topic.json index 635e31a765..1a449965b2 100644 --- a/public/language/ru/topic.json +++ b/public/language/ru/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Тем не найдено!", "no_posts_found": "Посты не найдены!", "post_is_deleted": "Этот пост удален!", + "topic_is_deleted": "This topic is deleted!", "profile": "Профиль", "posted_by": "Создано %1", "posted_by_guest": "Опубликовано гостем", diff --git a/public/language/ru/user.json b/public/language/ru/user.json index 800be7cf79..be8dea688f 100644 --- a/public/language/ru/user.json +++ b/public/language/ru/user.json @@ -21,6 +21,7 @@ "watched": "Просмотров", "followers": "Читателей", "following": "Читаемых", + "aboutme": "About me", "signature": "Подпись", "gravatar": "Gravatar", "birthday": "День рождения", diff --git a/public/language/sc/error.json b/public/language/sc/error.json index 71c02b3dc5..ac2457e250 100644 --- a/public/language/sc/error.json +++ b/public/language/sc/error.json @@ -68,6 +68,7 @@ "invalid-file": "Invalid File", "uploads-are-disabled": "Uploads are disabled", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/sc/topic.json b/public/language/sc/topic.json index c0ce4121ff..206ecf6465 100644 --- a/public/language/sc/topic.json +++ b/public/language/sc/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Peruna arresonada agatada!", "no_posts_found": "Perunu arresonu agatadu!", "post_is_deleted": "This post is deleted!", + "topic_is_deleted": "This topic is deleted!", "profile": "Perfilu", "posted_by": "Posted by %1", "posted_by_guest": "Posted by Guest", diff --git a/public/language/sc/user.json b/public/language/sc/user.json index 8f73839294..70097b829d 100644 --- a/public/language/sc/user.json +++ b/public/language/sc/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Sighidores", "following": "Sighende", + "aboutme": "About me", "signature": "Firma", "gravatar": "Gravatas", "birthday": "Cumpleannu", diff --git a/public/language/sk/error.json b/public/language/sk/error.json index 079f0712d0..b86131117b 100644 --- a/public/language/sk/error.json +++ b/public/language/sk/error.json @@ -68,6 +68,7 @@ "invalid-file": "Neplatný súbor", "uploads-are-disabled": "Nahrávanie je znefunkčnené", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/sk/topic.json b/public/language/sk/topic.json index 007cf0f22a..108ab80c20 100644 --- a/public/language/sk/topic.json +++ b/public/language/sk/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Neboli nájdené žiadne témy!", "no_posts_found": "Neboli nájdené žiadne príspevky", "post_is_deleted": "Tento príspevok bol vymazaný!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Publikované %1", "posted_by_guest": "Publikované %1 od hosťa", diff --git a/public/language/sk/user.json b/public/language/sk/user.json index da71890f8c..957dde36e1 100644 --- a/public/language/sk/user.json +++ b/public/language/sk/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Nasledujú ho", "following": "Nasleduje", + "aboutme": "About me", "signature": "Podpis", "gravatar": "Gravatar", "birthday": "Dátum narodenia", diff --git a/public/language/sv/error.json b/public/language/sv/error.json index bfd4e763eb..ca8dd6f96e 100644 --- a/public/language/sv/error.json +++ b/public/language/sv/error.json @@ -2,7 +2,7 @@ "invalid-data": "Ogiltig data", "not-logged-in": "Du verkar inte vara inloggad.", "account-locked": "Ditt konto har tillfälligt blivit låst", - "search-requires-login": "Sökningar kräver att du har ett konto. Logga in eller registrera dig. ", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Ogiltigt id för kategori", "invalid-tid": "Ogiltigt id för ämne", "invalid-pid": "Ogiltigt id för inlägg", @@ -68,6 +68,7 @@ "invalid-file": "Ogiltig fil", "uploads-are-disabled": "Uppladdningar är inaktiverat", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/sv/topic.json b/public/language/sv/topic.json index 40b81f0ec4..b581cea269 100644 --- a/public/language/sv/topic.json +++ b/public/language/sv/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Inga ämnen hittades!", "no_posts_found": "Inga inlägg hittades!", "post_is_deleted": "Det här inlägget är raderat.", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "Skapat av %1", "posted_by_guest": "Inlägg av anonym", diff --git a/public/language/sv/user.json b/public/language/sv/user.json index 2702388846..dd8f04d712 100644 --- a/public/language/sv/user.json +++ b/public/language/sv/user.json @@ -21,6 +21,7 @@ "watched": "Watched", "followers": "Följare", "following": "Följer", + "aboutme": "About me", "signature": "Signatur", "gravatar": "Gravatar", "birthday": "Födelsedag", diff --git a/public/language/th/error.json b/public/language/th/error.json index 1c33a57db0..a962e365f4 100644 --- a/public/language/th/error.json +++ b/public/language/th/error.json @@ -2,7 +2,7 @@ "invalid-data": "ข้อมูลไม่ถูกต้อง", "not-logged-in": "คุณยังไม่ได้ลงชื่อเข้าระบบ", "account-locked": "บัญชีของคุณถูกระงับการใช้งานชั่วคราว", - "search-requires-login": "ต้องลงทะเบียนบัญชีผู้ใช้สำหรับการค้นหา! โปรดลงชื่อเข้าระบบ หรือ ลงทะเบียน!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Category ID ไม่ถูกต้อง", "invalid-tid": "Topic ID ไม่ถูกต้อง", "invalid-pid": "Post ID ไม่ถูกต้อง", @@ -68,6 +68,7 @@ "invalid-file": "Invalid File", "uploads-are-disabled": "Uploads are disabled", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/th/topic.json b/public/language/th/topic.json index ea6a1a8998..15d1718498 100644 --- a/public/language/th/topic.json +++ b/public/language/th/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "ไม่พบกระทู้", "no_posts_found": "ไม่พบโพส", "post_is_deleted": "ลบ Post นี้เรียบร้อยแล้ว!", + "topic_is_deleted": "This topic is deleted!", "profile": "รายละเอียด", "posted_by": "โพสโดย %1", "posted_by_guest": "โพสโดย Guest", diff --git a/public/language/th/user.json b/public/language/th/user.json index f53b390dd7..15cd6fb01b 100644 --- a/public/language/th/user.json +++ b/public/language/th/user.json @@ -21,6 +21,7 @@ "watched": "ดูแล้ว", "followers": "คนติดตาม", "following": "ติดตาม", + "aboutme": "About me", "signature": "ลายเซ็น", "gravatar": "Gravatar", "birthday": "วันเกิด", diff --git a/public/language/tr/error.json b/public/language/tr/error.json index 49e7247239..b34823ccfd 100644 --- a/public/language/tr/error.json +++ b/public/language/tr/error.json @@ -2,7 +2,7 @@ "invalid-data": "Geçersiz Veri", "not-logged-in": "Giriş yapmamış görünüyorsunuz.", "account-locked": "Hesabınız geçici olarak kitlendi", - "search-requires-login": "Arama hesap gerektiriyor. Lütfen giriş yapın ya da kaydolun.", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Geçersiz Kategori ID", "invalid-tid": "Geçersiz Başlık ID", "invalid-pid": "Geçersiz İleti ID", @@ -68,6 +68,7 @@ "invalid-file": "Geçersiz Dosya", "uploads-are-disabled": "Yüklemeler kapalı", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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": "Ardı ardına çok fazla mesaj yolladınız, lütfen biraz bekleyiniz.", diff --git a/public/language/tr/topic.json b/public/language/tr/topic.json index ef6276ca31..9700a29663 100644 --- a/public/language/tr/topic.json +++ b/public/language/tr/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Hiç konu bulunamadı!", "no_posts_found": "Hiç bir ileti bulunamadı!", "post_is_deleted": "Bu ileti silinmiş!", + "topic_is_deleted": "This topic is deleted!", "profile": "Profil", "posted_by": "%1 tarafından gönderildi", "posted_by_guest": "Ziyaretçi tarafından yayımlandı", diff --git a/public/language/tr/user.json b/public/language/tr/user.json index 285cb3ebc5..b5edba6bbd 100644 --- a/public/language/tr/user.json +++ b/public/language/tr/user.json @@ -21,6 +21,7 @@ "watched": "İzlendi", "followers": "Takipçiler", "following": "Takip Ediyor", + "aboutme": "About me", "signature": "İmza", "gravatar": "Avatar", "birthday": "Doğum Tarihi", diff --git a/public/language/vi/error.json b/public/language/vi/error.json index 3aecae1d63..33da9ba7ce 100644 --- a/public/language/vi/error.json +++ b/public/language/vi/error.json @@ -2,7 +2,7 @@ "invalid-data": "Dữ liệu không hợp lệ", "not-logged-in": "Bạn chưa đăng nhập", "account-locked": "Tài khoản của bạn đang tạm thời bị khóa", - "search-requires-login": "Bạn cần đăng nhập để thực hiện việc tìm kiếm! Xin hãy đăng nhập hoặc đăng ký!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "Danh mục ID không hợp lệ", "invalid-tid": "ID chủ đề không hợp lệ", "invalid-pid": "ID bài viết không hợp lệ", @@ -68,6 +68,7 @@ "invalid-file": "File không hợp lệ", "uploads-are-disabled": "Đã khóa lựa chọn tải lên", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "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.", diff --git a/public/language/vi/topic.json b/public/language/vi/topic.json index 9d0ca5e82d..f2c2193892 100644 --- a/public/language/vi/topic.json +++ b/public/language/vi/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "Không tìm thấy chủ đề nào!", "no_posts_found": "Không tìm thấy bài gửi nào", "post_is_deleted": "Bài gửi này đã bị xóa!", + "topic_is_deleted": "This topic is deleted!", "profile": "Hồ sơ", "posted_by": "Được viết bởi %1", "posted_by_guest": "Đăng bởi khách", diff --git a/public/language/vi/user.json b/public/language/vi/user.json index d567c55285..5d60c007a1 100644 --- a/public/language/vi/user.json +++ b/public/language/vi/user.json @@ -21,6 +21,7 @@ "watched": "Đã theo dõi", "followers": "Số người theo dõi", "following": "Đang theo dõi", + "aboutme": "About me", "signature": "Chữ ký", "gravatar": "Gavatar", "birthday": "Ngày sinh ", diff --git a/public/language/zh_CN/error.json b/public/language/zh_CN/error.json index 934a7e3991..f461c9fa36 100644 --- a/public/language/zh_CN/error.json +++ b/public/language/zh_CN/error.json @@ -2,7 +2,7 @@ "invalid-data": "无效数据", "not-logged-in": "您还没有登陆。", "account-locked": "您的帐号已被临时锁定", - "search-requires-login": "搜索功能仅限会员使用!请先登录或者注册!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "无效版块 ID", "invalid-tid": "无效主题 ID", "invalid-pid": "无效帖子 ID", @@ -68,6 +68,7 @@ "invalid-file": "无效文件", "uploads-are-disabled": "上传已禁用", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "您不能和自己聊天!", "chat-restricted": "此用户限制了他的聊天消息。必须他先关注您,您才能和他聊天。", "too-many-messages": "您发送了太多消息,请稍等片刻。", diff --git a/public/language/zh_CN/topic.json b/public/language/zh_CN/topic.json index 9b113c0c90..0bbbc10a7b 100644 --- a/public/language/zh_CN/topic.json +++ b/public/language/zh_CN/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "没有找到主题!", "no_posts_found": "没有找到帖子!", "post_is_deleted": "此帖已被删除!", + "topic_is_deleted": "This topic is deleted!", "profile": "资料", "posted_by": "%1 发布", "posted_by_guest": "游客发布", diff --git a/public/language/zh_CN/user.json b/public/language/zh_CN/user.json index 583c03fd09..16fa062ce3 100644 --- a/public/language/zh_CN/user.json +++ b/public/language/zh_CN/user.json @@ -21,6 +21,7 @@ "watched": "已订阅", "followers": "粉丝", "following": "关注", + "aboutme": "About me", "signature": "签名档", "gravatar": "头像", "birthday": "生日", diff --git a/public/language/zh_TW/error.json b/public/language/zh_TW/error.json index 5c3e212270..d2f4f0806a 100644 --- a/public/language/zh_TW/error.json +++ b/public/language/zh_TW/error.json @@ -2,7 +2,7 @@ "invalid-data": "無效的資料", "not-logged-in": "您似乎還沒有登入喔!", "account-locked": "您的帳戶暫時被鎖定!", - "search-requires-login": "你需要一個帳戶才能搜索!請登錄或註冊!", + "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "無效的類別 ID", "invalid-tid": "無效的主題 ID", "invalid-pid": "無效的文章 ID", @@ -68,6 +68,7 @@ "invalid-file": "無效的檔案", "uploads-are-disabled": "上傳功能被停用", "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", + "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", "cant-chat-with-yourself": "你不能與自己聊天!", "chat-restricted": "此用戶已限制了他的聊天功能。你要在他關注你之後,才能跟他聊天", "too-many-messages": "You have sent too many messages, please wait awhile.", diff --git a/public/language/zh_TW/topic.json b/public/language/zh_TW/topic.json index a65ccc6833..71c592aea9 100644 --- a/public/language/zh_TW/topic.json +++ b/public/language/zh_TW/topic.json @@ -5,6 +5,7 @@ "no_topics_found": "沒有找到主題!", "no_posts_found": "找不到文章!", "post_is_deleted": "文章已被刪除!", + "topic_is_deleted": "This topic is deleted!", "profile": "資料", "posted_by": "由 %1 張貼", "posted_by_guest": "由訪客張貼", diff --git a/public/language/zh_TW/user.json b/public/language/zh_TW/user.json index 55163c4259..7296da0c9f 100644 --- a/public/language/zh_TW/user.json +++ b/public/language/zh_TW/user.json @@ -21,6 +21,7 @@ "watched": "觀看者", "followers": "跟隨者", "following": "正在關注", + "aboutme": "About me", "signature": "簽名", "gravatar": "Gravatar頭像", "birthday": "生日", From aa577f4adca2443dd1dc6165b4296289cdbba64c Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 19 May 2015 23:04:28 -0400 Subject: [PATCH 029/237] part 1 no upgrade script yet --- public/src/client/users.js | 73 +++++++++++++---------- src/controllers/users.js | 22 +++---- src/database/mongo/sorted.js | 24 ++++++++ src/database/redis/sorted.js | 10 ++++ src/groups.js | 21 ++----- src/socket.io/admin/user.js | 2 +- src/socket.io/user.js | 56 +++++++++++++++++- src/user/create.js | 9 ++- src/user/delete.js | 8 ++- src/user/profile.js | 17 +++++- src/user/search.js | 111 ++++++++--------------------------- 11 files changed, 202 insertions(+), 151 deletions(-) diff --git a/public/src/client/users.js b/public/src/client/users.js index eaa9467a00..efd589d42d 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -118,25 +118,18 @@ define('forum/users', ['translator'], function(translator) { var notify = $('#user-notfound-notify'); page = page || 1; + if (!username) { + return loadPage(page); + } + notify.html(''); - var filters = []; - $('.user-filter').each(function() { - var $this = $(this); - if($this.is(':checked')) { - filters.push({ - field:$this.attr('data-filter-field'), - type: $this.attr('data-filter-type'), - value: $this.attr('data-filter-value') - }); - } - }); socket.emit('user.search', { query: username, page: page, - searchBy: ['username', 'fullname'], + searchBy: 'username', sortBy: $('.search select').val(), - filterBy: filters + onlineOnly: $('.search .online-only').is(':checked') }, function(err, data) { if (err) { reset(); @@ -147,33 +140,49 @@ define('forum/users', ['translator'], function(translator) { return reset(); } - templates.parse('partials/paginator', {pagination: data.pagination}, function(html) { - $('.pagination-container').replaceWith(html); - }); + renderSearchResults(data); + }); + } - templates.parse('users', 'users', data, function(html) { - translator.translate(html, function(translated) { - $('#users-container').html(translated); - if (!data.users.length) { - translator.translate('[[error:no-user]]', function(translated) { - notify.html(translated); - notify.parent().removeClass('btn-success label-success').addClass('btn-warning label-warning'); - }); - } else { - translator.translate('[[users:users-found-search-took, ' + data.matchCount + ', ' + data.timing + ']]', function(translated) { - notify.html(translated); - notify.parent().removeClass('btn-warning label-warning').addClass('btn-success label-success'); - }); - } - }); + function loadPage(page) { + socket.emit('user.loadPage', {page: page, sortBy: $('.search select').val(), onlineOnly: $('.search .online-only').is(':checked')}, function(err, data) { + if (err) { + return app.alertError(err.message); + } + + renderSearchResults(data); + }); + } + + function renderSearchResults(data) { + var notify = $('#user-notfound-notify'); + templates.parse('partials/paginator', {pagination: data.pagination}, function(html) { + $('.pagination-container').replaceWith(html); + }); + + templates.parse('users', 'users', data, function(html) { + translator.translate(html, function(translated) { + $('#users-container').html(translated); + + if (!data.users.length) { + translator.translate('[[error:no-user]]', function(translated) { + notify.html(translated); + notify.parent().removeClass('btn-success label-success').addClass('btn-warning label-warning'); + }); + } else { + translator.translate('[[users:users-found-search-took, ' + data.matchCount + ', ' + data.timing + ']]', function(translated) { + notify.html(translated); + notify.parent().removeClass('btn-warning label-warning').addClass('btn-success label-success'); + }); + } }); }); } function onUserStatusChange(data) { var section = getActiveSection(); - + if ((section.startsWith('online') || section.startsWith('users'))) { updateUser(data); } diff --git a/src/controllers/users.js b/src/controllers/users.js index 29dd552b87..2c837b2861 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -48,26 +48,26 @@ usersController.getOnlineUsers = function(req, res, next) { }; usersController.getUsersSortedByPosts = function(req, res, next) { - usersController.getUsers('users:postcount', 50, req, res, next); + usersController.getUsers('users:postcount', 0, 49, req, res, next); }; usersController.getUsersSortedByReputation = function(req, res, next) { - usersController.getUsers('users:reputation', 50, req, res, next); + usersController.getUsers('users:reputation', 0, 49, req, res, next); }; usersController.getUsersSortedByJoinDate = function(req, res, next) { - usersController.getUsers('users:joindate', 50, req, res, next); + usersController.getUsers('users:joindate', 0, 49, req, res, next); }; -usersController.getUsers = function(set, count, req, res, next) { - getUsersAndCount(set, req.uid, count, function(err, data) { +usersController.getUsers = function(set, start, stop, req, res, next) { + usersController.getUsersAndCount(set, req.uid, start, stop, function(err, data) { if (err) { return next(err); } var pageCount = Math.ceil(data.count / (parseInt(meta.config.userSearchResultsPerPage, 10) || 20)); var userData = { search_display: 'hidden', - loadmore_display: data.count > count ? 'block' : 'hide', + loadmore_display: data.count > (stop - start + 1) ? 'block' : 'hide', users: data.users, pagination: pagination.create(1, pageCount) }; @@ -76,13 +76,13 @@ usersController.getUsers = function(set, count, req, res, next) { }); }; -function getUsersAndCount(set, uid, count, callback) { +usersController.getUsersAndCount = function(set, uid, start, stop, callback) { async.parallel({ users: function(next) { - user.getUsersFromSet(set, uid, 0, count - 1, next); + user.getUsersFromSet(set, uid, start, stop, next); }, count: function(next) { - db.getObjectField('global', 'userCount', next); + db.sortedSetCard(set, next); } }, function(err, results) { if (err) { @@ -94,7 +94,7 @@ function getUsersAndCount(set, uid, count, callback) { callback(null, results); }); -} +}; usersController.getUsersForSearch = function(req, res, next) { if (!req.uid) { @@ -102,7 +102,7 @@ usersController.getUsersForSearch = function(req, res, next) { } var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; - getUsersAndCount('users:joindate', req.uid, resultsPerPage, function(err, data) { + usersController.getUsersAndCount('users:joindate', req.uid, 0, resultsPerPage - 1, function(err, data) { if (err) { return next(err); } diff --git a/src/database/mongo/sorted.js b/src/database/mongo/sorted.js index 1d8f992ab9..fddda44388 100644 --- a/src/database/mongo/sorted.js +++ b/src/database/mongo/sorted.js @@ -509,4 +509,28 @@ module.exports = function(db, module) { callback(err, result && result.value ? result.value.score : null); }); }; + + module.getSortedSetRangeByLex = function(key, min, max, start, count, callback) { + var query = {_key: key}; + if (min !== '-') { + query.value = {$gte: min}; + } + if (max !== '+') { + query.value = query.value || {}; + query.value.$lte = max; + } + db.collection('objects').find(query, {_id: 0, value: 1}) + .sort({value: 1}) + .skip(start) + .limit(count === -1 ? 0 : count) + .toArray(function(err, data) { + if (err) { + return callback(err); + } + data = data.map(function(item) { + return item && item.value; + }); + callback(err, data); + }); + }; }; \ No newline at end of file diff --git a/src/database/redis/sorted.js b/src/database/redis/sorted.js index 195d9feec8..8d9b35896d 100644 --- a/src/database/redis/sorted.js +++ b/src/database/redis/sorted.js @@ -246,4 +246,14 @@ module.exports = function(redisClient, module) { module.sortedSetIncrBy = function(key, increment, value, callback) { redisClient.zincrby(key, increment, value, callback); }; + + module.getSortedSetRangeByLex = function(key, min, max, start, count, callback) { + if (min !== '-') { + min = '[' + min; + } + if (max !== '+') { + max = '(' + max; + } + redisClient.zrangebylex([key, min, max, 'LIMIT', start, count], callback); + }; }; \ No newline at end of file diff --git a/src/groups.js b/src/groups.js index b46b23aca5..c6db87f3c3 100644 --- a/src/groups.js +++ b/src/groups.js @@ -1144,7 +1144,7 @@ var async = require('async'), Groups.searchMembers = function(data, callback) { - function findUids(query, searchBy, startsWith, callback) { + function findUids(query, searchBy, callback) { if (!query) { return Groups.getMembers(data.groupName, 0, -1, callback); } @@ -1154,25 +1154,16 @@ var async = require('async'), Groups.getMembers(data.groupName, 0, -1, next); }, function(members, next) { - user.getMultipleUserFields(members, ['uid'].concat(searchBy), next); + user.getMultipleUserFields(members, ['uid'].concat([searchBy]), next); }, function(users, next) { var uids = []; - - for(var k=0; k 1) { - uids = uids.filter(function(uid, index, array) { - return array.indexOf(uid) === index; - }); - } - next(null, uids); } ], callback); diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index 454a51741a..60494ca6e1 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -205,7 +205,7 @@ User.deleteUsers = function(socket, uids, callback) { }; User.search = function(socket, data, callback) { - user.search({query: data.query, searchBy: data.searchBy, startsWith: false, uid: socket.uid}, function(err, searchData) { + user.search({query: data.query, searchBy: data.searchBy, 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 65af901b08..8a954faeaf 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -77,7 +77,7 @@ SocketUser.search = function(socket, data, callback) { page: data.page, searchBy: data.searchBy, sortBy: data.sortBy, - filterBy: data.filterBy, + onlineOnly: data.onlineOnly, uid: socket.uid }, callback); }; @@ -431,6 +431,60 @@ SocketUser.loadMore = function(socket, data, callback) { }); }; +SocketUser.loadPage = function(socket, data, callback) { + function done(err, result) { + if (err) { + return callback(err); + } + var pageCount = Math.ceil(result.count / resultsPerPage); + var userData = { + users: result.users, + pagination: pagination.create(data.page, pageCount) + }; + + callback(null, userData); + } + + var controllers = require('../controllers/users'); + var pagination = require('../pagination'); + var set = ''; + data.sortBy = data.sortBy || 'joindate'; + + var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; + var start = Math.max(0, data.page - 1) * resultsPerPage; + var stop = start + resultsPerPage - 1; + if (data.onlineOnly) { + async.parallel({ + users: function(next) { + user.getUsersFromSet('users:online', socket.uid, 0, 49, next); + }, + count: function(next) { + var now = Date.now(); + db.sortedSetCount('users:online', now - 300000, now, next); + } + }, done); + } else if (data.sortBy === 'username') { + async.parallel({ + count: function(next) { + db.sortedSetCard('username:sorted', next); + }, + users: function(next) { + db.getSortedSetRangeByLex('username:sorted', '-', '+', start, stop - start + 1, function(err, result) { + if (err) { + return next(err); + } + var uids = result.map(function(user) { + return user && user.split(':')[1]; + }); + user.getUsers(uids, socket.uid, next); + }); + } + }, done); + } else { + controllers.getUsersAndCount('users:joindate', socket.uid, start, stop, done); + } +}; + SocketUser.setStatus = function(socket, status, callback) { if (!socket.uid) { return callback(new Error('[[error:invalid-uid]]')); diff --git a/src/user/create.js b/src/user/create.js index 2580a738f1..9ce768b9ef 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -93,6 +93,9 @@ module.exports = function(User) { function(next) { db.sortedSetAdd('username:uid', userData.uid, userData.username, next); }, + function(next) { + db.sortedSetAdd('username:sorted', 0, userData.username.toLowerCase() + ':' + userData.uid, next); + }, function(next) { db.sortedSetAdd('userslug:uid', userData.uid, userData.userslug, next); }, @@ -107,7 +110,11 @@ module.exports = function(User) { }, function(next) { if (userData.email) { - db.sortedSetAdd('email:uid', userData.uid, userData.email.toLowerCase(), next); + async.parallel([ + async.apply(db.sortedSetAdd, 'email:uid', userData.uid, userData.email.toLowerCase()), + async.apply(db.sortedSetAdd, 'email:sorted', 0, userData.email.toLowerCase() + ':' + userData.uid) + ], next); + if (parseInt(userData.uid, 10) !== 1 && parseInt(meta.config.requireEmailConfirmation, 10) === 1) { User.email.sendValidationEmail(userData.uid, userData.email); } diff --git a/src/user/delete.js b/src/user/delete.js index 2d06caf745..2558399134 100644 --- a/src/user/delete.js +++ b/src/user/delete.js @@ -51,6 +51,9 @@ module.exports = function(User) { function(next) { db.sortedSetRemove('username:uid', userData.username, next); }, + function(next) { + db.sortedSetRemove('username:sorted', userData.username.toLowerCase() + ':' + uid, next); + }, function(next) { db.sortedSetRemove('userslug:uid', userData.userslug, next); }, @@ -59,7 +62,10 @@ module.exports = function(User) { }, function(next) { if (userData.email) { - db.sortedSetRemove('email:uid', userData.email.toLowerCase(), next); + async.parallel([ + async.apply(db.sortedSetRemove, 'email:uid', userData.email.toLowerCase()), + async.apply(db.sortedSetRemove, 'email:sorted', userData.email.toLowerCase() + ':' + uid) + ], next); } else { next(); } diff --git a/src/user/profile.js b/src/user/profile.js index d10aba66db..db0ce9029b 100644 --- a/src/user/profile.js +++ b/src/user/profile.js @@ -164,8 +164,10 @@ module.exports = function(User) { if (userData.email === newEmail) { return callback(); } - - db.sortedSetRemove('email:uid', userData.email.toLowerCase(), function(err) { + async.series([ + async.apply(db.sortedSetRemove, 'email:uid', userData.email.toLowerCase()), + async.apply(db.sortedSetRemove, 'email:sorted', userData.email.toLowerCase() + ':' + uid) + ], function(err) { if (err) { return callback(err); } @@ -178,6 +180,9 @@ module.exports = function(User) { function(next) { db.sortedSetAdd('email:uid', uid, newEmail.toLowerCase(), next); }, + function(next) { + db.sortedSetAdd('email:sorted', 0, newEmail.toLowerCase() + ':' + uid, next); + }, function(next) { User.setUserField(uid, 'email', newEmail, next); }, @@ -216,7 +221,13 @@ module.exports = function(User) { function(next) { var newUserslug = utils.slugify(newUsername); updateUidMapping('userslug', uid, newUserslug, userData.userslug, next); - } + }, + function(next) { + async.series([ + async.apply(db.sortedSetRemove, 'username:sorted', userData.username.toLowerCase() + ':' + uid), + async.apply(db.sortedSetAdd, 'username:sorted', 0, newUsername.toLowerCase() + ':' + uid) + ], next); + }, ], callback); }); } diff --git a/src/user/search.js b/src/user/search.js index ce1ad0c6b2..43697791be 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -11,8 +11,7 @@ module.exports = function(User) { User.search = function(data, callback) { var query = data.query || ''; - var searchBy = data.searchBy || ['username']; - var startsWith = data.hasOwnProperty('startsWith') ? data.startsWith : true; + var searchBy = data.searchBy || 'username'; var page = data.page || 1; var uid = data.uid || 0; var paginate = data.hasOwnProperty('paginate') ? data.paginate : true; @@ -27,14 +26,13 @@ module.exports = function(User) { async.waterfall([ function(next) { if (data.findUids) { - data.findUids(query, searchBy, startsWith, next); + data.findUids(query, searchBy, next); } else { - findUids(query, searchBy, startsWith, next); + findUids(query, searchBy, next); } }, function(uids, next) { - var filterBy = Array.isArray(data.filterBy) ? data.filterBy : []; - filterAndSortUids(uids, filterBy, data.sortBy, next); + filterAndSortUids(uids, data, next); }, function(uids, next) { plugins.fireHook('filter:users.search', {uids: uids, uid: uid}, next); @@ -75,70 +73,39 @@ module.exports = function(User) { }; }; - function findUids(query, searchBy, startsWith, callback) { + function findUids(query, searchBy, callback) { if (!query) { - return db.getSortedSetRevRange('users:joindate', 0, -1, callback); + return callback(null, []); } + var min = query; + var max = query.substr(0, query.length - 1) + String.fromCharCode(query.charCodeAt(query.length - 1) + 1); - var keys = searchBy.map(function(searchBy) { - return searchBy + ':uid'; - }); + var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; + var hardCap = resultsPerPage * 10; - async.map(keys, function(key, next) { - db.getSortedSetRangeWithScores(key, 0, -1, next); - }, function(err, hashes) { - if (err || !hashes) { - return callback(err, []); - } - - hashes = hashes.filter(Boolean); - - query = query.toLowerCase(); - - var uids = []; - var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; - var hardCap = resultsPerPage * 10; - - for (var i=0; i= hardCap) { - break; - } - } - } - if (uids.length >= hardCap) { - break; - } - } - - if (hashes.length > 1) { - uids = uids.filter(function(uid, index, array) { - return array.indexOf(uid) === index; - }); + db.getSortedSetRangeByLex(searchBy + ':sorted', min, max, 0, hardCap, function(err, data) { + if (err) { + return callback(err); } + var uids = data.map(function(data) { + return data.split(':')[1]; + }); callback(null, uids); }); } - function filterAndSortUids(uids, filterBy, sortBy, callback) { - sortBy = sortBy || 'joindate'; + function filterAndSortUids(uids, data, callback) { + var sortBy = data.sortBy || 'joindate'; - var fields = filterBy.map(function(filter) { - return filter.field; - }).concat(['uid', sortBy]).filter(function(field, index, array) { - return array.indexOf(field) === index; - }); + var fields = ['uid', 'status', sortBy]; async.parallel({ userData: function(next) { User.getMultipleUserFields(uids, fields, next); }, isOnline: function(next) { - if (fields.indexOf('status') !== -1) { + if (data.onlineOnly) { require('../socket.io').isUsersOnline(uids, next); } else { next(); @@ -148,53 +115,25 @@ module.exports = function(User) { if (err) { return callback(err); } + var userData = results.userData; - if (results.isOnline) { - userData.forEach(function(userData, index) { - userData.status = User.getStatus(userData.status, results.isOnline[index]); + if (data.onlineOnly) { + userData = userData.filter(function(user, index) { + return user && user.status !== 'offline' && results.isOnline[index]; }); } - userData = filterUsers(userData, filterBy); - sortUsers(userData, sortBy); uids = userData.map(function(user) { return user && user.uid; }); + callback(null, uids); }); } - function filterUsers(userData, filterBy) { - function passesFilter(user, filter) { - if (!user || !filter) { - return false; - } - var userValue = user[filter.field]; - if (filter.type === '=') { - return userValue === filter.value; - } else if (filter.type === '!=') { - return userValue !== filter.value; - } - return false; - } - - if (!filterBy.length) { - return userData; - } - - return userData.filter(function(user) { - for(var i=0; i Date: Tue, 19 May 2015 23:07:01 -0400 Subject: [PATCH 030/237] check error fix ip --- src/socket.io/user.js | 4 ++++ src/user/search.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 8a954faeaf..4cff6ff7f1 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -445,6 +445,10 @@ SocketUser.loadPage = function(socket, data, callback) { callback(null, userData); } + if (!data || !data.page) { + return callback(new Error('[[error:invalid-data]]')); + } + var controllers = require('../controllers/users'); var pagination = require('../pagination'); var set = ''; diff --git a/src/user/search.js b/src/user/search.js index 43697791be..e78a932106 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -16,7 +16,7 @@ module.exports = function(User) { var uid = data.uid || 0; var paginate = data.hasOwnProperty('paginate') ? data.paginate : true; - if (searchBy.indexOf('ip') !== -1) { + if (searchBy === 'ip') { return searchByIP(query, uid, callback); } From fbdae8fe1de873b93cecc127c6f23046b24dd938 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 19 May 2015 23:13:53 -0400 Subject: [PATCH 031/237] return time and matchcount on page switch --- public/src/client/users.js | 16 +++++++++------- src/socket.io/user.js | 4 +++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/public/src/client/users.js b/public/src/client/users.js index efd589d42d..eb400ad2c8 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -109,11 +109,6 @@ define('forum/users', ['translator'], function(translator) { } function doSearch(page) { - function reset() { - notify.html(''); - notify.parent().removeClass('btn-warning label-warning btn-success label-success'); - } - var username = $('#search-user').val(); var notify = $('#user-notfound-notify'); page = page || 1; @@ -132,21 +127,28 @@ define('forum/users', ['translator'], function(translator) { onlineOnly: $('.search .online-only').is(':checked') }, function(err, data) { if (err) { - reset(); + resetSearchNotify(); return app.alertError(err.message); } if (!data) { - return reset(); + return resetSearchNotify(); } renderSearchResults(data); }); } + function resetSearchNotify() { + var notify = $('#user-notfound-notify'); + notify.html(''); + notify.parent().removeClass('btn-warning label-warning btn-success label-success'); + } + function loadPage(page) { socket.emit('user.loadPage', {page: page, sortBy: $('.search select').val(), onlineOnly: $('.search .online-only').is(':checked')}, function(err, data) { + resetSearchNotify(); if (err) { return app.alertError(err.message); } diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 4cff6ff7f1..a6cfdd2481 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -438,6 +438,8 @@ SocketUser.loadPage = function(socket, data, callback) { } var pageCount = Math.ceil(result.count / resultsPerPage); var userData = { + matchCount: result.users.length, + timing: (process.elapsedTimeSince(startTime) / 1000).toFixed(2), users: result.users, pagination: pagination.create(data.page, pageCount) }; @@ -448,7 +450,7 @@ SocketUser.loadPage = function(socket, data, callback) { if (!data || !data.page) { return callback(new Error('[[error:invalid-data]]')); } - + var startTime = process.hrtime(); var controllers = require('../controllers/users'); var pagination = require('../pagination'); var set = ''; From fd817e865ec878b2f3800562e4dc7bc79a1aacd1 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Tue, 19 May 2015 23:24:33 -0400 Subject: [PATCH 032/237] added pagecount --- src/socket.io/user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/socket.io/user.js b/src/socket.io/user.js index a6cfdd2481..5ae2fdda2b 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -441,7 +441,8 @@ SocketUser.loadPage = function(socket, data, callback) { matchCount: result.users.length, timing: (process.elapsedTimeSince(startTime) / 1000).toFixed(2), users: result.users, - pagination: pagination.create(data.page, pageCount) + pagination: pagination.create(data.page, pageCount), + pageCount: pageCount }; callback(null, userData); From 671db1681ecf477e5768b3d338f704df8e64c77b Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 20 May 2015 09:57:04 -0400 Subject: [PATCH 033/237] allowing usage of "false" in silent and daemon environment variables --- loader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/loader.js b/loader.js index 5baf636dbf..c79756f09e 100644 --- a/loader.js +++ b/loader.js @@ -17,7 +17,7 @@ nconf.argv().env().file({ var pidFilePath = __dirname + '/pidfile', output = logrotate({ file: __dirname + '/logs/output.log', size: '1m', keep: 3, compress: true }), - silent = nconf.get('silent') !== false, + silent = nconf.get('silent') === 'false' ? false : nconf.get('silent') !== false, numProcs, workers = [], @@ -248,7 +248,7 @@ Loader.notifyWorkers = function(msg, worker_pid) { fs.open(path.join(__dirname, 'config.json'), 'r', function(err) { if (!err) { - if (nconf.get('daemon') !== false) { + if (nconf.get('daemon') !== 'false' && nconf.get('daemon') !== false) { if (fs.existsSync(pidFilePath)) { try { var pid = fs.readFileSync(pidFilePath, { encoding: 'utf-8' }); From 972ae42d913dcc0687c327a2142c18ee067e085a Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 20 May 2015 11:44:10 -0400 Subject: [PATCH 034/237] pruned upgrade scripts in preparation for 0.7.0, ping @barisusakli --- src/upgrade.js | 753 +------------------------------------------------ 1 file changed, 1 insertion(+), 752 deletions(-) diff --git a/src/upgrade.js b/src/upgrade.js index 47fd8badc0..d41c963a73 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -17,7 +17,7 @@ var db = require('./database'), Upgrade = {}, - minSchemaDate = Date.UTC(2014, 9, 22), // This value gets updated every new MINOR version + minSchemaDate = Date.UTC(2015, 1, 8), // This value gets updated every new MINOR version schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema @@ -72,757 +72,6 @@ Upgrade.upgrade = function(callback) { } }); }, - function(next) { - thisSchemaDate = Date.UTC(2014, 9, 31); - if (schemaDate < thisSchemaDate) { - updatesMade = true; - winston.info('[2014/10/31] Applying newbiePostDelay values'); - - async.series([ - async.apply(Meta.configs.setOnEmpty, 'newbiePostDelay', '120'), - async.apply(Meta.configs.setOnEmpty, 'newbiePostDelayThreshold', '3') - ], function(err) { - if (err) { - winston.error('[2014/10/31] Error encountered while Applying newbiePostDelay values'); - return next(err); - } - winston.info('[2014/10/31] Applying newbiePostDelay values done'); - Upgrade.update(thisSchemaDate, next); - }); - } else { - winston.info('[2014/10/31] Applying newbiePostDelay values skipped'); - next(); - } - }, - function(next) { - thisSchemaDate = Date.UTC(2014, 10, 6, 18, 30); - if (schemaDate < thisSchemaDate) { - updatesMade = true; - winston.info('[2014/11/6] Updating topic authorship sorted set'); - - async.waterfall([ - async.apply(db.getObjectField, 'global', 'nextTid'), - function(nextTid, next) { - var tids = []; - for(var x=1,numTids=nextTid-1;x Date: Wed, 20 May 2015 16:08:22 -0400 Subject: [PATCH 035/237] upgrade script --- src/controllers/users.js | 2 +- src/upgrade.js | 47 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/controllers/users.js b/src/controllers/users.js index 2c837b2861..f82e486900 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -82,7 +82,7 @@ usersController.getUsersAndCount = function(set, uid, start, stop, callback) { user.getUsersFromSet(set, uid, start, stop, next); }, count: function(next) { - db.sortedSetCard(set, next); + db.getObjectField('global', 'userCount', next); } }, function(err, results) { if (err) { diff --git a/src/upgrade.js b/src/upgrade.js index d41c963a73..c37bc2b7e6 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, 4, 11); + latestSchema = Date.UTC(2015, 4, 20); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -333,6 +333,51 @@ Upgrade.upgrade = function(callback) { winston.info('[2015/05/11] Updating widgets to tjs 0.2x skipped'); next(); } + }, + function(next) { + function upgradeSet(set, callback) { + db.getSortedSetRangeWithScores(set + ':uid', 0, -1, function(err, userData) { + if (err) { + return callback(err); + } + var index = 0; + async.eachLimit(userData, 500, function(userData, next) { + console.log(index++); + if (userData && userData.value) { + db.sortedSetAdd(set + ':sorted', 0, userData.value.toLowerCase() + ':' + userData.score, next); + } else { + next(); + } + }, function(err) { + callback(err); + }); + }); + } + + thisSchemaDate = Date.UTC(2015, 4, 20); + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.info('[2015/05/20] Adding username:sorted and email:sorted'); + + async.series([ + function(next) { + upgradeSet('username', next); + }, + function(next) { + upgradeSet('email', next); + } + ], function(err) { + if (err) { + return next(err); + } + + winston.info('[2015/05/20] Added username:sorted and email:sorted'); + Upgrade.update(thisSchemaDate, next); + }); + } else { + winston.info('[2015/05/20] Adding username:sorted and email:sorted skipped'); + next(); + } } // Add new schema updates here From 4f37d268b618b23fb0c989e782b20093776dec1f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 20 May 2015 16:36:26 -0400 Subject: [PATCH 036/237] removed sort by username --- public/src/client/users.js | 2 +- src/socket.io/user.js | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/public/src/client/users.js b/public/src/client/users.js index eb400ad2c8..9f440470b6 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -147,7 +147,7 @@ define('forum/users', ['translator'], function(translator) { function loadPage(page) { - socket.emit('user.loadPage', {page: page, sortBy: $('.search select').val(), onlineOnly: $('.search .online-only').is(':checked')}, function(err, data) { + socket.emit('user.loadSearchPage', {page: page, onlineOnly: $('.search .online-only').is(':checked')}, function(err, data) { resetSearchNotify(); if (err) { return app.alertError(err.message); diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 5ae2fdda2b..af4d5ca3b4 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -454,8 +454,6 @@ SocketUser.loadPage = function(socket, data, callback) { var startTime = process.hrtime(); var controllers = require('../controllers/users'); var pagination = require('../pagination'); - var set = ''; - data.sortBy = data.sortBy || 'joindate'; var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20; var start = Math.max(0, data.page - 1) * resultsPerPage; @@ -470,23 +468,6 @@ SocketUser.loadPage = function(socket, data, callback) { db.sortedSetCount('users:online', now - 300000, now, next); } }, done); - } else if (data.sortBy === 'username') { - async.parallel({ - count: function(next) { - db.sortedSetCard('username:sorted', next); - }, - users: function(next) { - db.getSortedSetRangeByLex('username:sorted', '-', '+', start, stop - start + 1, function(err, result) { - if (err) { - return next(err); - } - var uids = result.map(function(user) { - return user && user.split(':')[1]; - }); - user.getUsers(uids, socket.uid, next); - }); - } - }, done); } else { controllers.getUsersAndCount('users:joindate', socket.uid, start, stop, done); } From 3341fc56446981cb433aea197fb6a223763e4060 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Wed, 20 May 2015 16:39:33 -0400 Subject: [PATCH 037/237] fix method name --- 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 af4d5ca3b4..3c9575f9ec 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -431,7 +431,7 @@ SocketUser.loadMore = function(socket, data, callback) { }); }; -SocketUser.loadPage = function(socket, data, callback) { +SocketUser.loadSearchPage = function(socket, data, callback) { function done(err, result) { if (err) { return callback(err); From 927971b392036da979fcca1bc4e824466ace76a6 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 20 May 2015 17:40:08 -0400 Subject: [PATCH 038/237] added hooks for following/follower retrieval --- src/user/follow.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/user/follow.js b/src/user/follow.js index fc776bcef8..34efbf8149 100644 --- a/src/user/follow.js +++ b/src/user/follow.js @@ -2,6 +2,7 @@ 'use strict'; var async = require('async'), + plugins = require('../plugins'), db = require('./../database'); module.exports = function(User) { @@ -54,24 +55,31 @@ module.exports = function(User) { } User.getFollowing = function(uid, start, stop, callback) { - getFollow(uid, 'following:' + uid, start, stop, callback); + getFollow(uid, 'following', start, stop, callback); }; User.getFollowers = function(uid, start, stop, callback) { - getFollow(uid, 'followers:' + uid, start, stop, callback); + getFollow(uid, 'followers', start, stop, callback); }; - function getFollow(uid, set, start, stop, callback) { + function getFollow(uid, type, start, stop, callback) { if (!parseInt(uid, 10)) { return callback(null, []); } - db.getSortedSetRevRange(set, start, stop, function(err, uids) { + db.getSortedSetRevRange(type + ':' + uid, start, stop, function(err, uids) { if (err) { return callback(err); } - User.getUsers(uids, uid, callback); + plugins.fireHook('filter:user.' + type, { + uids: uids, + uid: uid, + start: start, + stop: stop + }, function(err, data) { + User.getUsers(data.uids, uid, callback); + }); }); } From 8414e31730486743846087941534e7099d9da9bc Mon Sep 17 00:00:00 2001 From: Timothy Fike Date: Wed, 20 May 2015 21:41:36 -0400 Subject: [PATCH 039/237] Fix specificity on panel heading. Needs to be specific so I can put an accordion inside. :sunglasses: --- public/src/admin/extend/widgets.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/src/admin/extend/widgets.js b/public/src/admin/extend/widgets.js index b57453ffab..4e8d3160aa 100644 --- a/public/src/admin/extend/widgets.js +++ b/public/src/admin/extend/widgets.js @@ -58,9 +58,9 @@ define('admin/extend/widgets', function() { panel.remove(); } }); - }).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'); + }).on('mouseup', '> .panel > .panel-heading', function(evt) { + if ( !( $(this).parent().is('.ui-sortable-helper') || $(evt.target).closest('.delete-widget').length ) ) { + $(this).parent().children('.panel-body').toggleClass('hidden'); } }); From 22e227a6cd7f916f3511a2f32ecade000f4e9675 Mon Sep 17 00:00:00 2001 From: "Ole R." Date: Thu, 21 May 2015 15:38:19 +0200 Subject: [PATCH 040/237] fixed error-report within translator.js reported by [rex-huang](https://community.nodebb.org/user/rex-huang), see https://community.nodebb.org/topic/4520/error-handling-is-wrong-in-translator-js --- public/src/modules/translator.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/public/src/modules/translator.js b/public/src/modules/translator.js index ac3be2728e..689f3c8d2e 100644 --- a/public/src/modules/translator.js +++ b/public/src/modules/translator.js @@ -283,11 +283,12 @@ } try { - callback(JSON.parse(data.toString())); + data = JSON.parse(data.toString()); } catch (e) { winston.error('Could not parse `' + filename + '.json`, syntax error? Skipping...'); - callback({}); + data = {}; } + callback(data); }); } @@ -307,4 +308,4 @@ typeof exports === 'object' ? exports : typeof define === 'function' && define.amd ? {} : translator = {} -); \ No newline at end of file +); From 58b0b6011f4edbecc8547e5b3c8dc6069fee893d Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 21 May 2015 10:07:00 -0400 Subject: [PATCH 041/237] removed console.log from upgrade script (@barisusakli :rage2:) --- src/upgrade.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/upgrade.js b/src/upgrade.js index c37bc2b7e6..6399a4ff32 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -342,7 +342,6 @@ Upgrade.upgrade = function(callback) { } var index = 0; async.eachLimit(userData, 500, function(userData, next) { - console.log(index++); if (userData && userData.value) { db.sortedSetAdd(set + ':sorted', 0, userData.value.toLowerCase() + ':' + userData.score, next); } else { From 830e1a7a3d8199ebff67ae8cfc3987571f079468 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 21 May 2015 11:15:34 -0400 Subject: [PATCH 042/237] fixed issue where privileges were not correctly determined if you were granted moderator access to a category as a group (vs as a single user) --- src/user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/user.js b/src/user.js index ff8f6fbb36..85c025ab63 100644 --- a/src/user.js +++ b/src/user.js @@ -441,7 +441,7 @@ var async = require('async'), if (Array.isArray(uid)) { async.parallel([ async.apply(groups.isMembers, uid, 'cid:' + cid + ':privileges:mods'), - async.apply(groups.isMembers, uid, 'cid:' + cid + ':privileges:groups:moderate') + async.apply(groups.isMembersOfGroupList, uid, 'cid:' + cid + ':privileges:groups:moderate') ], function(err, checks) { var isModerator = checks[0].map(function(isMember, idx) { return isMember || checks[1][idx]; @@ -451,7 +451,7 @@ var async = require('async'), } else { async.parallel([ async.apply(groups.isMember, uid, 'cid:' + cid + ':privileges:mods'), - async.apply(groups.isMember, uid, 'cid:' + cid + ':privileges:groups:moderate') + async.apply(groups.isMemberOfGroupList, uid, 'cid:' + cid + ':privileges:groups:moderate') ], function(err, checks) { var isModerator = checks[0] || checks[1]; filterIsModerator(null, isModerator); From aae3ac6b9840d19b4762d699a60cf6d689c239a6 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 21 May 2015 12:07:46 -0400 Subject: [PATCH 043/237] updated title parsing methods to call a new hook: filter:parse.title --- src/meta/title.js | 43 ++++++++++++++++++++++++++---------- src/middleware/middleware.js | 4 ++-- src/socket.io/meta.js | 4 ++-- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/meta/title.js b/src/meta/title.js index 7522dbe3a7..c33348ab4e 100644 --- a/src/meta/title.js +++ b/src/meta/title.js @@ -3,6 +3,7 @@ var winston = require('winston'), validator = require('validator'), user = require('../user'), + plugins = require('../plugins'), translator = require('../../public/src/modules/translator'); module.exports = function(Meta) { @@ -15,7 +16,7 @@ module.exports = function(Meta) { isUserPage: /^user\/[^\/]+(\/[\w]+)?/ }; - Meta.title.build = function (urlFragment, language, locals, callback) { + Meta.title.build = function (urlFragment, language, callback) { var uri = ''; var fallbackTitle = validator.escape(Meta.config.browserTitle || Meta.config.title || 'NodeBB'); try { @@ -25,7 +26,7 @@ module.exports = function(Meta) { return callback(null, fallbackTitle); } - Meta.title.parseFragment(uri, language, locals, function(err, title) { + Meta.title.parseFragment(uri, language, function(err, title) { if (err) { title = fallbackTitle; } else { @@ -39,29 +40,47 @@ module.exports = function(Meta) { }); }; - Meta.title.parseFragment = function (urlFragment, language, locals, callback) { - var translated = ['', 'recent', 'unread', 'users', 'notifications', 'popular', 'tags']; + Meta.title.parseFragment = function (urlFragment, language, callback) { + var translated = ['', 'recent', 'unread', 'users', 'notifications', 'popular', 'tags'], + onParsed = function(err, translated) { + if (err) { + return callback(err); + } + + plugins.fireHook('filter:parse.title', { + fragment: urlFragment, + language: language, + parsed: translated + }, function(err, data) { + if (err) { + return callback(err); + } + + callback(null, data.parsed); + }); + }; + if (translated.indexOf(urlFragment) !== -1) { if (!urlFragment.length) { urlFragment = 'home'; } translator.translate('[[pages:' + urlFragment + ']]', language, function(translated) { - callback(null, translated); + onParsed(null, translated); }); } else if (tests.isCategory.test(urlFragment)) { var cid = urlFragment.match(/category\/(\d+)/)[1]; - require('../categories').getCategoryField(cid, 'name', callback); + require('../categories').getCategoryField(cid, 'name', onParsed); } else if (tests.isTopic.test(urlFragment)) { var tid = urlFragment.match(/topic\/(\d+)/)[1]; - require('../topics').getTopicField(tid, 'title', callback); + require('../topics').getTopicField(tid, 'title', onParsed); } else if (tests.isTag.test(urlFragment)) { var tag = urlFragment.match(/tags\/([\s\S]+)/)[1]; translator.translate('[[pages:tag, ' + tag + ']]', language, function(translated) { - callback(null, translated); + onParsed(null, translated); }); } else if (tests.isUserPage.test(urlFragment)) { var matches = urlFragment.match(/user\/([^\/]+)\/?([\w]+)?/), @@ -70,7 +89,7 @@ module.exports = function(Meta) { user.getUsernameByUserslug(userslug, function(err, username) { if (err) { - return callback(err); + return onParsed(err); } if (!username) { @@ -78,15 +97,15 @@ module.exports = function(Meta) { } if (!subpage) { - return callback(null, username); + return onParsed(null, username); } translator.translate('[[pages:user.' + subpage + ', ' + username + ']]', language, function(translated) { - callback(null, translated); + onParsed(null, translated); }); }); } else { - callback(null); + onParsed(null); } }; }; \ No newline at end of file diff --git a/src/middleware/middleware.js b/src/middleware/middleware.js index 8adc6aabe7..956963f76d 100644 --- a/src/middleware/middleware.js +++ b/src/middleware/middleware.js @@ -229,10 +229,10 @@ middleware.renderHeader = function(req, res, callback) { if (err) { return next(err); } - meta.title.build(req.url.slice(1), settings.userLang, res.locals, next); + meta.title.build(req.url.slice(1), settings.userLang, next); }); } else { - meta.title.build(req.url.slice(1), meta.config.defaultLang, res.locals, next); + meta.title.build(req.url.slice(1), meta.config.defaultLang, next); } }, isAdmin: function(next) { diff --git a/src/socket.io/meta.js b/src/socket.io/meta.js index 890a40c3e0..9368d0c470 100644 --- a/src/socket.io/meta.js +++ b/src/socket.io/meta.js @@ -41,10 +41,10 @@ SocketMeta.buildTitle = function(socket, text, callback) { if (err) { return callback(err); } - meta.title.build(text, settings.userLang, {}, callback); + meta.title.build(text, settings.userLang, callback); }); } else { - meta.title.build(text, meta.config.defaultLang, {}, callback); + meta.title.build(text, meta.config.defaultLang, callback); } }; From d052db85e072989e8d0ef7d13231bca1fe8dc45c Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 21 May 2015 12:26:47 -0400 Subject: [PATCH 044/237] fixed bug where isMemberOfGroupList would return null if there were no groups to check, instead of false --- src/groups.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/groups.js b/src/groups.js index c6db87f3c3..72cb0e9b28 100644 --- a/src/groups.js +++ b/src/groups.js @@ -365,7 +365,7 @@ var async = require('async'), } groupNames = internals.removeEphemeralGroups(groupNames); if (groupNames.length === 0) { - return callback(null, null); + return callback(null, false); } Groups.isMemberOfGroups(uid, groupNames, function(err, isMembers) { From f6181e6481611a10d7000ff531cf0e16621cb537 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 21 May 2015 13:36:27 -0400 Subject: [PATCH 045/237] fixes #3148 --- public/src/ajaxify.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index dc1845f99e..b155efdaf3 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -261,7 +261,11 @@ $(document).ready(function() { } if (!e.ctrlKey && !e.shiftKey && !e.metaKey && e.which === 1) { - if (this.host === '' || (this.host === window.location.host && this.protocol === window.location.protocol)) { + if ( + this.host === '' || // Relative paths are always internal links... + (this.host === window.location.host && this.protocol === window.location.protocol && // Otherwise need to check that protocol and host match + (RELATIVE_PATH.length > 0 ? this.pathname.indexOf(RELATIVE_PATH) === 0 : true)) // Subfolder installs need this additional check + ) { // Internal link var url = this.href.replace(rootUrl + '/', ''); From 7125d902d0384c44b7cb95cc93ec8d63a7d219ed Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 21 May 2015 13:48:03 -0400 Subject: [PATCH 046/237] prettifying things --- src/controllers/admin.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/controllers/admin.js b/src/controllers/admin.js index 926e30d7e1..1df316267a 100644 --- a/src/controllers/admin.js +++ b/src/controllers/admin.js @@ -154,12 +154,8 @@ adminController.categories.getAll = function(req, res, next) { disabled = []; async.waterfall([ - function(next) { - db.getSortedSetRange('categories:cid', 0, -1, next); - }, - function(cids, next) { - categories.getCategoriesData(cids, next); - }, + async.apply(db.getSortedSetRange, 'categories:cid', 0, -1), + async.apply(categories.getCategoriesData), function(categories, next) { plugins.fireHook('filter:admin.categories.get', {req: req, res: res, categories: categories}, next); } From d90f3649a6295d03ba210bd0d702af1be3a957f8 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 21 May 2015 14:07:45 -0400 Subject: [PATCH 047/237] minor tweak to retrieval of category listing in ACP so that hidden categories (those with order of -1) are not retrieved --- src/controllers/admin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/admin.js b/src/controllers/admin.js index 1df316267a..94ae787145 100644 --- a/src/controllers/admin.js +++ b/src/controllers/admin.js @@ -154,7 +154,7 @@ adminController.categories.getAll = function(req, res, next) { disabled = []; async.waterfall([ - async.apply(db.getSortedSetRange, 'categories:cid', 0, -1), + async.apply(db.getSortedSetRangeByScore, 'categories:cid', 0, -1, 0, Date.now()), async.apply(categories.getCategoriesData), function(categories, next) { plugins.fireHook('filter:admin.categories.get', {req: req, res: res, categories: categories}, next); From 8acb0ca30416ac6ad11b7b002a9efe55da9397e8 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 21 May 2015 14:23:01 -0400 Subject: [PATCH 048/237] incr on user create --- src/user/create.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/create.js b/src/user/create.js index 9ce768b9ef..f1ad7f9294 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -141,7 +141,7 @@ module.exports = function(User) { ], next); }, function(results, next) { - User.updateUserCount(next); + db.incrObjectField('global', 'userCount', next); }, function(next) { if (userNameChanged) { From 09ee1ae77ef32a1957ecaef541c0d060f37032ec Mon Sep 17 00:00:00 2001 From: Timothy Fike Date: Thu, 21 May 2015 14:37:23 -0400 Subject: [PATCH 049/237] Call Plugins.addLanguages on reload. Fixes #3153 Ensures routes are set correctly for custom languages. --- src/plugins.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins.js b/src/plugins.js index 156ba49a3b..078745742c 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -67,11 +67,6 @@ var fs = require('fs'), emitter.emit('plugins:loaded'); callback(); }); - - Plugins.registerHook('core', { - hook: 'static:app.load', - method: addLanguages - }); }; Plugins.reload = function(callback) { @@ -84,6 +79,11 @@ var fs = require('fs'), Plugins.clientScripts.length = 0; Plugins.libraryPaths.length = 0; + Plugins.registerHook('core', { + hook: 'static:app.load', + method: addLanguages + }); + async.waterfall([ function(next) { db.getSortedSetRange('plugins:active', 0, -1, next); From 39c3afec62d6767fb3fbc89c53c916065b4f8df7 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 21 May 2015 14:52:39 -0400 Subject: [PATCH 050/237] removed updateUserCount --- src/user/create.js | 15 +++------------ src/user/delete.js | 12 ++++-------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/user/create.js b/src/user/create.js index f1ad7f9294..a9d22ac3c6 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -90,6 +90,9 @@ module.exports = function(User) { }, function(next) { async.parallel([ + function(next) { + db.incrObjectField('global', 'userCount', next); + }, function(next) { db.sortedSetAdd('username:uid', userData.uid, userData.username, next); }, @@ -141,9 +144,6 @@ module.exports = function(User) { ], next); }, function(results, next) { - db.incrObjectField('global', 'userCount', next); - }, - function(next) { if (userNameChanged) { User.notifications.sendNameChangeNotification(userData.uid, userData.username); } @@ -155,15 +155,6 @@ module.exports = function(User) { }); }; - User.updateUserCount = function(callback) { - db.sortedSetCard('users:joindate', function(err, count) { - if (err) { - return callback(err); - } - db.setObjectField('global', 'userCount', count, callback); - }); - }; - function isDataValid(userData, callback) { async.parallel({ emailValid: function(next) { diff --git a/src/user/delete.js b/src/user/delete.js index 2558399134..f27527e1e4 100644 --- a/src/user/delete.js +++ b/src/user/delete.js @@ -79,6 +79,9 @@ module.exports = function(User) { 'users:online' ], uid, next); }, + function(next) { + db.decrObjectField('global', 'userCount', next); + }, function(next) { var keys = [ 'uid:' + uid + ':notifications:read', 'uid:' + uid + ':notifications:unread', @@ -107,14 +110,7 @@ module.exports = function(User) { return callback(err); } - async.parallel([ - function(next) { - db.deleteAll(['followers:' + uid, 'following:' + uid, 'user:' + uid], next); - }, - function(next) { - User.updateUserCount(next); - } - ], callback); + db.deleteAll(['followers:' + uid, 'following:' + uid, 'user:' + uid], callback); }); }); }; From 117bb407b067b083a747a78e815daaba5c561639 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 21 May 2015 16:24:40 -0400 Subject: [PATCH 051/237] /compose route --- src/controllers/index.js | 3 +++ src/routes/index.js | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/controllers/index.js b/src/controllers/index.js index 59bf03994c..7adcf8d3ca 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -128,6 +128,9 @@ Controllers.register = function(req, res, next) { }); }; +Controllers.compose = function(req, res, next) { + res.render('composer', {}); +}; Controllers.confirmEmail = function(req, res, next) { user.email.confirm(req.params.code, function (err) { diff --git a/src/routes/index.js b/src/routes/index.js index 437f19359d..63c8fb6d65 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -25,6 +25,7 @@ function mainRoutes(app, middleware, controllers) { setupPageRoute(app, '/login', middleware, loginRegisterMiddleware, controllers.login); setupPageRoute(app, '/register', middleware, loginRegisterMiddleware, controllers.register); + setupPageRoute(app, '/compose', middleware, [middleware.authenticate], controllers.compose); setupPageRoute(app, '/confirm/:code', middleware, [], controllers.confirmEmail); setupPageRoute(app, '/outgoing', middleware, [], controllers.outgoing); setupPageRoute(app, '/search/:term?', middleware, [middleware.guestSearchingAllowed], controllers.search.search); @@ -207,7 +208,7 @@ function handle404(app, middleware) { function handleErrors(app, middleware) { app.use(function(err, req, res, next) { if (err.code === 'EBADCSRFTOKEN') { - winston.error(req.path + '\n', err.message) + winston.error(req.path + '\n', err.message); return res.sendStatus(403); } From 55bed3464ee3d478a1b7433201f106effe9e5115 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 21 May 2015 16:25:57 -0400 Subject: [PATCH 052/237] if mobile, go to /compose route #3090 --- public/src/modules/composer.js | 218 +++++++++++++++++---------------- 1 file changed, 114 insertions(+), 104 deletions(-) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index 4e8ce528f3..a5ba70cc19 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -321,117 +321,127 @@ define('composer', [ isAdminOrMod: app.user.isAdmin || postData.isMod }; - parseAndTranslate('composer', data, function(composerTemplate) { - if ($('#cmp-uuid-' + post_uuid).length) { - return; - } - composerTemplate = $(composerTemplate); - - composerTemplate.attr('id', 'cmp-uuid-' + post_uuid); - - $(document.body).append(composerTemplate); - - var postContainer = $(composerTemplate[0]), - bodyEl = postContainer.find('textarea'), - draft = drafts.getDraft(postData.save_id), - submitBtn = postContainer.find('.composer-submit'); - - preview.handleToggler(postContainer); - tags.init(postContainer, composer.posts[post_uuid]); - categoryList.init(postContainer, composer.posts[post_uuid]); - - activate(post_uuid); - resize.reposition(postContainer); - - if (config.allowFileUploads || config.hasImageUploadPlugin) { - uploads.initialize(post_uuid); - } - - formatting.addHandler(postContainer); - - if (allowTopicsThumbnail) { - uploads.toggleThumbEls(postContainer, composer.posts[post_uuid].topic_thumb || ''); - } - - postContainer.on('change', 'input, textarea', function() { - composer.posts[post_uuid].modified = true; + if (data.isMobile) { + ajaxify.go('compose', function() { + renderComposer(); }); + } else { + renderComposer(); + } - submitBtn.on('click', function() { - var action = $(this).attr('data-action'); - - switch(action) { - case 'post-lock': - $(this).attr('disabled', true); - post(post_uuid, {lock: true}); - break; - - case 'post': // intentional fall-through - default: - $(this).attr('disabled', true); - post(post_uuid); - break; - } - }); - - postContainer.on('click', 'a[data-switch-action]', function() { - var action = $(this).attr('data-switch-action'), - label = $(this).html(); - - submitBtn.attr('data-action', action).html(label); - }); - - postContainer.find('.composer-discard').on('click', function() { - if (!composer.posts[post_uuid].modified) { - removeComposerHistory(); - discard(post_uuid); + function renderComposer() { + parseAndTranslate('composer', data, function(composerTemplate) { + if ($('#cmp-uuid-' + post_uuid).length) { return; } - var btn = $(this).prop('disabled', true); - translator.translate('[[modules:composer.discard]]', function(translated) { - bootbox.confirm(translated, function(confirm) { - if (confirm) { - removeComposerHistory(); - discard(post_uuid); - } - btn.prop('disabled', false); + composerTemplate = $(composerTemplate); + + composerTemplate.attr('id', 'cmp-uuid-' + post_uuid); + + $(document.body).append(composerTemplate); + + var postContainer = $(composerTemplate[0]), + bodyEl = postContainer.find('textarea'), + draft = drafts.getDraft(postData.save_id), + submitBtn = postContainer.find('.composer-submit'); + + preview.handleToggler(postContainer); + tags.init(postContainer, composer.posts[post_uuid]); + categoryList.init(postContainer, composer.posts[post_uuid]); + + activate(post_uuid); + resize.reposition(postContainer); + + if (config.allowFileUploads || config.hasImageUploadPlugin) { + uploads.initialize(post_uuid); + } + + formatting.addHandler(postContainer); + + if (allowTopicsThumbnail) { + uploads.toggleThumbEls(postContainer, composer.posts[post_uuid].topic_thumb || ''); + } + + postContainer.on('change', 'input, textarea', function() { + composer.posts[post_uuid].modified = true; + }); + + submitBtn.on('click', function() { + var action = $(this).attr('data-action'); + + switch(action) { + case 'post-lock': + $(this).attr('disabled', true); + post(post_uuid, {lock: true}); + break; + + case 'post': // intentional fall-through + default: + $(this).attr('disabled', true); + post(post_uuid); + break; + } + }); + + postContainer.on('click', 'a[data-switch-action]', function() { + var action = $(this).attr('data-switch-action'), + label = $(this).html(); + + submitBtn.attr('data-action', action).html(label); + }); + + postContainer.find('.composer-discard').on('click', function() { + if (!composer.posts[post_uuid].modified) { + removeComposerHistory(); + discard(post_uuid); + return; + } + var btn = $(this).prop('disabled', true); + translator.translate('[[modules:composer.discard]]', function(translated) { + bootbox.confirm(translated, function(confirm) { + if (confirm) { + removeComposerHistory(); + discard(post_uuid); + } + btn.prop('disabled', false); + }); }); }); + + postContainer.on('click', function() { + if (!taskbar.isActive(post_uuid)) { + taskbar.updateActive(post_uuid); + } + }); + + bodyEl.on('input propertychange', function() { + preview.render(postContainer); + }); + + bodyEl.on('scroll', function() { + preview.matchScroll(postContainer); + }); + + bodyEl.val(draft ? draft : postData.body); + + preview.render(postContainer, function() { + preview.matchScroll(postContainer); + }); + + drafts.init(postContainer, postData); + + resize.handleResize(postContainer); + + handleHelp(postContainer); + + $(window).trigger('action:composer.loaded', { + post_uuid: post_uuid + }); + + formatting.addComposerButtons(); + focusElements(postContainer); }); - - postContainer.on('click', function() { - if (!taskbar.isActive(post_uuid)) { - taskbar.updateActive(post_uuid); - } - }); - - bodyEl.on('input propertychange', function() { - preview.render(postContainer); - }); - - bodyEl.on('scroll', function() { - preview.matchScroll(postContainer); - }); - - bodyEl.val(draft ? draft : postData.body); - - preview.render(postContainer, function() { - preview.matchScroll(postContainer); - }); - - drafts.init(postContainer, postData); - - resize.handleResize(postContainer); - - handleHelp(postContainer); - - $(window).trigger('action:composer.loaded', { - post_uuid: post_uuid - }); - - formatting.addComposerButtons(); - focusElements(postContainer); - }); + } } function parseAndTranslate(template, data, callback) { From 63a2a20fd3624f3e670e4cf9a5c5b726b3874dd4 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Thu, 21 May 2015 16:33:18 -0400 Subject: [PATCH 053/237] remove the old history.pushState hack for mobile composer --- public/src/modules/composer.js | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index a5ba70cc19..a42cf80afb 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -23,6 +23,13 @@ define('composer', [ $(window).off('resize', onWindowResize).on('resize', onWindowResize); + $(window).on('action:composer.topics.post', function(ev, data) { + localStorage.removeItem('category:' + data.data.cid + ':bookmark'); + localStorage.removeItem('category:' + data.data.cid + ':bookmark:clicked'); + ajaxify.go('topic/' + data.data.slug); + removeComposerHistory(); + }); + $(window).on('popstate', function(ev, data) { var env = utils.findBootstrapEnvironment(); @@ -36,21 +43,12 @@ define('composer', [ bootbox.confirm(translated, function(confirm) { if (confirm) { discard(composer.active); - } else { - history.pushState({}, ''); } }); }); } }); - $(window).on('action:composer.topics.post', function(ev, data) { - localStorage.removeItem('category:' + data.data.cid + ':bookmark'); - localStorage.removeItem('category:' + data.data.cid + ':bookmark:clicked'); - ajaxify.go('topic/' + data.data.slug); - removeComposerHistory(); - }); - function removeComposerHistory() { var env = utils.findBootstrapEnvironment(); if (env === 'xs' || env ==='sm') { @@ -121,13 +119,7 @@ define('composer', [ } composer.posts[uuid] = post; - composer.load(uuid); - - var env = utils.findBootstrapEnvironment(); - if (env === 'xs' || env ==='sm') { - history.pushState({}, ''); - } } function composerAlert(post_uuid, message) { @@ -321,7 +313,7 @@ define('composer', [ isAdminOrMod: app.user.isAdmin || postData.isMod }; - if (data.isMobile) { + if (data.mobile) { ajaxify.go('compose', function() { renderComposer(); }); From 9165da3b26a044c288d5db73c4933ca2b29e6a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 21 May 2015 17:19:21 -0400 Subject: [PATCH 054/237] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4684d5c73a..d8b5435dbc 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Additional functionality is enabled through the use of third-party plugins. NodeBB requires the following software to be installed: * A version of Node.js at least 0.10 or greater -* Redis, version 2.6 or greater **or** MongoDB, version 2.6 or greater +* Redis, version 2.8.9 or greater **or** MongoDB, version 2.6 or greater * nginx, version 1.3.13 or greater (**only if** intending to use nginx to proxy requests to a NodeBB) ## Installation From 118de65f5eabd5eda54e7324b20630f38f87589d Mon Sep 17 00:00:00 2001 From: Kalina Panayotova Date: Thu, 21 May 2015 16:11:19 -0700 Subject: [PATCH 055/237] Bugfix: use sorted set to get user followers in sendTopicNotificationToFollowers --- src/user/notifications.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/notifications.js b/src/user/notifications.js index fe9ffc80b8..b92df0ce68 100644 --- a/src/user/notifications.js +++ b/src/user/notifications.js @@ -258,7 +258,7 @@ var async = require('async'), }; UserNotifications.sendTopicNotificationToFollowers = function(uid, topicData, postData) { - db.getSetMembers('followers:' + uid, function(err, followers) { + db.getSortedSetRange('followers:' + uid, 0, -1, function(err, followers) { if (err || !Array.isArray(followers) || !followers.length) { return; } From 62f1a788e08f386570ddee9a47289455c4a7e976 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 21 May 2015 23:00:56 -0400 Subject: [PATCH 056/237] prematurely removing null objects before they get parsed as messages --- src/messaging.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/messaging.js b/src/messaging.js index 2cb1fedf1d..f15ac4e74f 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -142,7 +142,7 @@ var db = require('./database'), async.waterfall([ async.apply(db.getObjects, keys), function(messages, next) { - async.map(messages, function(message, next) { + async.filter(Boolean).map(messages, function(message, next) { var self = parseInt(message.fromuid, 10) === parseInt(fromuid, 10); message.fromUser = self ? userData[0] : userData[1]; message.toUser = self ? userData[1] : userData[0]; From 95e9d7c798c9f78d78e1da1ffb9769ac3d84839b Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 22 May 2015 00:39:48 -0400 Subject: [PATCH 057/237] filter messages --- src/messaging.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/messaging.js b/src/messaging.js index 2cb1fedf1d..78694627be 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -142,6 +142,9 @@ var db = require('./database'), async.waterfall([ async.apply(db.getObjects, keys), function(messages, next) { + + messages = messages.filter(Boolean); + async.map(messages, function(message, next) { var self = parseInt(message.fromuid, 10) === parseInt(fromuid, 10); message.fromUser = self ? userData[0] : userData[1]; From 990b02d0db67f8372b8050e7ceec650aa62fe82d Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 22 May 2015 00:42:24 -0400 Subject: [PATCH 058/237] fix crash @julianlam --- src/messaging.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/messaging.js b/src/messaging.js index 78694627be..052f13fbdd 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -142,9 +142,7 @@ var db = require('./database'), async.waterfall([ async.apply(db.getObjects, keys), function(messages, next) { - messages = messages.filter(Boolean); - async.map(messages, function(message, next) { var self = parseInt(message.fromuid, 10) === parseInt(fromuid, 10); message.fromUser = self ? userData[0] : userData[1]; From 79fd5a4d8eb5ef76ad0b2e7e8dc9a5abd358bf65 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Fri, 22 May 2015 13:45:32 -0400 Subject: [PATCH 059/237] closes #3169 --- public/src/modules/composer.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index a42cf80afb..a1ebce132d 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -27,7 +27,6 @@ define('composer', [ localStorage.removeItem('category:' + data.data.cid + ':bookmark'); localStorage.removeItem('category:' + data.data.cid + ':bookmark:clicked'); ajaxify.go('topic/' + data.data.slug); - removeComposerHistory(); }); $(window).on('popstate', function(ev, data) { @@ -49,13 +48,6 @@ define('composer', [ } }); - function removeComposerHistory() { - var env = utils.findBootstrapEnvironment(); - if (env === 'xs' || env ==='sm') { - history.back(); - } - } - // Query server for formatting options socket.emit('modules.composer.getFormattingOptions', function(err, options) { composer.formatting = options; From 7b81c5db9fa29a18036ac50fea1acddb72a6ed05 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Fri, 22 May 2015 13:49:57 -0400 Subject: [PATCH 060/237] #3169 --- public/src/modules/composer.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index a1ebce132d..91a0d0fb83 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -48,6 +48,13 @@ define('composer', [ } }); + function removeComposerHistory() { + var env = utils.findBootstrapEnvironment(); + if (env === 'xs' || env ==='sm') { + history.back(); + } + } + // Query server for formatting options socket.emit('modules.composer.getFormattingOptions', function(err, options) { composer.formatting = options; From f698d28dfb8315a557587c4ddcd878b65d335f83 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Fri, 22 May 2015 13:57:42 -0400 Subject: [PATCH 061/237] one last fix for #3169 --- public/src/modules/composer.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/public/src/modules/composer.js b/public/src/modules/composer.js index 91a0d0fb83..8ec6b7ca2d 100644 --- a/public/src/modules/composer.js +++ b/public/src/modules/composer.js @@ -26,7 +26,6 @@ define('composer', [ $(window).on('action:composer.topics.post', function(ev, data) { localStorage.removeItem('category:' + data.data.cid + ':bookmark'); localStorage.removeItem('category:' + data.data.cid + ':bookmark:clicked'); - ajaxify.go('topic/' + data.data.slug); }); $(window).on('popstate', function(ev, data) { @@ -549,6 +548,12 @@ define('composer', [ discard(post_uuid); drafts.removeDraft(postData.save_id); + if (action === 'topics.post') { + ajaxify.go('topic/' + data.slug); + } else { + removeComposerHistory(); + } + $(window).trigger('action:composer.' + action, {composerData: composerData, data: data}); }); } From 1c4d78eb2dd3e4a472e07ade7e117624e32dae92 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Fri, 22 May 2015 14:37:46 -0400 Subject: [PATCH 062/237] return back data in cb similar to topics.post call --- src/socket.io/posts.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js index ae45e46b8e..ad3da08ddd 100644 --- a/src/socket.io/posts.js +++ b/src/socket.io/posts.js @@ -45,7 +45,7 @@ SocketPosts.reply = function(socket, data, callback) { 'downvote:disabled': parseInt(meta.config['downvote:disabled'], 10) === 1, }; - callback(); + callback(null, postData); socket.emit('event:new_post', result); @@ -305,11 +305,11 @@ SocketPosts.edit = function(socket, data, callback) { if (parseInt(result.post.deleted) !== 1) { websockets.in('topic_' + result.topic.tid).emit('event:post_edited', result); - return callback(); + return callback(null, result.post); } socket.emit('event:post_edited', result); - callback(); + callback(null, result.post); async.parallel({ admins: async.apply(groups.getMembers, 'administrators', 0, -1), From 63489457fe0cc541eaf0cf2106f57817614b6789 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 22 May 2015 17:07:21 -0400 Subject: [PATCH 063/237] group search change --- src/groups.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/groups.js b/src/groups.js index 72cb0e9b28..02e24a41bb 100644 --- a/src/groups.js +++ b/src/groups.js @@ -1098,19 +1098,17 @@ var async = require('async'), Groups.search = function(query, options, callback) { if (!query) { - query = ''; + return callback(null, []); } - + query = query.toLowerCase(); async.waterfall([ async.apply(db.getObjectValues, 'groupslug:groupname'), function(groupNames, next) { groupNames = groupNames.filter(function(name) { - return name.match(new RegExp(query, 'i')) && name !== 'administrators'; + return name.toLowerCase().indexOf(query) !== -1 && name !== 'administrators'; }); - - async.mapLimit(groupNames, 5, function(groupName, next) { - Groups.get(groupName, options || {}, next); - }, next); + groupNames = groupNames.slice(0, 100); + Groups.getGroupsData(groupNames, next); }, async.apply(Groups.sort, options.sort) ], callback); From 5ce617ca5a2eb575ac241e864c5ab07a170c4e9f Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 23 May 2015 16:16:05 -0400 Subject: [PATCH 064/237] fix case in search --- src/groups.js | 2 ++ src/user/search.js | 1 + 2 files changed, 3 insertions(+) diff --git a/src/groups.js b/src/groups.js index 02e24a41bb..802f4346e2 100644 --- a/src/groups.js +++ b/src/groups.js @@ -1147,6 +1147,8 @@ var async = require('async'), return Groups.getMembers(data.groupName, 0, -1, callback); } + query = query.toLowerCase(); + async.waterfall([ function(next) { Groups.getMembers(data.groupName, 0, -1, next); diff --git a/src/user/search.js b/src/user/search.js index e78a932106..9d8d3c2f38 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -77,6 +77,7 @@ module.exports = function(User) { if (!query) { return callback(null, []); } + query = query.toLowerCase(); var min = query; var max = query.substr(0, query.length - 1) + String.fromCharCode(query.charCodeAt(query.length - 1) + 1); From f6ba4c446a1d54018b588cb1cecc7104bc255180 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sat, 23 May 2015 18:42:47 -0400 Subject: [PATCH 065/237] updated minimum versions for nodebb plugins to be the latest they are today --- package.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 278141c507..3ca0456426 100644 --- a/package.json +++ b/package.json @@ -38,16 +38,16 @@ "mmmagic": "^0.3.13", "morgan": "^1.3.2", "nconf": "~0.7.1", - "nodebb-plugin-dbsearch": "^0.2.5", - "nodebb-plugin-emoji-extended": "^0.4.1-4", - "nodebb-plugin-markdown": "^2.1.0", - "nodebb-plugin-mentions": "^0.11.0", - "nodebb-plugin-soundpack-default": "~0.1.1", + "nodebb-plugin-dbsearch": "^0.2.12", + "nodebb-plugin-emoji-extended": "^0.4.8", + "nodebb-plugin-markdown": "^2.1.7", + "nodebb-plugin-mentions": "^0.11.2", + "nodebb-plugin-soundpack-default": "^0.1.1", "nodebb-plugin-spam-be-gone": "^0.4.0", - "nodebb-theme-lavender": "^1.0.28", - "nodebb-theme-vanilla": "^1.0.120", - "nodebb-theme-persona": "^0.1.39", - "nodebb-widget-essentials": "^1.0.0", + "nodebb-theme-lavender": "^1.0.42", + "nodebb-theme-vanilla": "^1.0.130", + "nodebb-theme-persona": "^0.1.55", + "nodebb-widget-essentials": "^1.0.2", "nodebb-rewards-essentials": "^0.0.1", "npm": "^2.1.4", "passport": "^0.2.1", From 45589fbeca25852921b0f606bded9d09164d43d7 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sat, 23 May 2015 18:50:41 -0400 Subject: [PATCH 066/237] fixed bug where the selected language in the ACP was arabic, if no language was set at all" --- src/controllers/admin.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/controllers/admin.js b/src/controllers/admin.js index 94ae787145..65112ad229 100644 --- a/src/controllers/admin.js +++ b/src/controllers/admin.js @@ -290,9 +290,11 @@ adminController.languages.get = function(req, res, next) { if (err) { return next(err); } + languages.forEach(function(language) { - language.selected = language.code === meta.config.defaultLang; + language.selected = language.code === (meta.config.defaultLang || 'en_GB'); }); + res.render('admin/general/languages', { languages: languages }); From 434f1d924eb52cb27b373fb02a3271274ad88e35 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sat, 23 May 2015 19:01:09 -0400 Subject: [PATCH 067/237] bumped the package's version number for dev purposes --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3ca0456426..27d4933f94 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "nodebb", "license": "GPLv3 or later", "description": "NodeBB Forum", - "version": "0.7.0-dev", + "version": "0.7.1-dev", "homepage": "http://www.nodebb.org", "repository": { "type": "git", From 3055ee96a1f336ff4c4989eb86bde042b730036e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sat, 23 May 2015 19:12:13 -0400 Subject: [PATCH 068/237] latest translations and fallbacks --- public/language/ar/category.json | 4 +-- public/language/ar/error.json | 2 +- public/language/ar/login.json | 2 +- public/language/ar/register.json | 10 +++--- public/language/ar/reset_password.json | 12 +++---- public/language/ar/tags.json | 8 ++--- public/language/bg/error.json | 4 +-- public/language/es/error.json | 32 +++++++++--------- public/language/es/register.json | 4 +-- public/language/es/topic.json | 2 +- public/language/es/user.json | 14 ++++---- public/language/et/email.json | 46 +++++++++++++------------- public/language/fr/error.json | 4 +-- public/language/ru/user.json | 2 +- public/language/sv/category.json | 2 +- public/language/sv/email.json | 10 +++--- public/language/sv/login.json | 4 +-- public/language/sv/search.json | 2 +- public/language/sv/user.json | 32 +++++++++--------- 19 files changed, 98 insertions(+), 98 deletions(-) diff --git a/public/language/ar/category.json b/public/language/ar/category.json index 6a975425c0..b1732ff8ba 100644 --- a/public/language/ar/category.json +++ b/public/language/ar/category.json @@ -1,11 +1,11 @@ { "new_topic_button": "موضوع جديد", - "guest-login-post": "المرجو تسجيل الدخول أوَّلا", + "guest-login-post": "يجب عليك تسجيل الدخول للرد", "no_topics": "لا توجد مواضيع في هذه الفئةلم لا تحاول إنشاء موضوع؟
", "browsing": "تصفح", "no_replies": "لم يرد أحد", "share_this_category": "انشر هذه الفئة", - "watch": "Watch", + "watch": "متابعة", "ignore": "تجاهل", "watch.message": "You are now watching updates from this category", "ignore.message": "You are now ignoring updates from this category" diff --git a/public/language/ar/error.json b/public/language/ar/error.json index 4c10a8cf38..04ee524176 100644 --- a/public/language/ar/error.json +++ b/public/language/ar/error.json @@ -1,7 +1,7 @@ { "invalid-data": "بيانات غير صالحة", "not-logged-in": "لم تقم بتسجيل الدخول", - "account-locked": "تم إقفال حسابكم مؤقتًا.", + "account-locked": "تم حظر حسابك مؤقتًا.", "search-requires-login": "Searching requires an account - please login or register.", "invalid-cid": "قائمة غير موجودة", "invalid-tid": "موضوع غير متواجد", diff --git a/public/language/ar/login.json b/public/language/ar/login.json index 878a32533c..29d256203f 100644 --- a/public/language/ar/login.json +++ b/public/language/ar/login.json @@ -7,5 +7,5 @@ "alternative_logins": "تسجيلات الدخول البديلة", "failed_login_attempt": "فشلت محاولة تسجيل الدخول، يرجى المحاولة مرة أخرى.", "login_successful": "قمت بتسجيل الدخول بنجاح!", - "dont_have_account": "لم تفتح حسابك بعد؟" + "dont_have_account": "لا تملك حساب؟" } \ No newline at end of file diff --git a/public/language/ar/register.json b/public/language/ar/register.json index d456c82572..311ced9103 100644 --- a/public/language/ar/register.json +++ b/public/language/ar/register.json @@ -2,15 +2,15 @@ "register": "تسجيل", "help.email": "افتراضيا، سيتم إخفاء بريدك الإلكتروني من الجمهور.", "help.username_restrictions": "اسم مستخدم فريدة من نوعها بين1% و2% حرفا. يمكن للآخرين ذكرك @ <'span id='your-username> اسم المستخدم .", - "help.minimum_password_length": "كلمتك السر يجب أن تكون على الأقل متألفة من 1% أحرف", + "help.minimum_password_length": "كلمة المرور يجب أن تكون على الأقل بها 1% أحرف", "email_address": "عنوان البريد الإلكتروني", "email_address_placeholder": "ادخل عنوان البريد الإلكتروني", "username": "اسم المستخدم", "username_placeholder": "أدخل اسم المستخدم", - "password": "كلمة السر", - "password_placeholder": "أدخل كلمة السر", - "confirm_password": "تأكيد كلمة السر", - "confirm_password_placeholder": "تأكيد كلمة السر", + "password": "كلمة المرور", + "password_placeholder": "أدخل كلمة المرور", + "confirm_password": "تأكيد كلمة المرور", + "confirm_password_placeholder": "تأكيد كلمة المرور", "register_now_button": "قم بالتسجيل الآن", "alternative_registration": "طريقة تسجيل بديلة", "terms_of_use": "شروط الاستخدام", diff --git a/public/language/ar/reset_password.json b/public/language/ar/reset_password.json index cdd2b378a0..f6107ec45b 100644 --- a/public/language/ar/reset_password.json +++ b/public/language/ar/reset_password.json @@ -1,12 +1,12 @@ { - "reset_password": "إعادة تعيين كلمة السر", - "update_password": "تحديث كلمة السر", - "password_changed.title": "تم تغير كلمة السر", - "password_changed.message": "

تم تغير كلمة السر بنجاح. يرجى إعادة الدخول

", + "reset_password": "إعادة تعيين كلمة المرور", + "update_password": "تحديث كلمة المرور", + "password_changed.title": "تم تغير كلمة المرور", + "password_changed.message": "

تم تغير كلمة المرور بنجاح، الرجاء إعادة الدخول

", "wrong_reset_code.title": "رمز إعادة التعيين غير صحيح", "wrong_reset_code.message": "رمز إعادة التعين غير صحيح، يرجى المحاولة مرة أخرى أو اطلب رمزا جديدا", - "new_password": "كلمة السر الجديدة", - "repeat_password": "تأكيد كلمة السر", + "new_password": "كلمة المرور الجديدة", + "repeat_password": "تأكيد كلمة المرور", "enter_email": "يرجى إدخال عنوان البريد الإلكتروني الخاص بك وسوف نرسل لك رسالة بالبريد الالكتروني مع تعليمات حول كيفية إستعادة حسابك.", "enter_email_address": "ادخل عنوان البريد الإلكتروني", "password_reset_sent": "إعادة تعيين كلمة السر أرسلت", diff --git a/public/language/ar/tags.json b/public/language/ar/tags.json index f2eccbd1c0..2798a0c8c8 100644 --- a/public/language/ar/tags.json +++ b/public/language/ar/tags.json @@ -1,7 +1,7 @@ { - "no_tag_topics": "لاوجود لمواضيع تحمل هذا الوسم.", - "tags": "بطاقات", + "no_tag_topics": "لا يوجد مواضيع بهذه الكلمة الدلالية.", + "tags": "الكلمات الدلالية", "enter_tags_here": "Enter tags here, between %1 and %2 characters each.", - "enter_tags_here_short": "أدخل البطاقات...", - "no_tags": "لاتوجد هناك بطاقات بعد." + "enter_tags_here_short": "أدخل الكلمات الدلالية...", + "no_tags": "لا يوجد كلمات دلالية بعد." } \ No newline at end of file diff --git a/public/language/bg/error.json b/public/language/bg/error.json index ce39acb82d..a48531a6ea 100644 --- a/public/language/bg/error.json +++ b/public/language/bg/error.json @@ -67,8 +67,8 @@ "topic-thumbnails-are-disabled": "Иконките на темите са изключени.", "invalid-file": "Грешен файл", "uploads-are-disabled": "Качването не е разрешено", - "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", - "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", + "signature-too-long": "Съжаляваме, но подписът Ви трябва да съдържа не повече от %1 символ(а).", + "about-me-too-long": "Съжаляваме, но информацията за Вас трябва да съдържа не повече от %1 символ(а).", "cant-chat-with-yourself": "Не можете да пишете чат съобщение на себе си!", "chat-restricted": "Този потребител е ограничил чат съобщенията до себе си. Той трябва първо да Ви последва, преди да можете да си пишете с него.", "too-many-messages": "Изпратили сте твърде много съобщения. Моля, изчакайте малко.", diff --git a/public/language/es/error.json b/public/language/es/error.json index cd90a8470b..02b0c930cc 100644 --- a/public/language/es/error.json +++ b/public/language/es/error.json @@ -2,7 +2,7 @@ "invalid-data": "Datos no válidos", "not-logged-in": "No has iniciado sesión.", "account-locked": "Tu cuenta ha sido bloqueada temporalmente.", - "search-requires-login": "Searching requires an account - please login or register.", + "search-requires-login": "¡Buscar requiere estar registrado! Por favor, entra o regístrate.", "invalid-cid": "Identificador de categoría no válido", "invalid-tid": "Identificador de tema no válido", "invalid-pid": "Identificador de publicación no válido", @@ -21,11 +21,11 @@ "email-not-confirmed-chat": "No puedes usar el chat hasta que confirmes tu dirección de correo electrónico, por favor haz click aquí para confirmar tu correo.", "no-email-to-confirm": "Este foro requiere confirmación de su email, por favor pulse aquí para introducir un email", "email-confirm-failed": "No se ha podido confirmar su email, por favor inténtelo de nuevo más tarde.", - "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", + "confirm-email-already-sent": "El email de confirmación ya ha sido enviado, por favor espera %1 minuto(s) para enviar otro.", "username-too-short": "Nombre de usuario es demasiado corto", "username-too-long": "Nombre de usuario demasiado largo", "user-banned": "Usuario baneado", - "user-too-new": "Sorry, you are required to wait %1 second(s) before making your first post", + "user-too-new": "Lo sentimos, es necesario que esperes %1 segundo(s) antes poder hacer tu primera publicación", "no-category": "La categoría no existe", "no-topic": "El tema no existe", "no-post": "La publicación no existe", @@ -36,17 +36,17 @@ "no-emailers-configured": "No se ha cargado ningún plugin de email, así que no se pudo enviar el email de prueba.", "category-disabled": "Categoría deshabilitada", "topic-locked": "Tema bloqueado", - "post-edit-duration-expired": "You are only allowed to edit posts for %1 second(s) after posting", + "post-edit-duration-expired": "Sólo puedes editar mensajes durante %1 segundo(s) después de haberlo escrito", "still-uploading": "Por favor, espera a que terminen las subidas.", - "content-too-short": "Please enter a longer post. Posts should contain at least %1 character(s).", - "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 character(s).", - "title-too-short": "Please enter a longer title. Titles should contain at least %1 character(s).", - "title-too-long": "Please enter a shorter title. Titles can't be longer than %1 character(s).", - "too-many-posts": "You can only post once every %1 second(s) - please wait before posting again", - "too-many-posts-newbie": "As a new user, you can only post once every %1 second(s) 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 character(s)", - "tag-too-long": "Please enter a shorter tag. Tags can't be longer than %1 character(s)", - "file-too-big": "Maximum allowed file size is %1 kB - please upload a smaller file", + "content-too-short": "Por favor introduzca una publicación más larga. Las publicaciones deben contener al menos %1 caractere(s).", + "content-too-long": "Por favor introduzca un mensaje más corto. Los mensajes no pueden exceder los %1 caractere(s).", + "title-too-short": "Por favor introduzca un título más largo. Los títulos deben contener al menos %1 caractere(s).", + "title-too-long": "Por favor, introduce un título más corto, que no sobrepase los %1 caractere(s).", + "too-many-posts": "Solo puedes publicar una vez cada %1 segundo(s) - por favor espere antes de volver a publicar", + "too-many-posts-newbie": "Como nuevo usuario, solo puedes publicar una vez cada %1 segundo(s) hasta hayas ganado una reputación de %2 - por favor espera antes de volver a publicar", + "tag-too-short": "Por favor introduce una etiqueta más larga. Las etiquetas deben contener por lo menos %1 caractere(s)", + "tag-too-long": "Por favor introduce una etiqueta más corta. Las etiquetas no pueden exceder los %1 caractere(s)", + "file-too-big": "El tamaño de fichero máximo es de %1 kB - por favor, suba un fichero más pequeño", "cant-vote-self-post": "No puedes votar tus propios posts", "already-favourited": "Ya ha marcado esta publicación como favorita", "already-unfavourited": "Ya ha desmarcado esta publicación como favorita", @@ -63,12 +63,12 @@ "post-already-restored": "Esta publicación ya ha sido restaurada", "topic-already-deleted": "Este tema ya ha sido borrado", "topic-already-restored": "Este tema ya ha sido restaurado", - "cant-purge-main-post": "You can't purge the main post, please delete the topic instead", + "cant-purge-main-post": "No puedes purgar el mensaje principal, por favor utiliza borrar tema", "topic-thumbnails-are-disabled": "Las miniaturas de los temas están deshabilitadas.", "invalid-file": "Archivo no válido", "uploads-are-disabled": "Las subidas están deshabilitadas.", - "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", - "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", + "signature-too-long": "Lo sentimos, pero tu firma no puede ser más larga de %1 caractere(s).", + "about-me-too-long": "Lo sentimos, pero tu descripción no puede ser más larga de %1 caractere(s).", "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": "Has enviado demasiados mensajes, por favor espera un poco.", diff --git a/public/language/es/register.json b/public/language/es/register.json index 4ffa4d8bdd..064f05fa64 100644 --- a/public/language/es/register.json +++ b/public/language/es/register.json @@ -1,5 +1,5 @@ { - "register": "Registrase", + "register": "Registrarse", "help.email": "Por defecto, tu cuenta de correo electrónico estará oculta al publico.", "help.username_restrictions": "El nombre de usuario debe tener entre %1 y %2 carácteres. Los miembros pueden responderte escribiendo @usuario.", "help.minimum_password_length": "Tu contraseña debe tener al menos %1 carácteres.", @@ -11,7 +11,7 @@ "password_placeholder": "Introduce tu contraseña", "confirm_password": "Confirmar contraseña", "confirm_password_placeholder": "Confirmar contraseña", - "register_now_button": "Registrarme ahora", + "register_now_button": "Registrarse ahora", "alternative_registration": "Métodos de registro alternativos", "terms_of_use": "Términos y Condiciones de uso", "agree_to_terms_of_use": "Acepto los Términos y Condiciones de uso" diff --git a/public/language/es/topic.json b/public/language/es/topic.json index edf271b351..c90bccb9d0 100644 --- a/public/language/es/topic.json +++ b/public/language/es/topic.json @@ -5,7 +5,7 @@ "no_topics_found": "¡No se encontraron temas!", "no_posts_found": "¡No se encontraron publicaciones!", "post_is_deleted": "¡Esta publicación está eliminada!", - "topic_is_deleted": "This topic is deleted!", + "topic_is_deleted": "¡Este tema ha sido eliminado!", "profile": "Perfil", "posted_by": "Publicado por %1", "posted_by_guest": "Publicado por Invitado", diff --git a/public/language/es/user.json b/public/language/es/user.json index 44baffb856..10fef1a69b 100644 --- a/public/language/es/user.json +++ b/public/language/es/user.json @@ -21,7 +21,7 @@ "watched": "Visto", "followers": "Seguidores", "following": "Siguiendo", - "aboutme": "About me", + "aboutme": "Sobre mí", "signature": "Firma", "gravatar": "Gravatar", "birthday": "Cumpleaños", @@ -69,16 +69,16 @@ "has_no_watched_topics": "Este usuario todavía no ha visto ninguna publicación.", "email_hidden": "Correo electrónico oculto", "hidden": "oculto", - "paginate_description": "Paginate topics and posts instead of using infinite scroll", + "paginate_description": "Paginar hilos y mensajes en lugar de usar desplazamiento infinito", "topics_per_page": "Temas por página", "posts_per_page": "Post por página", - "notification_sounds": "Play a sound when you receive a notification", + "notification_sounds": "Reproducir un sonido al recibir una notificación", "browsing": "Preferencias de navegación.", - "open_links_in_new_tab": "Open outgoing links in new tab", + "open_links_in_new_tab": "Abrir los enlaces externos en una nueva pestaña", "enable_topic_searching": "Activar la búsqueda \"in-topic\"", - "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", + "topic_search_help": "Si está activada, la búsqueda 'in-topic' sustituirá el comportamiento por defecto del navegador y le permitirá buscar en el tema al completo, en vez de hacer una búsqueda únicamente sobre el contenido mostrado en pantalla", + "follow_topics_you_reply_to": "Seguir los temas en las que respondes", + "follow_topics_you_create": "Seguir publicaciones que creas", "grouptitle": "Selecciona el título del grupo que deseas visualizar", "no-group-title": "Sin título de grupo" } \ No newline at end of file diff --git a/public/language/et/email.json b/public/language/et/email.json index 9f3a49318e..1f1c1e853a 100644 --- a/public/language/et/email.json +++ b/public/language/et/email.json @@ -1,28 +1,28 @@ { "password-reset-requested": "Parooli muutmise taotlus - %1!", - "welcome-to": "Tere tulemast %1", + "welcome-to": "Tere tulemast foorumisse %1", "greeting_no_name": "Tere", "greeting_with_name": "Tere %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", - "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", - "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!" + "welcome.text1": "Täname et oled registreerinud foorumisse %1!", + "welcome.text2": "Konto täielikuks aktiveerimiseks peame me kinnitama, et registreerimisel kasutatud e-mail kuulub teile.", + "welcome.cta": "Vajuta siia, et kinnitada oma e-maili aadress", + "reset.text1": "Meile laekus päring parooli muutmiseks. Kui päring ei ole teie poolt esitatud või te ei soovi parooli muuta, siis võite antud kirja ignoreerida.", + "reset.text2": "Selleks, et jätkata parooli muutmisega vajuta järgnevale lingile:", + "reset.cta": "Vajuta siia, et taotleda uut parooli", + "reset.notify.subject": "Parool edukalt muudetud", + "reset.notify.text1": "Teavitame sind, et sinu parool %1 foorumis on edukalt muudetud.", + "reset.notify.text2": "Kui te ei ole lubanud seda, siis teavitage koheselt administraatorit.", + "digest.notifications": "Sul on lugemata teateid %1 poolt:", + "digest.latest_topics": "Viimased teemad %1 poolt", + "digest.cta": "Vajuta siia et külastada %1", + "digest.unsub.info": "See uudiskiri on saadetud teile tellimuse seadistuse tõttu.", + "digest.no_topics": "Viimase %1 jooksul ei ole olnud ühtegi aktiivset teemat", + "notif.chat.subject": "Sulle on saabunud uus sõnum kasutajalt %1", + "notif.chat.cta": "Vajuta siia, et jätkata vestlusega", + "notif.chat.unsub.info": "See chat teavitus on saadetud teile tellimuse seadistuse tõttu.", + "notif.post.cta": "Vajuta siia, et lugeda teemat täies mahus", + "notif.post.unsub.info": "See postituse teavitus on saadetud teile tellimuse seadistuse tõttu.", + "test.text1": "See on test e-mail kinnitamaks, et emailer on korrektselt seadistatud sinu NodeBB jaoks.", + "unsub.cta": "Vajuta siia, et muuta neid seadeid", + "closing": "Aitäh!" } \ No newline at end of file diff --git a/public/language/fr/error.json b/public/language/fr/error.json index dd79c11b72..dd012bc393 100644 --- a/public/language/fr/error.json +++ b/public/language/fr/error.json @@ -67,8 +67,8 @@ "topic-thumbnails-are-disabled": "Les miniatures de sujet sont désactivés", "invalid-file": "Fichier invalide", "uploads-are-disabled": "Les envois sont désactivés", - "signature-too-long": "Sorry, your signature cannot be longer than %1 character(s).", - "about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).", + "signature-too-long": "La signature ne peut dépasser %1 caractère(s).", + "about-me-too-long": "Votre texte \"à propos de moi\" ne peut dépasser %1 caractère(s).", "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": "Vous avez envoyé trop de messages, veuillez patienter un instant.", diff --git a/public/language/ru/user.json b/public/language/ru/user.json index be8dea688f..755cbce9f3 100644 --- a/public/language/ru/user.json +++ b/public/language/ru/user.json @@ -21,7 +21,7 @@ "watched": "Просмотров", "followers": "Читателей", "following": "Читаемых", - "aboutme": "About me", + "aboutme": "Обо мне", "signature": "Подпись", "gravatar": "Gravatar", "birthday": "День рождения", diff --git a/public/language/sv/category.json b/public/language/sv/category.json index 722a8d0c45..d82abe3a24 100644 --- a/public/language/sv/category.json +++ b/public/language/sv/category.json @@ -1,6 +1,6 @@ { "new_topic_button": "Nytt ämne", - "guest-login-post": "Log in to post", + "guest-login-post": "Logga in för att posta", "no_topics": "Det finns inga ämnen i denna kategori.
Varför skapar inte du ett ämne?", "browsing": "läser", "no_replies": "Ingen har svarat", diff --git a/public/language/sv/email.json b/public/language/sv/email.json index 808c73caa8..410aea5b6a 100644 --- a/public/language/sv/email.json +++ b/public/language/sv/email.json @@ -9,9 +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.", + "reset.notify.subject": "Lösenordet ändrat", + "reset.notify.text1": "Vi vill uppmärksamma dig på att ditt lösenord ändrades den %1", + "reset.notify.text2": "Om du inte godkänt det här så vänligen kontakta en admin snarast. ", "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", @@ -20,8 +20,8 @@ "notif.chat.subject": "Nytt chatt-meddelande från %1", "notif.chat.cta": "Klicka här för att fortsätta konversationen", "notif.chat.unsub.info": "Denna chatt-notifikation skickades till dig på grund av dina inställningar för prenumerationer.", - "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": "Klicka här för att läsa hela ämnet", + "notif.post.unsub.info": "Det här meddelandet fick du på grund av dina inställningar för prenumeration. ", "test.text1": "\nDet här är ett textmeddelande som verifierar att eposten är korrekt installerat för din NodeBB. ", "unsub.cta": "Klicka här för att ändra dom inställningarna", "closing": "Tack!" diff --git a/public/language/sv/login.json b/public/language/sv/login.json index c96dd64485..363da51e9b 100644 --- a/public/language/sv/login.json +++ b/public/language/sv/login.json @@ -1,6 +1,6 @@ { - "username-email": "Username / Email", - "username": "Username", + "username-email": "Användarnamn eller epostadress", + "username": "Användarnamn", "email": "Email", "remember_me": "Kom ihåg mig?", "forgot_password": "Glömt lösenord?", diff --git a/public/language/sv/search.json b/public/language/sv/search.json index 7822eeae96..92ef77c3d1 100644 --- a/public/language/sv/search.json +++ b/public/language/sv/search.json @@ -1,6 +1,6 @@ { "results_matching": "%1 resultat matchar \"%2\", (%3 sekunder)", - "no-matches": "No matches found", + "no-matches": "Inga träffar", "advanced-search": "Advanced Search", "in": "In", "titles": "Titles", diff --git a/public/language/sv/user.json b/public/language/sv/user.json index dd8f04d712..9131f6ff9d 100644 --- a/public/language/sv/user.json +++ b/public/language/sv/user.json @@ -2,8 +2,8 @@ "banned": "Bannad", "offline": "Offline", "username": "Användarnamn", - "joindate": "Join Date", - "postcount": "Post Count", + "joindate": "Gick med", + "postcount": "Antal inlägg", "email": "Epost", "confirm_email": "Bekräfta epostadress ", "delete_account": "Ta bort ämne", @@ -18,17 +18,17 @@ "profile_views": "Profil-visningar", "reputation": "Rykte", "favourites": "Favoriter", - "watched": "Watched", + "watched": "Bevakad", "followers": "Följare", "following": "Följer", - "aboutme": "About me", + "aboutme": "Om mig", "signature": "Signatur", "gravatar": "Gravatar", "birthday": "Födelsedag", "chat": "Chatta", "follow": "Följ", "unfollow": "Sluta följ", - "more": "More", + "more": "Mer", "profile_update_success": "Profilen uppdaterades.", "change_picture": "Ändra bild", "edit": "Ändra", @@ -60,25 +60,25 @@ "digest_weekly": "Veckovis", "digest_monthly": "Månadsvis", "send_chat_notifications": "Skicka ett epostmeddelande om nya chatt-meddelanden tas emot när jag inte är online.", - "send_post_notifications": "Send an email when replies are made to topics I am subscribed to", - "settings-require-reload": "Some setting changes require a reload. Click here to reload the page.", + "send_post_notifications": "Skicka ett epost när svar kommit på ämnen jag prenumererar på till", + "settings-require-reload": "Vissa inställningar som ändrades kräver att sidan laddas om. Klicka här för att ladda om sidan.", "has_no_follower": "Denna användare har inga följare :(", "follows_no_one": "Denna användare följer ingen :(", "has_no_posts": "Denna användare har inte gjort några inlägg än.", "has_no_topics": "Den här användaren har inte skrivit något inlägg ännu.", - "has_no_watched_topics": "This user didn't watch any topics yet.", + "has_no_watched_topics": "Den här användaren bevakar inga ämnen ännu.", "email_hidden": "Epost dold", "hidden": "dold", - "paginate_description": "Paginate topics and posts instead of using infinite scroll", + "paginate_description": "Gör så att ämnen och inlägg visas som sidor istället för oändlig skroll", "topics_per_page": "Ämnen per sida", "posts_per_page": "Inlägg per sida", - "notification_sounds": "Play a sound when you receive a notification", + "notification_sounds": "Spela ett ljud när du får en notis", "browsing": "Inställning för bläddring", - "open_links_in_new_tab": "Open outgoing links in new tab", + "open_links_in_new_tab": "Öppna utgående länkar på ny flik", "enable_topic_searching": "Aktivera Sökning Inom Ämne", - "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", - "grouptitle": "Select the group title you would like to display", - "no-group-title": "No group title" + "topic_search_help": "Om aktiverat kommer sökning inom ämne överskrida webbläsarens vanliga funktionen för sökning bland sidor och tillåta dig att söka genom hela ämnet istället för det som endast visas på skärmen.", + "follow_topics_you_reply_to": "Följ ämnen som du svarat på", + "follow_topics_you_create": "Följ ämnen du skapat", + "grouptitle": "Välj tittel för gruppen så som du vill att den ska visas", + "no-group-title": "Ingen titel på gruppen" } \ No newline at end of file From 3b891ed7d87ab4659135e1de18f6d687c274c1b1 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sat, 23 May 2015 19:14:37 -0400 Subject: [PATCH 069/237] closes #3173 --- public/language/ru/reset_password.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/language/ru/reset_password.json b/public/language/ru/reset_password.json index ee6b29edb7..0a0c439606 100644 --- a/public/language/ru/reset_password.json +++ b/public/language/ru/reset_password.json @@ -2,7 +2,7 @@ "reset_password": "Восстановить пароль", "update_password": "Изменить пароль", "password_changed.title": "Пароль изменен", - "password_changed.message": "

Пароль успешно восстановлен, пожалуйста войдите еще раз.", + "password_changed.message": "

Пароль успешно восстановлен, пожалуйста войдите еще раз.", "wrong_reset_code.title": "Неверный код восстановления", "wrong_reset_code.message": "Неправильный код восстановления пароля. Попробуйте еще раз, или запросите новый код восстановления.", "new_password": "Новый пароль", From 4b4be3d4cced8b9fd2f92d8b6a67a97e1cef819c Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 23 May 2015 19:30:31 -0400 Subject: [PATCH 070/237] fix minSchemaDate --- src/upgrade.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/upgrade.js b/src/upgrade.js index 6399a4ff32..2abdfe426c 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -17,7 +17,7 @@ var db = require('./database'), Upgrade = {}, - minSchemaDate = Date.UTC(2015, 1, 8), // This value gets updated every new MINOR version + minSchemaDate = Date.UTC(2015, 0, 30), // This value gets updated every new MINOR version schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema From 9ed88b7bb95859c898b70b4d3a6f5cfe45d61dea Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sat, 23 May 2015 22:08:17 -0400 Subject: [PATCH 071/237] updated readme a bit --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d8b5435dbc..f54187be2f 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,12 @@ Additional functionality is enabled through the use of third-party plugins. * [Get NodeBB](http://www.nodebb.org/ "NodeBB") * [Demo & Meta Discussion](http://community.nodebb.org) -* [NodeBB Blog](http://blog.nodebb.org) * [Documentation & Installation Instructions](http://docs.nodebb.org) +* [Help translate NodeBB](https://www.transifex.com/projects/p/nodebb/) +* [NodeBB Blog](http://blog.nodebb.org) * [Join us on IRC](https://kiwiirc.com/client/irc.freenode.net/nodebb) - #nodebb on Freenode * [Follow us on Twitter](http://www.twitter.com/NodeBB/ "NodeBB Twitter") * [Like us on Facebook](http://www.facebook.com/NodeBB/ "NodeBB Facebook") -* [Get Plugins](http://community.nodebb.org/category/7/nodebb-plugins "NodeBB Plugins") -* [Get Themes](http://community.nodebb.org/category/10/nodebb-themes "NodeBB Themes") -* [Help translate NodeBB](https://www.transifex.com/projects/p/nodebb/) ## Screenshots @@ -62,4 +60,6 @@ Detailed upgrade instructions are listed in [Upgrading NodeBB](https://docs.node ## License -NodeBB is licensed under the **GNU General Public License v3 (GPL-3)** (http://www.gnu.org/copyleft/gpl.html) +NodeBB is licensed under the **GNU General Public License v3 (GPL-3)** (http://www.gnu.org/copyleft/gpl.html). + +Interested in a sublicense agreement for use of NodeBB in a non-free/restrictive environment? Contact us at sales@nodebb.org. \ No newline at end of file From 714c7356f98481ea64b4cfa5c35c483640c14365 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 23 May 2015 22:11:20 -0400 Subject: [PATCH 072/237] closes #3176 --- install/data/defaults.json | 134 ++++++++----------------------------- src/install.js | 39 +++++++---- 2 files changed, 55 insertions(+), 118 deletions(-) diff --git a/install/data/defaults.json b/install/data/defaults.json index 9a0d6eb1ec..4e5ebc035e 100644 --- a/install/data/defaults.json +++ b/install/data/defaults.json @@ -1,106 +1,28 @@ -[ - { - "field": "title", - "value": "NodeBB" - }, - { - "field": "showSiteTitle", - "value": "1" - }, - { - "field": "postDelay", - "value": 10 - }, - { - "field": "initialPostDelay", - "value": 10 - }, - { - "field": "newbiePostDelay", - "value": 120 - }, - { - "field": "newbiePostDelayThreshold", - "value": 3 - }, - { - "field": "minimumPostLength", - "value": 8 - }, - { - "field": "maximumPostLength", - "value": 32767 - }, - { - "field": "allowGuestSearching", - "value": 0 - }, - { - "field": "allowTopicsThumbnail", - "value": 0 - }, - { - "field": "allowRegistration", - "value": 1 - }, - { - "field": "allowLocalLogin", - "value": 1 - }, - { - "field": "allowAccountDelete", - "value": 1 - }, - { - "field": "allowFileUploads", - "value": 0 - }, - { - "field": "maximumFileSize", - "value": 2048 - }, - { - "field": "minimumTitleLength", - "value": 3 - }, - { - "field": "maximumTitleLength", - "value": 255 - }, - { - "field": "minimumUsernameLength", - "value": 2 - }, - { - "field": "maximumUsernameLength", - "value": 16 - }, - { - "field": "minimumPasswordLength", - "value": 6 - }, - { - "field": "maximumSignatureLength", - "value": 255 - }, - { - "field": "maximumAboutMeLength", - "value": 1000 - }, - { - "field": "maximumProfileImageSize", - "value": 256 - }, - { - "field": "profileImageDimension", - "value": 128 - }, - { - "field": "requireEmailConfirmation", - "value": 0 - }, - { - "field": "profile:allowProfileImageUploads", - "value": 1 - } -] +{ + "title": "NodeBB", + "showSiteTitle": 1, + "postDelay": 10, + "initialPostDelay": 10, + "newbiePostDelay": 120, + "newbiePostDelayThreshold": 3, + "minimumPostLength": 8, + "maximumPostLength": 32767, + "allowGuestSearching": 0, + "allowTopicsThumbnail": 0, + "allowRegistration": 1, + "allowLocalLogin": 1, + "allowAccountDelete": 1, + "allowFileUploads": 0, + "maximumFileSize": 2048, + "minimumTitleLength": 3, + "maximumTitleLength": 255, + "minimumUsernameLength": 2, + "maximumUsernameLength": 16, + "minimumPasswordLength": 6, + "maximumSignatureLength": 255, + "maximumAboutMeLength": 1000, + "maximumProfileImageSize": 256, + "profileImageDimension": 128, + "requireEmailConfirmation": 0, + "profile:allowProfileImageUploads": 1 +} diff --git a/src/install.js b/src/install.js index 8b7c97ffc5..93597029f6 100644 --- a/src/install.js +++ b/src/install.js @@ -239,24 +239,39 @@ function setupDefaultConfigs(next) { var meta = require('./meta'), defaults = require(path.join(__dirname, '../', 'install/data/defaults.json')); - async.each(defaults, function (configObj, next) { - meta.configs.setOnEmpty(configObj.field, configObj.value, next); + async.each(Object.keys(defaults), function (key, next) { + meta.configs.setOnEmpty(key, defaults[key], next); }, function (err) { - meta.configs.init(next); - }); + if (err) { + return next(err); + } - if (install.values) { - setIfPaired('social:twitter:key', 'social:twitter:secret'); - setIfPaired('social:google:id', 'social:google:secret'); - setIfPaired('social:facebook:app_id', 'social:facebook:secret'); - } + if (install.values) { + async.parallel([ + async.apply(setIfPaired, 'social:twitter:key', 'social:twitter:secret'), + async.apply(setIfPaired, 'social:google:id', 'social:google:secret'), + async.apply(setIfPaired, 'social:facebook:app_id', 'social:facebook:secret') + ], function(err) { + if (err) { + return next(err); + } + meta.configs.init(next); + }); + } else { + meta.configs.init(next); + } + }); } -function setIfPaired(key1, key2) { +function setIfPaired(key1, key2, callback) { var meta = require('./meta'); if (install.values[key1] && install.values[key2]) { - meta.configs.setOnEmpty(key1, install.values[key1]); - meta.configs.setOnEmpty(key2, install.values[key2]); + async.parallel([ + async.apply(meta.configs.setOnEmpty, key1, install.values[key1]), + async.apply(meta.configs.setOnEmpty, key2, install.values[key2]) + ], callback); + } else { + callback(); } } From 349de1694d4759154983a18a3ccfa96380b9c3d1 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 24 May 2015 10:15:16 -0400 Subject: [PATCH 073/237] fixed log line in web installer --- install/web.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/web.js b/install/web.js index 0587238244..9d53349724 100644 --- a/install/web.js +++ b/install/web.js @@ -41,8 +41,7 @@ web.install = function(port) { function launchExpress(port) { server = app.listen(port, function() { - var host = server.address().address; - winston.info('Web installer listening on http://%s:%s', host, port); + winston.info('Web installer listening on http://%s:%s', '0.0.0.0', port); }); } From b2f2561e745b044117c9b2a8d74bbb8df0f26f24 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 24 May 2015 10:39:52 -0400 Subject: [PATCH 074/237] adding a bit of logging when launching NodeBB from the web installer --- install/web.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/web.js b/install/web.js index 9d53349724..673e9c22fd 100644 --- a/install/web.js +++ b/install/web.js @@ -103,6 +103,9 @@ function launch(req, res) { stdio: ['ignore', 'ignore', 'ignore'] }); + process.stdout.write('\nStarting NodeBB\n'); + process.stdout.write(' "./nodebb stop" to stop the NodeBB server\n'); + process.stdout.write(' "./nodebb log" to view server output\n'); child.unref(); process.exit(0); From d8e52d7ebf6b40aabc04f45f8f6bf0cd4daa67b5 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 25 May 2015 13:27:59 -0400 Subject: [PATCH 075/237] closes https://github.com/NodeBB/nodebb-theme-persona/issues/87 --- src/socket.io/categories.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/socket.io/categories.js b/src/socket.io/categories.js index 8ed8881f68..dd2e130010 100644 --- a/src/socket.io/categories.js +++ b/src/socket.io/categories.js @@ -78,6 +78,11 @@ SocketCategories.loadMore = function(socket, data, callback) { } data.privileges = results.privileges; + data.template = { + category: true, + name: 'category' + }; + callback(null, data); }); }); From a0a8d328d0b05421fd70295d0ab9388ad2687c45 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 25 May 2015 14:05:52 -0400 Subject: [PATCH 076/237] closes #3182 --- src/install.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/install.js b/src/install.js index 93597029f6..ed9616ffc3 100644 --- a/src/install.js +++ b/src/install.js @@ -422,10 +422,17 @@ function createCategories(next) { } function createMenuItems(next) { - var navigation = require('./navigation/admin'), - data = require('../install/data/navigation.json'); + var db = require('./database'); - navigation.save(data, next); + db.exists('navigation:enabled', function(err, exists) { + if (err || exists) { + return next(err); + } + var navigation = require('./navigation/admin'), + data = require('../install/data/navigation.json'); + + navigation.save(data, next); + }); } function createWelcomePost(next) { From fc2efb0c83ad46aad5ee6b9047aee440a772915e Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 25 May 2015 14:47:54 -0400 Subject: [PATCH 077/237] added one more line to stdout when nodebb status is invoked, or nodebb web installer finishes --- install/web.js | 1 + nodebb | 1 + 2 files changed, 2 insertions(+) diff --git a/install/web.js b/install/web.js index 673e9c22fd..0c7fb2521f 100644 --- a/install/web.js +++ b/install/web.js @@ -106,6 +106,7 @@ function launch(req, res) { process.stdout.write('\nStarting NodeBB\n'); process.stdout.write(' "./nodebb stop" to stop the NodeBB server\n'); process.stdout.write(' "./nodebb log" to view server output\n'); + process.stdout.write(' "./nodebb restart" to restart NodeBB\n'); child.unref(); process.exit(0); diff --git a/nodebb b/nodebb index 6e0e4f679e..d45163ee32 100755 --- a/nodebb +++ b/nodebb @@ -28,6 +28,7 @@ case "$1" in echo "Starting NodeBB"; echo " \"./nodebb stop\" to stop the NodeBB server"; echo " \"./nodebb log\" to view server output"; + echo " \"./nodebb restart\" to restart NodeBB"; # Start the loader daemon "$node" loader "$@" From e6061810f938c70a654a71e108b0ef4fee38d213 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 25 May 2015 16:06:49 -0400 Subject: [PATCH 078/237] updating nodebb executable so that it is a node script instead of bash script --- nodebb | 244 +++++++++++++++++++++++++-------------------------- package.json | 10 ++- 2 files changed, 124 insertions(+), 130 deletions(-) diff --git a/nodebb b/nodebb index d45163ee32..dd05fbf841 100755 --- a/nodebb +++ b/nodebb @@ -1,138 +1,130 @@ -#!/bin/bash +#!/usr/bin/env node -# $0 script path -# $1 action -# $2 subaction +var colors = require('colors'), + cproc = require('child_process'), + argv = require('minimist')(process.argv.slice(2)), + fs = require('fs'); -node="$(which nodejs 2>/dev/null)"; -if [ $? -gt 0 ]; - then node="$(which node)"; -fi +var getRunningPid = function(callback) { + fs.readFile(__dirname + '/pidfile', { + encoding: 'utf-8' + }, function(err, pid) { + if (err) { + return callback(err); + } -function pidExists() { - if [ -e "pidfile" ]; - then - if ps -p $(cat pidfile) > /dev/null - then return 1; - else - rm ./pidfile; - return 0; - fi - else - return 0; - fi + try { + process.kill(parseInt(pid, 10), 0); + callback(null, parseInt(pid, 10)); + } catch(e) { + callback(e); + } + }); + }; + +switch(process.argv[2]) { + case 'status': + getRunningPid(function(err, pid) { + if (!err) { + process.stdout.write('\nNodeBB Running '.bold + '(pid '.cyan + pid.toString().cyan + ')\n'.cyan); + process.stdout.write('\t"' + './nodebb stop'.yellow + '" to stop the NodeBB server\n'); + process.stdout.write('\t"' + './nodebb log'.yellow + '" to view server output\n'); + process.stdout.write('\t"' + './nodebb restart'.yellow + '" to restart NodeBB\n\n'); + } else { + process.stdout.write('\nNodeBB is not running\n'.bold); + process.stdout.write('\t"' + './nodebb start'.yellow + '" to launch the NodeBB server\n\n'); + } + }) + break; + + case 'start': + process.stdout.write('\nStarting NodeBB\n'.bold); + process.stdout.write(' "' + './nodebb stop'.yellow + '" to stop the NodeBB server\n'); + process.stdout.write(' "' + './nodebb log'.yellow + '" to view server output\n'); + process.stdout.write(' "' + './nodebb restart'.yellow + '" to restart NodeBB\n\n'); + + // Spawn a new NodeBB process + cproc.fork(__dirname + '/loader.js', { + env: process.env, + detatched: true + }); + break; + + case 'stop': + getRunningPid(function(err, pid) { + if (!err) { + process.kill(pid, 'SIGTERM'); + process.stdout.write('Stopping NodeBB. Goodbye!\n') + } else { + process.stdout.write('NodeBB is already stopped.\n'); + } + }); + break; + + case 'restart': + getRunningPid(function(err, pid) { + if (!err) { + process.kill(pid, 'SIGHUP'); + } else { + process.stdout.write('NodeBB could not be restarted, as a running instance could not be found.'); + } + }); + break; + + case 'reload': + getRunningPid(function(err, pid) { + if (!err) { + process.kill(pid, 'SIGUSR2'); + } else { + process.stdout.write('NodeBB could not be reloaded, as a running instance could not be found.'); + } + }); + break; + + case 'dev': + process.env.NODE_ENV = 'development'; + cproc.fork(__dirname + '/loader.js', ['--no-daemon', '--no-silent'], { + env: process.env + }); + break; + + default: + process.stdout.write('\nWelcome to NodeBB\n\n'.bold); + process.stdout.write('Usage: ./nodebb {start|stop|reload|restart|log|setup|reset|upgrade|dev}\n\n'); + process.stdout.write('\t' + 'start'.yellow + '\tStart the NodeBB server\n'); + process.stdout.write('\t' + 'stop'.yellow + '\tStops the NodeBB server\n'); + process.stdout.write('\t' + 'reload'.yellow + '\tRestarts NodeBB\n'); + process.stdout.write('\t' + 'restart'.yellow + '\tRestarts NodeBB\n'); + process.stdout.write('\t' + 'log'.yellow + '\tOpens the logging interface (useful for debugging)\n'); + process.stdout.write('\t' + 'setup'.yellow + '\tRuns the NodeBB setup script\n'); + process.stdout.write('\t' + 'reset'.yellow + '\tDisables all plugins, restores the default theme.\n'); + process.stdout.write('\t' + 'upgrade'.yellow + '\tRun NodeBB upgrade scripts, ensure packages are up-to-date\n'); + process.stdout.write('\t' + 'dev'.yellow + '\tStart NodeBB in interactive development mode\n'); + process.stdout.write('\t' + 'watch'.yellow + '\tStart NodeBB in development mode and watch for changes\n'); + process.stdout.write('\n'); + break; } -case "$1" in - start) - echo "Starting NodeBB"; - echo " \"./nodebb stop\" to stop the NodeBB server"; - echo " \"./nodebb log\" to view server output"; - echo " \"./nodebb restart\" to restart NodeBB"; - - # Start the loader daemon - "$node" loader "$@" - ;; - - stop) - pidExists; - if [ 0 -eq $? ]; - then - echo "NodeBB is already stopped."; - else - echo "Stopping NodeBB. Goodbye!"; - kill $(cat pidfile); - fi - ;; - - restart) - pidExists; - if [ 0 -eq $? ]; - then - echo "NodeBB could not be restarted, as a running instance could not be found."; - else - echo "Restarting NodeBB."; - kill -1 $(cat pidfile); - fi - ;; - - reload) - pidExists; - if [ 0 -eq $? ]; - then - echo "NodeBB could not be reloaded, as a running instance could not be found."; - else - echo "Reloading NodeBB."; - kill -12 $(cat pidfile); - fi - ;; - - status) - pidExists; - if [ 0 -eq $? ]; - then - echo "NodeBB is not running"; - echo " \"./nodebb start\" to launch the NodeBB server"; - else - echo "NodeBB Running (pid $(cat pidfile))"; - echo " \"./nodebb stop\" to stop the NodeBB server"; - echo " \"./nodebb log\" to view server output"; - echo " \"./nodebb restart\" to restart NodeBB"; - fi - ;; - +/* log) - clear; - tail -F ./logs/output.log; - ;; + clear; + tail -F ./logs/output.log; + ;; upgrade) - npm install - # ls -d node_modules/nodebb* | xargs -n1 basename | xargs npm install - # ls -d node_modules/nodebb* | xargs -n1 basename | xargs npm update - npm i nodebb-theme-vanilla nodebb-theme-lavender nodebb-widget-essentials - "$node" app --upgrade - touch package.json - ;; + npm install + # ls -d node_modules/nodebb* | xargs -n1 basename | xargs npm install + # ls -d node_modules/nodebb* | xargs -n1 basename | xargs npm update + npm i nodebb-theme-vanilla nodebb-theme-lavender nodebb-widget-essentials + "$node" app --upgrade + touch package.json + ;; setup) - "$node" app --setup "$@" - ;; + "$node" app --setup "$@" + ;; reset) - "$node" app --reset --$2 - ;; - - dev) - echo "Launching NodeBB in \"development\" mode." - echo "To run the production build of NodeBB, please use \"forever\"." - echo "More Information: https://docs.nodebb.org/en/latest/running/index.html" - NODE_ENV=development "$node" loader --no-daemon --no-silent "$@" - ;; - - watch) - echo "***************************************************************************" - echo "WARNING: ./nodebb watch will be deprecated soon. Please use grunt: " - echo "https://docs.nodebb.org/en/latest/running/index.html#grunt-development" - echo "***************************************************************************" - NODE_ENV=development supervisor -q --ignore public/templates,public/nodebb.min.js,public/nodebb.min.js.map --extensions 'node|js|tpl|less' -- app "$@" - ;; - - *) - echo "Welcome to NodeBB" - echo $"Usage: $0 {start|stop|reload|restart|log|setup|reset|upgrade|dev|watch}" - echo '' - column -s ' ' -t <<< ' - start Start the NodeBB server - stop Stops the NodeBB server - reload Restarts NodeBB - restart Restarts NodeBB - log Opens the logging interface (useful for debugging) - setup Runs the NodeBB setup script - reset Disables all plugins, restores the default theme. - upgrade Run NodeBB upgrade scripts, ensure packages are up-to-date - dev Start NodeBB in interactive development mode - watch Start NodeBB in development mode and watch for changes - ' - exit 1 -esac + "$node" app --reset --$2 + ;; +*/ \ No newline at end of file diff --git a/package.json b/package.json index 27d4933f94..6fd4275862 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "async": "~0.9.0", "bcryptjs": "~2.1.0", "body-parser": "^1.9.0", + "colors": "^1.1.0", "compression": "^1.1.0", "connect-ensure-login": "^0.1.1", "connect-flash": "^0.1.1", @@ -34,6 +35,7 @@ "logrotate-stream": "^0.2.3", "lru-cache": "^2.6.1", "mime": "^1.3.4", + "minimist": "^1.1.1", "mkdirp": "~0.5.0", "mmmagic": "^0.3.13", "morgan": "^1.3.2", @@ -44,11 +46,11 @@ "nodebb-plugin-mentions": "^0.11.2", "nodebb-plugin-soundpack-default": "^0.1.1", "nodebb-plugin-spam-be-gone": "^0.4.0", - "nodebb-theme-lavender": "^1.0.42", - "nodebb-theme-vanilla": "^1.0.130", - "nodebb-theme-persona": "^0.1.55", - "nodebb-widget-essentials": "^1.0.2", "nodebb-rewards-essentials": "^0.0.1", + "nodebb-theme-lavender": "^1.0.42", + "nodebb-theme-persona": "^0.1.55", + "nodebb-theme-vanilla": "^1.0.130", + "nodebb-widget-essentials": "^1.0.2", "npm": "^2.1.4", "passport": "^0.2.1", "passport-local": "1.0.0", From 4a0bc1fb030e50f6b6e05254b1bb865e8856d18c Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 25 May 2015 21:08:05 -0400 Subject: [PATCH 079/237] finished up executable rewrite, and prettified reset script output --- app.js | 34 +++++++++++++------- nodebb | 88 +++++++++++++++++++++++++++++++++++++--------------- package.json | 1 + 3 files changed, 86 insertions(+), 37 deletions(-) diff --git a/app.js b/app.js index 8ff5647023..4e677df7c1 100644 --- a/app.js +++ b/app.js @@ -29,6 +29,7 @@ var fs = require('fs'), async = require('async'), semver = require('semver'), winston = require('winston'), + colors = require('colors'), path = require('path'), pkg = require('./package.json'), utils = require('./public/src/utils.js'); @@ -274,17 +275,19 @@ function reset() { process.exit(); } - if (nconf.get('theme')) { + if (nconf.get('t')) { resetThemes(); - } else if (nconf.get('plugin')) { - resetPlugin(nconf.get('plugin')); - } else if (nconf.get('plugins')) { - resetPlugins(); - } else if (nconf.get('widgets')) { + } else if (nconf.get('p')) { + if (nconf.get('p') === true) { + resetPlugins(); + } else { + resetPlugin(nconf.get('p')); + } + } else if (nconf.get('w')) { resetWidgets(); - } else if (nconf.get('settings')) { + } else if (nconf.get('s')) { resetSettings(); - } else if (nconf.get('all')) { + } else if (nconf.get('a')) { require('async').series([resetWidgets, resetThemes, resetPlugins, resetSettings], function(err) { if (!err) { winston.info('[reset] Reset complete.'); @@ -294,10 +297,17 @@ function reset() { process.exit(); }); } else { - winston.warn('[reset] Nothing reset.'); - winston.info('Use ./nodebb reset {theme|plugins|widgets|settings|all}'); - winston.info(' or'); - winston.info('Use ./nodebb reset plugin="nodebb-plugin-pluginName"'); + process.stdout.write('\nNodeBB Reset\n'.bold); + process.stdout.write('No arguments passed in, so nothing was reset.\n\n'.yellow); + process.stdout.write('Use ./nodebb reset ' + '{-t|-p|-w|-s|-a}\n'.red); + process.stdout.write(' -t\tthemes\n'); + process.stdout.write(' -p\tplugins\n'); + process.stdout.write(' -w\twidgets\n'); + process.stdout.write(' -s\tsettings\n'); + process.stdout.write(' -a\tall of the above\n'); + + process.stdout.write('\nPlugin reset flag (-p) can take a single argument\n'); + process.stdout.write(' e.g. ./nodebb reset -p nodebb-plugin-mentions\n'); process.exit(); } }); diff --git a/nodebb b/nodebb index dd05fbf841..37a783ec79 100755 --- a/nodebb +++ b/nodebb @@ -3,7 +3,10 @@ var colors = require('colors'), cproc = require('child_process'), argv = require('minimist')(process.argv.slice(2)), - fs = require('fs'); + fs = require('fs'), + async = require('async'), + touch = require('touch'), + npm = require('npm'); var getRunningPid = function(callback) { fs.readFile(__dirname + '/pidfile', { @@ -88,6 +91,65 @@ switch(process.argv[2]) { }); break; + case 'log': + process.stdout.write('\nType '.red + 'Ctrl-C '.bold + 'to exit\n\n'.red); + cproc.spawn('tail', ['-F', './logs/output.log'], { + cwd: __dirname, + stdio: 'inherit' + }); + break; + + case 'setup': + cproc.fork('app.js', ['--setup'], { + cwd: __dirname, + silent: false + }); + break; + + case 'reset': + var args = process.argv.slice(0); + args.unshift('--reset'); + + cproc.fork('app.js', args, { + cwd: __dirname, + silent: false + }); + break; + + case 'upgrade': + async.series([ + function(next) { + process.stdout.write('1. '.bold + 'Bringing base dependencies up to date\n'.yellow); + npm.load({ + loglevel: 'silent' + }, function() { + npm.commands.install(next); + }); + }, + function(next) { + process.stdout.write('2. '.bold + 'Updating NodeBB data store schema\n'.yellow); + var upgradeProc = cproc.fork('app.js', ['--upgrade'], { + cwd: __dirname, + silent: false + }); + + upgradeProc.on('close', next) + }, + function(next) { + process.stdout.write('3. '.bold + 'Storing upgrade date in "package.json"\n'.yellow); + touch(__dirname + '/package.json', {}, next); + } + ], function(err) { + if (err) { + process.stdout.write('\nError'.red + ': ' + err.message + '\n'); + } else { + var message = 'NodeBB Upgrade Complete!', + spaces = new Array(Math.floor(process.stdout.columns / 2) - (message.length / 2) + 1).join(' '); + process.stdout.write('\n' + spaces + message.green.bold + '\n\n'); + } + }); + break; + default: process.stdout.write('\nWelcome to NodeBB\n\n'.bold); process.stdout.write('Usage: ./nodebb {start|stop|reload|restart|log|setup|reset|upgrade|dev}\n\n'); @@ -104,27 +166,3 @@ switch(process.argv[2]) { process.stdout.write('\n'); break; } - -/* - log) - clear; - tail -F ./logs/output.log; - ;; - - upgrade) - npm install - # ls -d node_modules/nodebb* | xargs -n1 basename | xargs npm install - # ls -d node_modules/nodebb* | xargs -n1 basename | xargs npm update - npm i nodebb-theme-vanilla nodebb-theme-lavender nodebb-widget-essentials - "$node" app --upgrade - touch package.json - ;; - - setup) - "$node" app --setup "$@" - ;; - - reset) - "$node" app --reset --$2 - ;; -*/ \ No newline at end of file diff --git a/package.json b/package.json index 6fd4275862..908cda8d9c 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "socketio-wildcard": "~0.1.1", "string": "^3.0.0", "templates.js": "^0.2.3", + "touch": "0.0.3", "uglify-js": "git+https://github.com/julianlam/UglifyJS2.git", "underscore": "~1.8.3", "validator": "^3.30.0", From cbb05429847ae882c71a5a4f0324b62f9454f002 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 26 May 2015 10:51:23 -0400 Subject: [PATCH 080/237] changed behaviour of privilege table so that groups without explicit privileges are not shown in the privilege table --- src/privileges/categories.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/privileges/categories.js b/src/privileges/categories.js index 59b2f79a1d..4572de2e92 100644 --- a/src/privileges/categories.js +++ b/src/privileges/categories.js @@ -101,19 +101,25 @@ module.exports = function(privileges) { groupNames.splice(0, 0, groupNames.splice(groupNames.indexOf('registered-users'), 1)[0]); groupNames.splice(groupNames.indexOf('administrators'), 1); - var memberData = groupNames.filter(function(member) { + var memberPrivs, boolSet, + memberData = groupNames.filter(function(member) { return member.indexOf(':privileges:') === -1; }).map(function(member) { - var memberPrivs = {}; + memberPrivs = {}; + boolSet = []; // Here, the boolSet is used as a quick way to determine whether a given group's privilege set is empty or not (see below) for(var x=0,numPrivs=privileges.length;x Date: Tue, 26 May 2015 11:52:34 -0400 Subject: [PATCH 081/237] allowing array of privileges to be passed into setPrivilege in category admin socket listener --- src/socket.io/admin/categories.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/socket.io/admin/categories.js b/src/socket.io/admin/categories.js index 4db4445d4d..848d175a09 100644 --- a/src/socket.io/admin/categories.js +++ b/src/socket.io/admin/categories.js @@ -59,7 +59,13 @@ Categories.setPrivilege = function(socket, data, callback) { return callback(new Error('[[error:invalid-data]]')); } - groups[data.set ? 'join' : 'leave']('cid:' + data.cid + ':privileges:' + data.privilege, data.member, callback); + if (Array.isArray(data.privilege)) { + async.each(data.privilege, function(privilege, next) { + groups[data.set ? 'join' : 'leave']('cid:' + data.cid + ':privileges:' + privilege, data.member, next); + }, callback); + } else { + groups[data.set ? 'join' : 'leave']('cid:' + data.cid + ':privileges:' + data.privilege, data.member, callback); + } }; Categories.getPrivilegeSettings = function(socket, cid, callback) { From 8f7416d1cb074655c9ebcb848468ff687e69eed4 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 26 May 2015 12:35:27 -0400 Subject: [PATCH 082/237] updated acp category privilege settings so that not all groups are shown in privilege table, closes #3036 --- public/less/admin/admin.less | 5 + public/src/admin/manage/category.js | 83 +++++++++--- public/src/modules/autocomplete.js | 31 +++++ src/views/admin/manage/category.tpl | 6 +- .../admin/partials/categories/privileges.tpl | 123 +++++++++++------- 5 files changed, 175 insertions(+), 73 deletions(-) diff --git a/public/less/admin/admin.less b/public/less/admin/admin.less index 40ddcf08e3..8ab5c633e9 100644 --- a/public/less/admin/admin.less +++ b/public/less/admin/admin.less @@ -283,6 +283,11 @@ #taskbar { display: none; /* not sure why I have to do this, but it only seems to show up on prod */ } + + /* Allows the autocomplete dropbox to appear on top of a modal's backdrop */ + .ui-autocomplete { + z-index: @zindex-popover; + } } // Allowing text to the right of an image-type brand diff --git a/public/src/admin/manage/category.js b/public/src/admin/manage/category.js index 238317144c..6524ed8b37 100644 --- a/public/src/admin/manage/category.js +++ b/public/src/admin/manage/category.js @@ -158,26 +158,6 @@ define('admin/manage/category', [ }; Category.setupPrivilegeTable = function() { - var searchEl = $('.privilege-search'), - searchObj = autocomplete.user(searchEl); - - // User search + addition to table - searchObj.on('autocompleteselect', function(ev, ui) { - socket.emit('admin.categories.setPrivilege', { - cid: ajaxify.variables.get('cid'), - privilege: 'read', - set: true, - member: ui.item.user.uid - }, function(err) { - if (err) { - return app.alertError(err.message); - } - - Category.refreshPrivilegeTable(); - searchEl.val(''); - }); - }); - // Checkbox event capture $('.privilege-table-container').on('change', 'input[type="checkbox"]', function() { var checkboxEl = $(this), @@ -205,6 +185,9 @@ define('admin/manage/category', [ } }); + $('.privilege-table-container').on('click', '[data-action="search.user"]', Category.addUserToPrivilegeTable); + $('.privilege-table-container').on('click', '[data-action="search.group"]', Category.addGroupToPrivilegeTable); + Category.exposeAssumedPrivileges(); }; @@ -292,5 +275,65 @@ define('admin/manage/category', [ }); }; + Category.addUserToPrivilegeTable = function() { + var modal = bootbox.dialog({ + title: 'Find a User', + message: '', + show: true + }); + + modal.on('shown.bs.modal', function() { + var inputEl = modal.find('input'), + searchObj = autocomplete.user(inputEl); + + searchObj.on('autocompleteselect', function(ev, ui) { + socket.emit('admin.categories.setPrivilege', { + cid: ajaxify.variables.get('cid'), + privilege: ['find', 'read'], + set: true, + member: ui.item.user.uid + }, function(err) { + if (err) { + return app.alertError(err.message); + } + + Category.refreshPrivilegeTable(); + modal.modal('hide'); + }); + }); + }); + }; + + Category.addGroupToPrivilegeTable = function() { + var modal = bootbox.dialog({ + title: 'Find a Group', + message: '', + show: true + }); + + modal.on('shown.bs.modal', function() { + var inputEl = modal.find('input'), + searchObj = autocomplete.group(inputEl); + + searchObj.on('autocompleteselect', function(ev, ui) { + console.log(ui); + socket.emit('admin.categories.setPrivilege', { + cid: ajaxify.variables.get('cid'), + privilege: ['groups:find', 'groups:read'], + set: true, + member: ui.item.group.name + }, function(err) { + console.log(arguments); + if (err) { + return app.alertError(err.message); + } + + Category.refreshPrivilegeTable(); + modal.modal('hide'); + }); + }); + }); + }; + return Category; }); \ No newline at end of file diff --git a/public/src/modules/autocomplete.js b/public/src/modules/autocomplete.js index 55c15b8686..8a6967a308 100644 --- a/public/src/modules/autocomplete.js +++ b/public/src/modules/autocomplete.js @@ -35,5 +35,36 @@ define('autocomplete', function() { }); }; + module.group = function(input) { + return input.autocomplete({ + delay: 100, + source: function(request, response) { + socket.emit('groups.search', { + query: request.term, + options: {} + }, function(err, results) { + if (err) { + return app.alertError(err.message); + } + + if (results && results.length) { + var names = results.map(function(group) { + return group && { + label: group.name, + value: group.name, + group: { + name: group.name, + slug: group.slug + } + }; + }); + response(names); + } + $('.ui-autocomplete a').attr('data-ajaxify', 'false'); + }); + } + }); + }; + return module; }); diff --git a/src/views/admin/manage/category.tpl b/src/views/admin/manage/category.tpl index 80b5dbe694..48d07b0e6c 100644 --- a/src/views/admin/manage/category.tpl +++ b/src/views/admin/manage/category.tpl @@ -86,9 +86,9 @@ these settings.


- -
- +
+ +
diff --git a/src/views/admin/partials/categories/privileges.tpl b/src/views/admin/partials/categories/privileges.tpl index 7e1f97b580..eb97e6bcac 100644 --- a/src/views/admin/partials/categories/privileges.tpl +++ b/src/views/admin/partials/categories/privileges.tpl @@ -1,51 +1,74 @@ -
- - - - - - - - - - - - - {function.spawnPrivilegeStates, privileges.users.username, privileges} - - - - - - - -
User{privileges.labels.users.name}
{privileges.users.username}
-
No user-specific privileges in this category.
-
+ + + + + + + + + + + + + {function.spawnPrivilegeStates, privileges.users.username, privileges} + + + + + + + + + + +
User{privileges.labels.users.name}
{privileges.users.username}
+ +
+
+ + No user-specific privileges in this category. +
+
- - - - - - - - - - - {function.spawnPrivilegeStates, name, privileges} - - -
Group{privileges.labels.groups.name}
- - - - {privileges.groups.name} -
-
- If the registered-users group is granted a specific privilege, all other groups receive an - implicit privilege, even if they are not explicitly defined/checked. This implicit - privilege is shown to you because all users are part of the registered-users user group, - and so, privileges for additional groups need not be explicitly granted. -
-
\ No newline at end of file + + + + + + + + + + + + + {function.spawnPrivilegeStates, name, privileges} + + + + + + + + + + +
Group{privileges.labels.groups.name}
+ + + + {privileges.groups.name} +
+ +
+
+ + No group-specific privileges in this category. +
+
+
+ If the registered-users group is granted a specific privilege, all other groups receive an + implicit privilege, even if they are not explicitly defined/checked. This implicit + privilege is shown to you because all users are part of the registered-users user group, + and so, privileges for additional groups need not be explicitly granted. +
From 8a225ad719fef6cda4ef1bcbf0dfdaaf309fa00d Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 26 May 2015 12:37:31 -0400 Subject: [PATCH 083/237] starting groups organization --- src/groups/create.js | 68 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/groups/create.js diff --git a/src/groups/create.js b/src/groups/create.js new file mode 100644 index 0000000000..efabac3fc5 --- /dev/null +++ b/src/groups/create.js @@ -0,0 +1,68 @@ +'use strict'; + +var async = require('async'), + meta = require('../meta'), + plugins = require('../plugins'), + utils = require('../../public/src/utils'), + db = require('./../database'); + +module.exports = function(Groups) { + Groups.create = function(data, callback) { + if (data.name.length === 0) { + return callback(new Error('[[error:group-name-too-short]]')); + } + + if (data.name === 'administrators' || data.name === 'registered-users' || Groups.internals.isPrivilegeGroup.test(data.name)) { + var system = true; + } + + meta.userOrGroupExists(data.name, function (err, exists) { + if (err) { + return callback(err); + } + + if (exists) { + return callback(new Error('[[error:group-already-exists]]')); + } + var timestamp = data.timestamp || Date.now(); + + var slug = utils.slugify(data.name), + groupData = { + name: data.name, + slug: slug, + createtime: timestamp, + userTitle: data.name, + description: data.description || '', + memberCount: 0, + deleted: '0', + hidden: data.hidden || '0', + system: system ? '1' : '0', + private: data.private || '1' + }, + tasks = [ + async.apply(db.sortedSetAdd, 'groups:createtime', timestamp, data.name), + async.apply(db.setObject, 'group:' + data.name, groupData) + ]; + + if (data.hasOwnProperty('ownerUid')) { + tasks.push(async.apply(db.setAdd, 'group:' + data.name + ':owners', data.ownerUid)); + tasks.push(async.apply(db.sortedSetAdd, 'group:' + data.name + ':members', timestamp, data.ownerUid)); + tasks.push(async.apply(db.setObjectField, 'group:' + data.name, 'memberCount', 1)); + + groupData.ownerUid = data.ownerUid; + } + + if (!data.hidden) { + tasks.push(async.apply(db.setObjectField, 'groupslug:groupname', slug, data.name)); + } + + async.series(tasks, function(err) { + if (!err) { + plugins.fireHook('action:group.create', groupData); + } + + callback(err, groupData); + }); + }); + }; +}; From 3f1726636fdbe40107c99715fc1c76c106bba924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 26 May 2015 13:17:49 -0400 Subject: [PATCH 084/237] groups create/delete/update --- src/groups.js | 261 ++----------------------------------------- src/groups/create.js | 2 +- src/groups/delete.js | 42 +++++++ src/groups/update.js | 165 +++++++++++++++++++++++++++ 4 files changed, 220 insertions(+), 250 deletions(-) create mode 100644 src/groups/delete.js create mode 100644 src/groups/update.js diff --git a/src/groups.js b/src/groups.js index 802f4346e2..7763353764 100644 --- a/src/groups.js +++ b/src/groups.js @@ -22,7 +22,11 @@ var async = require('async'), (function(Groups) { - var ephemeralGroups = ['guests'], + require('./groups/create')(Groups); + require('./groups/delete')(Groups); + require('./groups/update')(Groups); + + var ephemeralGroups = ['guests'], internals = { filterGroups: function(groups, options) { @@ -63,10 +67,14 @@ var async = require('async'), } return groups; - }, - isPrivilegeGroup: /^cid:\d+:privileges:[\w:]+$/ + } }; + var isPrivilegeGroupRegex = /^cid:\d+:privileges:[\w:]+$/; + Groups.isPrivilegeGroup = function(groupName) { + return isPrivilegeGroupRegex.test(groupName); + }; + Groups.getEphemeralGroups = function() { return ephemeralGroups; }; @@ -497,256 +505,11 @@ var async = require('async'), } }; - Groups.create = function(data, callback) { - if (data.name.length === 0) { - return callback(new Error('[[error:group-name-too-short]]')); - } - - if (data.name === 'administrators' || data.name === 'registered-users' || internals.isPrivilegeGroup.test(data.name)) { - var system = true; - } - - meta.userOrGroupExists(data.name, function (err, exists) { - if (err) { - return callback(err); - } - - if (exists) { - return callback(new Error('[[error:group-already-exists]]')); - } - var timestamp = data.timestamp || Date.now(); - - var slug = utils.slugify(data.name), - groupData = { - name: data.name, - slug: slug, - createtime: timestamp, - userTitle: data.name, - description: data.description || '', - memberCount: 0, - deleted: '0', - hidden: data.hidden || '0', - system: system ? '1' : '0', - private: data.private || '1' - }, - tasks = [ - async.apply(db.sortedSetAdd, 'groups:createtime', timestamp, data.name), - async.apply(db.setObject, 'group:' + data.name, groupData) - ]; - - if (data.hasOwnProperty('ownerUid')) { - tasks.push(async.apply(db.setAdd, 'group:' + data.name + ':owners', data.ownerUid)); - tasks.push(async.apply(db.sortedSetAdd, 'group:' + data.name + ':members', timestamp, data.ownerUid)); - tasks.push(async.apply(db.setObjectField, 'group:' + data.name, 'memberCount', 1)); - - groupData.ownerUid = data.ownerUid; - } - - if (!data.hidden) { - tasks.push(async.apply(db.setObjectField, 'groupslug:groupname', slug, data.name)); - } - - async.series(tasks, function(err) { - if (!err) { - plugins.fireHook('action:group.create', groupData); - } - - callback(err, groupData); - }); - }); - }; - Groups.hide = function(groupName, callback) { callback = callback || function() {}; db.setObjectField('group:' + groupName, 'hidden', 1, callback); }; - Groups.update = function(groupName, values, callback) { - callback = callback || function() {}; - db.exists('group:' + groupName, function (err, exists) { - if (err || !exists) { - return callback(err || new Error('[[error:no-group]]')); - } - - var payload = { - description: values.description || '', - icon: values.icon || '', - labelColor: values.labelColor || '#000000' - }; - - if (values.hasOwnProperty('userTitle')) { - payload.userTitle = values.userTitle || ''; - } - - if (values.hasOwnProperty('userTitleEnabled')) { - payload.userTitleEnabled = values.userTitleEnabled ? '1' : '0'; - } - - if (values.hasOwnProperty('hidden')) { - payload.hidden = values.hidden ? '1' : '0'; - } - - if (values.hasOwnProperty('private')) { - payload.private = values.private ? '1' : '0'; - } - - 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); - } - - plugins.fireHook('action:group.update', { - name: groupName, - values: values - }); - callback(); - }); - }); - }; - - function updatePrivacy(groupName, newValue, callback) { - if (!newValue) { - return callback(); - } - - Groups.getGroupFields(groupName, ['private'], function(err, currentValue) { - if (err) { - return callback(err); - } - currentValue = currentValue.private === '1'; - - 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(); - } - - db.getObject('group:' + oldName, function(err, group) { - if (err || !group) { - return callback(err); - } - - if (parseInt(group.system, 10) === 1 || parseInt(group.hidden, 10) === 1) { - return callback(); - } - - Groups.exists(newName, function(err, exists) { - if (err || exists) { - return callback(err || new Error('[[error:group-already-exists]]')); - } - - async.series([ - async.apply(db.setObjectField, 'group:' + oldName, 'name', newName), - async.apply(db.setObjectField, 'group:' + oldName, 'slug', utils.slugify(newName)), - async.apply(db.deleteObjectField, 'groupslug:groupname', group.slug), - async.apply(db.setObjectField, 'groupslug:groupname', utils.slugify(newName), newName), - function(next) { - db.getSortedSetRange('groups:createtime', 0, -1, function(err, groups) { - if (err) { - return next(err); - } - async.each(groups, function(group, next) { - renameGroupMember('group:' + group + ':members', oldName, newName, next); - }, next); - }); - }, - async.apply(db.rename, 'group:' + oldName, 'group:' + newName), - async.apply(db.rename, 'group:' + oldName + ':members', 'group:' + newName + ':members'), - async.apply(db.rename, 'group:' + oldName + ':owners', 'group:' + newName + ':owners'), - async.apply(db.rename, 'group:' + oldName + ':pending', 'group:' + newName + ':pending'), - async.apply(db.rename, 'group:' + oldName + ':invited', 'group:' + newName + ':invited'), - async.apply(renameGroupMember, 'groups:createtime', oldName, newName), - function(next) { - plugins.fireHook('action:group.rename', { - old: oldName, - new: newName - }); - - next(); - } - ], callback); - }); - }); - } - - function renameGroupMember(group, oldName, newName, callback) { - db.isSortedSetMember(group, oldName, function(err, isMember) { - if (err || !isMember) { - return callback(err); - } - var score; - async.waterfall([ - function (next) { - db.sortedSetScore(group, oldName, next); - }, - function (_score, next) { - score = _score; - db.sortedSetRemove(group, oldName, next); - }, - function (next) { - db.sortedSetAdd(group, score, newName, next); - } - ], callback); - }); - } - - Groups.destroy = function(groupName, callback) { - Groups.getGroupsData([groupName], function(err, groupsData) { - if (err) { - return callback(err); - } - if (!Array.isArray(groupsData) || !groupsData[0]) { - return callback(); - } - var groupObj = groupsData[0]; - plugins.fireHook('action:group.destroy', groupObj); - - async.parallel([ - async.apply(db.delete, 'group:' + groupName), - async.apply(db.sortedSetRemove, 'groups:createtime', groupName), - async.apply(db.delete, 'group:' + groupName + ':members'), - async.apply(db.delete, 'group:' + groupName + ':pending'), - async.apply(db.delete, 'group:' + groupName + ':invited'), - async.apply(db.delete, 'group:' + groupName + ':owners'), - async.apply(db.deleteObjectField, 'groupslug:groupname', utils.slugify(groupName)), - function(next) { - db.getSortedSetRange('groups:createtime', 0, -1, function(err, groups) { - if (err) { - return next(err); - } - async.each(groups, function(group, next) { - db.sortedSetRemove('group:' + group + ':members', groupName, next); - }, next); - }); - } - ], callback); - }); - }; - Groups.join = function(groupName, uid, callback) { function join() { var tasks = [ @@ -1159,7 +922,7 @@ var async = require('async'), function(users, next) { var uids = []; for(var i=0; i Date: Tue, 26 May 2015 13:44:52 -0400 Subject: [PATCH 085/237] dont call groups.get just to read 2 values --- src/groups.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/groups.js b/src/groups.js index 7763353764..e6acafcd80 100644 --- a/src/groups.js +++ b/src/groups.js @@ -647,13 +647,12 @@ var async = require('async'), uid: uid }); - // If this is a hidden group, and it is now empty, delete it - Groups.get(groupName, {}, function(err, group) { - if (err || !group) { + Groups.getGroupFields(groupName, ['hidden', 'memberCount'], function(err, groupData) { + if (err || !groupData) { return callback(err); } - if (group.hidden && group.memberCount === 0) { + if (parseInt(groupData.hidden, 10) === 1 && parseInt(groupData.memberCount, 10) === 0) { Groups.destroy(groupName, callback); } else { callback(); From 8300aeec3529fbf45a9b37649393309970ab052a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 26 May 2015 13:55:40 -0400 Subject: [PATCH 086/237] parseInt member count, use getMemberCount in install js --- src/groups.js | 7 ++++++- src/install.js | 7 +++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/groups.js b/src/groups.js index e6acafcd80..0c667c9871 100644 --- a/src/groups.js +++ b/src/groups.js @@ -363,7 +363,12 @@ var async = require('async'), }; Groups.getMemberCount = function(groupName, callback) { - db.getObjectField('group:' + groupName, 'memberCount', callback); + db.getObjectField('group:' + groupName, 'memberCount', function(err, count) { + if (err) { + return callback(err); + } + callback(null, parseInt(count, 10)); + }); }; Groups.isMemberOfGroupList = function(uid, groupListKey, callback) { diff --git a/src/install.js b/src/install.js index ed9616ffc3..9aafa5d598 100644 --- a/src/install.js +++ b/src/install.js @@ -294,8 +294,11 @@ function enableDefaultTheme(next) { function createAdministrator(next) { var Groups = require('./groups'); - Groups.get('administrators', {}, function (err, groupObj) { - if (!err && groupObj && groupObj.memberCount > 0) { + Groups.getMemberCount('administrators', function (err, memberCount) { + if (err) { + return next(err); + } + if (memberCount > 0) { process.stdout.write('Administrator found, skipping Admin setup\n'); next(); } else { From aca5d24a7d83916fcf4ebf22560a7e05c34a30c2 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 26 May 2015 14:45:17 -0400 Subject: [PATCH 087/237] split groups.js into more subsidiary files --- src/groups.js | 482 +-------------------------------------- src/groups/membership.js | 317 +++++++++++++++++++++++++ src/groups/ownership.js | 31 +++ src/groups/search.js | 86 +++++++ src/groups/update.js | 73 +++++- 5 files changed, 510 insertions(+), 479 deletions(-) create mode 100644 src/groups/membership.js create mode 100644 src/groups/ownership.js create mode 100644 src/groups/search.js diff --git a/src/groups.js b/src/groups.js index 0c667c9871..17d39c413b 100644 --- a/src/groups.js +++ b/src/groups.js @@ -2,8 +2,6 @@ var async = require('async'), winston = require('winston'), - _ = require('underscore'), - crypto = require('crypto'), path = require('path'), nconf = require('nconf'), fs = require('fs'), @@ -16,15 +14,16 @@ var async = require('async'), posts = require('./posts'), privileges = require('./privileges'), utils = require('../public/src/utils'), - util = require('util'), - - uploadsController = require('./controllers/uploads'); + util = require('util'); (function(Groups) { require('./groups/create')(Groups); require('./groups/delete')(Groups); require('./groups/update')(Groups); + require('./groups/membership')(Groups); + require('./groups/ownership')(Groups); + require('./groups/search')(Groups); var ephemeralGroups = ['guests'], @@ -70,6 +69,8 @@ var async = require('async'), } }; + Groups.internals = internals; + var isPrivilegeGroupRegex = /^cid:\d+:privileges:[\w:]+$/; Groups.isPrivilegeGroup = function(groupName) { return isPrivilegeGroupRegex.test(groupName); @@ -330,144 +331,6 @@ var async = require('async'), }); }; - Groups.getMembers = function(groupName, start, stop, callback) { - db.getSortedSetRevRange('group:' + groupName + ':members', start, stop, callback); - }; - - Groups.getMembersOfGroups = function(groupNames, callback) { - db.getSortedSetsMembers(groupNames.map(function(name) { - return 'group:' + name + ':members'; - }), callback); - }; - - Groups.isMember = function(uid, groupName, callback) { - if (!uid || parseInt(uid, 10) <= 0) { - return callback(null, false); - } - db.isSortedSetMember('group:' + groupName + ':members', uid, callback); - }; - - Groups.isMembers = function(uids, groupName, callback) { - db.isSortedSetMembers('group:' + groupName + ':members', uids, callback); - }; - - Groups.isMemberOfGroups = function(uid, groups, callback) { - if (!uid || parseInt(uid, 10) <= 0) { - return callback(null, groups.map(function() {return false;})); - } - groups = groups.map(function(groupName) { - return 'group:' + groupName + ':members'; - }); - - db.isMemberOfSortedSets(groups, uid, callback); - }; - - Groups.getMemberCount = function(groupName, callback) { - db.getObjectField('group:' + groupName, 'memberCount', function(err, count) { - if (err) { - return callback(err); - } - callback(null, parseInt(count, 10)); - }); - }; - - Groups.isMemberOfGroupList = function(uid, groupListKey, callback) { - db.getSortedSetRange('group:' + groupListKey + ':members', 0, -1, function(err, groupNames) { - if (err) { - return callback(err); - } - groupNames = internals.removeEphemeralGroups(groupNames); - if (groupNames.length === 0) { - return callback(null, false); - } - - Groups.isMemberOfGroups(uid, groupNames, function(err, isMembers) { - if (err) { - return callback(err); - } - - callback(null, isMembers.indexOf(true) !== -1); - }); - }); - }; - - Groups.isMemberOfGroupsList = function(uid, groupListKeys, callback) { - var sets = groupListKeys.map(function(groupName) { - return 'group:' + groupName + ':members'; - }); - - db.getSortedSetsMembers(sets, function(err, members) { - if (err) { - return callback(err); - } - - var uniqueGroups = _.unique(_.flatten(members)); - uniqueGroups = internals.removeEphemeralGroups(uniqueGroups); - - Groups.isMemberOfGroups(uid, uniqueGroups, function(err, isMembers) { - if (err) { - return callback(err); - } - - var map = {}; - - uniqueGroups.forEach(function(groupName, index) { - map[groupName] = isMembers[index]; - }); - - var result = members.map(function(groupNames) { - for (var i=0; i