mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 22:53:43 +08:00
FIX: Decorate posts that are loaded after the initial render in post stream (#14600)
To clarify, this problem is not about the topic posts stream, it's about posts streams like the user Activity one in the profile page (or in technical terms anything using the `{{user-stream}}` component). Post decorations are currently applied inside a `didInsertElement` hook of the `{{user-stream}}` component. However, when the user scrolls the component will load more posts but these will be missing decorations because the `didInsertElement` is only fired once at the beginning of the component lifecycle. This PR makes the component keep track of the last decorated post/DOM node, and when new posts are loaded the component fire an event for each new post and pass the post's DOM node with the event. Our plugin API (I noticed this problem when I was working on https://github.com/discourse/discourse-follow/pull/37) Co-authored-by: Robin Ward <robin.ward@gmail.com>
This commit is contained in:
parent
82945a3d21
commit
7f3468e7d5
|
@ -14,6 +14,7 @@ import { schedule } from "@ember/runloop";
|
|||
|
||||
export default Component.extend(LoadMore, {
|
||||
tagName: "ul",
|
||||
_lastDecoratedElement: null,
|
||||
|
||||
_initialize: on("init", function () {
|
||||
const filter = this.get("stream.filter");
|
||||
|
@ -47,6 +48,7 @@ export default Component.extend(LoadMore, {
|
|||
$(this.element).on("click.discourse-redirect", ".excerpt a", (e) => {
|
||||
return ClickTrack.trackClick(e, this.siteSettings);
|
||||
});
|
||||
this._updateLastDecoratedElement();
|
||||
}),
|
||||
|
||||
// This view is being removed. Shut down operations
|
||||
|
@ -59,6 +61,18 @@ export default Component.extend(LoadMore, {
|
|||
$(this.element).off("click.discourse-redirect", ".excerpt a");
|
||||
}),
|
||||
|
||||
_updateLastDecoratedElement() {
|
||||
const nodes = this.element.querySelectorAll(".user-stream-item");
|
||||
if (nodes.length === 0) {
|
||||
return;
|
||||
}
|
||||
const lastElement = nodes[nodes.length - 1];
|
||||
if (lastElement === this._lastDecoratedElement) {
|
||||
return;
|
||||
}
|
||||
this._lastDecoratedElement = lastElement;
|
||||
},
|
||||
|
||||
actions: {
|
||||
removeBookmark(userAction) {
|
||||
const stream = this.stream;
|
||||
|
@ -123,7 +137,15 @@ export default Component.extend(LoadMore, {
|
|||
|
||||
this.set("loading", true);
|
||||
const stream = this.stream;
|
||||
stream.findItems().then(() => this.set("loading", false));
|
||||
stream.findItems().then(() => {
|
||||
this.set("loading", false);
|
||||
let element = this._lastDecoratedElement?.nextElementSibling;
|
||||
while (element) {
|
||||
this.trigger("user-stream:new-item-inserted", element);
|
||||
element = element.nextElementSibling;
|
||||
}
|
||||
this._updateLastDecoratedElement();
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -311,12 +311,10 @@ class PluginApi {
|
|||
if (!opts.onlyStream) {
|
||||
decorate(ComposerEditor, "previewRefreshed", callback, opts.id);
|
||||
decorate(DiscourseBanner, "didInsertElement", callback, opts.id);
|
||||
decorate(
|
||||
this.container.factoryFor("component:user-stream").class,
|
||||
"didInsertElement",
|
||||
callback,
|
||||
opts.id
|
||||
);
|
||||
["didInsertElement", "user-stream:new-item-inserted"].forEach((event) => {
|
||||
const klass = this.container.factoryFor("component:user-stream").class;
|
||||
decorate(klass, event, callback, opts.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user