From 1257aa981e2b062df8993b3b75de381379697370 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Wed, 2 Dec 2020 17:02:35 -0500 Subject: [PATCH] feat: expose uploaded thumbnails to client-side via API + plugin hook: filter:topics.getThumbs --- src/topics/index.js | 18 +++++++++++++++++- src/topics/thumbs.js | 19 ++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/topics/index.js b/src/topics/index.js index 97b341f010..f4455606cc 100644 --- a/src/topics/index.js +++ b/src/topics/index.js @@ -75,12 +75,13 @@ Topics.getTopicsByTids = async function (tids, options) { return postData.map(p => p.handle); } - const [teasers, users, userSettings, categoriesData, guestHandles] = await Promise.all([ + const [teasers, users, userSettings, categoriesData, guestHandles, thumbs] = await Promise.all([ Topics.getTeasers(topics, options), user.getUsersFields(uids, ['uid', 'username', 'fullname', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned', 'status']), user.getMultipleUserSettings(uids), categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'backgroundImage', 'imageClass', 'bgColor', 'color', 'disabled']), loadGuestHandles(), + Topics.thumbs.get(tids), ]); users.forEach((userObj, idx) => { @@ -96,6 +97,7 @@ Topics.getTopicsByTids = async function (tids, options) { usersMap: _.zipObject(uids, users), categoriesMap: _.zipObject(cids, categoriesData), tidToGuestHandle: _.zipObject(guestTopics.map(t => t.tid), guestHandles), + thumbs, }; } @@ -111,6 +113,7 @@ Topics.getTopicsByTids = async function (tids, options) { const sortOldToNew = callerSettings.topicPostSort === 'newest_to_oldest'; result.topics.forEach(function (topic, i) { if (topic) { + topic.thumbs = result.thumbs[i]; topic.category = result.categoriesMap[topic.cid]; topic.user = topic.uid ? result.usersMap[topic.uid] : { ...result.usersMap[topic.uid] }; if (result.tidToGuestHandle[topic.tid]) { @@ -150,6 +153,7 @@ Topics.getTopicWithPosts = async function (topicData, set, uid, start, stop, rev deleter, merger, related, + thumbs, ] = await Promise.all([ getMainPostAndReplies(topicData, set, uid, start, stop, reverse), categories.getCategoryData(topicData.cid), @@ -161,8 +165,20 @@ Topics.getTopicWithPosts = async function (topicData, set, uid, start, stop, rev getDeleter(topicData), getMerger(topicData), getRelated(topicData, uid), + Topics.thumbs.get(topicData.tid), ]); + topicData.thumbs = thumbs; + // Note: Backwards compatibility with old thumb logic, remove in v1.16.0 + if (topicData.thumb && !topicData.thumbs.length) { + topicData.thumbs = [{ + url: topicData.thumb, + }]; + } else if (topicData.thumbs.length) { + topicData.thumb = topicData.thumbs[0].url; + } + // end + topicData.posts = posts; topicData.category = category; topicData.tagWhitelist = tagWhitelist[0]; diff --git a/src/topics/thumbs.js b/src/topics/thumbs.js index 6cdc9bf799..484c84a0a0 100644 --- a/src/topics/thumbs.js +++ b/src/topics/thumbs.js @@ -30,9 +30,22 @@ Thumbs.exists = async function (tid, path) { return db.isSortedSetMember(`topic:${tid}:thumbs`, path); }; -Thumbs.get = async function (tid) { - const thumbs = await db.getSortedSetRange(`topic:${tid}:thumbs`, 0, -1); - return thumbs.map(thumb => path.join(nconf.get('upload_path'), thumb)); +Thumbs.get = async function (tids) { + // Allow singular or plural usage + let singular = false; + if (!Array.isArray(tids)) { + tids = [tids]; + singular = true; + } + + const sets = tids.map(tid => `topic:${tid}:thumbs`); + const thumbs = await db.getSortedSetsMembers(sets); + let response = thumbs.map(thumbSet => thumbSet.map(thumb => ({ + url: path.join(nconf.get('upload_url'), thumb), + }))); + + ({ thumbs: response } = await plugins.hooks.fire('filter:topics.getThumbs', { tids, thumbs: response })); + return singular ? response.pop() : response; }; Thumbs.associate = async function (id, path, isDraft) {