Skip to content

Commit

Permalink
feat: store topic tags in topic hash (#9656)
Browse files Browse the repository at this point in the history
* feat: store topic tags in topic hash

breaking: remove color info from tags (use css)

* fix: remove unused tag modal

* fix: tag search
  • Loading branch information
barisusakli committed Jul 12, 2021
1 parent 0d3f74b commit 4a56388
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 275 deletions.
1 change: 0 additions & 1 deletion public/language/en-GB/admin/manage/tags.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"none": "Your forum does not have any topics with tags yet.",
"bg-color": "Background Colour",
"text-color": "Text Colour",
"create-modify": "Create & Modify Tags",
"description": "Select tags by clicking or dragging, use <code>CTRL</code> to select multiple tags.",
"create": "Create Tag",
"modify": "Modify Tags",
Expand Down
49 changes: 0 additions & 49 deletions public/src/admin/manage/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ define('admin/manage/tags', [

handleCreate();
handleSearch();
handleModify();
handleRename();
handleDeleteSelected();
};
Expand Down Expand Up @@ -82,54 +81,6 @@ define('admin/manage/tags', [
});
}

function handleModify() {
$('#modify').on('click', function () {
var tagsToModify = $('.tag-row.ui-selected');
if (!tagsToModify.length) {
return;
}

var firstTag = $(tagsToModify[0]);
bootbox.dialog({
title: '[[admin/manage/tags:alerts.editing]]',
message: firstTag.find('.tag-modal').html(),
buttons: {
success: {
label: 'Save',
className: 'btn-primary save',
callback: function () {
var modal = $('.bootbox');
var resetColors = modal.find('#reset-colors').is(':checked');
var bgColor = resetColors ? '' : modal.find('[data-name="bgColor"]').val();
var color = resetColors ? '' : modal.find('[data-name="color"]').val();

var data = [];
tagsToModify.each(function (idx, tag) {
tag = $(tag);
data.push({
value: tag.attr('data-tag'),
color: color,
bgColor: bgColor,
});

tag.find('[data-name="bgColor"]').val(bgColor);
tag.find('[data-name="color"]').val(color);
tag.find('.tag-item').css('background-color', bgColor).css('color', color);
});

socket.emit('admin.tags.update', data, function (err) {
if (err) {
return app.alertError(err.message);
}
app.alertSuccess('[[admin/manage/tags:alerts.update-success]]');
});
},
},
},
});
});
}

function handleRename() {
$('#rename').on('click', function () {
var tagsToModify = $('.tag-row.ui-selected');
Expand Down
5 changes: 4 additions & 1 deletion src/controllers/write/topics.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ Topics.addTags = async (req, res) => {
if (!await privileges.topics.canEdit(req.params.tid, req.user.uid)) {
return helpers.formatApiResponse(403, res);
}
const cid = await topics.getTopicField(req.params.tid, 'cid');
await topics.validateTags(req.body.tags, cid, req.user.uid, req.params.tid);
const tags = await topics.filterTags(req.body.tags);

await topics.createTags(req.body.tags, req.params.tid, Date.now());
await topics.addTags(tags, [req.params.tid]);
helpers.formatApiResponse(200, res);
};

Expand Down
1 change: 0 additions & 1 deletion src/privileges/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ privsAdmin.socketMap = {
'admin.user.invite': 'admin:users',

'admin.tags.create': 'admin:tags',
'admin.tags.update': 'admin:tags',
'admin.tags.rename': 'admin:tags',
'admin.tags.deleteTags': 'admin:tags',

Expand Down
18 changes: 4 additions & 14 deletions src/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,15 @@ async function getUsers(uids, data) {
async function getTopics(tids, data) {
const topicsData = await topics.getTopicsData(tids);
const cids = _.uniq(topicsData.map(topic => topic && topic.cid));
const [categories, tags] = await Promise.all([
getCategories(cids, data),
getTags(tids, data),
]);
const categories = await getCategories(cids, data);

const cidToCategory = _.zipObject(cids, categories);
topicsData.forEach((topic, index) => {
topicsData.forEach((topic) => {
if (topic && categories && cidToCategory[topic.cid]) {
topic.category = cidToCategory[topic.cid];
}
if (topic && tags && tags[index]) {
topic.tags = tags[index];
if (topic && topic.tags) {
topic.tags = topic.tags.map(tag => tag.value);
}
});

Expand All @@ -186,13 +183,6 @@ async function getCategories(cids, data) {
return await db.getObjectsFields(cids.map(cid => `category:${cid}`), categoryFields);
}

async function getTags(tids, data) {
if (Array.isArray(data.hasTags) && data.hasTags.length) {
return await topics.getTopicsTags(tids);
}
return null;
}

function filterByPostcount(posts, postCount, repliesFilter) {
postCount = parseInt(postCount, 10);
if (postCount) {
Expand Down
8 changes: 0 additions & 8 deletions src/socket.io/admin/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ Tags.create = async function (socket, data) {
await topics.createEmptyTag(data.tag);
};

Tags.update = async function (socket, data) {
if (!Array.isArray(data)) {
throw new Error('[[error:invalid-data]]');
}

await topics.updateTags(data);
};

Tags.rename = async function (socket, data) {
if (!Array.isArray(data)) {
throw new Error('[[error:invalid-data]]');
Expand Down
6 changes: 6 additions & 0 deletions src/topics/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ module.exports = function (Topics) {
postcount: 0,
viewcount: 0,
};

if (Array.isArray(data.tags) && data.tags.length) {
topicData.tags = data.tags.join(',');
}

const result = await plugins.hooks.fire('filter:topic.create', { topic: topicData, data: data });
topicData = result.topic;
await db.setObject(`topic:${topicData.tid}`, topicData);
Expand Down Expand Up @@ -79,6 +84,7 @@ module.exports = function (Topics) {
}
Topics.checkTitle(data.title);
await Topics.validateTags(data.tags, data.cid, uid);
data.tags = await Topics.filterTags(data.tags, data.cid);
Topics.checkContent(data.content);

const [categoryExists, canCreate, canTag] = await Promise.all([
Expand Down
8 changes: 8 additions & 0 deletions src/topics/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,12 @@ function modifyTopic(topic, fields) {
if (fields.includes('teaserPid') || !fields.length) {
topic.teaserPid = topic.teaserPid || null;
}

if (fields.includes('tags') || !fields.length) {
const tags = String(topic.tags || '');
topic.tags = tags.split(',').filter(Boolean).map(tag => ({
value: tag,
valueEscaped: validator.escape(String(tag)),
}));
}
}
13 changes: 2 additions & 11 deletions src/topics/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ Topics.getTopicsByTids = async function (tids, options) {
};
}

const [result, tags, hasRead, isIgnored, bookmarks, callerSettings] = await Promise.all([
const [result, hasRead, isIgnored, bookmarks, callerSettings] = await Promise.all([
loadTopics(),
Topics.getTopicsTagsObjects(tids),
Topics.hasReadTopics(tids, uid),
Topics.isIgnoring(tids, uid),
Topics.getUserBookmarks(tids, uid),
Expand All @@ -136,8 +135,6 @@ Topics.getTopicsByTids = async function (tids, options) {
topic.user.displayname = topic.user.username;
}
topic.teaser = result.teasers[i] || null;
topic.tags = tags[i];

topic.isOwner = topic.uid === parseInt(uid, 10);
topic.ignored = isIgnored[i];
topic.unread = parseInt(uid, 10) > 0 && !hasRead[i] && !isIgnored[i];
Expand Down Expand Up @@ -180,7 +177,7 @@ Topics.getTopicWithPosts = async function (topicData, set, uid, start, stop, rev
social.getActivePostSharing(),
getDeleter(topicData),
getMerger(topicData),
getRelated(topicData, uid),
Topics.getRelatedTopics(topicData, uid),
Topics.thumbs.load([topicData]),
Topics.events.get(topicData.tid, uid),
]);
Expand Down Expand Up @@ -268,12 +265,6 @@ async function getMerger(topicData) {
return merger;
}

async function getRelated(topicData, uid) {
const tags = await Topics.getTopicTagsObjects(topicData.tid);
topicData.tags = tags;
return await Topics.getRelatedTopics(topicData, uid);
}

Topics.getMainPost = async function (tid, uid) {
const mainPosts = await Topics.getMainPosts([tid], uid);
return Array.isArray(mainPosts) && mainPosts.length ? mainPosts[0] : null;
Expand Down

0 comments on commit 4a56388

Please sign in to comment.