mirror of
https://github.com/discourse/discourse.git
synced 2025-05-25 19:29:34 +08:00
DEV: allows to decorate topic list item (#9294)
Co-authored-by: David Taylor <david@taylorhq.com>
This commit is contained in:
@ -7,6 +7,8 @@ import { findRawTemplate } from "discourse/lib/raw-templates";
|
|||||||
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||||
import { on } from "@ember/object/evented";
|
import { on } from "@ember/object/evented";
|
||||||
|
|
||||||
|
import { topicTitleDecorators } from "discourse/components/topic-title";
|
||||||
|
|
||||||
export function showEntrance(e) {
|
export function showEntrance(e) {
|
||||||
let target = $(e.target);
|
let target = $(e.target);
|
||||||
|
|
||||||
@ -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() {
|
willDestroyElement() {
|
||||||
|
@ -1,6 +1,33 @@
|
|||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import KeyEnterEscape from "discourse/mixins/key-enter-escape";
|
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, {
|
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")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ import deprecated from "discourse-common/lib/deprecated";
|
|||||||
import { iconNode } from "discourse-common/lib/icon-library";
|
import { iconNode } from "discourse-common/lib/icon-library";
|
||||||
import { addDecorator } from "discourse/widgets/post-cooked";
|
import { addDecorator } from "discourse/widgets/post-cooked";
|
||||||
import { addPluginOutletDecorator } from "discourse/components/plugin-connector";
|
import { addPluginOutletDecorator } from "discourse/components/plugin-connector";
|
||||||
|
import { addTopicTitleDecorator } from "discourse/components/topic-title";
|
||||||
import ComposerEditor from "discourse/components/composer-editor";
|
import ComposerEditor from "discourse/components/composer-editor";
|
||||||
import DiscourseBanner from "discourse/components/discourse-banner";
|
import DiscourseBanner from "discourse/components/discourse-banner";
|
||||||
import { addButton } from "discourse/widgets/post-menu";
|
import { addButton } from "discourse/widgets/post-menu";
|
||||||
@ -54,7 +55,7 @@ import { on } from "@ember/object/evented";
|
|||||||
import KeyboardShortcuts, { bindings } from "discourse/lib/keyboard-shortcuts";
|
import KeyboardShortcuts, { bindings } from "discourse/lib/keyboard-shortcuts";
|
||||||
|
|
||||||
// If you add any methods to the API ensure you bump up this number
|
// 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 {
|
class PluginApi {
|
||||||
constructor(version, container) {
|
constructor(version, container) {
|
||||||
@ -1017,6 +1018,26 @@ class PluginApi {
|
|||||||
decoratePluginOutlet(outletName, callback, opts) {
|
decoratePluginOutlet(outletName, callback, opts) {
|
||||||
addPluginOutletDecorator(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;
|
let _pluginv01;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
import selectKit from "helpers/select-kit-helper";
|
import selectKit from "helpers/select-kit-helper";
|
||||||
import { acceptance } from "helpers/qunit-helpers";
|
import { acceptance } from "helpers/qunit-helpers";
|
||||||
import { IMAGE_VERSION as v } from "pretty-text/emoji/version";
|
import { IMAGE_VERSION as v } from "pretty-text/emoji/version";
|
||||||
@ -358,3 +359,30 @@ QUnit.test("Bookmarks Modal", async assert => {
|
|||||||
await click(".topic-post:first-child button.bookmark");
|
await click(".topic-post:first-child button.bookmark");
|
||||||
assert.ok(exists("#bookmark-reminder-modal"), "it shows the bookmark modal");
|
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"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
@ -16,6 +16,7 @@ import { clearRewrites } from "discourse/lib/url";
|
|||||||
import { initSearchData } from "discourse/widgets/search-menu";
|
import { initSearchData } from "discourse/widgets/search-menu";
|
||||||
import { resetDecorators } from "discourse/widgets/widget";
|
import { resetDecorators } from "discourse/widgets/widget";
|
||||||
import { resetWidgetCleanCallbacks } from "discourse/components/mount-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 resetPostCookedDecorators } from "discourse/widgets/post-cooked";
|
||||||
import { resetDecorators as resetPluginOutletDecorators } from "discourse/components/plugin-connector";
|
import { resetDecorators as resetPluginOutletDecorators } from "discourse/components/plugin-connector";
|
||||||
import { resetCache as resetOneboxCache } from "pretty-text/oneboxer";
|
import { resetCache as resetOneboxCache } from "pretty-text/oneboxer";
|
||||||
@ -129,6 +130,7 @@ export function acceptance(name, options) {
|
|||||||
resetDecorators();
|
resetDecorators();
|
||||||
resetPostCookedDecorators();
|
resetPostCookedDecorators();
|
||||||
resetPluginOutletDecorators();
|
resetPluginOutletDecorators();
|
||||||
|
resetTopicTitleDecorators();
|
||||||
resetOneboxCache();
|
resetOneboxCache();
|
||||||
resetCustomPostMessageCallbacks();
|
resetCustomPostMessageCallbacks();
|
||||||
Discourse._runInitializer("instanceInitializers", function(
|
Discourse._runInitializer("instanceInitializers", function(
|
||||||
|
Reference in New Issue
Block a user