From a30c8ab5c80a80857fea127f8fed219def9a98b3 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 8 Dec 2020 12:26:07 -0500 Subject: [PATCH] feat: clent-side modal for managing topic thumbs closes #9087 --- public/.eslintrc | 3 +- public/language/en-GB/modules.json | 9 +++- public/less/modals.less | 6 +++ public/src/modules/topicThumbs.js | 75 +++++++++++++++++++++++++++++- src/controllers/api.js | 3 ++ src/topics/thumbs.js | 4 +- src/views/modals/topic-thumbs.tpl | 20 ++++++++ 7 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 src/views/modals/topic-thumbs.tpl diff --git a/public/.eslintrc b/public/.eslintrc index 606f50bebb..04903c5f62 100644 --- a/public/.eslintrc +++ b/public/.eslintrc @@ -31,11 +31,10 @@ "prefer-template": "off" }, "parserOptions": { - "ecmaVersion": 6, + "ecmaVersion": 2018, "ecmaFeatures": { "classes": false, "defaultParams": false, - "experimentalObjectRestSpread": false, "blockBindings": false, "forOf": false, "generators": false, diff --git a/public/language/en-GB/modules.json b/public/language/en-GB/modules.json index 0ce26e11d7..5d8500b287 100644 --- a/public/language/en-GB/modules.json +++ b/public/language/en-GB/modules.json @@ -70,5 +70,12 @@ "cover.dragging_title": "Cover Photo Positioning", "cover.dragging_message": "Drag the cover photo to the desired position and click \"Save\"", - "cover.saved": "Cover photo image and position saved" + "cover.saved": "Cover photo image and position saved", + + "thumbs.modal.title": "Manage topic thumbnails", + "thumbs.modal.no-thumbs": "No thumbnails found.", + "thumbs.modal.resize-note": "Note: This forum is configured to resize topic thumbnails down to a maximum width of %1px", + "thumbs.modal.add": "Add thumbnail", + "thumbs.modal.remove": "Remove thumbnail", + "thumbs.modal.confirm-remove": "Are you sure you want to remove this thumbnail?" } \ No newline at end of file diff --git a/public/less/modals.less b/public/less/modals.less index 96e47ebb53..8bf0da402e 100644 --- a/public/less/modals.less +++ b/public/less/modals.less @@ -9,4 +9,10 @@ .tool-modal { max-width: 33%; } +} + +.topic-thumbs-modal { + img.media-object { + max-width: 20rem; + } } \ No newline at end of file diff --git a/public/src/modules/topicThumbs.js b/public/src/modules/topicThumbs.js index f1ef70531f..f7fd7dfc54 100644 --- a/public/src/modules/topicThumbs.js +++ b/public/src/modules/topicThumbs.js @@ -1,6 +1,6 @@ 'use strict'; -define('topicThumbs', ['api'], function (api) { +define('topicThumbs', ['api', 'bootbox', 'uploader', 'benchpress', 'translator'], function (api, bootbox, uploader, Benchpress, translator) { const Thumbs = {}; Thumbs.get = id => api.get(`/topics/${id}/thumbs`, {}); @@ -17,5 +17,78 @@ define('topicThumbs', ['api'], function (api) { }); }; + Thumbs.upload = id => new Promise((resolve) => { + uploader.show({ + title: '[[topic:composer.thumb_title]]', + method: 'put', + route: config.relative_path + `/api/v3/topics/${id}/thumbs`, + }, function (url) { + resolve(url); + }); + }); + + Thumbs.modal = {}; + + Thumbs.modal.open = function (payload) { + const { id, pid } = payload; + let { modal } = payload; + + return new Promise((resolve) => { + Promise.all([ + Thumbs.get(id), + pid ? Thumbs.getByPid(pid) : [], + ]).then(results => new Promise((resolve) => { + resolve(results.reduce((memo, cur) => memo.concat(cur))); + })).then(thumbs => Benchpress.render('modals/topic-thumbs', { thumbs })).then((html) => { + if (modal) { + translator.translate(html, function (translated) { + modal.find('.bootbox-body').html(translated); + }); + } else { + modal = bootbox.dialog({ + title: '[[modules:thumbs.modal.title]]', + message: html, + buttons: { + add: { + label: ' [[modules:thumbs.modal.add]]', + className: 'btn-primary', + callback: () => { + Thumbs.upload(id).then(() => { + Thumbs.modal.open({ ...payload, modal }); + resolve(); + }); + return false; + }, + }, + }, + }); + Thumbs.modal.handleDelete({ ...payload, modal }); + } + }); + }); + }; + + Thumbs.modal.handleDelete = (payload) => { + const modalEl = payload.modal.get(0); + + modalEl.addEventListener('click', (ev) => { + if (ev.target.closest('button[data-action="remove"]')) { + bootbox.confirm('[[modules:thumbs.modal.confirm-remove]]', (ok) => { + if (!ok) { + return; + } + + const id = ev.target.closest('.media[data-id]').getAttribute('data-id'); + const path = ev.target.closest('.media[data-path]').getAttribute('data-path'); + api.del(`/topics/${id}/thumbs`, { + path: path, + }).then(() => { + Thumbs.modal.open(payload); + }).catch(app.alertError); + }); + } + }); + }; + return Thumbs; }); diff --git a/src/controllers/api.js b/src/controllers/api.js index c3d36999ff..57e98ed0b7 100644 --- a/src/controllers/api.js +++ b/src/controllers/api.js @@ -77,6 +77,9 @@ apiController.loadConfig = async function (req) { link: translator.escape(validator.escape(meta.config.cookieConsentLink || '[[global:cookies.learn_more]]')).replace(/\\/g, '\\\\'), link_url: translator.escape(validator.escape(meta.config.cookieConsentLinkUrl || 'https://www.cookiesandyou.com')).replace(/\\/g, '\\\\'), }, + thumbs: { + size: meta.config.topicThumbSize, + }, }; let settings = config; diff --git a/src/topics/thumbs.js b/src/topics/thumbs.js index f024fa8886..0601f79982 100644 --- a/src/topics/thumbs.js +++ b/src/topics/thumbs.js @@ -29,7 +29,9 @@ Thumbs.get = async function (tids) { const sets = tids.map(tid => `${validator.isUUID(String(tid)) ? 'draft' : 'topic'}:${tid}:thumbs`); const thumbs = await db.getSortedSetsMembers(sets); - let response = thumbs.map(thumbSet => thumbSet.map(thumb => ({ + let response = thumbs.map(thumbSet => thumbSet.map((thumb, idx) => ({ + id: tids[idx], + name: path.basename(thumb), url: path.join(nconf.get('upload_url'), thumb), }))); diff --git a/src/views/modals/topic-thumbs.tpl b/src/views/modals/topic-thumbs.tpl new file mode 100644 index 0000000000..7ee9773836 --- /dev/null +++ b/src/views/modals/topic-thumbs.tpl @@ -0,0 +1,20 @@ +
+ {{{ if !thumbs.length }}} +
[[modules:thumbs.modal.no-thumbs]]
+ {{{ end }}} + {{{ each thumbs }}} +
+
+ +
+
+

+ {./name} +

+ +
+
+
+ {{{ end }}} +

[[modules:thumbs.modal.resize-note, {config.thumbs.size}]]

+
\ No newline at end of file