From 8f27d7810b92912c252edf6716887b93e1c254a8 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Thu, 9 Feb 2017 15:50:05 -0700 Subject: [PATCH 01/16] Ajaxify improvement, `/assets/uploads` --- public/src/ajaxify.js | 67 +++++++++++++++++----------------------- src/controllers/index.js | 2 +- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 6b18e5dda0..4e1a576035 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -249,48 +249,37 @@ $(document).ready(function () { $(window).trigger('action:script.load', data); // Require and parse modules - var outstanding = 0; - var onReady = function () { - if (outstanding) { - return setTimeout(onReady, 100); + var outstanding = data.scripts.length; + + data.scripts.map(function (script) { + if (typeof script === 'function') { + return function (next) { + script(); + next(); + }; } - - data.scripts = data.scripts.filter(Boolean); - data.scripts.forEach(function (functionRef) { - functionRef(); - }); - - callback(); - }; - - data.scripts.forEach(function (script, idx) { - switch (typeof script) { - case 'string': - ++outstanding; - (function (idx) { - require([script], function (script) { - if (script && script.init) { - data.scripts[idx] = script.init; - } else { - data.scripts[idx] = null; - } - --outstanding; - }); - }(idx)); - break; - - case 'function': - // No changes needed - break; - - default: - // Neither? No comprende - data.scripts[idx] = undefined; - break; + if (typeof script === 'string') { + return function (next) { + require([script], function (script) { + if (script && script.init) { + script.init(); + } + next(); + }, function () { + // ignore 404 error + next(); + }); + }; } + return null; + }).filter(Boolean).forEach(function (fn) { + fn(function () { + outstanding -= 1; + if (outstanding === 0) { + callback(); + } + }); }); - - onReady(); }; ajaxify.loadData = function (url, callback) { diff --git a/src/controllers/index.js b/src/controllers/index.js index 7d6666f8da..800559db4b 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -365,7 +365,7 @@ Controllers.handle404 = function (req, res) { if (isClientScript.test(req.url)) { res.type('text/javascript').status(200).send(''); - } else if (req.path.startsWith(relativePath + '/uploads') || (req.get('accept') && req.get('accept').indexOf('text/html') === -1) || req.path === '/favicon.ico') { + } else if (req.path.startsWith(relativePath + '/assets/uploads') || (req.get('accept') && req.get('accept').indexOf('text/html') === -1) || req.path === '/favicon.ico') { meta.errors.log404(req.path || ''); res.sendStatus(404); } else if (req.accepts('html')) { From b553236620c758abb6573be040a0398d06b0735f Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Fri, 10 Feb 2017 21:18:09 -0700 Subject: [PATCH 02/16] Better defaults if cache buster read fails --- src/meta/cacheBuster.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/meta/cacheBuster.js b/src/meta/cacheBuster.js index ca00fba057..461bcaf801 100644 --- a/src/meta/cacheBuster.js +++ b/src/meta/cacheBuster.js @@ -32,15 +32,15 @@ exports.read = function read(callback) { fs.readFile(filePath, function (err, buffer) { if (err) { winston.warn('[cache-buster] could not read cache buster: ' + err.message); - return callback(); + return callback(null, generate()); } - buffer = buffer.toString(); - if (buffer) { - cached = buffer; - return callback(null, cached); + if (!buffer || buffer.toString().length !== 11) { + winston.warn('[cache-buster] cache buster string invalid: expected /[a-z0-9]{11}/, got `' + buffer + '`'); + return callback(null, generate()); } - callback(); + cached = buffer.toString(); + callback(null, cached); }); }; From 2c428cdec176cac5ac136498ef3c85456502dd16 Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Thu, 16 Feb 2017 09:22:12 +0000 Subject: [PATCH 03/16] Latest translations and fallbacks --- public/language/es/admin/advanced/errors.json | 2 +- public/language/es/admin/extend/plugins.json | 2 +- public/language/es/admin/extend/rewards.json | 2 +- public/language/es/admin/general/navigation.json | 2 +- public/language/es/admin/general/sounds.json | 2 +- public/language/es/admin/manage/registration.json | 2 +- public/language/es/admin/manage/users.json | 12 ++++++------ public/language/es/admin/settings/advanced.json | 2 +- public/language/es/admin/settings/notifications.json | 2 +- public/language/es/admin/settings/uploads.json | 2 +- public/language/es/admin/settings/user.json | 2 +- public/language/es/global.json | 2 +- public/language/nl/admin/admin.json | 8 ++++---- public/language/nl/search.json | 4 ++-- public/language/nl/topic.json | 4 ++-- public/language/nl/user.json | 8 ++++---- public/language/tr/admin/general/dashboard.json | 2 +- public/language/tr/notifications.json | 6 +++--- public/language/tr/search.json | 4 ++-- public/language/tr/topic.json | 4 ++-- 20 files changed, 37 insertions(+), 37 deletions(-) diff --git a/public/language/es/admin/advanced/errors.json b/public/language/es/admin/advanced/errors.json index ca55056f4b..e053348013 100644 --- a/public/language/es/admin/advanced/errors.json +++ b/public/language/es/admin/advanced/errors.json @@ -8,7 +8,7 @@ "clear-error-log": "Cerrar Log de Error", "route": "Ruta", "count": "Contar", - "no-routes-not-found": "Hooray! No 404 errors!", + "no-routes-not-found": "¡Hurra! ¡No hay errores 404!", "clear404-confirm": "¿Estas seguro que desea borrar los registros de errores 404?", "clear404-success": "\"404 no encontrado\" Errores borrados" } \ No newline at end of file diff --git a/public/language/es/admin/extend/plugins.json b/public/language/es/admin/extend/plugins.json index 1661a987b7..4bb8cff1c1 100644 --- a/public/language/es/admin/extend/plugins.json +++ b/public/language/es/admin/extend/plugins.json @@ -1,5 +1,5 @@ { - "installed": "Installed", + "installed": "Instalado", "active": "Active", "inactive": "Inactive", "out-of-date": "Out of Date", diff --git a/public/language/es/admin/extend/rewards.json b/public/language/es/admin/extend/rewards.json index 5383a90b33..27560eee28 100644 --- a/public/language/es/admin/extend/rewards.json +++ b/public/language/es/admin/extend/rewards.json @@ -1,5 +1,5 @@ { - "rewards": "Rewards", + "rewards": "Recompensas", "condition-if-users": "If User's", "condition-is": "Is:", "condition-then": "Then:", diff --git a/public/language/es/admin/general/navigation.json b/public/language/es/admin/general/navigation.json index c4ba0d09ac..e2a66f7af2 100644 --- a/public/language/es/admin/general/navigation.json +++ b/public/language/es/admin/general/navigation.json @@ -1,5 +1,5 @@ { - "icon": "Icon:", + "icon": "Icono:", "change-icon": "change", "route": "Route:", "tooltip": "Tooltip:", diff --git a/public/language/es/admin/general/sounds.json b/public/language/es/admin/general/sounds.json index 95ccbde0f1..29c441db26 100644 --- a/public/language/es/admin/general/sounds.json +++ b/public/language/es/admin/general/sounds.json @@ -1,5 +1,5 @@ { - "notifications": "Notifications", + "notifications": "Notificaciones", "chat-messages": "Chat Messages", "play-sound": "Play", "incoming-message": "Incoming Message", diff --git a/public/language/es/admin/manage/registration.json b/public/language/es/admin/manage/registration.json index f51b4d56e6..defa4f1b30 100644 --- a/public/language/es/admin/manage/registration.json +++ b/public/language/es/admin/manage/registration.json @@ -1,5 +1,5 @@ { - "queue": "Queue", + "queue": "Cola", "description": "There are no users in the registration queue.
To enable this feature, go to Settings → User → User Registration and set Registration Type to \"Admin Approval\".", "list.name": "Name", diff --git a/public/language/es/admin/manage/users.json b/public/language/es/admin/manage/users.json index f1651a814b..da98ea0b09 100644 --- a/public/language/es/admin/manage/users.json +++ b/public/language/es/admin/manage/users.json @@ -1,5 +1,5 @@ { - "users": "Users", + "users": "Usuarios", "edit": "Edit", "make-admin": "Make Admin", "remove-admin": "Remove Admin", @@ -76,14 +76,14 @@ "alerts.validate-email-success": "Emails validated", "alerts.password-reset-confirm": "Do you want to send password reset email(s) to these user(s)?", "alerts.confirm-delete": "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 remain.", - "alerts.delete-success": "User(s) Deleted!", + "alerts.delete-success": "¡Usuario(s) Borrado(s)!", "alerts.confirm-purge": "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!", - "alerts.create": "Create User", - "alerts.button-create": "Create", - "alerts.button-cancel": "Cancel", + "alerts.create": "Crear Usuario", + "alerts.button-create": "Crear", + "alerts.button-cancel": "Cancelar", "alerts.error-passwords-different": "Passwords must match!", "alerts.error-x": "Error

%1

", - "alerts.create-success": "User created!", + "alerts.create-success": "¡Usuario creado!", "alerts.prompt-email": "Email: ", "alerts.email-sent-to": "An invitation email has been sent to %1", diff --git a/public/language/es/admin/settings/advanced.json b/public/language/es/admin/settings/advanced.json index b023528d04..31a15df457 100644 --- a/public/language/es/admin/settings/advanced.json +++ b/public/language/es/admin/settings/advanced.json @@ -1,5 +1,5 @@ { - "maintenance-mode": "Maintenance Mode", + "maintenance-mode": "Modo de Mantenimiento", "maintenance-mode.help": "When the forum is in maintenance mode, all requests will be redirected to a static holding page. Administrators are exempt from this redirection, and are able to access the site normally.", "maintenance-mode.message": "Maintenance Message", "headers": "Headers", diff --git a/public/language/es/admin/settings/notifications.json b/public/language/es/admin/settings/notifications.json index 4eff7f341a..7cfd68f3d6 100644 --- a/public/language/es/admin/settings/notifications.json +++ b/public/language/es/admin/settings/notifications.json @@ -1,5 +1,5 @@ { - "notifications": "Notifications", + "notifications": "Notificaciones", "welcome-notification": "Welcome Notification", "welcome-notification-link": "Welcome Notification Link" } \ No newline at end of file diff --git a/public/language/es/admin/settings/uploads.json b/public/language/es/admin/settings/uploads.json index 35eaa5a58f..c48d591d9f 100644 --- a/public/language/es/admin/settings/uploads.json +++ b/public/language/es/admin/settings/uploads.json @@ -1,5 +1,5 @@ { - "posts": "Posts", + "posts": "Mensajes", "allow-files": "Allow users to upload regular files", "private": "Make uploaded files private", "max-image-width": "Resize images down to specified width (in pixels)", diff --git a/public/language/es/admin/settings/user.json b/public/language/es/admin/settings/user.json index bdabb075e9..8e231827ca 100644 --- a/public/language/es/admin/settings/user.json +++ b/public/language/es/admin/settings/user.json @@ -1,5 +1,5 @@ { - "authentication": "Authentication", + "authentication": "Autentificación", "allow-local-login": "Allow local login", "require-email-confirmation": "Require Email Confirmation", "email-confirm-interval": "User may not resend a confirmation email until", diff --git a/public/language/es/global.json b/public/language/es/global.json index 31a0064c3d..37608b7c42 100644 --- a/public/language/es/global.json +++ b/public/language/es/global.json @@ -103,5 +103,5 @@ "cookies.message": "Esta web usa cookies para asegurar que usted recibe la mejor experiencia de navegación.", "cookies.accept": "De Acuerdo!", "cookies.learn_more": "Quiero saber más", - "edited": "Edited" + "edited": "Editado" } \ No newline at end of file diff --git a/public/language/nl/admin/admin.json b/public/language/nl/admin/admin.json index 9c01f56006..7f6e9cebd7 100644 --- a/public/language/nl/admin/admin.json +++ b/public/language/nl/admin/admin.json @@ -1,7 +1,7 @@ { - "alert.confirm-reload": "Are you sure you wish to reload NodeBB?", - "alert.confirm-restart": "Are you sure you wish to restart NodeBB?", + "alert.confirm-reload": "Weet u zeker dat u NodeBB wilt herladen?", + "alert.confirm-restart": "Weet u zeker dat u NodeBB opnieuw wilt opstarten?", - "acp-title": "%1 | NodeBB Admin Control Panel", - "settings-header-contents": "Contents" + "acp-title": "%1 | NodeBB Administratiepaneel", + "settings-header-contents": "Inhoud" } \ No newline at end of file diff --git a/public/language/nl/search.json b/public/language/nl/search.json index 2c7c9b000e..55a1964be5 100644 --- a/public/language/nl/search.json +++ b/public/language/nl/search.json @@ -8,11 +8,11 @@ "posted-by": "Geplaatst door", "in-categories": "In categorieën", "search-child-categories": "Doorzoek subcategorieën ", - "has-tags": "Has tags", + "has-tags": "Is getagged", "reply-count": "Aantal reacties", "at-least": "op zijn minst", "at-most": "op zijn meest", - "relevance": "Relevance", + "relevance": "Relevantie", "post-time": "Geplaatst op", "newer-than": "Nieuwer dan", "older-than": "Ouder dan", diff --git a/public/language/nl/topic.json b/public/language/nl/topic.json index 398ae2b220..1e0be1b1c3 100644 --- a/public/language/nl/topic.json +++ b/public/language/nl/topic.json @@ -13,8 +13,8 @@ "notify_me": "Krijg een melding wanneer nieuwe reacties volgen", "quote": "Citeren", "reply": "Reageren", - "replies_to_this_post": "%1 Replies", - "last_reply_time": "Last reply", + "replies_to_this_post": "%1 Antwoorden", + "last_reply_time": "Laatste antwoord", "reply-as-topic": "Reageren als onderwerp", "guest-login-reply": "Aanmelden om te reageren", "edit": "Aanpassen", diff --git a/public/language/nl/user.json b/public/language/nl/user.json index 1e6b49c38d..6d897f89cd 100644 --- a/public/language/nl/user.json +++ b/public/language/nl/user.json @@ -33,7 +33,7 @@ "chat": "Chat", "chat_with": "Chat verder met %1", "new_chat_with": "Begin een chat met %1", - "flag-profile": "Flag Profile", + "flag-profile": "Profiel vlaggen", "follow": "Volgen", "unfollow": "Ontvolgen", "more": "Meer", @@ -64,9 +64,9 @@ "upload_a_picture": "Upload een afbeelding", "remove_uploaded_picture": "Verwijder gëuploade foto", "upload_cover_picture": "Upload je coverafbeelding", - "remove_cover_picture_confirm": "Are you sure you want to remove the cover picture?", - "crop_picture": "Crop picture", - "upload_cropped_picture": "Crop and upload", + "remove_cover_picture_confirm": "Weet u zeker dat u de cover foto wilt verwijderen?", + "crop_picture": "Foto bijsnijden", + "upload_cropped_picture": "Bijsnijden en uploaden", "settings": "Instellingen", "show_email": "E-mailadres weergeven", "show_fullname": "Laat mijn volledige naam zien", diff --git a/public/language/tr/admin/general/dashboard.json b/public/language/tr/admin/general/dashboard.json index e4c022f1d0..0ebf6e50f6 100644 --- a/public/language/tr/admin/general/dashboard.json +++ b/public/language/tr/admin/general/dashboard.json @@ -29,7 +29,7 @@ "search-plugin-not-installed": "Search Plugin not installed", "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", - "control-panel": "System Control", + "control-panel": "Sistem Kontrol", "reload": "Reload", "restart": "Restart", "restart-warning": "Reloading or Restarting your NodeBB will drop all existing connections for a few seconds.", diff --git a/public/language/tr/notifications.json b/public/language/tr/notifications.json index 8ae2cbda19..c402cddfc1 100644 --- a/public/language/tr/notifications.json +++ b/public/language/tr/notifications.json @@ -19,9 +19,9 @@ "user_flagged_post_in": "%1 bir iletiyi bayrakladı. %2", "user_flagged_post_in_dual": " %1 ve %2 %3 gönderini bayrakladı", "user_flagged_post_in_multiple": "%1 ve %2 kişi daha %3 gönderini bayrakladı", - "user_flagged_user": "%1 flagged a user profile (%2)", - "user_flagged_user_dual": "%1 and %2 flagged a user profile (%3)", - "user_flagged_user_multiple": "%1 and %2 others flagged a user profile (%3)", + "user_flagged_user": "%1 bayraklanan bir kullanıcı profili (%2)", + "user_flagged_user_dual": "%1 ve %2 bayraklanan kullanıcı profili (%3)", + "user_flagged_user_multiple": "%1 ve %2 diğer bayraklanan kullanıcı profili (%3)", "user_posted_to": "%1 %2 başlığına bir ileti gönderdi.", "user_posted_to_dual": "%1 ve %2 gönderine cevap verdi: %3", "user_posted_to_multiple": "%1 ve %2 kişi daha gönderine cevap verdi: %3", diff --git a/public/language/tr/search.json b/public/language/tr/search.json index 305c5cbf37..cfbcc7db4b 100644 --- a/public/language/tr/search.json +++ b/public/language/tr/search.json @@ -8,11 +8,11 @@ "posted-by": "Gönderen", "in-categories": "Kategorilerde", "search-child-categories": "Alt kategorilerde arat", - "has-tags": "Has tags", + "has-tags": "Etiketler", "reply-count": "Cevap Sayısı", "at-least": "En az", "at-most": "En fazla", - "relevance": "Relevance", + "relevance": "İlgi", "post-time": "Yayınlama zamanı", "newer-than": "Daha yeni", "older-than": "Daha eski", diff --git a/public/language/tr/topic.json b/public/language/tr/topic.json index fa6802f3d1..ad57a76331 100644 --- a/public/language/tr/topic.json +++ b/public/language/tr/topic.json @@ -13,8 +13,8 @@ "notify_me": "Bu konudaki cevaplardan haberdar ol", "quote": "Alıntı", "reply": "Cevap", - "replies_to_this_post": "%1 Replies", - "last_reply_time": "Last reply", + "replies_to_this_post": "%1 Cevap", + "last_reply_time": "Son cevap", "reply-as-topic": "İletiye Cevap Ver", "guest-login-reply": "Cevaplamak için giriş yapın", "edit": "Düzenle", From c285eb7fcdb03cacbbdcfc3a89a2b97dca9107e8 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 16 Feb 2017 15:01:06 +0300 Subject: [PATCH 04/16] closes #5450 --- package.json | 2 +- public/src/client/topic/postTools.js | 47 +++++++++++++++++----------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index f01ae0f487..bc9b07489b 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", - "nodebb-plugin-composer-default": "4.4.0", + "nodebb-plugin-composer-default": "4.3.9", "nodebb-plugin-dbsearch": "1.0.5", "nodebb-plugin-emoji-extended": "1.1.1", "nodebb-plugin-emoji-one": "1.1.5", diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index e3b2e49c14..f9b2090f3a 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -197,7 +197,7 @@ define('forum/topic/postTools', [ } function onReplyClicked(button, tid) { - var selectedText = getSelectedText(button); + var selectedNode = getSelectedNode(); showStaleWarning(function () { var username = getUserName(button); @@ -207,15 +207,15 @@ define('forum/topic/postTools', [ var toPid = button.is('[component="post/reply"]') ? getData(button, 'data-pid') : null; - if (selectedText) { + if (selectedNode.text && (!toPid || !selectedNode.pid || toPid === selectedNode.pid)) { + username = username || selectedNode.username; $(window).trigger('action:composer.addQuote', { tid: tid, - slug: ajaxify.data.slug, - index: getData(button, 'data-index'), pid: toPid, topicName: ajaxify.data.titleRaw, username: username, - text: selectedText + text: selectedNode.text, + selectedPid: selectedNode.pid }); } else { $(window).trigger('action:composer.post.new', { @@ -229,16 +229,14 @@ define('forum/topic/postTools', [ } function onQuoteClicked(button, tid) { - var selectedText = getSelectedText(button); + var selectedNode = getSelectedNode(); showStaleWarning(function () { function quote(text) { $(window).trigger('action:composer.addQuote', { tid: tid, - slug: ajaxify.data.slug, - index: getData(button, 'data-index'), - pid: pid, + pid: toPid, username: username, topicName: ajaxify.data.titleRaw, text: text @@ -246,12 +244,12 @@ define('forum/topic/postTools', [ } var username = getUserName(button); - var pid = getData(button, 'data-pid'); + var toPid = getData(button, 'data-pid'); - if (selectedText) { - return quote(selectedText); + if (selectedNode.text && toPid && toPid === selectedNode.pid) { + return quote(selectedNode.text); } - socket.emit('posts.getRawPost', pid, function (err, post) { + socket.emit('posts.getRawPost', toPid, function (err, post) { if (err) { return app.alertError(err.message); } @@ -261,12 +259,20 @@ define('forum/topic/postTools', [ }); } - function getSelectedText(button) { - var selectionText = ''; + function getSelectedNode() { + var selectedText = ''; + var selectedPid; + var username = ''; var selection = window.getSelection ? window.getSelection() : document.selection.createRange(); - var content = button.parents('[component="post"]').find('[component="post/content"]').get(0); + var postContents = $('[component="post"] [component="post/content"]'); + var content; + postContents.each(function(index, el) { + if (selection && selection.containsNode && el && selection.containsNode(el, true)) { + content = el; + } + }); - if (selection && selection.containsNode && content && selection.containsNode(content, true)) { + if (content) { var bounds = document.createRange(); bounds.selectNodeContents(content); var range = selection.getRangeAt(0).cloneRange(); @@ -277,10 +283,13 @@ define('forum/topic/postTools', [ range.setEnd(bounds.endContainer, bounds.endOffset); } bounds.detach(); - selectionText = range.toString(); + selectedText = range.toString(); + var postEl = $(content).parents('[component="post"]'); + selectedPid = postEl.attr('data-pid'); + username = getUserName($(content)); range.detach(); } - return selectionText; + return {text: selectedText, pid: selectedPid, username: username}; } function bookmarkPost(button, pid) { From dad5b135c39323854dad4d8fd0e5cc74e74d2e32 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 16 Feb 2017 15:11:31 +0300 Subject: [PATCH 05/16] lint --- public/src/client/topic/postTools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index f9b2090f3a..ccd72c640d 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -266,7 +266,7 @@ define('forum/topic/postTools', [ var selection = window.getSelection ? window.getSelection() : document.selection.createRange(); var postContents = $('[component="post"] [component="post/content"]'); var content; - postContents.each(function(index, el) { + postContents.each(function (index, el) { if (selection && selection.containsNode && el && selection.containsNode(el, true)) { content = el; } From 9b3741bc636e55f5912a5bbe9e41f6535bdc42e3 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 16 Feb 2017 15:35:19 +0300 Subject: [PATCH 06/16] up composer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bc9b07489b..f01ae0f487 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", - "nodebb-plugin-composer-default": "4.3.9", + "nodebb-plugin-composer-default": "4.4.0", "nodebb-plugin-dbsearch": "1.0.5", "nodebb-plugin-emoji-extended": "1.1.1", "nodebb-plugin-emoji-one": "1.1.5", From fd88e9fdff5bf107fef750a52d6d927925ac6b8a Mon Sep 17 00:00:00 2001 From: barisusakli Date: Thu, 16 Feb 2017 22:07:20 +0300 Subject: [PATCH 07/16] up composer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f01ae0f487..2e16cc0e19 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "morgan": "^1.3.2", "mousetrap": "^1.5.3", "nconf": "~0.8.2", - "nodebb-plugin-composer-default": "4.4.0", + "nodebb-plugin-composer-default": "4.4.1", "nodebb-plugin-dbsearch": "1.0.5", "nodebb-plugin-emoji-extended": "1.1.1", "nodebb-plugin-emoji-one": "1.1.5", From 3d56dc485711203142d3f688d22118e492f95802 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Thu, 16 Feb 2017 13:33:28 -0700 Subject: [PATCH 08/16] Fix #5368 --- src/meta/css.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/meta/css.js b/src/meta/css.js index 3627c6c41a..53388da57b 100644 --- a/src/meta/css.js +++ b/src/meta/css.js @@ -143,7 +143,12 @@ module.exports = function (Meta) { return callback(err); } - postcss(global.env === 'development' ? [ autoprefixer ] : [ autoprefixer, clean() ]).process(lessOutput.css).then(function (result) { + postcss(global.env === 'development' ? [ autoprefixer ] : [ + autoprefixer, + clean({ + processImportFrom: ['local'] + }), + ]).process(lessOutput.css).then(function (result) { result.warnings().forEach(function (warn) { winston.verbose(warn.toString()); }); From 484891472e4d1912268ed599583def1393fc7017 Mon Sep 17 00:00:00 2001 From: pichalite Date: Fri, 17 Feb 2017 00:48:38 +0000 Subject: [PATCH 09/16] Make cropper in to a module --- public/src/client/account/edit.js | 88 +++++----------------------- public/src/client/account/header.js | 6 +- public/src/client/groups/details.js | 6 +- public/src/modules/pictureCropper.js | 78 ++++++++++++++++++++++++ public/src/modules/uploader.js | 36 ++++++------ 5 files changed, 119 insertions(+), 95 deletions(-) create mode 100644 public/src/modules/pictureCropper.js diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js index 2856d10f99..03e9f2914a 100644 --- a/public/src/client/account/edit.js +++ b/public/src/client/account/edit.js @@ -2,7 +2,7 @@ /* globals define, ajaxify, socket, app, config, templates, bootbox */ -define('forum/account/edit', ['forum/account/header', 'uploader', 'translator', 'components', 'cropper'], function (header, uploader, translator, components, cropper) { +define('forum/account/edit', ['forum/account/header', 'uploader', 'translator', 'components', 'pictureCropper'], function (header, uploader, translator, components, pictureCropper) { var AccountEdit = {}; AccountEdit.init = function () { @@ -210,86 +210,21 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator', updateHeader(); } } - - function handleImageCrop(data) { - $('#crop-picture-modal').remove(); - templates.parse('modals/crop_picture', {url: data.url}, function (cropperHtml) { - translator.translate(cropperHtml, function (translated) { - var cropperModal = $(translated); - cropperModal.modal('show'); - - var img = document.getElementById('cropped-image'); - var cropperTool = new cropper.default(img, { - aspectRatio: 1 / 1, - viewMode: 1 - }); - - cropperModal.find('.rotate').on('click', function () { - var degrees = this.getAttribute("data-degrees"); - cropperTool.rotate(degrees); - }); - - cropperModal.find('.flip').on('click', function () { - var option = this.getAttribute("data-option"); - var method = this.getAttribute("data-method"); - method === 'scaleX' ? cropperTool.scaleX(option) : cropperTool.scaleY(option); - this.setAttribute("data-option", option * -1); - }); - - cropperModal.find('.reset').on('click', function () { - cropperTool.reset(); - }); - - cropperModal.find('.crop-btn').on('click', function () { - $(this).addClass('disabled'); - var imageData = data.imageType ? cropperTool.getCroppedCanvas().toDataURL(data.imageType) : cropperTool.getCroppedCanvas().toDataURL(); - - cropperModal.find('#upload-progress-bar').css('width', '100%'); - cropperModal.find('#upload-progress-box').show().removeClass('hide'); - - socket.emit('user.uploadCroppedPicture', { - uid: ajaxify.data.theirid, - imageData: imageData - }, function (err, imageData) { - if (err) { - cropperModal.find('#upload-progress-box').hide(); - cropperModal.find('.upload-btn').removeClass('disabled'); - cropperModal.find('.crop-btn').removeClass('disabled'); - app.alertError(err.message); - } - - onUploadComplete(imageData.url); - cropperModal.modal('hide'); - }); - }); - - cropperModal.find('.upload-btn').on('click', function () { - $(this).addClass('disabled'); - cropperTool.destroy(); - - cropperTool = new cropper.default(img, { - viewMode: 1, - autoCropArea: 1 - }); - - cropperModal.find('.crop-btn').trigger('click'); - }); - }); - }); - } modal.find('[data-action="upload"]').on('click', function () { modal.modal('hide'); uploader.show({ - route: config.relative_path + '/api/user/' + ajaxify.data.userslug + '/uploadpicture', - params: {}, + socketMethod: 'user.uploadCroppedPicture', + aspectRatio: '1 / 1', + paramName: 'uid', + paramValue: ajaxify.data.theirid, fileSize: ajaxify.data.maximumProfileImageSize, title: '[[user:upload_picture]]', description: '[[user:upload_a_picture]]', accept: '.png,.jpg,.bmp' - }, function (data) { - handleImageCrop(data); + }, function (url) { + onUploadComplete(url); }); return false; @@ -309,7 +244,14 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator', } uploadModal.modal('hide'); - handleImageCrop({url: url}); + + pictureCropper.handleImageCrop({ + url: url, + socketMethod: 'user.uploadCroppedPicture', + aspectRatio: '1 / 1', + paramName: 'uid', + paramValue: ajaxify.data.theirid, + }, onUploadComplete); return false; }); diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index d0f84ade3a..757b87dc1f 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -80,8 +80,10 @@ define('forum/account/header', [ function () { uploader.show({ title: '[[user:upload_cover_picture]]', - route: config.relative_path + '/api/user/' + ajaxify.data.userslug + '/uploadcover', - params: {uid: ajaxify.data.uid }, + socketMethod: 'user.updateCover', + aspectRatio: '16 / 9', + paramName: 'uid', + paramValue: ajaxify.data.theirid, accept: '.png,.jpg,.bmp' }, function (imageUrlOnServer) { components.get('account/cover').css('background-image', 'url(' + imageUrlOnServer + '?' + config['cache-buster'] + ')'); diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js index 96610baf38..9de3e47113 100644 --- a/public/src/client/groups/details.js +++ b/public/src/client/groups/details.js @@ -33,8 +33,10 @@ define('forum/groups/details', [ function () { uploader.show({ title: '[[groups:upload-group-cover]]', - route: config.relative_path + '/api/groups/uploadpicture', - params: {groupName: groupName} + socketMethod: 'groups.cover.update', + aspectRatio: '16 / 9', + paramName: 'groupName', + paramValue: groupName }, function (imageUrlOnServer) { components.get('groups/cover').css('background-image', 'url(' + imageUrlOnServer + ')'); }); diff --git a/public/src/modules/pictureCropper.js b/public/src/modules/pictureCropper.js new file mode 100644 index 0000000000..c4a896b551 --- /dev/null +++ b/public/src/modules/pictureCropper.js @@ -0,0 +1,78 @@ +'use strict'; + +/* globals define, socket, app, templates */ + +define('pictureCropper', ['translator', 'cropper'], function (translator, cropper) { + + var module = {}; + + module.handleImageCrop = function (data, callback) { + $('#crop-picture-modal').remove(); + templates.parse('modals/crop_picture', {url: data.url}, function (cropperHtml) { + translator.translate(cropperHtml, function (translated) { + var cropperModal = $(translated); + cropperModal.modal('show'); + + var img = document.getElementById('cropped-image'); + var cropperTool = new cropper.default(img, { + aspectRatio: data.aspectRatio, + viewMode: 1 + }); + + cropperModal.find('.rotate').on('click', function () { + var degrees = this.getAttribute("data-degrees"); + cropperTool.rotate(degrees); + }); + + cropperModal.find('.flip').on('click', function () { + var option = this.getAttribute("data-option"); + var method = this.getAttribute("data-method"); + method === 'scaleX' ? cropperTool.scaleX(option) : cropperTool.scaleY(option); + this.setAttribute("data-option", option * -1); + }); + + cropperModal.find('.reset').on('click', function () { + cropperTool.reset(); + }); + + cropperModal.find('.crop-btn').on('click', function () { + $(this).addClass('disabled'); + var imageData = data.imageType ? cropperTool.getCroppedCanvas().toDataURL(data.imageType) : cropperTool.getCroppedCanvas().toDataURL(); + + cropperModal.find('#upload-progress-bar').css('width', '100%'); + cropperModal.find('#upload-progress-box').show().removeClass('hide'); + + var socketData = {}; + socketData[data.paramName] = data.paramValue; + socketData['imageData'] = imageData; + + socket.emit(data.socketMethod, socketData, function (err, imageData) { + if (err) { + cropperModal.find('#upload-progress-box').hide(); + cropperModal.find('.upload-btn').removeClass('disabled'); + cropperModal.find('.crop-btn').removeClass('disabled'); + return app.alertError(err.message); + } + + callback(imageData.url); + cropperModal.modal('hide'); + }); + }); + + cropperModal.find('.upload-btn').on('click', function () { + $(this).addClass('disabled'); + cropperTool.destroy(); + + cropperTool = new cropper.default(img, { + viewMode: 1, + autoCropArea: 1 + }); + + cropperModal.find('.crop-btn').trigger('click'); + }); + }); + }); + } + + return module; +}); diff --git a/public/src/modules/uploader.js b/public/src/modules/uploader.js index bae1a2ce00..1a15e0e6ea 100644 --- a/public/src/modules/uploader.js +++ b/public/src/modules/uploader.js @@ -1,8 +1,8 @@ 'use strict'; -/* globals define, ajaxify, socket, app, templates */ +/* globals define, templates */ -define('uploader', ['translator', 'cropper'], function (translator, cropper) { +define('uploader', ['translator', 'pictureCropper'], function (translator, pictureCropper) { var module = {}; @@ -32,17 +32,10 @@ define('uploader', ['translator', 'cropper'], function (translator, cropper) { uploadModal.remove(); }); - var uploadForm = uploadModal.find('#uploadForm'); - uploadForm.attr('action', data.route); - uploadForm.find('#params').val(JSON.stringify(data.params)); - uploadModal.find('#fileUploadSubmitBtn').on('click', function () { $(this).addClass('disabled'); - uploadForm.submit(); - }); - - uploadForm.submit(function () { - onSubmit(uploadModal, fileSize, callback); + data.uploadModal = uploadModal; + onSubmit(data, callback); return false; }); }); @@ -52,16 +45,16 @@ define('uploader', ['translator', 'cropper'], function (translator, cropper) { $(modal).find('#alert-status, #alert-success, #alert-error, #upload-progress-box').addClass('hide'); }; - function onSubmit(uploadModal, fileSize, callback) { + function onSubmit(data, callback) { function showAlert(type, message) { - module.hideAlerts(uploadModal); + module.hideAlerts(data.uploadModal); if (type === 'error') { - uploadModal.find('#fileUploadSubmitBtn').removeClass('disabled'); + data.uploadModal.find('#fileUploadSubmitBtn').removeClass('disabled'); } - uploadModal.find('#alert-' + type).translateText(message).removeClass('hide'); + data.uploadModal.find('#alert-' + type).translateText(message).removeClass('hide'); } - var fileInput = uploadModal.find('#fileInput'); + var fileInput = data.uploadModal.find('#fileInput'); if (!fileInput.val()) { return showAlert('error', '[[uploads:select-file-to-upload]]'); } @@ -74,9 +67,16 @@ define('uploader', ['translator', 'cropper'], function (translator, cropper) { reader.addEventListener("load", function () { imageUrl = reader.result; - uploadModal.modal('hide'); + data.uploadModal.modal('hide'); - callback({url: imageUrl, imageType: imageType}); + pictureCropper.handleImageCrop({ + url: imageUrl, + imageType: imageType, + socketMethod: data.socketMethod, + aspectRatio: data.aspectRatio, + paramName: data.paramName, + paramValue: data.paramValue + }, callback); }, false); if (file) { From 43f4d9819ef664238be949b90d645f98d7d2c983 Mon Sep 17 00:00:00 2001 From: pichalite Date: Fri, 17 Feb 2017 00:54:53 +0000 Subject: [PATCH 10/16] Linting --- public/src/modules/pictureCropper.js | 118 +++++++++++++-------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/public/src/modules/pictureCropper.js b/public/src/modules/pictureCropper.js index c4a896b551..c4887e0d6e 100644 --- a/public/src/modules/pictureCropper.js +++ b/public/src/modules/pictureCropper.js @@ -4,75 +4,75 @@ define('pictureCropper', ['translator', 'cropper'], function (translator, cropper) { - var module = {}; + var module = {}; module.handleImageCrop = function (data, callback) { - $('#crop-picture-modal').remove(); - templates.parse('modals/crop_picture', {url: data.url}, function (cropperHtml) { - translator.translate(cropperHtml, function (translated) { - var cropperModal = $(translated); - cropperModal.modal('show'); + $('#crop-picture-modal').remove(); + templates.parse('modals/crop_picture', {url: data.url}, function (cropperHtml) { + translator.translate(cropperHtml, function (translated) { + var cropperModal = $(translated); + cropperModal.modal('show'); + + var img = document.getElementById('cropped-image'); + var cropperTool = new cropper.default(img, { + aspectRatio: data.aspectRatio, + viewMode: 1 + }); + + cropperModal.find('.rotate').on('click', function () { + var degrees = this.getAttribute("data-degrees"); + cropperTool.rotate(degrees); + }); + + cropperModal.find('.flip').on('click', function () { + var option = this.getAttribute("data-option"); + var method = this.getAttribute("data-method"); + method === 'scaleX' ? cropperTool.scaleX(option) : cropperTool.scaleY(option); + this.setAttribute("data-option", option * -1); + }); + + cropperModal.find('.reset').on('click', function () { + cropperTool.reset(); + }); + + cropperModal.find('.crop-btn').on('click', function () { + $(this).addClass('disabled'); + var imageData = data.imageType ? cropperTool.getCroppedCanvas().toDataURL(data.imageType) : cropperTool.getCroppedCanvas().toDataURL(); - var img = document.getElementById('cropped-image'); - var cropperTool = new cropper.default(img, { - aspectRatio: data.aspectRatio, - viewMode: 1 - }); + cropperModal.find('#upload-progress-bar').css('width', '100%'); + cropperModal.find('#upload-progress-box').show().removeClass('hide'); - cropperModal.find('.rotate').on('click', function () { - var degrees = this.getAttribute("data-degrees"); - cropperTool.rotate(degrees); - }); + var socketData = {}; + socketData[data.paramName] = data.paramValue; + socketData['imageData'] = imageData; - cropperModal.find('.flip').on('click', function () { - var option = this.getAttribute("data-option"); - var method = this.getAttribute("data-method"); - method === 'scaleX' ? cropperTool.scaleX(option) : cropperTool.scaleY(option); - this.setAttribute("data-option", option * -1); - }); + socket.emit(data.socketMethod, socketData, function (err, imageData) { + if (err) { + cropperModal.find('#upload-progress-box').hide(); + cropperModal.find('.upload-btn').removeClass('disabled'); + cropperModal.find('.crop-btn').removeClass('disabled'); + return app.alertError(err.message); + } - cropperModal.find('.reset').on('click', function () { - cropperTool.reset(); + callback(imageData.url); + cropperModal.modal('hide'); }); - - cropperModal.find('.crop-btn').on('click', function () { - $(this).addClass('disabled'); - var imageData = data.imageType ? cropperTool.getCroppedCanvas().toDataURL(data.imageType) : cropperTool.getCroppedCanvas().toDataURL(); - - cropperModal.find('#upload-progress-bar').css('width', '100%'); - cropperModal.find('#upload-progress-box').show().removeClass('hide'); - - var socketData = {}; - socketData[data.paramName] = data.paramValue; - socketData['imageData'] = imageData; - - socket.emit(data.socketMethod, socketData, function (err, imageData) { - if (err) { - cropperModal.find('#upload-progress-box').hide(); - cropperModal.find('.upload-btn').removeClass('disabled'); - cropperModal.find('.crop-btn').removeClass('disabled'); - return app.alertError(err.message); - } - - callback(imageData.url); - cropperModal.modal('hide'); - }); - }); - - cropperModal.find('.upload-btn').on('click', function () { - $(this).addClass('disabled'); - cropperTool.destroy(); - - cropperTool = new cropper.default(img, { - viewMode: 1, - autoCropArea: 1 - }); - - cropperModal.find('.crop-btn').trigger('click'); + }); + + cropperModal.find('.upload-btn').on('click', function () { + $(this).addClass('disabled'); + cropperTool.destroy(); + + cropperTool = new cropper.default(img, { + viewMode: 1, + autoCropArea: 1 }); + + cropperModal.find('.crop-btn').trigger('click'); }); }); - } + }); + }; return module; }); From d784a8dce832f86d2ef2b9207cfe53deba09c123 Mon Sep 17 00:00:00 2001 From: pichalite Date: Fri, 17 Feb 2017 04:26:34 +0000 Subject: [PATCH 11/16] Restore uploader.js --- public/src/modules/uploader.js | 101 ++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/public/src/modules/uploader.js b/public/src/modules/uploader.js index 1a15e0e6ea..0e2a7e7ec8 100644 --- a/public/src/modules/uploader.js +++ b/public/src/modules/uploader.js @@ -2,7 +2,7 @@ /* globals define, templates */ -define('uploader', ['translator', 'pictureCropper'], function (translator, pictureCropper) { +define('uploader', ['translator'], function (translator) { var module = {}; @@ -32,10 +32,17 @@ define('uploader', ['translator', 'pictureCropper'], function (translator, pictu uploadModal.remove(); }); + var uploadForm = uploadModal.find('#uploadForm'); + uploadForm.attr('action', data.route); + uploadForm.find('#params').val(JSON.stringify(data.params)); + uploadModal.find('#fileUploadSubmitBtn').on('click', function () { $(this).addClass('disabled'); - data.uploadModal = uploadModal; - onSubmit(data, callback); + uploadForm.submit(); + }); + + uploadForm.submit(function () { + onSubmit(uploadModal, fileSize, callback); return false; }); }); @@ -45,43 +52,55 @@ define('uploader', ['translator', 'pictureCropper'], function (translator, pictu $(modal).find('#alert-status, #alert-success, #alert-error, #upload-progress-box').addClass('hide'); }; - function onSubmit(data, callback) { + function onSubmit(uploadModal, fileSize, callback) { function showAlert(type, message) { - module.hideAlerts(data.uploadModal); + module.hideAlerts(uploadModal); if (type === 'error') { - data.uploadModal.find('#fileUploadSubmitBtn').removeClass('disabled'); + uploadModal.find('#fileUploadSubmitBtn').removeClass('disabled'); } - data.uploadModal.find('#alert-' + type).translateText(message).removeClass('hide'); + uploadModal.find('#alert-' + type).translateText(message).removeClass('hide'); } - var fileInput = data.uploadModal.find('#fileInput'); + showAlert('status', '[[uploads:uploading-file]]'); + + uploadModal.find('#upload-progress-bar').css('width', '0%'); + uploadModal.find('#upload-progress-box').show().removeClass('hide'); + + var fileInput = uploadModal.find('#fileInput'); if (!fileInput.val()) { return showAlert('error', '[[uploads:select-file-to-upload]]'); } - - var file = fileInput[0].files[0]; - var reader = new FileReader(); - var imageUrl; - var imageType = file.type; - - reader.addEventListener("load", function () { - imageUrl = reader.result; - - data.uploadModal.modal('hide'); - - pictureCropper.handleImageCrop({ - url: imageUrl, - imageType: imageType, - socketMethod: data.socketMethod, - aspectRatio: data.aspectRatio, - paramName: data.paramName, - paramValue: data.paramValue - }, callback); - }, false); - - if (file) { - reader.readAsDataURL(file); + if (!hasValidFileSize(fileInput[0], fileSize)) { + return showAlert('error', '[[error:file-too-big, ' + fileSize + ']]'); } + + uploadModal.find('#uploadForm').ajaxSubmit({ + headers: { + 'x-csrf-token': config.csrf_token + }, + error: function (xhr) { + xhr = maybeParse(xhr); + showAlert('error', xhr.responseJSON ? (xhr.responseJSON.error || xhr.statusText) : 'error uploading, code : ' + xhr.status); + }, + uploadProgress: function (event, position, total, percent) { + uploadModal.find('#upload-progress-bar').css('width', percent + '%'); + }, + success: function (response) { + response = maybeParse(response); + + if (response.error) { + return showAlert('error', response.error); + } + + callback(response[0].url); + + showAlert('success', '[[uploads:upload-success]]'); + setTimeout(function () { + module.hideAlerts(uploadModal); + uploadModal.modal('hide'); + }, 750); + } + }); } function parseModal(tplVals, callback) { @@ -90,5 +109,23 @@ define('uploader', ['translator', 'pictureCropper'], function (translator, pictu }); } + function maybeParse(response) { + if (typeof response === 'string') { + try { + return $.parseJSON(response); + } catch (e) { + return {error: '[[error:parse-error]]'}; + } + } + return response; + } + + function hasValidFileSize(fileElement, maxSize) { + if (window.FileReader && maxSize) { + return fileElement.files[0].size <= maxSize * 1000; + } + return true; + } + return module; -}); +}); \ No newline at end of file From 2ca8f60e7745ad3b3c2656dbd213133212af6ba3 Mon Sep 17 00:00:00 2001 From: pichalite Date: Fri, 17 Feb 2017 05:32:37 +0000 Subject: [PATCH 12/16] Finalize cropper module --- public/src/client/account/edit.js | 4 +- public/src/client/account/header.js | 6 +- public/src/client/groups/details.js | 6 +- public/src/modules/pictureCropper.js | 182 +++++++++++++++++++-------- 4 files changed, 135 insertions(+), 63 deletions(-) diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js index 03e9f2914a..bc80fd49e5 100644 --- a/public/src/client/account/edit.js +++ b/public/src/client/account/edit.js @@ -2,7 +2,7 @@ /* globals define, ajaxify, socket, app, config, templates, bootbox */ -define('forum/account/edit', ['forum/account/header', 'uploader', 'translator', 'components', 'pictureCropper'], function (header, uploader, translator, components, pictureCropper) { +define('forum/account/edit', ['forum/account/header', 'translator', 'components', 'pictureCropper'], function (header, translator, components, pictureCropper) { var AccountEdit = {}; AccountEdit.init = function () { @@ -214,7 +214,7 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator', modal.find('[data-action="upload"]').on('click', function () { modal.modal('hide'); - uploader.show({ + pictureCropper.show({ socketMethod: 'user.uploadCroppedPicture', aspectRatio: '1 / 1', paramName: 'uid', diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index 757b87dc1f..7dcf320fbe 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -3,10 +3,10 @@ define('forum/account/header', [ 'coverPhoto', - 'uploader', + 'pictureCropper', 'components', 'translator' -], function (coverPhoto, uploader, components, translator) { +], function (coverPhoto, pictureCropper, components, translator) { var AccountHeader = {}; var isAdminOrSelfOrGlobalMod; @@ -78,7 +78,7 @@ define('forum/account/header', [ }, callback); }, function () { - uploader.show({ + pictureCropper.show({ title: '[[user:upload_cover_picture]]', socketMethod: 'user.updateCover', aspectRatio: '16 / 9', diff --git a/public/src/client/groups/details.js b/public/src/client/groups/details.js index 9de3e47113..771c355fcc 100644 --- a/public/src/client/groups/details.js +++ b/public/src/client/groups/details.js @@ -6,10 +6,10 @@ define('forum/groups/details', [ 'iconSelect', 'components', 'coverPhoto', - 'uploader', + 'pictureCropper', 'translator', 'vendor/colorpicker/colorpicker' -], function (memberList, iconSelect, components, coverPhoto, uploader, translator) { +], function (memberList, iconSelect, components, coverPhoto, pictureCropper, translator) { var Details = {}; var groupName; @@ -31,7 +31,7 @@ define('forum/groups/details', [ }, callback); }, function () { - uploader.show({ + pictureCropper.show({ title: '[[groups:upload-group-cover]]', socketMethod: 'groups.cover.update', aspectRatio: '16 / 9', diff --git a/public/src/modules/pictureCropper.js b/public/src/modules/pictureCropper.js index c4887e0d6e..40be206c19 100644 --- a/public/src/modules/pictureCropper.js +++ b/public/src/modules/pictureCropper.js @@ -3,8 +3,33 @@ /* globals define, socket, app, templates */ define('pictureCropper', ['translator', 'cropper'], function (translator, cropper) { + var module = {}; - var module = {}; + module.show = function (data, callback) { + var fileSize = data.hasOwnProperty('fileSize') && data.fileSize !== undefined ? parseInt(data.fileSize, 10) : false; + parseModal({ + showHelp: data.hasOwnProperty('showHelp') && data.showHelp !== undefined ? data.showHelp : true, + fileSize: fileSize, + title: data.title || '[[global:upload_file]]', + description: data.description || '', + button: data.button || '[[global:upload]]', + accept: data.accept ? data.accept.replace(/,/g, ', ') : '' + }, function (uploadModal) { + uploadModal = $(uploadModal); + + uploadModal.modal('show'); + uploadModal.on('hidden.bs.modal', function () { + uploadModal.remove(); + }); + + uploadModal.find('#fileUploadSubmitBtn').on('click', function () { + $(this).addClass('disabled'); + data.uploadModal = uploadModal; + onSubmit(data, callback); + return false; + }); + }); + }; module.handleImageCrop = function (data, callback) { $('#crop-picture-modal').remove(); @@ -12,67 +37,114 @@ define('pictureCropper', ['translator', 'cropper'], function (translator, croppe translator.translate(cropperHtml, function (translated) { var cropperModal = $(translated); cropperModal.modal('show'); - + var img = document.getElementById('cropped-image'); var cropperTool = new cropper.default(img, { aspectRatio: data.aspectRatio, - viewMode: 1 - }); - - cropperModal.find('.rotate').on('click', function () { - var degrees = this.getAttribute("data-degrees"); - cropperTool.rotate(degrees); - }); - - cropperModal.find('.flip').on('click', function () { - var option = this.getAttribute("data-option"); - var method = this.getAttribute("data-method"); - method === 'scaleX' ? cropperTool.scaleX(option) : cropperTool.scaleY(option); - this.setAttribute("data-option", option * -1); - }); - - cropperModal.find('.reset').on('click', function () { - cropperTool.reset(); - }); - - cropperModal.find('.crop-btn').on('click', function () { - $(this).addClass('disabled'); - var imageData = data.imageType ? cropperTool.getCroppedCanvas().toDataURL(data.imageType) : cropperTool.getCroppedCanvas().toDataURL(); - - cropperModal.find('#upload-progress-bar').css('width', '100%'); - cropperModal.find('#upload-progress-box').show().removeClass('hide'); - - var socketData = {}; - socketData[data.paramName] = data.paramValue; - socketData['imageData'] = imageData; - - socket.emit(data.socketMethod, socketData, function (err, imageData) { - if (err) { - cropperModal.find('#upload-progress-box').hide(); - cropperModal.find('.upload-btn').removeClass('disabled'); - cropperModal.find('.crop-btn').removeClass('disabled'); - return app.alertError(err.message); - } - - callback(imageData.url); - cropperModal.modal('hide'); - }); - }); - - cropperModal.find('.upload-btn').on('click', function () { - $(this).addClass('disabled'); - cropperTool.destroy(); - - cropperTool = new cropper.default(img, { - viewMode: 1, - autoCropArea: 1 - }); - - cropperModal.find('.crop-btn').trigger('click'); + viewMode: 1, + ready: function () { + cropperModal.find('.rotate').on('click', function () { + var degrees = this.getAttribute("data-degrees"); + cropperTool.rotate(degrees); + }); + + cropperModal.find('.flip').on('click', function () { + var option = this.getAttribute("data-option"); + var method = this.getAttribute("data-method"); + method === 'scaleX' ? cropperTool.scaleX(option) : cropperTool.scaleY(option); + this.setAttribute("data-option", option * -1); + }); + + cropperModal.find('.reset').on('click', function () { + cropperTool.reset(); + }); + + cropperModal.find('.crop-btn').on('click', function () { + $(this).addClass('disabled'); + var imageData = data.imageType ? cropperTool.getCroppedCanvas().toDataURL(data.imageType) : cropperTool.getCroppedCanvas().toDataURL(); + + cropperModal.find('#upload-progress-bar').css('width', '100%'); + cropperModal.find('#upload-progress-box').show().removeClass('hide'); + + var socketData = {}; + socketData[data.paramName] = data.paramValue; + socketData['imageData'] = imageData; + + socket.emit(data.socketMethod, socketData, function (err, imageData) { + if (err) { + cropperModal.find('#upload-progress-box').hide(); + cropperModal.find('.upload-btn').removeClass('disabled'); + cropperModal.find('.crop-btn').removeClass('disabled'); + return app.alertError(err.message); + } + + callback(imageData.url); + cropperModal.modal('hide'); + }); + }); + + cropperModal.find('.upload-btn').on('click', function () { + $(this).addClass('disabled'); + cropperTool.destroy(); + + cropperTool = new cropper.default(img, { + viewMode: 1, + autoCropArea: 1, + ready: function () { + cropperModal.find('.crop-btn').trigger('click'); + } + }); + }); + } }); }); }); }; + function onSubmit(data, callback) { + function showAlert(type, message) { + module.hideAlerts(data.uploadModal); + if (type === 'error') { + data.uploadModal.find('#fileUploadSubmitBtn').removeClass('disabled'); + } + data.uploadModal.find('#alert-' + type).translateText(message).removeClass('hide'); + } + + var fileInput = data.uploadModal.find('#fileInput'); + if (!fileInput.val()) { + return showAlert('error', '[[uploads:select-file-to-upload]]'); + } + + var file = fileInput[0].files[0]; + var reader = new FileReader(); + var imageUrl; + var imageType = file.type; + + reader.addEventListener("load", function () { + imageUrl = reader.result; + + data.uploadModal.modal('hide'); + + module.handleImageCrop({ + url: imageUrl, + imageType: imageType, + socketMethod: data.socketMethod, + aspectRatio: data.aspectRatio, + paramName: data.paramName, + paramValue: data.paramValue + }, callback); + }, false); + + if (file) { + reader.readAsDataURL(file); + } + } + + function parseModal(tplVals, callback) { + templates.parse('partials/modals/upload_file_modal', tplVals, function (html) { + translator.translate(html, callback); + }); + } + return module; }); From 461ad301a1b21349d6f77069a6d85aeda16c2e71 Mon Sep 17 00:00:00 2001 From: "Misty (Bot)" Date: Fri, 17 Feb 2017 09:22:25 +0000 Subject: [PATCH 13/16] Latest translations and fallbacks --- .../tr/admin/appearance/customise.json | 4 +- .../language/tr/admin/general/dashboard.json | 64 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/public/language/tr/admin/appearance/customise.json b/public/language/tr/admin/appearance/customise.json index faf0f66b15..83e506e854 100644 --- a/public/language/tr/admin/appearance/customise.json +++ b/public/language/tr/admin/appearance/customise.json @@ -1,9 +1,9 @@ { "custom-css": "Özel CSS", "custom-css.description": "Enter your own CSS declarations here, which will be applied after all other styles.", - "custom-css.enable": "Enable Custom CSS", + "custom-css.enable": "Özel CSS Aktif", - "custom-header": "Custom Header", + "custom-header": "Özel Header", "custom-header.description": "Enter custom HTML here (ex. JavaScript, Meta Tags, etc.), which will be appended to the <head> section of your forum's markup.", "custom-header.enable": "Enable Custom Header" } \ No newline at end of file diff --git a/public/language/tr/admin/general/dashboard.json b/public/language/tr/admin/general/dashboard.json index 0ebf6e50f6..33e63acd78 100644 --- a/public/language/tr/admin/general/dashboard.json +++ b/public/language/tr/admin/general/dashboard.json @@ -15,49 +15,49 @@ "stats.all": "Tüm Zamanlar", "updates": "Güncellemeler", - "running-version": "You are running NodeBB v%1.", - "keep-updated": "Always make sure that your NodeBB is up to date for the latest security patches and bug fixes.", + "running-version": "NodeBB v%1 çalışıyor.", + "keep-updated": "En son güvenlik değişiklikleri ve hata düzeltmeleri için NodeBB güncel olduğundan emin olun.", "up-to-date": "

You are up-to-date

", "upgrade-available": "

A new version (v%1) has been released. Consider upgrading your NodeBB.

", "prerelease-upgrade-available": "

This is an outdated pre-release version of NodeBB. A new version (v%1) has been released. Consider upgrading your NodeBB.

", "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", - "notices": "Notices", - "restart-not-required": "Restart not required", - "restart-required": "Restart required", - "search-plugin-installed": "Search Plugin installed", - "search-plugin-not-installed": "Search Plugin not installed", + "notices": "Bildirimler", + "restart-not-required": "Yeniden başlatma gerekmiyor", + "restart-required": "Yeniden başlatma gerekiyor", + "search-plugin-installed": "Arama Eklentisi yüklendi", + "search-plugin-not-installed": "Arama Eklentisi yüklenmedi", "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "Sistem Kontrol", - "reload": "Reload", - "restart": "Restart", + "reload": "Tekrar Yükle", + "restart": "Yeniden Başlat", "restart-warning": "Reloading or Restarting your NodeBB will drop all existing connections for a few seconds.", "maintenance-mode": "Bakım Modu", - "maintenance-mode-title": "Click here to set up maintenance mode for NodeBB", - "realtime-chart-updates": "Realtime Chart Updates", - - "active-users": "Active Users", - "active-users.users": "Users", - "active-users.guests": "Guests", - "active-users.total": "Total", - "active-users.connections": "Connections", - - "anonymous-registered-users": "Anonymous vs Registered Users", - "anonymous": "Anonymous", - "registered": "Registered", - - "user-presence": "User Presence", - "on-categories": "On categories list", - "reading-posts": "Reading posts", - "browsing-topics": "Browsing topics", - "recent": "Recent", - "unread": "Unread", + "maintenance-mode-title": "NodeBB için bakım modunu ayarlamak için buraya tıklayın", + "realtime-chart-updates": "Gerçek Zamanlı Grafik Güncellemeleri", + + "active-users": "Aktif Kullanıcılar", + "active-users.users": "Kullanıcılar", + "active-users.guests": "Ziyaretçiler", + "active-users.total": "Genel Toplam", + "active-users.connections": "Bağlantılar", + + "anonymous-registered-users": "Anonim vs Kayıtlı Kullanıcılar", + "anonymous": "Anonim", + "registered": "Kayıtlı", + + "user-presence": "Kullanıcı Durumları", + "on-categories": "Kategoriler listesinde", + "reading-posts": "Okunan İletiler", + "browsing-topics": "Gözden Geçirilen Başlıklar", + "recent": "Yeni", + "unread": "Okunmamış", "high-presence-topics": "High Presence Topics", - "graphs.page-views": "Page Views", - "graphs.unique-visitors": "Unique Visitors", - "graphs.registered-users": "Registered Users", - "graphs.anonymous-users": "Anonymous Users" + "graphs.page-views": "Sayfa Gösterimi", + "graphs.unique-visitors": "Benzersiz Ziyaretçiler", + "graphs.registered-users": "Kayıtlı Kullanıcılar", + "graphs.anonymous-users": "Anonim Kullanıcılar" } From 4d05e492cc7f6e489ee96fd10628b6c958d3f1d2 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 17 Feb 2017 14:45:36 +0300 Subject: [PATCH 14/16] closes #5312 --- public/src/client/account/header.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index d0f84ade3a..6b33d70e16 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -42,7 +42,9 @@ define('forum/account/header', [ }); components.get('account/new-chat').on('click', function () { - app.newChat(ajaxify.data.uid); + app.newChat(ajaxify.data.uid, function () { + components.get('account/chat').parent().removeClass('hidden'); + }); }); @@ -173,7 +175,7 @@ define('forum/account/header', [ if (!confirm) { return; } - + socket.emit('user.removeCover', { uid: ajaxify.data.uid }, function (err) { From a427bba9cb4cc705c1f009e47b8347600d4fb2e8 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 17 Feb 2017 14:48:09 +0300 Subject: [PATCH 15/16] up persona --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2e16cc0e19..e10b8ec9b6 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "nodebb-plugin-spam-be-gone": "0.4.10", "nodebb-rewards-essentials": "0.0.9", "nodebb-theme-lavender": "3.0.15", - "nodebb-theme-persona": "4.2.2", + "nodebb-theme-persona": "4.2.3", "nodebb-theme-vanilla": "5.2.0", "nodebb-widget-essentials": "2.0.13", "nodemailer": "2.6.4", From e009ce5609a0c1901e8785986d9d02ecc9ab6272 Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 17 Feb 2017 16:46:30 +0300 Subject: [PATCH 16/16] closes #5443 --- package.json | 2 +- public/src/client/category.js | 23 ++++++++++++++++------- public/src/modules/navigator.js | 16 +++++++--------- src/controllers/category.js | 2 +- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index e10b8ec9b6..e5907c0378 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "nodebb-plugin-spam-be-gone": "0.4.10", "nodebb-rewards-essentials": "0.0.9", "nodebb-theme-lavender": "3.0.15", - "nodebb-theme-persona": "4.2.3", + "nodebb-theme-persona": "4.2.4", "nodebb-theme-vanilla": "5.2.0", "nodebb-widget-essentials": "2.0.13", "nodemailer": "2.6.4", diff --git a/public/src/client/category.js b/public/src/client/category.js index 24b0d274f6..d0af1d21b2 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -58,12 +58,25 @@ define('forum/category', [ }); }); + handleScrollToTopicIndex(); + handleIgnoreWatch(cid); $(window).trigger('action:topics.loaded', {topics: ajaxify.data.topics}); $(window).trigger('action:category.loaded', {cid: ajaxify.data.cid}); }; + function handleScrollToTopicIndex() { + var parts = window.location.pathname.split('/'); + var topicIndex = parts[parts.length - 1]; + if (topicIndex && utils.isNumber(topicIndex)) { + topicIndex = Math.max(0, parseInt(topicIndex, 10) - 1); + if (topicIndex && window.location.search.indexOf('page=') === -1) { + navigator.scrollToElement($('[component="category/topic"][data-index="' + topicIndex + '"]'), true, 0); + } + } + } + function handleIgnoreWatch(cid) { $('[component="category/watching"], [component="category/ignoring"]').on('click', function () { var $this = $(this); @@ -104,14 +117,10 @@ define('forum/category', [ }; $(window).on('action:ajaxify.contentLoaded', function (ev, data) { - if (ajaxify.data.template.category) { - var cid = ajaxify.data.cid; - if (!cid) { - return; - } + if (ajaxify.data.template.category && ajaxify.data.cid) { - var bookmarkIndex = localStorage.getItem('category:' + cid + ':bookmark'); - var clickedIndex = localStorage.getItem('category:' + cid + ':bookmark:clicked'); + var bookmarkIndex = localStorage.getItem('category:' + ajaxify.data.cid + ':bookmark'); + var clickedIndex = localStorage.getItem('category:' + ajaxify.data.cid + ':bookmark:clicked'); bookmarkIndex = Math.max(0, parseInt(bookmarkIndex, 10) || 0); clickedIndex = Math.max(0, parseInt(clickedIndex, 10) || 0); diff --git a/public/src/modules/navigator.js b/public/src/modules/navigator.js index c6ef158221..d7ecccf965 100644 --- a/public/src/modules/navigator.js +++ b/public/src/modules/navigator.js @@ -238,14 +238,17 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co navigator.scrollToPostIndex = function (postIndex, highlight, duration) { var scrollTo = components.get('post', 'index', postIndex); - var postHeight = scrollTo.height(); - var viewportHeight = $(window).height(); - var navbarHeight = components.get('navbar').height(); + navigator.scrollToElement(scrollTo, highlight, duration); + }; + navigator.scrollToElement = function(scrollTo, highlight, duration) { if (!scrollTo.length) { navigator.scrollActive = false; return; } + var postHeight = scrollTo.height(); + var viewportHeight = $(window).height(); + var navbarHeight = components.get('navbar').height(); // Temporarily disable navigator update on scroll $(window).off('scroll', navigator.update); @@ -290,13 +293,8 @@ define('navigator', ['forum/pagination', 'components'], function (pagination, co } } - if (components.get('topic').length) { - animateScroll(); - } else { - navigator.scrollActive = false; - } + animateScroll(); }; - return navigator; }); diff --git a/src/controllers/category.js b/src/controllers/category.js index bb9efe1cb5..3570f279ee 100644 --- a/src/controllers/category.js +++ b/src/controllers/category.js @@ -69,7 +69,7 @@ categoryController.get = function (req, res, callback) { } if (!settings.usePagination) { - topicIndex = Math.max(topicIndex - (settings.topicsPerPage - 1), 0); + topicIndex = Math.max(0, topicIndex - (Math.ceil(settings.topicsPerPage / 2) - 1)); } else if (!req.query.page) { var index = Math.max(parseInt((topicIndex || 0), 10), 0); currentPage = Math.ceil((index + 1) / settings.topicsPerPage);