Skip to content

Adding a banner to chat messages

Tips
  • @DownPW Does it appear if you reload the page?

  • @DownPW Very odd - I see this on your DEV server

    3d34b97b-f793-400f-9f36-e37438c43ea3-image.png

  • It’s because you have joined the public chat and so we have a system message. (Phenomlab as joined the room…)

    If you are the creator of the room, no joined her and 0 message (user and system message), banner don’t appear but it’s not very serious

    image.png

  • @DownPW Can you create another ? I should be able to get this to work…

  • ok, I recreated the "“Support” lounge

  • @DownPW Can you create a new room? There are events in the old one which will trigger the message

  • ok, no problem

  • @DownPW I can’t replicate this issue. Each time I access the room, it will add a system event which causes the JS to trigger

    b9c530f9-7d93-4d11-9ae0-66938e5776e0-image.png

  • hmm I think because you have not create the room like me but like I said, it’s not very serious

  • @DownPW Nope. I get the same if I create the room

    323977da-f3c4-4506-9104-531fd6d4f228-image.png

  • Here’s a small modification to the chatBanner function that will place the message just above the composer/reply component meaning it is pinned at the bottom and always in view as a reminder. I’ve made this change to support the threadedChat I’m currently developing

    // Chat message banner
    function chatBanner() {
        var roomName = $("h5[component='chat/header/title']").text().trim();
        var bannerContent;
        if (roomName === "Testing 3") {
            bannerContent = '<div id="chatbanner">This message will fire for chat rooms with the title of "Testing 3"</div>';
        } else {
            bannerContent = '<div id="chatbanner">This session is for <strong>private discussion only</strong> between the chosen participants. Please do <strong>not</strong> place support requests here and create a <a href="#" onclick="app.newTopic();">new topic</a> instead.</div>';
        }
        var chatMessagesContainer = $('[component="chat/system-message"]:last-of-type');
        //var existingMessages = $('[component="chat/message"]');
        var existingMessages = $('[component="chat/composer"]');   
        if (existingMessages.length === 0) {
            // If there are no messages, append the banner to the messages container
            chatMessagesContainer.first().after(bannerContent);
        } else {
            // If there are messages, add the banner after the last message
           // existingMessages.last().after(bannerContent);
           existingMessages.before(bannerContent);
        }
    }
    

    There are only two changes here:

    var existingMessages = $('[component="chat/message"]');
    

    becomes

    var existingMessages = $('[component="chat/composer"]');
    

    and

    existingMessages.last().after(bannerContent);
    

    becomes

    existingMessages.before(bannerContent);
    
  • phenomlabundefined phenomlab referenced this topic on
  • phenomlabundefined phenomlab referenced this topic on
  • hi @phenomlab

    since v3.9, widget chat room is officialy available with nodebb-widget essential.

    I use this code for now for different banenr message for different room

    // ------------------------------------------
    // Chat messages banner 
    // ------------------------------------------
    
    // Several banner for several chat
    
    function chatBanner() {
        var roomName = $("h5[component='chat/header/title']").text().trim();
        var bannerContent;
        if (roomName === "General") {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 1. </div>';
        } else if (roomName === "Support") {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i>  Message 2.</div>';
        } else if (roomName === "Info") {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i>  Message 3</div>';
        } else if (roomName === "xxxxxxx") {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i>  Message 4.</div>';
        } else if (roomName === "xxxxxxxx") {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i>  Message 5.</div>';
        } else if (roomName === "xxxxxxxxx") {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i>  Message 6.</div>';
        } else {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Ce canal est une discussion privée. </div>';
        }
        var chatMessagesContainer = $('[component="chat/system-message"]:last-of-type');
        //var existingMessages = $('[component="chat/message"]');
        var existingMessages = $('[component="chat/composer"]');
    
        if (existingMessages.length === 0) {
            // If there are no messages, append the banner to the messages container
            chatMessagesContainer.first().after(bannerContent);
        } else {
            // If there are messages, add the banner after the last message
            //existingMessages.last().after(bannerContent);
            existingMessages.before(bannerContent);
        }
    }
    
    $(window).on('action:chat.loaded', function(data) {
        $(document).ready(function() {
            chatBanner()
        });
    });
    

    On the new widget, only the last message appears :

    } else {
          bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Ce canal est une discussion privée. </div>';
      }
    

    When I Change room on the chat room widget, no change.

    It’s possible to adapt the code for chatroom widget without bug if we don’t use the chatroom widget ?

    many thanks

  • @DownPW Possible, yes, but not using the existing code. It would need to be changed to test for multiple entries based on two distinct widget areas. This should work (it’s already applied on your DEV server)

    function chatBanner() {
        var roomName = $("h5[component='chat/header/title']").text().trim();
        var roomNameWidget = $('[id*="chat-modal"] .btn-ghost.btn-sm.dropdown-toggle').text().trim();
        var bannerContent;
        if (roomName === "General" || roomNameWidget === "General") {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 1. </div>';
        } else if (roomName === "Support" || roomNameWidget === "Support")  {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 2.</div>';
        } else if (roomName === "Info" || roomNameWidget === "Info")  {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 3</div>';
        } else if (roomName === "xxxxxx" || roomNameWidget === "xxxxxx")  {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 4</div>';
        } else if (roomName === "xxxxxx" || roomNameWidget === "xxxxxx")  {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 5</div>';
        } else if (roomName === "xxxxxx" || roomNameWidget === "xxxxxx") {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Message 6</div>';
        } else {
            bannerContent = '<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> Ce canal est une discussion privée. </div>';
        }
        var chatMessagesContainer = $('[component="chat/system-message"]:last-of-type');
        //var existingMessages = $('[component="chat/message"]');
        var existingMessages = $('[component="chat/composer"]');
    
        if (existingMessages.length === 0) {
            // If there are no messages, append the banner to the messages container
            chatMessagesContainer.first().after(bannerContent);
        } else {
            // If there are messages, add the banner after the last message
            //existingMessages.last().after(bannerContent);
            existingMessages.before(bannerContent);
        }
    }
    

    Here, we are using || which is essentially an OR operator. Because we cannot know the chat room ID in advance, it is necessary to use a wildcard to track it

    [id*="chat-modal"] .btn-ghost.btn-sm.dropdown-toggle
    
  • woooo it works perfectly.

    Bright !!

    Thanks @phenomlab

  • @DownPW One other “bug” (well, not in the traditional sense) that I spotted was that if you are on the root page with the chat modal widget showing, and then click the chat icon, you’ll notice some undesirable effect here in the sense that the room banner does not change.

    This is expected in fact, because the chat modal window is already exposed, and therefore, the value already exists. It is possible to alter this behaviour, but it is expensive in terms of performance as you’d need to hide the chat modal first and then re-run the function so that it only collects data from resultant chat window you opened from the side bar (hope this makes sense).

  • hmm it all depends on whether you think that makes sense.

    I always trust your opinion

  • @DownPW Sorry, I meant how I explained it. Pictures speak a thousand words, so I can easily put together a video and you’ll see what I mean. It’s almost the perfect storm - you are asking the code to choose either selector, and yet they both exist, so the latest value will always win.

  • Looks very interesting Mark, I’m going to attempt to add this to my forum tomorrow 🤝.


Related Topics