Technical Articles
Dark-Light: Auto Theme Changer based on Local Sunset Time or Simple FLP Configuration
Inspiration:
You would have seen some of your apps (e.g. Google Maps), laptop background screens (like in a Mac) automatically change background color/overall theme from light to dark mode by the time its evening and change back in the morning.
How cool would it be if we could do something like this on your UI5 app?
End Result:
Dark and Light mode
The idea is something like – once the app loads, it gets your geo-location, then based on it it identifies the sunset time for that location and if your current time is greater than the sunset time, change to Dark Theme else Light Theme.
Benefit:
Since the app is completely based on your geo-location, you don’t need to have any country specific coding to find sunset time or change the mode, etc.
Also take a use-case for a user who is spending a lot of time on the application and loses track of time – this is a very good visual aid to let him/her know that its evening/past sunset.
Technical Approach:
We are using window.navigator.geolocation to find your co-ordinates and using the open source sunrise-sunset api to get the sunset time of that geo-location.
To start with, say we have a function fnChangeTheme which we will call once our first view is rendered and we call this every minute to keep checking if our time has crossed sunset time or not.
onAfterRendering : function() {
//Code for fnChangeTheme()
.
.
.
//Check every minute for location/sunset change
setInterval(function () {
fnChangeTheme()
}, 60000);
}
Now what is our fnChangeTheme() function?
We simply call the navigator.geolocation.getCurrentPosition() function with fnGetSunset as our callback on what should happen after getting our current position.
function fnChangeTheme() {
//Get the current position and pass it to fnGetSunset() if GeoLocation is supported
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(fnGetSunset);
} else {
//If we do not allow Geo-location for the browser/page
alert("Geolocation is not supported by this browser.");
}
}
fnGetSunset accepts the current position and calls the open source sunrise-sunset api taking into consideration the location passed and we are just concerned on the sunset time returned.
Just for a quick rough code – if the current time hours is greater than or equal to the sunset time hours, this means we have crossed sunset, so change the theme to the dark theme, else change it to light theme.
function fnGetSunset(position) {
console.log(position);
var lat = position.coords.latitude;
var long = position.coords.longitude;
$.getJSON('https://api.sunrise-sunset.org/json?lat=' + lat + '&lng=' + long + '&formatted=0&callback=?', function (data) {
console.log(data);
var currentHrs = new Date().getHours();
console.log("CurrentHrs: " + currentHrs);
var sunsetHrs = new Date(data.results.sunset).getHours();
console.log("Sunset:" + sunsetHrs);
//if Current Hrs is <= Sunset Hrs, then light theme else dark theme
if (currentHrs <= sunsetHrs) {
sap.ui.getCore().applyTheme("sap_fiori_3");
} else {
sap.ui.getCore().applyTheme("sap_fiori_3_dark");
};
});
}
And that’s pretty much it.
Conclusion:
There are many improvement points in the coding or better approaches, but this is just one crude way to get an idea in place. Open for suggestion on how to enhance or better the approach.
The code is available on GitHub
Happy Learning!
Cheers!
UPDATE: 30th June
I got some feedback on also some approach to make it a simple configurable FLP Plugin where say the company has a policy of letting people know its evening/long working hours after 1600hrs (4pm), then you can simply configure the plugin in FLP with parameter configHrs = 16 and the plugin will take care of shifting the theme at 4pm.
I am assuming that creation of a shell plugin I need not explain as there are enough and more articles on the same.
init: function () {
var rendererPromise = this._getRenderer();
var currentHrs;
var configHrs = this.getComponentData().config.configHrs;
function fnChangeTheme() {
currentHrs = new Date().getHours();
//if Current Hrs is <= Config. Hrs, then light theme else dark theme
if (currentHrs <= configHrs) {
sap.ui.getCore().applyTheme("sap_fiori_3");
} else {
sap.ui.getCore().applyTheme("sap_fiori_3_dark");
}
}
setInterval(function () {
fnChangeTheme()
}, 60000);
},
<Keeping this place holder for sharing the plugin code once its ready>
Nice idea, you should make a FLP plugin and and share it with Wouter Lemaire and Tom Van Doorslaer initiative on showcasing FLP plugins
Thanks a lot Jakob
Wasn't aware of sharing FLP plugins - I will definitely try to package this and publish there.