refactor: add thumbsOnly option to thumbs retrieval method so that embeds/attachments don't show up in composer thumbnail modal

This commit is contained in:
Julian Lam
2024-12-17 11:14:29 -05:00
parent f4835695de
commit 51fd65abc8
5 changed files with 48 additions and 27 deletions

View File

@@ -11,6 +11,13 @@ get:
required: true required: true
description: a valid topic id description: a valid topic id
example: 1 example: 1
- in: query
name: thumbsOnly
schema:
type: boolean
required: false
description: "(default: false) exclude post attachments, uploaded media, and those added by plugins"
example: 0
responses: responses:
'200': '200':
description: Thumbnails successfully retrieved description: Thumbnails successfully retrieved

View File

@@ -5,7 +5,7 @@ define('topicThumbs', [
], function (api, bootbox, alerts, uploader, Benchpress, translator) { ], function (api, bootbox, alerts, uploader, Benchpress, translator) {
const Thumbs = {}; const Thumbs = {};
Thumbs.get = id => api.get(`/topics/${id}/thumbs`, {}); Thumbs.get = id => api.get(`/topics/${id}/thumbs`, { thumbsOnly: 1 });
Thumbs.getByPid = pid => api.get(`/posts/${encodeURIComponent(pid)}`, {}).then(post => Thumbs.get(post.tid)); Thumbs.getByPid = pid => api.get(`/posts/${encodeURIComponent(pid)}`, {}).then(post => Thumbs.get(post.tid));

View File

@@ -215,7 +215,7 @@ topicsAPI.deleteTags = async (caller, { tid }) => {
await topics.deleteTopicTags(tid); await topics.deleteTopicTags(tid);
}; };
topicsAPI.getThumbs = async (caller, { tid }) => { topicsAPI.getThumbs = async (caller, { tid, thumbsOnly }) => {
if (isFinite(tid)) { // post_uuids can be passed in occasionally, in that case no checks are necessary if (isFinite(tid)) { // post_uuids can be passed in occasionally, in that case no checks are necessary
const [exists, canRead] = await Promise.all([ const [exists, canRead] = await Promise.all([
topics.exists(tid), topics.exists(tid),
@@ -229,7 +229,7 @@ topicsAPI.getThumbs = async (caller, { tid }) => {
} }
} }
return await topics.thumbs.get(tid); return await topics.thumbs.get(tid, { thumbsOnly });
}; };
// topicsAPI.addThumb // topicsAPI.addThumb

View File

@@ -127,7 +127,9 @@ Topics.deleteTags = async (req, res) => {
}; };
Topics.getThumbs = async (req, res) => { Topics.getThumbs = async (req, res) => {
helpers.formatApiResponse(200, res, await api.topics.getThumbs(req, { ...req.params })); let { thumbsOnly } = req.query;
thumbsOnly = thumbsOnly ? !!parseInt(thumbsOnly, 10) : false;
helpers.formatApiResponse(200, res, await api.topics.getThumbs(req, { ...req.params, thumbsOnly }));
}; };
Topics.addThumb = async (req, res) => { Topics.addThumb = async (req, res) => {

View File

@@ -41,7 +41,7 @@ Thumbs.load = async function (topicData) {
return topicData.map(t => (t && t.tid ? (tidToThumbs[t.tid] || []) : [])); return topicData.map(t => (t && t.tid ? (tidToThumbs[t.tid] || []) : []));
}; };
Thumbs.get = async function (tids) { Thumbs.get = async function (tids, options) {
// Allow singular or plural usage // Allow singular or plural usage
let singular = false; let singular = false;
if (!Array.isArray(tids)) { if (!Array.isArray(tids)) {
@@ -49,6 +49,12 @@ Thumbs.get = async function (tids) {
singular = true; singular = true;
} }
if (!options) {
options = {
thumbsOnly: false,
};
}
const isDraft = !await topics.exists(tids); const isDraft = !await topics.exists(tids);
if (!meta.config.allowTopicsThumbnail || !tids.length) { if (!meta.config.allowTopicsThumbnail || !tids.length) {
@@ -63,30 +69,32 @@ Thumbs.get = async function (tids) {
let mainPids = await topics.getTopicsFields(tids, ['mainPid']); let mainPids = await topics.getTopicsFields(tids, ['mainPid']);
mainPids = mainPids.map(o => o.mainPid); mainPids = mainPids.map(o => o.mainPid);
// Add uploaded media to thumb sets if (!options.thumbsOnly) {
const mainPidUploads = await Promise.all(mainPids.map(async pid => await posts.uploads.list(pid))); // Add uploaded media to thumb sets
mainPidUploads.forEach((uploads, idx) => { const mainPidUploads = await Promise.all(mainPids.map(async pid => await posts.uploads.list(pid)));
uploads = uploads.map(path => `/${path}`); mainPidUploads.forEach((uploads, idx) => {
uploads = uploads.filter( uploads = uploads.map(path => `/${path}`);
upload => !thumbs[idx].includes(upload) && mime.getType(upload).startsWith('image/') uploads = uploads.filter(
); upload => !thumbs[idx].includes(upload) && mime.getType(upload).startsWith('image/')
);
if (uploads.length) { if (uploads.length) {
thumbs[idx].push(...uploads); thumbs[idx].push(...uploads);
} }
}); });
// Add attachments to thumb sets // Add attachments to thumb sets
const mainPidAttachments = await posts.attachments.get(mainPids); const mainPidAttachments = await posts.attachments.get(mainPids);
mainPidAttachments.forEach((attachments, idx) => { mainPidAttachments.forEach((attachments, idx) => {
attachments = attachments.filter( attachments = attachments.filter(
attachment => !thumbs[idx].includes(attachment.url) && (attachment.mediaType && attachment.mediaType.startsWith('image/')) attachment => !thumbs[idx].includes(attachment.url) && (attachment.mediaType && attachment.mediaType.startsWith('image/'))
); );
if (attachments.length) { if (attachments.length) {
thumbs[idx].push(...attachments.map(attachment => attachment.url)); thumbs[idx].push(...attachments.map(attachment => attachment.url));
} }
}); });
}
let response = thumbs.map((thumbSet, idx) => thumbSet.map(thumb => ({ let response = thumbs.map((thumbSet, idx) => thumbSet.map(thumb => ({
id: tids[idx], id: tids[idx],
@@ -98,7 +106,11 @@ Thumbs.get = async function (tids) {
url: thumb.startsWith('http') ? thumb : path.posix.join(upload_url, thumb.replace(/\\/g, '/')), url: thumb.startsWith('http') ? thumb : path.posix.join(upload_url, thumb.replace(/\\/g, '/')),
}))); })));
({ thumbs: response } = await plugins.hooks.fire('filter:topics.getThumbs', { tids, thumbs: response })); ({ thumbs: response } = await plugins.hooks.fire('filter:topics.getThumbs', {
tids,
thumbsOnly: options.thumbsOnly,
thumbs: response,
}));
return singular ? response.pop() : response; return singular ? response.pop() : response;
}; };