Use prefers-color-scheme for night mode by default (closes #1334)

This commit is contained in:
Bernd Bestel
2022-04-02 19:26:55 +02:00
parent 3e4f2eaf5d
commit 2042db29ee
7 changed files with 114 additions and 57 deletions

View File

@@ -95,6 +95,8 @@
### General
- Optimized form validation: Save / submit buttons are now not disabled when the form is invalid, the invalid / missing fields are instead highlighted when trying to submit / save the form (making it more obvious which fields are invalid / missing exactly)
- Night mode can now use / follow the system preferred color scheme
- The user setting `night_mode_enabled` has been removed and replaced by `night_mode` which now defaults to `follow-system` (which uses the system preferred color scheme)
- Fixed an server error (on every page) when not having any quantity unit
### API

View File

@@ -153,7 +153,7 @@ Setting('FEATURE_FLAG_AUTO_TORCH_ON_WITH_CAMERA', true); // Enables the torch au
// which are used when the user has not changed the setting so far
// Night mode related
DefaultUserSetting('night_mode_enabled', false); // If night mode is enabled always
DefaultUserSetting('night_mode', 'follow-system'); // "on" = Night mode is always on ; "off" = Night mode is always off / "follow-system" = System preferred color schema is used
DefaultUserSetting('auto_night_mode_enabled', false); // If night mode is enabled automatically when inside a given time range (see the two settings below)
DefaultUserSetting('auto_night_mode_time_range_from', '20:00'); // Format HH:mm
DefaultUserSetting('auto_night_mode_time_range_to', '07:00'); // Format HH:mm

View File

@@ -2338,3 +2338,15 @@ msgstr ""
msgid "The parent product %1$s is currently not in stock, %2$s is the current next sub product based on the default consume rule (Opened first, then first due first, then first in first out)"
msgstr ""
msgid "Night mode"
msgstr ""
msgid "On"
msgstr ""
msgid "Use system setting"
msgstr ""
msgid "Off"
msgstr ""

2
migrations/0184.sql Normal file
View File

@@ -0,0 +1,2 @@
DELETE FROM user_settings
WHERE key IN ('night_mode_enabled', 'currently_inside_night_mode_range');

View File

@@ -436,9 +436,9 @@ Grocy.FrontendHelpers.ShowGenericError = function(message, exception)
console.error(exception);
}
Grocy.FrontendHelpers.SaveUserSetting = function(settingsKey, value)
Grocy.FrontendHelpers.SaveUserSetting = function(settingsKey, value, force = false)
{
if (Grocy.UserSettings[settingsKey] == value)
if (Grocy.UserSettings[settingsKey] == value && !force)
{
return;
}

View File

@@ -1,18 +1,9 @@
$("#night-mode-enabled").on("change", function()

$("input.user-setting-control:radio[name=night-mode]").on("change", function()
{
var value = $(this).is(":checked");
if (value)
{
// Force disable auto night mode when night mode is enabled
$("#auto-night-mode-enabled").prop("checked", false);
$("#auto-night-mode-enabled").trigger("change");
$("body").addClass("night-mode");
}
else
{
$("body").removeClass("night-mode");
}
Grocy.UserSettings.night_mode = $("input.user-setting-control:radio[name=night-mode]:checked").val();
Grocy.FrontendHelpers.SaveUserSetting("night_mode", Grocy.UserSettings.night_mode, true);
CheckNightMode();
});
$("#auto-night-mode-enabled").on("change", function()
@@ -21,7 +12,7 @@ $("#auto-night-mode-enabled").on("change", function()
$("#auto-night-mode-time-range-from").prop("readonly", !value);
$("#auto-night-mode-time-range-to").prop("readonly", !value);
if (!value && !BoolVal(Grocy.UserSettings.night_mode_enabled))
if (!value && !BoolVal(Grocy.UserSettings.night_mode_enabled_internal))
{
$("body").removeClass("night-mode");
}
@@ -58,7 +49,7 @@ $("#auto-night-mode-time-range-goes-over-midgnight").on("change", function()
if (Grocy.UserId !== -1)
{
$("#night-mode-enabled").prop("checked", BoolVal(Grocy.UserSettings.night_mode_enabled));
$("input.user-setting-control:radio[name=night-mode][value=" + Grocy.UserSettings.night_mode + "]").prop("checked", true);
$("#auto-night-mode-enabled").prop("checked", BoolVal(Grocy.UserSettings.auto_night_mode_enabled));
$("#auto-night-mode-time-range-goes-over-midgnight").prop("checked", BoolVal(Grocy.UserSettings.auto_night_mode_time_range_goes_over_midnight));
$("#auto-night-mode-enabled").trigger("change");
@@ -70,42 +61,66 @@ if (Grocy.UserId !== -1)
function CheckNightMode()
{
if (Grocy.UserId === -1 || !BoolVal(Grocy.UserSettings.auto_night_mode_enabled))
if (Grocy.UserId === -1)
{
return;
}
var start = moment(Grocy.UserSettings.auto_night_mode_time_range_from, "HH:mm", true);
var end = moment(Grocy.UserSettings.auto_night_mode_time_range_to, "HH:mm", true);
var now = moment();
var nightModeEnabledInternalBefore = Grocy.UserSettings.night_mode_enabled_internal;
if (!start.isValid() || !end.isValid)
if (Grocy.UserSettings.night_mode != "follow-system" && BoolVal(Grocy.UserSettings.auto_night_mode_enabled))
{
return;
}
var start = moment(Grocy.UserSettings.auto_night_mode_time_range_from, "HH:mm", true);
var end = moment(Grocy.UserSettings.auto_night_mode_time_range_to, "HH:mm", true);
var now = moment();
if (BoolVal(Grocy.UserSettings.auto_night_mode_time_range_goes_over_midnight))
{
end.add(1, "day");
}
if (now.isBetween(start, end)) // We're INSIDE of night mode time range
{
if (!$("body").hasClass("night-mode"))
if (!start.isValid() || !end.isValid)
{
$("body").addClass("night-mode");
$("#currently-inside-night-mode-range").prop("checked", true);
$("#currently-inside-night-mode-range").trigger("change");
return;
}
if (BoolVal(Grocy.UserSettings.auto_night_mode_time_range_goes_over_midnight))
{
end.add(1, "day");
}
if (now.isBetween(start, end)) // We're INSIDE of night mode time range
{
Grocy.UserSettings.night_mode_enabled_internal = true;
}
else // We're OUTSIDE of night mode time range
{
Grocy.UserSettings.night_mode_enabled_internal = false;
}
}
else // We're OUTSIDE of night mode time range
else
{
if ($("body").hasClass("night-mode"))
if (Grocy.UserSettings.night_mode == "on")
{
$("body").removeClass("night-mode");
$("#currently-inside-night-mode-range").prop("checked", false);
$("#currently-inside-night-mode-range").trigger("change");
Grocy.UserSettings.night_mode_enabled_internal = true;
}
else if (Grocy.UserSettings.night_mode == "off")
{
Grocy.UserSettings.night_mode_enabled_internal = false;
}
else if (Grocy.UserSettings.night_mode == "follow-system")
{
Grocy.UserSettings.night_mode_enabled_internal = window.matchMedia("(prefers-color-scheme: dark)").matches;
}
}
if (BoolVal(nightModeEnabledInternalBefore) != BoolVal(Grocy.UserSettings.night_mode_enabled_internal))
{
Grocy.FrontendHelpers.SaveUserSetting("night_mode_enabled_internal", BoolVal(Grocy.UserSettings.night_mode_enabled_internal), true);
}
if (BoolVal(Grocy.UserSettings.night_mode_enabled_internal))
{
$("body").addClass("night-mode");
}
else
{
$("body").removeClass("night-mode");
}
}
if (Grocy.UserId !== -1)

View File

@@ -115,7 +115,14 @@
</script>
</head>
<body class="fixed-nav @if(boolval($userSettings['night_mode_enabled']) || (boolval($userSettings['auto_night_mode_enabled']) && boolval($userSettings['currently_inside_night_mode_range']))) night-mode @endif @if($embedded) embedded @endif">
@php
if (!isset($userSettings['night_mode_enabled_internal']))
{
$userSettings['night_mode_enabled_internal'] = false;
}
@endphp
<body class="fixed-nav @if(boolval($userSettings['night_mode_enabled_internal']) || (boolval($userSettings['auto_night_mode_enabled']) && boolval($userSettings['currently_inside_night_mode_range']))) night-mode @endif @if($embedded) embedded @endif">
@if(!($embedded))
<nav id="mainNav"
class="navbar navbar-expand-lg navbar-light fixed-top">
@@ -528,16 +535,39 @@
</div>
</div>
<div class="dropdown-divider"></div>
<div class="dropdown-item">
<div class="form-check">
<input class="form-check-input user-setting-control"
type="checkbox"
id="night-mode-enabled"
data-setting-key="night_mode_enabled">
<label class="form-check-label"
for="night-mode-enabled">
{{ $__t('Enable night mode') }}
</label>
<div class="dropdown-item pt-0">
<div>
{{ $__t('Night mode') }}
</div>
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input user-setting-control"
type="radio"
name="night-mode"
id="night-mode-on"
value="on"
data-setting-key="night_mode">
<label class="custom-control-label"
for="night-mode-on">{{ $__t('On') }}</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input user-setting-control"
type="radio"
name="night-mode"
id="night-mode-follow-system"
value="follow-system"
data-setting-key="night_mode">
<label class="custom-control-label"
for="night-mode-follow-system">{{ $__t('Use system setting') }}</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input class="custom-control-input user-setting-control"
type="radio"
name="night-mode"
id="night-mode-off"
value="off"
data-setting-key="night_mode">
<label class="custom-control-label"
for="night-mode-off">{{ $__t('Off') }}</label>
</div>
</div>
<div class="dropdown-item">
@@ -575,10 +605,6 @@
{{ $__t('Time range goes over midnight') }}
</label>
</div>
<input class="form-check-input d-none user-setting-control"
type="checkbox"
id="currently-inside-night-mode-range"
data-setting-key="currently_inside_night_mode_range">
</div>
<div class="dropdown-divider"></div>
<div class="dropdown-item">