Skip to content

Commit

Permalink
DEV: allows to decorate topic list item (discourse#9294)
Browse files Browse the repository at this point in the history
Co-authored-by: David Taylor <[email protected]>
  • Loading branch information
jjaffeux and davidtaylorhq authored Mar 27, 2020
1 parent c721bdb commit 38e347a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 2 deletions.
14 changes: 14 additions & 0 deletions app/assets/javascripts/discourse/components/topic-list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { findRawTemplate } from "discourse/lib/raw-templates";
import { wantsNewWindow } from "discourse/lib/intercept-click";
import { on } from "@ember/object/evented";

import { topicTitleDecorators } from "discourse/components/topic-title";

export function showEntrance(e) {
let target = $(e.target);

Expand Down Expand Up @@ -67,6 +69,18 @@ export default Component.extend({
}
});
}

schedule("afterRender", () => {
if (this.element && !this.isDestroying && !this.isDestroyed) {
const rawTopicLink = this.element.querySelector(".raw-topic-link");

rawTopicLink &&
topicTitleDecorators &&
topicTitleDecorators.forEach(cb =>
cb(this.topic, rawTopicLink, "topic-list-item-title")
);
}
});
},

willDestroyElement() {
Expand Down
29 changes: 28 additions & 1 deletion app/assets/javascripts/discourse/components/topic-title.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
import Component from "@ember/component";
import KeyEnterEscape from "discourse/mixins/key-enter-escape";
import { schedule } from "@ember/runloop";

export let topicTitleDecorators = [];

export function addTopicTitleDecorator(decorator) {
topicTitleDecorators.push(decorator);
}

export function resetTopicTitleDecorators() {
topicTitleDecorators = [];
}

export default Component.extend(KeyEnterEscape, {
elementId: "topic-title"
elementId: "topic-title",

didInsertElement() {
this._super(...arguments);

schedule("afterRender", () => {
if (this.element && !this.isDestroying && !this.isDestroyed) {
const fancyTitle = this.element.querySelector(".fancy-title");

fancyTitle &&
topicTitleDecorators &&
topicTitleDecorators.forEach(cb =>
cb(this.model, fancyTitle, "topic-title")
);
}
});
}
});
23 changes: 22 additions & 1 deletion app/assets/javascripts/discourse/lib/plugin-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import deprecated from "discourse-common/lib/deprecated";
import { iconNode } from "discourse-common/lib/icon-library";
import { addDecorator } from "discourse/widgets/post-cooked";
import { addPluginOutletDecorator } from "discourse/components/plugin-connector";
import { addTopicTitleDecorator } from "discourse/components/topic-title";
import ComposerEditor from "discourse/components/composer-editor";
import DiscourseBanner from "discourse/components/discourse-banner";
import { addButton } from "discourse/widgets/post-menu";
Expand Down Expand Up @@ -54,7 +55,7 @@ import { on } from "@ember/object/evented";
import KeyboardShortcuts, { bindings } from "discourse/lib/keyboard-shortcuts";

// If you add any methods to the API ensure you bump up this number
const PLUGIN_API_VERSION = "0.8.39";
const PLUGIN_API_VERSION = "0.8.40";

class PluginApi {
constructor(version, container) {
Expand Down Expand Up @@ -1017,6 +1018,26 @@ class PluginApi {
decoratePluginOutlet(outletName, callback, opts) {
addPluginOutletDecorator(outletName, callback, opts || {});
}

/**
* Allows altering the topic title in the topic list, and in the topic view
*
* topicTitleType can be `topic-title` or `topic-list-item-title`
*
* For example, to replace the topic title:
*
* ```
* api.decorateTopicTitle(
* (topicModel, node, topicTitleType) => {
* node.innerText("my new topic title");
* }
* );
* ```
*
**/
decorateTopicTitle(callback) {
addTopicTitleDecorator(callback);
}
}

let _pluginv01;
Expand Down
28 changes: 28 additions & 0 deletions test/javascripts/acceptance/topic-test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withPluginApi } from "discourse/lib/plugin-api";
import selectKit from "helpers/select-kit-helper";
import { acceptance } from "helpers/qunit-helpers";
import { IMAGE_VERSION as v } from "pretty-text/emoji/version";
Expand Down Expand Up @@ -358,3 +359,30 @@ QUnit.test("Bookmarks Modal", async assert => {
await click(".topic-post:first-child button.bookmark");
assert.ok(exists("#bookmark-reminder-modal"), "it shows the bookmark modal");
});

acceptance("Topic with title decorated", {
loggedIn: true,
beforeEach() {
withPluginApi("0.8.40", api => {
api.decorateTopicTitle((topic, node, topicTitleType) => {
node.innerText = `${node.innerText}-${topic.id}-${topicTitleType}`;
});
});
}
});

QUnit.test("Decorate topic title", async assert => {
await visit("/t/internationalization-localization/280");

assert.ok(
find(".fancy-title")[0].innerText.endsWith("-280-topic-title"),
"it decorates topic title"
);

assert.ok(
find(".raw-topic-link:nth-child(1)")[0].innerText.endsWith(
"-27331-topic-list-item-title"
),
"it decorates topic list item title"
);
});
2 changes: 2 additions & 0 deletions test/javascripts/helpers/qunit-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { clearRewrites } from "discourse/lib/url";
import { initSearchData } from "discourse/widgets/search-menu";
import { resetDecorators } from "discourse/widgets/widget";
import { resetWidgetCleanCallbacks } from "discourse/components/mount-widget";
import { resetTopicTitleDecorators } from "discourse/components/topic-title";
import { resetDecorators as resetPostCookedDecorators } from "discourse/widgets/post-cooked";
import { resetDecorators as resetPluginOutletDecorators } from "discourse/components/plugin-connector";
import { resetCache as resetOneboxCache } from "pretty-text/oneboxer";
Expand Down Expand Up @@ -129,6 +130,7 @@ export function acceptance(name, options) {
resetDecorators();
resetPostCookedDecorators();
resetPluginOutletDecorators();
resetTopicTitleDecorators();
resetOneboxCache();
resetCustomPostMessageCallbacks();
Discourse._runInitializer("instanceInitializers", function(
Expand Down

0 comments on commit 38e347a

Please sign in to comment.