diff --git a/api/js/framework/fw_base.js b/api/js/framework/fw_base.js index c2522689b8..d74c6e4bed 100644 --- a/api/js/framework/fw_base.js +++ b/api/js/framework/fw_base.js @@ -64,8 +64,17 @@ var fw_base = (function(){ "use strict"; return Class.extend( // keep track of opened popups this.popups = []; + // initiate dark mode - this._setDarkMode(egw.preference('darkmode', 'common')); + let darkmode = egw.getSessionItem('api', 'darkmode'); + if (darkmode == '0' || darkmode == '1') + { + this._setDarkMode(darkmode); + } + else if (egw.preference('darkmode', 'common') !='2') + { + this._setDarkMode( egw.preference('darkmode', 'common')); + } }, /** @@ -1304,8 +1313,14 @@ var fw_base = (function(){ "use strict"; return Class.extend( return _app && _app.appName != _app.internalName; }, + /** + * set darkmode attribute into html tag + * @param string _state '0' means off and '1' means on + * @private + */ _setDarkMode: function(_state) { jQuery('html').attr('data-darkmode', _state); + egw.setSessionItem('api', 'darkmode',_state == '0' ?'0':'1'); } });}).call(this); diff --git a/api/js/framework/fw_desktop.js b/api/js/framework/fw_desktop.js index 7357227481..61cab2046d 100644 --- a/api/js/framework/fw_desktop.js +++ b/api/js/framework/fw_desktop.js @@ -220,6 +220,31 @@ egw.message(egw.lang('Browser %1 %2 is not recommended. You may experience issues and not working features. Please use the latest version of Chrome, Firefox or Edge. Thank You!', 'IE',''), 'info', 'browser:ie:warning'); } }); + + // initiate darkmode + let darkmode = egw.preference('darkmode', 'common'); + if (darkmode == '2') + { + let prefes_color_scheme = this._get_prefers_color_scheme(); + if (prefes_color_scheme) + { + + window.matchMedia('(prefers-color-scheme: dark)') + .addEventListener('change', event => { + this.toggle_darkmode(document.getElementById('topmenu_info_darkmode'), event.matches?false:true); + }); + this.toggle_darkmode(document.getElementById('topmenu_info_darkmode'), prefes_color_scheme == 'light'); + } + } + else if (egw.getSessionItem('api', 'darkmode') == '1') + { + this.toggle_darkmode(document.getElementById('topmenu_info_darkmode'), false); + } + else if(egw.getSessionItem('api', 'darkmode') == '0') + { + this.toggle_darkmode(document.getElementById('topmenu_info_darkmode'), true); + } + }, /** @@ -537,14 +562,31 @@ if (app.status) app.status.mergeContent(_data, true); }, + /** + * Get color scheme + * @return {string|null} returns active color scheme mode or null in case browser not supporting it + * @private + */ + _get_prefers_color_scheme: function () + { + if (window.matchMedia('(prefers-color-scheme: light)').matches) + { + return 'light'; + } + if (window.matchMedia('(prefers-color-scheme: dark)').matches) + { + return 'dark' + } + return null; + }, + /** * * @param node */ - toggle_darkmode: function(node) + toggle_darkmode: function(node, _state) { - let state = node.firstElementChild.classList.contains('darkmode_on'); - egw.set_preference('common', 'darkmode',state?'0':'1'); + let state = (typeof _state != 'undefined') ? _state : node.firstElementChild.classList.contains('darkmode_on'); this._setDarkMode(state?'0':'1'); if (state == 1) { diff --git a/api/js/jsapi/egw_app.js b/api/js/jsapi/egw_app.js index 2df94e4271..d596a2348a 100644 --- a/api/js/jsapi/egw_app.js +++ b/api/js/jsapi/egw_app.js @@ -118,7 +118,7 @@ var EgwApp = /** @class */ (function () { // Highlights the favorite based on initial list state this.highlight_favorite(); // apply theme mode - jQuery('html').attr('data-darkmode', egw.preference('darkmode', 'common')); + window.framework._setDarkMode(egw.getSessionItem('api', 'darkmode')); }; /** * Observer method receives update notifications from all applications diff --git a/api/js/jsapi/egw_app.ts b/api/js/jsapi/egw_app.ts index 5675d44ad4..ed26e25474 100644 --- a/api/js/jsapi/egw_app.ts +++ b/api/js/jsapi/egw_app.ts @@ -208,7 +208,7 @@ export abstract class EgwApp // Highlights the favorite based on initial list state this.highlight_favorite(); // apply theme mode - jQuery('html').attr('data-darkmode', egw.preference('darkmode', 'common')); + window.framework._setDarkMode(egw.getSessionItem('api', 'darkmode')); } /** diff --git a/api/js/login.js b/api/js/login.js index 5d167c798c..ecb5284060 100644 --- a/api/js/login.js +++ b/api/js/login.js @@ -72,6 +72,8 @@ egw_LAB.wait(function() this.form.method = 'get'; jQuery(this.form).append(''); }); + //cleanup darkmode session value + egw.setSessionItem('api', 'darkmode',''); }); }); diff --git a/pixelegg/less/darkmode.less b/pixelegg/less/darkmode.less index bbe1245c4c..050e92b0dd 100644 --- a/pixelegg/less/darkmode.less +++ b/pixelegg/less/darkmode.less @@ -25,7 +25,7 @@ filter: invert(1) hue-rotate(180deg) !important; } div.dhtmlxMenu_egw_SubLevelArea_Polygon,.egw_tooltip, - body .egw_message_wrapper,#egw_fw_header #egw_fw_topmenu,.ui-dialog, .box_shadow, + body .egw_message_wrapper,#egw_fw_header #egw_fw_topmenu,.ui-dialog, .box_shadow { box-shadow: 0px 0px 2px 2px #666666; -moz-box-shadow: 0px 0px 2px 2px #666666; diff --git a/preferences/inc/class.preferences_hooks.inc.php b/preferences/inc/class.preferences_hooks.inc.php index e343411953..1dbb4884d0 100644 --- a/preferences/inc/class.preferences_hooks.inc.php +++ b/preferences/inc/class.preferences_hooks.inc.php @@ -182,7 +182,7 @@ class preferences_hooks 'type' => 'select', 'label' => 'Dark mode theme', 'name' => 'darkmode', - 'values' => array('0' => 'off', '1' => 'on'), + 'values' => array('0' => 'off', '1' => 'on', '2'=> 'auto'), 'help' => 'Dark mode theme', 'admin' => False, 'default' => '0'