Trigger a jquery function on post load

Hi!

If you access this instance of disocurse, you’ll notive I’ve added levels next to peoples pictures.

Thing is, when we scroll or reload the page, users don’t have their levels displayed.

I would need to run a function on the call back when users posts are displayed.

I’ve looked at the client side api doc:

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/plugin-api.js.es6#L11

but I can’t seem to figure it out.

U guys got any clues as to how I could do this?

Update: I’m pretty sure I could use the onAppEvent() function. I just have no idea which events gets triggered when. Is there a way I could “listen” to events and log them in the console to make this easier?

  onAppEvent(name, fn) {
    let appEvents = this.container.lookup('app-events:main');
    appEvents.on(name, fn);
  }

This should help you:

2 Likes

The thing is, I can’t use onPageChange because the actual post gets loaded in the DOM AFTER the onPageChange takes places.

I can’t use on AjaxComplete because there are wayyyy too many ajax request being made unrelated to what I’m trying to do.

The closest thing to what I’m trying to do is

 /**
   * Used for decorating the `cooked` content of a post after it is rendered using
   * jQuery.
   *
   * `callback` will be called when it is time to decorate with a jQuery selector.
   *
   * Use `options.onlyStream` if you only want to decorate posts within a topic,
   * and not in other places like the user stream.
   *
   * For example, to add a yellow background to all posts you could do this:
   *
   * ```
   * api.decorateCooked($elem => $elem.css({ backgroundColor: 'yellow' }));
   * ```
   **/
  decorateCooked(callback, opts) {
    opts = opts || {};

    addDecorator(callback);

    if (!opts.onlyStream) {
      decorate(ComposerEditor, 'previewRefreshed', callback);
      decorate(this.container.factoryFor('component:user-stream').class, 'didInsertElement', callback);
    }
  }

But I can only affect what’s INSIDE the user’s post. His avatar is off limits.

Did you check this theme code?

https://github.com/tshenry/discourse-trust-level-avatar-flair/blob/master/common/head_tag.html

3 Likes

I don’t want to display the user’s trust level, I did a custom leveling system that’s partly based on action made on both wordpress AND discourse.

Here’s the best workaround I’ve found so far:

// I fetch my JS object containing all my members with user levels, calculated server side.
$.get('https://www.latranchee.com/php/users/gamification.php', function( data ) {
    users = JSON.parse(data);
});

// The function that will add users level next to their name
function add_levels(){
    $('.topic-avatar img.avatar:not(.lvl)').each(function(){
        var username = $(this).attr("title");
        if(window.users[username]){
            $(this).after("<span class='user_level_img'>"+window.users[username]+"</span>")
        }
        $(this).addClass("lvl");
    });
}

// A timer that triggers the check Avatar function
window.setInterval(function(){
  checkForAvatar();
}, 1000);

// A function that check if there's an image on the page without it's level being displayed.
function checkForAvatar(){
   if ( $('.topic-avatar img.avatar:not(.lvl)').length ){
       add_levels();
    }
}

Far from optimal, but I guess it will have to do.

That was an example of the optimal way to append a DOM element to the user avatar. You can add anything there, just change it from trust level to whatever you want.

3 Likes

Got it! Thanks I’ll fiddle with it!

Hey @Falco, I’ve tried the code and it is indeed much more efficient. However, I need to run a GET request first.

Using your method, the script fire before the users variable get registered in the window variable.

Unless you know of a quick workaround, I guess I’ll just let it be added after page load. The setInterval function is annoying but I guess it’ll have to do.

I still think the onAppEvent() would be best though!

This line should give you all the info you need about the user.

Are you running this extra request for every poster in a topic?

If you store this info in a custom_user_field, and make put it in the public_user_custom_fields site setting they should be available there. (not sure about this, you will need to test. If they aren’t you can add those to the topic/post serializer in a plugin)

1 Like

Just once when the app loads. But yeah, custom fields sounds much better.

I guess I’ll need to set this variable server side right? I add it once in the admin pannel, then store the data on user login through php or something?

You can pass it in the SSO payload, via the API, set it using a plugin, etc.

3 Likes