Skip to content

Threaded post support for NodeBB

Let's Build It
  • I have just forget to delete the first but this nothing change.

  • @DownPW just curious 🤭

    The second would override the first anyway.

    I’m in transit currently and not in front of a pc but will review this as soon as I can.

  • i have a problem with my codes 😞

    image.png

  • phenomlabundefined phenomlab referenced this topic on
  • @phenomlab thank you Mark i did not read this one.

  • @cagatay no problems. Easily missed!!

  • @DownPW said in Threading support for NodeBB:

    I think I understand by reading the code that it is necessary to specify the classes chnaged in the function.js (with add .threaded) but I don’t really see how to add more

    Can you post the current function code you have?

  • sure :

    function threaded() {
        $(document).ready(function () {
            // Check if the screen width is 1200px or more
            if ($(window).width() >= 1200) {
                // Check if the dropdown already exists
                if ($('#enableThreading').length === 0) {
                    var threadView = $('<div class="threads-wrapper"><i class="fa fa-fw fa-bars left"></i><form class="form"><div class="form-check form-switch sticky-tools-bar"> \
                        <input class="form-check-input" id="enableThreading" type="checkbox" data-field="enableThreading"> \
                        <label class=" d-none d-md-inline fw-semibold" for="enableThreading"><i class="fa fa-fw fa-bars-staggered right"></i></label> \
                    </div></form></div>');
                    $('.topic .sticky-tools ul [component="topic/browsing-users"]:last-of-type').append(threadView);
                    // Check if there's a stored state for the checkbox and update it
                    var storedState = localStorage.getItem('enableThreadingState');
                    if (storedState === 'true') {
                        $('#enableThreading').prop('checked', true);
                    }
                }
                // Toggle the class 'threaded' on or off when the checkbox changes state
                $('#enableThreading').on('change', function () {
                    var isChecked = $(this).is(':checked');
                    if (isChecked) {
                        console.log('Thread view is active.');
                        $('ul[component="topic"]').addClass('threaded');
                        $('.posts-container').addClass('threaded')
                        $('ul[component="topic"]').addClass('threaded')
                        $('.post-container').addClass('threaded')
                        $('.timeline-event').addClass('threaded')
                        $('[component="post/footer"]').addClass('threaded');
                        $('[component="post"]').each(function () {
                            // Add the 'threaded' class to matching elements
                            if ($(this).hasClass('pt-4') || $(this).hasClass('self-post')) {
                                $(this).addClass('threaded');
                                $('.topic .sticky-tools').addClass('threaded');
                            }
                        });
                    } else {
                        console.log('Thread view is inactive.');
                        $('[component="post"]').removeClass('threaded');
                        $('ul[component="topic"]').removeClass('threaded');
                        $('.posts-container').removeClass('threaded')
                        $('ul[component="topic"]').removeClass('threaded')
                        $('.post-container').removeClass('threaded')
                        $('.timeline-event').removeClass('threaded')
                        $('[component="post/footer"]').removeClass('threaded');
                        $('.topic .sticky-tools').removeClass('threaded');
                    }
                    // Store the checkbox state in localStorage
                    localStorage.setItem('enableThreadingState', isChecked);
                });
                // Check for changes in the checkbox state when the page loads
                $('#enableThreading').trigger('change');
            }
        });
    }
    
    function threadedChat() {
        $(document).ready(function () {
            // Check if the screen width is 1200px or more
            if ($(window).width() >= 1200) {
                // Check if the dropdown already exists
                if ($('#enableThreadingChat').length === 0) {
                    var chatView = $('<div class="threads-wrapper"><i class="fa fa-fw fa-bars left"></i><form class="form"><div class="form-check form-switch sticky-tools-bar"> \
                        <input class="form-check-input" id="enableThreadingChat" type="checkbox" data-field="enableThreading"> \
                        <label class=" d-none d-md-inline fw-semibold" for="enableThreadingChat"><span class="title-tooltip top" tooltip-text="Éditer Profil"><i class="fa fa-fw fa-bars-staggered right"></i></label> \
                    </div></form></div>');
                    $('[component="chat/header"]').prepend(chatView);
    
                    // Check if there's a stored state for the checkbox and update it
                    var storedState = localStorage.getItem('enableThreadingStateChat');
                    if (storedState === 'true') {
                        $('#enableThreadingChat').prop('checked', true);
                    }
                }
    
                // Toggle the class 'threaded' on or off when the checkbox changes state
                $('#enableThreadingChat').on('change', function () {
                    var isChecked = $(this).is(':checked');
                    if (isChecked) {
                        console.log('Thread view is active.');
                        $('[component="chat/message"]').each(function () {
                            // Add the 'threaded' class to matching elements
                            if ($(this).hasClass('chat-message')) {
                                $(this).addClass('threaded');
                            }
                        });
                    } else {
                        console.log('Thread view is inactive.');
                        $('[component="chat/message"]').removeClass('threaded');
                    }
    
                    // Store the checkbox state in localStorage
                    localStorage.setItem('enableThreadingStateChat', isChecked);
                });
    
                // Check for changes in the checkbox state when the page loads
                $('#enableThreadingChat').trigger('change');
            }
        });
    }
    
    
    $(window).on('action:chat.loaded', function(data) {
            threadedChat();
    });
    $(window).on('action:chat.received', function(data) {
            threadedChat();
    });
    $(window).on('action:ajaxify.end', function (data) {
        threaded();
    });
    
    $(window).on('action:posts.edited', function (data) {
        threaded();
    });
    
    $(window).on('action:posts.loaded', function (data) {
        threaded();
    });
    
  • @DownPW Thanks. You should remove the threadedChat function and these lines

    $(window).on('action:chat.loaded', function(data) {
            threadedChat();
    });
    $(window).on('action:chat.received', function(data) {
            threadedChat();
    });
    

    That code is not functional yet and is very experimental 🙂

    I’ll have a look at your DEV environment to make the code recommendations.

  • @DownPW I changed your CSS as it was lacking the actual .threaded class which is the target we add and remove

    .page-topic .topic .posts.timeline [component="topic/event"].timeline-event, .page-topic .topic .posts.timeline [component="topic/necro-post"].timeline-event.threaded {
        background: transparent !important;
        margin-bottom: 10px !important;
    }
    .page-topic .topic .posts.timeline .threaded:last-child .timeline-event:last-child,
    .page-topic .topic .posts.timeline .threaded:last-child>[component="post/placeholder"]:last-child,
    .page-topic .topic .posts.timeline .threaded:last-child>[component=post]:last-child {
        margin-left: 0.5rem !important;
    }
    

    Seems to work, but can you confirm?

  • nope

    Sorry I was on my way back from work @phenomlab

    So in fact I’m already going to try adding .threaded to the CSS code.

    When I activate Thread mode, everything is OK however when I deactivate Thread mode, certain classes remain and are not deleted

    For example here, without Thread mode, the background is not returned to vanilla and the same thing for the border-radius :

    0a214db5-6435-49dc-b04d-52842ba0b28d-image.png

  • @DownPW For clarity, I didn’t change all of the classes - only the two you posted last

    Threading off

    fe3562db-edee-4f63-a8aa-1eb59c1279ea-image.png

    Threading on

    a92e0031-cf0c-416e-a1f7-53a6cb3a6631-image.png

  • yep but these 2 class have problem, on your screens, with Threading Off, background color use –bs-body-navbar and not –bs-body-bg.
    And if you seen topi event is not transparent like vanilla

  • @DownPW That should make no difference?

    Just remove it from the class

    .page-topic .topic .posts.timeline .timeline-event, .page-topic .topic .posts.timeline > [component="post/placeholder"], .page-topic .topic .posts.timeline > [component=post] {
        border-left: none;
        transition: transform 0.3s ease !important;
        background: var(--bs-body-bg);
        /* background: var(--bs-body-navbar); */
        border-radius: var(--bs-border-radius);
    }
    

    9871c5b3-1b9b-415b-b848-0f663341fc09-image.png

  • that makes all the difference 🙂

    Vanilla is like this:

    image.png

  • @DownPW said in Threading support for NodeBB:

    And if you seen topi event is not transparent like vanilla

    It is for me

    6d89cea9-6311-48d1-8eea-07b7b827eafd-image.png

  • nope for me

    image.png

  • no return to vanilla background

    blink2.gif

    vanilla: bs-body-bg
    thread ON: bs-body-navbar

  • @DownPW Because your CSS has not been altered dude.

    ebe21e6c-5409-498f-a5dd-605403c52622-image.png

    Try now. It works for me?

  • I have not the same result :

    image.png

    I have bs-body-bg with thread ON


Related Topics
  • 3 Votes
    2 Posts
    81 Views

    Very great 😉

  • Threaded chat support for NodeBB

    Let's Build It
    35
    19 Votes
    35 Posts
    2k Views

    @DownPW said in Threaded chat support for NodeBB:

    Better like this : add shadow and border-left on self answer

    Of course - you style to your own requirements and taste 🙂 I’ll commit that CSS we discussed yesterday also

  • Interesting Widget code, but can't fetch API

    Solved Customisation
    26
    2 Votes
    26 Posts
    1k Views

    @Panda said in Interesting Widget code, but can’t fetch API:

    How did you drop that widget into the post there?
    I hadnt seen this BSgenerator anywhere on sudonix site, do you use it somewhere already?

    Yes, here

    https://sudonix.org/topic/414/corporate-bullshit-generator?_=1687774393044

    It’s not a “post” or “topic” in the common sense. It is actually a page in it’s own right and leverages nodebb-plugin-custom-pages. This in turn creates a new “route” which behaves like a page, meaning it is then exposed for widgets.

    @Panda said in Interesting Widget code, but can’t fetch API:

    Also can you explain more what you mean by calling the code externally. In my API call example, how would I go about doing that?

    By this, I mean create all the required code in an external JS file that is reachable by the NodeBB instance - so, in “public” for example - or in my case /public/js. The widget then “calls” that file and because it runs outside of the scope of NodeBB, you just need to return the values to the widget.

    Hope this makes sense?

  • Smart Widgets

    Solved Configure
    9
    3 Votes
    9 Posts
    408 Views

    @Panda said in Smart Widgets:

    So why is that, or conversely why would the function to expose username ever be required, as it seems app.user is already an available global object?

    It is, yes, but not if you are using it outside of a widget. The function I wrote is also historical and comes from the 2.x train 🙂

  • 2 Votes
    2 Posts
    157 Views

    @dave1904 that’s a really good point actually. I know it was there previously on Persona, but you’re right - no such function exists on harmony.

    However, putting something in place to mimick the behaviour of Persona won’t be hard from the js standpoint, although I wonder if perhaps we should ask the NodeBB developers is this feature was overlooked?

  • Blinking text Effect

    Customisation
    3
    5 Votes
    3 Posts
    438 Views

    @phenomlab

    I love it too

    @phenomlab said in Blinking text Effect:

    Has that “broken neon light” look that you see in films.

    It’s exactly that, kind of old neon signs of bar or pubs a bit cyberpunk too 😉

  • Adjusting the size of boxes in posts-list class

    Solved Customisation
    3
    3 Votes
    3 Posts
    278 Views

    @phenomlab thanks a lot, this combination works best 👍

    .posts-list .posts-list-item .content { overflow: auto; max-height: 600px; }
  • NodeBB Design help

    Solved Customisation
    8
    2 Votes
    8 Posts
    924 Views

    @riekmedia I’ve applied some new CSS to your site. Can you reload the page and try again ?

    For the record, this is what I added

    #footer { background: #2d343e; border-top: 4px solid #2d343e; font-size: 0.9em; margin-top: 70px; padding: 80px 0 0; position: relative; clear: both; bottom: 0; left: 0; right: 0; z-index: 1000; margin-left: -15px; margin-right: -338px; }

    The /categories page seems a bit messed up, so looking at that currently

    EDIT - issued some override CSS in the CATEGORIES widget

    <!--- CSS fix for overspill on /categories page - DO NOT DELETE --> <style> #footer { margin-right: -45px; } </style>

    That should resolve the /categories issue.