Merge branch 'master' into develop

v1.18.x
Julian Lam 8 years ago
commit 184dacf1d7

@ -71,7 +71,7 @@ It is important to ensure that your NodeBB and database servers are secured. Bea
## Upgrading NodeBB
Detailed upgrade instructions are listed in [Upgrading NodeBB](https://docs.nodebb.org/en/latest/upgrading/index.html)
Detailed upgrade instructions are listed in [Upgrading NodeBB](https://docs.nodebb.org/configuring/upgrade/)
## License

@ -2,7 +2,7 @@
"name": "nodebb",
"license": "GPL-3.0",
"description": "NodeBB Forum",
"version": "1.5.1",
"version": "1.5.2",
"homepage": "http://www.nodebb.org",
"repository": {
"type": "git",
@ -55,7 +55,7 @@
"morgan": "^1.3.2",
"mousetrap": "^1.5.3",
"nconf": "~0.8.2",
"nodebb-plugin-composer-default": "5.0.1",
"nodebb-plugin-composer-default": "5.0.3",
"nodebb-plugin-dbsearch": "2.0.6",
"nodebb-plugin-emoji-extended": "1.1.1",
"nodebb-plugin-emoji-one": "1.2.1",
@ -68,7 +68,7 @@
"nodebb-theme-persona": "5.0.13",
"nodebb-theme-slick": "1.1.0",
"nodebb-theme-vanilla": "6.0.10",
"nodebb-widget-essentials": "3.0.0",
"nodebb-widget-essentials": "3.0.1",
"nodemailer": "2.6.4",
"nodemailer-sendmail-transport": "1.0.0",
"nodemailer-smtp-transport": "^2.4.1",

@ -2,33 +2,33 @@
"results_matching": "%1 result(s) matching \"%2\", (%3 seconds)",
"no-matches": "No matches found",
"advanced-search": "Pokročilé hledání",
"in": "In",
"in": "v",
"titles": "Titles",
"titles-posts": "Titles and Posts",
"posted-by": "Posted by",
"in-categories": "In Categories",
"posted-by": "Napsal",
"in-categories": "V kategoriích",
"search-child-categories": "Search child categories",
"has-tags": "Has tags",
"has-tags": "Obsahuje značky",
"reply-count": "Reply Count",
"at-least": "At least",
"at-most": "At most",
"at-least": "Nejméně",
"at-most": "Nejvíce",
"relevance": "Relevance",
"post-time": "Post time",
"post-time": "Čas příspěvku",
"newer-than": "Novější než",
"older-than": "Starší než",
"any-date": "Any date",
"any-date": "Jakékoliv datum",
"yesterday": "Včera",
"one-week": "Jeden týden",
"two-weeks": "Dva týdny",
"one-month": "Jeden měsíc",
"three-months": "Three months",
"three-months": "Tři měsíce",
"six-months": "Šest měsíců",
"one-year": "Jeden rok",
"sort-by": "Řadit dle",
"last-reply-time": "Čas poslední odpovědi",
"topic-title": "Topic title",
"topic-title": "Název tématu",
"number-of-replies": "Počet odpovědí",
"number-of-views": "Number of views",
"number-of-views": "Počet zobrazení",
"topic-start-date": "Topic start date",
"username": "Uživatelské jméno",
"category": "Kategorie",

@ -13,9 +13,9 @@
"notify_me": "Dostávat upozornění na nové odpovědi",
"quote": "Citovat",
"reply": "Odpovědět",
"replies_to_this_post": "%1 Replies",
"one_reply_to_this_post": "1 Reply",
"last_reply_time": "Last reply",
"replies_to_this_post": "%1 odpovědí",
"one_reply_to_this_post": "1 odpověď",
"last_reply_time": "Poslední odpověď",
"reply-as-topic": "Odpovědět jako Téma",
"guest-login-reply": "Přihlásit se pro odpověď",
"edit": "Upravit",
@ -28,8 +28,8 @@
"share": "Sdílet",
"tools": "Nástroje",
"locked": "Uzamčeno",
"pinned": "Pinned",
"moved": "Moved",
"pinned": "Připnuto",
"moved": "Přesunuto",
"bookmark_instructions": "Click here to return to the last read post in this thread.",
"flag_title": "Flag this post for moderation",
"deleted_message": "This topic has been deleted. Only users with topic management privileges can see it.",
@ -37,47 +37,47 @@
"not_following_topic.message": "You will see this topic in the unread topics list, but you will not receive notifications when somebody posts to this topic.",
"ignoring_topic.message": "You will no longer see this topic in the unread topics list. You will be notified when you are mentioned or your post is up voted.",
"login_to_subscribe": "Please register or log in in order to subscribe to this topic.",
"markAsUnreadForAll.success": "Topic marked as unread for all.",
"markAsUnreadForAll.success": "Téma označeno jako nepřečtené pro všechny.",
"mark_unread": "Označ za nepřečtené",
"mark_unread.success": "Téma označeno jako nepřečtené",
"watch": "Sledovat",
"unwatch": "Přesta sledovat",
"watch.title": "Be notified of new replies in this topic",
"watch.title": "Být upozorněn u nových odpovědí v tomto tématu",
"unwatch.title": "Přestat sledovat toto téma",
"share_this_post": "Sdílet toto téma",
"watching": "Sledováno",
"not-watching": "Nesledováno",
"ignoring": "Ignoring",
"ignoring": "Ignorování",
"watching.description": "Notify me of new replies.<br/>Show topic in unread.",
"not-watching.description": "Do not notify me of new replies.<br/>Show topic in unread if category is not ignored.",
"ignoring.description": "Do not notify me of new replies.<br/>Do not show topic in unread.",
"thread_tools.title": "Správa tématu",
"thread_tools.markAsUnreadForAll": "Mark unread for all",
"thread_tools.markAsUnreadForAll": "Označit jako nepřečtené pro všechny",
"thread_tools.pin": "Připnout téma",
"thread_tools.unpin": "Odepnout téma",
"thread_tools.lock": "Zamknout téma",
"thread_tools.unlock": "Odemknout téma",
"thread_tools.move": "Přesunout téma",
"thread_tools.move_all": "Přesunout vše",
"thread_tools.select_category": "Select Category",
"thread_tools.select_category": "Vybrat kategorii",
"thread_tools.fork": "Větvit téma",
"thread_tools.delete": "Odstranit téma",
"thread_tools.delete-posts": "Odstranit přispěvky",
"thread_tools.delete_confirm": "Opravdu chcete smazat toto téma.",
"thread_tools.restore": "Obnovit téma",
"thread_tools.restore_confirm": "Are you sure you want to restore this topic?",
"thread_tools.purge": "Purge Topic",
"thread_tools.purge_confirm": "Are you sure you want to purge this topic?",
"topic_move_success": "This topic has been successfully moved to %1",
"post_delete_confirm": "Are you sure you want to delete this post?",
"post_restore_confirm": "Are you sure you want to restore this post?",
"post_purge_confirm": "Are you sure you want to purge this post?",
"thread_tools.restore_confirm": "Jste si jist/a, že chcete obnovit toto téma?",
"thread_tools.purge": "Vyčistit téma",
"thread_tools.purge_confirm": "Jste si jist/a, že chcete vyčistit toto téma?",
"topic_move_success": "Toto téma bylo úspěšně přesunuto do %1",
"post_delete_confirm": "Jste si jist/a, že chcete odstranit tento příspěvek?",
"post_restore_confirm": "Jste si jist/a, že chcete obnovit tento příspěvek?",
"post_purge_confirm": "Jste si jist/a, že chcete tento příspěvek vyčistit?",
"load_categories": "Načítání kategorií",
"confirm_move": "Přesunout",
"confirm_fork": "Rozdělit",
"bookmark": "Bookmark",
"bookmarks": "Bookmarks",
"bookmarks.has_no_bookmarks": "You haven't bookmarked any posts yet.",
"bookmark": "Záložka",
"bookmarks": "Záložky",
"bookmarks.has_no_bookmarks": "Ještě jste nezazáložkoval žádný příspěvek.",
"loading_more_posts": "Načítání více příspěvků",
"move_topic": "Přesunout téma",
"move_topics": "Přesunout témata",
@ -86,9 +86,9 @@
"fork_topic": "Rozdělit příspěvek",
"fork_topic_instruction": "Vyber příspěvky, které chceš oddělit",
"fork_no_pids": "Žádné příspěvky nebyly vybrány!",
"fork_pid_count": "%1 post(s) selected",
"fork_pid_count": "Vybráno %1 příspěvek/ů",
"fork_success": "Successfully forked topic! Click here to go to the forked topic.",
"delete_posts_instruction": "Click the posts you want to delete/purge",
"delete_posts_instruction": "Klikněte na příspěvek, který chcete odstranit/vyčistit",
"composer.title_placeholder": "Zadejte název tématu…",
"composer.handle_placeholder": "Jméno",
"composer.discard": "Zrušit",
@ -101,7 +101,7 @@
"composer.thumb_url_placeholder": "http://example.com/thumb.png",
"composer.thumb_file_label": "Nebo nahrajte soubor",
"composer.thumb_remove": "Vymazat pole",
"composer.drag_and_drop_images": "Drag and Drop Images Here",
"composer.drag_and_drop_images": "Přesuňte sem myší obrázek",
"more_users_and_guests": "%1 more user(s) and %2 guest(s)",
"more_users": "%1 more user(s)",
"more_guests": "%1 more guest(s)",

@ -6,7 +6,7 @@
"postcount": "Počet příspěvků",
"email": "E-mail",
"confirm_email": "Potvrdit e-mail",
"account_info": "Account Info",
"account_info": "Informace o účtu",
"ban_account": "Zablokovat účet",
"ban_account_confirm": "Opravdu chcete zablokovat tohoto uživatele?",
"unban_account": "Odblokovat účet",
@ -23,7 +23,7 @@
"profile": "Profil",
"profile_views": "Zobrazení profilu",
"reputation": "Reputace",
"bookmarks": "Bookmarks",
"bookmarks": "Záložky",
"watched": "Sledován",
"followers": "Sledují ho",
"following": "Sleduje",
@ -31,8 +31,8 @@
"signature": "Podpis",
"birthday": "Datum narození",
"chat": "Chat",
"chat_with": "Continue chat with %1",
"new_chat_with": "Start new chat with %1",
"chat_with": "Pokračovat v chatu s %1",
"new_chat_with": "Začít nový chat s %1",
"flag-profile": "Flag Profile",
"follow": "Sledovat",
"unfollow": "Nesledovat",
@ -60,14 +60,14 @@
"username_taken_workaround": "Zvolené uživatelské jméno je již zabrané, takže jsme ho trochu upravili. Nyní jste znám jako <strong>%1</strong>",
"password_same_as_username": "Vaše heslo je stejné jako vaše přihlašovací jméno. Zvolte si prosím jiné heslo.",
"password_same_as_email": "Vaše heslo je stejné jako váš e-mail. Zvolte si prosím jiné heslo.",
"weak_password": "Weak password.",
"weak_password": "Slabé heslo.",
"upload_picture": "Nahrát obrázek",
"upload_a_picture": "Nahrát obrázek",
"remove_uploaded_picture": "Odstranit nahraný obrázek",
"upload_cover_picture": "Náhrát titulní obrázek",
"remove_cover_picture_confirm": "Are you sure you want to remove the cover picture?",
"crop_picture": "Crop picture",
"upload_cropped_picture": "Crop and upload",
"remove_cover_picture_confirm": "Jste si jist, že vyjmout obrázek coveru?",
"crop_picture": "Oříznout obrázek",
"upload_cropped_picture": "Oříznout a nahrát",
"settings": "Nastavení",
"show_email": "Zobrazovat můj e-mail v profilu",
"show_fullname": "Zobrazovat celé jméno",
@ -78,35 +78,35 @@
"digest_daily": "Denně",
"digest_weekly": "Týdně",
"digest_monthly": "Měsíčně",
"send_chat_notifications": "Send an email if a new chat message arrives and I am not online",
"send_post_notifications": "Send an email when replies are made to topics I am subscribed to",
"settings-require-reload": "Some setting changes require a reload. Click here to reload the page.",
"send_chat_notifications": "Odeslat e-mail, dorazí-li nová zpráva chatu a já nejsem připojen",
"send_post_notifications": "Zaslat e-mail, přibudou-li nové odpovědi k tématu, kde mám přihlášen odběr",
"settings-require-reload": "Některá nastavení vyžadují znovu načtení. Pro znovu načtení stránky, klikněte zde.",
"has_no_follower": "Tohoto uživatele nikdo nesleduje :(",
"follows_no_one": "Tento uživatel nikoho nesleduje :(",
"has_no_posts": "This user hasn't posted anything yet.",
"has_no_topics": "This user hasn't posted any topics yet.",
"has_no_posts": "Tento uživatel ještě nic nenapsal.",
"has_no_topics": "Tento uživatel ještě nenapsal žádné téma.",
"has_no_watched_topics": "Tento uživatel zatím nesleduje žádná témata.",
"has_no_upvoted_posts": "This user hasn't upvoted any posts yet.",
"has_no_downvoted_posts": "This user hasn't downvoted any posts yet.",
"has_no_voted_posts": "This user has no voted posts",
"has_no_voted_posts": "Tento uživatel nemá žádné hlasovací příspěvky",
"email_hidden": "E-mail skryt",
"hidden": "skrytý",
"paginate_description": "Paginate topics and posts instead of using infinite scroll",
"paginate_description": "Stránkovat témata a příspěvky místo použití nekonečného posunování",
"topics_per_page": "Témat na stránce",
"posts_per_page": "Příspěvků na stránce",
"notification_sounds": "Přehrát zvuk když dostanete notifikaci",
"notifications_and_sounds": "Upozornění a zvuky",
"incoming-message-sound": "Incoming message sound",
"outgoing-message-sound": "Outgoing message sound",
"notification-sound": "Notification sound",
"no-sound": "No sound",
"incoming-message-sound": "Zvuk příchozí zprávy",
"outgoing-message-sound": "Zvuk odchozí zprávy",
"notification-sound": "Zvuk oznámení",
"no-sound": "Bez zvuku",
"browsing": "Nastavení prohlížení",
"open_links_in_new_tab": "Open outgoing links in new tab",
"enable_topic_searching": "Enable In-Topic Searching",
"open_links_in_new_tab": "Otevřít odchozí odkaz v nové záložce",
"enable_topic_searching": "Povolit vyhledávání v tématu",
"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",
"delay_image_loading": "Delay Image Loading",
"delay_image_loading": "Zpoždění načtení obrázku",
"image_load_delay_help": "If enabled, images in topics will not load until they are scrolled into view",
"scroll_to_my_post": "After posting a reply, show the new post",
"scroll_to_my_post": "Po odeslání odpovědi, zobrazit nový příspěvek",
"follow_topics_you_reply_to": "Sledovat témata, do kterých přispějete",
"follow_topics_you_create": "Sledovat témata, která vytvoříte",
"grouptitle": "Nadpis skupiny",
@ -122,15 +122,15 @@
"sso.not-associated": "Click here to associate with",
"info.latest-flags": "Latest Flags",
"info.no-flags": "No Flagged Posts Found",
"info.ban-history": "Recent Ban History",
"info.no-ban-history": "This user has never been banned",
"info.banned-until": "Banned until %1",
"info.banned-permanently": "Banned permanently",
"info.banned-reason-label": "Reason",
"info.banned-no-reason": "No reason given.",
"info.username-history": "Username History",
"info.email-history": "Email History",
"info.moderation-note": "Moderation Note",
"info.moderation-note.success": "Moderation note saved",
"info.moderation-note.add": "Add note"
"info.ban-history": "Poslední historie banování",
"info.no-ban-history": "Tento uživatel nebyl nikdy zabanován",
"info.banned-until": "Zabanován do %1",
"info.banned-permanently": "Permanentně zabanován",
"info.banned-reason-label": "Důvod",
"info.banned-no-reason": "Bez důvodu",
"info.username-history": "Historie uživatelského jména",
"info.email-history": "E-mailová historie",
"info.moderation-note": "Poznámka moderace",
"info.moderation-note.success": "Poznámka moderace byla uložena",
"info.moderation-note.add": "Přidat poznámku"
}

@ -5,7 +5,7 @@
"max-image-width": "Resize images down to specified width (in pixels)",
"max-image-width-help": "(in pixels, default: 760 pixels, set to 0 to disable)",
"max-file-size": "Maximum File Size (in KiB)",
"max-file-size-help": "(in kilobytes, default: 2048 KiB)",
"max-file-size-help": "(in kibibytes, default: 2048 KiB)",
"allow-topic-thumbnails": "Allow users to upload topic thumbnails",
"topic-thumb-size": "Topic Thumb Size",
"allowed-file-extensions": "Allowed File Extensions",
@ -18,9 +18,9 @@
"profile-image-dimension": "Profile Image Dimension",
"profile-image-dimension-help": "(in pixels, default: 128 pixels)",
"max-profile-image-size": "Maximum Profile Image File Size",
"max-profile-image-size-help": "(in kilobytes, default: 256 KiB)",
"max-profile-image-size-help": "(in kibibytes, default: 256 KiB)",
"max-cover-image-size": "Maximum Cover Image File Size",
"max-cover-image-size-help": "(in kilobytes, default: 2,048 KiB)",
"max-cover-image-size-help": "(in kibibytes, default: 2,048 KiB)",
"keep-all-user-images": "Keep old versions of avatars and profile covers on the server",
"profile-covers": "Profile Covers",
"default-covers": "Default Cover Images",

@ -27,8 +27,8 @@
"redis.blocked-clients": "Người dùng vi phạm",
"redis.used-memory": "Bộ nhớ đã sử dụng",
"redis.memory-frag-ratio": "Memory Fragmentation Ratio",
"redis.total-connections-recieved": "Total Connections Received",
"redis.total-commands-processed": "Total Commands Processed",
"redis.total-connections-recieved": "Tổng số kết nối nhận được",
"redis.total-commands-processed": "Tổng số kết nối đã thực thi",
"redis.iops": "Instantaneous Ops. Per Second",
"redis.keyspace-hits": "Keyspace Hits",
"redis.keyspace-misses": "Keyspace Misses",

@ -16,7 +16,7 @@ define('forum/category', [
var Category = {};
$(window).on('action:ajaxify.start', function (ev, data) {
if (data.url && !data.url.startsWith('category/')) {
if (!String(data.url).startsWith('category/')) {
navigator.disable();
removeListeners();

@ -23,7 +23,7 @@ define('forum/topic', [
Topic.replaceURLTimeout = 0;
}
if (data.url && !data.url.startsWith('topic/')) {
if (!String(data.url).startsWith('topic/')) {
navigator.disable();
components.get('navbar/title').find('span').text('').hide();
app.removeAlert('bookmark');

@ -20,6 +20,7 @@ define('forum/topic/images', [
} else {
images.attr('data-state', 'loaded');
Images.wrapImagesInLinks(posts);
$(window).trigger('action:images.loaded');
}
};
@ -75,6 +76,7 @@ define('forum/topic/images', [
adjusting = false;
Images.wrapImagesInLinks(posts);
$(window).trigger('action:images.loaded');
posts.length = 0;
}
}

@ -59,6 +59,25 @@ module.exports = function (Categories) {
], callback);
};
Categories.updateRecentTidForCid = function (cid, callback) {
async.waterfall([
function (next) {
db.getSortedSetRevRange('cid:' + cid + ':pids', 0, 0, next);
},
function (pid, next) {
pid = pid[0];
posts.getPostField(pid, 'tid', next);
},
function (tid, next) {
if (!parseInt(tid, 10)) {
return next();
}
Categories.updateRecentTid(cid, tid, next);
},
], callback);
};
Categories.getRecentTopicReplies = function (categoryData, uid, callback) {
if (!Array.isArray(categoryData) || !categoryData.length) {
return callback();
@ -180,8 +199,11 @@ module.exports = function (Categories) {
Categories.moveRecentReplies = function (tid, oldCid, cid, callback) {
callback = callback || function () {};
updatePostCount(tid, oldCid, cid);
async.waterfall([
function (next) {
updatePostCount(tid, oldCid, cid, next);
},
function (next) {
topics.getPids(tid, next);
},
@ -212,7 +234,6 @@ module.exports = function (Categories) {
};
function updatePostCount(tid, oldCid, newCid, callback) {
callback = callback || function () {};
async.waterfall([
function (next) {
topics.getTopicField(tid, 'postcount', next);
@ -228,7 +249,9 @@ module.exports = function (Categories) {
function (next) {
db.incrObjectFieldBy('category:' + newCid, 'post_count', postCount, next);
},
], next);
], function (err) {
next(err);
});
},
], callback);
}

@ -7,7 +7,7 @@ var categories = require('../categories');
var meta = require('../meta');
var helpers = require('./helpers');
var categoriesController = {};
var categoriesController = module.exports;
categoriesController.list = function (req, res, next) {
res.locals.metaTags = [{
@ -34,32 +34,27 @@ categoriesController.list = function (req, res, next) {
categories.getRecentTopicReplies(allCategories, req.uid, next);
},
], function (err) {
if (err) {
return next(err);
}
var data = {
title: '[[pages:categories]]',
categories: categoryData,
};
if (req.path.startsWith('/api/categories') || req.path.startsWith('/categories')) {
data.breadcrumbs = helpers.buildBreadcrumbs([{ text: data.title }]);
}
data.categories.forEach(function (category) {
if (category && Array.isArray(category.posts) && category.posts.length) {
category.teaser = {
url: nconf.get('relative_path') + '/topic/' + category.posts[0].topic.slug + '/' + category.posts[0].index,
timestampISO: category.posts[0].timestampISO,
pid: category.posts[0].pid,
};
function () {
var data = {
title: '[[pages:categories]]',
categories: categoryData,
};
if (req.path.startsWith('/api/categories') || req.path.startsWith('/categories')) {
data.breadcrumbs = helpers.buildBreadcrumbs([{ text: data.title }]);
}
});
res.render('categories', data);
});
data.categories.forEach(function (category) {
if (category && Array.isArray(category.posts) && category.posts.length) {
category.teaser = {
url: nconf.get('relative_path') + '/post/' + category.posts[0].pid,
timestampISO: category.posts[0].timestampISO,
pid: category.posts[0].pid,
};
}
});
res.render('categories', data);
},
], next);
};
module.exports = categoriesController;

@ -227,11 +227,16 @@ function saveFileToLocal(uploadedFile, callback) {
file.saveFileToLocal(filename, 'files', uploadedFile.path, next);
},
function (upload, next) {
next(null, {
var storedFile = {
url: nconf.get('relative_path') + upload.url,
path: upload.path,
name: uploadedFile.name,
});
};
plugins.fireHook('filter:uploadStored', { uploadedFile: uploadedFile, storedFile: storedFile }, next);
},
function (data, next) {
next(null, data.storedFile);
},
], callback);
}

@ -28,6 +28,10 @@ module.exports = function (Groups) {
return callback(new Error('[[error:invalid-data]]'));
}
if (!uid) {
return callback(new Error('[[error:invalid-uid]]'));
}
async.waterfall([
function (next) {
Groups.isMember(uid, groupName, next);

@ -30,17 +30,14 @@ module.exports = function (SocketTopics) {
topicData.tid = tid;
topics.tools.move(tid, data.cid, socket.uid, next);
},
], function (err) {
if (err) {
return next(err);
}
socketHelpers.emitToTopicAndCategory('event:topic_moved', topicData);
function (next) {
socketHelpers.emitToTopicAndCategory('event:topic_moved', topicData);
socketHelpers.sendNotificationToTopicOwner(tid, socket.uid, 'move', 'notifications:moved_your_topic');
socketHelpers.sendNotificationToTopicOwner(tid, socket.uid, 'move', 'notifications:moved_your_topic');
next();
});
next();
},
], next);
}, callback);
};

@ -195,6 +195,7 @@ module.exports = function (Topics) {
'cid:' + topicData.cid + ':tids',
'cid:' + topicData.cid + ':tids:pinned',
'cid:' + topicData.cid + ':tids:posts',
'cid:' + topicData.cid + ':recent_tids',
'cid:' + topicData.cid + ':uid:' + topicData.uid + ':tids',
'uid:' + topicData.uid + ':topics',
], tid, next);

@ -50,6 +50,9 @@ module.exports = function (Topics) {
Topics[isDelete ? 'delete' : 'restore'](tid, uid, next);
},
function (next) {
categories.updateRecentTidForCid(topicData.cid, next);
},
function (next) {
topicData.deleted = isDelete ? 1 : 0;
@ -258,7 +261,8 @@ module.exports = function (Topics) {
db.sortedSetsRemove([
'cid:' + topicData.cid + ':tids',
'cid:' + topicData.cid + ':tids:pinned',
'cid:' + topicData.cid + ':tids:posts', // post count
'cid:' + topicData.cid + ':tids:posts',
'cid:' + topicData.cid + ':recent_tids',
], tid, next);
},
function (next) {
@ -280,8 +284,9 @@ module.exports = function (Topics) {
},
function (next) {
oldCid = topic.cid;
categories.moveRecentReplies(tid, oldCid, cid);
categories.moveRecentReplies(tid, oldCid, cid, next);
},
function (next) {
async.parallel([
function (next) {
categories.incrementCategoryFieldBy(oldCid, 'topic_count', -1, next);
@ -289,6 +294,12 @@ module.exports = function (Topics) {
function (next) {
categories.incrementCategoryFieldBy(cid, 'topic_count', 1, next);
},
function (next) {
categories.updateRecentTid(cid, tid, next);
},
function (next) {
categories.updateRecentTidForCid(oldCid, next);
},
function (next) {
Topics.setTopicFields(tid, {
cid: cid,

@ -5,7 +5,7 @@
<th class="arrowed" colspan="3">
[[admin/manage/categories:privileges.section-viewing]]
</th>
<th class="arrowed" colspan="7">
<th class="arrowed" colspan="8">
[[admin/manage/categories:privileges.section-posting]]
</th>
<th class="arrowed" colspan="2">
@ -61,7 +61,7 @@
<th class="arrowed" colspan="3">
[[admin/manage/categories:privileges.section-viewing]]
</th>
<th class="arrowed" colspan="7">
<th class="arrowed" colspan="8">
[[admin/manage/categories:privileges.section-posting]]
</th>
<th class="arrowed" colspan="2">

@ -15,10 +15,10 @@
<h3 class="menu-section-title">[[admin/menu:section-manage]]</h3>
<ul class="menu-section-list">
<li><a href="{relative_path}/admin/manage/categories">[[admin/menu:manage/categories]]</a></li>
<li><a href="{relative_path}/admin/manage/tags">[[admin/menu:manage/tags]]</a></li>
<li><a href="{relative_path}/admin/manage/users">[[admin/menu:manage/users]]</a></li>
<li><a href="{relative_path}/admin/manage/registration">[[admin/menu:manage/registration]]</a></li>
<li><a href="{relative_path}/admin/manage/groups">[[admin/menu:manage/groups]]</a></li>
<li><a href="{relative_path}/admin/manage/tags">[[admin/menu:manage/tags]]</a></li>
<li><a href="{relative_path}/admin/manage/registration">[[admin/menu:manage/registration]]</a></li>
<li><a href="{relative_path}/admin/manage/ip-blacklist">[[admin/menu:manage/ip-blacklist]]</a></li>
</ul>
</section>
@ -27,16 +27,16 @@
<h3 class="menu-section-title">[[admin/menu:section-settings]]</h3>
<ul class="menu-section-list">
<li><a href="{relative_path}/admin/settings/general">[[admin/menu:section-general]]</a></li>
<li><a href="{relative_path}/admin/settings/reputation">[[admin/menu:settings/reputation]]</a></li>
<li><a href="{relative_path}/admin/settings/email">[[admin/menu:settings/email]]</a></li>
<li><a href="{relative_path}/admin/settings/user">[[admin/menu:settings/user]]</a></li>
<li><a href="{relative_path}/admin/settings/group">[[admin/menu:settings/group]]</a></li>
<li><a href="{relative_path}/admin/settings/tags">[[admin/menu:manage/tags]]</a></li>
<li><a href="{relative_path}/admin/settings/post">[[admin/menu:settings/post]]</a></li>
<li><a href="{relative_path}/admin/settings/email">[[admin/menu:settings/email]]</a></li>
<li><a href="{relative_path}/admin/settings/reputation">[[admin/menu:settings/reputation]]</a></li>
<li><a href="{relative_path}/admin/settings/guest">[[admin/menu:settings/guest]]</a></li>
<li><a href="{relative_path}/admin/settings/uploads">[[admin/menu:settings/uploads]]</a></li>
<li><a href="{relative_path}/admin/settings/post">[[admin/menu:settings/post]]</a></li>
<li><a href="{relative_path}/admin/settings/chat">[[admin/menu:settings/chat]]</a></li>
<li><a href="{relative_path}/admin/settings/pagination">[[admin/menu:settings/pagination]]</a></li>
<li><a href="{relative_path}/admin/settings/tags">[[admin/menu:manage/tags]]</a></li>
<li><a href="{relative_path}/admin/settings/notifications">[[admin/menu:settings/notifications]]</a></li>
<li><a href="{relative_path}/admin/settings/cookies">[[admin/menu:settings/cookies]]</a></li>
<li><a href="{relative_path}/admin/settings/web-crawler">[[admin/menu:settings/web-crawler]]</a></li>
@ -94,9 +94,9 @@
<ul class="menu-section-list">
<li><a href="{relative_path}/admin/advanced/database">[[admin/menu:advanced/database]]</a></li>
<li><a href="{relative_path}/admin/advanced/events">[[admin/menu:advanced/events]]</a></li>
<li><a href="{relative_path}/admin/advanced/logs">[[admin/menu:advanced/logs]]</a></li>
<li><a href="{relative_path}/admin/advanced/errors">[[admin/menu:advanced/errors]]</a></li>
<li><a href="{relative_path}/admin/advanced/cache">[[admin/menu:advanced/cache]]</a></li>
<li><a href="{relative_path}/admin/advanced/errors">[[admin/menu:advanced/errors]]</a></li>
<li><a href="{relative_path}/admin/advanced/logs">[[admin/menu:advanced/logs]]</a></li>
<!-- IF env -->
<li><a href="{relative_path}/admin/development/logger">[[admin/menu:development/logger]]</a></li>
<!-- ENDIF env -->
@ -187,10 +187,10 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">[[admin/menu:section-manage]]</a>
<ul class="dropdown-menu" role="menu">
<li><a href="{relative_path}/admin/manage/categories">[[admin/menu:manage/categories]]</a></li>
<li><a href="{relative_path}/admin/manage/tags">[[admin/menu:manage/tags]]</a></li>
<li><a href="{relative_path}/admin/manage/users">[[admin/menu:manage/users]]</a></li>
<li><a href="{relative_path}/admin/manage/registration">[[admin/menu:manage/registration]]</a></li>
<li><a href="{relative_path}/admin/manage/groups">[[admin/menu:manage/groups]]</a></li>
<li><a href="{relative_path}/admin/manage/tags">[[admin/menu:manage/tags]]</a></li>
<li><a href="{relative_path}/admin/manage/registration">[[admin/menu:manage/registration]]</a></li>
<li><a href="{relative_path}/admin/manage/ip-blacklist">[[admin/menu:manage/ip-blacklist]]</a></li>
</ul>
</li>
@ -198,16 +198,16 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">[[admin/menu:section-settings]]</a>
<ul class="dropdown-menu" role="menu">
<li><a href="{relative_path}/admin/settings/general">[[admin/menu:section-general]]</a></li>
<li><a href="{relative_path}/admin/settings/reputation">[[admin/menu:settings/reputation]]</a></li>
<li><a href="{relative_path}/admin/settings/email">[[admin/menu:settings/email]]</a></li>
<li><a href="{relative_path}/admin/settings/user">[[admin/menu:settings/user]]</a></li>
<li><a href="{relative_path}/admin/settings/group">[[admin/menu:settings/group]]</a></li>
<li><a href="{relative_path}/admin/settings/tags">[[admin/menu:manage/tags]]</a></li>
<li><a href="{relative_path}/admin/settings/post">[[admin/menu:settings/post]]</a></li>
<li><a href="{relative_path}/admin/settings/email">[[admin/menu:settings/email]]</a></li>
<li><a href="{relative_path}/admin/settings/reputation">[[admin/menu:settings/reputation]]</a></li>
<li><a href="{relative_path}/admin/settings/guest">[[admin/menu:settings/guest]]</a></li>
<li><a href="{relative_path}/admin/settings/uploads">[[admin/menu:settings/uploads]]</a></li>
<li><a href="{relative_path}/admin/settings/post">[[admin/menu:settings/post]]</a></li>
<li><a href="{relative_path}/admin/settings/chat">[[admin/menu:settings/chat]]</a></li>
<li><a href="{relative_path}/admin/settings/pagination">[[admin/menu:settings/pagination]]</a></li>
<li><a href="{relative_path}/admin/settings/tags">[[admin/menu:manage/tags]]</a></li>
<li><a href="{relative_path}/admin/settings/notifications">[[admin/menu:settings/notifications]]</a></li>
<li><a href="{relative_path}/admin/settings/cookies">[[admin/menu:settings/cookies]]</a></li>
<li><a href="{relative_path}/admin/settings/web-crawler">[[admin/menu:settings/web-crawler]]</a></li>
@ -264,9 +264,9 @@
<ul class="dropdown-menu" role="menu">
<li><a href="{relative_path}/admin/advanced/database">[[admin/menu:advanced/database]]</a></li>
<li><a href="{relative_path}/admin/advanced/events">[[admin/menu:advanced/events]]</a></li>
<li><a href="{relative_path}/admin/advanced/logs">[[admin/menu:advanced/logs]]</a></li>
<li><a href="{relative_path}/admin/advanced/errors">[[admin/menu:advanced/errors]]</a></li>
<li><a href="{relative_path}/admin/advanced/cache">[[admin/menu:advanced/cache]]</a></li>
<li><a href="{relative_path}/admin/advanced/errors">[[admin/menu:advanced/errors]]</a></li>
<li><a href="{relative_path}/admin/advanced/logs">[[admin/menu:advanced/logs]]</a></li>
<!-- IF env -->
<li><a href="{relative_path}/admin/development/logger">[[admin/menu:development/logger]]</a></li>
<!-- ENDIF env -->

@ -99,7 +99,7 @@
<div class="form-group">
<label>[[admin/settings/uploads:max-profile-image-size]]</label>
<input type="text" class="form-control" placeholder="Maximum size of uploaded user images in kilobytes" data-field="maximumProfileImageSize" />
<input type="text" class="form-control" placeholder="Maximum size of uploaded user images in kibibytes" data-field="maximumProfileImageSize" />
<p class="help-block">
[[admin/settings/uploads:max-profile-image-size-help]]
</p>
@ -107,7 +107,7 @@
<div class="form-group">
<label>[[admin/settings/uploads:max-cover-image-size]]</label>
<input type="text" class="form-control" placeholder="Maximum size of uploaded cover images in kilobytes" data-field="maximumCoverImageSize" />
<input type="text" class="form-control" placeholder="Maximum size of uploaded cover images in kibibytes" data-field="maximumCoverImageSize" />
<p class="help-block">
[[admin/settings/uploads:max-cover-image-size-help]]
</p>

@ -411,6 +411,32 @@ describe('Groups', function () {
});
});
});
it('should fail to add user to group if group name is invalid', function (done) {
Groups.join(0, 1, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
Groups.join(null, 1, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
Groups.join(undefined, 1, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
done();
});
});
});
});
it('should fail to add user to group if uid is invalid', function (done) {
Groups.join('Test', 0, function (err) {
assert.equal(err.message, '[[error:invalid-uid]]');
Groups.join('Test', null, function (err) {
assert.equal(err.message, '[[error:invalid-uid]]');
Groups.join('Test', undefined, function (err) {
assert.equal(err.message, '[[error:invalid-uid]]');
done();
});
});
});
});
});
describe('.leave()', function () {

Loading…
Cancel
Save