@Norrad Are you looking for anything in particular? I only ask because Sudonix uses a number of custom functions which I wrote, but all are available on GitHub and fully supported here.
v3 & Harmony diary / thoughts / code snippets
-
Hi All,
I thought that seeing as I’ve been quiet for a while that I’d start a new thread that will detail the journey Sudonix is taking to reach BS5, v3 of NodeBB, and the adoption of the Harmony theme. I’ve been playing with the “Nord” theme, and am pleased to report that the CSS needed since the move from standard
CSS
toLESS / SCSS
has been remarkably reduced. Presently, I’m at 324 lines - a huge difference to the 4,479 (yes, that’s right…) currently in use here.And no doubt you’re curious as to what
v3.beta1
of NodeBB looks like, combined with Harmony, and the theme I’m working on?Here’s what the standard iteration looks like via https://community.nodebb.org
And here’s what the
Nord
theme on https://sudonix.dev looks likeWARNING: Extreme sexiness ahead
The Swatch script is also functional
Interestingly, this differs heavily from v2 (mostly because the jump from BS3 to BS5 is significant). Currently, it looks like this in v2
// ------------------------------------------ // Swatch Applet // ------------------------------------------ $(document).ready(function() { function generateRandomString(length) { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; } var string = generateRandomString(10); $("#random_string").text(string); var whichTheme = localStorage.getItem("theme"); var activeTheme = localStorage.getItem("activeTheme"); // If no theme is detected (for example, a new visitor), then set this to default if (!whichTheme) { // dark-mode media query matched or not let matched = window.matchMedia('(prefers-color-scheme: dark)').matches; //var override = getUrlParameter('override'); if (matched) { // Offer the mifnight theme by default whichTheme = "midnight"; activeTheme = "/assets/customcss/midnight.css?version=" + string; //$("link[rel=stylesheet]").attr('href' , thishref + "?version=" + string + ""); } else { // Leave the default theme intact whichTheme = "default"; activeTheme = "/assets/customcss/daylight.css?version=" + string; } // See if override has been enabled if (whichTheme === 'default') { // Sudonix is overriding operating system settings and will force dark scheme activeTheme = "/assets/customcss/daylight.css?version=" + string; } if (whichTheme === 'daylight') { // $('[component="post"]').addClass("background"); $('li.self-post .content:not(.isSolved [component="post/content"]').addClass("response"); } else { // Nothing to do :) } } /*$(".forum-logo").attr("src","/assets/uploads/system/sl_" + whichTheme + ".webp?version=" + string + ""); */ var panel = $('<li id="switcher" class="dropdown"> \ <a title="" data-original-title="Swatch" class="navigation-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> \ <i id="ticon" class="fa fa-light fa-swatchbook" data-content="" aria-hidden="true"></i> \ <span class="visible-xs-inline">Swatch</span> \ <i class="fa fa-caret-down" aria-hidden="true"></i> \ </a> \ <ul id="theme" class="dropdown-menu"> \ <li><a id="default" href="#" rel="/assets/customcss/daylight.css">Default</a></li> \ <li><a id="anthracite" href="#" rel="/assets/customcss/anthracite.css">Anthracite</a></li> \ <li><a id="darkly" href="#" rel="/assets/customcss/darkly.css">Darkly</a></li> \ <li><a id="daylight" href="#" rel="/assets/customcss/daylight.css">Daylight</a></li> \ <li><a id="facetube" href="#" rel="/assets/customcss/facetube.css">FaceTube</a></li> \ <li><a id="greybird" href="#" rel="/assets/customcss/greybird.css">Greybird</a></li> \ <li><a id="midnight" href="#" rel="/assets/customcss/midnight.css">Midnight</a></li> \ <li><a id="nord" href="#" rel="/assets/customcss/nord.css">Nord</a></li> \ <li><a id="slate" href="#" rel="/assets/customcss/slate.css">Slate</a></li> \ <li><a id="superhero" href="#" rel="/assets/customcss/superhero.css">Superhero</a></li> \ <li><a id="tempest" href="#" rel="/assets/customcss/tempest.css">Tempest</a></li> \ <li><a id="twitter" href="#" rel="/assets/customcss/twitter.css">Twitter</a></li> \ </ul> \ </li> \ </div> \ '); if (whichTheme) { $.get(activeTheme, function(css) { $('<style type="text/css"></style>') .html(css) .appendTo("head"); }); } else {} $('#main-nav').append(panel); if (utils.findBootstrapEnvironment() === 'xs') { $('#main-nav').append(panel); } $(document).ready(function() { $("body").on("click change", "#theme li a", function() { var thishref = $(this).attr('rel') + '?version=' + string; $.get(thishref, function(css) { $('<style type="text/css"></style>') .html(css) .appendTo("head"); }); console.log("Applying swatch " + thishref); //location.reload(); var selected = $(this).attr("id"); var theTheme = $(this).attr("rel"); if (selected === 'default') { localStorage.setItem("theme", selected); localStorage.setItem("activeTheme", "/assets/customcss/daylight.css?version=" + string); //location.reload(); } else { localStorage.setItem("theme", selected); localStorage.setItem("activeTheme", theTheme); } return false; }); }); });
Now in v3, it looks VERY different
var mobiledropdown = $('<li class="nav-item dropend" title="Swatch"> \ <a class="nav-link nav-btn navigation-link px-3 py-2 dropdown-toggle" href="#" role="button" data-bs-toggle="collapse" data-bs-target="#theme" onclick="event.stopPropagation();"> \ <span class="d-inline-flex justify-content-between align-items-center w-100"> \ <span class="text-nowrap truncate-open"> \ <i class="fa fa-fw fa-painbrush" data-content="" aria-hidden="true"></i> <span class="nav-text visible-open px-2 fw-semibold">More</span> </span> <span component="navigation/count" class="visible-open badge rounded-1 bg-primary hidden"></span> </span> </a> <div class="ps-3"> <ul id="theme" class="collapse list-unstyled ps-3"> \ <li><a id="default" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/daylight.css">Default</a></li> \ <li><a id="anthracite" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/anthracite.css">Anthracite</a></li> \ <li><a id="darkly" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/darkly.css">Darkly</a></li> \ <li><a id="daylight" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/daylight.css">Daylight</a></li> \ <li><a id="facetube" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/facetube.css">FaceTube</a></li> \ <li><a id="greybird" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/greybird.css">Greybird</a></li> \ <li><a id="midnight" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/midnight.css">Midnight</a></li> \ <li><a id="nord" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/nord.css">Nord</a></li> \ <li><a id="slate" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/slate.css">Slate</a></li> \ <li><a id="superhero" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/superhero.css">Superhero</a></li> \ <li><a id="tempest" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/tempest.css">Tempest</a></li> \ <li><a id="twitter" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/twitter.css">Twitter</a></li> \ </ul> </div> </li> '); var desktopnavbar = $('<li id="switcher" class="nav-item mx-2 dropend" title="Swatch"> \ <a class="nav-link nav-btn navigation-link d-flex gap-2 justify-content-between align-items-center dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> \ <span class="d-flex gap-2 align-items-center text-nowrap truncate-open"> \ <span class="position-relative"> \ <i class="fa fa-fw fa-paintbrush" data-content="" aria-hidden="true"></i> \ <span component="navigation/count" class="visible-closed position-absolute top-0 start-100 translate-middle badge rounded-1 bg-primary hidden"></span> \ </span> \ <span class="nav-text small visible-open fw-semibold text-truncate">Swatch</span> \ </span> \ <span component="navigation/count" class="visible-open badge rounded-1 bg-primary hidden"></span> \ </a> \ <ul id="theme" class="dropdown-menu overflow-auto" data-popper-placement="right-end"> \ <li><a id="default" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/daylight.css">Default</a></li> \ <li><a id="anthracite" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/anthracite.css">Anthracite</a></li> \ <li><a id="darkly" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/darkly.css">Darkly</a></li> \ <li><a id="daylight" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/daylight.css">Daylight</a></li> \ <li><a id="facetube" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/facetube.css">FaceTube</a></li> \ <li><a id="greybird" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/greybird.css">Greybird</a></li> \ <li><a id="midnight" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/midnight.css">Midnight</a></li> \ <li><a id="nord" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/nord.css">Nord</a></li> \ <li><a id="slate" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/slate.css">Slate</a></li> \ <li><a id="superhero" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/superhero.css">Superhero</a></li> \ <li><a id="tempest" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/tempest.css">Tempest</a></li> \ <li><a id="twitter" class="dropdown-item rounded-1" href="#" rel="/assets/customcss/twitter.css">Twitter</a></li> \ </ul> \ </li> \ </div> \ ');
I’ve yet to decide how many of the v2 swatches will make their way into v3 on Sudonix -likely candidates will be
- Anthracite
- Darkly
- Facetube
- Midnight
- Nord
- Slate
- Superhero
- Tempest
Also, the “conversational / messenger view” is destined to be scrapped. It looked good at the time, and I know a number of you adopted it for your own forums, but it’s not really “today’s standard” - and, a LOT of effort to code for very little cosmetic return.
Stay tuned for more updates
-
Let me know if you have any specific requests around v3 theming
-
Can’t wait to try this
-
The colour palette used in the Nord theme (see first post here) is taken from this excellent resource
-
How to use it ?
PM if you want. -
@DownPW You just use the hex codes it provides. Nothing more to it than that.
-
-
@DownPW sorry, I thought you were referring to the Nord theme URL I posted. The Swatch code isn’t ready for use yet.
-
@phenomlab Ok bro. No problem
-
I’ve made significant progress with the first Swatch template. However, it’s a little way off being completely ready as there are a number of
js
functions that need to be completed (or in some cases, rewritten) first before the alpha phase of testing can start.In addition, there’s the rapid succession of changes and updates to the bootstrap core in NodeBB v3, plus updates to the harmony theme itself, It’s hard to determine the impact this will have on the Swatch code itself. I’ve already found an issue in the tooltip function - as the Swatch code runs after the harmony code, it means that the same function for the tooltip has to be run again.
This then causes an error to be generated in the console at random intervals. I know why this is - essentially, it’s because
destroy
as aJS
function was removed in BS 4.1 and replaced withdispose
- see the below thread raised in the NodeBB forum.https://community.nodebb.org/topic/16914/3-0-0-bug-report-thread/56?_=1675107774184
The advice here is to start NodeBB using Grunt so that the
JS
remains uncompressed - which should make thedestroy
function easier to track. None of this is the “end of the world” - it’s merely cosmetic, but could cause issues further down the line, so it’s best to isolate this issue now and remediate - unless there’s a better way to activate the tooltip function again without it throwing the same error.Another option here is to use the navigation menu in the ACP which means that the tooltip function should fire as the menu items are already in the DOM. However, taking this route comes with a number of drawbacks in the sense that it isn’t as flexible as adding arbitrary code.
This is something I’ll need to investigate further but taking this route places additional burden on those using the Swatch code which obviously negates the user experience.
-
More styling work completed today. Started looking at an decent alternative to the scroll top navigator featured on this site. I designed this a while ago and it’s designed to mimic the post scroller in Persona. With a little bit of modification, it would fit harmony very well in my view.
Currently the code I wrote for this is lying dormant on a VM I created for v3 development but since abandoned when the announcement around the harmony theme was announced. Its going to be hard to walk away from what constitutes around 100 hours of new CSS and
js
but this was designed for Persona, and my thoughts are given all the fanfare with Harmony, the previous staple theme will fade into obscurity - perhaps no longer developed, meaning I’d have to both fork the last version and maintain it going forward.Honestly, I just don’t have time to commit to that, so the decision to turn my back on Persona development has been made, and it’s all harmony from now on. Sadly, this does mean the death knell for the conversation style CSS I developed. I won’t be including this in harmony as it’s difficult to support given it needs to add various new CSS classes into the DOM as posts are being loaded by Ajax. Clearly, this isn’t exactly optimum, and in fact, will slow down the rendering process if poorly coded.
Not sure if it’s my imagination, but v3 seems “oh so slightly” slower than v2. Literally nothing in it, but noticeable to me so clearly, there’s some room for tuning here which I think will be at the nginx level.
Stay tuned.
-
@phenomlab said in v3 / Harmony diary:
perhaps no longer developed
well, although I understand your choice with Harmony, I believe Persona has its charm and will continue to be developed. you do not think so?
-
@phenomlab it seems i gonne use v2 end of this year. because i see that v2 very fast than v3 i mean page speed, user test etc.
-
@crazycells said in v3 / Harmony diary:
I believe Persona has its charm and will continue to be developed. you do not think so?
It’s a feeling I have, and in my experience, something I’ve seen many times. Persona was the default theme shipped with v2, and has been the mainstay of that version for a long time. However, things change, and by NodeBB’s own admission, it needed an update to bring it in line with modern layouts and mobile design. As you know, Harmony is not a fork, but a completely new design that also requires v3 for it to work at all.
To me, this is the final whistle for Persona. Harmony will supersede it in every way, and eventually, development will stall for the former product with all the focus being on Harmony itself. My view is that Persona will become a community fork to stop it from disappearing completely, but in the same vein, I think most (like me) will jump ship and move to Harmony.
-
@cagatay said in v3 / Harmony diary:
it seems i gonne use v2 end of this year. because i see that v2 very fast than v3 i mean page speed, user test etc
Yes, I’m glad I’m not the only one to witness this. I am going to raise this with the NodeBB team
EDIT - raised in the v3 Bug thread
https://community.nodebb.org/topic/16914/3-0-0-bug-report-thread/76?_=1675420990079 -
Ok, spun up the dev VM I started working on
And here’s a video of the reworked pagination / scroller utility I wrote that fires on pages
https://sudonix.com/assets/uploads/files/screen-capture.webm
This was originally designed to work in tandem with the Persona scroller / navigation, but would be simple to convert to Harmony and BS5.
-
Today’s playground
Here’s a video… still needs a bit more work, but…
Notice the newer scroll and progress bar I was talking about earlier…
-
Oh It’s very good. I love it
-
@phenomlab waiting
-
@phenomlab said in v3 / Harmony diary:
Today’s playground
Here’s a video… still needs a bit more work, but…
Notice the newer scroll and progress bar I was talking about earlier…
Hello Mark,
I just tested the functioning of the scroll bar and I saw this bug:
https://i.imgur.com/VQw5zw5.mp4
It should be moved to the left so as not to encroach on the collapse button of the custom footer navbar.
Then, when we play with the collapse button of the custom footer navbar we should:
-
When the custom footer navbar is deactivated: it sticks to the bottom right while not encroaching on the right sidebar. All this taking into account the collapse of the right sidebar (not obvious, I don’t know if I’m clear
)
-
When the custom footer navbar is activated: it moves just to the left of the floatright block or can be above the floatright block?
The solution may be less difficult to code would be to make a vertical scrollbar inside the right sidebar like in topics. There might be less to manage
Keep the good work my friend
-
Related Topics
-
-
-
NodeBB socket with CloudFlare
Unsolved Performance -
NodeBB: Creating pages
Solved Configure -
nodebb loading emojis
Solved Configure -
-
-