Browse Source

implement automatic night mode detection using MQL
add separate light.css to force light theme
remove manual night mode toggle and related code

Andrew Dolgov 2 months ago
parent
commit
0237dee980
9 changed files with 30 additions and 36 deletions
  1. 1 1
      include/controls.php
  2. 0 2
      include/functions.php
  3. 0 1
      index.php
  4. 25 24
      js/AppBase.js
  5. 0 2
      js/prefs.js
  6. 0 6
      js/tt-rss.js
  7. 2 0
      themes/light.css
  8. 1 0
      themes/light.css.map
  9. 1 0
      themes/light.less

+ 1 - 1
include/controls.php

@@ -238,7 +238,7 @@ function stylesheet_tag($filename, $id = false) {
 
 	$id_part = $id ? "id=\"$id\"" : "";
 
-	return "<link rel=\"stylesheet\" $id_part type=\"text/css\" href=\"$filename?$timestamp\"/>\n";
+	return "<link rel=\"stylesheet\" $id_part type=\"text/css\" data-orig-href=\"$filename\" href=\"$filename?$timestamp\"/>\n";
 }
 
 function javascript_tag($filename) {

+ 0 - 2
include/functions.php

@@ -1101,7 +1101,6 @@
 				"create_label" => __("Create label"),
 				"create_filter" => __("Create filter"),
 				"collapse_sidebar" => __("Un/collapse sidebar"),
-				"toggle_night_mode" => __("Toggle night mode"),
 				"help_dialog" => __("Show help dialog"))
 		);
 
@@ -1172,7 +1171,6 @@
 			"c l" => "create_label",
 			"c f" => "create_filter",
 			"c s" => "collapse_sidebar",
-			"a N" => "toggle_night_mode",
 			"?" => "help_dialog",
 		);
 

+ 0 - 1
index.php

@@ -234,7 +234,6 @@
                         <div dojoType="dijit.MenuItem" onclick="App.onActionSelected('qmcShowOnlyUnread')"><?php echo __('(Un)hide read feeds') ?></div>
                         <div dojoType="dijit.MenuItem" disabled="1"><?php echo __('Other actions:') ?></div>
                         <div dojoType="dijit.MenuItem" onclick="App.onActionSelected('qmcToggleWidescreen')"><?php echo __('Toggle widescreen mode') ?></div>
-                        <div dojoType="dijit.MenuItem" onclick="App.onActionSelected('qmcToggleNightMode')"><?php echo __('Toggle night mode') ?></div>
                         <div dojoType="dijit.MenuItem" onclick="App.onActionSelected('qmcHKhelp')"><?php echo __('Keyboard shortcuts help') ?></div>
 
                         <?php

+ 25 - 24
js/AppBase.js

@@ -9,6 +9,7 @@ define(["dojo/_base/declare"], function (declare) {
 		hotkey_prefix_timeout: 0,
 		constructor: function() {
 			window.onerror = this.Error.onWindowError;
+			this.setupNightModeDetection();
 		},
 		getInitParam: function(k) {
 			return this._initParams[k];
@@ -16,6 +17,30 @@ define(["dojo/_base/declare"], function (declare) {
 		setInitParam: function(k, v) {
 			this._initParams[k] = v;
 		},
+		nightModeChanged: function(is_night) {
+			console.log("night mode changed to", is_night);
+
+			const link = $("theme_css");
+
+			if (link) {
+
+				if (link.getAttribute("data-orig-href").indexOf("css/default.css") !== -1) {
+					const css_override = is_night ? "themes/night.css" : "css/default.css";
+					link.setAttribute("href", css_override + "?" + Date.now());
+				}
+			}
+		},
+		setupNightModeDetection: function() {
+			if (window.matchMedia) {
+				const mql = window.matchMedia('(prefers-color-scheme: dark)');
+
+				mql.addEventListener("change", () => {
+					this.nightModeChanged(mql.matches);
+				});
+
+				this.nightModeChanged(mql.matches);
+			}
+		},
 		enableCsrfSupport: function() {
 			Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
 				function (callOriginal, options) {
@@ -358,30 +383,6 @@ define(["dojo/_base/declare"], function (declare) {
 
 			this.initSecondStage();
 		},
-		toggleNightMode: function() {
-			const link = $("theme_css");
-
-			if (link) {
-
-				let user_theme = "";
-				let user_css = "";
-
-				if (link.getAttribute("href").indexOf("themes/night.css") == -1) {
-					user_css = "themes/night.css?" + Date.now();
-					user_theme = "night.css";
-				} else {
-					user_theme = "default.php";
-					user_css = "css/default.css?" + Date.now();
-				}
-
-				$("main").fade({duration: 0.5, afterFinish: () => {
-					link.setAttribute("href", user_css);
-					$("main").appear({duration: 0.5});
-					xhrPost("backend.php", {op: "rpc", method: "setpref", key: "USER_CSS_THEME", value: user_theme});
-				}});
-
-			}
-		},
 		explainError: function(code) {
 			return this.displayDlg(__("Error explained"), "explainError", code);
 		},

+ 0 - 2
js/prefs.js

@@ -142,8 +142,6 @@ require(["dojo/_base/kernel",
 							case "help_dialog":
 								App.helpDialog("main");
 								return false;
-							case "toggle_night_mode":
-								App.toggleNightMode();
 							default:
 								console.log("unhandled action: " + action_name + "; keycode: " + event.which);
 						}

+ 0 - 6
js/tt-rss.js

@@ -513,9 +513,6 @@ require(["dojo/_base/kernel",
 							Headlines.renderAgain();
 						});
 					};
-					this.hotkey_actions["toggle_night_mode"] = function () {
-						App.toggleNightMode();
-					};
 				},
 				onActionSelected: function(opid) {
 					switch (opid) {
@@ -581,9 +578,6 @@ require(["dojo/_base/kernel",
 								alert(__("Widescreen is not available in combined mode."));
 							}
 							break;
-						case "qmcToggleNightMode":
-							App.toggleNightMode();
-							break;
 						case "qmcHKhelp":
 							App.helpDialog("main");
 							break;

+ 2 - 0
themes/light.css

@@ -0,0 +1,2 @@
[email protected] "../css/default.css";
+/*# sourceMappingURL=light.css.map */

+ 1 - 0
themes/light.css.map

@@ -0,0 +1 @@
+{"version":3,"sources":["light.less"],"names":[],"mappings":"QAAQ","file":"light.css"}

+ 1 - 0
themes/light.less

@@ -0,0 +1 @@
[email protected] "../css/default.css";