diff --git a/public/language/nl/error.json b/public/language/nl/error.json
index cf918a18db..bfe113c836 100644
--- a/public/language/nl/error.json
+++ b/public/language/nl/error.json
@@ -78,7 +78,7 @@
"too-many-messages": "Er zijn in korte tijd teveel berichten verzonden, een moment geduld.",
"invalid-chat-message": "Ongeldig bericht",
"chat-message-too-long": "Het chatbericht is te lang",
- "cant-edit-chat-message": "You are not allowed to edit this message",
+ "cant-edit-chat-message": "Het is niet toegestaan om dit bericht aan te passen",
"reputation-system-disabled": "Reputatie systeem is uitgeschakeld.",
"downvoting-disabled": "Negatief stemmen staat uitgeschakeld.",
"not-enough-reputation-to-downvote": "Dit gebruikersaccount beschikt over onvoldoende reputatie om een negatieve stem uit te mogen brengen.",
diff --git a/public/language/nl/modules.json b/public/language/nl/modules.json
index 75792aec27..39a61ffe9f 100644
--- a/public/language/nl/modules.json
+++ b/public/language/nl/modules.json
@@ -15,7 +15,7 @@
"chat.seven_days": "7 dagen",
"chat.thirty_days": "30 dagen",
"chat.three_months": "3 maanden",
- "chat.delete_message_confirm": "Are you sure you wish to delete this message?",
+ "chat.delete_message_confirm": "Weet u het zeker dat u dit bericht wilt verwijderen?",
"composer.compose": "Samenstellen",
"composer.show_preview": "Voorbeeldweergave",
"composer.hide_preview": "Verberg voorbeeld",
diff --git a/public/language/ru/error.json b/public/language/ru/error.json
index 717d307f63..4dd3c99934 100644
--- a/public/language/ru/error.json
+++ b/public/language/ru/error.json
@@ -78,7 +78,7 @@
"too-many-messages": "Вы отправили слишком много сообщений, подождите немного.",
"invalid-chat-message": "Неверное сообщение чата",
"chat-message-too-long": "Слишком длинное сообщение чата",
- "cant-edit-chat-message": "You are not allowed to edit this message",
+ "cant-edit-chat-message": "У вас нет доступа для редактирования этого сообщения",
"reputation-system-disabled": "Система репутации отключена.",
"downvoting-disabled": "Понижение оценки отключено",
"not-enough-reputation-to-downvote": "У Вас недостаточно репутации для понижения оценки сообщения",
diff --git a/public/language/ru/modules.json b/public/language/ru/modules.json
index cada7e8fc9..b9ea06f477 100644
--- a/public/language/ru/modules.json
+++ b/public/language/ru/modules.json
@@ -15,7 +15,7 @@
"chat.seven_days": "7 дней",
"chat.thirty_days": "30 дней",
"chat.three_months": "3 месяца",
- "chat.delete_message_confirm": "Are you sure you wish to delete this message?",
+ "chat.delete_message_confirm": "Вы уверены, что хотите удалить это сообщение?",
"composer.compose": "Редактор",
"composer.show_preview": "Показать предпросмотр",
"composer.hide_preview": "Скрыть предпросмотр",
@@ -24,7 +24,7 @@
"composer.discard": "Вы уверены, что хотите отменить все изменения?",
"composer.submit_and_lock": "Отправить и закрыть",
"composer.toggle_dropdown": "Показать выпадающий список",
- "composer.uploading": "Uploading %1",
+ "composer.uploading": "Загрузка %1",
"bootbox.ok": "ОК",
"bootbox.cancel": "Отмена",
"bootbox.confirm": "Подтвердить",
diff --git a/public/language/ru/notifications.json b/public/language/ru/notifications.json
index 197bfa2c09..9c258affe0 100644
--- a/public/language/ru/notifications.json
+++ b/public/language/ru/notifications.json
@@ -15,9 +15,9 @@
"upvoted_your_post_in_dual": "%1 and %2 have upvoted your post in %3.",
"upvoted_your_post_in_multiple": "%1 and %2 others have upvoted your post in %3.",
"moved_your_post": "%1 has moved your post to %2",
- "moved_your_topic": "%1 has moved %2",
+ "moved_your_topic": "%1 переместил %2",
"favourited_your_post_in": "%1 добавил в избранное Ваше сообщение в %2.",
- "favourited_your_post_in_dual": "%1 and %2 have favourited your post in %3.",
+ "favourited_your_post_in_dual": "%1 и %2 добавили в избранное Ваше сообщение в %3.",
"favourited_your_post_in_multiple": "%1 and %2 others have favourited your post in %3.",
"user_flagged_post_in": "%1 пометил сообщение в %2",
"user_flagged_post_in_dual": "%1 and %2 flagged a post in %3",
diff --git a/public/language/ru/topic.json b/public/language/ru/topic.json
index b733f7305a..0ba0064291 100644
--- a/public/language/ru/topic.json
+++ b/public/language/ru/topic.json
@@ -98,10 +98,10 @@
"most_posts": "По количеству ответов",
"stale.title": "Create new topic instead?",
"stale.warning": "The topic you are replying to is quite old. Would you like to create a new topic instead, and reference this one in your reply?",
- "stale.create": "Create a new topic",
- "stale.reply_anyway": "Reply to this topic anyway",
+ "stale.create": "Создать новую тему",
+ "stale.reply_anyway": "Всё равно ответить в этой теме",
"stale.link_back": "Re: [%1](%2)",
- "spam": "Spam",
+ "spam": "Спам",
"offensive": "Offensive",
"custom-flag-reason": "Enter a flagging reason"
}
\ No newline at end of file
diff --git a/public/language/ru/user.json b/public/language/ru/user.json
index 83a614e156..d9b7cc6621 100644
--- a/public/language/ru/user.json
+++ b/public/language/ru/user.json
@@ -30,16 +30,16 @@
"signature": "Подпись",
"birthday": "День рождения",
"chat": "Чат",
- "chat_with": "Chat with %1",
+ "chat_with": "Чат с %1",
"follow": "Читать",
"unfollow": "Не читать",
"more": "Ещё",
"profile_update_success": "Профиль обновлен!",
"change_picture": "Изменить фотографию",
- "change_username": "Change Username",
- "change_email": "Change Email",
+ "change_username": "Изменить имя пользователя",
+ "change_email": "Изменить Email",
"edit": "Редактировать",
- "default_picture": "Default Icon",
+ "default_picture": "Иконка по умолчанию",
"uploaded_picture": "Загруженные фотографии",
"upload_new_picture": "Загрузить новую фотографию",
"upload_new_picture_from_url": "Загрузить новое изображение с адреса URL",
@@ -58,7 +58,7 @@
"upload_picture": "Загрузить фотографию",
"upload_a_picture": "Загрузить фотографию",
"remove_uploaded_picture": "Удалить загруженные фотографии",
- "image_spec": "You may only upload PNG, JPG, or BMP files",
+ "image_spec": "Вы можете загружать только PNG, JPG или BMP файлы",
"settings": "Настройки",
"show_email": "Показывать мой Email",
"show_fullname": "Показывать Полное Имя",
@@ -92,8 +92,8 @@
"grouptitle": "Выберите бейдж группы для отображения",
"no-group-title": "Не показывать бейдж",
"select-skin": "Выбрать скин",
- "select-homepage": "Select a Homepage",
- "homepage": "Homepage",
+ "select-homepage": "Укажите главную страницу",
+ "homepage": "Главная страница",
"homepage_description": "Select a page to use as the forum homepage or 'None' to use the default homepage.",
"custom_route": "Custom Homepage Route",
"custom_route_help": "Enter a route name here, without any preceding slash (e.g. \"recent\", or \"popular\")",
diff --git a/public/src/admin/appearance/skins.js b/public/src/admin/appearance/skins.js
index 8f838ca8c2..895b97de52 100644
--- a/public/src/admin/appearance/skins.js
+++ b/public/src/admin/appearance/skins.js
@@ -5,9 +5,11 @@ define('admin/appearance/skins', function() {
var Skins = {};
Skins.init = function() {
- var scriptEl = $('');
- scriptEl.attr('src', '//bootswatch.aws.af.cm/3/?callback=bootswatchListener');
- $('body').append(scriptEl);
+ // Populate skins from Bootswatch API
+ $.ajax({
+ method: 'get',
+ url: 'https://bootswatch.com/api/3.json'
+ }).done(Skins.render);
$('#skins').on('click', function(e){
var target = $(e.target);
diff --git a/public/vendor/jquery/timeago/locales/jquery.timeago.af.js b/public/vendor/jquery/timeago/locales/jquery.timeago.af.js
new file mode 100644
index 0000000000..ffb23e6f9c
--- /dev/null
+++ b/public/vendor/jquery/timeago/locales/jquery.timeago.af.js
@@ -0,0 +1,20 @@
+// Afrikaans
+jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "gelede",
+ suffixFromNow: "van nou af",
+ seconds: "%d sekondes",
+ minute: "1 minuut",
+ minutes: "%d minute",
+ hour: "1 uur",
+ hours: "%d ure",
+ day: "1 dag",
+ days: "%d dae",
+ month: "1 maand",
+ months: "%d maande",
+ year: "1 jaar",
+ years: "%d jaar",
+ wordSeparator: " ",
+ numbers: []
+};
\ No newline at end of file
diff --git a/public/vendor/jquery/timeago/locales/jquery.timeago.cz.js b/public/vendor/jquery/timeago/locales/jquery.timeago.cz.js
deleted file mode 100644
index b7137384b1..0000000000
--- a/public/vendor/jquery/timeago/locales/jquery.timeago.cz.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Czech
-jQuery.timeago.settings.strings = {
- prefixAgo: "před",
- prefixFromNow: null,
- suffixAgo: null,
- suffixFromNow: null,
- seconds: "méně než minutou",
- minute: "minutou",
- minutes: "%d minutami",
- hour: "hodinou",
- hours: "%d hodinami",
- day: "1 dnem",
- days: "%d dny",
- month: "1 měsícem",
- months: "%d měsíci",
- year: "1 rokem",
- years: "%d roky"
-};
\ No newline at end of file
diff --git a/public/vendor/jquery/timeago/locales/jquery.timeago.dv.js b/public/vendor/jquery/timeago/locales/jquery.timeago.dv.js
new file mode 100644
index 0000000000..9f2a9da0ca
--- /dev/null
+++ b/public/vendor/jquery/timeago/locales/jquery.timeago.dv.js
@@ -0,0 +1,22 @@
+/**
+ * Dhivehi time in Thaana for timeago.js
+ **/
+jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "ކުރިން",
+ suffixFromNow: "ފަހުން",
+ seconds: "ސިކުންތުކޮޅެއް",
+ minute: "މިނިޓެއްވަރު",
+ minutes: "%d މިނިޓު",
+ hour: "ގަޑިއެއްވަރު",
+ hours: "ގާތްގަނޑަކަށް %d ގަޑިއިރު",
+ day: "އެއް ދުވަސް",
+ days: "މީގެ %d ދުވަސް",
+ month: "މަހެއްވަރު",
+ months: "މީގެ %d މަސް",
+ year: "އަހަރެއްވަރު",
+ years: "މީގެ %d އަހަރު",
+ wordSeparator: " ",
+ numbers: []
+};
diff --git a/public/vendor/jquery/timeago/locales/jquery.timeago.eu.js b/public/vendor/jquery/timeago/locales/jquery.timeago.eu.js
new file mode 100644
index 0000000000..4b2c91a237
--- /dev/null
+++ b/public/vendor/jquery/timeago/locales/jquery.timeago.eu.js
@@ -0,0 +1,17 @@
+jQuery.timeago.settings.strings = {
+ prefixAgo: "duela",
+ prefixFromNow: "hemendik",
+ suffixAgo: "",
+ suffixFromNow: "barru",
+ seconds: "minutu bat bainu gutxiago",
+ minute: "minutu bat",
+ minutes: "%d minutu inguru",
+ hour: "ordu bat",
+ hours: "%d ordu",
+ day: "egun bat",
+ days: "%d egun",
+ month: "hilabete bat",
+ months: "%d hilabete",
+ year: "urte bat",
+ years: "%d urte"
+};
diff --git a/public/vendor/jquery/timeago/locales/jquery.timeago.fa-short.js b/public/vendor/jquery/timeago/locales/jquery.timeago.fa-short.js
new file mode 100644
index 0000000000..66d314cd42
--- /dev/null
+++ b/public/vendor/jquery/timeago/locales/jquery.timeago.fa-short.js
@@ -0,0 +1,20 @@
+// persion shortened
+jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "",
+ suffixFromNow: "",
+ seconds: "1دقیقه",
+ minute: "1دقیقه",
+ minutes: "%dدقیقه",
+ hour: "1ساعت",
+ hours: "%dساعت",
+ day: "1روز",
+ days: "%dروز",
+ month: "1ماه",
+ months: "%dماه",
+ year: "1سال",
+ years: "%dسال",
+ wordSeparator: " ",
+ numbers: []
+};
diff --git a/public/vendor/jquery/timeago/locales/jquery.timeago.it-short.js b/public/vendor/jquery/timeago/locales/jquery.timeago.it-short.js
index f4d92ad209..64328baa85 100644
--- a/public/vendor/jquery/timeago/locales/jquery.timeago.it-short.js
+++ b/public/vendor/jquery/timeago/locales/jquery.timeago.it-short.js
@@ -17,4 +17,4 @@ jQuery.timeago.settings.strings = {
years: "%da",
wordSeparator: " ",
numbers: []
-};
\ No newline at end of file
+};
diff --git a/public/vendor/jquery/timeago/locales/jquery.timeago.pt-short.js b/public/vendor/jquery/timeago/locales/jquery.timeago.pt-short.js
new file mode 100644
index 0000000000..8f6ef76d5c
--- /dev/null
+++ b/public/vendor/jquery/timeago/locales/jquery.timeago.pt-short.js
@@ -0,0 +1,20 @@
+// Portuguese shortened
+jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "",
+ suffixFromNow: "",
+ seconds: "1m",
+ minute: "1m",
+ minutes: "%dm",
+ hour: "1h",
+ hours: "%dh",
+ day: "1d",
+ days: "%dd",
+ month: "1M",
+ months: "%dM",
+ year: "1a",
+ years: "%da",
+ wordSeparator: " ",
+ numbers: []
+};
diff --git a/src/controllers/unread.js b/src/controllers/unread.js
index af7bf816ef..741e5c673a 100644
--- a/src/controllers/unread.js
+++ b/src/controllers/unread.js
@@ -34,7 +34,7 @@ unreadController.get = function(req, res, next) {
privileges.categories.filterCids('read', results.watchedCategories, req.uid, next);
},
function(cids, next) {
- categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'link'], next);
+ categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'link', 'color', 'bgColor'], next);
},
function(categories, next) {
categories = categories.filter(function(category) {
diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js
index b7e8a9c51e..2b4246b625 100644
--- a/src/socket.io/groups.js
+++ b/src/socket.io/groups.js
@@ -148,6 +148,9 @@ SocketGroups.update = isOwner(function(socket, data, callback) {
SocketGroups.kick = isOwner(function(socket, data, callback) {
+ if (socket.uid === parseInt(data.uid, 10)) {
+ return callback(new Error('[[error:cant-kick-self]]'));
+ }
groups.leave(data.groupName, data.uid, callback);
});
diff --git a/src/topics.js b/src/topics.js
index 423dafe197..d2c4c79359 100644
--- a/src/topics.js
+++ b/src/topics.js
@@ -192,25 +192,22 @@ var async = require('async'),
}, next);
},
function(results, next) {
- if (plugins.hasListeners('filter:topic.getRelatedTopics')) {
- plugins.fireHook('filter:topic.getRelatedTopics', results, next);
- } else {
- Topics.getRelatedTopics(results, next);
- }
- }, function(results, next) {
topicData.posts = results.posts;
topicData.category = results.category;
topicData.thread_tools = results.threadTools.tools;
topicData.tags = results.tags;
topicData.isFollowing = results.isFollowing[0];
topicData.bookmark = results.bookmark;
- topicData.related = results.related || [];
topicData.unreplied = parseInt(topicData.postcount, 10) === 1;
topicData.deleted = parseInt(topicData.deleted, 10) === 1;
topicData.locked = parseInt(topicData.locked, 10) === 1;
topicData.pinned = parseInt(topicData.pinned, 10) === 1;
+ Topics.getRelatedTopics(topicData, uid, next);
+ },
+ function(related, next) {
+ topicData.related = related || [];
plugins.fireHook('filter:topic.get', {topic: topicData, uid: uid}, next);
},
function(data, next) {
diff --git a/src/topics/tags.js b/src/topics/tags.js
index 183dbe903c..d816d5c49c 100644
--- a/src/topics/tags.js
+++ b/src/topics/tags.js
@@ -5,7 +5,6 @@ var async = require('async'),
db = require('../database'),
meta = require('../meta'),
- user = require('../user'),
_ = require('underscore'),
plugins = require('../plugins');
@@ -323,43 +322,33 @@ module.exports = function(Topics) {
});
};
- Topics.getRelatedTopics = function(topicData, callback) {
- var maximumTopics = typeof meta.config.maximumRelatedTopics !== 'undefined' ? parseInt(meta.config.maximumRelatedTopics, 10) : 5;
+ Topics.getRelatedTopics = function(topicData, uid, callback) {
+ if (plugins.hasListeners('filter:topic.getRelatedTopics')) {
+ return plugins.fireHook('filter:topic.getRelatedTopics', {topic: topicData, uid: uid}, callback);
+ }
+
+ var maximumTopics = parseInt(meta.config.maximumRelatedTopics, 10) || 5;
if (!topicData.tags.length || maximumTopics === 0) {
return callback(null, topicData);
}
- var related = [];
-
- user.isAdministrator(topicData.threadTools.uid, function(err, isAdministrator) {
- async.each(topicData.tags, function(tag, next) {
- tag = tag.value;
-
- Topics.getTagTids(tag, 0, 5, function(err, tids) {
- Topics.getTopics(tids, topicData.threadTools.uid, function(err, topics) {
- related = related.concat(topics.filter(function(topic) {
- var doesntOwnTopic = parseInt(topic.uid, 10) !== parseInt(topicData.threadTools.uid, 10);
- var isntSameTopic = parseInt(topic.tid, 10) !== parseInt(topicData.threadTools.topic.tid, 10);
-
- return doesntOwnTopic && isntSameTopic;
- }));
-
- next(err);
- });
+ async.waterfall([
+ function (next) {
+ async.map(topicData.tags, function (tag, next) {
+ Topics.getTagTids(tag.value, 0, 5, next);
+ }, next);
+ },
+ function (tids, next) {
+ tids = _.shuffle(_.unique(_.flatten(tids))).slice(0, maximumTopics);
+ Topics.getTopics(tids, uid, next);
+ },
+ function (topics, next) {
+ topics = topics.filter(function(topic) {
+ return topic && !topic.deleted && parseInt(topic.uid, 10) !== parseInt(uid, 10);
});
- }, function(err) {
- if (!isAdministrator) {
- related = related.filter(function(topic) {
- return topic && !topic.deleted;
- });
- }
-
- related = _.shuffle(related).slice(0, maximumTopics);
-
- topicData.related = related;
- callback(err, topicData);
- });
- });
+ next(null, topics);
+ }
+ ], callback);
};
};
\ No newline at end of file
diff --git a/src/user/notifications.js b/src/user/notifications.js
index 9f3766977d..f40143a28d 100644
--- a/src/user/notifications.js
+++ b/src/user/notifications.js
@@ -64,6 +64,8 @@ var async = require('async'),
}
function getNotificationsFromSet(set, read, uid, start, stop, callback) {
+ var setNids;
+
async.waterfall([
async.apply(db.getSortedSetRevRange, set, start, stop),
function(nids, next) {
@@ -71,6 +73,7 @@ var async = require('async'),
return callback(null, []);
}
+ setNids = nids;
UserNotifications.getNotifications(nids, uid, next);
},
function(notifs, next) {
@@ -78,8 +81,8 @@ var async = require('async'),
notifs.forEach(function(notification, index) {
if (!notification) {
- winston.verbose('[notifications.get] nid ' + notification.nid + ' not found. Removing.');
- deletedNids.push(notification.nid);
+ winston.verbose('[notifications.get] nid ' + setNids[index] + ' not found. Removing.');
+ deletedNids.push(setNids[index]);
} else {
notification.read = read;
notification.readClass = !notification.read ? 'unread' : '';
diff --git a/src/views/admin/appearance/skins.tpl b/src/views/admin/appearance/skins.tpl
index fe50dead11..ce145eec79 100644
--- a/src/views/admin/appearance/skins.tpl
+++ b/src/views/admin/appearance/skins.tpl
@@ -8,12 +8,4 @@
undo
-
-
-
+
\ No newline at end of file