Skip to content

Material View Support for Stock NodeBB

Unsolved Let's Build It
  • @DownPW done. Fixed a typo

  • Hello @phenomlab

    I didn’t even notice because I never use this mode. But when I say never it’s so much that I forget that it’s possible to do it.

    When right sidebar is expand, the button is at the bottom of the sidebar like this :
    image.png

    –> For now, I resolve the problem by change var buttonContainer = $('[component="sidebar/right"]'); for var buttonContainer = $('[component="sidebar/drafts"]');

    // ------------------------------------------
    function material() {
    $(document).ready(function () {
    // Create the button for custom thread view mode with custom IDs
    if ($('#materialThreadViewButton').length === 0) {
    var threadViewButton = $('<div class="material-threads-wrapper"><form class="form"><div class="form-check form-switch form-switch-sm material-threads-wrapper"> \
    <input class="form-check-input" id="materialThreadViewButton" type="checkbox" data-field="materialThreadView"> \
    <label class=" d-none d-md-inline fw-semibold" for="materialThreadViewButton"></label> \
    </div></form></div>');
    // Check if the screen width is 991px or more
    if ($(window).width() >= 991) {
    // Check if the custom thread view button already exists in the right sidebar
    var buttonContainer = $('[component="sidebar/drafts"]');
    // Append the button to the selected container
    buttonContainer.append(threadViewButton);
    }
    if ($(window).width() <= 991) {
    // Check if the custom thread view button already exists in the bottom bar
    //$buttonContainer = $('.bottombar-nav.p-2.text-dark.bg-light.d-flex.justify-content-between.align-items-center.w-100');
    if ($("#logged-in-menu").length > 0) {
    var buttonContainer = $('.bottombar-nav ul#logged-in-menu');
    }
    else {
    var buttonContainer = $('.bottombar-nav ul#logged-out-menu');
    }
    // Prepend the button to the selected container
    buttonContainer.prepend(threadViewButton);
    }
    }
    ..............

    it’s clearly better :

    c5c4df57-b33e-46ce-814b-18e514bf6933-image.png

    but if you have better solution (like add text if sidebar is expand for example) I take it 🙂

  • Seems this solution give me a new bug for tooltip

    image.png

    I have test this with no working :

    if (isChecked) {
    $('[component="sidebar/drafts"]').find('[data-toggle="tooltip"]').tooltip('dispose');
    } else {
    $('[component="sidebar/drafts"]').find('[data-toggle="tooltip"]').tooltip();
    }
  • @DownPW Seems to work fine for me?

  • @DownPW It doesn’t look right - the toggle switch is now located at the top of the menu

    a9e329a2-fff6-407c-bc08-9668b9b002c1-image.png

  • yep I test things at the moment

    I’m go back for you to see

    EDIT: You can test now @phenomlab

  • @DownPW Try this. Change the function to

    function material() {
    $(document).ready(function () {
    // Create the button for custom thread view mode with custom IDs
    if ($('#materialThreadViewButton').length === 0) {
    var threadViewButton = $('<div class="material-threads-wrapper"><form class="form"><div class="form-check form-switch form-switch-sm material-threads-wrapper"> \
    <input class="form-check-input" id="materialThreadViewButton" type="checkbox" data-field="materialThreadView"> \
    <label class=" d-none d-md-inline fw-semibold" for="materialThreadViewButton"></label> \
    </div></form></div>');
    // Check if the screen width is 991px or more
    if ($(window).width() >= 991) {
    // Check if the custom thread view button already exists in the right sidebar
    //var buttonContainer = $('[component="sidebar/right"]ul#logged-in-menu');
    if ($("#logged-in-menu").length > 0) {
    var buttonContainer = $('ul#logged-in-menu');
    }
    else {
    var buttonContainer = $('ul#logged-out-menu');
    }
    // Append the button to the selected container
    buttonContainer.append(threadViewButton);
    }
    if ($(window).width() <= 991) {
    // Check if the custom thread view button already exists in the bottom bar
    //$buttonContainer = $('.bottombar-nav.p-2.text-dark.bg-light.d-flex.justify-content-between.align-items-center.w-100');
    if ($("#logged-in-menu").length > 0) {
    var buttonContainer = $('.bottombar-nav ul#logged-in-menu');
    }
    else {
    var buttonContainer = $('.bottombar-nav ul#logged-out-menu');
    }
    // Prepend the button to the selected container
    buttonContainer.prepend(threadViewButton);
    }
    }
    // Check if there's a stored state for the checkbox and update it
    var storedState = localStorage.getItem('materialThreadViewState');
    console.log("Stored State is " + storedState);
    if (storedState === 'true') {
    $('#materialThreadViewButton').prop('checked', true);
    }
    // Toggle the class 'material' on or off when the checkbox changes state
    $('#materialThreadViewButton').on('change', function () {
    var isChecked = $(this).is(':checked');
    var theTooltip = isChecked ? "Material View Off" : "Material View On"; // Update tooltip message
    // Remove any existing tooltips
    $(this).tooltip('dispose');
    // Toggle CSS rules when the button is turned on or off
    if (isChecked) {
    console.log('Material Thread view is active.');
    // Apply your CSS rules here
    $('[component="category/topic"]').addClass('material');
    $('li[component="category/topic"]').addClass('material');
    $('[component="categories/category"]').addClass('material');
    $('.posts-container').addClass('material')
    $('ul[component="topic"]').addClass('material')
    $('.post-container').addClass('material')
    $('.timeline-event').addClass('material')
    $('[component="post/footer"]').addClass('material')
    $('li.pt-4.deleted').addClass('material')
    $('.page-topic .topic .posts.timeline .timeline-event > div:first-of-type, .page-topic .topic .posts.timeline > [component="post/placeholder"] > div:first-of-type, .page-topic .topic .posts.timeline > [component=post] > div:first-of-type').addClass('material');
    $('#pageUp.show').addClass('material');
    $('[component="post"]').each(function () {
    // Add the 'material' class to matching elements
    if ($(this).hasClass('pt-4') || $(this).hasClass('self-post')) {
    $(this).addClass('material');
    $('[component="sidebar/right"]').addClass('material');
    }
    });
    $('[component="topic/necro-post"]').each(function () {
    // Add the 'material' class to matching elements
    if ($(this).hasClass('timeline-event')) {
    $(this).addClass('material');
    }
    });
    } else {
    console.log('Material Thread view is inactive.');
    // Remove the CSS rules here
    $('[component="category/topic"]').removeClass('material');
    $('li[component="category/topic"]').removeClass('material');
    $('[component="categories/category"]').removeClass('material');
    $('[component="post"]').removeClass('material');
    $('ul[component="topic"]').removeClass('material');
    $('.posts-container').removeClass('material')
    $('ul[component="topic"]').removeClass('material')
    $('.post-container').removeClass('material')
    $('.timeline-event').removeClass('material')
    $('[component="post/footer"]').removeClass('material');
    $('li.pt-4.deleted').removeClass('material');
    $('.page-topic .topic .posts.timeline .timeline-event > div:first-of-type, .page-topic .topic .posts.timeline > [component="post/placeholder"] > div:first-of-type, .page-topic .topic .posts.timeline > [component=post] > div:first-of-type').removeClass('material');
    $('#pageUp.show').removeClass('material');
    $('[component="sidebar/right"]').removeClass('material');
    }
    // Store the checkbox state in localStorage
    localStorage.setItem('materialThreadViewState', isChecked);
    // Update the tooltip title
    $(this).attr('data-original-title', theTooltip).tooltip('dispose').tooltip({
    placement: 'bottom',
    title: theTooltip,
    trigger: 'hover'
    });
    });
    // Check for changes in the checkbox state when the page loads
    $('#materialThreadViewButton').trigger('change');
    });
    }

    And modify this CSS to the below

    @media (min-width: 991px) {
    #materialThreadViewButton {
    border-radius: 7px;
    cursor: pointer;
    position: relative !important;
    z-index: 999;
    display: flex;
    left: 15px !important;
    top: 5px !important;
    transform: rotate(90deg) !important;
    }
    }

    Essentially, we have to change the positioning of the block to use the logged-in and logged-out ID’s

    // Check if the screen width is 991px or more
    if ($(window).width() >= 991) {
    // Check if the custom thread view button already exists in the right sidebar
    //var buttonContainer = $('[component="sidebar/right"]ul#logged-in-menu');
    if ($("#logged-in-menu").length > 0) {
    var buttonContainer = $('ul#logged-in-menu');
    }
    else {
    var buttonContainer = $('ul#logged-out-menu');
    }
    // Append the button to the selected container
    buttonContainer.append(threadViewButton);
    }
  • I tested the same thing but added a container like [component="sidebar/right"] or [component="sidebar/drafts"] or the sidebar right CSS class. it worked but it created other bugs

    I’m not sure I would have thought to do this without specifying a container and just use ul#logged-out-menu & ul#logged-in-menu ALONE, no component or CSS class 🙂

    Thanks @phenomlab

  • @DownPW The real issue here is that you should always bind (either append or prepend) to an ID rather than a class. You can guarantee in most cases that the ID is unique, whereas the class probably isn’t, and that’s what is causing your issue.

  • Oh yes, that’s what’s super cool, I learn something every day. Afterwards I start from so low in JS


49/51

9 Oct 2023, 10:46

Related Topics