Advanced Nightmode for NodeBB



  • So, turns out users /really/ like nightmode.

    So while for some sites, the previous, much simpler nightmode will work fine, some will find their users demanding more complex functionality out of the nightmode as the site grows, or at least I did.

    This is a far more complex setup, however- so if you find it intimidating, the simple night mode will work almost as well, with a third of the work.

    So here's a more complex nightmode, with the following functionalities:

    1. Saved state- It will remember a users preference, and flip the nightmode to it on load.
    2. Auto nightmode option- Like google maps, it flips nightmode on when its night, and off when it's day.
    3. Instead of a cluttered toggle, separated functions

    Step 1: CSS

    Grab notepad or nodepad++, and your favorite web browser for development. Open up the inspector (ctrl-shift-i on chrome), and carefully tweak your way to a working night mode, copy pasting each CSS rule you make to the txt document, removing any unrelated rules (Keep only things you change!).

    Be detailed! Remember dismiss dialogs, search pages, group pages, user settings pages, composers, everything.

    Once you have a full night mode CSS, save this file as nightmode.css

    Step 2: Putting the CSS file on your server

    Use filezilla or similar to throw nightmode.css into nodebb/public

    Step 3: JS

    Paste the following into your header:

     <script>
     function nightmodeon(){
         var el = document.getElementById('myStyles');
         if ( el !== null ) {  
         } else {        
             var oLink = document.createElement("link") 
             oLink.id   = 'myStyles';
             oLink.href = "/nightmode.css";
             oLink.rel = "stylesheet"; 
             oLink.type = "text/css"; 
             document.body.appendChild(oLink);
         }
     }
     function daymode(){
         var el = document.getElementById('myStyles'); 
         if ( el !== null ) {               
             el.parentNode.removeChild(el);  
         } else {
             var oLink = document.createElement("link") 
             oLink.id   = 'myStyles';
             oLink.href = "/nightmode.css";
             oLink.rel = "stylesheet"; 
             oLink.type = "text/css"; 
         }
     }
     function autonightmode(){
     var d = new Date();
     var n = d.getHours();
     if (n >= 21 || n <= 5) {
     	nightmodeon()
     }
     else{
         daymode()
     }
     }
     function nmSwitch(){
     if (Number(localStorage.nmState) == 1) {
         localStorage.nmState = Number(localStorage.nmState)+1;
     	modeSet()
     }
     else if (Number(localStorage.nmState) == 2) {
         localStorage.nmState = Number(localStorage.nmState)+1;
         modeSet()
     }
     else if (Number(localStorage.nmState) == 3) {
         localStorage.nmState = Number(localStorage.nmState)+1;
         modeSet()
     }
     else {
         localStorage.nmState = 1;
     }
     }
     function modeSet(){
     if (Number(localStorage.nmState) == 1) {
         autonightmode();
         console.log('modeAuto');
     }
     else if (Number(localStorage.nmState) == 2) {
         daymode();
         console.log('modeDay');
         $(".nightmodeCSS").html(" ");
     }
     else if (Number(localStorage.nmState) == 3) {
         nightmodeon();
         console.log('modeNight');
         $(".nightmodeCSS").html(" ");
     }
     else {
         autonightmode();
         localStorage.nmState = 1;
     	console.log('modeElseAuto');
     }
     }
     </script>`
    

    You also need to create a HTML footer widget, and place this inside the widget. If you do not do this, it will not work.

    <script> modeSet(); </script>

    Step 4: Button

    The button for this CAN be simple, but that will be absolutely baffling for the user, because it has three states, one less obvious then the others. You /will/ want to style this button to have three states, one for each mode, so the user can tell what mode they're in. However, if you just want to get it working and let the users sort it out, you can simply place this:

    <button class="nightmodebutton" onclick="nmSwitch();"><span></span></button>

    HOWEVER, there is a special place in hell for people who do that. Ideally, you should style the above button as "OFF" in your default CSS, style it as "ON" in your nightmode CSS, then add something like:

    $(".[CLASS OF SOME EMPTY DIV HERE]").html("<style>.[BUTTONCLASS] span {color: #2196f3 !important;}</style>");

    into "function autonightmode()", to give it an "Auto" state.


    Hopefully that wasn't too complex, I'm aware it's a bit of a wall of text. Feel free to shoot me a chat if you have issues setting this up!


  • Plugin & Theme Dev

    css should be compiled with your theme, uploading to public seems like a hack for me :p


  • Global Moderator

    Add to custom header...

    <script>
    $(window).on('action:widgets.loaded', function() {
      if (!$('li.lights-out').length) {
        var panel = $('<li class="lights-out"><a title="" href="#" data-original-title="Dark Theme"><i class="fa fa-fw fa-lightbulb-o"></i><span class="visible-xs-inline">Dark Theme</span></a></li>');
        $('ul#logged-in-menu').prepend(panel);
        $('ul#logged-out-menu').prepend(panel);
        panel.on('click', function() {
        enabled = !$('body').hasClass('lights-out');
        $('body').toggleClass('lights-out',  enabled);
        localStorage.setItem('user:theme', enabled ?  'lights-out' : '');
        });      
      }
    });
    </script>
    
    
    <script>
    $('document').ready(function() {
        var theme = localStorage.getItem('user:theme');
        if (theme) {
            $('body').addClass(theme );
        }
    });
    </script>
    
    body.lights-out {
        background: none repeat scroll 0 0 #262525;
        color: #bdbdbd;
    }
    

    Rinse and repeat with css including body.lights-out before your changes, add to custom css.



  • @exodo Anything I do will always be a hack, rule one of things I produce. I do spagetti code like some sort of horrible, programming emnem.

    @a_5mith

    That is a good midway method, if much less copy and paste ease of set up for more complex tweaks then just changing out 2 or 3 divs.

    However, besides the automode, that is inarguably more elegant programmatically way to accomplish that!


  • Global Moderator

    @Arc said:

    @a_5mith

    That is a good midway method, if much less copy and paste ease of set up for more complex tweaks then just changing out 2 or 3 divs.

    However, besides the automode, that is inarguably more elegant programmatically way to accomplish that!

    My aim was to have one theme that changed the important bits to match a dark theme. Got a bit tedious keeping up with theme changes. Will rework it for Persona just as they release a new theme. :D



  • @a_5mith said in Advanced Nightmode for NodeBB:

    Add to custom header...

    <script>
    $(window).on('action:widgets.loaded', function() {
      if (!$('li.lights-out').length) {
        var panel = $('<li class="lights-out"><a title="" href="#" data-original-title="Dark Theme"><i class="fa fa-fw fa-lightbulb-o"></i><span class="visible-xs-inline">Dark Theme</span></a></li>');
        $('ul#logged-in-menu').prepend(panel);
        $('ul#logged-out-menu').prepend(panel);
        panel.on('click', function() {
        enabled = !$('body').hasClass('lights-out');
        $('body').toggleClass('lights-out',  enabled);
        localStorage.setItem('user:theme', enabled ?  'lights-out' : '');
        });      
      }
    });
    </script>
    
    
    <script>
    $('document').ready(function() {
        var theme = localStorage.getItem('user:theme');
        if (theme) {
            $('body').addClass(theme );
        }
    });
    </script>
    
    body.lights-out {
        background: none repeat scroll 0 0 #262525;
        color: #bdbdbd;
    }
    

    Rinse and repeat with css including body.lights-out before your changes, add to custom css.

    If I use the code, I see 2 lightbulbs in the navbar.

    0_1472780754264_Knipsel.JPG



  • can somebody explain why I have 2 lightbulbs?


  • Admin

    what's your forum URL?

    It's probably this, probably both menus are shown:

    $('ul#logged-in-menu').prepend(panel);
    $('ul#logged-out-menu').prepend(panel);
    


  • @psychobunny http://keen.wtf

    if you need to login you can use the following


    username: AAA
    password: AAAAAA




  • @psychobunny if I remove one of those lines it doesn't make a different



  • How could I alter this to switch skins? I use flatly but I'd like the darkly to enable at night automagically.



  • btw, on nodebb 1.2.1 the 2 lightbulbs are fixed it's now 1


Log in to reply
 


Looks like your connection to NodeBB was lost, please wait while we try to reconnect.