Dark mode with Dark Reader / best solution but how to implement...?

There is a Dark Theme module - Dark Reader (https://marketplace.mendix.com/link/component/116773), which perfectly reflects my expectations of running dark mode. It is ideal because it does not require you to define the colours of the elements "manually" but everything happens "automatically".   However, it has one but significant drawback: it is not persistent. This means that every time the user logs in to the site, he or she has to turn it on because, by default, the script runs with nanoflow.   The module works exactly like this: it runs nanoflow, which creates a defined non-persistent entity, and then runs a java script that retrieves data from the entity, which in the next step runs another java script that changes the colours to dark (based on the Dark Reader algorithm, the effects of which can be obtained if only as a browser add-on, more here: https://darkreader.org).   What I want is to be able to run this when the user has the dark mode enabled in their settings (boolean parameter in the user settings entity).   The issue seems simple but it is killed by the limitations and rules of microflows and nanoflows.   Firstly, nanoflow cannot retrive an entity that has not been passed as a parameter. So at runtime it cannot check what setting the user has. But nanoflow can't be run after the page starts anyway. It would be possible to retrieve this parameter via microflow but this in turn cannot run nanoflow. So in theory you could create a Java Action that runs the code I mentioned earlier that is used in nanoflow. But this is where I unfortunately fell down.   The code seems very simple: export async function JSA_ApplyTheme(theme, themeOptions, themeFixes) { // BEGIN USER CODE var options = themeOptions == null ? {} : { brightness: themeOptions.get("Brightness"), contrast: themeOptions.get("Contrast"), grayscale: themeOptions.get("Grayscale"), sepia: themeOptions.get("Sepia"), useFont: themeOptions.get("UseFont"), fontFamily: themeOptions.get("FontFamily"), textStroke: themeOptions.get("TextStroke"), darkSchemeBackgroundColor: themeOptions.get("DarkSchemeBackgroundColor"), darkSchemeTextColor: themeOptions.get("DarkSchemeTextColor"), lightSchemeBackgroundColor: themeOptions.get("LightSchemeBackgroundColor"), lightSchemeTextColor: themeOptions.get("LightSchemeTextColor"), scrollbarColor: themeOptions.get("ScrollbarColor"), selectionColor: themeOptions.get("SelectionColor"), styleSystemControls: themeOptions.get("StyleSystemControls") }; var themeFixesObj = null; try { themeFixesObj = JSON.parse(themeFixes); } catch ( e ) { console.warn("Failed to parse theme fixes. ",e); } if ( theme == "light" ) { DarkReader.disable(); } else if ( theme == "dark") { DarkReader.enable(options, themeFixesObj); } else { DarkReader.auto(options, themeFixesObj); } // parseDynamicThemeFixes(themeFixes); // END USER CODE Entity:   And it is this code that runs the code from the darkener.js file, which is responsible for the "magic". But unfortunately I don't know how to translate this into Java Action. I just get errors popping up at the level of importing data from the passed in entity.    And this code runs the code from the darkener.js file, which is responsible for the "magic". But unfortunately I don't know how to translate this into Java Action. I just get errors popping up at the level of importing data from the passed in entity.  In fact, I need two codes: the first one that interprets the data from the indicated entity (the one above) which it sends to the second code that does the relevant calculations and changes the colours.    Maybe someone has an idea how to do this?   You can find the code that does the actual calculations here: https://www.npmjs.com/package/darkreader?activeTab=code or the whole source code here: https://github.com/darkreader  
2 answers

Hey Marc,

If you want a quick, working solution,
You can use the microflow timer widget on the user's home page. This widget can call a nanoflow and has the option to execute it only once. This nanoflow can have your logic check the boolean of the user theme and execute the Javascript action :).


This is a good idea however not without its drawbacks.

The widget has to be placed on a specific page (most likely the home page) and then everything works fine IF, someone does not enter from outside on a page other than the home page (for example using DeepLink). And this is where the solution seems to come in: in theory TopBar seems to be the right solution. Placing the widget on the TopBar and retrieving the entity information from there, which is passed to nanoflow RIGHTLY works ;)

Everything is ok until the user refreshes the page or enters from an external link - then the screen "bursts" with bright light for a while before the Timer runs the code (of course the code is set to run as soon as it loads, but it takes a while to process this and originally the page loads in bright colours for a moment – I think it takes about 200-300ms, but it is very annoying if you are sitting in a dark room).

I guess I'll have to sit down and change the colours in the CSS for darkmode as this solution probably won't work in the long run. 

But thanks for the reply, that's a really good lead ;)