FEATURE: display category icon in post body (#36)
* FEATURE: display category icon in post body This commit allows displaying category icons in the body of the post. Related meta topic: https://meta.discourse.org/t/category-icons-dont-show-up-in-post-text/315851
This commit is contained in:
parent
1df45ac226
commit
7f44f9bc24
|
@ -3,6 +3,7 @@ import { h } from "virtual-dom";
|
|||
import categoriesBoxes from "discourse/components/categories-boxes";
|
||||
import categoriesBoxesWithTopics from "discourse/components/categories-boxes-with-topics";
|
||||
import categoryTitleLink from "discourse/components/category-title-link";
|
||||
import CategoryHashtagType from "discourse/lib/hashtag-types/category";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import { isRTL } from "discourse/lib/text-direction";
|
||||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
|
@ -12,10 +13,29 @@ import { helperContext } from "discourse-common/lib/helpers";
|
|||
import { iconHTML, iconNode } from "discourse-common/lib/icon-library";
|
||||
import I18n from "I18n";
|
||||
|
||||
class CategoryHashtagTypeWithIcon extends CategoryHashtagType {
|
||||
constructor(dict, owner) {
|
||||
super(owner);
|
||||
this.dict = dict;
|
||||
}
|
||||
generateIconHTML(hashtag) {
|
||||
const opt = this.dict[hashtag.id];
|
||||
if (opt) {
|
||||
const newIcon = document.createElement("span");
|
||||
newIcon.classList.add("hashtag-category-icon");
|
||||
newIcon.innerHTML = iconHTML(opt.icon);
|
||||
newIcon.style.color = opt.color;
|
||||
return newIcon.outerHTML;
|
||||
} else {
|
||||
return super.generateIconHTML(hashtag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "category-icons",
|
||||
|
||||
initialize() {
|
||||
initialize(owner) {
|
||||
withPluginApi("0.8.26", (api) => {
|
||||
let categoryThemeList = settings.category_icon_list.split("|");
|
||||
let lockIcon = settings.category_lock_icon || "lock";
|
||||
|
@ -199,6 +219,37 @@ export default {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (api.registerHashtagType) {
|
||||
const site = api.container.lookup("service:site");
|
||||
const dict = {};
|
||||
for (const str of categoryThemeList) {
|
||||
let [slug, icon, color, match] = str.split(",");
|
||||
if (slug && icon) {
|
||||
slug = slug.toLowerCase();
|
||||
for (const cat of site.categories) {
|
||||
const catSlug = cat.slug.toLowerCase();
|
||||
if (
|
||||
match === "partial" ? !catSlug.includes(slug) : catSlug !== slug
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const opts = {
|
||||
icon,
|
||||
color,
|
||||
};
|
||||
if (!color || color?.match(/categoryColo(u*)r/g)) {
|
||||
opts.color = `#${cat.color}`;
|
||||
}
|
||||
dict[cat.id] = opts;
|
||||
}
|
||||
}
|
||||
}
|
||||
api.registerHashtagType(
|
||||
"category",
|
||||
new CategoryHashtagTypeWithIcon(dict, owner)
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import { visit } from "@ember/test-helpers";
|
||||
import { test } from "qunit";
|
||||
import TopicFixtures from "discourse/tests/fixtures/topic";
|
||||
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
||||
import { cloneJSON } from "discourse-common/lib/object";
|
||||
|
||||
function makeHashtagHTML(category) {
|
||||
return `<a class=\"hashtag-cooked\" href=\"${category.href}\" data-type=\"category\" data-slug=\"${category.slug}\" data-id=\"${category.id}\"><span class=\"hashtag-icon-placeholder\"><svg class=\"fa d-icon d-icon-square-full svg-icon svg-node\"><use href=\"#square-full\"></use></svg></span><span>${category.name}</span></a>`;
|
||||
}
|
||||
|
||||
acceptance("Post body - Category icons", function (needs) {
|
||||
needs.user();
|
||||
|
||||
const categories = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Category 1",
|
||||
slug: "category-1",
|
||||
color: "111111",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Category 2",
|
||||
slug: "category-2",
|
||||
color: "000000",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Category 3",
|
||||
slug: "category-3",
|
||||
color: "888888",
|
||||
},
|
||||
];
|
||||
|
||||
needs.site({
|
||||
categories,
|
||||
});
|
||||
|
||||
needs.hooks.beforeEach(function () {
|
||||
settings.category_lock_icon = "wrench";
|
||||
settings.category_icon_list = `category-1,wrench,#FF0000|category-2,question-circle,categoryColor`;
|
||||
});
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/t/131.json", () => {
|
||||
const topicList = cloneJSON(TopicFixtures["/t/130.json"]);
|
||||
topicList.post_stream.posts[0].cooked = `<p>${makeHashtagHTML(
|
||||
categories[0]
|
||||
)} ${makeHashtagHTML(categories[1])} ${makeHashtagHTML(
|
||||
categories[2]
|
||||
)}</p>`;
|
||||
return helper.response(topicList);
|
||||
});
|
||||
});
|
||||
|
||||
test("Icon for category when `category_icon_list` theme setting has been configured", async function (assert) {
|
||||
await visit("/t/131");
|
||||
|
||||
assert
|
||||
.dom(
|
||||
`.cooked .hashtag-cooked[data-id="1"] .hashtag-category-icon .d-icon-wrench`
|
||||
)
|
||||
.exists("wrench icon is displayed for category-1");
|
||||
|
||||
assert
|
||||
.dom(`.cooked .hashtag-cooked[data-id="1"] .hashtag-category-icon`)
|
||||
.hasStyle(
|
||||
{ color: "rgb(255, 0, 0)" },
|
||||
"category-1 's icon has the right color"
|
||||
);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
`.cooked .hashtag-cooked[data-id="2"] .hashtag-category-icon .d-icon-question-circle`
|
||||
)
|
||||
.exists("question-circle icon is displayed for category-2");
|
||||
|
||||
assert
|
||||
.dom(`.cooked .hashtag-cooked[data-id="2"] .hashtag-category-icon`)
|
||||
.hasStyle(
|
||||
{ color: "rgb(0, 0, 0)" },
|
||||
"category-2 's icon has the right categoryColor"
|
||||
);
|
||||
|
||||
assert
|
||||
.dom(`.cooked .hashtag-cooked[data-id="3"] .hashtag-category-badge`)
|
||||
.exists("unconfigured categories have a default badge");
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue