diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index cc592ac143..28dd965678 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,6 +1,7 @@ Please include the following information when submitting a bug report/issue: * NodeBB version and git hash (to find your git hash, execute `git rev-parse HEAD` from the main NodeBB directory) +* Database (mongo or redis) and it's version. * Exact steps to cause this issue 1. First I did this... 2. Then, I clicked on this item... @@ -9,4 +10,4 @@ Please include the following information when submitting a bug report/issue: * What happened instead * e.g. Instead, I got *zyx* and NodeBB set fire to my house -Thank you! \ No newline at end of file +Thank you! diff --git a/README.md b/README.md index 200a444b6d..2d1c90fed8 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,10 @@ Additional functionality is enabled through the use of third-party plugins. [![](http://i.imgur.com/LmHtPhob.png)](http://i.imgur.com/LmHtPho.png) [![](http://i.imgur.com/paiJPJkb.jpg)](http://i.imgur.com/paiJPJk.jpg) -[![](http://i.imgur.com/8OLssij.png)](http://i.imgur.com/8OLssij.png) -[![](http://i.imgur.com/JKOc0LZ.png)](http://i.imgur.com/JKOc0LZ.png) +[![](http://i.imgur.com/HwNEXGu.png)](http://i.imgur.com/HwNEXGu.png) +[![](http://i.imgur.com/II1byYs.png)](http://i.imgur.com/II1byYs.png) + + ## How can I follow along/contribute? diff --git a/install/web.js b/install/web.js index 7d2cfad21a..0f4e645e8a 100644 --- a/install/web.js +++ b/install/web.js @@ -1,16 +1,16 @@ "use strict"; -var winston = require('winston'), - express = require('express'), - bodyParser = require('body-parser'), - fs = require('fs'), - path = require('path'), - less = require('less'), - async = require('async'), - uglify = require('uglify-js'), - nconf = require('nconf'), - app = express(), - server; +var winston = require('winston'); +var express = require('express'); +var bodyParser = require('body-parser'); +var fs = require('fs'); +var path = require('path'); +var less = require('less'); +var async = require('async'); +var uglify = require('uglify-js'); +var nconf = require('nconf'); +var app = express(); +var server; winston.add(winston.transports.File, { filename: 'logs/webinstall.log', @@ -22,13 +22,13 @@ winston.add(winston.transports.File, { level: 'verbose' }); -var web = {}, - scripts = [ - 'public/vendor/xregexp/xregexp.js', - 'public/vendor/xregexp/unicode/unicode-base.js', - 'public/src/utils.js', - 'public/src/installer/install.js' - ]; +var web = {}; +var scripts = [ + 'public/vendor/xregexp/xregexp.js', + 'public/vendor/xregexp/unicode/unicode-base.js', + 'public/src/utils.js', + 'public/src/installer/install.js' +]; web.install = function(port) { port = port || 4567; @@ -62,22 +62,23 @@ function setupRoutes() { } function welcome(req, res) { - var dbs = ['redis', 'mongo'], - databases = []; - - dbs.forEach(function(el) { - databases.push({ + var dbs = ['redis', 'mongo']; + var databases = dbs.map(function(el) { + return { name: el, questions: require('../src/database/' + el).questions - }); + }; }); + var defaults = require('./data/defaults'); + res.render('install/index', { databases: databases, skipDatabaseSetup: !!nconf.get('database'), error: res.locals.error ? true : false, success: res.locals.success ? true : false, - values: req.body + values: req.body, + minimumPasswordLength: defaults.minimumPasswordLength }); } @@ -104,7 +105,6 @@ function install(req, res) { } function launch(req, res) { - var pidFilePath = __dirname + '../pidfile'; res.json({}); server.close(); @@ -146,10 +146,10 @@ function compileJS(callback) { return callback(false); } - var scriptPath = path.join(__dirname, '..'), - result = uglify.minify(scripts.map(function(script) { - return path.join(scriptPath, script); - })); + var scriptPath = path.join(__dirname, '..'); + var result = uglify.minify(scripts.map(function(script) { + return path.join(scriptPath, script); + })); fs.writeFile(path.join(__dirname, '../public/nodebb.min.js'), result.code, callback); diff --git a/package.json b/package.json index 2494bfda18..d600e4661c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "nodebb", "license": "GPL-3.0", "description": "NodeBB Forum", - "version": "1.1.1-auto.3", + "version": "1.1.2", "homepage": "http://www.nodebb.org", "repository": { "type": "git", @@ -25,7 +25,7 @@ "connect-flash": "^0.1.1", "connect-mongo": "~1.1.0", "connect-multiparty": "^2.0.0", - "connect-redis": "~3.0.2", + "connect-redis": "~3.1.0", "cookie-parser": "^1.3.3", "cron": "^1.0.5", "csurf": "^1.6.1", @@ -47,17 +47,17 @@ "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", - "nodebb-plugin-composer-default": "4.1.5", + "nodebb-plugin-composer-default": "4.1.8", "nodebb-plugin-dbsearch": "1.0.2", "nodebb-plugin-emoji-extended": "1.1.1", "nodebb-plugin-emoji-one": "1.1.5", "nodebb-plugin-markdown": "6.0.2", "nodebb-plugin-mentions": "1.1.3", "nodebb-plugin-soundpack-default": "0.1.6", - "nodebb-plugin-spam-be-gone": "0.4.9", + "nodebb-plugin-spam-be-gone": "0.4.10", "nodebb-rewards-essentials": "0.0.9", "nodebb-theme-lavender": "3.0.13", - "nodebb-theme-persona": "4.1.19", + "nodebb-theme-persona": "4.1.20", "nodebb-theme-vanilla": "5.1.9", "nodebb-widget-essentials": "2.0.10", "nodemailer": "2.0.0", @@ -67,7 +67,7 @@ "passport-local": "1.0.0", "postcss": "^5.0.13", "prompt": "^1.0.0", - "redis": "~2.4.2", + "redis": "~2.6.2", "request": "^2.44.0", "rimraf": "~2.5.0", "rss": "^1.0.0", @@ -80,7 +80,7 @@ "socketio-wildcard": "~0.3.0", "string": "^3.0.0", "templates.js": "0.3.4", - "toobusy-js": "^0.4.2", + "toobusy-js": "^0.5.1", "uglify-js": "^2.6.0", "underscore": "^1.8.3", "underscore.deep": "^0.5.1", @@ -117,4 +117,4 @@ "url": "https://github.com/barisusakli" } ] -} \ No newline at end of file +} diff --git a/public/language/ar/error.json b/public/language/ar/error.json index 33ff273b6b..4717871d44 100644 --- a/public/language/ar/error.json +++ b/public/language/ar/error.json @@ -20,6 +20,7 @@ "email-taken": "البريد الالكتروني مأخوذ", "email-not-confirmed": "عنوان بريدك الإلكتروني غير مفعل بعد. انقر هنا لتفعيله من فضلك.", "email-not-confirmed-chat": "لا يمكنك الدردشة حتى تقوم بتأكيد بريدك الإلكتروني، الرجاء إضغط هنا لتأكيد بريدك اﻹلكتروني.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "هذا المنتدى يستلزم تفعيل بريدك الإلكتروني، انقر هنا من فضلك لإدخاله.", "email-confirm-failed": "لم نستطع تفعيل بريدك الإلكتروني، المرجو المحاولة لاحقًا.", "confirm-email-already-sent": "لقد تم ارسال بريد التأكيد، الرجاء اﻹنتظار 1% دقائق لإعادة اﻹرسال", diff --git a/public/language/ar/modules.json b/public/language/ar/modules.json index c753143075..ce14cc171b 100644 --- a/public/language/ar/modules.json +++ b/public/language/ar/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "إلغاء", "bootbox.confirm": "تأكيد", diff --git a/public/language/ar/register.json b/public/language/ar/register.json index 3c61bf8b34..c6ccf2231e 100644 --- a/public/language/ar/register.json +++ b/public/language/ar/register.json @@ -1,6 +1,6 @@ { "register": "تسجيل", - "cancel_registration": "Cancel Registration", + "cancel_registration": "إلغاء التسجيل", "help.email": "افتراضيا، سيتم إخفاء بريدك الإلكتروني من العامة.", "help.username_restrictions": "اسم مستخدم فريدة من نوعها بين1% و2% حرفا. يمكن للآخرين ذكرك @ <'span id='your-username> اسم المستخدم .", "help.minimum_password_length": "كلمة المرور يجب أن تكون على الأقل بها 1% أحرف", diff --git a/public/language/ar/topic.json b/public/language/ar/topic.json index 9810d07d64..6ffaaa75d7 100644 --- a/public/language/ar/topic.json +++ b/public/language/ar/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "هذا الموضوع سوف ينقل إلى فئة", "fork_topic_instruction": "إضغط على المشاركات التي تريد تفريعها", "fork_no_pids": "لم تختر أي مشاركة", + "fork_pid_count": "%1 post(s) selected", "fork_success": "تم إنشاء فرع للموضوع بنجاح! إضغط هنا لمعاينة الفرع.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "أدخل عنوان موضوعك هنا...", diff --git a/public/language/ar/user.json b/public/language/ar/user.json index 6d6b236865..0654ea0a71 100644 --- a/public/language/ar/user.json +++ b/public/language/ar/user.json @@ -6,7 +6,7 @@ "postcount": "عدد المشاركات", "email": "البريد الإلكتروني", "confirm_email": "تأكيد عنوان البريد الإلكتروني", - "account_info": "Account Info", + "account_info": "معلومات الحساب", "ban_account": "Ban Account", "ban_account_confirm": "هل تريد حقاً حظر هاذا العضو؟", "unban_account": "Unban Account", diff --git a/public/language/bg/error.json b/public/language/bg/error.json index 076b6fb878..6a3ef24696 100644 --- a/public/language/bg/error.json +++ b/public/language/bg/error.json @@ -20,6 +20,7 @@ "email-taken": "Е-пощата е заета", "email-not-confirmed": "Вашата е-поща все още не е потвърдена. Моля, натиснете тук, за да потвърдите е-пощата си.", "email-not-confirmed-chat": "Няма да можете да пишете в разговори, докато е-пощата Ви не бъде потвърдена. Моля, натиснете тук, за да потвърдите е-пощата си.", + "email-not-confirmed-email-sent": "Вашата е-поща все още не е потвърдена. Моля, проверете входящата си кутия за писмото за потвърждение.", "no-email-to-confirm": "Този форум изисква потвърдена е-поща. Моля, натиснете тук, за да въведете е-поща", "email-confirm-failed": "Не успяхме да потвърдим е-пощата Ви. Моля, опитайте отново по-късно.", "confirm-email-already-sent": "Е-писмото за потвърждение вече е изпратено. Моля, почакайте още %1 минута/и, преди да изпратите ново.", diff --git a/public/language/bg/modules.json b/public/language/bg/modules.json index d87e0f446d..e17f98847b 100644 --- a/public/language/bg/modules.json +++ b/public/language/bg/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Снимка", "composer.upload-picture": "Качване на изображение", "composer.upload-file": "Качване на файл", + "composer.zen_mode": "Режим Дзен", "bootbox.ok": "Добре", "bootbox.cancel": "Отказ", "bootbox.confirm": "Потвърждаване", diff --git a/public/language/bg/topic.json b/public/language/bg/topic.json index 46f4a70313..c7853b18af 100644 --- a/public/language/bg/topic.json +++ b/public/language/bg/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Тази тема ще бъде преместена в категорията", "fork_topic_instruction": "Натиснете публикациите, които искате да отделите", "fork_no_pids": "Няма избрани публикации!", + "fork_pid_count": "Избрани публикации: %1", "fork_success": "Темата е разделена успешно! Натиснете тук, за да преминете към отделената тема.", "delete_posts_instruction": "Натиснете публикациите, които искате да изтриете/изчистите", "composer.title_placeholder": "Въведете заглавието на темата си тук...", diff --git a/public/language/bn/error.json b/public/language/bn/error.json index 9f8be3d140..6a07599afa 100644 --- a/public/language/bn/error.json +++ b/public/language/bn/error.json @@ -20,6 +20,7 @@ "email-taken": "ইমেইল আগেই ব্যবহৃত", "email-not-confirmed": "আপনার ইমেইল এড্রেস নিশ্চিত করা হয় নি, নিশ্চিত করতে এখানে ক্লিক করুন।", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/bn/modules.json b/public/language/bn/modules.json index 567a648df0..67a8aeddd3 100644 --- a/public/language/bn/modules.json +++ b/public/language/bn/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/bn/topic.json b/public/language/bn/topic.json index 51e88fd6e3..030f48311c 100644 --- a/public/language/bn/topic.json +++ b/public/language/bn/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "এই টপিকটি ক্যাটাগরীতে সরানো হবে", "fork_topic_instruction": "যে পোষ্টটি ফর্ক করতে চান সেটি ক্লিক করুন", "fork_no_pids": "কোন পোষ্ট সিলেক্ট করা হয় নি", + "fork_pid_count": "%1 post(s) selected", "fork_success": "টপিক ফর্ক করা হয়েছে। ফর্ক করা টপিকে যেতে এখানে ক্লিক করুন", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "আপনার টপিকের শিরোনাম দিন", diff --git a/public/language/cs/error.json b/public/language/cs/error.json index 086b3b9eca..7162bf5ebd 100644 --- a/public/language/cs/error.json +++ b/public/language/cs/error.json @@ -20,6 +20,7 @@ "email-taken": "Email je již použit", "email-not-confirmed": "Vaše emailová adresa zatím nebyla potvrzena. Kliknutím zde svůj email potvrdíte.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Potvrzovací email již byl odeslán. Vyčkejte %1 minut pokud chcete odeslat další.", diff --git a/public/language/cs/modules.json b/public/language/cs/modules.json index a6d59b761f..d12f123cb1 100644 --- a/public/language/cs/modules.json +++ b/public/language/cs/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Obrázek", "composer.upload-picture": "Nahrát obrázek", "composer.upload-file": "Nahrát soubor", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Zrušit", "bootbox.confirm": "Potvrdit", diff --git a/public/language/cs/topic.json b/public/language/cs/topic.json index b528de0a8c..cc513a5dc4 100644 --- a/public/language/cs/topic.json +++ b/public/language/cs/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Toto téma bude přesunuto do kategorie", "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_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Zadejte název tématu...", diff --git a/public/language/da/error.json b/public/language/da/error.json index 6320e0e990..78e2b469c3 100644 --- a/public/language/da/error.json +++ b/public/language/da/error.json @@ -20,6 +20,7 @@ "email-taken": "Emailadresse allerede i brug", "email-not-confirmed": "Din email adresse er ikke blevet bekræftet endnu, venligst klik her for at bekrætige den.", "email-not-confirmed-chat": "Du kan ikke chatte før din email er bekræftet, klik her for at bekræfte din email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Dette forum kræver bekræftelse af din email, klik her for at indtaste en email", "email-confirm-failed": "Vi kunne ikke bekræfte din email, prøv igen senere.", "confirm-email-already-sent": "Bekræftelses email er allerede afsendt, vent venligt %1 minut(ter) for at sende endnu en.", diff --git a/public/language/da/modules.json b/public/language/da/modules.json index d54ad1ec52..01a3655865 100644 --- a/public/language/da/modules.json +++ b/public/language/da/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Annuller", "bootbox.confirm": "Bekræft", diff --git a/public/language/da/topic.json b/public/language/da/topic.json index 22ca530310..181a58ffb7 100644 --- a/public/language/da/topic.json +++ b/public/language/da/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Denne tråd vil blive flyttet til katagorien", "fork_topic_instruction": "Klik på indlæg du ønsker at fraskille", "fork_no_pids": "Ingen indlæg valgt", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Tråden blev fraskilt! Klik her for at gå til den fraskilte tråd.", "delete_posts_instruction": "Klik på de indlæg du vil slette/rense", "composer.title_placeholder": "Angiv din trådtittel her ...", diff --git a/public/language/de/category.json b/public/language/de/category.json index 6ce06deed2..9169f01756 100644 --- a/public/language/de/category.json +++ b/public/language/de/category.json @@ -2,7 +2,7 @@ "category": "Kategorie", "subcategories": "Unterkategorien", "new_topic_button": "Neues Thema", - "guest-login-post": "Anmelden, um einen Beitrag zu erstellen", + "guest-login-post": "Melde dich an, um einen Beitrag zu erstellen", "no_topics": "Es gibt noch keine Themen in dieser Kategorie.
Warum beginnst du nicht eins?", "browsing": "Aktiv", "no_replies": "Niemand hat geantwortet", diff --git a/public/language/de/error.json b/public/language/de/error.json index 6f7bd0e385..544aead1c3 100644 --- a/public/language/de/error.json +++ b/public/language/de/error.json @@ -20,6 +20,7 @@ "email-taken": "Die E-Mail-Adresse ist bereits vergeben", "email-not-confirmed": "Deine E-Mail wurde noch nicht bestätigt, bitte klicke hier, um deine E-Mail zu bestätigen.", "email-not-confirmed-chat": "Du kannst denn Chat erst nutzen wenn deine E-Mail bestätigt wurde, bitte klicke hier, um deine E-Mail zu bestätigen.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Dieses Forum setzt eine E-Mail-Bestätigung voraus, bitte klicke hier um eine E-Mail-Adresse einzugeben.", "email-confirm-failed": "Wir konnten deine E-Mail-Adresse nicht bestätigen, bitte versuch es später noch einmal", "confirm-email-already-sent": "Die Bestätigungsmail wurde verschickt, bitte warte %1 Minute(n) um eine Weitere zu verschicken.", diff --git a/public/language/de/modules.json b/public/language/de/modules.json index e5f569dbed..688564237f 100644 --- a/public/language/de/modules.json +++ b/public/language/de/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Bild", "composer.upload-picture": "Bild hochladen", "composer.upload-file": "Datei hochladen", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Abbrechen", "bootbox.confirm": "Bestätigen", diff --git a/public/language/de/register.json b/public/language/de/register.json index 41998933f1..9d1b7ca049 100644 --- a/public/language/de/register.json +++ b/public/language/de/register.json @@ -1,6 +1,6 @@ { "register": "Registrieren", - "cancel_registration": "Cancel Registration", + "cancel_registration": "Registrierungsvorgang abbrechen", "help.email": "Deine E-Mail Adresse ist standardmäßig nicht öffentlich sichtbar.", "help.username_restrictions": "Einen einmaligen Benutzernamen. %1-%2 Zeichen. Andere Benutzer können dich mit @Benutzername anschreiben.", "help.minimum_password_length": "Dein Passwort muss mindestens %1 Zeichen lang sein.", @@ -16,8 +16,8 @@ "alternative_registration": "Alternative Registrierung", "terms_of_use": "Nutzungsbedingungen", "agree_to_terms_of_use": "Ich stimme den Nutzungsbedingungen zu", - "terms_of_use_error": "You must agree to the Terms of Use", + "terms_of_use_error": "Du musst den Nutzungsbedingungen zustimmen", "registration-added-to-queue": "Deine Registration wurde abgeschickt. Du wirst eine E-Mail erhalten, sobald sie von einem Administrator akzeptiert wird.", - "interstitial.intro": "We require some additional information before we can create your account.", - "interstitial.errors-found": "We could not complete your registration:" + "interstitial.intro": "Wir benötigen ein wenig mehr Informationen bevor wir deinen Account erstellen können.", + "interstitial.errors-found": "Wir konnten deinen Registrierungsvorgang nicht abschließen:" } \ No newline at end of file diff --git a/public/language/de/topic.json b/public/language/de/topic.json index 7d4cd8fc97..816f417397 100644 --- a/public/language/de/topic.json +++ b/public/language/de/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Dieses Thema wird verschoben nach", "fork_topic_instruction": "Klicke auf die Beiträge, die aufgespaltet werden sollen", "fork_no_pids": "Keine Beiträge ausgewählt!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Thema erfolgreich aufgespalten! Klicke hier, um zum aufgespalteten Thema zu gelangen.", "delete_posts_instruction": "Wähle die zu löschenden Beiträge aus", "composer.title_placeholder": "Hier den Titel des Themas eingeben...", diff --git a/public/language/el/error.json b/public/language/el/error.json index 45f9f6b2fb..b7f9c621ed 100644 --- a/public/language/el/error.json +++ b/public/language/el/error.json @@ -20,6 +20,7 @@ "email-taken": "Το email είναι πιασμένο", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/el/modules.json b/public/language/el/modules.json index af0d74e3cd..2103f5def7 100644 --- a/public/language/el/modules.json +++ b/public/language/el/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/el/topic.json b/public/language/el/topic.json index 7625226e7d..4cb37383e7 100644 --- a/public/language/el/topic.json +++ b/public/language/el/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Το θέμα θα μετακινηθεί στην κατηγορία", "fork_topic_instruction": "Κάνε κλικ στις δημοσιεύσεις που θέλεις να διαχωρίσεις", "fork_no_pids": "Δεν έχουν επιλεχθεί δημοσιεύσεις!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Εισαγωγή του τίτλου του θέματος εδώ...", diff --git a/public/language/en@pirate/error.json b/public/language/en@pirate/error.json index 3a95ab7cc6..6a614b6de4 100644 --- a/public/language/en@pirate/error.json +++ b/public/language/en@pirate/error.json @@ -20,6 +20,7 @@ "email-taken": "Email taken", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/en@pirate/modules.json b/public/language/en@pirate/modules.json index 974cdf1b43..aca98482b4 100644 --- a/public/language/en@pirate/modules.json +++ b/public/language/en@pirate/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/en@pirate/topic.json b/public/language/en@pirate/topic.json index edcc8a8435..238f75eb0e 100644 --- a/public/language/en@pirate/topic.json +++ b/public/language/en@pirate/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "This topic will be moved to the category", "fork_topic_instruction": "Click the posts you want to fork", "fork_no_pids": "No posts selected!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Enter your topic title here...", diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index fa73ccfa8a..319f5005b6 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -67,6 +67,9 @@ "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting", "post-delete-duration-expired-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting", + "cant-delete-topic-has-reply": "You can't delete your topic after it has a reply", + "cant-delete-topic-has-replies": "You can't delete your topic after it has %1 replies", + "content-too-short": "Please enter a longer post. Posts should contain at least %1 character(s).", "content-too-long": "Please enter a shorter post. Posts can't be longer than %1 character(s).", "title-too-short": "Please enter a longer title. Titles should contain at least %1 character(s).", diff --git a/public/language/en_GB/topic.json b/public/language/en_GB/topic.json index 78769c64b5..f177725d56 100644 --- a/public/language/en_GB/topic.json +++ b/public/language/en_GB/topic.json @@ -61,7 +61,7 @@ "ignoring.description": "Do not notify me of new replies.
Do not show topic in unread.", "thread_tools.title": "Topic Tools", - "thread_tools.markAsUnreadForAll": "Mark Unread", + "thread_tools.markAsUnreadForAll": "Mark unread for all", "thread_tools.pin": "Pin Topic", "thread_tools.unpin": "Unpin Topic", "thread_tools.lock": "Lock Topic", diff --git a/public/language/en_US/error.json b/public/language/en_US/error.json index 3a95ab7cc6..6a614b6de4 100644 --- a/public/language/en_US/error.json +++ b/public/language/en_US/error.json @@ -20,6 +20,7 @@ "email-taken": "Email taken", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/en_US/modules.json b/public/language/en_US/modules.json index b3775ab68f..ac0177941a 100644 --- a/public/language/en_US/modules.json +++ b/public/language/en_US/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/en_US/topic.json b/public/language/en_US/topic.json index edcc8a8435..238f75eb0e 100644 --- a/public/language/en_US/topic.json +++ b/public/language/en_US/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "This topic will be moved to the category", "fork_topic_instruction": "Click the posts you want to fork", "fork_no_pids": "No posts selected!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Enter your topic title here...", diff --git a/public/language/es/category.json b/public/language/es/category.json index 4ae8ebc1e6..1997061dea 100644 --- a/public/language/es/category.json +++ b/public/language/es/category.json @@ -2,7 +2,7 @@ "category": "Categoría", "subcategories": "Subcategorías", "new_topic_button": "Nuevo tema", - "guest-login-post": "Accede para poder escribir un mensaje", + "guest-login-post": "Accede para escribir un mensaje", "no_topics": "No hay temas en esta categoría.
¿Por qué no te animas y publicas uno?", "browsing": "viendo ahora", "no_replies": "Nadie ha respondido aún", diff --git a/public/language/es/error.json b/public/language/es/error.json index 723aa9beb6..0df59adbad 100644 --- a/public/language/es/error.json +++ b/public/language/es/error.json @@ -20,6 +20,7 @@ "email-taken": "Correo electrónico ocupado", "email-not-confirmed": "Su cuenta de correo electrónico no ha sido confirmada aún, por favor haga click aquí para confirmarla.", "email-not-confirmed-chat": "No puedes usar el chat hasta que confirmes tu dirección de correo electrónico, por favor haz click aquí para confirmar tu correo.", + "email-not-confirmed-email-sent": "Tu correo electrónico está sin confirmar, por favor busca el correo de confirmación en tu bandeja de entrada.", "no-email-to-confirm": "Este foro requiere confirmación de su email, por favor pulse aquí para introducir un email", "email-confirm-failed": "No se ha podido confirmar su email, por favor inténtelo de nuevo más tarde.", "confirm-email-already-sent": "El email de confirmación ya ha sido enviado, por favor espera %1 minuto(s) para enviar otro.", diff --git a/public/language/es/global.json b/public/language/es/global.json index fbe548dd54..79fd9c1a88 100644 --- a/public/language/es/global.json +++ b/public/language/es/global.json @@ -48,7 +48,7 @@ "online": "Conectado", "users": "Usuarios", "topics": "Temas", - "posts": "Posts", + "posts": "Mensajes", "best": "Mejor valorados", "upvoters": "Positivos", "upvoted": "Votado positivamente", diff --git a/public/language/es/modules.json b/public/language/es/modules.json index 87cc59c2fb..d47569a921 100644 --- a/public/language/es/modules.json +++ b/public/language/es/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Foto", "composer.upload-picture": "Subir foto", "composer.upload-file": "Subir archivo", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancelar", "bootbox.confirm": "Confirmar", diff --git a/public/language/es/topic.json b/public/language/es/topic.json index dd3d6bb709..a1bdf48ff4 100644 --- a/public/language/es/topic.json +++ b/public/language/es/topic.json @@ -80,12 +80,13 @@ "loading_more_posts": "Cargando más publicaciones", "move_topic": "Mover tema", "move_topics": "Mover temas", - "move_post": "Mover publicación", + "move_post": "Mover mensaje", "post_moved": "¡Publicación movida correctamente!", "fork_topic": "Dividir tema", "topic_will_be_moved_to": "Este tema será movido a la categoría", "fork_topic_instruction": "Pulsa en los mensajes que quieres dividir", "fork_no_pids": "¡No has seleccionado ningún mensaje!", + "fork_pid_count": "%1 mensaje(s) seleccionados", "fork_success": "¡Se ha creado un nuevo tema a partir del original! Haz click aquí para ir al nuevo tema.", "delete_posts_instruction": "Haz click en los mensajes que quieres eliminar/limpiar", "composer.title_placeholder": "Ingresa el título de tu tema...", diff --git a/public/language/et/error.json b/public/language/et/error.json index 02713277b5..48024ec16a 100644 --- a/public/language/et/error.json +++ b/public/language/et/error.json @@ -20,6 +20,7 @@ "email-taken": "Email on võetud", "email-not-confirmed": "Su emaili aadress ei ole kinnitatud, vajuta siia et kinnitada.", "email-not-confirmed-chat": "Sõnumeid ei ole võimalik enne saata kui sinu email on kinnitatud. Kinnitamiseks vajuta siia.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "See foorum nõuab emaili kinnitust, palun vajuta siia, et sisestada email", "email-confirm-failed": "Meil ei õnnestunud sinu emaili kinnitada, proovi hiljem uuesti.", "confirm-email-already-sent": "Kinnituskiri on juba saadetud, palun oota %1 minut(it) uue kirja saatmiseks.", diff --git a/public/language/et/modules.json b/public/language/et/modules.json index c4a2434ec1..bb0f15c66a 100644 --- a/public/language/et/modules.json +++ b/public/language/et/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Pilt", "composer.upload-picture": "Lae pilt üles", "composer.upload-file": "Lae fail üles", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Olgu", "bootbox.cancel": "Katkesta", "bootbox.confirm": "Kinnita", diff --git a/public/language/et/topic.json b/public/language/et/topic.json index 622c2b6982..0e236f149d 100644 --- a/public/language/et/topic.json +++ b/public/language/et/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "See teema liigutatakse antud kategooriasse", "fork_topic_instruction": "Vajuta postitustele, mida soovid forkida", "fork_no_pids": "Sa ei ole postitusi valinud!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Edukalt ''forkisid'' teema! Vajuta siia, et vaadata loodud teemat.", "delete_posts_instruction": "Klikka postitustel, mida tahad kustutada/puhastada", "composer.title_placeholder": "Sisesta teema pealkiri siia...", diff --git a/public/language/fa_IR/error.json b/public/language/fa_IR/error.json index d4661f4c8d..965f4a00c2 100644 --- a/public/language/fa_IR/error.json +++ b/public/language/fa_IR/error.json @@ -20,6 +20,7 @@ "email-taken": "این ایمیل گرفته شده است.", "email-not-confirmed": "ایمیل شما تاکنون تایید نشده است، برای تایید ایمیل خود را اینجا را کلیک کنید.", "email-not-confirmed-chat": "شما تا قبل از تایید ایمیل قادر به چت نیستید، لطفا برای تایید ایمیل خود اینجا کلیک کنید", + "email-not-confirmed-email-sent": "ایمیل شما هنوز تایید نشده است، لطفا صندوق پیام های خود را برای تایید ایمیل بررسی کنید.", "no-email-to-confirm": "ایمیل شما تایید نشده است ، لطفا برای وارد کردن ایمیل اینجا کلیک کنید", "email-confirm-failed": "سیستم موفق به تایید ایمیل شما نشد، لطفا بعدا دوباره سعی کنید", "confirm-email-already-sent": "ایمیل فعال‌سازی قبلا فرستاده شده، لطفا %1 دقیقه صبر کنید تا ایمیل دیگری بفرستید.", diff --git a/public/language/fa_IR/modules.json b/public/language/fa_IR/modules.json index 728ffe5153..9b39f7cb7f 100644 --- a/public/language/fa_IR/modules.json +++ b/public/language/fa_IR/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "عکس", "composer.upload-picture": "بارگذاری عکس", "composer.upload-file": "بارگذاری فایل", + "composer.zen_mode": "حالت ذن", "bootbox.ok": "باشه", "bootbox.cancel": "انصراف", "bootbox.confirm": "تایید", diff --git a/public/language/fa_IR/topic.json b/public/language/fa_IR/topic.json index 45fca81ea5..f589a051ef 100644 --- a/public/language/fa_IR/topic.json +++ b/public/language/fa_IR/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "این موضوع جابه‌جا خواهد شد به دستهٔ", "fork_topic_instruction": "پست‌هایی را که می‌خواهید به موضوع تازه ببرید، انتخاب کنید", "fork_no_pids": "هیچ پستی انتخاب نشده!", + "fork_pid_count": "%1 پست (ها) انتخاب شده اند", "fork_success": "موضوع با موفقیت منشعب شد! برای رفتن به موضوع انشعابی اینجا را کلیک کنید.", "delete_posts_instruction": "با کلیک بر روی پست شما می خواهید به حذف/پاکسازی", "composer.title_placeholder": "عنوان موضوعتان را اینجا بنویسید...", diff --git a/public/language/fi/error.json b/public/language/fi/error.json index e728dcfc78..8862df7356 100644 --- a/public/language/fi/error.json +++ b/public/language/fi/error.json @@ -20,6 +20,7 @@ "email-taken": "Sähköpostiosoite varattu", "email-not-confirmed": "Sähköpostiasi ei ole vielä vahvistettu, ole hyvä ja napsauta tätä vahvistaaksesi sen.", "email-not-confirmed-chat": "Et voi keskustella ennen kuin sähköpostiosoitteesi on vahvistettu, ole hyvä ja paina tästä vahvistaaksesi sen.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/fi/modules.json b/public/language/fi/modules.json index 77fff03fd5..bc7af01bb1 100644 --- a/public/language/fi/modules.json +++ b/public/language/fi/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/fi/topic.json b/public/language/fi/topic.json index b2d5e9d127..b17e0664ab 100644 --- a/public/language/fi/topic.json +++ b/public/language/fi/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Tämä keskustelu siirretään aihealueelle", "fork_topic_instruction": "Napsauta viestejä, jotka haluat haaroittaa", "fork_no_pids": "Ei valittuja viestejä!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Syötä aiheesi otsikko tähän...", diff --git a/public/language/fr/error.json b/public/language/fr/error.json index f62e4043ff..0a494e47ab 100644 --- a/public/language/fr/error.json +++ b/public/language/fr/error.json @@ -20,6 +20,7 @@ "email-taken": "Email déjà utilisé", "email-not-confirmed": "Votre adresse email n'est pas confirmée, cliquez ici pour la valider.", "email-not-confirmed-chat": "Il ne vous est pas possible d'utiliser le chat tant que votre adresse email n'a pas été vérifiée. Veuillez cliquer ici pour confirmer votre adresse email.", + "email-not-confirmed-email-sent": "Votre adresse email n'a pas encore été confirmée. Merci de vérifier l'email de confirmation dans votre boîte de reception.", "no-email-to-confirm": "Ce forum requiert une vérification de votre adresse email. Veuillez cliquer ici pour entrer une adresse.", "email-confirm-failed": "Votre adresse email n'a pas pu être vérifiée. Veuillez ré-essayer plus tard.", "confirm-email-already-sent": "L'email de confirmation a déjà été envoyé. Veuillez attendre %1 minute(s) avant de redemander un nouvel envoi.", diff --git a/public/language/fr/login.json b/public/language/fr/login.json index b3c80182b9..72fa0ef401 100644 --- a/public/language/fr/login.json +++ b/public/language/fr/login.json @@ -8,5 +8,5 @@ "failed_login_attempt": "Identification échouée", "login_successful": "Vous êtes maintenant connecté !", "dont_have_account": "Vous n'avez pas de compte ?", - "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity" + "logged-out-due-to-inactivity": "Vous avez été déconnecté du Panneau de Contrôle d'Administration en raison de votre inactivité" } \ No newline at end of file diff --git a/public/language/fr/modules.json b/public/language/fr/modules.json index bc05644724..9a9eaa0675 100644 --- a/public/language/fr/modules.json +++ b/public/language/fr/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Image", "composer.upload-picture": "Envoyer une image", "composer.upload-file": "Envoyer un fichier", + "composer.zen_mode": "Mode Zen", "bootbox.ok": "OK", "bootbox.cancel": "Annuler", "bootbox.confirm": "Confirmer", diff --git a/public/language/fr/topic.json b/public/language/fr/topic.json index dc8bb65354..0a2f7ae7b3 100644 --- a/public/language/fr/topic.json +++ b/public/language/fr/topic.json @@ -26,8 +26,8 @@ "tools": "Outils", "flag": "Signaler", "locked": "Verrouillé", - "pinned": "Pinned", - "moved": "Moved", + "pinned": "Épinglé", + "moved": "Déplacé", "bookmark_instructions": "Cliquez ici pour retourner au dernier message lu de ce fil.", "flag_title": "Signaler ce message à la modération", "flag_success": "Ce message a bien été signalé aux modérateurs.", @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ce sujet sera déplacé vers la catégorie", "fork_topic_instruction": "Cliquez sur les postes à scinder", "fork_no_pids": "Aucun post sélectionné !", + "fork_pid_count": "%1 message(s) sélectionné(s)", "fork_success": "Sujet copié avec succès ! Cliquez ici pour aller au sujet copié.", "delete_posts_instruction": "Sélectionnez les messages que vous souhaitez supprimer/vider", "composer.title_placeholder": "Entrer le titre du sujet ici…", diff --git a/public/language/gl/error.json b/public/language/gl/error.json index 8944015afd..76bdf60486 100644 --- a/public/language/gl/error.json +++ b/public/language/gl/error.json @@ -20,6 +20,7 @@ "email-taken": "Correo en uso", "email-not-confirmed": "O teu correo aínda non está confirmado, por favor pica aquí para confirmalo.", "email-not-confirmed-chat": "Non podes charlar ata que confirmes o teu correo, por favor pica aquí para confirmalo.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Este foro require confirmación de correo, por favor pica aquí para introducir un correo.", "email-confirm-failed": "Non podemos confirmar o teu correo, por favor téntao de novo máis tarde.", "confirm-email-already-sent": "O correo de confirmación foi enviado, agarda %1 minute(s) para enviar outro.", diff --git a/public/language/gl/modules.json b/public/language/gl/modules.json index d097d97686..9bebb20db3 100644 --- a/public/language/gl/modules.json +++ b/public/language/gl/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Foto", "composer.upload-picture": "Subir foto", "composer.upload-file": "Subir arquivo", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "De acordo", "bootbox.cancel": "Cancelar", "bootbox.confirm": "Confirmar", diff --git a/public/language/gl/topic.json b/public/language/gl/topic.json index 96c8da628e..ab5fe853c3 100644 --- a/public/language/gl/topic.json +++ b/public/language/gl/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Este tema será movido á categoría", "fork_topic_instruction": "Fai clic nas publicacións que queiras dividir", "fork_no_pids": "Non seleccionaches ninguna publicación!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Creouse un novo tema a partir do orixinal! Fai clic aquí para ir ó novo tema.", "delete_posts_instruction": "Fai clic nas mensaxes que queres eliminar/limpar", "composer.title_placeholder": "Introduce o título do teu tema", diff --git a/public/language/he/error.json b/public/language/he/error.json index 3696f40550..7b00a4a288 100644 --- a/public/language/he/error.json +++ b/public/language/he/error.json @@ -20,6 +20,7 @@ "email-taken": "כתובת אימייל תפוסה", "email-not-confirmed": "כתובת המייל שלך עוד לא אושרה, לחץ כאן על-מנת לאשר את המייל שלך.", "email-not-confirmed-chat": "אין באפשרותך לשוחח עד שהדוא\"ל שלך יאושר, אנא לחץ כאן כדי לאשר את הדוא\"ל שלך.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "פורום זה דורש אישור בדוא\"ל, אנא לחץ כאן כדי להכניס לדואר אלקטרוני", "email-confirm-failed": "לא הצלחנו לאשר את הדוא\"ל שלך, תנסה שוב אחר כך", "confirm-email-already-sent": "מייל האישור כבר נשלח, אנא המתן %1 דקות כדי לשלוח מייל נוסף.", diff --git a/public/language/he/modules.json b/public/language/he/modules.json index 3664bac5b3..91827e7141 100644 --- a/public/language/he/modules.json +++ b/public/language/he/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "בסדר", "bootbox.cancel": "בטל", "bootbox.confirm": "אשר", diff --git a/public/language/he/topic.json b/public/language/he/topic.json index 8bf3fe2cda..dd0f7ad03f 100644 --- a/public/language/he/topic.json +++ b/public/language/he/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "נושא זה יועבר לקטגוריה", "fork_topic_instruction": "לחץ על הפוסטים שברצונך לשכפל", "fork_no_pids": "לא בחרת אף פוסט!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "הפוסט שוכפל בהצלחה! לחץ כאן על מנת לעבור לפוסט המשוכפל.", "delete_posts_instruction": "לחץ על הפוסטים שברצונך למחוק", "composer.title_placeholder": "הכנס את כותרת הנושא כאן...", diff --git a/public/language/hu/error.json b/public/language/hu/error.json index 19a14975ea..ce999c9ead 100644 --- a/public/language/hu/error.json +++ b/public/language/hu/error.json @@ -20,6 +20,7 @@ "email-taken": "Foglalt e-mail", "email-not-confirmed": "Az e-mail címed még nem lett ellenőrizve, kérlek kattints ide az e-mail címed ellenőrzéséhez!", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Ez a fórum e-mail megerősítést kíván, kérlek kattints ide egy cím beírásához", "email-confirm-failed": "Nem tudtuk ellenőrizni az e-mail címedet, kérlek próbálkozz később.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/hu/modules.json b/public/language/hu/modules.json index e7262c7dff..cd01a6c35f 100644 --- a/public/language/hu/modules.json +++ b/public/language/hu/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/hu/topic.json b/public/language/hu/topic.json index ef9dcb52b3..47c83d78ae 100644 --- a/public/language/hu/topic.json +++ b/public/language/hu/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ez a téma ebbe a kategóriába lesz mozgatva", "fork_topic_instruction": "Klikkelj azokra a hozzászólásokra, amiket szét akarsz szedni", "fork_no_pids": "Nincs hozzászólás kiválasztva!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Írd be a témanevet...", diff --git a/public/language/id/error.json b/public/language/id/error.json index 111505a95d..822698d462 100644 --- a/public/language/id/error.json +++ b/public/language/id/error.json @@ -20,6 +20,7 @@ "email-taken": "Email sudah terdaftar", "email-not-confirmed": "Email kamu belum dikonfirmasi, klik disini untuk mengkonfirmasi email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/id/modules.json b/public/language/id/modules.json index bd2946c9d7..e56070fdd4 100644 --- a/public/language/id/modules.json +++ b/public/language/id/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/id/topic.json b/public/language/id/topic.json index 757bc1b54f..4595b97798 100644 --- a/public/language/id/topic.json +++ b/public/language/id/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Topik ini akan dipindahkan ke kategori", "fork_topic_instruction": "Klik posting yang kamu ingin cabangkan", "fork_no_pids": "Tidak ada posting yang dipilih!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Topik berhasil dicabangkan! Klik disini untuk menuju topik yang telah dicabangkan.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Masukkan judul topik di sini...", diff --git a/public/language/it/error.json b/public/language/it/error.json index 740211d54e..e2ff61bf88 100644 --- a/public/language/it/error.json +++ b/public/language/it/error.json @@ -20,6 +20,7 @@ "email-taken": "Email già esistente", "email-not-confirmed": "La tua Email deve essere ancora confermata, per favore clicca qui per confermare la tua Email.", "email-not-confirmed-chat": "Non potrai chattare finchè non avrai confermato la tua email, per favore clicca qui per farlo ora.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Questo forum richiede la conferma dell'indirizzo email, per favore clicca qui per inserirne uno", "email-confirm-failed": "Non possiamo confermare la tua email, per favore prova ancora più tardi.", "confirm-email-already-sent": "Email di conferma già inviata, per favore attendere %1 minuti per richiederne un'altra.", diff --git a/public/language/it/modules.json b/public/language/it/modules.json index 1d39879d23..d18485ef7d 100644 --- a/public/language/it/modules.json +++ b/public/language/it/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Annulla", "bootbox.confirm": "Conferma", diff --git a/public/language/it/topic.json b/public/language/it/topic.json index ccfdcec340..1834ff19cd 100644 --- a/public/language/it/topic.json +++ b/public/language/it/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Questa discussione verrà spostata nella categoria", "fork_topic_instruction": "Clicca sui post che vuoi dividere", "fork_no_pids": "Nessun post selezionato!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Topic Diviso con successo ! Clicca qui per andare al Topic Diviso.", "delete_posts_instruction": "Clicca sui post che vuoi cancellare/eliminare", "composer.title_placeholder": "Inserisci qui il titolo della discussione...", diff --git a/public/language/ja/error.json b/public/language/ja/error.json index 786ca3988a..ba607d9c09 100644 --- a/public/language/ja/error.json +++ b/public/language/ja/error.json @@ -20,6 +20,7 @@ "email-taken": "メールアドレスは既に使われています", "email-not-confirmed": "あなたのメールアドレスはまだ確認されていません。メールアドレスを確認するためにはここをクリックしてください。", "email-not-confirmed-chat": "チャットを行うにはメールアドレスの確認を行う必要があります。メールアドレスを確認するためにはここをクリックしてください。", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "このフォーラムを利用するにはメールアドレスの確認を行う必要があります。メールアドレスを確認するためにはここをクリックしてください。", "email-confirm-failed": "メールアドレスの確認が出来ませんでした。再度お試しください。", "confirm-email-already-sent": "確認のメールは既に送信されています。再度送信するには、%1分後に再度お試しください。", diff --git a/public/language/ja/modules.json b/public/language/ja/modules.json index bc661721f9..0eb13821d6 100644 --- a/public/language/ja/modules.json +++ b/public/language/ja/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/ja/topic.json b/public/language/ja/topic.json index 4fc666f07a..a6d8c5bbf0 100644 --- a/public/language/ja/topic.json +++ b/public/language/ja/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "スレッドはこちらのカテゴリへ移動", "fork_topic_instruction": "フォークしたいポストをクリックして", "fork_no_pids": "ポストが選択されていません!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "トピックをフォークするのに成功しました。ここを押して、このフォークしたトピックに行きます。", "delete_posts_instruction": "削除または粛清するには、当てはまる投稿を押してください", "composer.title_placeholder": "スレッドのタイトルを入力して...", diff --git a/public/language/ko/error.json b/public/language/ko/error.json index 45b2c548d8..1a0e568eb3 100644 --- a/public/language/ko/error.json +++ b/public/language/ko/error.json @@ -20,6 +20,7 @@ "email-taken": "이미 사용 중인 이메일입니다.", "email-not-confirmed": "아직 이메일이 인증되지 않았습니다. 여기를 누르면 인증 메일을 발송할 수 있습니다.", "email-not-confirmed-chat": "아직 이메일이 인증되지 않았습니다. 대화기능은 인증 후에 사용이 가능합니다.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "이메일 인증이 필요합니다. 이곳을 클릭하여 이메일 입력하세요.", "email-confirm-failed": "이메일 인증이 실패하였습니다. 잠시 후에 다시 시도하세요.", "confirm-email-already-sent": "인증 메일이 이미 발송되었습니다. %1 분 이후에 재 발송이 가능합니다.", diff --git a/public/language/ko/modules.json b/public/language/ko/modules.json index 3d7b19c6a1..1a4cfa7b1c 100644 --- a/public/language/ko/modules.json +++ b/public/language/ko/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "확인", "bootbox.cancel": "취소", "bootbox.confirm": "확인", diff --git a/public/language/ko/topic.json b/public/language/ko/topic.json index 122525bb38..756b2d0824 100644 --- a/public/language/ko/topic.json +++ b/public/language/ko/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "이 주제를 지정한 카테고리로 이동합니다.", "fork_topic_instruction": "분리할 게시물을 선택하세요.", "fork_no_pids": "게시물이 선택되지 않았습니다.", + "fork_pid_count": "%1 post(s) selected", "fork_success": "주제가 분리되었습니다! 분리된 주제를 보려면 여기를 클릭하세요.", "delete_posts_instruction": "삭제할 게시물을 선택하세요.", "composer.title_placeholder": "여기에 제목을 입력하세요.", diff --git a/public/language/lt/error.json b/public/language/lt/error.json index 01c1a1d505..a1c40b2542 100644 --- a/public/language/lt/error.json +++ b/public/language/lt/error.json @@ -20,6 +20,7 @@ "email-taken": "El. pašto adresas jau užimtas", "email-not-confirmed": "Jūsų el. paštas nepatvirtintas, prašome paspausti čia norint jį patvirtinti.", "email-not-confirmed-chat": "Jūs negalite bendrauti, kol jūsų el.paštas nėra patvirtintas, prašome spausti čia kad aktyvuoti jūsų el.paštą", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Šis forumas reikalauja patvirtinimo el. paštu prašome spausti čia el. adreso įrašymui", "email-confirm-failed": "Negalime patvirtinti jūsų el. adreso, prašom bandyti vėliau.", "confirm-email-already-sent": "Patvirtinimo laiškas išsiųstas, prašome palaukti %1 minute(s) kad išsiųstume kita", diff --git a/public/language/lt/modules.json b/public/language/lt/modules.json index a490086245..a339fe7558 100644 --- a/public/language/lt/modules.json +++ b/public/language/lt/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/lt/topic.json b/public/language/lt/topic.json index 4c8e07fc98..1aa37b4730 100644 --- a/public/language/lt/topic.json +++ b/public/language/lt/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ši tema bus perkelta į kategoriją", "fork_topic_instruction": "Pažymėkite ant įrašų, kuriuos norite perkelti į naują temą", "fork_no_pids": "Nepasirinktas joks įrašas!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Sėkmingai išsišakota iš temos! Spausk čia kad nueitu į išsišakota temą", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Įrašykite temos pavadinimą...", diff --git a/public/language/ms/error.json b/public/language/ms/error.json index f90fd5f3b3..d7b0fed05c 100644 --- a/public/language/ms/error.json +++ b/public/language/ms/error.json @@ -20,6 +20,7 @@ "email-taken": "Emel telah digunakan", "email-not-confirmed": "Emel anda belum disahkan lagi, sila klik sini untuk mengesahkan emel anda.", "email-not-confirmed-chat": "Anda tidak dibenarkan sembang sehingga emel disahkan, sila sahkan emel anda.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Forum ini memerlukan pengesahan emel, sila klik sini untuk memasukkan emel", "email-confirm-failed": "Kami tidak dapat memastikan emel anda, sila cuba lagi nanti", "confirm-email-already-sent": "Pengesahan emel telah dihantar, sila tunggu %1 minit() untuk menghantar yang baru.", diff --git a/public/language/ms/modules.json b/public/language/ms/modules.json index 774d674123..15c7f29f9f 100644 --- a/public/language/ms/modules.json +++ b/public/language/ms/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Ok", "bootbox.cancel": "Batal", "bootbox.confirm": "Pasti", diff --git a/public/language/ms/topic.json b/public/language/ms/topic.json index 04b30e193d..c55222b87c 100644 --- a/public/language/ms/topic.json +++ b/public/language/ms/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Topik ini akan dipindahkan kepada kategori", "fork_topic_instruction": "Klik kiriman yang anda hendak salin", "fork_no_pids": "Tiada kiriman yang dipilih", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Berjaya menyalin topik. Klik sini untuk ke topik yang disalin.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Masukkan tajuk topik disini", diff --git a/public/language/nb/error.json b/public/language/nb/error.json index 416c950043..b2df20d45c 100644 --- a/public/language/nb/error.json +++ b/public/language/nb/error.json @@ -20,6 +20,7 @@ "email-taken": "E-post opptatt", "email-not-confirmed": "E-posten din har ikke blitt bekreftet enda, vennligst klikk for å bekrefte din e-post.", "email-not-confirmed-chat": "Du kan ikke chatte før e-posten din er bekreftet, vennligst klikk her for å bekrefte e-postadressen.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Dette forumet krever e-postbekreftelse, vennligst klikk her for å skrive inn en e-post", "email-confirm-failed": "Vi kunne ikke bekrefte e-posten din, vennligst prøv igjen senere.", "confirm-email-already-sent": "E-post for bekreftelse er allerede sendt, vennligst vent %1 minutt(er) for å sende en til.", diff --git a/public/language/nb/modules.json b/public/language/nb/modules.json index 6b3309287d..999358e96c 100644 --- a/public/language/nb/modules.json +++ b/public/language/nb/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Avbryt", "bootbox.confirm": "Bekreft", diff --git a/public/language/nb/topic.json b/public/language/nb/topic.json index fe18a3d9f9..98049be51f 100644 --- a/public/language/nb/topic.json +++ b/public/language/nb/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Dette emnet vil bli flyttet til kategorien", "fork_topic_instruction": "Trykk på innleggene du vil forgrene", "fork_no_pids": "Ingen innlegg valgt!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Dette emnet ble forgrenet! Klikk for å gå til forgrenet emne.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Skriv din tråd-tittel her", diff --git a/public/language/nl/error.json b/public/language/nl/error.json index e66ba5134d..c22b6ec22c 100644 --- a/public/language/nl/error.json +++ b/public/language/nl/error.json @@ -20,6 +20,7 @@ "email-taken": "E-mailadres is al in gebruik", "email-not-confirmed": "Het e-mailadres van dit account is nog niet bevestigd, klik hier om je e-mailadres te bevestigen.", "email-not-confirmed-chat": "Het gebruik van chatfunctionaliteit is pas toegestaan na validatie van het e-mailadres.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Dit berichtenforum vereist bevestiging per e-mail, klik hier om een e-mailadres te registreren", "email-confirm-failed": "Helaas kon het e-mailadres niet bevestigd worden, probeer het later nog eens.", "confirm-email-already-sent": "Bevestigingsmail is zojuist al verzonden, wacht alsjeblieft %1 minuut (minuten) voordat je opnieuw een bevestigingsmail aanvraagt.", diff --git a/public/language/nl/login.json b/public/language/nl/login.json index 9704cc7ce7..e6d21e1fa6 100644 --- a/public/language/nl/login.json +++ b/public/language/nl/login.json @@ -8,5 +8,5 @@ "failed_login_attempt": "Aanmelden mislukt", "login_successful": "Je bent succesvol ingelogd!", "dont_have_account": "Geen gebruikersaccount?", - "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity" + "logged-out-due-to-inactivity": "Je bent uitgelogt van het admin control panel vanwege inactiviteit." } \ No newline at end of file diff --git a/public/language/nl/modules.json b/public/language/nl/modules.json index 9210bfd177..5d27c1549f 100644 --- a/public/language/nl/modules.json +++ b/public/language/nl/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Afbeelding", "composer.upload-picture": "Upload afbeelding", "composer.upload-file": "Upload bestand", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Annuleren", "bootbox.confirm": "Bevestig", diff --git a/public/language/nl/topic.json b/public/language/nl/topic.json index d938fb6c50..8a7a93ba7e 100644 --- a/public/language/nl/topic.json +++ b/public/language/nl/topic.json @@ -27,7 +27,7 @@ "flag": "Markeren", "locked": "Gesloten", "pinned": "Pinned", - "moved": "Moved", + "moved": "Verplaatst", "bookmark_instructions": "Klik hier om terug te keren naar de laatst gelezen post in deze thread.", "flag_title": "Bericht aan beheerders melden", "flag_success": "Dit bericht is gerapporteerd aan de beheerder.", @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Dit onderwerp zal naar de categorie verplaatst worden", "fork_topic_instruction": "Klik op de berichten die afgesplitst moeten worden", "fork_no_pids": "Geen berichten geselecteerd!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Onderwerp is succesvol afgesplitst. Klik hier om het nieuwe onderwerp te zien.", "delete_posts_instruction": "Klik op de berichten die verwijderd moeten worden", "composer.title_placeholder": "Voer hier de titel van het onderwerp in...", diff --git a/public/language/pl/category.json b/public/language/pl/category.json index e4053aa931..bbbdeee94c 100644 --- a/public/language/pl/category.json +++ b/public/language/pl/category.json @@ -10,10 +10,10 @@ "share_this_category": "Udostępnij tę kategorię", "watch": "Obserwuj", "ignore": "Ignoruj", - "watching": "Watching", - "ignoring": "Ignoring", - "watching.description": "Show topics in unread", - "ignoring.description": "Do not show topics in unread", + "watching": "Obserwowanie", + "ignoring": "Ignorowanie", + "watching.description": "Pokaż tematy jako nieprzeczytane", + "ignoring.description": "Nie pokazuj tematów jako nieprzeczytane", "watch.message": "Obserwujesz teraz uaktualnienia z tej kategorii", "ignore.message": "Ignorujesz teraz uaktualnienia z tej kategorii", "watched-categories": "Obserwowane kategorie" diff --git a/public/language/pl/error.json b/public/language/pl/error.json index 627f7e061b..0a887ccf89 100644 --- a/public/language/pl/error.json +++ b/public/language/pl/error.json @@ -20,6 +20,7 @@ "email-taken": "Email zajęty", "email-not-confirmed": "Twój email nie został jeszcze potwierdzony. Proszę kliknąć tutaj by go potwierdzić.", "email-not-confirmed-chat": "Nie możesz prowadzić rozmów dopóki twój email nie zostanie potwierdzony, kliknij tutaj, aby potwierdzić swój email.", + "email-not-confirmed-email-sent": "Twój e-mail jeszcze nie został potwierdzony, proszę sprawdź swoją skrzynkę odbiorczą.", "no-email-to-confirm": "To forum wymaga weryfikacji przez email. Proszę kliknąć tutaj, aby wprowadzić adres.", "email-confirm-failed": "Nie byliśmy w stanie potwierdzić twojego email-a. Proszę spróbować później.", "confirm-email-already-sent": "Email potwierdzający został już wysłany, proszę odczekaj jeszcze %1 minut(y), aby wysłać kolejny.", @@ -30,7 +31,7 @@ "user-banned": "Użytkownik zbanowany", "user-too-new": "Przepraszamy, musisz odczekać %1 sekund(y) przed utworzeniem pierwszego posta", "blacklisted-ip": "Twój adres IP został zablokowany na tej społeczności. Jeśli uważasz to za błąd, zgłoś to administratorowi", - "ban-expiry-missing": "Please provide an end date for this ban", + "ban-expiry-missing": "Wprowadź datę końca blokady", "no-category": "Kategoria nie istnieje", "no-topic": "Temat nie istnieje", "no-post": "Post nie istnieje", @@ -47,13 +48,13 @@ "post-edit-duration-expired-hours-minutes": "Możesz edytować posty tylko przez %1 godzin(y) i %2 minut(y) po ich napisaniu", "post-edit-duration-expired-days": "Możesz edytować posty tylko przez %1 dzień (dni) po ich napisaniu", "post-edit-duration-expired-days-hours": "Możesz edytować posty tylko przez %1 dzień (dni) i %2 godzin(y) po ich napisaniu", - "post-delete-duration-expired": "You are only allowed to delete posts for %1 second(s) after posting", - "post-delete-duration-expired-minutes": "You are only allowed to delete posts for %1 minute(s) after posting", - "post-delete-duration-expired-minutes-seconds": "You are only allowed to delete posts for %1 minute(s) %2 second(s) after posting", - "post-delete-duration-expired-hours": "You are only allowed to delete posts for %1 hour(s) after posting", - "post-delete-duration-expired-hours-minutes": "You are only allowed to delete posts for %1 hour(s) %2 minute(s) after posting", - "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting", - "post-delete-duration-expired-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting", + "post-delete-duration-expired": "Możesz kasować posty przez %1 sekund(-y) po napisaniu", + "post-delete-duration-expired-minutes": "Możesz kasować posty przez %1 minut(-y) po napisaniu", + "post-delete-duration-expired-minutes-seconds": "Możesz kasować posty przez %1 minut(-y) i %2 sekund(-y) po napisaniu", + "post-delete-duration-expired-hours": "Możesz kasować posty przez %1 godzin(-y) po napisaniu", + "post-delete-duration-expired-hours-minutes": "Możesz kasować posty przez %1 godzin(-y) i %2 minut(-y) po napisaniu", + "post-delete-duration-expired-days": "Możesz kasować posty przez %1 dni po napisaniu", + "post-delete-duration-expired-days-hours": "Możesz kasować posty przez %1 dni i %2 godzin(-y) po napisaniu", "content-too-short": "Prosimy wpisać dłuższy post. Posty powinny zawierać co najmniej %1 znaków.", "content-too-long": "Prosimy wpisać krótszy post. Posty nie mogą zawierać więcej niż %1 znaków.", "title-too-short": "Prosimy podać dłuższy tytuł. Tytuły powinny zawierać co najmniej %1 znaków.", @@ -76,7 +77,7 @@ "invalid-image-extension": "Błędne rozszerzenie pliku", "invalid-file-type": "Błędny typ pliku. Dozwolone typy to: %1", "group-name-too-short": "Nazwa grupy za krótka", - "group-name-too-long": "Group name too long", + "group-name-too-long": "Nazwa grupy jest za długa", "group-already-exists": "Grupa już istnieje", "group-name-change-not-allowed": "Nie można zmieniać nazwy tej grupy.", "group-already-member": "Już jesteś członkiem tej grupy", @@ -119,6 +120,6 @@ "not-in-room": "Użytkownik nie jest w pokoju", "no-users-in-room": "Brak użytkowników w pokoju", "cant-kick-self": "Nie możesz wyrzucić samego siebie z grupy", - "no-users-selected": "No user(s) selected", + "no-users-selected": "Nie wybrano żadnych użytkowników", "invalid-home-page-route": "Invalid home page route" } \ No newline at end of file diff --git a/public/language/pl/global.json b/public/language/pl/global.json index bd9821c5b0..946993295c 100644 --- a/public/language/pl/global.json +++ b/public/language/pl/global.json @@ -50,10 +50,10 @@ "topics": "Tematy", "posts": "Posty", "best": "Najlepsze", - "upvoters": "Upvoters", - "upvoted": "Upvoted", - "downvoters": "Downvoters", - "downvoted": "Downvoted", + "upvoters": "Głosujący za", + "upvoted": "Oddane głosy za", + "downvoters": "Głosujący przeciw", + "downvoted": "Oddane głosy przeciw", "views": "wyświetleń", "reputation": "Punkty reputacji", "read_more": "czytaj więcej", diff --git a/public/language/pl/login.json b/public/language/pl/login.json index 2421563634..1bcd2c3cd5 100644 --- a/public/language/pl/login.json +++ b/public/language/pl/login.json @@ -8,5 +8,5 @@ "failed_login_attempt": "Nie udało się zalogować. Spróbuj ponownie.", "login_successful": "Zostałeś pomyślnie zalogowany.", "dont_have_account": "Nie masz konta?", - "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity" + "logged-out-due-to-inactivity": "Zostałeś wylogowany z Panelu Administratora z powodu braku aktywności." } \ No newline at end of file diff --git a/public/language/pl/modules.json b/public/language/pl/modules.json index 1a9902604b..5461f81b39 100644 --- a/public/language/pl/modules.json +++ b/public/language/pl/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Obraz", "composer.upload-picture": "Wyślij obraz", "composer.upload-file": "Wyślij plik", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Anuluj", "bootbox.confirm": "Potwierdź", diff --git a/public/language/pl/pages.json b/public/language/pl/pages.json index 9e11cb4c57..d748c3919b 100644 --- a/public/language/pl/pages.json +++ b/public/language/pl/pages.json @@ -12,7 +12,7 @@ "users/sort-posts": "Użytkownicy z największą liczbą postów", "users/sort-reputation": "Użytkownicy z najwyższą reputacją", "users/banned": "Banned Users", - "users/most-flags": "Most flagged users", + "users/most-flags": "Najczęściej oznaczani użytkownicy", "users/search": "Wyszukiwanie Użytkownków", "notifications": "Powiadomienia", "tags": "Tagi", @@ -29,7 +29,7 @@ "account/edit/password": "Editing password of \"%1\"", "account/edit/username": "Editing username of \"%1\"", "account/edit/email": "Editing email of \"%1\"", - "account/info": "Account Info", + "account/info": "Informacje o koncie", "account/following": "Obserwowani przez %1", "account/followers": "Obserwujący %1", "account/posts": "Posty napisane przez %1", diff --git a/public/language/pl/register.json b/public/language/pl/register.json index fee052540f..49c89fb6ac 100644 --- a/public/language/pl/register.json +++ b/public/language/pl/register.json @@ -1,6 +1,6 @@ { "register": "Rejestracja", - "cancel_registration": "Cancel Registration", + "cancel_registration": "Anuluj rejestrację", "help.email": "Domyślnie twój adres e-mail będzie ukryty.", "help.username_restrictions": "Unikalna nazwa użytkownika z min. %1 i maks. %2 znaków. Inni użytkownicy mogą ciebie zawołać pisząc @nazwa użytkownika.", "help.minimum_password_length": "Hasło musi mieć co najmniej %1 znaków.", @@ -16,8 +16,8 @@ "alternative_registration": "Alternatywna rejestracja", "terms_of_use": "Warunki korzystania z serwisu", "agree_to_terms_of_use": "Zgadzam się na powyższe warunki", - "terms_of_use_error": "You must agree to the Terms of Use", + "terms_of_use_error": "Musisz zaakceptować Terms of Use", "registration-added-to-queue": "Twoja rejestracja została dodana do kolejki oczekujących na akceptację. Otrzymasz email, kiedy zostanie zatwierdzona przez administratora.", - "interstitial.intro": "We require some additional information before we can create your account.", - "interstitial.errors-found": "We could not complete your registration:" + "interstitial.intro": "Potrzebujemy dodatkowych informacji zanim przejdziemy dalej do utworzenia Twojego konta.", + "interstitial.errors-found": "Nie mogliśmy ukończyć procesu rejestracji:" } \ No newline at end of file diff --git a/public/language/pl/topic.json b/public/language/pl/topic.json index 2c5cd28d2a..c74aa085be 100644 --- a/public/language/pl/topic.json +++ b/public/language/pl/topic.json @@ -26,14 +26,14 @@ "tools": "Narzędzia", "flag": "Zgłoś", "locked": "Zablokowany", - "pinned": "Pinned", - "moved": "Moved", + "pinned": "Przypięte", + "moved": "Przeniesione", "bookmark_instructions": "Click here to return to the last read post in this thread.", "flag_title": "Zgłoś post do moderacji", "flag_success": "Ten post został oznaczony do moderacji.", "deleted_message": "Ten temat został skasowany. Tylko użytkownicy z uprawnieniami do zarządzania mogą go zobaczyć.", "following_topic.message": "Będziesz od teraz otrzymywał powiadomienia, gdy ktoś odpowie w tym temacie.", - "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.", + "not_following_topic.message": "Zobaczysz ten temat na liście nieprzeczytanych, ale nie otrzymasz żadnego powiadomienia dotyczącego tego tematu.", "ignoring_topic.message": "Nie zobaczysz już tego tematu na liście nieprzeczytanych. Otrzymasz powiadomienie, kiedy zostaniesz wspomniany lub ktoś odda głos na twój post.", "login_to_subscribe": "Zaloguj się, aby subskrybować ten temat.", "markAsUnreadForAll.success": "Temat oznaczony jako nieprzeczytany dla wszystkich.", @@ -60,7 +60,7 @@ "thread_tools.move_all": "Przenieś wszystko", "thread_tools.fork": "Skopiuj Temat", "thread_tools.delete": "Usuń Temat", - "thread_tools.delete-posts": "Delete Posts", + "thread_tools.delete-posts": "Usuń posty", "thread_tools.delete_confirm": "Na pewno chcesz skasować ten temat?", "thread_tools.restore": "Przywróć Temat", "thread_tools.restore_confirm": "Na pewno chcesz przywrócić ten temat?", @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ten temat zostanie przeniesiony do kategorii", "fork_topic_instruction": "Zaznacz posty, które chcesz sklonować", "fork_no_pids": "Nie zaznaczyłeś żadnych postów!", + "fork_pid_count": "wybrano %1 post(-ów)", "fork_success": "Udało się skopiować temat. Kliknij tutaj, aby do niego przejść.", "delete_posts_instruction": "Kliknij na posty, które chcesz usunąć", "composer.title_placeholder": "Wpisz tutaj tytuł tematu...", @@ -117,5 +118,5 @@ "link_back": "Re: [%1](%2)", "spam": "Spam", "offensive": "Obrażliwy", - "custom-flag-reason": "Enter a flagging reason" + "custom-flag-reason": "Wprowadź powód oznaczenia" } \ No newline at end of file diff --git a/public/language/pl/user.json b/public/language/pl/user.json index 807f9b6bd4..5bc57dafba 100644 --- a/public/language/pl/user.json +++ b/public/language/pl/user.json @@ -6,7 +6,7 @@ "postcount": "Liczba postów", "email": "Adres e-mail", "confirm_email": "Potwierdź e-mail", - "account_info": "Account Info", + "account_info": "Informacje o koncie", "ban_account": "Zbanuj Konto", "ban_account_confirm": "Na pewno chcesz zbanować tego użytkownika?", "unban_account": "Odbanuj Konto", @@ -96,8 +96,8 @@ "delay_image_loading": "Opóźnienie ładowania zdjęcia", "image_load_delay_help": "Jeśli włączone, zdjęcia w temacie nie załadują się dopóki nie najedzie się", "scroll_to_my_post": "Po napisaniu odpowiedzi, wyświetl najnowsze posty", - "follow_topics_you_reply_to": "Watch topics that you reply to", - "follow_topics_you_create": "Watch topics you create", + "follow_topics_you_reply_to": "Obserwuj tematy w których uczestniczysz", + "follow_topics_you_create": "Obserwuj tematy które utworzyłeś", "grouptitle": "Tytuł grupy", "no-group-title": "Brak tytułu grupy", "select-skin": "Wybierz Skórkę", diff --git a/public/language/pt_BR/error.json b/public/language/pt_BR/error.json index eeca061a70..64286e8352 100644 --- a/public/language/pt_BR/error.json +++ b/public/language/pt_BR/error.json @@ -20,6 +20,7 @@ "email-taken": "Email já cadastrado", "email-not-confirmed": "O seu email ainda não foi confirmado, por favor clique aqui para confirmar seu email.", "email-not-confirmed-chat": "Você não está habilitado a conversar até que seu email seja confirmado, por favor clique aqui para confirmar seu email.", + "email-not-confirmed-email-sent": "O seu email ainda não foi confirmado, por favor confira a sua caixa de entrada pelo email de confirmação.", "no-email-to-confirm": "Este fórum exige confirmação de email, por gentileza clique aqui para digitar um email", "email-confirm-failed": "Nós não pudemos confirmar seu email, por gentileza tente novamente mais tarde.", "confirm-email-already-sent": "O email de confirmação já foi enviado, por favor aguarde %1 minuto(s) para enviar outro.", diff --git a/public/language/pt_BR/modules.json b/public/language/pt_BR/modules.json index 20d1fe1805..d02547efe4 100644 --- a/public/language/pt_BR/modules.json +++ b/public/language/pt_BR/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Imagem", "composer.upload-picture": "Fazer upload de Imagem", "composer.upload-file": "Fazer upload de Arquivo", + "composer.zen_mode": "Modo Zen", "bootbox.ok": "OK", "bootbox.cancel": "Cancelar", "bootbox.confirm": "Confirmar", diff --git a/public/language/pt_BR/topic.json b/public/language/pt_BR/topic.json index 760fe42a3f..194f00c316 100644 --- a/public/language/pt_BR/topic.json +++ b/public/language/pt_BR/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Este tópico será movido para a categoria", "fork_topic_instruction": "Clique nos posts que você quer ramificar", "fork_no_pids": "Nenhum post selecionado!", + "fork_pid_count": "%1 post(s) selecionado(s)", "fork_success": "Tópico ramificado com sucesso! Clique aqui para ir ao tópico ramificado.", "delete_posts_instruction": "Clique nos posts que você deseja deletar/limpar", "composer.title_placeholder": "Digite aqui o título para o seu tópico...", diff --git a/public/language/ro/error.json b/public/language/ro/error.json index 0dabe24cbf..fdb92e303b 100644 --- a/public/language/ro/error.json +++ b/public/language/ro/error.json @@ -20,6 +20,7 @@ "email-taken": "Adresa de email este deja folostă", "email-not-confirmed": "Adresa ta de email nu a fost inca confirmata, click aici ca sa o confirmi.", "email-not-confirmed-chat": "Nu vei putea trimite mesaje daca email-ul tau nu e confirmat, click aici sa il confirmi.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Ca sa accesezi forumul trebuie sa iti confirmi email-ul, click aici ca sa intri in mail.", "email-confirm-failed": "Mail-ul tau nu a putut fi confirmat, te rog incearca mai tarziu.", "confirm-email-already-sent": "Email-ul de confirmare ti-a fost trimis, asteapta te rog %1 minut(e) ca sa trimiti inca unul.", diff --git a/public/language/ro/modules.json b/public/language/ro/modules.json index fa79140b83..1c25e2a5ba 100644 --- a/public/language/ro/modules.json +++ b/public/language/ro/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/ro/topic.json b/public/language/ro/topic.json index 0daf15f7ec..0a9b94434b 100644 --- a/public/language/ro/topic.json +++ b/public/language/ro/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Acest subiect va fi mutat în categoria", "fork_topic_instruction": "Apasă pe mesajele care vrei sa le bifurci", "fork_no_pids": "Nu a fost selectat nici un mesaj!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Introdu numele subiectului aici ...", diff --git a/public/language/ru/error.json b/public/language/ru/error.json index 80f601eb1e..a0e7ea3108 100644 --- a/public/language/ru/error.json +++ b/public/language/ru/error.json @@ -20,6 +20,7 @@ "email-taken": "Email занят", "email-not-confirmed": "Ваш email не подтвержден, нажмите для подтверждения.", "email-not-confirmed-chat": "Вы не можете оставлять сообщения, пока Ваш email не подтверждён. Нажмите на это сообщение чтобы получить письмо повторно.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Этот форум требует подтверждения по E-mail. Нажмите здесь для ввода E-mail.", "email-confirm-failed": "Мы не можем подтвердить Ваш E-mail, попробуйте позже.", "confirm-email-already-sent": "Сообщение для подтверждения уже выслано на E-mail. Повторная отправка возможна через %1 мин.", diff --git a/public/language/ru/modules.json b/public/language/ru/modules.json index a4dfd79293..17151cbc94 100644 --- a/public/language/ru/modules.json +++ b/public/language/ru/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Изображение", "composer.upload-picture": "Загрузить изображение", "composer.upload-file": "Загрузить файл", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "ОК", "bootbox.cancel": "Отмена", "bootbox.confirm": "Подтвердить", diff --git a/public/language/ru/topic.json b/public/language/ru/topic.json index 9ccfff5668..0912a92c32 100644 --- a/public/language/ru/topic.json +++ b/public/language/ru/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Эта тема будет перенесена в категорию", "fork_topic_instruction": "Отметьте сообщения для ответвления", "fork_no_pids": "Сообщения не отмечены!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Готово! Нажмите для перехода в отделённую тему.", "delete_posts_instruction": "Отметьте сообщения, которые Вы хотите удалить/очистить", "composer.title_placeholder": "Введите название темы...", diff --git a/public/language/rw/error.json b/public/language/rw/error.json index abe75583d8..07e0a50743 100644 --- a/public/language/rw/error.json +++ b/public/language/rw/error.json @@ -20,6 +20,7 @@ "email-taken": "Email yarafashwe mbere", "email-not-confirmed": "Email yawe ntabwo iremezwa. Kanda hano kugirango wemeze email yawe.", "email-not-confirmed-chat": "Ntabwo uremererwa kuganirira mu gikari kuko email yawe itari yemezwa. Kanda hano kugirango wemeze email yawe. ", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Uru rubuga rusaba ko wemeza ko utunze email. Kanda hano kugirango utange email yawe", "email-confirm-failed": "Ntabwo email yawe yabashije kwemezwa. Ongera ugerageze mu bundi buryo. ", "confirm-email-already-sent": "Email yo kwemeza yamaze koherezwa. Tegereza iminota (umunota) %1 mbere yo kohereza indi. ", diff --git a/public/language/rw/modules.json b/public/language/rw/modules.json index 15d1ea25eb..2ce5ceac86 100644 --- a/public/language/rw/modules.json +++ b/public/language/rw/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Sawa", "bootbox.cancel": "Isubire", "bootbox.confirm": "Emeza", diff --git a/public/language/rw/topic.json b/public/language/rw/topic.json index bd05fdfc3a..09f54f891f 100644 --- a/public/language/rw/topic.json +++ b/public/language/rw/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Iki kiganiro kirimurirwa mu cyiciro", "fork_topic_instruction": "Kanda ku byashizweho ushaka kugabanyaho", "fork_no_pids": "Nta kintu wahisemo!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Umaze kugabanyaho ku kiganiro! Kanda hano ugezwe ku kiganiro cyavutse. ", "delete_posts_instruction": "Kanda ku bintu ushaka guhisha/gusiba", "composer.title_placeholder": "Shyira umutwe w'ikiganiro cyawe aha...", diff --git a/public/language/sc/error.json b/public/language/sc/error.json index 3a95ab7cc6..6a614b6de4 100644 --- a/public/language/sc/error.json +++ b/public/language/sc/error.json @@ -20,6 +20,7 @@ "email-taken": "Email taken", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/sc/modules.json b/public/language/sc/modules.json index 93c5b11202..9727532086 100644 --- a/public/language/sc/modules.json +++ b/public/language/sc/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/sc/topic.json b/public/language/sc/topic.json index 97fb268bc0..1cc32bab64 100644 --- a/public/language/sc/topic.json +++ b/public/language/sc/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Custa arresonada at a èssere mòvida in sa creze", "fork_topic_instruction": "Sèbera is arresonos chi boles partzire", "fork_no_pids": "Perunu arresonu seberadu!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Pone su tìtulu de s'arresonada inoghe...", diff --git a/public/language/sk/error.json b/public/language/sk/error.json index 8d286eaa7c..d5116a21d9 100644 --- a/public/language/sk/error.json +++ b/public/language/sk/error.json @@ -20,6 +20,7 @@ "email-taken": "Email je obsadený", "email-not-confirmed": "Your email has not been confirmed yet, please click here to confirm your email.", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "This forum requires email confirmation, please click here to enter an email", "email-confirm-failed": "We could not confirm your email, please try again later.", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/sk/modules.json b/public/language/sk/modules.json index 0268001e7f..b7450e202c 100644 --- a/public/language/sk/modules.json +++ b/public/language/sk/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/sk/topic.json b/public/language/sk/topic.json index 78c8473ae0..95eade8db2 100644 --- a/public/language/sk/topic.json +++ b/public/language/sk/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Táto téma bude presunutá do kategórie", "fork_topic_instruction": "Vyber príspevky, ktoré chceš oddeliť", "fork_no_pids": "Žiadne príspevky neboli vybrané!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Vlož nadpis témy sem...", diff --git a/public/language/sl/category.json b/public/language/sl/category.json index f2c156394d..63495a5f90 100644 --- a/public/language/sl/category.json +++ b/public/language/sl/category.json @@ -1,6 +1,6 @@ { "category": "Kategorija", - "subcategories": "Podkategorija", + "subcategories": "Podkategorije", "new_topic_button": "Nova tema", "guest-login-post": "Za objavljanje moraš biti prijavljen", "no_topics": "V tej kategoriji ni tem.
Boš odprl novo temo?", @@ -10,11 +10,11 @@ "share_this_category": "Deli to kategorijo", "watch": "Spremljaj", "ignore": "Ne spremljaj", - "watching": "Watching", - "ignoring": "Ignoring", - "watching.description": "Show topics in unread", - "ignoring.description": "Do not show topics in unread", + "watching": "Spremljanje", + "ignoring": "Prezri", + "watching.description": "Pokaži teme v neprebrano", + "ignoring.description": "Ne pokaži teme v neprebrano", "watch.message": "Trenutno spremljaš nove objave v tej kategoriji", "ignore.message": "Ne spremljaš novih objav v tej kategoriji", - "watched-categories": "Watched categories" + "watched-categories": "Spremljane kategorije" } \ No newline at end of file diff --git a/public/language/sl/email.json b/public/language/sl/email.json index b214e979b6..dcc9b48946 100644 --- a/public/language/sl/email.json +++ b/public/language/sl/email.json @@ -1,36 +1,36 @@ { - "password-reset-requested": "Zahtevana ponastavitev gesla - %1!", + "password-reset-requested": "Zahtevana je ponastavitev gesla - %1!", "welcome-to": "Pozdravljeni na %1", "invite": "Povabilo od %1", "greeting_no_name": "Živjo", "greeting_with_name": "Živjo %1", "welcome.text1": "Hvala, ker ste se registrirali na %1!", - "welcome.text2": "Za popolno aktivacijo vašega računa morate potrditi elektronski naslov s katerim ste se registrirali.", - "welcome.text3": "Administrator je odobril prošnjo za registracijo. Sedaj se lahko registrirate z vašim uporabniškim imenom in geslom.", - "welcome.cta": "Kliknite za potrditev vašega elektronskega naslova", + "welcome.text2": "Za popolno aktivacijo vašega računa morate potrditi e-poštni naslov s katerim ste se registrirali.", + "welcome.text3": "Srbnik je odobril prošnjo za registracijo. Sedaj se lahko registrirate z vašim uporabniškim imenom in geslom.", + "welcome.cta": "Kliknite za potrditev vašega e-poštnega naslova", "invitation.text1": "%1 te je povabil, da se pridružiš %2", - "invitation.ctr": "Klikni tu za kreiranje vašega računa.", + "invitation.ctr": "Klikni tu in ustvari svoj račun.", "reset.text1": "Dobili smo zahtevo za ponastavitev vašega gesla. Če niste zahtevali ponastavitve gesla, prosimo prezrite to sporočilo.", "reset.text2": "Za nadaljevanje ponastavitve gesla prosimo kliknite na sledečo povezavo:", "reset.cta": "Kliknite tu za ponastavitev gesla", "reset.notify.subject": "Geslo uspešno spremenjeno", "reset.notify.text1": "Obveščamo vas, da je bilo na %1 uspešno spremenjeno vaše geslo.", - "reset.notify.text2": "Če niste dali te zahteve, prosimo nemudoma kontaktirajte administratorja.", + "reset.notify.text2": "Če niste dali te zahteve, prosimo nemudoma obvestite skrbnika.", "digest.notifications": "Imate eno neprebrano obvestilo na %1:", "digest.latest_topics": "Zadnja tema na %1", "digest.cta": "Kliknite tu za obisk %1", - "digest.unsub.info": "Ta izvleček je bil poslan zaradi vaših nastavitev obvestil.", - "digest.no_topics": "V preteklosti ni bilo aktivnih tem na %1", - "digest.day": "day", - "digest.week": "week", - "digest.month": "month", - "digest.subject": "Digest for %1", - "notif.chat.subject": "Novo sporočilo prejeto na %1", + "digest.unsub.info": "Ta izvleček vam je bil poslan zaradi vaših nastavitev naročnine.", + "digest.no_topics": "%1, ki je pretekel ni imel aktivnih tem.", + "digest.day": "dan", + "digest.week": "teden", + "digest.month": "mesec", + "digest.subject": "Povzetek za %1", + "notif.chat.subject": "Novo sporočilo klepeta prejeto na %1", "notif.chat.cta": "Kliknite tu za nadaljevanje pogovora", - "notif.chat.unsub.info": "Obvestilu o pogovoru je bilo poslano zaradi vaših nastavitev obvestil.", - "notif.post.cta": "Kliknite tu za celotno temo.", - "notif.post.unsub.info": "Obvestilo o odgovoru je bilo poslano zaradi vaših nastavitev obvestil.", - "test.text1": "To je testno elektronsko sporočilo za preverjanje prejemnika, če je pravilno nastavil NodeBB.", + "notif.chat.unsub.info": "Obvestilo o klepetu vam je bilo poslano zaradi vaših nastavitev naročnine.", + "notif.post.cta": "Kliknite tu, če želite prebrati celotno temo.", + "notif.post.unsub.info": "Obvestilo o objavi je bilo poslano zaradi vaših nastavitev naročnine.", + "test.text1": "To je testno elektronsko sporočilo, služi preverjanju pravilnosti nastavite podsistema za pošiljanje NodeBB poštnih sporočil.", "unsub.cta": "Kliknite tu za spremembo nastavitev.", "closing": "Hvala!" } \ No newline at end of file diff --git a/public/language/sl/error.json b/public/language/sl/error.json index be36f337e3..709870ec9c 100644 --- a/public/language/sl/error.json +++ b/public/language/sl/error.json @@ -20,14 +20,15 @@ "email-taken": "E-mail naslov je že zaseden", "email-not-confirmed": "Vaš e-mail naslov še ni bil potrjen. Prosimo kliknite tu za potrditev vašega e-mail naslova.", "email-not-confirmed-chat": "Ne morete klepetati dokler ne potrdite vašega e-mail naslova. Prosimo kliknite tu za potrditev vašega e-mail naslova.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Ta forum zahteva potrjen e-mail naslov. Prosim kliknite tu za vnos e-mail naslova.", "email-confirm-failed": "Nismo mogli potrditi vašega e-mail naslova. Prosimo poskusite ponovno.", "confirm-email-already-sent": "Potrditveni e-mail naslov je že poslan. Prosimo počakajte %1 minut(o) za ponovno pošiljanje.", "sendmail-not-found": "The sendmail executable could not be found, please ensure it is installed and executable by the user running NodeBB.", "username-too-short": "Uporabniško ime je prekratko", "username-too-long": "Uporabniško ime je predolgo", - "password-too-long": "Password too long", - "user-banned": "Uporabnik je blokiran", + "password-too-long": "Geslo je predolgo", + "user-banned": "Uporabnik je izločen", "user-too-new": "Oprostite, počakajte %1 sekund pred vašo prvo objavo", "blacklisted-ip": "Sorry, your IP address has been banned from this community. If you feel this is in error, please contact an administrator.", "ban-expiry-missing": "Please provide an end date for this ban", @@ -69,15 +70,15 @@ "guest-upload-disabled": "Guest uploading has been disabled", "already-favourited": "You have already bookmarked this post", "already-unfavourited": "You have already unbookmarked this post", - "cant-ban-other-admins": "Ne morete blokirati drugih administratorjev!", - "cant-remove-last-admin": "Ste edini administrator. Dodajte novega administratorja preden boste odstranili sebe.", + "cant-ban-other-admins": "Ne morete izločiti drugih skrbnikov!", + "cant-remove-last-admin": "Ste edini skrbnik. Preden se boste odstranili, dodajte novega skrbnika.", "cant-delete-admin": "Remove administrator privileges from this account before attempting to delete it.", "invalid-image-type": "Nedovoljen format slike. Dovoljeni formati so: %1", - "invalid-image-extension": "Nedovoljena končnica slike", - "invalid-file-type": "Nedovoljen format datoteke. Dovoljeni formati so: %1", + "invalid-image-extension": "Nedovoljena pripona slike", + "invalid-file-type": "Nedovoljena vrsta datoteke. Dovoljene vrste so: %1", "group-name-too-short": "Ime skupine je prekratko", - "group-name-too-long": "Group name too long", - "group-already-exists": "Skupina še obstaja", + "group-name-too-long": "Ime skupine je predolgo", + "group-already-exists": "Skupina že obstaja", "group-name-change-not-allowed": "Sprememba imena skupine ni dovoljena", "group-already-member": "Already part of this group", "group-not-member": "Not a member of this group", @@ -85,26 +86,26 @@ "group-already-invited": "Ta uporabnik je že bil povabljen", "group-already-requested": "Vaša prošnja za članstvo je že bila sprejeta.", "post-already-deleted": "Ta objava je že bila izbrisana", - "post-already-restored": "Ta objava je že bila razveljavljena", + "post-already-restored": "Ta objava je že bila obnovljena", "topic-already-deleted": "Ta tema je že bila izbrisana", - "topic-already-restored": "Ta tema je že bila razveljavljena", + "topic-already-restored": "Ta tema je že bila obnovljena", "cant-purge-main-post": "Ne morete odstraniti prve objave, prosimo izbrišite temo.", "topic-thumbnails-are-disabled": "Sličice teme so onemogočene.", "invalid-file": "Nedovoljena datoteka", - "uploads-are-disabled": "Nalaganje je onemogočeno", + "uploads-are-disabled": "Prenosi so onemogočeni", "signature-too-long": "Vaš podpis ne sme biti daljši od %1 znak(ov).", "about-me-too-long": "Rubrika \"O meni\" ne sme biti daljša od %1 znak(ov).", "cant-chat-with-yourself": "Ne morete klepetati s seboj!", - "chat-restricted": "Uporabnik je omejil klepetanje. Za možnost klepetanja vas mora uporabnik slediti", - "chat-disabled": "Chat system disabled", + "chat-restricted": "Uporabnik je omejil klepetanje. Za možnost klepetanja vas mora uporabnik spremljati", + "chat-disabled": "Klepet je onemogočen", "too-many-messages": "Poslali ste veliko število sporočil, prosimo počakajte nekaj časa.", - "invalid-chat-message": "Invalid chat message", - "chat-message-too-long": "Chat message is too long", + "invalid-chat-message": "Neveljavno sporočilo klepeta", + "chat-message-too-long": "Sporočilo klepeta je predolgo", "cant-edit-chat-message": "You are not allowed to edit this message", "cant-remove-last-user": "You can't remove the last user", "cant-delete-chat-message": "You are not allowed to delete this message", "already-voting-for-this-post": "You have already voted for this post.", - "reputation-system-disabled": "Možnost ugleda je onemogočena.", + "reputation-system-disabled": "Sistem za ugled je onemogočen.", "downvoting-disabled": "Negativno glasovanje je onemogočeno", "not-enough-reputation-to-downvote": "Nimate dovolj ugleda za negativno glasovanje", "not-enough-reputation-to-flag": "Nimate dovolj ugleda za prijavo te objave", @@ -112,7 +113,7 @@ "reload-failed": "NodeBB je zaznal težavo pri osveževanju: ", "registration-error": "Napaka pri registraciji", "parse-error": "Nekaj je šlo narobe pri pridobivanju odgovora s strežnika", - "wrong-login-type-email": "Uporabite svoj e-mail naslov za prijavo", + "wrong-login-type-email": "Uporabite svoj e-poštni naslov za prijavo", "wrong-login-type-username": "Uporabite svoje uporabniško ime za prijavo", "invite-maximum-met": "You have invited the maximum amount of people (%1 out of %2).", "no-session-found": "No login session found!", diff --git a/public/language/sl/global.json b/public/language/sl/global.json index f26add34d6..5dd5474601 100644 --- a/public/language/sl/global.json +++ b/public/language/sl/global.json @@ -52,8 +52,8 @@ "best": "Best", "upvoters": "Upvoters", "upvoted": "Upvoted", - "downvoters": "Downvoters", - "downvoted": "Downvoted", + "downvoters": "Negativnih glasovalcev", + "downvoted": "Negativno glasovano", "views": "Ogledi", "reputation": "Ugled", "read_more": "preberi več", diff --git a/public/language/sl/modules.json b/public/language/sl/modules.json index a9b88e3019..34b250169e 100644 --- a/public/language/sl/modules.json +++ b/public/language/sl/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "Vredu", "bootbox.cancel": "Prekliči", "bootbox.confirm": "Potrdi", diff --git a/public/language/sl/pages.json b/public/language/sl/pages.json index 27eebd626a..e89f935421 100644 --- a/public/language/sl/pages.json +++ b/public/language/sl/pages.json @@ -39,7 +39,7 @@ "account/settings": "Uporabniške nastavitve", "account/watched": "Teme, ki jih spremlja uporabnik %1", "account/upvoted": "Posts upvoted by %1", - "account/downvoted": "Posts downvoted by %1", + "account/downvoted": "Negativno glasovane objave od %1", "account/best": "Best posts made by %1", "confirm": "Email Confirmed", "maintenance.text": "%1 je trenutno v prenovi. Prosimo pridite nazaj kasneje.", diff --git a/public/language/sl/tags.json b/public/language/sl/tags.json index 4fbbab14d8..954005559f 100644 --- a/public/language/sl/tags.json +++ b/public/language/sl/tags.json @@ -3,5 +3,5 @@ "tags": "Oznake", "enter_tags_here": "Tu vpišite oznake, med %1 in %2 znaki.", "enter_tags_here_short": "Vpišite oznake...", - "no_tags": "Ni še oznak." + "no_tags": "Nobene oznake še ni." } \ No newline at end of file diff --git a/public/language/sl/topic.json b/public/language/sl/topic.json index 225d18110b..92012a4925 100644 --- a/public/language/sl/topic.json +++ b/public/language/sl/topic.json @@ -13,7 +13,7 @@ "notify_me": "Bodi obveščen o novih odgovorih na to temo", "quote": "Citiraj", "reply": "Odgovori", - "reply-as-topic": "Reply as topic", + "reply-as-topic": "Odgovori z temo", "guest-login-reply": "Prijavi se za odgovor", "edit": "Uredi", "delete": "Izbriši", @@ -26,44 +26,44 @@ "tools": "Orodja", "flag": "Prijavi", "locked": "Zaklenjeno", - "pinned": "Pinned", - "moved": "Moved", - "bookmark_instructions": "Click here to return to the last read post in this thread.", - "flag_title": "Prijavi to objavo v pregled administratorju", + "pinned": "Pripeto", + "moved": "Premaknjeno", + "bookmark_instructions": "Klikni tukaj za vrnitev na zadnje prebrano objavo v tej niti", + "flag_title": "Označi to objavo za vodenje", "flag_success": "Ta objava je bila prijavljena v pregled administratorju.", - "deleted_message": "Ta tema je bila izbrisana. Le uporabniki s pravicami teme jo lahko vidijo.", - "following_topic.message": "Sedaj boste dobili obvestila, ko bo nekdo objavil v to temo.", + "deleted_message": "Ta tema je bila izbrisana. Le uporabniki s pravicami upravljanja tem jo lahko vidijo.", + "following_topic.message": "Ob objavi v to temo, boste od sedaj dobivali obvestila. ", "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": "Prosimo prijavite ali registrirajte se za naročanje o tej temi.", "markAsUnreadForAll.success": "Tema označena kot neprebrana za vse.", - "mark_unread": "Mark unread", - "mark_unread.success": "Topic marked as unread.", + "mark_unread": "Označi kot neprebrano", + "mark_unread.success": "Tema označena kot neprebrana.", "watch": "Spremljaj", "unwatch": "Ne spremljaj", "watch.title": "Bodi obveščen o novih odgovorih v tej temi", "unwatch.title": "Prenehaj spremljati to temo", "share_this_post": "Deli to objavo", - "watching": "Watching", - "not-watching": "Not Watching", - "ignoring": "Ignoring", + "watching": "Spremljano", + "not-watching": "Ni spremljano", + "ignoring": "Prezri", "watching.description": "Notify me of new replies.
Show topic in unread.", "not-watching.description": "Do not notify me of new replies.
Show topic in unread if category is not ignored.", "ignoring.description": "Do not notify me of new replies.
Do not show topic in unread.", "thread_tools.title": "Orodja teme", "thread_tools.markAsUnreadForAll": "Označi kot neprebrano", - "thread_tools.pin": "Prilepi temo", - "thread_tools.unpin": "Odlepi temo", + "thread_tools.pin": "Pripni temo", + "thread_tools.unpin": "Odpni temo", "thread_tools.lock": "Zakleni temo", "thread_tools.unlock": "Odkleni temo", - "thread_tools.move": "Prestavi temo", - "thread_tools.move_all": "Prestavi vse", + "thread_tools.move": "Premakni temo", + "thread_tools.move_all": "Premakni vse", "thread_tools.fork": "Razcepi temo", "thread_tools.delete": "Izbriši temo", - "thread_tools.delete-posts": "Delete Posts", + "thread_tools.delete-posts": "Izbriši objave", "thread_tools.delete_confirm": "Ste prepričani, da želite izbrisati to temo?", - "thread_tools.restore": "Razveljavi temo", - "thread_tools.restore_confirm": "Ste prepričani, da želite razveljaviti to temo?", + "thread_tools.restore": "Obnovi temo", + "thread_tools.restore_confirm": "Ste prepričani, da želite obnoviti to temo?", "thread_tools.purge": "Očisti temo", "thread_tools.purge_confirm": "Ste prepričani, da želite očistiti to temo?", "topic_move_success": "Ta tema je bila uspešno prestavljena v %1", @@ -74,9 +74,9 @@ "disabled_categories_note": "Onemogočene kategorije so obarvane sivo", "confirm_move": "Premakni", "confirm_fork": "Razcepi", - "favourite": "Bookmark", - "favourites": "Bookmarks", - "favourites.has_no_favourites": "You haven't bookmarked any posts yet.", + "favourite": "Zaznamek", + "favourites": "Zaznamki", + "favourites.has_no_favourites": "Zaznamovali še niste nobenih objav.", "loading_more_posts": "Nalagam več objav", "move_topic": "Premakni temo", "move_topics": "Premakni teme", @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Ta tema bo premaknjena v to kategorijo", "fork_topic_instruction": "Klikni na objavo, ki o želiš odcepiti", "fork_no_pids": "Ni izbranih objav!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Uspešno ste razcepili temo! Klikni tu za ogled te teme.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Vpiši naslov teme...", diff --git a/public/language/sl/uploads.json b/public/language/sl/uploads.json index 1622cb5693..85ee20d0c2 100644 --- a/public/language/sl/uploads.json +++ b/public/language/sl/uploads.json @@ -1,6 +1,6 @@ { - "uploading-file": "Uploading the file...", - "select-file-to-upload": "Select a file to upload!", - "upload-success": "File uploaded successfully!", - "maximum-file-size": "Maximum %1 kb" + "uploading-file": "Prenašanje datoteke ...", + "select-file-to-upload": "Izberete datoteko, ki jo želite prenesti!", + "upload-success": "Datoteka je bila uspešno prenesena!", + "maximum-file-size": "Največ %1 kb " } \ No newline at end of file diff --git a/public/language/sl/user.json b/public/language/sl/user.json index 57a2b00c47..330d37b7ee 100644 --- a/public/language/sl/user.json +++ b/public/language/sl/user.json @@ -1,19 +1,19 @@ { - "banned": "Blokirani", + "banned": "Izločen", "offline": "Odjavljeni", "username": "Uporabniško ime", "joindate": "Datum pridružitve", "postcount": "Število objav", "email": "E-pošta", "confirm_email": "Potrdi e-poštni naslov", - "account_info": "Account Info", - "ban_account": "Blokiraj račun", - "ban_account_confirm": "Ali želiš blokirati uporabnika?", - "unban_account": "Odblokiraj račun", + "account_info": "Podatki računa", + "ban_account": "Izločen račun", + "ban_account_confirm": "Ali želiš izločiti uporabnika?", + "unban_account": "Ponovno vključi račun", "delete_account": "Izbriši račun", "delete_account_confirm": "Ali želiš izbrisati račun?
S potrditvijo bodo izbrisani vsi podatki, ki jih ne bo več možno obnoviti.

Vpiši svoje uporabniško ime za dokončanje procesa.", "delete_this_account_confirm": "Ali želiš izbrisati račun?
S potrditvijo bodo izbrisani vsi podatki, ki jih ne bo več možno obnoviti.

", - "account-deleted": "Account deleted", + "account-deleted": "Račun je izbrisan", "fullname": "Ime in priimek", "website": "Spletna stran", "location": "Lokacija", @@ -23,25 +23,25 @@ "profile": "Profil", "profile_views": "Ogledi", "reputation": "Naziv", - "favourites": "Bookmarks", - "watched": "Zgodovina ogledov", - "followers": "Sledilci", - "following": "Sledim", + "favourites": "Zaznamki", + "watched": "Spremljano", + "followers": "Spremljevalci", + "following": "Spremljano", "aboutme": "O meni", "signature": "Podpis", "birthday": "Rojstni datum", "chat": "Klepet", - "chat_with": "Chat with %1", + "chat_with": "Klepet z %1", "follow": "Spremljaj", "unfollow": "Ne spremljaj", "more": "Več", - "profile_update_success": "Prosil je bil uspešno posodobljen.", + "profile_update_success": "Profil je bil uspešno posodobljen.", "change_picture": "Spremeni sliko", - "change_username": "Change Username", - "change_email": "Change Email", + "change_username": "Spremeni uporabniško ime", + "change_email": "Spremeni e-poštni naslov", "edit": "Uredi", - "edit-profile": "Edit Profile", - "default_picture": "Default Icon", + "edit-profile": "Uredi profil", + "default_picture": "Privzeta ikona", "uploaded_picture": "Naloži fotografijo", "upload_new_picture": "Naloži novo fotografijo", "upload_new_picture_from_url": "Naloži novo fotografijo s spletnega naslova", @@ -56,12 +56,12 @@ "confirm_password": "Potrdi geslo", "password": "Geslo", "username_taken_workaround": "Predlagano uporabniško ime je že zasedeno, zato predlagamo %1", - "password_same_as_username": "Your password is the same as your username, please select another password.", - "password_same_as_email": "Your password is the same as your email, please select another password.", + "password_same_as_username": "Vaše geslo je enako kot vaše uporabniško ime, prosim izberite drugačno geslo.", + "password_same_as_email": "Vaše geslo je enako kot vaše e-poštni naslov, prosim izberite drugačno geslo.", "upload_picture": "Naloži fotografijo", "upload_a_picture": "Naloži fotografijo", - "remove_uploaded_picture": "Remove Uploaded Picture", - "upload_cover_picture": "Upload cover picture", + "remove_uploaded_picture": "Odstrani preneseno sliko ", + "upload_cover_picture": "Prenesi fotografijo naslovnice", "settings": "Nastavitve.", "show_email": "Pokaži moj e-poštni naslov.", "show_fullname": "Pokaži moj ime in priimek.", @@ -80,9 +80,9 @@ "has_no_posts": "Uporabnik še ni ustvaril nobene objave.", "has_no_topics": "Uporabnik še ni odprl nobene teme.", "has_no_watched_topics": "Uporabnik še ne spremlja nobene teme.", - "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_upvoted_posts": "Uporabnik še ni pritrdil nobeni objavi.", + "has_no_downvoted_posts": "Uporabnik še ni ne pritrdil nobeni objavi.", + "has_no_voted_posts": "Uporabnik še nima nobene pritrditve objavam", "email_hidden": "Skrit e-poštni naslov", "hidden": "skrit", "paginate_description": "Uporabi oštevilčenje strani namesto neskončnega drsenja", @@ -93,14 +93,14 @@ "open_links_in_new_tab": "Zunanje povezave odpri v novem zavihku", "enable_topic_searching": "Omogoči iskanje znotraj teme", "topic_search_help": "Če omogočite, bo iskanje prepisalo brskalnikove prevzete nastavitve in vam omogočilo iskanje skozi celotno temo.", - "delay_image_loading": "Delay Image Loading", + "delay_image_loading": "Zakasnitev pri nalaganju slike", "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", - "follow_topics_you_reply_to": "Watch topics that you reply to", - "follow_topics_you_create": "Watch topics you create", + "follow_topics_you_reply_to": "Spremljanj teme, na katere si odgovoril", + "follow_topics_you_create": "Spremljanj teme, ki si jih ustvaril", "grouptitle": "Group Title", "no-group-title": "Skupina nima imena", - "select-skin": "Izberi obliko", + "select-skin": "Izberi preobleko", "select-homepage": "Select a Homepage", "homepage": "Homepage", "homepage_description": "Select a page to use as the forum homepage or 'None' to use the default homepage.", diff --git a/public/language/sr/error.json b/public/language/sr/error.json index 3827af2da1..05241438be 100644 --- a/public/language/sr/error.json +++ b/public/language/sr/error.json @@ -20,6 +20,7 @@ "email-taken": "Адреса е-поште је заусета", "email-not-confirmed": "Ваша адреса е-поште жоуш увек није оверена, кликните овде да би сте то учинили.", "email-not-confirmed-chat": "Није вам дозвољено да ћаскате док не оверите вашу е-пошту, клкните овде да то учините.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Форум захтева потврду е-поште, кликните овде да бисте отворили е-пошту", "email-confirm-failed": "Потврда е-поште није успела, молимо вас да покушате касније.", "confirm-email-already-sent": "Конфирмациони имејл је већ послат, молимо вас да сачекате %1 минут(а) да бисте послали други.", diff --git a/public/language/sr/modules.json b/public/language/sr/modules.json index 24d2e521f9..2ef142c34f 100644 --- a/public/language/sr/modules.json +++ b/public/language/sr/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "ОК", "bootbox.cancel": "Откажи", "bootbox.confirm": "Потврди", diff --git a/public/language/sr/topic.json b/public/language/sr/topic.json index 42b56929a3..e43df818ad 100644 --- a/public/language/sr/topic.json +++ b/public/language/sr/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "This topic will be moved to the category", "fork_topic_instruction": "Click the posts you want to fork", "fork_no_pids": "No posts selected!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "Enter your topic title here...", diff --git a/public/language/sv/error.json b/public/language/sv/error.json index 9096296fbb..172f78e6cd 100644 --- a/public/language/sv/error.json +++ b/public/language/sv/error.json @@ -20,6 +20,7 @@ "email-taken": "Epostadress upptagen", "email-not-confirmed": "Din epostadress är ännu inte bekräftad. Klicka här för att bekräfta din epostadress.", "email-not-confirmed-chat": "Du kan ej använda chatten förrän din epostadress har blivit bekräftad, var god klicka här för att bekräfta din epostadress.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Detta forum kräver bekräftning av epostadresser, var god klicka här för att fylla i en epostadress", "email-confirm-failed": "Vi kunde ej bekräfta din epostadress, var god försök igen senare.", "confirm-email-already-sent": "Bekräftningsbrev redan skickat, var god vänta %1 minut(er) innan du skickar ett nytt.", diff --git a/public/language/sv/modules.json b/public/language/sv/modules.json index 3d69a7aab8..56ddf0ceb5 100644 --- a/public/language/sv/modules.json +++ b/public/language/sv/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Bild", "composer.upload-picture": "Ladda upp bild", "composer.upload-file": "Ladda upp fil", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Avbryt", "bootbox.confirm": "Bekräfta", diff --git a/public/language/sv/topic.json b/public/language/sv/topic.json index 734afb5719..99fad2d42b 100644 --- a/public/language/sv/topic.json +++ b/public/language/sv/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Detta ämne kommer att flyttas till kategorin", "fork_topic_instruction": "Klicka på de inlägg du vill grena", "fork_no_pids": "Inga inlägg valda!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Ämnet har blivit förgrenat. Klicka här för att gå till det förgrenade ämnet.", "delete_posts_instruction": "Klicka på inläggen du vill radera/rensa bort", "composer.title_placeholder": "Skriv in ämnets titel här...", diff --git a/public/language/th/error.json b/public/language/th/error.json index fcb210f49c..27373e3aa5 100644 --- a/public/language/th/error.json +++ b/public/language/th/error.json @@ -20,6 +20,7 @@ "email-taken": "อีเมลนี้มีการใช้แล้ว", "email-not-confirmed": "ยังไม่มีการยืนยันอีเมลของคุณ, โปรดกดยืนยันอีเมลของคุณตรงนี้", "email-not-confirmed-chat": "You are unable to chat until your email is confirmed, please click here to confirm your email.", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "Forum นี้ต้องการการยืนยันอีเมล กรุณากดที่นี่เพื่อระบุอีเมล", "email-confirm-failed": "เราไม่สามารถยืนยันอีเมลของคุณ ณ ขณะนี้ กรุณาลองใหม่อีกครั้งภายหลัง", "confirm-email-already-sent": "Confirmation email already sent, please wait %1 minute(s) to send another one.", diff --git a/public/language/th/modules.json b/public/language/th/modules.json index 51c6065cd8..2527f30e40 100644 --- a/public/language/th/modules.json +++ b/public/language/th/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Picture", "composer.upload-picture": "Upload Image", "composer.upload-file": "Upload File", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Cancel", "bootbox.confirm": "Confirm", diff --git a/public/language/th/topic.json b/public/language/th/topic.json index 532af2a8a8..fa4e0bccc4 100644 --- a/public/language/th/topic.json +++ b/public/language/th/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "กระทู้นี้จะถูกย้ายไปที่หมวดหมู่", "fork_topic_instruction": "คลิกที่โพสที่คุณต้องการที่จะแยก", "fork_no_pids": "ไม่มีโพสต์ที่เลือก!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "Successfully forked topic! Click here to go to the forked topic.", "delete_posts_instruction": "Click the posts you want to delete/purge", "composer.title_placeholder": "ป้อนชื่อกระทู้ของคุณที่นี่ ...", diff --git a/public/language/tr/error.json b/public/language/tr/error.json index 6fad971610..48811f7373 100644 --- a/public/language/tr/error.json +++ b/public/language/tr/error.json @@ -20,6 +20,7 @@ "email-taken": "E-posta Alınmış", "email-not-confirmed": "E-postanız onaylanmamış, onaylamak için lütfen buraya tıklayın.", "email-not-confirmed-chat": "E-postanız onaylanana kadar sohbet edemezsiniz, onaylamak için lütfen buraya tıklayın.", + "email-not-confirmed-email-sent": "E-postanız onaylanmamış, onaylamak için lütfen gelen kutunuzu kontrol edin.", "no-email-to-confirm": "Bu forum e-posta doğrulaması gerektirir, lütfen buraya bir e-posta adresi girin", "email-confirm-failed": "E-posta adresinizi doğrulayamıyoruz. Lütfen daha sonra tekrar deneyin.", "confirm-email-already-sent": "E-mail onayı zaten gönderilmiş, yeni bir onay göndermek için lütfen 1 dakika bekleyin.", diff --git a/public/language/tr/modules.json b/public/language/tr/modules.json index 06e5876c68..0edc53c346 100644 --- a/public/language/tr/modules.json +++ b/public/language/tr/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Görsel", "composer.upload-picture": "Görsel Yükle", "composer.upload-file": "Dosya Yükle", + "composer.zen_mode": "Zen Modu", "bootbox.ok": "Tamam", "bootbox.cancel": "İptal", "bootbox.confirm": "Onayla", diff --git a/public/language/tr/topic.json b/public/language/tr/topic.json index b870308c74..8854a5eab9 100644 --- a/public/language/tr/topic.json +++ b/public/language/tr/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Bu konu kategorisine taşınacak", "fork_topic_instruction": "Ayırmak istediğiniz iletileri tıklayın", "fork_no_pids": "Hiç bir ileti seçilmedi!", + "fork_pid_count": "%1 ileti(ler) seçildi", "fork_success": "Başlık başarıyla ayrıldı!", "delete_posts_instruction": "Silmek/temizlemek istediğiniz iletilere tıklayın.", "composer.title_placeholder": "Başlık ismini buraya girin...", diff --git a/public/language/vi/error.json b/public/language/vi/error.json index 38a0ab9a69..6af283b8de 100644 --- a/public/language/vi/error.json +++ b/public/language/vi/error.json @@ -20,6 +20,7 @@ "email-taken": "Email đã được đăng kí", "email-not-confirmed": "Email của bạn chưa được xác nhận, xin hãy nhấn vào đây để xác nhận địa chỉ này là của bạn", "email-not-confirmed-chat": "Bạn không được quyền chat nếu email của bạn chưa được xác nhận, vui lòng click vào đây để xác nhận email của bạn.", + "email-not-confirmed-email-sent": "Email của bạn chưa được xác nhận, xin hãy nhấn vào đây để xác nhận địa chỉ này là của bạn", "no-email-to-confirm": "Diễn đàn này yêu cầu xác nhận email, vui lòng nhấn vào đây để nhập email.", "email-confirm-failed": "Chúng tôi không thể xác nhận email của bạn, vui lòng thử lại sau.", "confirm-email-already-sent": "Email xác nhận đã được gửi, vui lòng chờ %1 phút để yêu cầu gửi lại.", @@ -29,8 +30,8 @@ "password-too-long": "Mật khẩu quá dài", "user-banned": "Tài khoản bị ban", "user-too-new": "Rất tiếc, bạn phải chờ %1 giây để đăng bài viết đầu tiên.", - "blacklisted-ip": "Rất tiếc, địa chỉ IP của bạn đã bị ban khỏi cộng đồng. Nếu bạn cảm thấy có gì không đúng, hãy liên lạc với người quản trị.", - "ban-expiry-missing": "Please provide an end date for this ban", + "blacklisted-ip": "Rất tiếc, địa chỉ IP của bạn đã bị cấm khỏi cộng đồng. Nếu bạn cảm thấy có gì không đúng, hãy liên lạc với người quản trị.", + "ban-expiry-missing": "Vui lòng cung cấp ngày hết hạn của lệnh cấm", "no-category": "Danh mục không tồn tại", "no-topic": "Chủ đề không tồn tại", "no-post": "Bài viết không tồn tại", @@ -47,13 +48,13 @@ "post-edit-duration-expired-hours-minutes": "Bạn chỉ được phép sửa các bài viết sau khi đăng %1 giờ(s) %2 phút(s)", "post-edit-duration-expired-days": "Bạn chỉ được phép sửa các bài viết sau khi đăng %1 ngày(s)", "post-edit-duration-expired-days-hours": "Bạn chỉ được phép sửa các bài viết sau khi đăng %1 ngày(s) %2 giờ(s)", - "post-delete-duration-expired": "You are only allowed to delete posts for %1 second(s) after posting", - "post-delete-duration-expired-minutes": "You are only allowed to delete posts for %1 minute(s) after posting", - "post-delete-duration-expired-minutes-seconds": "You are only allowed to delete posts for %1 minute(s) %2 second(s) after posting", - "post-delete-duration-expired-hours": "You are only allowed to delete posts for %1 hour(s) after posting", - "post-delete-duration-expired-hours-minutes": "You are only allowed to delete posts for %1 hour(s) %2 minute(s) after posting", - "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting", - "post-delete-duration-expired-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting", + "post-delete-duration-expired": "Bạn chỉ được phép xóa bài viết sau khi đăng %1 giây(s)", + "post-delete-duration-expired-minutes": "Bạn chỉ được phép xóa bài viết sau khi đăng %1 phút(s)", + "post-delete-duration-expired-minutes-seconds": "Bạn chỉ được phép xóa các bài viết sau khi đăng %1 phút(s) %2 giây(s)", + "post-delete-duration-expired-hours": "Bạn chỉ được phép xóa bài viết sau khi đăng %1 giờ(s)", + "post-delete-duration-expired-hours-minutes": "Bạn chỉ được phép xóa bài viết sau khi đăng %1 giờ(s) 2 phút(s)", + "post-delete-duration-expired-days": "Bạn chỉ được phép xóa các bài viết sau khi đăng %1 ngày(s)", + "post-delete-duration-expired-days-hours": "Bạn chỉ được phép xóa các bài viết sau khi đăng %1 ngày(s) %2 giờ(s)", "content-too-short": "Vui lòng nhập một bài viết dài hơn. Bài viết phải có tối thiểu %1 ký tự.", "content-too-long": "Vui lòng nhập một bài viết ngắn hơn. Bài viết chỉ có thể có tối đa %1 ký tự.", "title-too-short": "Vui lòng nhập tiêu đề dài hơn. Tiêu đề phải có tối thiểu %1 ký tự.", @@ -69,14 +70,14 @@ "guest-upload-disabled": "Khách (chưa có tài khoản) không có quyền tải lên file.", "already-favourited": "Bạn đã đánh dấu bài viết này", "already-unfavourited": "Bạn đã bỏ đánh dấu bài viết này", - "cant-ban-other-admins": "Bạn không thể ban được các admin khác", + "cant-ban-other-admins": "Bạn không thể cấm được các quản trị viên khác", "cant-remove-last-admin": "Bạn là quản trị viên duy nhất. Hãy cho thành viên khác làm quản trị viên trước khi huỷ bỏ quyền quản trị của bạn.", - "cant-delete-admin": "Remove administrator privileges from this account before attempting to delete it.", + "cant-delete-admin": "Hủy quyền quản trị của tài khoản này trước khi xóa", "invalid-image-type": "Định dạng ảnh không hợp lệ. Những định dạng được cho phép là: %1", "invalid-image-extension": "Định dạng ảnh không hợp lệ", "invalid-file-type": "Định dạng file không hợp lệ. Những định dạng được cho phép là: %1", "group-name-too-short": "Tên nhóm quá ngắn", - "group-name-too-long": "Group name too long", + "group-name-too-long": "Tên nhóm quá dài", "group-already-exists": "Nhóm đã tồn tại", "group-name-change-not-allowed": "Không cho phép đổi tên nhóm", "group-already-member": "Bạn đã là thành viên của nhóm này.", @@ -119,6 +120,6 @@ "not-in-room": "Thành viên không có trong phòng", "no-users-in-room": "Không có ai trong phòng này", "cant-kick-self": "Bạn không thể kick chính bạn ra khỏi nhóm", - "no-users-selected": "No user(s) selected", - "invalid-home-page-route": "Invalid home page route" + "no-users-selected": "Chưa có người dùng(s) nào", + "invalid-home-page-route": "Đường dẫn trang chủ không hợp lệ" } \ No newline at end of file diff --git a/public/language/vi/global.json b/public/language/vi/global.json index 7eb329ec13..6928ecfefa 100644 --- a/public/language/vi/global.json +++ b/public/language/vi/global.json @@ -50,9 +50,9 @@ "topics": "Số Chủ đề", "posts": "Số bài viết", "best": "Hay nhất", - "upvoters": "Upvoters", + "upvoters": "Tán thành", "upvoted": "Tán thành", - "downvoters": "Downvoters", + "downvoters": "Phản đối", "downvoted": "Phản đối", "views": "Lượt xem", "reputation": "Điểm tín nhiệm", diff --git a/public/language/vi/modules.json b/public/language/vi/modules.json index c7863e97aa..fda573b3fd 100644 --- a/public/language/vi/modules.json +++ b/public/language/vi/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "Hình ảnh", "composer.upload-picture": "Tải ảnh lên", "composer.upload-file": "Tải file lên", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "OK", "bootbox.cancel": "Huỷ bỏ", "bootbox.confirm": "Xác nhận", diff --git a/public/language/vi/topic.json b/public/language/vi/topic.json index 8c7085fcbf..8701518f30 100644 --- a/public/language/vi/topic.json +++ b/public/language/vi/topic.json @@ -26,14 +26,14 @@ "tools": "Công cụ", "flag": "Gắn cờ", "locked": "Khóa", - "pinned": "Pinned", - "moved": "Moved", + "pinned": "Đã ghim", + "moved": "Chuyển đi", "bookmark_instructions": "Bấm vào đây để quay về đọc bài viết mới nhất trong chủ đề này.", "flag_title": "Flag bài viết này để chỉnh sửa", "flag_success": "Chủ đề này đã được flag để chỉnh sửa", "deleted_message": "Chủ đề này đã bị xóa. Chỉ ban quản trị mới xem được.", "following_topic.message": "Từ giờ bạn sẽ nhận được thông báo khi có ai đó gửi bài viết trong chủ đề này", - "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.", + "not_following_topic.message": "Bạn có thể xem chủ đề này trong danh sách chủ đề chưa xem, nhưng bạn sẽ không nhận thông báo khi có ai đó đăng bài viết trong chủ đề này", "ignoring_topic.message": "Bạn sẽ không còn xem được chủ đề này trong danh sách các chủ đề chưa đọc nữa. Bạn sẽ nhận được thông báo khi bạn được đề cập tới hoặc bài viết của bạn được bỏ phiếu.", "login_to_subscribe": "Xin hãy đăng ký hoặc đăng nhập để theo dõi topic này", "markAsUnreadForAll.success": "Chủ đề đã được đánh dấu là chưa đọc toàn bộ", @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "Chủ đề này sẽ được chuyển tới phần mục", "fork_topic_instruction": "Chọn vào bài gửi mà bạn muốn fork", "fork_no_pids": "Chưa chọn bài gửi nào!", + "fork_pid_count": "%1 bài viết(s) đã được gửi", "fork_success": "Tạo bản sao thành công! Nhấn vào đây để chuyển tới chủ đề vừa tạo.", "delete_posts_instruction": "Chọn những bài viết bạn muốn xoá", "composer.title_placeholder": "Nhập tiêu đề cho chủ đề của bạn tại đây...", diff --git a/public/language/zh_CN/error.json b/public/language/zh_CN/error.json index 51ce4481b2..aa496cca6f 100644 --- a/public/language/zh_CN/error.json +++ b/public/language/zh_CN/error.json @@ -20,6 +20,7 @@ "email-taken": "此电子邮箱已被占用", "email-not-confirmed": "您的电子邮箱尚未确认,请点击这里确认您的电子邮箱。", "email-not-confirmed-chat": "您的电子邮箱尚未确认,无法聊天,请点击这里确认您的电子邮箱。", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "本论坛需要电子邮箱确认,请点击这里输入电子邮箱地址", "email-confirm-failed": "我们无法确认您的电子邮箱,请重试", "confirm-email-already-sent": "确认邮件已发出,如需重新发送请等待 %1 分钟后再试。", diff --git a/public/language/zh_CN/modules.json b/public/language/zh_CN/modules.json index da6d813ee3..869a8bf0c0 100644 --- a/public/language/zh_CN/modules.json +++ b/public/language/zh_CN/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "图片", "composer.upload-picture": "上传图片", "composer.upload-file": "上传文件", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "确认", "bootbox.cancel": "取消", "bootbox.confirm": "确认", diff --git a/public/language/zh_CN/topic.json b/public/language/zh_CN/topic.json index 63ebe02f77..072da54e1a 100644 --- a/public/language/zh_CN/topic.json +++ b/public/language/zh_CN/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "此主题将被移动到版块", "fork_topic_instruction": "点击将分割的帖子", "fork_no_pids": "未选中帖子!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "成功分割主题! 点这里跳转到分割后的主题。", "delete_posts_instruction": "点击想要删除/永久删除的帖子", "composer.title_placeholder": "在此输入您主题的标题...", diff --git a/public/language/zh_TW/error.json b/public/language/zh_TW/error.json index 617902283b..3c9a9849e6 100644 --- a/public/language/zh_TW/error.json +++ b/public/language/zh_TW/error.json @@ -20,6 +20,7 @@ "email-taken": "該信箱已被使用", "email-not-confirmed": "你的電子郵件尚未確認,請點擊此處確認你的電子郵件。", "email-not-confirmed-chat": "你需要先確認電子郵件後才能進行聊天,請點擊這裡來確認你的電子郵件。", + "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.", "no-email-to-confirm": "討論區要求電子郵件確認,請點擊這裡輸入一個電子郵件。", "email-confirm-failed": "我們無法確認你的Email,請之後再重試。", "confirm-email-already-sent": "確認電子郵件已經寄送,請等待 %1 分鐘才能再寄送另一封。", diff --git a/public/language/zh_TW/modules.json b/public/language/zh_TW/modules.json index bbf71c78bf..e02c0908f1 100644 --- a/public/language/zh_TW/modules.json +++ b/public/language/zh_TW/modules.json @@ -37,6 +37,7 @@ "composer.formatting.picture": "圖片", "composer.upload-picture": "上傳圖片", "composer.upload-file": "上傳檔案", + "composer.zen_mode": "Zen Mode", "bootbox.ok": "好", "bootbox.cancel": "取消", "bootbox.confirm": "確認", diff --git a/public/language/zh_TW/topic.json b/public/language/zh_TW/topic.json index 87bb2d8e08..30d46b9419 100644 --- a/public/language/zh_TW/topic.json +++ b/public/language/zh_TW/topic.json @@ -86,6 +86,7 @@ "topic_will_be_moved_to": "這個主題將會被移動到類別", "fork_topic_instruction": "點擊要作為主題的文章", "fork_no_pids": "尚未選擇文章!", + "fork_pid_count": "%1 post(s) selected", "fork_success": "成功分叉成新的主題!點擊這裡進入新的主題。", "delete_posts_instruction": "點擊你想要刪除/清除的張貼", "composer.title_placeholder": "輸入標題...", diff --git a/public/src/admin/advanced/errors.js b/public/src/admin/advanced/errors.js index 2e72bcceb5..52d6427240 100644 --- a/public/src/admin/advanced/errors.js +++ b/public/src/admin/advanced/errors.js @@ -29,7 +29,7 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { dailyLabels = dailyLabels.slice(-7); if (utils.isMobile()) { - Chart.defaults.global.showTooltips = false; + Chart.defaults.global.tooltips.enabled = false; } var data = { @@ -38,12 +38,12 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { datasets: [ { label: "", - fillColor: "rgba(186,139,175,0.2)", - strokeColor: "rgba(186,139,175,1)", - pointColor: "rgba(186,139,175,1)", - pointStrokeColor: "#fff", - pointHighlightFill: "#fff", - pointHighlightStroke: "rgba(186,139,175,1)", + backgroundColor: "rgba(186,139,175,0.2)", + borderColor: "rgba(186,139,175,1)", + pointBackgroundColor: "rgba(186,139,175,1)", + pointHoverBackgroundColor: "#fff", + pointBorderColor: "#fff", + pointHoverBorderColor: "rgba(186,139,175,1)", data: ajaxify.data.analytics['not-found'] } ] @@ -53,12 +53,12 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { datasets: [ { label: "", - fillColor: "rgba(151,187,205,0.2)", - strokeColor: "rgba(151,187,205,1)", - pointColor: "rgba(151,187,205,1)", - pointStrokeColor: "#fff", - pointHighlightFill: "#fff", - pointHighlightStroke: "rgba(151,187,205,1)", + backgroundColor: "rgba(151,187,205,0.2)", + borderColor: "rgba(151,187,205,1)", + pointBackgroundColor: "rgba(151,187,205,1)", + pointHoverBackgroundColor: "#fff", + pointBorderColor: "#fff", + pointHoverBorderColor: "rgba(151,187,205,1)", data: ajaxify.data.analytics['toobusy'] } ] @@ -67,13 +67,41 @@ define('admin/advanced/errors', ['Chart'], function(Chart) { notFoundCanvas.width = $(notFoundCanvas).parent().width(); tooBusyCanvas.width = $(tooBusyCanvas).parent().width(); - new Chart(notFoundCanvas.getContext('2d')).Line(data['not-found'], { - responsive: true, - animation: false + + new Chart(notFoundCanvas.getContext('2d'), { + type: 'line', + data: data['not-found'], + options: { + responsive: true, + legend: { + display: false + }, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } }); - new Chart(tooBusyCanvas.getContext('2d')).Line(data['toobusy'], { - responsive: true, - animation: false + + new Chart(tooBusyCanvas.getContext('2d'), { + type: 'line', + data: data['toobusy'], + options: { + responsive: true, + legend: { + display: false + }, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + } + } }); }; diff --git a/public/src/admin/general/dashboard.js b/public/src/admin/general/dashboard.js index 1071c76b0d..1224d2ace2 100644 --- a/public/src/admin/general/dashboard.js +++ b/public/src/admin/general/dashboard.js @@ -165,8 +165,7 @@ define('admin/general/dashboard', ['semver', 'Chart'], function(semver, Chart) { trafficLabels = utils.getHoursArray(); if (isMobile) { - Chart.defaults.global.showTooltips = false; - Chart.defaults.global.animation = false; + Chart.defaults.global.tooltips.enabled = false; } var data = { diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index cc39889807..7138bb01b9 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -195,7 +195,7 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable) return; } - bootbox.confirm('Warning!
Do you really want to delete user(s)?
This action is not reversable, all user data and content will be erased!', function(confirm) { + bootbox.confirm('Warning!
Do you really want to delete user(s)?
This action is not reversable, only the user account will be deleted, their posts and topics will not be deleled!', function(confirm) { if (confirm) { socket.emit('admin.user.deleteUsers', uids, function(err) { if (err) { @@ -210,6 +210,26 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable) }); }); + $('.delete-user-and-content').on('click', function() { + var uids = getSelectedUids(); + if (!uids.length) { + return; + } + bootbox.confirm('Warning!
Do you really want to delete user(s) and their content?
This action is not reversable, all user data and content will be erased!', function(confirm) { + if (confirm) { + socket.emit('admin.user.deleteUsersAndContent', uids, function(err) { + if (err) { + return app.alertError(err.message); + } + + app.alertSuccess('User(s) Deleted!'); + removeSelected(); + unselectAll(); + }); + } + }); + }); + function handleUserCreate() { var errorEl = $('#create-modal-error'); $('#createUser').on('click', function() { diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index ba6222f06c..de20693eb0 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -66,6 +66,12 @@ $(document).ready(function() { url = ajaxify.start(url); + // If any listeners alter url and set it to an empty string, abort the ajaxification + if (url === null) { + $(window).trigger('action:ajaxify.end', {url: url, tpl_url: ajaxify.data.template.name, title: ajaxify.data.title}); + return false; + } + previousBodyClass = ajaxify.data.bodyClass; $('#footer, #content').removeClass('hide').addClass('ajaxifying'); @@ -107,9 +113,13 @@ $(document).ready(function() { ajaxify.start = function(url) { url = ajaxify.removeRelativePath(url.replace(/^\/|\/$/g, '')); - $(window).trigger('action:ajaxify.start', {url: url}); + var payload = { + url: url + } - return url; + $(window).trigger('action:ajaxify.start', payload); + + return payload.url; }; ajaxify.updateHistory = function(url, quiet) { diff --git a/public/src/app.js b/public/src/app.js index 390bde2f04..a913517363 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -511,20 +511,22 @@ app.cacheBuster = null; app.parseAndTranslate = function(template, blockName, data, callback) { require(['translator'], function(translator) { + function translate(html, callback) { + translator.translate(html, function(translatedHTML) { + translatedHTML = translator.unescape(translatedHTML); + callback($(translatedHTML)); + }); + } + if (typeof blockName === 'string') { templates.parse(template, blockName, data, function(html) { - translator.translate(html, function(translatedHTML) { - translatedHTML = translator.unescape(translatedHTML); - callback($(translatedHTML)); - }); + translate(html, callback); }); } else { - callback = data, data = blockName; + callback = data; + data = blockName; templates.parse(template, data, function(html) { - translator.translate(html, function(translatedHTML) { - translatedHTML = translator.unescape(translatedHTML); - callback($(translatedHTML)); - }); + translate(html, callback); }); } }); diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index 616cebbe82..6b39b7f2da 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -152,7 +152,7 @@ define('forum/account/header', [ return; } - socket.emit('admin.user.deleteUsers', [ajaxify.data.theirid], function(err) { + socket.emit('admin.user.deleteUsersAndContent', [ajaxify.data.theirid], function(err) { if (err) { return app.alertError(err.message); } diff --git a/public/src/client/footer.js b/public/src/client/footer.js index f1d05d4bfe..30da71aa12 100644 --- a/public/src/client/footer.js +++ b/public/src/client/footer.js @@ -50,10 +50,12 @@ define('forum/footer', ['notifications', 'chat', 'components', 'translator'], fu } $(window).on('action:ajaxify.end', function(ev, data) { - var tid = data.url.match(/^topic\/(\d+)/); + if (data.url) { + var tid = data.url.match(/^topic\/(\d+)/); - if (tid && tid[1]) { - delete unreadTopics[tid[1]]; + if (tid && tid[1]) { + delete unreadTopics[tid[1]]; + } } }); diff --git a/public/src/client/topic.js b/public/src/client/topic.js index da4e5456e8..aff00909d1 100644 --- a/public/src/client/topic.js +++ b/public/src/client/topic.js @@ -31,7 +31,7 @@ define('forum/topic', [ $(window).off('keydown', onKeyDown); } - if (!data.url.startsWith('topic/')) { + if (data.url && !data.url.startsWith('topic/')) { require(['search'], function(search) { if (search.topicDOM.active) { search.topicDOM.end(); diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index 0c6ee5ea06..68a864198e 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -188,7 +188,7 @@ define('forum/topic/events', [ var isDeleted = postEl.hasClass('deleted'); postTools.toggle(data.pid, isDeleted); - if (!app.user.isAdmin && !app.user.isGlobalMod && parseInt(data.uid, 10) !== parseInt(app.user.uid, 10)) { + if (!ajaxify.data.privileges.isAdminOrMod && parseInt(data.uid, 10) !== parseInt(app.user.uid, 10)) { postEl.find('[component="post/tools"]').toggleClass('hidden', isDeleted); if (isDeleted) { postEl.find('[component="post/content"]').translateHtml('[[topic:post_is_deleted]]'); diff --git a/public/src/client/topic/fork.js b/public/src/client/topic/fork.js index feb02a9f78..ca30f157b0 100644 --- a/public/src/client/topic/fork.js +++ b/public/src/client/topic/fork.js @@ -1,20 +1,26 @@ 'use strict'; -/* globals define, app, ajaxify, socket, templates, translator */ +/* globals define, app, ajaxify, socket */ define('forum/topic/fork', ['components', 'postSelect'], function(components, postSelect) { - var Fork = {}, - forkModal, - forkCommit; + var Fork = {}; + var forkModal; + var forkCommit; Fork.init = function() { $('.topic').on('click', '[component="topic/fork"]', onForkThreadClicked); + $(window).on('action:ajaxify.start', onAjaxifyStart); }; + function onAjaxifyStart() { + closeForkModal(); + $(window).off('action:ajaxify.start', onAjaxifyStart); + } + function onForkThreadClicked() { - parseModal(function(html) { - forkModal = $(html); + app.parseAndTranslate('partials/fork_thread_modal', {}, function(html) { + forkModal = html; forkCommit = forkModal.find('#fork_thread_commit'); @@ -33,12 +39,6 @@ define('forum/topic/fork', ['components', 'postSelect'], function(components, po }); } - function parseModal(callback) { - templates.parse('partials/fork_thread_modal', {}, function(html) { - translator.translate(html, callback); - }); - } - function createTopicFromPosts() { forkCommit.attr('disabled', true); socket.emit('topics.createTopicFromPosts', { @@ -95,7 +95,10 @@ define('forum/topic/fork', ['components', 'postSelect'], function(components, po components.get('post', 'pid', pid).toggleClass('bg-success', false); }); - forkModal.remove(); + if (forkModal) { + forkModal.remove(); + forkModal = null; + } components.get('topic').off('click', '[data-pid]'); postSelect.enableClicksOnPosts(); diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index 41aa3d4ca4..85a8986a4b 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -35,7 +35,7 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator socket.emit('posts.loadPostTools', {pid: pid, cid: ajaxify.data.cid}, function(err, data) { if (err) { - return app.alertError(err); + return app.alertError(err.message); } data.posts.display_move_tools = data.posts.display_move_tools && index !== 0; @@ -384,11 +384,11 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator className: 'vote-modal', show: true }); - + dialog.on('click', function() { dialog.modal('hide'); }); - + }); }); }); diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index c656b899a2..656364b3a1 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -27,9 +27,11 @@ define('forum/topic/posts', [ data.privileges = ajaxify.data.privileges; data.posts.forEach(function(post) { post.selfPost = !!app.user.uid && parseInt(post.uid, 10) === parseInt(app.user.uid, 10); - post.display_moderator_tools = post.selfPost || ajaxify.data.privileges.isAdminOrMod; + post.display_edit_tools = (ajaxify.data.privileges['posts:edit'] && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; + post.display_delete_tools = (ajaxify.data.privileges['posts:delete'] && post.selfPost) || ajaxify.data.privileges.isAdminOrMod; + post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; post.display_move_tools = ajaxify.data.privileges.isAdminOrMod; - post.display_post_menu = ajaxify.data.privileges.isAdminOrMod || post.selfPost || ((app.user.uid || ajaxify.data.postSharing.length) && !post.deleted); + post.display_post_menu = ajaxify.data.privileges.isAdminOrMod || (post.selfPost && !ajaxify.data.locked) || ((app.user.uid || ajaxify.data.postSharing.length) && !post.deleted); }); updatePostCounts(data.posts); diff --git a/public/src/client/topic/threadTools.js b/public/src/client/topic/threadTools.js index 3110b92a4d..a18c069cd5 100644 --- a/public/src/client/topic/threadTools.js +++ b/public/src/client/topic/threadTools.js @@ -173,15 +173,24 @@ define('forum/topic/threadTools', [ return; } - var isLocked = data.isLocked && !app.user.isAdmin; + var isLocked = data.isLocked && !ajaxify.data.privileges.isAdminOrMod; components.get('topic/lock').toggleClass('hidden', data.isLocked); components.get('topic/unlock').toggleClass('hidden', !data.isLocked); - components.get('topic/reply/container').toggleClass('hidden', isLocked); - components.get('topic/reply/locked').toggleClass('hidden', !isLocked); - threadEl.find('[component="post/reply"], [component="post/quote"], [component="post/edit"], [component="post/delete"]').toggleClass('hidden', isLocked); + var hideReply = (data.isLocked || ajaxify.data.deleted) && !ajaxify.data.privileges.isAdminOrMod; + + components.get('topic/reply/container').toggleClass('hidden', hideReply); + components.get('topic/reply/locked').toggleClass('hidden', ajaxify.data.privileges.isAdminOrMod || !data.isLocked || ajaxify.data.deleted); + + threadEl.find('[component="post"]:not(.deleted) [component="post/reply"], [component="post"]:not(.deleted) [component="post/quote"]').toggleClass('hidden', hideReply); + threadEl.find('[component="post/edit"], [component="post/delete"]').toggleClass('hidden', isLocked); + + threadEl.find('[component="post"][data-uid="'+app.user.uid+'"].deleted [component="post/tools"]').toggleClass('hidden', isLocked); + $('[component="post/header"] i.fa-lock').toggleClass('hidden', !data.isLocked); + $('[component="post/tools"] .dropdown-menu').html(''); + ajaxify.data.locked = data.isLocked; }; ThreadTools.setDeleteState = function(data) { @@ -195,9 +204,17 @@ define('forum/topic/threadTools', [ components.get('topic/purge').toggleClass('hidden', !data.isDelete); components.get('topic/deleted/message').toggleClass('hidden', !data.isDelete); + var hideReply = data.isDelete && !ajaxify.data.privileges.isAdminOrMod; + + components.get('topic/reply/container').toggleClass('hidden', hideReply); + components.get('topic/reply/locked').toggleClass('hidden', ajaxify.data.privileges.isAdminOrMod || !ajaxify.data.locked || data.isDelete); + threadEl.find('[component="post"]:not(.deleted) [component="post/reply"], [component="post"]:not(.deleted) [component="post/quote"]').toggleClass('hidden', hideReply); + threadEl.toggleClass('deleted', data.isDelete); + ajaxify.data.deleted = data.isDelete; }; + ThreadTools.setPinnedState = function(data) { var threadEl = components.get('topic'); if (parseInt(data.tid, 10) !== parseInt(threadEl.attr('data-tid'), 10)) { @@ -207,6 +224,7 @@ define('forum/topic/threadTools', [ components.get('topic/pin').toggleClass('hidden', data.isPinned); components.get('topic/unpin').toggleClass('hidden', !data.isPinned); $('[component="post/header"] i.fa-thumb-tack').toggleClass('hidden', !data.isPinned); + ajaxify.data.pinned = data.isPinned; }; function setFollowState(state) { diff --git a/public/src/installer/install.js b/public/src/installer/install.js index f7224fb71a..d2e5b64fc8 100644 --- a/public/src/installer/install.js +++ b/public/src/installer/install.js @@ -44,7 +44,7 @@ $('document').ready(function() { if ($('form .admin .error').length) { ev.preventDefault(); $('html, body').animate({'scrollTop': '0px'}, 400); - + return false; } else { $('#submit .fa-spin').removeClass('hide'); @@ -69,6 +69,9 @@ $('document').ready(function() { if (!utils.isPasswordValid(field)) { parent.addClass('error'); help.html('Invalid Password.'); + } else if (field.length < $('[name="admin:password"]').attr('data-minimum-length')) { + parent.addClass('error'); + help.html('Password is too short.'); } else { parent.removeClass('error'); } diff --git a/src/categories/create.js b/src/categories/create.js index 6e13d8689d..e2d6960e45 100644 --- a/src/categories/create.js +++ b/src/categories/create.js @@ -49,7 +49,7 @@ module.exports = function(Categories) { function(data, next) { category = data.category; - var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'upload:post:image']; + var defaultPrivileges = ['find', 'read', 'topics:read', 'topics:create', 'topics:reply', 'posts:edit', 'posts:delete', 'topics:delete', 'upload:post:image']; async.series([ async.apply(db.setObject, 'category:' + category.cid, category), diff --git a/src/controllers/accounts/info.js b/src/controllers/accounts/info.js index 6662c60cd6..1117cb28c1 100644 --- a/src/controllers/accounts/info.js +++ b/src/controllers/accounts/info.js @@ -1,22 +1,30 @@ 'use strict'; -var async = require('async'), - _ = require('underscore'), +var async = require('async'); +var _ = require('underscore'); - user = require('../../user'), - helpers = require('../helpers'), - accountHelpers = require('./helpers'); +var user = require('../../user'); +var helpers = require('../helpers'); +var accountHelpers = require('./helpers'); var infoController = {}; infoController.get = function(req, res, next) { accountHelpers.getBaseUser(req.params.userslug, req.uid, function(err, userData) { + if (err) { + return next(err); + } + async.parallel({ ips: async.apply(user.getIPs, res.locals.uid, 4), history: async.apply(user.getModerationHistory, res.locals.uid), fields: async.apply(user.getUserFields, res.locals.uid, ['banned']) }, function(err, data) { - data = _.extend(userData, { + if (err) { + return next(err); + } + + userData = _.extend(userData, { ips: data.ips, history: data.history }, data.fields); @@ -24,7 +32,7 @@ infoController.get = function(req, res, next) { userData.title = '[[pages:account/info]]'; userData.breadcrumbs = helpers.buildBreadcrumbs([{text: userData.username, url: '/user/' + userData.userslug}, {text: '[[user:settings]]'}]); - res.render('account/info', data); + res.render('account/info', userData); }); }); }; diff --git a/src/controllers/accounts/settings.js b/src/controllers/accounts/settings.js index 483a7e5eb1..9efa8ebe6b 100644 --- a/src/controllers/accounts/settings.js +++ b/src/controllers/accounts/settings.js @@ -32,9 +32,6 @@ settingsController.get = function(req, res, callback) { settings: function(next) { user.getSettings(userData.uid, next); }, - userGroups: function(next) { - groups.getUserGroupsFromSet('groups:createtime', [userData.uid], next); - }, languages: function(next) { languages.list(next); }, @@ -49,9 +46,6 @@ settingsController.get = function(req, res, callback) { }, function(results, next) { userData.settings = results.settings; - userData.userGroups = results.userGroups[0].filter(function(group) { - return group && group.userTitleEnabled && !groups.isPrivilegeGroup(group.name) && group.name !== 'registered-users'; - }); userData.languages = results.languages; userData.homePageRoutes = results.homePageRoutes; userData.ips = results.ips; @@ -118,10 +112,6 @@ settingsController.get = function(req, res, callback) { skin.selected = skin.value === userData.settings.bootswatchSkin; }); - userData.userGroups.forEach(function(group) { - group.selected = group.name === userData.settings.groupTitle; - }); - userData.languages.forEach(function(language) { language.selected = language.code === userData.settings.userLang; }); diff --git a/src/controllers/admin/dashboard.js b/src/controllers/admin/dashboard.js index 24a65983f1..84ee4fd3d0 100644 --- a/src/controllers/admin/dashboard.js +++ b/src/controllers/admin/dashboard.js @@ -19,8 +19,8 @@ dashboardController.get = function(req, res, next) { var notices = [ { done: !meta.reloadRequired, - doneText: 'Reload not required', - notDoneText:'Reload required' + doneText: 'Restart not required', + notDoneText:'Restart required' }, { done: plugins.hasListeners('filter:search.query'), diff --git a/src/controllers/index.js b/src/controllers/index.js index bd6daa6581..4ad3d5ab0a 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -8,7 +8,6 @@ var winston = require('winston'); var meta = require('../meta'); var user = require('../user'); var plugins = require('../plugins'); -var sitemap = require('../sitemap'); var helpers = require('./helpers'); var Controllers = { @@ -27,7 +26,8 @@ var Controllers = { authentication: require('./authentication'), api: require('./api'), admin: require('./admin'), - globalMods: require('./globalmods') + globalMods: require('./globalmods'), + sitemap: require('./sitemap') }; @@ -251,65 +251,6 @@ Controllers.confirmEmail = function(req, res) { }); }; -Controllers.sitemap = {}; -Controllers.sitemap.render = function(req, res, next) { - sitemap.render(function(err, tplData) { - if (err) { - return next(err); - } - - Controllers.render('sitemap', tplData, function(err, xml) { - res.header('Content-Type', 'application/xml'); - res.send(xml); - }); - }); -}; - -Controllers.sitemap.getPages = function(req, res, next) { - if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { - return next(); - } - - sitemap.getPages(function(err, xml) { - if (err) { - return next(err); - } - res.header('Content-Type', 'application/xml'); - res.send(xml); - }); -}; - -Controllers.sitemap.getCategories = function(req, res, next) { - if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { - return next(); - } - - sitemap.getCategories(function(err, xml) { - if (err) { - return next(err); - } - res.header('Content-Type', 'application/xml'); - res.send(xml); - }); -}; - -Controllers.sitemap.getTopicPage = function(req, res, next) { - if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { - return next(); - } - - sitemap.getTopicPage(parseInt(req.params[0], 10), function(err, xml) { - if (err) { - return next(err); - } else if (!xml) { - return next(); - } - - res.header('Content-Type', 'application/xml'); - res.send(xml); - }); -}; - Controllers.robots = function (req, res) { res.set('Content-Type', 'text/plain'); diff --git a/src/controllers/sitemap.js b/src/controllers/sitemap.js new file mode 100644 index 0000000000..eee344fc92 --- /dev/null +++ b/src/controllers/sitemap.js @@ -0,0 +1,68 @@ +'use strict'; + +var sitemap = require('../sitemap'); +var meta = require('../meta'); + +var sitemapController = {}; +sitemapController.render = function(req, res, next) { + sitemap.render(function(err, tplData) { + if (err) { + return next(err); + } + var Controllers = require('./index'); + Controllers.render('sitemap', tplData, function(err, xml) { + if (err) { + return next(err); + } + res.header('Content-Type', 'application/xml'); + res.send(xml); + }); + }); +}; + +sitemapController.getPages = function(req, res, next) { + if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { + return next(); + } + + sitemap.getPages(function(err, xml) { + if (err) { + return next(err); + } + res.header('Content-Type', 'application/xml'); + res.send(xml); + }); +}; + +sitemapController.getCategories = function(req, res, next) { + if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { + return next(); + } + + sitemap.getCategories(function(err, xml) { + if (err) { + return next(err); + } + res.header('Content-Type', 'application/xml'); + res.send(xml); + }); +}; + +sitemapController.getTopicPage = function(req, res, next) { + if (parseInt(meta.config['feeds:disableSitemap'], 10) === 1) { + return next(); + } + + sitemap.getTopicPage(parseInt(req.params[0], 10), function(err, xml) { + if (err) { + return next(err); + } else if (!xml) { + return next(); + } + + res.header('Content-Type', 'application/xml'); + res.send(xml); + }); +}; + +module.exports = sitemapController; \ No newline at end of file diff --git a/src/database/mongo/sorted.js b/src/database/mongo/sorted.js index 9e9f72969e..1f9a67adb1 100644 --- a/src/database/mongo/sorted.js +++ b/src/database/mongo/sorted.js @@ -595,4 +595,82 @@ module.exports = function(db, module) { callback ); }; + + + module.getSortedSetIntersect = function(params, callback) { + params.sort = 1; + getSortedSetRevIntersect(params, callback); + }; + + module.getSortedSetRevIntersect = function(params, callback) { + params.sort = -1; + getSortedSetRevIntersect(params, callback); + }; + + function getSortedSetRevIntersect (params, callback) { + var sets = params.sets; + var start = params.hasOwnProperty('start') ? params.start : 0; + var stop = params.hasOwnProperty('stop') ? params.stop : -1; + var weights = params.weights || []; + var aggregate = {}; + + if (params.aggregate) { + aggregate['$' + params.aggregate.toLowerCase()] = '$score'; + } else { + aggregate.$sum = '$score'; + } + + var limit = stop - start + 1; + if (limit <= 0) { + limit = 0; + } + + var pipeline = [{ $match: { _key: {$in: sets}} }]; + + weights.forEach(function(weight, index) { + if (weight !== 1) { + pipeline.push({ + $project: { + value: 1, + score: { + $cond: { if: { $eq: [ "$_key", sets[index] ] }, then: { $multiply: [ '$score', weight ] }, else: '$score' } + } + } + }); + } + }); + + pipeline.push({ $group: { _id: {value: '$value'}, totalScore: aggregate, count: {$sum: 1}} }); + pipeline.push({ $match: { count: sets.length} }); + pipeline.push({ $sort: { totalScore: params.sort} }); + + if (start) { + pipeline.push({ $skip: start }); + } + + if (limit > 0) { + pipeline.push({ $limit: limit }); + } + + var project = { _id: 0, value: '$_id.value'}; + if (params.withScores) { + project.score = '$totalScore'; + } + pipeline.push({ $project: project }); + + db.collection('objects').aggregate(pipeline, function(err, data) { + if (err || !data) { + return callback(err); + } + + if (!params.withScores) { + data = data.map(function(item) { + return item.value; + }); + } + + callback(null, data); + }); + } + }; diff --git a/src/database/redis/sorted.js b/src/database/redis/sorted.js index 0341c043f7..eaa3b2430f 100644 --- a/src/database/redis/sorted.js +++ b/src/database/redis/sorted.js @@ -29,7 +29,7 @@ module.exports = function(redisClient, module) { args.push(scores[i], values[i]); } - redisClient.zadd(args, function(err, res) { + redisClient.zadd(args, function(err) { callback(err); }); } @@ -42,7 +42,7 @@ module.exports = function(redisClient, module) { multi.zadd(keys[i], score, value); } - multi.exec(function(err, res) { + multi.exec(function(err) { callback(err); }); }; @@ -53,13 +53,13 @@ module.exports = function(redisClient, module) { value = [value]; } - helpers.multiKeyValues(redisClient, 'zrem', key, value, function(err, result) { + helpers.multiKeyValues(redisClient, 'zrem', key, value, function(err) { callback(err); }); }; module.sortedSetsRemove = function(keys, value, callback) { - helpers.multiKeysValue(redisClient, 'zrem', keys, value, function(err, result) { + helpers.multiKeysValue(redisClient, 'zrem', keys, value, function(err) { callback(err); }); }; @@ -70,7 +70,7 @@ module.exports = function(redisClient, module) { for(var i=0; i (parseInt(meta.config.maximumGroupNameLength, 10) || 255)) { + if (!Groups.isPrivilegeGroup(name) && name.length > (parseInt(meta.config.maximumGroupNameLength, 10) || 255)) { return callback(new Error('[[error:group-name-too-long]]')); } diff --git a/src/meta.js b/src/meta.js index 1cbd1af0ae..8dfbc0d99a 100644 --- a/src/meta.js +++ b/src/meta.js @@ -41,50 +41,14 @@ var async = require('async'), }); }; + /** + * Reload deprecated as of v1.1.2+, remove in v2.x + */ Meta.reload = function(callback) { - pubsub.publish('meta:reload', {hostname: os.hostname()}); - reload(callback); + restart(); + callback(); }; - pubsub.on('meta:reload', function(data) { - if (data.hostname !== os.hostname()) { - reload(); - } - }); - - function reload(callback) { - callback = callback || function() {}; - - var plugins = require('./plugins'); - async.series([ - function (next) { - plugins.fireHook('static:app.reload', {}, next); - }, - async.apply(plugins.clearRequireCache), - async.apply(Meta.css.minify), - async.apply(Meta.js.minify, 'nodebb.min.js'), - async.apply(Meta.js.minify, 'acp.min.js'), - async.apply(Meta.sounds.init), - async.apply(languages.init), - async.apply(Meta.templates.compile), - async.apply(plugins.reload), - async.apply(plugins.reloadRoutes), - async.apply(auth.reloadRoutes), - function(next) { - Meta.config['cache-buster'] = utils.generateUUID(); - templates.flush(); - next(); - } - ], function(err) { - if (!err) { - emitter.emit('nodebb:ready'); - } - Meta.reloadRequired = false; - - callback(err); - }); - } - Meta.restart = function() { pubsub.publish('meta:restart', {hostname: os.hostname()}); restart(); diff --git a/src/meta/themes.js b/src/meta/themes.js index c3d912a222..ed6b061db9 100644 --- a/src/meta/themes.js +++ b/src/meta/themes.js @@ -161,6 +161,4 @@ module.exports = function(Meta) { nconf.set('theme_templates_path', themePath); nconf.set('theme_config', path.join(nconf.get('themes_path'), themeObj.id, 'theme.json')); }; - - }; \ No newline at end of file diff --git a/src/plugins/load.js b/src/plugins/load.js index a70fce41ab..70aea70ccd 100644 --- a/src/plugins/load.js +++ b/src/plugins/load.js @@ -153,22 +153,22 @@ module.exports = function(Plugins) { } Plugins.clientScripts = Plugins.clientScripts.concat(pluginData.scripts.map(function(file) { - return path.join(__dirname, '../../node_modules/', pluginData.id, file); - })); + return resolveModulePath(path.join(__dirname, '../../node_modules/', pluginData.id, file), file); + })).filter(Boolean); } if (Array.isArray(pluginData.acpScripts)) { if (global.env === 'development') { - winston.verbose('[plugins] Found ' + pluginData.acpScripts.length + ' js file(s) for plugin ' + pluginData.id); + winston.verbose('[plugins] Found ' + pluginData.acpScripts.length + ' ACP js file(s) for plugin ' + pluginData.id); } Plugins.acpScripts = Plugins.acpScripts.concat(pluginData.acpScripts.map(function(file) { - return path.join(__dirname, '../../node_modules/', pluginData.id, file); - })); + return resolveModulePath(path.join(__dirname, '../../node_modules/', pluginData.id, file), file); + })).filter(Boolean); } callback(); - }; + } function mapClientModules(pluginData, callback) { if (!pluginData.hasOwnProperty('modules')) { @@ -201,14 +201,16 @@ module.exports = function(Plugins) { } for (var name in pluginData.modules) { - modules[name] = path.join('./node_modules/', pluginData.id, pluginData.modules[name]); + if (pluginData.modules.hasOwnProperty(name)) { + modules[name] = path.join('./node_modules/', pluginData.id, pluginData.modules[name]); + } } meta.js.scripts.modules = _.extend(meta.js.scripts.modules, modules); } callback(); - }; + } function loadLanguages(pluginData, callback) { if (typeof pluginData.languages !== 'string') { @@ -265,6 +267,30 @@ module.exports = function(Plugins) { }); } + function resolveModulePath(fullPath, relPath) { + /** + * With npm@3, dependencies can become flattened, and appear at the root level. + * This method resolves these differences if it can. + */ + var atRootLevel = fullPath.match(/node_modules/g).length === 1; + + try { + fs.statSync(fullPath); + winston.verbose('[plugins/load] File found: ' + fullPath); + return fullPath; + } catch (e) { + // File not visible to the calling process, ascend to root level if possible and try again + if (!atRootLevel && relPath) { + winston.verbose('[plugins/load] File not found: ' + fullPath + ' (Ascending)'); + return resolveModulePath(path.join(__dirname, '../..', relPath)); + } else { + // Already at root level, file was simply not found + winston.warn('[plugins/load] File not found: ' + fullPath + ' (Ignoring)'); + return null; + } + } + } + Plugins.loadPluginInfo = function(pluginPath, callback) { async.parallel({ package: function(next) { diff --git a/src/posts/edit.js b/src/posts/edit.js index e8af9ae2d4..e1df94aa9f 100644 --- a/src/posts/edit.js +++ b/src/posts/edit.js @@ -28,8 +28,8 @@ module.exports = function(Posts) { privileges.posts.canEdit(data.pid, data.uid, next); }, function (canEdit, next) { - if (!canEdit) { - return next(new Error('[[error:no-privileges]]')); + if (!canEdit.flag) { + return next(new Error(canEdit.message)); } Posts.getPostData(data.pid, next); }, diff --git a/src/posts/tools.js b/src/posts/tools.js index 40d150d049..e2573554e8 100644 --- a/src/posts/tools.js +++ b/src/posts/tools.js @@ -37,8 +37,8 @@ module.exports = function(Posts) { privileges.posts.canDelete(pid, uid, next); }, function (canDelete, next) { - if (!canDelete) { - return next(new Error('[[error:no-privileges]]')); + if (!canDelete.flag) { + return next(new Error(canDelete.message)); } if (isDelete) { diff --git a/src/privileges.js b/src/privileges.js index 1f28a7cb91..34b6e6fb69 100644 --- a/src/privileges.js +++ b/src/privileges.js @@ -8,6 +8,9 @@ privileges.userPrivilegeList = [ 'topics:read', 'topics:create', 'topics:reply', + 'posts:edit', + 'posts:delete', + 'topics:delete', 'upload:post:image', 'upload:post:file', 'purge', @@ -20,6 +23,9 @@ privileges.groupPrivilegeList = [ 'groups:topics:read', 'groups:topics:create', 'groups:topics:reply', + 'groups:posts:edit', + 'groups:posts:delete', + 'groups:topics:delete', 'groups:upload:post:image', 'groups:upload:post:file', 'groups:purge', @@ -33,4 +39,4 @@ require('./privileges/topics')(privileges); require('./privileges/posts')(privileges); require('./privileges/users')(privileges); -module.exports = privileges; \ No newline at end of file +module.exports = privileges; diff --git a/src/privileges/categories.js b/src/privileges/categories.js index ce2c30506e..0baf08af91 100644 --- a/src/privileges/categories.js +++ b/src/privileges/categories.js @@ -23,6 +23,9 @@ module.exports = function(privileges) { {name: 'Access Topics'}, {name: 'Create Topics'}, {name: 'Reply to Topics'}, + {name: 'Edit Posts'}, + {name: 'Delete Posts'}, + {name: 'Delete Topics'}, {name: 'Upload Images'}, {name: 'Upload Files'}, {name: 'Purge'}, @@ -362,6 +365,15 @@ module.exports = function(privileges) { 'topics:reply': function(next) { groups.isMember(uid, 'cid:' + cid + ':privileges:topics:reply', next); }, + 'posts:edit': function(next) { + groups.isMember(uid, 'cid:' + cid + ':privileges:posts:edit', next); + }, + 'posts:delete': function(next) { + groups.isMember(uid, 'cid:' + cid + ':privileges:posts:delete', next); + }, + 'topics:delete': function(next) { + groups.isMember(uid, 'cid:' + cid + ':privileges:topics:delete', next); + }, mods: function(next) { user.isModerator(uid, cid, next); } @@ -380,6 +392,15 @@ module.exports = function(privileges) { 'groups:topics:reply': function(next) { groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:reply', next); }, + 'groups:posts:edit': function(next) { + groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:posts:edit', next); + }, + 'groups:posts:delete': function(next) { + groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:posts:delete', next); + }, + 'groups:topics:delete': function(next) { + groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:delete', next); + }, 'groups:topics:read': function(next) { groups.isMember(groupName, 'cid:' + cid + ':privileges:groups:topics:read', next); } diff --git a/src/privileges/posts.js b/src/privileges/posts.js index a0d06f3600..8ebf9e4bcb 100644 --- a/src/privileges/posts.js +++ b/src/privileges/posts.js @@ -30,6 +30,7 @@ module.exports = function(privileges) { isOwner: async.apply(posts.isOwner, pids, uid), 'topics:read': async.apply(helpers.isUserAllowedTo, 'topics:read', uid, cids), read: async.apply(helpers.isUserAllowedTo, 'read', uid, cids), + 'posts:edit': async.apply(helpers.isUserAllowedTo, 'posts:edit', uid, cids), }, next); } ], function(err, results) { @@ -41,7 +42,7 @@ module.exports = function(privileges) { for (var i=0; i postDeleteDuration * 1000)) { - return callback(new Error('[[error:post-delete-duration-expired, ' + meta.config.postDeleteDuration + ']]')); + return callback(null, {flag: false, message: '[[error:post-delete-duration-expired, ' + meta.config.postDeleteDuration + ']]'}); } - callback(null, results.isOwner); + + callback(null, {flag: results.isOwner, message: '[[error:no-privileges]]'}); }); }; @@ -218,26 +223,31 @@ module.exports = function(privileges) { }; function isPostEditable(pid, uid, callback) { + var tid; async.waterfall([ function(next) { posts.getPostFields(pid, ['tid', 'timestamp'], next); }, function(postData, next) { + tid = postData.tid; var postEditDuration = parseInt(meta.config.postEditDuration, 10); if (postEditDuration && Date.now() - parseInt(postData.timestamp, 10) > postEditDuration * 1000) { - return callback(null, {isEditExpired: true}); + return callback(null, {flag: false, message: '[[error:post-edit-duration-expired, ' + meta.config.postEditDuration + ']]'}); } topics.isLocked(postData.tid, next); }, function(isLocked, next) { if (isLocked) { - return callback(null, {isLocked: true}); + return callback(null, {flag: false, message: '[[error:topic-locked]]'}); } - posts.isOwner(pid, uid, next); + async.parallel({ + owner: async.apply(posts.isOwner, pid, uid), + edit: async.apply(privileges.posts.can, 'posts:edit', pid, uid) + }, next); }, - function(isOwner, next) { - next(null, {editable: isOwner}); + function(result, next) { + next(null, {flag: result.owner && result.edit, message: '[[error:no-privileges]]'}); } ], callback); } diff --git a/src/privileges/topics.js b/src/privileges/topics.js index d1c8958045..b6fffb8a6a 100644 --- a/src/privileges/topics.js +++ b/src/privileges/topics.js @@ -3,6 +3,7 @@ var async = require('async'); +var meta = require('../meta'); var topics = require('../topics'); var user = require('../user'); var helpers = require('./helpers'); @@ -16,12 +17,15 @@ module.exports = function(privileges) { privileges.topics.get = function(tid, uid, callback) { var topic; async.waterfall([ - async.apply(topics.getTopicFields, tid, ['cid', 'uid', 'locked']), + async.apply(topics.getTopicFields, tid, ['cid', 'uid', 'locked', 'deleted']), function(_topic, next) { topic = _topic; async.parallel({ 'topics:reply': async.apply(helpers.isUserAllowedTo, 'topics:reply', uid, [topic.cid]), 'topics:read': async.apply(helpers.isUserAllowedTo, 'topics:read', uid, [topic.cid]), + 'topics:delete': async.apply(helpers.isUserAllowedTo, 'topics:delete', uid, [topic.cid]), + 'posts:edit': async.apply(helpers.isUserAllowedTo, 'posts:edit', uid, [topic.cid]), + 'posts:delete': async.apply(helpers.isUserAllowedTo, 'posts:delete', uid, [topic.cid]), read: async.apply(helpers.isUserAllowedTo, 'read', uid, [topic.cid]), isOwner: function(next) { next(null, !!parseInt(uid, 10) && parseInt(uid, 10) === parseInt(topic.uid, 10)); @@ -38,14 +42,19 @@ module.exports = function(privileges) { var disabled = parseInt(results.disabled, 10) === 1; var locked = parseInt(topic.locked, 10) === 1; + var deleted = parseInt(topic.deleted, 10) === 1; + var isAdminOrMod = results.isAdministrator || results.isModerator; var editable = isAdminOrMod; - var deletable = isAdminOrMod || results.isOwner; + var deletable = isAdminOrMod || (results.isOwner && results['topics:delete'][0]); plugins.fireHook('filter:privileges.topics.get', { - 'topics:reply': (results['topics:reply'][0] && !locked) || isAdminOrMod, - read: results.read[0] || isAdminOrMod, + 'topics:reply': (results['topics:reply'][0] && !locked && !deleted) || isAdminOrMod, 'topics:read': results['topics:read'][0] || isAdminOrMod, + 'topics:delete': (results.isOwner && results['topics:delete'][0]) || isAdminOrMod, + 'posts:edit': (results['posts:edit'][0] && !locked) || isAdminOrMod, + 'posts:delete': (results['posts:delete'][0] && !locked) || isAdminOrMod, + read: results.read[0] || isAdminOrMod, view_thread_tools: editable || deletable, editable: editable, deletable: deletable, @@ -176,6 +185,46 @@ module.exports = function(privileges) { ], callback); }; + privileges.topics.canDelete = function(tid, uid, callback) { + var topicData; + async.waterfall([ + function(next) { + topics.getTopicFields(tid, ['cid', 'postcount'], next); + }, + function(_topicData, next) { + topicData = _topicData; + async.parallel({ + isModerator: async.apply(user.isModerator, uid, topicData.cid), + isAdministrator: async.apply(user.isAdministrator, uid), + isOwner: async.apply(topics.isOwner, tid, uid), + 'topics:delete': async.apply(helpers.isUserAllowedTo, 'topics:delete', uid, [topicData.cid]) + }, next); + } + ], function(err, results) { + if (err) { + return callback(err); + } + + if (results.isModerator || results.isAdministrator) { + return callback(null, true); + } + + var preventTopicDeleteAfterReplies = parseInt(meta.config.preventTopicDeleteAfterReplies, 10) || 0; + if (preventTopicDeleteAfterReplies && (topicData.postcount - 1) >= preventTopicDeleteAfterReplies) { + var langKey = preventTopicDeleteAfterReplies > 1 ? + '[[error:cant-delete-topic-has-replies, ' + meta.config.preventTopicDeleteAfterReplies + ']]': + '[[error:cant-delete-topic-has-reply]]'; + return callback(new Error(langKey)); + } + + if (!results['topics:delete'][0]) { + return callback(null, false); + } + + callback(null, results.isOwner); + }); + }; + privileges.topics.canEdit = function(tid, uid, callback) { privileges.topics.isOwnerOrAdminOrMod(tid, uid, callback); }; diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index a290238e21..556eee0290 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -49,21 +49,10 @@ SocketAdmin.before = function(socket, method, data, next) { }); }; -SocketAdmin.reload = function(socket, data, callback) { - events.log({ - type: 'reload', - uid: socket.uid, - ip: socket.ip - }); - if (process.send) { - process.send({ - action: 'reload' - }); - callback(); - } else { - meta.reload(callback); - } -}; +/** + * Reload deprecated as of v1.1.2+, remove in v2.x + */ +SocketAdmin.reload = SocketAdmin.restart; SocketAdmin.restart = function(socket, data, callback) { events.log({ diff --git a/src/socket.io/admin/categories.js b/src/socket.io/admin/categories.js index 8e24359e7a..ff2f8400b0 100644 --- a/src/socket.io/admin/categories.js +++ b/src/socket.io/admin/categories.js @@ -54,7 +54,7 @@ Categories.update = function(socket, data, callback) { }; Categories.setPrivilege = function(socket, data, callback) { - if(!data) { + if (!data) { return callback(new Error('[[error:invalid-data]]')); } @@ -72,7 +72,7 @@ Categories.getPrivilegeSettings = function(socket, cid, callback) { }; Categories.copyPrivilegesToChildren = function(socket, cid, callback) { - categories.getCategories([cid], socket.uid, function(err, categories) { + categories.getCategories([cid], socket.uid, function(err, categories) { if (err) { return callback(err); } diff --git a/src/socket.io/admin/groups.js b/src/socket.io/admin/groups.js index c912008210..0088fbc5c8 100644 --- a/src/socket.io/admin/groups.js +++ b/src/socket.io/admin/groups.js @@ -1,8 +1,9 @@ "use strict"; var async = require('async'); -var groups = require('../../groups'), - Groups = {}; +var groups = require('../../groups'); + +var Groups = {}; Groups.create = function(socket, data, callback) { if (!data) { diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index ed7b4b378d..3fd69a8d10 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -142,7 +142,19 @@ User.sendPasswordResetEmail = function(socket, uids, callback) { }; User.deleteUsers = function(socket, uids, callback) { - if(!Array.isArray(uids)) { + deleteUsers(socket, uids, function(uid, next) { + user.deleteAccount(uid, next); + }, callback); +}; + +User.deleteUsersAndContent = function(socket, uids, callback) { + deleteUsers(socket, uids, function(uid, next) { + user.delete(socket.uid, uid, next); + }, callback); +}; + +function deleteUsers(socket, uids, method, callback) { + if (!Array.isArray(uids)) { return callback(new Error('[[error:invalid-data]]')); } @@ -156,7 +168,7 @@ User.deleteUsers = function(socket, uids, callback) { return next(new Error('[[error:cant-delete-other-admins]]')); } - user.delete(socket.uid, uid, next); + method(uid, next); }, function (next) { events.log({ @@ -169,7 +181,7 @@ User.deleteUsers = function(socket, uids, callback) { } ], next); }, callback); -}; +} User.search = function(socket, data, callback) { user.search({query: data.query, searchBy: data.searchBy, uid: socket.uid}, function(err, searchData) { diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index 4e48a9649b..5df97f80f5 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -5,6 +5,7 @@ var async = require('async'), groups = require('../groups'), meta = require('../meta'), user = require('../user'), + utils = require('../../public/src/utils'), groupsController = require('../controllers/groups'), SocketGroups = {}; @@ -216,12 +217,12 @@ SocketGroups.search = function(socket, data, callback) { }; SocketGroups.loadMore = function(socket, data, callback) { - if (!data.sort || !data.after) { + if (!data.sort || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { return callback(); } var groupsPerPage = 9; - var start = parseInt(data.after); + var start = parseInt(data.after, 10); var stop = start + groupsPerPage - 1; groupsController.getGroupsFromSet(socket.uid, data.sort, start, stop, callback); }; @@ -232,7 +233,7 @@ SocketGroups.searchMembers = function(socket, data, callback) { }; SocketGroups.loadMoreMembers = function(socket, data, callback) { - if (!data.groupName || !parseInt(data.after, 10)) { + if (!data.groupName || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { return callback(new Error('[[error:invalid-data]]')); } data.after = parseInt(data.after, 10); diff --git a/src/socket.io/posts/tools.js b/src/socket.io/posts/tools.js index bcb7e59642..91e8dca241 100644 --- a/src/socket.io/posts/tools.js +++ b/src/socket.io/posts/tools.js @@ -28,6 +28,12 @@ module.exports = function(SocketPosts) { isAdminOrMod: function(next) { privileges.categories.isAdminOrMod(data.cid, socket.uid, next); }, + canEdit: function(next) { + privileges.posts.canEdit(data.pid, socket.uid, next); + }, + canDelete: function(next) { + privileges.posts.canDelete(data.pid, socket.uid, next); + }, favourited: function(next) { favourites.getFavouritesByPostIDs([data.pid], socket.uid, next); }, @@ -41,11 +47,14 @@ module.exports = function(SocketPosts) { if (err) { return callback(err); } + results.posts.tools = results.tools.tools; results.posts.deleted = parseInt(results.posts.deleted, 10) === 1; results.posts.favourited = results.favourited[0]; results.posts.selfPost = socket.uid && socket.uid === parseInt(results.posts.uid, 10); - results.posts.display_moderator_tools = results.isAdminOrMod || results.posts.selfPost; + results.posts.display_edit_tools = results.canEdit.flag; + results.posts.display_delete_tools = results.canDelete.flag; + results.posts.display_moderator_tools = results.posts.display_edit_tools || results.posts.display_delete_tools; results.posts.display_move_tools = results.isAdminOrMod; callback(null, results); }); @@ -165,4 +174,4 @@ module.exports = function(SocketPosts) { }, callback); } -}; \ No newline at end of file +}; diff --git a/src/socket.io/user.js b/src/socket.io/user.js index c38bcc5bbf..44c17ea476 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -1,7 +1,7 @@ 'use strict'; var async = require('async'); - +var winston = require('winston'); var user = require('../user'); var topics = require('../topics'); @@ -91,7 +91,17 @@ SocketUser.reset.send = function(socket, email, callback) { return callback(new Error('[[error:invalid-data]]')); } - user.reset.send(email, callback); + user.reset.send(email, function(err) { + if (err && err.message !== '[[error:invalid-email]]') { + return callback(err); + } + if (err && err.message === '[[error:invalid-email]]') { + winston.verbose('[user/reset] Invalid email attempt: ' + email); + return setTimeout(callback, 2500); + } + + callback(); + }); }; SocketUser.reset.commit = function(socket, data, callback) { diff --git a/src/socket.io/user/ban.js b/src/socket.io/user/ban.js index d52251d76d..a2c4ea50d3 100644 --- a/src/socket.io/user/ban.js +++ b/src/socket.io/user/ban.js @@ -13,10 +13,12 @@ module.exports = function(SocketUser) { data = { uids: data, until: 0 - } + }; } - toggleBan(socket.uid, data.uids, banUser.bind(null, data.until || 0), function(err) { + toggleBan(socket.uid, data.uids, function(uid, next) { + banUser(data.until || 0, uid, next); + }, function(err) { if (err) { return callback(err); } @@ -69,7 +71,6 @@ module.exports = function(SocketUser) { next(); } ], callback); - }; - + } }; diff --git a/src/topics.js b/src/topics.js index b92d0b51bf..0079c501ce 100644 --- a/src/topics.js +++ b/src/topics.js @@ -192,7 +192,8 @@ var social = require('./social'); isFollowing: async.apply(Topics.isFollowing, [topicData.tid], uid), isIgnoring: async.apply(Topics.isIgnoring, [topicData.tid], uid), bookmark: async.apply(Topics.getUserBookmark, topicData.tid, uid), - postSharing: async.apply(social.getActivePostSharing) + postSharing: async.apply(social.getActivePostSharing), + related: async.apply(Topics.getRelatedTopics, topicData, uid) }, next); }, function (results, next) { @@ -205,6 +206,7 @@ var social = require('./social'); topicData.isIgnoring = results.isIgnoring[0]; topicData.bookmark = results.bookmark; topicData.postSharing = results.postSharing; + topicData.related = results.related || []; topicData.unreplied = parseInt(topicData.postcount, 10) === 1; topicData.deleted = parseInt(topicData.deleted, 10) === 1; @@ -213,10 +215,6 @@ var social = require('./social'); topicData.icons = []; - Topics.getRelatedTopics(topicData, uid, next); - }, - function (related, next) { - topicData.related = related || []; plugins.fireHook('filter:topic.get', {topic: topicData, uid: uid}, next); }, function (data, next) { diff --git a/src/topics/create.js b/src/topics/create.js index a173c1d661..cd1bf23a62 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -191,25 +191,28 @@ module.exports = function(Topics) { function(_cid, next) { cid = _cid; async.parallel({ - exists: async.apply(Topics.exists, tid), - locked: async.apply(Topics.isLocked, tid), + topicData: async.apply(Topics.getTopicData, tid), canReply: async.apply(privileges.topics.can, 'topics:reply', tid, uid), - isAdmin: async.apply(user.isAdministrator, uid), - isModerator: async.apply(user.isModerator, uid, cid) + isAdminOrMod: async.apply(privileges.categories.isAdminOrMod, cid, uid), }, next); }, function(results, next) { - if (!results.exists) { + if (!results.topicData) { return next(new Error('[[error:no-topic]]')); } - if (results.locked && !results.isAdmin && !results.isModerator) { + if (parseInt(results.topicData.locked, 10) === 1 && !results.isAdminOrMod) { return next(new Error('[[error:topic-locked]]')); } + if (parseInt(results.topicData.deleted, 10) === 1 && !results.isAdminOrMod) { + return next(new Error('[[error:topic-deleted]]')); + } + if (!results.canReply) { return next(new Error('[[error:no-privileges]]')); } + guestHandleValid(data, next); }, function(next) { @@ -292,6 +295,8 @@ module.exports = function(Topics) { postData.favourited = false; postData.votes = 0; + postData.display_edit_tools = true; + postData.display_delete_tools = true; postData.display_moderator_tools = true; postData.display_move_tools = true; postData.selfPost = false; diff --git a/src/topics/fork.js b/src/topics/fork.js index b2e16f069d..fbc9cdb54c 100644 --- a/src/topics/fork.js +++ b/src/topics/fork.js @@ -61,8 +61,8 @@ module.exports = function(Topics) { function(_tid, next) { function move(pid, next) { privileges.posts.canEdit(pid, uid, function(err, canEdit) { - if(err || !canEdit) { - return next(err); + if (err || !canEdit.flag) { + return next(err || new Error(canEdit.message)); } Topics.movePostToTopic(pid, tid, next); diff --git a/src/topics/posts.js b/src/topics/posts.js index 6bdf103420..80bde62334 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -141,9 +141,11 @@ module.exports = function(Topics) { var loggedIn = !!parseInt(topicPrivileges.uid, 10); topicData.posts.forEach(function(post) { if (post) { - post.display_moderator_tools = topicPrivileges.isAdminOrMod || post.selfPost; + post.display_edit_tools = topicPrivileges.isAdminOrMod || (post.selfPost && topicPrivileges['posts:edit']); + post.display_delete_tools = topicPrivileges.isAdminOrMod || (post.selfPost && topicPrivileges['posts:delete']); + post.display_moderator_tools = post.display_edit_tools || post.display_delete_tools; post.display_move_tools = topicPrivileges.isAdminOrMod && post.index !== 0; - post.display_post_menu = topicPrivileges.isAdminOrMod || post.selfPost || ((loggedIn || topicData.postSharing.length) && !post.deleted); + post.display_post_menu = topicPrivileges.isAdminOrMod || (post.selfPost && !topicData.locked) || ((loggedIn || topicData.postSharing.length) && !post.deleted); post.ip = topicPrivileges.isAdminOrMod ? post.ip : undefined; if (post.deleted && !(topicPrivileges.isAdminOrMod || post.selfPost)) { diff --git a/src/topics/tags.js b/src/topics/tags.js index 83702331b7..ec16c09ff6 100644 --- a/src/topics/tags.js +++ b/src/topics/tags.js @@ -316,7 +316,7 @@ module.exports = function(Topics) { return plugins.fireHook('filter:topic.getRelatedTopics', {topic: topicData, uid: uid}, callback); } - var maximumTopics = parseInt(meta.config.maximumRelatedTopics, 10); + var maximumTopics = parseInt(meta.config.maximumRelatedTopics, 10) || 0; if (maximumTopics === 0 || !topicData.tags.length) { return callback(null, []); } diff --git a/src/topics/tools.js b/src/topics/tools.js index fd5321eb6b..3975193f76 100644 --- a/src/topics/tools.js +++ b/src/topics/tools.js @@ -1,11 +1,12 @@ 'use strict'; -var async = require('async'), +var async = require('async'); - db = require('../database'), - categories = require('../categories'), - plugins = require('../plugins'), - privileges = require('../privileges'); +var db = require('../database'); +var categories = require('../categories'); +var meta = require('../meta'); +var plugins = require('../plugins'); +var privileges = require('../privileges'); module.exports = function(Topics) { @@ -32,10 +33,10 @@ module.exports = function(Topics) { if (!exists) { return next(new Error('[[error:no-topic]]')); } - privileges.topics.isOwnerOrAdminOrMod(tid, uid, next); + privileges.topics.canDelete(tid, uid, next); }, - function (isOwnerOrAdminOrMod, next) { - if (!isOwnerOrAdminOrMod) { + function (canDelete, next) { + if (!canDelete) { return next(new Error('[[error:no-privileges]]')); } Topics.getTopicFields(tid, ['tid', 'cid', 'uid', 'deleted', 'title', 'mainPid'], next); diff --git a/src/upgrade.js b/src/upgrade.js index dc4af652c9..ae3877458d 100644 --- a/src/upgrade.js +++ b/src/upgrade.js @@ -10,7 +10,7 @@ var db = require('./database'), schemaDate, thisSchemaDate, // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema - latestSchema = Date.UTC(2016, 7, 5); + latestSchema = Date.UTC(2016, 8, 7); Upgrade.check = function(callback) { db.get('schemaDate', function(err, value) { @@ -682,6 +682,111 @@ Upgrade.upgrade = function(callback) { winston.info('[2016/08/05] Removing best posts with negative scores skipped!'); next(); } + }, + function(next) { + thisSchemaDate = Date.UTC(2016, 8, 7); + + if (schemaDate < thisSchemaDate) { + updatesMade = true; + winston.info('[2016/08/07] Granting edit/delete/delete topic on existing categories'); + + var groupsAPI = require('./groups'); + var privilegesAPI = require('./privileges'); + + db.getSortedSetRange('categories:cid', 0, -1, function(err, cids) { + async.eachSeries(cids, function(cid, next) { + privilegesAPI.categories.list(cid, function(err, data) { + var groups = data.groups; + var users = data.users; + + async.waterfall([ + function(next) { + async.eachSeries(groups, function(group, next) { + if (group.privileges['groups:topics:reply']) { + return async.parallel([ + async.apply(groupsAPI.join, 'cid:' + cid + ':privileges:groups:posts:edit', group.name), + async.apply(groupsAPI.join, 'cid:' + cid + ':privileges:groups:posts:delete', group.name) + ], function(err) { + if (!err) { + winston.info('cid:' + cid + ':privileges:groups:posts:edit, cid:' + cid + ':privileges:groups:posts:delete granted to gid: ' + group.name); + } + + return next(err); + }); + } + + next(null); + }, next); + }, + function(next) { + async.eachSeries(groups, function(group, next) { + if (group.privileges['groups:topics:create']) { + return groupsAPI.join('cid:' + cid + ':privileges:groups:topics:delete', group.name, function(err) { + if (!err) { + winston.info('cid:' + cid + ':privileges:groups:topics:delete granted to gid: ' + group.name); + } + + return next(err); + }); + } + + next(null); + }, next); + }, + function(next) { + async.eachSeries(users, function(user, next) { + if (user.privileges['topics:reply']) { + return async.parallel([ + async.apply(groupsAPI.join, 'cid:' + cid + ':privileges:posts:edit', user.uid), + async.apply(groupsAPI.join, 'cid:' + cid + ':privileges:posts:delete', user.uid) + ], function(err) { + if (!err) { + winston.info('cid:' + cid + ':privileges:posts:edit, cid:' + cid + ':privileges:posts:delete granted to uid: ' + user.uid); + } + + return next(err); + }); + } + + next(null); + }, next); + }, + function(next) { + async.eachSeries(users, function(user, next) { + if (user.privileges['topics:create']) { + return groupsAPI.join('cid:' + cid + ':privileges:topics:delete', user.uid, function(err) { + if (!err) { + winston.info('cid:' + cid + ':privileges:topics:delete granted to uid: ' + user.uid); + } + + return next(err); + }); + } + + next(null); + }, next); + } + ], function(err) { + if (!err) { + winston.info('-- cid ' + cid + ' upgraded'); + } + + next(err); + }); + }); + }, function(err) { + if (err) { + return next(err); + } + + winston.info('[2016/08/07] Granting edit/delete/delete topic on existing categories - done'); + Upgrade.update(thisSchemaDate, next); + }); + }); + } else { + winston.info('[2016/08/07] Granting edit/delete/delete topic on existing categories - skipped!'); + next(); + } } // Add new schema updates here // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 24!!! diff --git a/src/user.js b/src/user.js index e4f2eb5f55..d04b7c8cce 100644 --- a/src/user.js +++ b/src/user.js @@ -91,7 +91,7 @@ var utils = require('../public/src/utils'); User.getUsers = function(uids, uid, callback) { var fields = ['uid', 'username', 'userslug', 'picture', 'status', 'flags', - 'banned', 'joindate', 'postcount', 'reputation', 'email:confirmed', 'lastonline']; + 'banned', 'banned:expire', 'joindate', 'postcount', 'reputation', 'email:confirmed', 'lastonline']; async.waterfall([ function (next) { @@ -118,6 +118,8 @@ var utils = require('../public/src/utils'); user.joindateISO = utils.toISOString(user.joindate); user.administrator = results.isAdmin[index]; user.banned = parseInt(user.banned, 10) === 1; + user.banned_until = parseInt(user['banned:expire'], 10) || 0; + user.banned_until_readable = user.banned_until ? new Date(user.banned_until).toString() : 'Not Banned'; user['email:confirmed'] = parseInt(user['email:confirmed'], 10) === 1; user.lastonlineISO = utils.toISOString(user.lastonline) || user.joindateISO; } @@ -258,35 +260,6 @@ var utils = require('../public/src/utils'); }); }; - User.isBanned = function(uid, callback) { - async.waterfall([ - async.apply(User.getUserField, uid, 'banned'), - function(banned, next) { - banned = parseInt(banned, 10) === 1; - if (!banned) { - return next(null, banned); - } else { - // If they are banned, see if the ban has expired - db.sortedSetScore('users:banned:expire', uid, function(err, score) { - var stillBanned = !score || Date.now() < score; - - if (!stillBanned) { - async.parallel([ - async.apply(db.sortedSetRemove.bind(db), 'users:banned:expire', uid), - async.apply(db.sortedSetRemove.bind(db), 'users:banned', uid), - async.apply(User.setUserField, uid, 'banned', 0) - ], function(err) { - next(err, false); - }); - } else { - next(err, true); - } - }); - } - } - ], callback); - }; - User.addInterstitials = function(callback) { plugins.registerHook('core', { hook: 'filter:register.interstitial', diff --git a/src/user/admin.js b/src/user/admin.js index cf09c0a4ed..e4384782ee 100644 --- a/src/user/admin.js +++ b/src/user/admin.js @@ -71,6 +71,7 @@ module.exports = function(User) { if (until > 0 && Date.now() < until) { tasks.push(async.apply(db.sortedSetAdd, 'users:banned:expire', until, uid)); + tasks.push(async.apply(User.setUserField, uid, 'banned:expire', until)); } else { until = 0; } @@ -91,7 +92,7 @@ module.exports = function(User) { User.unban = function(uid, callback) { async.waterfall([ function (next) { - User.setUserField(uid, 'banned', 0, next); + User.setUserFields(uid, {banned: 0, 'banned:expire': 0}, next); }, function (next) { db.sortedSetsRemove(['users:banned', 'users:banned:expire'], uid, next); @@ -103,6 +104,32 @@ module.exports = function(User) { ], callback); }; + User.isBanned = function(uid, callback) { + async.waterfall([ + async.apply(User.getUserFields, uid, ['banned', 'banned:expire']), + function(userData, next) { + var banned = parseInt(userData.banned, 10) === 1; + if (!banned) { + return next(null, banned); + } + + // If they are banned, see if the ban has expired + var stillBanned = !userData['banned:expire'] || Date.now() < userData['banned:expire']; + + if (stillBanned) { + return next(null, true); + } + async.parallel([ + async.apply(db.sortedSetRemove.bind(db), 'users:banned:expire', uid), + async.apply(db.sortedSetRemove.bind(db), 'users:banned', uid), + async.apply(User.setUserFields, uid, {banned:0, 'banned:expire': 0}) + ], function(err) { + next(err, false); + }); + } + ], callback); + }; + User.resetFlags = function(uids, callback) { if (!Array.isArray(uids) || !uids.length) { return callback(); diff --git a/src/user/create.js b/src/user/create.js index bd79270a93..df504c3da4 100644 --- a/src/user/create.js +++ b/src/user/create.js @@ -26,7 +26,7 @@ module.exports = function(User) { var userData = { 'username': data.username, 'userslug': data.userslug, - 'email': data.email, + 'email': data.email || '', 'joindate': timestamp, 'lastonline': timestamp, 'picture': '', diff --git a/src/user/data.js b/src/user/data.js index 8e179ca119..6f2a2dd4b7 100644 --- a/src/user/data.js +++ b/src/user/data.js @@ -55,16 +55,6 @@ module.exports = function(User) { return callback(err); } - if (fields.indexOf('banned') !== -1) { - // Also retrieve ban expiry for these users - db.sortedSetScores('users:banned:expire', uids, function(err, scores) { - users = users.map(function(userObj, idx) { - userObj.banned_until = scores[idx] || 0; - userObj.banned_until_readable = scores[idx] ? new Date(scores[idx]).toString() : 'Not Banned'; - }); - }); - } - modifyUserData(users, fieldsToRemove, callback); }); }; @@ -104,7 +94,9 @@ module.exports = function(User) { return; } - user.username = validator.escape(user.username ? user.username.toString() : ''); + if (user.hasOwnProperty('username')) { + user.username = validator.escape(user.username ? user.username.toString() : ''); + } if (user.password) { user.password = undefined; diff --git a/src/user/info.js b/src/user/info.js index a9ca675eab..da85e25116 100644 --- a/src/user/info.js +++ b/src/user/info.js @@ -1,33 +1,39 @@ 'use strict'; -var async = require('async'), - _ = require('underscore'); +var async = require('async'); +var _ = require('underscore'); -var db = require('../database'), - posts = require('../posts'), - topics = require('../topics'); +var db = require('../database'); +var posts = require('../posts'); +var topics = require('../topics'); module.exports = function(User) { User.getModerationHistory = function(uid, callback) { async.waterfall([ function(next) { async.parallel({ - flags: async.apply(db.getSortedSetRevRangeByScoreWithScores, 'uid:' + uid + ':flag:pids', 0, 20, '+inf', '-inf'), - bans: async.apply(db.getSortedSetRevRangeByScoreWithScores, 'uid:' + uid + ':bans', 0, 20, '+inf', '-inf') + flags: async.apply(db.getSortedSetRevRangeWithScores, 'uid:' + uid + ':flag:pids', 0, 19), + bans: async.apply(db.getSortedSetRevRangeWithScores, 'uid:' + uid + ':bans', 0,19) }, next); }, - async.apply(getFlagMetadata), - async.apply(formatBanData) + function(data, next) { + getFlagMetadata(data, next); + } ], function(err, data) { - callback(err, data); + if (err) { + return callback(err); + } + formatBanData(data); + callback(null, data); }); }; function getFlagMetadata(data, callback) { - // Retrieve post title & slug from flags list - posts.getPostsFields(data.flags.map(function(flagObj) { + var pids = data.flags.map(function(flagObj) { return parseInt(flagObj.value, 10); - }), ['tid'], function(err, postData) { + }); + + posts.getPostsFields(pids, ['tid'], function(err, postData) { if (err) { return callback(err); } @@ -37,6 +43,9 @@ module.exports = function(User) { }); topics.getTopicsFields(tids, ['title'], function(err, topicData) { + if (err) { + return callback(err); + } data.flags = data.flags.map(function(flagObj, idx) { flagObj.pid = flagObj.value; flagObj.timestamp = flagObj.score; @@ -54,7 +63,7 @@ module.exports = function(User) { }); } - function formatBanData(data, callback) { + function formatBanData(data) { data.bans = data.bans.map(function(banObj) { banObj.until = parseInt(banObj.value, 10); banObj.untilReadable = new Date(banObj.until).toString(); @@ -67,7 +76,5 @@ module.exports = function(User) { return banObj; }); - - setImmediate(callback, null, data); } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/user/settings.js b/src/user/settings.js index 7b78ea3c72..55bf2b14ff 100644 --- a/src/user/settings.js +++ b/src/user/settings.js @@ -122,7 +122,6 @@ module.exports = function(User) { restrictChat: data.restrictChat, topicSearchEnabled: data.topicSearchEnabled, delayImageLoading: data.delayImageLoading, - groupTitle: data.groupTitle, homePageRoute : ((data.homePageRoute === 'custom' ? data.homePageCustom : data.homePageRoute) || '').replace(/^\//, ''), scrollToMyPost: data.scrollToMyPost }; diff --git a/src/views/admin/general/dashboard.tpl b/src/views/admin/general/dashboard.tpl index 6ea841352a..a478c21c16 100644 --- a/src/views/admin/general/dashboard.tpl +++ b/src/views/admin/general/dashboard.tpl @@ -95,11 +95,10 @@
System Control

- - +

- Maintenance Mode + Maintenance Mode


diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl index 6683f6e887..d6dd8c5a25 100644 --- a/src/views/admin/manage/users.tpl +++ b/src/views/admin/manage/users.tpl @@ -30,6 +30,7 @@
  • Reset Flags
  • Delete User(s)
  • +
  • Delete User(s) and Content
  • diff --git a/src/views/admin/partials/categories/groups.tpl b/src/views/admin/partials/categories/groups.tpl index eb432bfd27..495aa9589f 100644 --- a/src/views/admin/partials/categories/groups.tpl +++ b/src/views/admin/partials/categories/groups.tpl @@ -10,8 +10,11 @@
  • Access Topics
  • Create Topics
  • Reply to Topics
  • +
  • Edit Posts
  • +
  • Delete Posts
  • +
  • Delete Topics
  • {groups.displayName} - \ No newline at end of file + diff --git a/src/views/admin/partials/categories/users.tpl b/src/views/admin/partials/categories/users.tpl index 9ec7c262fd..772053d5b0 100644 --- a/src/views/admin/partials/categories/users.tpl +++ b/src/views/admin/partials/categories/users.tpl @@ -10,10 +10,13 @@
  • Access Topics
  • Create Topics
  • Reply to Topics
  • +
  • Edit Posts
  • +
  • Delete Posts
  • +
  • Delete Topics
  • Moderator
  • {users.username} - \ No newline at end of file + diff --git a/src/views/admin/partials/menu.tpl b/src/views/admin/partials/menu.tpl index e35b41847c..34ddbf9acd 100644 --- a/src/views/admin/partials/menu.tpl +++ b/src/views/admin/partials/menu.tpl @@ -121,11 +121,6 @@