How to correctly listen on post-stream update

Hi,

I am trying to run a custom function, when additional content to the page is added, (for long posts) using the following API:

api.onAppEvent('post-stream:refresh', () => {
       console.log('New content to the page added ...');
});

… however, the above didn’t work. What am I doing wrong and what would be the correct way of doing it?

Can you share a little more about what you’re trying to achieve? There are a few different APIs that allow you to modify post content when it renders. The most common one would be api.decorateCookedElement

1 Like

In fact, I just realized that I need to run the function on post content added to the DOM.

I am practically re-creating addPosterIcon API, because mine has to contain custom HTML. I have it already done everything working, except when the long page is being scrolled.

I am trying to add an icon next to the poster username, which triggers a custom event. The only problem is that it’s not getting yet added upon DOM change.

The problem with this method, is that it triggers multiple cooked objects at once and thus preferes an id (to avoid memory leaks), which is not something I need. What would worked for me, is if only one event was triggered after all elements are cooked. I have an idea on how it could be clutched but is there a proper way of doing it using Discourse API?

The decorateCookedElement api will be triggered once for each rendered post. The callback will be passed the DOM element containing the post content. The idea is that you only modify the element you’ve been passed, and not anything else on the page.

But since you want to make modifications to the metadata around the post content, decorateCookedElement probably isn’t the right option.

Then the best thing is probably to look at how the addPosterIcon API is implemented:

Under the covers it is a call to the api.decorateWidget function. You could make that call yourself, and then make it render raw HTML. For more information about the decorateWidget API, you can check https://meta.discourse.org/t/developer-s-guide-to-discourse-themes/93648#heading--4-c-6

1 Like

The solution for me to have decorateCookedElement run only once for a specific type, and when the last cooked content is ready, was as simple as that:

<script type="text/discourse-plugin" version="0.11">
  api.decorateCookedElement((callback, opts) => {
      if(opts?.widget?.dirtyKeys?.name === 'post-stream') {
          if(this?.cooking) clearTimeout(this.cooking);
          this.cooking = setTimeout(() => {
              console.log('All cooking is done, update new content..');
          });
      }
  });
</script>

Please correct me if there is anything wrong or there are any pitfalls in this code.