diff --git a/loader.js b/loader.js
index e0bfac6258..20f9d49f88 100644
--- a/loader.js
+++ b/loader.js
@@ -6,6 +6,18 @@ var nconf = require('nconf'),
start = function() {
var fork = require('child_process').fork,
nbb_start = function() {
+ if (timesStarted > 3) {
+ console.log('\n[loader] Experienced three start attempts in 10 seconds, most likely am error on startup. Halting.');
+ process.exit();
+ return;
+ }
+
+ timesStarted++;
+ if (startTimer) {
+ clearTimeout(startTimer);
+ }
+ startTimer = setTimeout(resetTimer, 1000*10);
+
nbb = fork('./app', process.argv.slice(2), {
env: {
'NODE_ENV': process.env.NODE_ENV
@@ -29,6 +41,10 @@ var nconf = require('nconf'),
});
},
nbb_stop = function() {
+ if (startTimer) {
+ clearTimeout(startTimer);
+ }
+
nbb.kill();
if (fs.existsSync(pidFilePath)) {
var pid = parseInt(fs.readFileSync(pidFilePath, { encoding: 'utf-8' }), 10);
@@ -42,7 +58,13 @@ var nconf = require('nconf'),
nbb_start();
});
nbb.kill();
- };
+ },
+ resetTimer = function() {
+ clearTimeout(startTimer);
+ timesStarted = 0;
+ },
+ timesStarted = 0,
+ startTimer;
process.on('SIGINT', nbb_stop);
process.on('SIGTERM', nbb_stop);
diff --git a/public/language/ar/unread.json b/public/language/ar/unread.json
index 0c763e2d90..3a973748af 100644
--- a/public/language/ar/unread.json
+++ b/public/language/ar/unread.json
@@ -1,6 +1,9 @@
{
"title": "Unread",
"no_unread_topics": "ليس هناك أي موضوع غير مقروء",
- "mark_all_read": "إجعل كل المواضيع مقرؤة",
- "load_more": "حمل المزيد"
+ "load_more": "حمل المزيد",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/cs/unread.json b/public/language/cs/unread.json
index 88f2fd2255..e3e5bc1ce5 100644
--- a/public/language/cs/unread.json
+++ b/public/language/cs/unread.json
@@ -1,6 +1,9 @@
{
"title": "Unread",
"no_unread_topics": "Nejsou zde žádné nepřečtené témata.",
- "mark_all_read": "Označit vše jako přečtené",
- "load_more": "Načíst další"
+ "load_more": "Načíst další",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/de/category.json b/public/language/de/category.json
index b0a4cd36a5..85e6c3da99 100644
--- a/public/language/de/category.json
+++ b/public/language/de/category.json
@@ -7,6 +7,6 @@
"browsing": "Aktiv",
"no_replies": "Niemand hat geantwortet",
"replied": "geantwortet",
- "last_edited_by": "zuletzt editiert durch",
- "share_this_category": "Share this category"
+ "last_edited_by": "zuletzt editiert von",
+ "share_this_category": "Teile diese Kategorie"
}
\ No newline at end of file
diff --git a/public/language/de/unread.json b/public/language/de/unread.json
index 0ca36e3266..3362e0dee9 100644
--- a/public/language/de/unread.json
+++ b/public/language/de/unread.json
@@ -1,6 +1,9 @@
{
"title": "Ungelesen",
"no_unread_topics": "Es gibt keine ungelesenen Themen.",
- "mark_all_read": "alle als gelesen markieren",
- "load_more": "mehr laden"
+ "load_more": "mehr laden",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/en@pirate/unread.json b/public/language/en@pirate/unread.json
index a4bb2fd315..17e7089fdf 100644
--- a/public/language/en@pirate/unread.json
+++ b/public/language/en@pirate/unread.json
@@ -1,6 +1,9 @@
{
"title": "Unread",
"no_unread_topics": "There be no unread topics.",
- "mark_all_read": "I seen 'em all!",
- "load_more": "Giv'er more"
+ "load_more": "Giv'er more",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json
index dcab1f9288..584a472327 100644
--- a/public/language/en_GB/error.json
+++ b/public/language/en_GB/error.json
@@ -5,11 +5,32 @@
"invalid-cid": "Invalid Category ID",
"invalid-tid": "Invalid Topic ID",
+ "invalid-pid": "Invalid Post ID",
+ "invalid-uid": "Invalid User ID",
+
+ "invalid-username": "Invalid Username",
+ "invalid-email": "Invalid Email",
+ "invalid-title": "Invalid title",
+ "invalid-user-data": "Invalid User Data",
+ "invalid-password": "Invalid Password",
+
+ "invalid-pagination-value": "Invalid pagination value",
+
+ "username-taken": "Username taken",
+ "email-taken": "Email taken",
+
+ "user-banned": "User banned",
"no-category": "Category doesn't exist",
"no-topic": "Topic doesn't exist",
+ "no-post": "Post doesn't exist",
+ "no-group": "Group doesn't exist",
+ "no-user": "User doesn't exist",
+ "no-teaser": "Teaser doesn't exist",
"no-privileges": "You don't have enough privileges for this action.",
+ "category-disabled": "Category disabled",
+
"topic-locked": "Topic Locked",
"still-uploading" : "Please wait for uploads to complete.",
@@ -17,5 +38,32 @@
"title-too-short" : "Please enter a longer title. At least %1 characters.",
"title-too-long" : "Please enter a shorter title. Titles can't be longer than %1 characters.",
"too-many-posts" : "You can only post every %1 seconds.'",
- "file-too-big" : "Maximum allowed file size is %1 kbs"
-}
\ No newline at end of file
+ "file-too-big" : "Maximum allowed file size is %1 kbs",
+
+ "cant-vote-self-post": "You cannot vote for your own post",
+ "already-favourited": "You already favourited this post",
+ "already-unfavourited": "You alread unfavourited this post",
+
+ "cant-ban-other-admins": "You can't ban other admins!",
+
+ "invalid-image-type": "Invalid image type",
+
+ "group-name-too-short": "Group name too short",
+ "group-already-exists": "Group already exists",
+ "group-name-change-not-allowed": "Group name change not allowed",
+
+ "post-already-deleted": "Post already deleted",
+ "post-already-restored": "Post already restored",
+
+ "topic-already-deleted": "Topic already deleted",
+ "topic-already-restored": "Topic already restored",
+
+
+ "topic-thumbnails-are-disabled": "Topic thumbnails are disabled.",
+ "invalid-file": "Invalid File",
+ "uploads-are-disabled": "Uploads are disabled",
+
+ "signature-too-long" : "Signature can't be longer than %1 characters!",
+
+ "cant-chat-with-yourself": "You can't chat with yourself!"
+}
diff --git a/public/language/en_GB/success.json b/public/language/en_GB/success.json
index 397b857c38..d38b90c6fa 100644
--- a/public/language/en_GB/success.json
+++ b/public/language/en_GB/success.json
@@ -1,4 +1,5 @@
{
- "topic-post": "You have successfully posted."
+ "topic-post": "You have successfully posted.",
+ "authentication-successful": "Authentication Successful"
}
\ No newline at end of file
diff --git a/public/language/en_GB/topic.json b/public/language/en_GB/topic.json
index 1a38c9f776..a11a3b941a 100644
--- a/public/language/en_GB/topic.json
+++ b/public/language/en_GB/topic.json
@@ -69,15 +69,8 @@
"favourite": "Favourite",
"favourites": "Favourites",
- "favourites.not_logged_in.title": "Not Logged In",
- "favourites.not_logged_in.message": "Please log in in order to favourite this post",
"favourites.has_no_favourites": "You don't have any favourites, favourite some posts to see them here!",
- "vote.not_logged_in.title": "Not Logged In",
- "vote.not_logged_in.message": "Please log in in order to vote",
- "vote.cant_vote_self.title": "Invalid Vote",
- "vote.cant_vote_self.message": "You cannot vote for your own post",
-
"loading_more_posts": "Loading More Posts",
"move_topic": "Move Topic",
"move_post": "Move Post",
diff --git a/public/language/en_GB/user.json b/public/language/en_GB/user.json
index d7f2d83b2d..110dd9698e 100644
--- a/public/language/en_GB/user.json
+++ b/public/language/en_GB/user.json
@@ -23,6 +23,7 @@
"follow": "Follow",
"unfollow": "Unfollow",
+ "profile_update_success": "Profile has been updated successfully!",
"change_picture": "Change Picture",
"edit": "Edit",
"uploaded_picture": "Uploaded Picture",
diff --git a/public/language/es/unread.json b/public/language/es/unread.json
index b06f14f687..29f15be5f2 100644
--- a/public/language/es/unread.json
+++ b/public/language/es/unread.json
@@ -1,6 +1,9 @@
{
"title": "No leído",
"no_unread_topics": "No hay temas nuevos para leer.",
- "mark_all_read": "Marcar todo como leído",
- "load_more": "Cargar más"
+ "load_more": "Cargar más",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/et/unread.json b/public/language/et/unread.json
index a8de01c463..606ffe7fcd 100644
--- a/public/language/et/unread.json
+++ b/public/language/et/unread.json
@@ -1,6 +1,9 @@
{
"title": "Lugemata",
"no_unread_topics": "Siin ei ole lugemata teemasi.",
- "mark_all_read": "Märgi kõik loetuks",
- "load_more": "Lae rohkem"
+ "load_more": "Lae rohkem",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/fa_IR/unread.json b/public/language/fa_IR/unread.json
index fcfe933e92..b65f56a41f 100644
--- a/public/language/fa_IR/unread.json
+++ b/public/language/fa_IR/unread.json
@@ -1,6 +1,9 @@
{
"title": "نخواندهها",
"no_unread_topics": "جستار خوانده نشدهای وجود ندارد.",
- "mark_all_read": "همه را خوانده شده بگیر",
- "load_more": "بارگذاری بیشتر"
+ "load_more": "بارگذاری بیشتر",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/fi/unread.json b/public/language/fi/unread.json
index 928290c7ce..f6f1990845 100644
--- a/public/language/fi/unread.json
+++ b/public/language/fi/unread.json
@@ -1,6 +1,9 @@
{
"title": "Lukematon",
"no_unread_topics": "Ei lukemattomia aiheita.",
- "mark_all_read": "Merkitse kaikki luetuiksi",
- "load_more": "Lataa lisää"
+ "load_more": "Lataa lisää",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/fr/unread.json b/public/language/fr/unread.json
index 69c70b8de9..f48f6def05 100644
--- a/public/language/fr/unread.json
+++ b/public/language/fr/unread.json
@@ -1,6 +1,9 @@
{
"title": "Non Lu",
"no_unread_topics": "Aucun sujet non lu.",
- "mark_all_read": "Marquer tout comme lu",
- "load_more": "Charger la suite"
+ "load_more": "Charger la suite",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/he/unread.json b/public/language/he/unread.json
index e191fbf760..1b4cd01f78 100644
--- a/public/language/he/unread.json
+++ b/public/language/he/unread.json
@@ -1,6 +1,9 @@
{
"title": "לא נקרא",
"no_unread_topics": "אין נושאים שלא נקראו",
- "mark_all_read": "סמן הכל כנקרא",
- "load_more": "טען עוד"
+ "load_more": "טען עוד",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/hu/unread.json b/public/language/hu/unread.json
index 8c3a6a1887..e120ac3948 100644
--- a/public/language/hu/unread.json
+++ b/public/language/hu/unread.json
@@ -1,6 +1,9 @@
{
"title": "Olvasatlan",
"no_unread_topics": "Nincsenek olvasatlan topikok.",
- "mark_all_read": "Az összes olvasottként jelölése",
- "load_more": "Több betöltése"
+ "load_more": "Több betöltése",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/it/unread.json b/public/language/it/unread.json
index 362b11e8f5..bb6af18556 100644
--- a/public/language/it/unread.json
+++ b/public/language/it/unread.json
@@ -1,6 +1,9 @@
{
"title": "Non letto",
"no_unread_topics": "Non ci sono discussioni non lette.",
- "mark_all_read": "Segna tutto come già letto",
- "load_more": "Carica Altro"
+ "load_more": "Carica Altro",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/nb/unread.json b/public/language/nb/unread.json
index 3e3150d7f1..f3a501649c 100644
--- a/public/language/nb/unread.json
+++ b/public/language/nb/unread.json
@@ -1,6 +1,9 @@
{
"title": "Uleste",
"no_unread_topics": "Det er ingen uleste emner.",
- "mark_all_read": "Marker alle som lest",
- "load_more": "Last mer"
+ "load_more": "Last mer",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/nl/unread.json b/public/language/nl/unread.json
index ce0b9a43e9..efee7eb23c 100644
--- a/public/language/nl/unread.json
+++ b/public/language/nl/unread.json
@@ -1,6 +1,9 @@
{
"title": "Ongelezen",
"no_unread_topics": "Er zijn geen ongelezen onderwerpen",
- "mark_all_read": "Alles markeren als Gelezen",
- "load_more": "Meer Laden"
+ "load_more": "Meer Laden",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/pl/unread.json b/public/language/pl/unread.json
index a69a8570a7..74197b2f5a 100644
--- a/public/language/pl/unread.json
+++ b/public/language/pl/unread.json
@@ -1,6 +1,9 @@
{
"title": "Nieprzeczytane",
"no_unread_topics": "Nie masz żadnych nieprzeczytanych wątków.",
- "mark_all_read": "Oznacz wszystkie jako przeczytane",
- "load_more": "Więcej"
+ "load_more": "Więcej",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/pt_BR/unread.json b/public/language/pt_BR/unread.json
index e5f60bcefa..b053b20a6f 100644
--- a/public/language/pt_BR/unread.json
+++ b/public/language/pt_BR/unread.json
@@ -1,6 +1,9 @@
{
"title": "Não Lido",
"no_unread_topics": "Todos os tópicos lidos.",
- "mark_all_read": "Marcar todos como Lido",
- "load_more": "Carregar"
+ "load_more": "Carregar",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/ru/unread.json b/public/language/ru/unread.json
index d1184cb5c8..1f7a121182 100644
--- a/public/language/ru/unread.json
+++ b/public/language/ru/unread.json
@@ -1,6 +1,9 @@
{
"title": "Непрочитанные темы",
"no_unread_topics": "Нет непрочитанных тем.",
- "mark_all_read": "Отметить все темы как прочитанные",
- "load_more": "Загрузить еще"
+ "load_more": "Загрузить еще",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/sc/unread.json b/public/language/sc/unread.json
index 6e0664abfc..db7e78b8c9 100644
--- a/public/language/sc/unread.json
+++ b/public/language/sc/unread.json
@@ -1,6 +1,9 @@
{
"title": "De Lèghere",
"no_unread_topics": "Non bi sunt arresonadas de lèghere.",
- "mark_all_read": "Signala comente Lèghidos",
- "load_more": "Càrriga de Prus"
+ "load_more": "Càrriga de Prus",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/sk/unread.json b/public/language/sk/unread.json
index 252ab9d3e4..99a9b42acf 100644
--- a/public/language/sk/unread.json
+++ b/public/language/sk/unread.json
@@ -1,6 +1,9 @@
{
"title": "Neprečítané",
"no_unread_topics": "Nie sú tu žiadne neprečítané témy.",
- "mark_all_read": "Označit všetko ako prečítané",
- "load_more": "Načítať dalšie"
+ "load_more": "Načítať dalšie",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/sv/unread.json b/public/language/sv/unread.json
index 12701bdde5..4bc578abc8 100644
--- a/public/language/sv/unread.json
+++ b/public/language/sv/unread.json
@@ -1,6 +1,9 @@
{
"title": "Olästa",
"no_unread_topics": "Det finns inga ilästa ämnen.",
- "mark_all_read": "Markera alla som lästa",
- "load_more": "Ladda fler"
+ "load_more": "Ladda fler",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/th/unread.json b/public/language/th/unread.json
index f0d186b444..37451a65ba 100644
--- a/public/language/th/unread.json
+++ b/public/language/th/unread.json
@@ -1,6 +1,9 @@
{
"title": "ไม่ได้อ่าน",
"no_unread_topics": "ไม่มีกระทู้ที่ยังไม่ได้อ่านเป็น",
- "mark_all_read": "มาร์คทั้งหมดเป็นอ่าน",
- "load_more": "โหลดเพิ่มเติม"
+ "load_more": "โหลดเพิ่มเติม",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/tr/unread.json b/public/language/tr/unread.json
index feabfb6e03..0473f2dd3a 100644
--- a/public/language/tr/unread.json
+++ b/public/language/tr/unread.json
@@ -1,6 +1,9 @@
{
"title": "Okunmadı",
"no_unread_topics": "Okunmamış başlık mevcut değil.",
- "mark_all_read": "Hepsini Okundu Olarak İşaretle",
- "load_more": "Daha Fazla"
+ "load_more": "Daha Fazla",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/zh_CN/unread.json b/public/language/zh_CN/unread.json
index b5107e3b47..296a432e01 100644
--- a/public/language/zh_CN/unread.json
+++ b/public/language/zh_CN/unread.json
@@ -1,6 +1,9 @@
{
"title": "未读",
"no_unread_topics": "没有未读主题。",
- "mark_all_read": "标记全部为已读",
- "load_more": "载入更多"
+ "load_more": "载入更多",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/language/zh_TW/unread.json b/public/language/zh_TW/unread.json
index 050c12403d..7f8beef22f 100644
--- a/public/language/zh_TW/unread.json
+++ b/public/language/zh_TW/unread.json
@@ -1,6 +1,9 @@
{
"title": "未讀",
"no_unread_topics": "沒有未讀主題。",
- "mark_all_read": "標記全部為已讀",
- "load_more": "載入更多"
+ "load_more": "載入更多",
+ "mark_as_read": "Mark as Read",
+ "selected": "Selected",
+ "all": "All",
+ "topics_marked_as_read.success": "Topics marked as read!"
}
\ No newline at end of file
diff --git a/public/src/app.js b/public/src/app.js
index 86e6033c45..108635da2e 100644
--- a/public/src/app.js
+++ b/public/src/app.js
@@ -320,25 +320,11 @@ var socket,
app.openChat = function (username, touid) {
if (username === app.username) {
- app.alert({
- type: 'warning',
- title: 'Invalid Chat',
- message: "You can't chat with yourself!",
- timeout: 5000
- });
-
- return;
+ return app.alertError('[[error:cant-chat-with-yourself]]');
}
if (!app.uid) {
- app.alert({
- type: 'danger',
- title: 'Not Logged In',
- message: 'Please log in to chat with ' + username + '',
- timeout: 5000
- });
-
- return;
+ return app.alertError('[[error:not-logged-in]]');
}
require(['chat'], function (chat) {
diff --git a/public/src/forum/accountedit.js b/public/src/forum/accountedit.js
index 701c97ff74..071cb31a3a 100644
--- a/public/src/forum/accountedit.js
+++ b/public/src/forum/accountedit.js
@@ -1,82 +1,82 @@
+'use strict';
+
+/* globals define, ajaxify, socket, app, config, utils, translator */
+
define(['forum/accountheader', 'uploader'], function(header, uploader) {
var AccountEdit = {},
gravatarPicture = '',
- uploadedPicture = '';
+ uploadedPicture = '',
+ selectedImageType = '';
AccountEdit.init = function() {
- header.init();
-
gravatarPicture = ajaxify.variables.get('gravatarpicture');
uploadedPicture = ajaxify.variables.get('uploadedpicture');
- var selectedImageType = '';
+ header.init();
- $('#submitBtn').on('click', function() {
+ $('#submitBtn').on('click', updateProfile);
- var userData = {
- uid: $('#inputUID').val(),
- username: $('#inputUsername').val(),
- email: $('#inputEmail').val(),
- fullname: $('#inputFullname').val(),
- website: $('#inputWebsite').val(),
- birthday: $('#inputBirthday').val(),
- location: $('#inputLocation').val(),
- signature: $('#inputSignature').val()
- };
+ handleImageChange();
+ handleImageUpload();
+ handlePasswordChange();
+ updateSignature();
+ };
- socket.emit('user.updateProfile', userData, function(err, data) {
- if(err) {
- return app.alertError(err.message);
- }
+ function updateProfile() {
+ var userData = {
+ uid: $('#inputUID').val(),
+ username: $('#inputUsername').val(),
+ email: $('#inputEmail').val(),
+ fullname: $('#inputFullname').val(),
+ website: $('#inputWebsite').val(),
+ birthday: $('#inputBirthday').val(),
+ location: $('#inputLocation').val(),
+ signature: $('#inputSignature').val()
+ };
- if (!data) {
- return app.alertError('There was an error updating the profile!');
- }
-
- app.alertSuccess('Profile has been updated successfully!');
- if (data.picture) {
- $('#user-current-picture').attr('src', data.picture);
- $('#user_label img').attr('src', data.picture);
- }
-
- if (data.gravatarpicture) {
- $('#user-gravatar-picture').attr('src', data.gravatarpicture);
- gravatarPicture = data.gravatarpicture;
- }
-
- if(data.userslug) {
- var oldslug = $('.account-username-box').attr('data-userslug');
- $('.account-username-box a').each(function(index) {
- $(this).attr('href', $(this).attr('href').replace(oldslug, data.userslug));
- });
-
- $('.account-username-box').attr('data-userslug', data.userslug);
-
- $('#user-profile-link').attr('href', config.relative_path + '/user/' + data.userslug);
- $('#user-profile-link span').html(' ' + userData.username);
- }
- });
- return false;
- });
-
-
- function getSignatureCharsLeft() {
- if($('#inputSignature').length) {
- return '(' + $('#inputSignature').val().length + '/' + config.maximumSignatureLength + ')';
- } else {
- return '';
+ socket.emit('user.updateProfile', userData, function(err, data) {
+ if (err) {
+ return app.alertError(err.message);
}
- }
- $('#signatureCharCountLeft').html(getSignatureCharsLeft());
+ app.alertSuccess('[[user:profile_update_success]]');
- $('#inputSignature').on('keyup change', function(ev) {
- $('#signatureCharCountLeft').html(getSignatureCharsLeft());
+ if (data.picture) {
+ $('#user-current-picture').attr('src', data.picture);
+ $('#user_label img').attr('src', data.picture);
+ }
+
+ if (data.gravatarpicture) {
+ $('#user-gravatar-picture').attr('src', data.gravatarpicture);
+ gravatarPicture = data.gravatarpicture;
+ }
+
+ if (data.userslug) {
+ var oldslug = $('.account-username-box').attr('data-userslug');
+ $('.account-username-box a').each(function(index) {
+ $(this).attr('href', $(this).attr('href').replace(oldslug, data.userslug));
+ });
+
+ $('.account-username-box').attr('data-userslug', data.userslug);
+
+ $('#user-profile-link').attr('href', config.relative_path + '/user/' + data.userslug);
+ $('#user-profile-link span').html(' ' + userData.username);
+ }
});
+ return false;
+ }
+
+ function handleImageChange() {
+ function selectImageType(type) {
+ $('#gravatar-box .fa-check').toggle(type === 'gravatar');
+ $('#uploaded-box .fa-check').toggle(type === 'uploaded');
+ selectedImageType = type;
+ }
+
$('#changePictureBtn').on('click', function() {
selectedImageType = '';
- AccountEdit.updateImages();
+ updateImages();
$('#change-picture-modal').modal('show');
$('#change-picture-modal').removeClass('hide');
@@ -85,31 +85,29 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) {
});
$('#gravatar-box').on('click', function() {
- $('#gravatar-box .fa-check').show();
- $('#uploaded-box .fa-check').hide();
- selectedImageType = 'gravatar';
+ selectImageType('gravatar');
});
$('#uploaded-box').on('click', function() {
- $('#gravatar-box .fa-check').hide();
- $('#uploaded-box .fa-check').show();
- selectedImageType = 'uploaded';
+ selectImageType('uploaded');
});
$('#savePictureChangesBtn').on('click', function() {
$('#change-picture-modal').modal('hide');
if (selectedImageType) {
- AccountEdit.changeUserPicture(selectedImageType);
+ changeUserPicture(selectedImageType);
- if (selectedImageType == 'gravatar')
+ if (selectedImageType === 'gravatar') {
$('#user-current-picture').attr('src', gravatarPicture);
- else if (selectedImageType == 'uploaded')
+ } else if (selectedImageType === 'uploaded') {
$('#user-current-picture').attr('src', uploadedPicture);
+ }
}
-
});
+ }
+ function handleImageUpload() {
$('#upload-picture-modal').on('hide', function() {
$('#userPhotoInput').val('');
});
@@ -117,7 +115,7 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) {
$('#uploadPictureBtn').on('click', function() {
$('#change-picture-modal').modal('hide');
- uploader.open(RELATIVE_PATH + '/user/uploadpicture', {uid: ajaxify.variables.get('theirid')}, config.maximumProfileImageSize, function(imageUrlOnServer) {
+ uploader.open(config.relative_path + '/user/uploadpicture', {uid: ajaxify.variables.get('theirid')}, config.maximumProfileImageSize, function(imageUrlOnServer) {
imageUrlOnServer = imageUrlOnServer + '?' + new Date().getTime();
$('#user-current-picture').attr('src', imageUrlOnServer);
@@ -130,137 +128,129 @@ define(['forum/accountheader', 'uploader'], function(header, uploader) {
}, app.updateHeader);
});
-
return false;
});
+ }
- function showError(element, msg) {
- translator.translate(msg, function(msg) {
- element.html(msg);
- element.parent()
- .removeClass('alert-success')
- .addClass('alert-danger');
- element.show();
- validationError = true;
- });
+ function handlePasswordChange() {
+ var currentPassword = $('#inputCurrentPassword');
+ var password_notify = $('#password-notify');
+ var password_confirm_notify = $('#password-confirm-notify');
+ var password = $('#inputNewPassword');
+ var password_confirm = $('#inputNewPasswordAgain');
+ var passwordvalid = false;
+ var passwordsmatch = false;
+ var successIcon = '';
+
+ function onPasswordChanged() {
+ passwordvalid = utils.isPasswordValid(password.val());
+ if (password.val().length < config.minimumPasswordLength) {
+ showError(password_notify, '[[user:change_password_error_length]]');
+ } else if (!passwordvalid) {
+ showError(password_notify, '[[user:change_password_error]]');
+ } else {
+ showSuccess(password_notify, successIcon);
+ }
}
- function showSuccess(element, msg) {
- translator.translate(msg, function(msg) {
- element.html(msg);
- element.parent()
- .removeClass('alert-danger')
- .addClass('alert-success');
- element.show();
- });
- }
-
- (function handlePasswordChange() {
- var currentPassword = $('#inputCurrentPassword');
- var password_notify = $('#password-notify');
- var password_confirm_notify = $('#password-confirm-notify');
- var password = $('#inputNewPassword');
- var password_confirm = $('#inputNewPasswordAgain');
- var passwordvalid = false;
- var passwordsmatch = false;
- var successIcon = '';
-
-
- function onPasswordChanged() {
- passwordvalid = utils.isPasswordValid(password.val());
- if (password.val().length < config.minimumPasswordLength) {
- showError(password_notify, '[[user:change_password_error_length]]');
- } else if (!passwordvalid) {
- showError(password_notify, '[[user:change_password_error]]');
+ function onPasswordConfirmChanged() {
+ if(password.val()) {
+ if (password.val() !== password_confirm.val()) {
+ showError(password_confirm_notify, '[[user:change_password_error_match]]');
+ passwordsmatch = false;
} else {
- showSuccess(password_notify, successIcon);
+ showSuccess(password_confirm_notify, successIcon);
+ passwordsmatch = true;
}
}
+ }
- function onPasswordConfirmChanged() {
- if(password.val()) {
- if (password.val() !== password_confirm.val()) {
- showError(password_confirm_notify, '[[user:change_password_error_match]]')
- passwordsmatch = false;
- } else {
- showSuccess(password_confirm_notify, successIcon);
- passwordsmatch = true;
+ password.on('blur', onPasswordChanged);
+ password_confirm.on('blur', onPasswordConfirmChanged);
+
+ $('#changePasswordBtn').on('click', function() {
+ if ((passwordvalid && passwordsmatch) || app.isAdmin) {
+ socket.emit('user.changePassword', {
+ 'currentPassword': currentPassword.val(),
+ 'newPassword': password.val(),
+ 'uid': ajaxify.variables.get('theirid')
+ }, function(err) {
+ currentPassword.val('');
+ password.val('');
+ password_confirm.val('');
+ passwordsmatch = false;
+ passwordvalid = false;
+
+ if (err) {
+ return app.alertError(err.message);
}
- }
+
+ app.alertSuccess('[[user:change_password_success]]');
+ });
}
+ return false;
+ });
+ }
- password.on('blur', onPasswordChanged);
- password_confirm.on('blur', onPasswordConfirmChanged);
-
- $('#changePasswordBtn').on('click', function() {
- if ((passwordvalid && passwordsmatch) || app.isAdmin) {
- socket.emit('user.changePassword', {
- 'currentPassword': currentPassword.val(),
- 'newPassword': password.val(),
- 'uid': ajaxify.variables.get('theirid')
- }, function(err) {
- currentPassword.val('');
- password.val('');
- password_confirm.val('');
- passwordsmatch = false;
- passwordvalid = false;
-
- if (err) {
- return app.alertError(err.message);
- }
-
- app.alertSuccess('[[user:change_password_success]]');
- });
- }
- return false;
- });
-
- }());
- };
-
-
- AccountEdit.changeUserPicture = function(type) {
- var userData = {
+ function changeUserPicture(type) {
+ socket.emit('user.changePicture', {
type: type,
uid: ajaxify.variables.get('theirid')
- };
-
- socket.emit('user.changePicture', userData, function(err) {
+ }, function(err) {
if(err) {
app.alertError(err.message);
}
});
}
- AccountEdit.updateImages = function() {
+ function updateImages() {
var currentPicture = $('#user-current-picture').attr('src');
if (gravatarPicture) {
$('#user-gravatar-picture').attr('src', gravatarPicture);
- $('#gravatar-box').show();
- } else {
- $('#gravatar-box').hide();
}
if (uploadedPicture) {
$('#user-uploaded-picture').attr('src', uploadedPicture);
- $('#uploaded-box').show();
- } else {
- $('#uploaded-box').hide();
}
+ $('#gravatar-box').toggle(!!gravatarPicture);
+ $('#uploaded-box').toggle(!!uploadedPicture);
- if (currentPicture == gravatarPicture) {
- $('#gravatar-box .fa-check').show();
- } else {
- $('#gravatar-box .fa-check').hide();
+ $('#gravatar-box .fa-check').toggle(currentPicture === gravatarPicture);
+ $('#uploaded-box .fa-check').toggle(currentPicture === uploadedPicture);
+ }
+
+ function updateSignature() {
+ function getSignatureCharsLeft() {
+ return $('#inputSignature').length ? '(' + $('#inputSignature').val().length + '/' + config.maximumSignatureLength + ')' : '';
}
- if (currentPicture == uploadedPicture) {
- $('#uploaded-box .fa-check').show();
- } else {
- $('#uploaded-box .fa-check').hide();
- }
+ $('#signatureCharCountLeft').html(getSignatureCharsLeft());
+
+ $('#inputSignature').on('keyup change', function(ev) {
+ $('#signatureCharCountLeft').html(getSignatureCharsLeft());
+ });
+ }
+
+ function showError(element, msg) {
+ translator.translate(msg, function(msg) {
+ element.html(msg);
+ element.parent()
+ .removeClass('alert-success')
+ .addClass('alert-danger');
+ element.show();
+ });
+ }
+
+ function showSuccess(element, msg) {
+ translator.translate(msg, function(msg) {
+ element.html(msg);
+ element.parent()
+ .removeClass('alert-danger')
+ .addClass('alert-success');
+ element.show();
+ });
}
return AccountEdit;
diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js
index 6df80606ea..ab9eb9d7ad 100644
--- a/public/src/forum/topic.js
+++ b/public/src/forum/topic.js
@@ -143,7 +143,7 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
ajaxify.register_events([
- 'event:rep_up', 'event:rep_down', 'event:favourited', 'event:unfavourited', 'event:new_post', 'get_users_in_room',
+ 'event:voted', 'event:favourited', 'event:new_post', 'get_users_in_room',
'event:topic_deleted', 'event:topic_restored', 'event:topic:locked',
'event:topic_unlocked', 'event:topic_pinned', 'event:topic_unpinned',
'event:topic_moved', 'event:post_edited', 'event:post_deleted', 'event:post_restored',
@@ -241,20 +241,12 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
app.populateOnlineUsers();
});
- socket.on('event:rep_up', function(data) {
- adjust_rep(1, data.pid, data.uid);
- });
-
- socket.on('event:rep_down', function(data) {
- adjust_rep(-1, data.pid, data.uid);
+ socket.on('event:voted', function(data) {
+ updatePostVotesAndUserReputation(data);
});
socket.on('event:favourited', function(data) {
- adjust_favourites(1, data.pid, data.uid);
- });
-
- socket.on('event:unfavourited', function(data) {
- adjust_favourites(-1, data.pid, data.uid);
+ updateFavouriteCount(data.post.pid, data.post.reputation);
});
socket.on('event:new_post', function(data) {
@@ -338,37 +330,31 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
});
});
- socket.on('posts.upvote', function(data) {
- if (data && data.pid) {
- $('li[data-pid="' + data.pid + '"] .upvote').addClass('btn-primary upvoted');
- }
+ socket.on('posts.upvote', function(pid) {
+ toggleUpvoteDownvote(pid, true, false);
});
- socket.on('posts.downvote', function(data) {
- if (data && data.pid) {
- $('li[data-pid="' + data.pid + '"] .downvote').addClass('btn-primary downvoted');
- }
+ socket.on('posts.downvote', function(pid) {
+ toggleUpvoteDownvote(pid, false, true);
});
- socket.on('posts.unvote', function(data) {
- if (data && data.pid) {
- var post = $('li[data-pid="' + data.pid + '"]');
-
- post.find('.upvote').removeClass('btn-primary upvoted');
- post.find('.downvote').removeClass('btn-primary downvoted');
- }
+ socket.on('posts.unvote', function(pid) {
+ toggleUpvoteDownvote(pid, false, false);
});
- socket.on('posts.favourite', function(data) {
- if (data && data.pid) {
- toggleFavourite(data.pid, true);
- }
+ function toggleUpvoteDownvote(pid, upvote, downvote) {
+ var post = $('li[data-pid="' + pid + '"]');
+
+ post.find('.upvote').toggleClass('btn-primary upvoted', upvote);
+ post.find('.downvote').toggleClass('btn-primary downvoted', downvote);
+ }
+
+ socket.on('posts.favourite', function(pid) {
+ toggleFavourite(pid, true);
});
- socket.on('posts.unfavourite', function(data) {
- if (data && data.pid) {
- toggleFavourite(data.pid, false);
- }
+ socket.on('posts.unfavourite', function(pid) {
+ toggleFavourite(pid, false);
});
function toggleFavourite(pid, isFavourited) {
@@ -406,26 +392,16 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
$('.thread_active_users [data-uid="' + uid + '"]').removeClass('replying');
});
- function adjust_rep(value, pid, uid) {
- var votes = $('li[data-pid="' + pid + '"] .votes'),
- reputationElements = $('.reputation[data-uid="' + uid + '"]'),
- currentVotes = parseInt(votes.attr('data-votes'), 10),
- reputation = parseInt(reputationElements.attr('data-reputation'), 10);
+ function updatePostVotesAndUserReputation(data) {
+ var votes = $('li[data-pid="' + data.post.pid + '"] .votes'),
+ reputationElements = $('.reputation[data-uid="' + data.post.uid + '"]');
- currentVotes += value;
- reputation += value;
-
- votes.html(currentVotes).attr('data-votes', currentVotes);
- reputationElements.html(reputation).attr('data-reputation', reputation);
+ votes.html(data.post.votes).attr('data-votes', data.post.votes);
+ reputationElements.html(data.user.reputation).attr('data-reputation', data.user.reputation);
}
- function adjust_favourites(value, pid, uid) {
- var favourites = $('li[data-pid="' + pid + '"] .favouriteCount'),
- currentFavourites = parseInt(favourites.attr('data-favourites'), 10);
-
- currentFavourites += value;
-
- favourites.html(currentFavourites).attr('data-favourites', currentFavourites);
+ function updateFavouriteCount(pid, value) {
+ $('li[data-pid="' + pid + '"] .favouriteCount').html(value).attr('data-favourites', value);
}
function set_locked_state(locked, alert) {
diff --git a/public/src/forum/topic/postTools.js b/public/src/forum/topic/postTools.js
index 36243dad79..bbe9a109ca 100644
--- a/public/src/forum/topic/postTools.js
+++ b/public/src/forum/topic/postTools.js
@@ -111,6 +111,10 @@ define(['composer', 'share'], function(composer, share) {
socket.emit(method, {
pid: pid,
room_id: app.currentRoom
+ }, function(err) {
+ if (err) {
+ app.alertError(err.message);
+ }
});
return false;
@@ -123,6 +127,10 @@ define(['composer', 'share'], function(composer, share) {
socket.emit(currentState ? 'posts.unvote' : method , {
pid: post.attr('data-pid'),
room_id: app.currentRoom
+ }, function(err) {
+ if (err) {
+ app.alertError(err.message);
+ }
});
return false;
diff --git a/src/categories.js b/src/categories.js
index 809c77c8e5..409e8e7aeb 100644
--- a/src/categories.js
+++ b/src/categories.js
@@ -64,7 +64,7 @@ var db = require('./database'),
Categories.getCategoryById = function(cid, start, end, uid, callback) {
Categories.getCategoryData(cid, function(err, category) {
if(err || !category) {
- return callback(err || new Error('category-not-found [' + cid + ']'));
+ return callback(err || new Error('[[error:invalid-cid]]'));
}
if(parseInt(uid, 10)) {
@@ -278,7 +278,7 @@ var db = require('./database'),
Categories.getCategories = function(cids, uid, callback) {
if (!Array.isArray(cids) || cids.length === 0) {
- return callback(new Error('invalid-cids'));
+ return callback(new Error('[[error:invalid-cid]]'));
}
async.parallel({
diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js
index 369449e9aa..518c170445 100644
--- a/src/controllers/accounts.js
+++ b/src/controllers/accounts.js
@@ -33,7 +33,7 @@ function userNotAllowed(res) {
function getUserDataByUserSlug(userslug, callerUID, callback) {
user.getUidByUserslug(userslug, function(err, uid) {
if(err || !uid) {
- return callback(err || new Error('invalid-user'));
+ return callback(err || new Error('[[error:invalid-uid]]'));
}
async.parallel({
@@ -54,7 +54,7 @@ function getUserDataByUserSlug(userslug, callerUID, callback) {
}
}, function(err, results) {
if(err || !results.userData) {
- return callback(err || new Error('invalid-user'));
+ return callback(err || new Error('[[error:invalid-uid]]'));
}
var userData = results.userData;
diff --git a/src/controllers/categories.js b/src/controllers/categories.js
index 93112a2524..f30dcc13b3 100644
--- a/src/controllers/categories.js
+++ b/src/controllers/categories.js
@@ -70,7 +70,7 @@ categoriesController.get = function(req, res, next) {
categoryTools.privileges(cid, uid, function(err, categoryPrivileges) {
if (!err) {
if (!categoryPrivileges.read) {
- next(new Error('not-enough-privileges'));
+ next(new Error('[[error:no-privileges]]'));
} else {
next(null, categoryPrivileges);
}
@@ -95,7 +95,7 @@ categoriesController.get = function(req, res, next) {
if (categoryData) {
if (parseInt(categoryData.disabled, 10) === 1) {
- return next(new Error('Category disabled'), null);
+ return next(new Error('[[error:category-disabled]]'));
}
}
diff --git a/src/controllers/topics.js b/src/controllers/topics.js
index aa5488295d..5fdf606d47 100644
--- a/src/controllers/topics.js
+++ b/src/controllers/topics.js
@@ -26,7 +26,7 @@ topicsController.get = function(req, res, next) {
}
if (!userPrivileges.read) {
- return next(new Error('not-enough-privileges'));
+ return next(new Error('[[error:no-privileges]]'));
}
privileges = userPrivileges;
@@ -45,7 +45,7 @@ topicsController.get = function(req, res, next) {
topics.getTopicWithPosts(tid, uid, start, end, function (err, topicData) {
if (topicData) {
if (parseInt(topicData.deleted, 10) === 1 && parseInt(topicData.expose_tools, 10) === 0) {
- return next(new Error('Topic deleted'));
+ return next(new Error('[[error:no-topic]]'));
}
topicData.currentPage = page;
}
diff --git a/src/database/mongo.js b/src/database/mongo.js
index aaf161ee42..e792d41b1a 100644
--- a/src/database/mongo.js
+++ b/src/database/mongo.js
@@ -538,21 +538,15 @@
getSortedSetRange(key, start, stop, -1, callback);
};
- module.getSortedSetRangeByScore = function(args, callback) {
- getSortedSetRangeByScore(args, 1, callback);
+ module.getSortedSetRangeByScore = function(key, start, count, min, max, callback) {
+ getSortedSetRangeByScore(key, start, count, min, max, 1, callback);
};
- module.getSortedSetRevRangeByScore = function(args, callback) {
- getSortedSetRangeByScore(args, -1, callback);
+ module.getSortedSetRevRangeByScore = function(key, start, count, max, min, callback) {
+ getSortedSetRangeByScore(key, start, count, min, max, -1, callback);
};
- function getSortedSetRangeByScore(args, sort, callback) {
- var key = args[0],
- max = (args[1] === '+inf') ? Number.MAX_VALUE : args[1],
- min = args[2],
- start = args[4],
- count = args[5];
-
+ function getSortedSetRangeByScore(key, start, count, min, max, sort, callback) {
if(parseInt(count, 10) === -1) {
count = 0;
}
diff --git a/src/database/redis.js b/src/database/redis.js
index 90daed3e74..f14863a83b 100644
--- a/src/database/redis.js
+++ b/src/database/redis.js
@@ -359,12 +359,12 @@
redisClient.zrevrange(key, start, stop, callback);
};
- module.getSortedSetRangeByScore = function(args, callback) {
- redisClient.zrangebyscore(args, callback);
+ module.getSortedSetRangeByScore = function(key, start, count, min, max, callback) {
+ redisClient.zrangebyscore([key, min, max, 'LIMIT', start, count], callback);
};
- module.getSortedSetRevRangeByScore = function(args, callback) {
- redisClient.zrevrangebyscore(args, callback);
+ module.getSortedSetRevRangeByScore = function(key, start, count, max, min, callback) {
+ redisClient.zrevrangebyscore([key, max, min, 'LIMIT', start, count], callback);
};
module.sortedSetCount = function(key, min, max, callback) {
diff --git a/src/favourites.js b/src/favourites.js
index 67c52b8d8c..30ef254cfb 100644
--- a/src/favourites.js
+++ b/src/favourites.js
@@ -8,67 +8,50 @@ var async = require('async'),
(function (Favourites) {
"use strict";
- function vote(type, unvote, pid, room_id, uid, socket, callback) {
- var websockets = require('./socket.io');
+ function vote(type, unvote, pid, uid, callback) {
+ uid = parseInt(uid, 10);
if (uid === 0) {
- return socket.emit('event:alert', {
- alert_id: 'post_vote',
- title: '[[topic:vote.not_logged_in.title]]',
- message: '[[topic:vote.not_logged_in.message]]',
- type: 'danger',
- timeout: 5000
- });
+ return callback(new Error('[[error:not-logged-in]]'));
}
- posts.getPostFields(pid, ['uid', 'timestamp'], function (err, postData) {
- if (uid === parseInt(postData.uid, 10)) {
- socket.emit('event:alert', {
- alert_id: 'post_vote',
- title: '[[topic:vote.cant_vote_self.title]]',
- message: '[[topic:vote.cant_vote_self.message]]',
- type: 'danger',
- timeout: 5000
- });
-
- if (callback) {
- callback(false);
- }
-
- return false;
+ posts.getPostFields(pid, ['pid', 'uid', 'timestamp'], function (err, postData) {
+ if (err) {
+ return callback(err);
}
- if(type === 'upvote' || !unvote) {
- db.sortedSetAdd('uid: ' + uid + ':upvote', postData.timestamp, pid);
+ if (uid === parseInt(postData.uid, 10)) {
+ return callback(new Error('[[error:cant-vote-self-post]]'));
+ }
+
+ if(type === 'upvote' && !unvote) {
+ db.sortedSetAdd('uid:' + uid + ':upvote', postData.timestamp, pid);
} else {
- db.sortedSetRemove('uid: ' + uid + ':upvote', pid);
+ db.sortedSetRemove('uid:' + uid + ':upvote', pid);
}
if(type === 'upvote' || unvote) {
- db.sortedSetRemove('uid: ' + uid + ':downvote', pid);
+ db.sortedSetRemove('uid:' + uid + ':downvote', pid);
} else {
- db.sortedSetAdd('uid: ' + uid + ':downvote', postData.timestamp, pid);
+ db.sortedSetAdd('uid:' + uid + ':downvote', postData.timestamp, pid);
}
user[type === 'upvote' ? 'incrementUserFieldBy' : 'decrementUserFieldBy'](postData.uid, 'reputation', 1, function (err, newreputation) {
- db.sortedSetAdd('users:reputation', newreputation, postData.uid);
- });
-
- if (room_id) {
- websockets.in(room_id).emit('event:' + (type === 'upvote' ? 'rep_up' : 'rep_down'), {
- uid: postData.uid,
- pid: pid
- });
- }
-
- socket.emit('posts.' + (unvote ? 'unvote' : type), {
- pid: pid
- });
-
- adjustPostVotes(pid, uid, type, unvote, function() {
- if (callback) {
- callback();
+ if (err) {
+ return callback(err);
}
+
+ db.sortedSetAdd('users:reputation', newreputation, postData.uid);
+
+ adjustPostVotes(pid, uid, type, unvote, function(err, votes) {
+ postData.votes = votes;
+ callback(err, {
+ user: {
+ reputation: newreputation
+ },
+ post: postData
+ });
+ });
});
});
}
@@ -79,21 +62,19 @@ var async = require('async'),
async.series([
function(next) {
if (unvote) {
- db.setRemove('pid:' + pid + ':' + type, uid, function(err) {
- next(err);
- });
+ db.setRemove('pid:' + pid + ':' + type, uid, next);
} else {
- db.setAdd('pid:' + pid + ':' + type, uid, function(err) {
- next(err);
- });
+ db.setAdd('pid:' + pid + ':' + type, uid, next);
}
},
function(next) {
- db.setRemove('pid:' + pid + ':' + notType, uid, function(err) {
- next(err);
- });
+ db.setRemove('pid:' + pid + ':' + notType, uid, next);
}
], function(err) {
+ if (err) {
+ return callback(err);
+ }
+
async.parallel({
upvotes: function(next) {
db.setCount('pid:' + pid + ':upvote', next);
@@ -102,48 +83,46 @@ var async = require('async'),
db.setCount('pid:' + pid + ':downvote', next);
}
}, function(err, results) {
- posts.setPostField(pid, 'votes', parseInt(results.upvotes, 10) - parseInt(results.downvotes, 10));
+ if (err) {
+ return callback(err);
+ }
+ var voteCount = parseInt(results.upvotes, 10) - parseInt(results.downvotes, 10);
+ posts.setPostField(pid, 'votes', voteCount, function(err) {
+ callback(err, voteCount);
+ });
});
+ });
+ }
- if (callback) {
- callback();
+ Favourites.upvote = function(pid, uid, callback) {
+ toggleVote('upvote', pid, uid, callback);
+ };
+
+ Favourites.downvote = function(pid, uid, callback) {
+ toggleVote('downvote', pid, uid, callback);
+ };
+
+ function toggleVote(type, pid, uid, callback) {
+ Favourites.unvote(pid, uid, function(err) {
+ if (err) {
+ return callback(err);
}
+
+ vote(type, false, pid, uid, callback);
});
}
- Favourites.upvote = function(pid, room_id, uid, socket) {
- toggleVote('upvote', pid, room_id, uid, socket);
- };
-
- Favourites.downvote = function(pid, room_id, uid, socket) {
- toggleVote('downvote', pid, room_id, uid, socket);
- };
-
- function toggleVote(type, pid, room_id, uid, socket) {
- Favourites.unvote(pid, room_id, uid, socket, function(err) {
- vote(type, false, pid, room_id, uid, socket);
- });
- }
-
- Favourites.unvote = function(pid, room_id, uid, socket, callback) {
- var websockets = require('./socket.io');
-
+ Favourites.unvote = function(pid, uid, callback) {
Favourites.hasVoted(pid, uid, function(err, voteStatus) {
- if (voteStatus.upvoted || voteStatus.downvoted) {
- socket.emit('posts.unvote', {
- pid: pid
- });
-
- return vote(voteStatus.upvoted ? 'downvote' : 'upvote', true, pid, room_id, uid, socket, function() {
- if (callback) {
- callback(err);
- }
- });
+ if (err) {
+ return callback(err);
}
- if (callback) {
- callback(err);
+ if (!voteStatus || (!voteStatus.upvoted && !voteStatus.downvoted)) {
+ return callback();
}
+
+ vote(voteStatus.upvoted ? 'downvote' : 'upvote', true, pid, uid, callback);
});
};
@@ -164,77 +143,64 @@ var async = require('async'),
}, callback);
};
- Favourites.favourite = function (pid, room_id, uid, socket) {
- var websockets = require('./socket.io');
+ Favourites.favourite = function (pid, uid, callback) {
+ toggleFavourite('favourite', pid, uid, callback);
+ };
+ Favourites.unfavourite = function(pid, uid, callback) {
+ toggleFavourite('unfavourite', pid, uid, callback);
+ };
+
+ function toggleFavourite(type, pid, uid, callback) {
if (uid === 0) {
- return socket.emit('event:alert', {
- alert_id: 'post_favourite',
- title: '[[topic:favourites.not_logged_in.title]]',
- message: '[[topic:favourites.not_logged_in.message]]',
- type: 'danger',
- timeout: 5000
- });
+ return callback(new Error('[[error:not-logged-in]]'));
}
- posts.getPostFields(pid, ['uid', 'timestamp'], function (err, postData) {
+ posts.getPostFields(pid, ['pid', 'uid', 'timestamp'], function (err, postData) {
+ if (err) {
+ return callback(err);
+ }
+
Favourites.hasFavourited(pid, uid, function (err, hasFavourited) {
- if (!hasFavourited) {
+ if (err) {
+ return callback(err);
+ }
+
+ if (type === 'favourite' && hasFavourited) {
+ return callback(new Error('[[error:already-favourited]]'));
+ }
+
+ if (type === 'unfavourite' && !hasFavourited) {
+ return callback(new Error('[[error:alrady-unfavourited]]'));
+ }
+
+ if (type === 'favourite') {
db.sortedSetAdd('uid:' + uid + ':favourites', postData.timestamp, pid);
- db.setAdd('pid:' + pid + ':users_favourited', uid, function(err) {
- db.setCount('pid:' + pid + ':users_favourited', function(err, count) {
- posts.setPostField(pid, 'reputation', count);
- });
- });
-
- if (room_id) {
- websockets.in(room_id).emit('event:favourited', {
- uid: uid !== postData.uid ? postData.uid : 0,
- pid: pid
- });
- }
-
- socket.emit('posts.favourite', {
- pid: pid
- });
- }
- });
- });
- };
-
- Favourites.unfavourite = function(pid, room_id, uid, socket) {
- var websockets = require('./socket.io');
-
- if (uid === 0) {
- return;
- }
-
- posts.getPostField(pid, 'uid', function (err, uid_of_poster) {
- Favourites.hasFavourited(pid, uid, function (err, hasFavourited) {
- if (hasFavourited) {
+ } else {
db.sortedSetRemove('uid:' + uid + ':favourites', pid);
- db.setRemove('pid:' + pid + ':users_favourited', uid, function(err) {
- db.setCount('pid:' + pid + ':users_favourited', function(err, count) {
- posts.setPostField(pid, 'reputation', count);
+ }
+
+
+ db[type === 'favourite' ? 'setAdd' : 'setRemove']('pid:' + pid + ':users_favourited', uid, function(err) {
+ if (err) {
+ return callback(err);
+ }
+
+ db.setCount('pid:' + pid + ':users_favourited', function(err, count) {
+ if (err) {
+ return callback(err);
+ }
+ postData.reputation = count;
+ posts.setPostField(pid, 'reputation', count, function(err) {
+ callback(err, {
+ post: postData
+ });
});
});
-
- if (room_id) {
- websockets.in(room_id).emit('event:unfavourited', {
- uid: uid !== uid_of_poster ? uid_of_poster : 0,
- pid: pid
- });
- }
-
- if (socket) {
- socket.emit('posts.unfavourite', {
- pid: pid
- });
- }
- }
+ });
});
});
- };
+ }
Favourites.hasFavourited = function(pid, uid, callback) {
db.isSetMember('pid:' + pid + ':users_favourited', uid, callback);
diff --git a/src/groups.js b/src/groups.js
index 24894ff7fb..6501b3dc66 100644
--- a/src/groups.js
+++ b/src/groups.js
@@ -137,7 +137,7 @@
Groups.create = function(name, description, callback) {
if (name.length === 0) {
- return callback(new Error('name-too-short'));
+ return callback(new Error('[[error:group-name-too-short]]'));
}
if (name === 'administrators' || name === 'registered-users') {
@@ -145,28 +145,32 @@
}
Groups.exists(name, function (err, exists) {
- if (!exists) {
- var groupData = {
- name: name,
- description: description,
- deleted: '0',
- hidden: '0',
- system: system ? '1' : '0'
- };
-
- async.parallel([
- function(next) {
- db.setAdd('groups', name, next);
- },
- function(next) {
- db.setObject('group:' + name, groupData, function(err) {
- Groups.get(name, {}, next);
- });
- }
- ], callback);
- } else {
- callback(new Error('group-exists'));
+ if (err) {
+ return callback(err);
}
+
+ if (exists) {
+ return callback(new Error('[[error:group-already-exists]]'));
+ }
+
+ var groupData = {
+ name: name,
+ description: description,
+ deleted: '0',
+ hidden: '0',
+ system: system ? '1' : '0'
+ };
+
+ async.parallel([
+ function(next) {
+ db.setAdd('groups', name, next);
+ },
+ function(next) {
+ db.setObject('group:' + name, groupData, function(err) {
+ Groups.get(name, {}, next);
+ });
+ }
+ ], callback);
});
};
@@ -184,12 +188,12 @@
db.setObject('group:' + groupName, values, callback);
} else {
if (callback) {
- callback(new Error('name-change-not-allowed'));
+ callback(new Error('[[error:group-name-change-not-allowed]]'));
}
}
} else {
if (callback) {
- callback(new Error('gid-not-found'));
+ callback(new Error('[[error:no-group]]'));
}
}
});
diff --git a/src/postTools.js b/src/postTools.js
index 7ecf7387ba..3cb73e2282 100644
--- a/src/postTools.js
+++ b/src/postTools.js
@@ -120,7 +120,7 @@ var winston = require('winston'),
PostTools.privileges(pid, uid, function(err, privileges) {
if (err || !privileges.editable) {
- return callback(err || new Error('not-privileges-to-edit'));
+ return callback(err || new Error('[[error:no-privileges]]'));
}
posts.getPostData(pid, function(err, postData) {
@@ -155,15 +155,15 @@ var winston = require('winston'),
},
function(deleted, next) {
if(parseInt(deleted, 10) === 1 && isDelete) {
- return next(new Error('Post already deleted'));
+ return next(new Error('[[error:post-already-deleted]]'));
} else if(parseInt(deleted, 10) !== 1 && !isDelete) {
- return next(new Error('Post already restored'));
+ return next(new Error('[[error:post-already-restored]]'));
}
PostTools.privileges(pid, uid, next);
},
function(privileges, next) {
if (!privileges || !privileges.editable) {
- return next(new Error('no privileges'));
+ return next(new Error('[[error:no-privileges]]'));
}
next();
}
diff --git a/src/posts.js b/src/posts.js
index 08603611ea..d35cd12e5d 100644
--- a/src/posts.js
+++ b/src/posts.js
@@ -30,7 +30,7 @@ var db = require('./database'),
toPid = data.toPid;
if (uid === null) {
- return callback(new Error('invalid-user'));
+ return callback(new Error('[[error:invalid-uid]]'));
}
var timestamp = Date.now(),
@@ -210,7 +210,7 @@ var db = require('./database'),
var count = parseInt(stop, 10) === -1 ? stop : stop - start + 1;
- db.getSortedSetRevRangeByScore(['posts:pid', '+inf', Date.now() - since, 'LIMIT', start, count], function(err, pids) {
+ db.getSortedSetRevRangeByScore('posts:pid', start, count, Infinity, Date.now() - since, function(err, pids) {
if(err) {
return callback(err);
}
@@ -420,7 +420,7 @@ var db = require('./database'),
topics.getTopicField(tid, 'cid', function(err, cid) {
if(err || !cid) {
- return callback(err || new Error('invalid-category-id'));
+ return callback(err || new Error('[[error:invalid-cid]]'));
}
callback(null, cid);
});
@@ -458,7 +458,7 @@ var db = require('./database'),
Posts.getPidPage = function(pid, uid, callback) {
if(!pid) {
- return callback(new Error('invalid-pid'));
+ return callback(new Error('[[error:invalid-pid]]'));
}
var index = 0;
diff --git a/src/routes/api.js b/src/routes/api.js
index 909f142863..54c72e3e45 100644
--- a/src/routes/api.js
+++ b/src/routes/api.js
@@ -63,14 +63,14 @@ function uploadPost(req, res, next) {
function uploadThumb(req, res, next) {
if (!meta.config.allowTopicsThumbnail) {
deleteTempFiles(req.files.files);
- return callback(new Error('Topic Thumbnails are disabled!'));
+ return callback(new Error('[[error:topic-thumbnails-are-disabled]]'));
}
upload(req, res, function(file, next) {
if(file.type.match(/image./)) {
uploadImage(file, next);
} else {
- next(new Error('Invalid File'));
+ next(new Error('[[error:invalid-file]]'));
}
}, next);
}
@@ -85,7 +85,7 @@ function uploadImage(image, callback) {
if (meta.config.allowFileUploads) {
uploadFile(image, callback);
} else {
- callback(new Error('Uploads are disabled!'));
+ callback(new Error('[[error:uploads-are-disabled]]'));
}
}
}
@@ -97,15 +97,15 @@ function uploadFile(file, callback) {
} else {
if(!meta.config.allowFileUploads) {
- return callback(new Error('File uploads are not allowed'));
+ return callback(new Error('[[error:uploads-are-disabled]]'));
}
if(!file) {
- return callback(new Error('invalid file'));
+ return callback(new Error('[[error:invalid-file]]'));
}
if(file.size > parseInt(meta.config.maximumFileSize, 10) * 1024) {
- return callback(new Error('File too big'));
+ return callback(new Error('[[error:file-too-big, ' + meta.config.maximumFileSize + ']]'));
}
var filename = 'upload-' + utils.generateUUID() + path.extname(file.name);
diff --git a/src/routes/authentication.js b/src/routes/authentication.js
index a2d9f66e44..2728f58116 100644
--- a/src/routes/authentication.js
+++ b/src/routes/authentication.js
@@ -158,7 +158,7 @@
Auth.login = function(username, password, next) {
if (!username || !password) {
- return next(new Error('invalid-user'));
+ return next(new Error('[[error:invalid-user-data]]'));
}
var userslug = utils.slugify(username);
@@ -170,7 +170,7 @@
if(!uid) {
// Even if a user doesn't exist, compare passwords anyway, so we don't immediately return
- return next(null, false, 'user doesn\'t exist');
+ return next(null, false, '[[error:no-user]]');
}
user.getUserFields(uid, ['password', 'banned'], function(err, userData) {
@@ -179,11 +179,11 @@
}
if (!userData || !userData.password) {
- return next(new Error('invalid userdata or password'));
+ return next(new Error('[[error:invalid-user-data]]'));
}
if (userData.banned && parseInt(userData.banned, 10) === 1) {
- return next(null, false, 'User banned');
+ return next(null, false, '[[error:user-banned]]');
}
bcrypt.compare(password, userData.password, function(err, res) {
@@ -192,12 +192,12 @@
}
if (!res) {
- return next(null, false, 'invalid-password');
+ return next(null, false, '[[error:invalid-password]]');
}
next(null, {
uid: uid
- }, 'Authentication successful');
+ }, '[[success:authentication-successful]]');
});
});
});
diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js
index 5888fd636d..dc0b248ae9 100644
--- a/src/socket.io/admin.js
+++ b/src/socket.io/admin.js
@@ -79,7 +79,7 @@ SocketAdmin.user.removeAdmin = function(socket, theirid, callback) {
SocketAdmin.user.createUser = function(socket, userData, callback) {
if (!userData) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
user.create(userData, callback);
};
@@ -87,7 +87,7 @@ SocketAdmin.user.createUser = function(socket, userData, callback) {
SocketAdmin.user.banUser = function(socket, theirid, callback) {
user.isAdministrator(theirid, function(err, isAdmin) {
if (err || isAdmin) {
- return callback(err || new Error('You can\'t ban other admins!'));
+ return callback(err || new Error('[[error:cant-ban-other-admins]]'));
}
user.ban(theirid, function(err) {
@@ -137,6 +137,10 @@ SocketAdmin.user.search = function(socket, username, callback) {
});
}
+ if (err) {
+ return callback(err);
+ }
+
async.each(data.users, isAdmin, function(err) {
callback(err, data);
});
@@ -146,7 +150,7 @@ SocketAdmin.user.search = function(socket, username, callback) {
/* Categories */
SocketAdmin.categories.create = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
categories.create(data, callback);
@@ -154,7 +158,7 @@ SocketAdmin.categories.create = function(socket, data, callback) {
SocketAdmin.categories.update = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
categories.update(data, callback);
@@ -162,7 +166,7 @@ SocketAdmin.categories.update = function(socket, data, callback) {
SocketAdmin.categories.search = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
var username = data.username,
@@ -184,7 +188,7 @@ SocketAdmin.categories.search = function(socket, data, callback) {
SocketAdmin.categories.setPrivilege = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
var cid = data.cid,
@@ -248,15 +252,14 @@ SocketAdmin.categories.getPrivilegeSettings = function(socket, cid, callback) {
callback(null, {
"+r": data['+r'].members,
"+w": data['+w'].members,
- "mods": data['mods'].members
+ "mods": data.mods.members
});
});
};
SocketAdmin.categories.setGroupPrivilege = function(socket, data, callback) {
-
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
if (data.set) {
@@ -295,7 +298,7 @@ SocketAdmin.themes.getInstalled = function(socket, data, callback) {
SocketAdmin.themes.set = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
widgets.reset(function(err) {
@@ -315,7 +318,7 @@ SocketAdmin.plugins.toggle = function(socket, plugin_id) {
SocketAdmin.widgets.set = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
widgets.setArea(data, callback);
@@ -328,7 +331,7 @@ SocketAdmin.config.get = function(socket, data, callback) {
SocketAdmin.config.set = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
meta.configs.set(data.key, data.value, function(err) {
@@ -354,7 +357,7 @@ SocketAdmin.config.remove = function(socket, key) {
/* Groups */
SocketAdmin.groups.create = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
groups.create(data.name, data.description, function(err, groupObj) {
@@ -376,7 +379,7 @@ SocketAdmin.groups.get = function(socket, groupName, callback) {
SocketAdmin.groups.join = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
groups.join(data.groupName, data.uid, callback);
@@ -384,7 +387,7 @@ SocketAdmin.groups.join = function(socket, data, callback) {
SocketAdmin.groups.leave = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
groups.leave(data.groupName, data.uid, callback);
@@ -392,7 +395,7 @@ SocketAdmin.groups.leave = function(socket, data, callback) {
SocketAdmin.groups.update = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
groups.update(data.groupName, data.values, function(err) {
diff --git a/src/socket.io/categories.js b/src/socket.io/categories.js
index 0dd546ef16..eaa6eb0966 100644
--- a/src/socket.io/categories.js
+++ b/src/socket.io/categories.js
@@ -13,7 +13,7 @@ SocketCategories.getRecentReplies = function(socket, cid, callback) {
return callback(err);
}
- if (privileges && !privileges.read) {
+ if (!privileges || !privileges.read) {
return callback(null, []);
}
@@ -27,7 +27,7 @@ SocketCategories.get = function(socket, data, callback) {
SocketCategories.loadMore = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
user.getSettings(socket.uid, function(err, settings) {
diff --git a/src/socket.io/meta.js b/src/socket.io/meta.js
index 08415ab260..e2733e33a7 100644
--- a/src/socket.io/meta.js
+++ b/src/socket.io/meta.js
@@ -37,7 +37,7 @@ SocketMeta.buildTitle = function(socket, text, callback) {
SocketMeta.updateHeader = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
if (socket.uid) {
@@ -76,7 +76,7 @@ SocketMeta.getUsageStats = function(socket, data, callback) {
SocketMeta.rooms.enter = function(socket, data) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
if (data.leave !== null) {
diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js
index 115bcf17b8..7dea871b32 100644
--- a/src/socket.io/modules.js
+++ b/src/socket.io/modules.js
@@ -49,35 +49,36 @@ var stopTracking = function(replyObj) {
};
SocketModules.composer.push = function(socket, pid, callback) {
- if (socket.uid || parseInt(meta.config.allowGuestPosting, 10)) {
- if (parseInt(pid, 10) > 0) {
-
- async.parallel([
- function(next) {
- posts.getPostFields(pid, ['content'], next);
- },
- function(next) {
- topics.getTopicDataByPid(pid, next);
- },
- function(next) {
- posts.getPidIndex(pid, next);
- }
- ], function(err, results) {
- if(err) {
- return callback(err);
- }
- callback(null, {
- pid: pid,
- body: results[0].content,
- title: results[1].title,
- topic_thumb: results[1].thumb,
- index: results[2]
- });
- });
- }
- } else {
- callback(new Error('no-uid'));
+ if(!socket.uid && parseInt(meta.config.allowGuestPosting, 10) !== 1) {
+ return callback(new Error('[[error:not-logged-in]]'));
}
+
+ posts.getPostFields(pid, ['content'], function(err, postData) {
+ if(err || (!postData && !postData.content)) {
+ return callback(err || new Error('[[error:invalid-pid]]'));
+ }
+
+ async.parallel({
+ topic: function(next) {
+ topics.getTopicDataByPid(pid, next);
+ },
+ index: function(next) {
+ posts.getPidIndex(pid, next);
+ }
+ }, function(err, results) {
+ if(err) {
+ return callback(err);
+ }
+
+ callback(null, {
+ pid: pid,
+ body: postData.content,
+ title: results.topic.title,
+ topic_thumb: results.topic.thumb,
+ index: results.index
+ });
+ });
+ });
};
SocketModules.composer.editCheck = function(socket, pid, callback) {
@@ -150,7 +151,7 @@ SocketModules.composer.getUsersByTid = function(socket, tid, callback) {
SocketModules.chats.get = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
Messaging.getMessages(socket.uid, data.touid, false, callback);
@@ -158,7 +159,7 @@ SocketModules.chats.get = function(socket, data, callback) {
SocketModules.chats.send = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
var touid = data.touid;
diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js
index 71bc1ab030..8383f58f82 100644
--- a/src/socket.io/posts.js
+++ b/src/socket.io/posts.js
@@ -11,7 +11,7 @@ var async = require('async'),
notifications = require('../notifications'),
groups = require('../groups'),
user = require('../user'),
- index = require('./index'),
+ websockets = require('./index'),
SocketPosts = {};
@@ -40,38 +40,50 @@ SocketPosts.reply = function(socket, data, callback) {
posts: [postData]
};
- index.server.sockets.emit('event:new_post', socketData);
+ websockets.server.sockets.emit('event:new_post', socketData);
callback();
}
});
};
-SocketPosts.upvote = function(socket, data) {
- favouriteCommand('upvote', socket, data);
+SocketPosts.upvote = function(socket, data, callback) {
+ favouriteCommand('upvote', 'voted', socket, data, callback);
sendNotificationToPostOwner(data, socket.uid, 'has upvoted your post');
};
-SocketPosts.downvote = function(socket, data) {
- favouriteCommand('downvote', socket, data);
+SocketPosts.downvote = function(socket, data, callback) {
+ favouriteCommand('downvote', 'voted', socket, data, callback);
};
-SocketPosts.unvote = function(socket, data) {
- favouriteCommand('unvote', socket, data);
+SocketPosts.unvote = function(socket, data, callback) {
+ favouriteCommand('unvote', 'voted', socket, data, callback);
};
-SocketPosts.favourite = function(socket, data) {
- favouriteCommand('favourite', socket, data);
+SocketPosts.favourite = function(socket, data, callback) {
+ favouriteCommand('favourite', 'favourited', socket, data, callback);
sendNotificationToPostOwner(data, socket.uid, 'has favourited your post');
};
-SocketPosts.unfavourite = function(socket, data) {
- favouriteCommand('unfavourite', socket, data);
+SocketPosts.unfavourite = function(socket, data, callback) {
+ favouriteCommand('unfavourite', 'favourited', socket, data, callback);
};
-function favouriteCommand(command, socket, data) {
+function favouriteCommand(command, eventName, socket, data, callback) {
+
if(data && data.pid && data.room_id) {
- favourites[command](data.pid, data.room_id, socket.uid, socket);
+ favourites[command](data.pid, socket.uid, function(err, result) {
+ if (err) {
+ return callback(err);
+ }
+
+ socket.emit('posts.' + command, data.pid);
+
+ if(data.room_id && result && eventName) {
+ websockets.in(data.room_id).emit('event:' + eventName, result);
+ }
+ callback();
+ });
}
}
@@ -116,8 +128,8 @@ SocketPosts.getRawPost = function(socket, pid, callback) {
return callback(err);
}
- if(data.deleted === '1') {
- return callback(new Error('This post no longer exists'));
+ if(parseInt(data.deleted, 10) === 1) {
+ return callback(new Error('[[error:no-post]]'));
}
callback(null, data.content);
@@ -140,7 +152,7 @@ SocketPosts.edit = function(socket, data, callback) {
return callback(err);
}
- index.server.sockets.in('topic_' + results.topic.tid).emit('event:post_edited', {
+ websockets.server.sockets.in('topic_' + results.topic.tid).emit('event:post_edited', {
pid: data.pid,
title: results.topic.title,
isMainPost: results.topic.isMainPost,
@@ -161,7 +173,7 @@ SocketPosts.restore = function(socket, data, callback) {
function deleteOrRestore(command, socket, data, callback) {
if(!data) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
postTools[command](socket.uid, data.pid, function(err) {
@@ -172,7 +184,7 @@ function deleteOrRestore(command, socket, data, callback) {
module.parent.exports.emitTopicPostStats();
var eventName = command === 'restore' ? 'event:post_restored' : 'event:post_deleted';
- index.server.sockets.in('topic_' + data.tid).emit(eventName, {
+ websockets.server.sockets.in('topic_' + data.tid).emit(eventName, {
pid: data.pid
});
@@ -235,7 +247,7 @@ SocketPosts.getPidIndex = function(socket, pid, callback) {
SocketPosts.flag = function(socket, pid, callback) {
if (!socket.uid) {
- return callback(new Error('not-logged-in'));
+ return callback(new Error('[[error:not-logged-in]]'));
}
var message = '',
@@ -273,7 +285,7 @@ SocketPosts.flag = function(socket, pid, callback) {
SocketPosts.loadMoreFavourites = function(socket, data, callback) {
if(!data || !data.after) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
var start = parseInt(data.after, 10),
@@ -284,7 +296,7 @@ SocketPosts.loadMoreFavourites = function(socket, data, callback) {
SocketPosts.loadMoreUserPosts = function(socket, data, callback) {
if(!data || !data.after || !data.uid) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
var start = parseInt(data.after, 10),
@@ -296,7 +308,7 @@ SocketPosts.loadMoreUserPosts = function(socket, data, callback) {
SocketPosts.getRecentPosts = function(socket, data, callback) {
if(!data || !data.count) {
- return callback(new Error('invalid data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
posts.getRecentPosts(socket.uid, 0, data.count - 1, data.term, callback);
diff --git a/src/socket.io/user.js b/src/socket.io/user.js
index 4dee39f4be..ce78fe9976 100644
--- a/src/socket.io/user.js
+++ b/src/socket.io/user.js
@@ -60,7 +60,7 @@ SocketUser.changePassword = function(socket, data, callback) {
SocketUser.updateProfile = function(socket, data, callback) {
if(!data || !data.uid) {
- return callback(new Error('invalid-data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
if(socket.uid === parseInt(data.uid, 10)) {
@@ -73,7 +73,7 @@ SocketUser.updateProfile = function(socket, data, callback) {
}
if(!isAdmin) {
- return callback(new Error('not allowed!'));
+ return callback(new Error('[[error:no-privileges]]'));
}
user.updateProfile(data.uid, data, callback);
@@ -82,7 +82,7 @@ SocketUser.updateProfile = function(socket, data, callback) {
SocketUser.changePicture = function(socket, data, callback) {
if(!data) {
- return callback(new Error('invalid-data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
var type = data.type;
@@ -117,7 +117,7 @@ SocketUser.changePicture = function(socket, data, callback) {
} else if (type === 'uploaded') {
type = 'uploadedpicture';
} else {
- return callback(new Error('invalid-image-type'));
+ return callback(new Error('[[error:invalid-image-type]]'));
}
if(socket.uid === parseInt(data.uid, 10)) {
@@ -136,7 +136,7 @@ SocketUser.changePicture = function(socket, data, callback) {
}
if(!isAdmin) {
- return callback(new Error('not-allowed'));
+ return callback(new Error('[[error:no-privileges]]'));
}
changePicture(data.uid, callback);
@@ -170,7 +170,7 @@ SocketUser.saveSettings = function(socket, data, callback) {
SocketUser.getOnlineUsers = function(socket, data, callback) {
var returnData = {};
if(!data) {
- return callback(new Error('invalid-data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
function getUserStatus(uid, next) {
@@ -202,11 +202,11 @@ SocketUser.getActiveUsers = function(socket, data, callback) {
SocketUser.loadMore = function(socket, data, callback) {
if(!data || !data.set || parseInt(data.after, 10) < 0) {
- return callback(new Error('invalid-data'));
+ return callback(new Error('[[error:invalid-data]]'));
}
if (!socket.uid && !!parseInt(meta.config.privateUserInfo, 10)) {
- return callback(new Error('not-allowed'));
+ return callback(new Error('[[error:no-privileges]]'));
}
var start = data.after,
diff --git a/src/threadTools.js b/src/threadTools.js
index 27f2da6fe2..7e7c8e509b 100644
--- a/src/threadTools.js
+++ b/src/threadTools.js
@@ -69,9 +69,9 @@ var winston = require('winston'),
}
if (parseInt(deleted, 10) && isDelete) {
- return callback(new Error('topic-already-deleted'));
+ return callback(new Error('[[error:topic-already-deleted]]'));
} else if (!parseInt(deleted, 10) && !isDelete) {
- return callback(new Error('topic-already-restored'));
+ return callback(new Error('[[error:topic-already-restored]]'));
}
topics[isDelete ? 'delete' : 'restore'](tid, function(err) {
diff --git a/src/topics.js b/src/topics.js
index 2da58b7245..a5cbd0b69b 100644
--- a/src/topics.js
+++ b/src/topics.js
@@ -58,7 +58,7 @@ var async = require('async'),
Topics.getTopicDataWithUser = function(tid, callback) {
Topics.getTopicData(tid, function(err, topic) {
if (err || !topic) {
- return callback(err || new Error('topic doesn\'t exist'));
+ return callback(err || new Error('[[error:no-topic]]'));
}
user.getUserFields(topic.uid, ['username', 'userslug', 'picture'] , function(err, userData) {
@@ -101,7 +101,7 @@ var async = require('async'),
Topics.getTidPage = function(tid, uid, callback) {
if(!tid) {
- return callback(new Error('invalid-tid'));
+ return callback(new Error('[[error:invalid-tid]]'));
}
async.parallel({
@@ -270,7 +270,7 @@ var async = require('async'),
Topics.getTopicWithPosts = function(tid, uid, start, end, callback) {
Topics.getTopicData(tid, function(err, topicData) {
if (err || !topicData) {
- return callback(err || new Error('Topic tid \'' + tid + '\' not found'));
+ return callback(err || new Error('[[error:no-topic]]'));
}
async.parallel({
@@ -328,8 +328,8 @@ var async = require('async'),
posts.getPostFields(pid, ['pid', 'uid', 'timestamp'], function(err, postData) {
if (err) {
return callback(err);
- } else if(!postData) {
- return callback(new Error('no-teaser-found'));
+ } else if(!postData || !postData.uid) {
+ return callback(new Error('[[error:no-teaser]]'));
}
user.getUserFields(postData.uid, ['username', 'userslug', 'picture'], function(err, userData) {
diff --git a/src/topics/fork.js b/src/topics/fork.js
index 6cda238973..005b137058 100644
--- a/src/topics/fork.js
+++ b/src/topics/fork.js
@@ -19,11 +19,11 @@ module.exports = function(Topics) {
}
if(!title) {
- return callback(new Error('invalid-title'));
+ return callback(new Error('[[error:invalid-title]]'));
}
if(!pids || !pids.length) {
- return callback(new Error('invalid-pids'));
+ return callback(new Error('[[error:invalid-pid]]'));
}
pids.sort();
@@ -71,7 +71,7 @@ module.exports = function(Topics) {
Topics.movePostToTopic = function(pid, tid, callback) {
threadTools.exists(tid, function(err, exists) {
if(err || !exists) {
- return callback(err || new Error('Topic doesn\'t exist'));
+ return callback(err || new Error('[[error:no-topic]]'));
}
posts.getPostFields(pid, ['deleted', 'tid', 'timestamp'], function(err, postData) {
@@ -79,8 +79,8 @@ module.exports = function(Topics) {
return callback(err);
}
- if(!postData) {
- return callback(new Error('Post doesn\'t exist'));
+ if(!postData || !postData.tid) {
+ return callback(new Error('[[error:no-post]]'));
}
Topics.removePostFromTopic(postData.tid, pid, function(err) {
diff --git a/src/topics/recent.js b/src/topics/recent.js
index bb51800785..255c65a388 100644
--- a/src/topics/recent.js
+++ b/src/topics/recent.js
@@ -30,7 +30,7 @@ module.exports = function(Topics) {
var count = parseInt(end, 10) === -1 ? end : end - start + 1;
- db.getSortedSetRevRangeByScore(['topics:recent', '+inf', Date.now() - since, 'LIMIT', start, count], callback);
+ db.getSortedSetRevRangeByScore('topics:recent', start, count, Infinity, Date.now() - since, callback);
};
};
diff --git a/src/user.js b/src/user.js
index 93805a567b..a06219b957 100644
--- a/src/user.js
+++ b/src/user.js
@@ -126,11 +126,11 @@ var bcrypt = require('bcryptjs'),
}
if (parseInt(results.banned, 10) === 1) {
- return callback(new Error('user-banned'));
+ return callback(new Error('[[error:user-banned]]'));
}
if (!results.exists) {
- return callback(new Error('invalid-user'));
+ return callback(new Error('[[error:no-user]]'));
}
var lastposttime = results.lastposttime;
diff --git a/src/user/create.js b/src/user/create.js
index 33d7a5fd8c..f8f95b0878 100644
--- a/src/user/create.js
+++ b/src/user/create.js
@@ -25,17 +25,17 @@ module.exports = function(User) {
async.parallel([
function(next) {
if (userData.email) {
- next(!utils.isEmailValid(userData.email) ? new Error('Invalid Email!') : null);
+ next(!utils.isEmailValid(userData.email) ? new Error('[[error:invalid-email]]') : null);
} else {
next();
}
},
function(next) {
- next((!utils.isUserNameValid(userData.username) || !userData.userslug) ? new Error('Invalid Username!') : null);
+ next((!utils.isUserNameValid(userData.username) || !userData.userslug) ? new Error('[[error:invalid-username]]') : null);
},
function(next) {
if (userData.password) {
- next(!utils.isPasswordValid(userData.password) ? new Error('Invalid Password!') : null);
+ next(!utils.isPasswordValid(userData.password) ? new Error('[[error:invalid-password]]') : null);
} else {
next();
}
@@ -45,7 +45,7 @@ module.exports = function(User) {
if (err) {
return next(err);
}
- next(exists ? new Error('Username taken!') : null);
+ next(exists ? new Error('[[error:username-taken]]') : null);
});
},
function(next) {
@@ -54,7 +54,7 @@ module.exports = function(User) {
if (err) {
return next(err);
}
- next(!available ? new Error('Email taken!') : null);
+ next(!available ? new Error('[[error:email-taken]]') : null);
});
} else {
next();
diff --git a/src/user/notifications.js b/src/user/notifications.js
index df3096b8e8..3b4542a787 100644
--- a/src/user/notifications.js
+++ b/src/user/notifications.js
@@ -114,7 +114,7 @@ var async = require('async'),
UserNotifications.getDailyUnread = function(uid, callback) {
var now = Date.now(),
yesterday = now - (1000*60*60*24); // Approximate, can be more or less depending on time changes, makes no difference really.
- db.getSortedSetRangeByScore(['uid:' + uid + ':notifications:unread', yesterday, now], function(err, nids) {
+ db.getSortedSetRangeByScore('uid:' + uid + ':notifications:unread', 0, 20, yesterday, now, function(err, nids) {
async.map(nids, function(nid, next) {
notifications.get(nid, uid, function(notif_data) {
next(null, notif_data);
diff --git a/src/user/profile.js b/src/user/profile.js
index 50a33112e5..8620dde36e 100644
--- a/src/user/profile.js
+++ b/src/user/profile.js
@@ -18,7 +18,7 @@ module.exports = function(User) {
function isSignatureValid(next) {
if (data.signature !== undefined && data.signature.length > meta.config.maximumSignatureLength) {
- next(new Error('Signature can\'t be longer than ' + meta.config.maximumSignatureLength + ' characters!'));
+ next(new Error('[[error:signature-too-long, ' + meta.config.maximumSignatureLength + ']]'));
} else {
next();
}
@@ -39,7 +39,7 @@ module.exports = function(User) {
return next(err);
}
- next(!available ? new Error('Email not available!') : null);
+ next(!available ? new Error('[[error:email-taken]]') : null);
});
});
@@ -55,7 +55,7 @@ module.exports = function(User) {
}
if(!utils.isUserNameValid(data.username) || !userslug) {
- return next(new Error('Invalid Username!'));
+ return next(new Error('[[error:invalid-username]]'));
}
User.exists(userslug, function(err, exists) {
@@ -63,7 +63,7 @@ module.exports = function(User) {
return next(err);
}
- next(exists ? new Error('Username not available!') : null);
+ next(exists ? new Error('[[error:username-taken]]') : null);
});
});
}
@@ -196,7 +196,7 @@ module.exports = function(User) {
User.changePassword = function(uid, data, callback) {
if(!data || !data.uid) {
- return callback(new Error('invalid-uid'));
+ return callback(new Error('[[error:invalid-uid]]'));
}
function hashAndSetPassword(callback) {
diff --git a/src/user/reset.js b/src/user/reset.js
index 330f49c843..7e3b2d75c8 100644
--- a/src/user/reset.js
+++ b/src/user/reset.js
@@ -40,7 +40,7 @@ var async = require('async'),
UserReset.send = function(socket, email, callback) {
user.getUidByEmail(email, function(err, uid) {
if(err || !uid) {
- return callback(err || new Error('invalid-email'));
+ return callback(err || new Error('[[error:invalid-email]]'));
}
// Generate a new reset code
diff --git a/src/user/settings.js b/src/user/settings.js
index bc28622960..7e9665d9f0 100644
--- a/src/user/settings.js
+++ b/src/user/settings.js
@@ -37,7 +37,7 @@ module.exports = function(User) {
User.saveSettings = function(uid, data, callback) {
if(!data.topicsPerPage || !data.postsPerPage || parseInt(data.topicsPerPage, 10) <= 0 || parseInt(data.postsPerPage, 10) <= 0) {
- return callback(new Error('Invalid pagination value!'));
+ return callback(new Error('[[error:invalid-pagination-value]]'));
}
plugins.fireHook('action:user.saveSettings', {uid: uid, settings: data});
diff --git a/tests/database.js b/tests/database.js
index 8ca9a8f390..eaa8bc667a 100644
--- a/tests/database.js
+++ b/tests/database.js
@@ -349,4 +349,4 @@ describe('Test database', function() {
});
});
-});
\ No newline at end of file
+});
diff --git a/tests/topics.js b/tests/topics.js
index a028c1b274..c28456fdbc 100644
--- a/tests/topics.js
+++ b/tests/topics.js
@@ -43,7 +43,7 @@ describe('Topic\'s', function() {
it('should fail to create new topic with wrong parameters', function(done) {
topics.post({uid: null, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) {
- assert.equal(err.message, 'invalid-user');
+ assert.equal(err.message, '[[error:no-user]]');
done();
});
});