Trigger a jquery function on post load


(Olivier Lambert) #1

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:

but I can’t seem to figure it out.

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


(Olivier Lambert) #2

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);
  }

(Felix Freiberger) #3

This should help you:


(Olivier Lambert) #4

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.


(Rafael dos Santos Silva) #5

Did you check this theme code?


(Olivier Lambert) #6

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.


(Rafael dos Santos Silva) #7

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.


(Olivier Lambert) #8

Got it! Thanks I’ll fiddle with it!


(Olivier Lambert) #9

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!


(Rafael dos Santos Silva) #10

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)


(Olivier Lambert) #11

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?


(Rafael dos Santos Silva) #12

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