mirror of
https://github.com/grocy/grocy.git
synced 2025-08-17 03:04:36 +00:00
Use prefers-color-scheme for night mode by default (closes #1334)
This commit is contained in:
@@ -95,6 +95,8 @@
|
|||||||
### General
|
### 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)
|
- 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
|
- Fixed an server error (on every page) when not having any quantity unit
|
||||||
|
|
||||||
### API
|
### API
|
||||||
|
@@ -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
|
// which are used when the user has not changed the setting so far
|
||||||
|
|
||||||
// Night mode related
|
// 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_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_from', '20:00'); // Format HH:mm
|
||||||
DefaultUserSetting('auto_night_mode_time_range_to', '07:00'); // Format HH:mm
|
DefaultUserSetting('auto_night_mode_time_range_to', '07:00'); // Format HH:mm
|
||||||
|
@@ -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)"
|
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 ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Night mode"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "On"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use system setting"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Off"
|
||||||
|
msgstr ""
|
||||||
|
2
migrations/0184.sql
Normal file
2
migrations/0184.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
DELETE FROM user_settings
|
||||||
|
WHERE key IN ('night_mode_enabled', 'currently_inside_night_mode_range');
|
@@ -436,9 +436,9 @@ Grocy.FrontendHelpers.ShowGenericError = function(message, exception)
|
|||||||
console.error(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;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -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");
|
Grocy.UserSettings.night_mode = $("input.user-setting-control:radio[name=night-mode]:checked").val();
|
||||||
if (value)
|
Grocy.FrontendHelpers.SaveUserSetting("night_mode", Grocy.UserSettings.night_mode, true);
|
||||||
{
|
CheckNightMode();
|
||||||
// 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");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#auto-night-mode-enabled").on("change", function()
|
$("#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-from").prop("readonly", !value);
|
||||||
$("#auto-night-mode-time-range-to").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");
|
$("body").removeClass("night-mode");
|
||||||
}
|
}
|
||||||
@@ -58,7 +49,7 @@ $("#auto-night-mode-time-range-goes-over-midgnight").on("change", function()
|
|||||||
|
|
||||||
if (Grocy.UserId !== -1)
|
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-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-time-range-goes-over-midgnight").prop("checked", BoolVal(Grocy.UserSettings.auto_night_mode_time_range_goes_over_midnight));
|
||||||
$("#auto-night-mode-enabled").trigger("change");
|
$("#auto-night-mode-enabled").trigger("change");
|
||||||
@@ -70,42 +61,66 @@ if (Grocy.UserId !== -1)
|
|||||||
|
|
||||||
function CheckNightMode()
|
function CheckNightMode()
|
||||||
{
|
{
|
||||||
if (Grocy.UserId === -1 || !BoolVal(Grocy.UserSettings.auto_night_mode_enabled))
|
if (Grocy.UserId === -1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var start = moment(Grocy.UserSettings.auto_night_mode_time_range_from, "HH:mm", true);
|
var nightModeEnabledInternalBefore = Grocy.UserSettings.night_mode_enabled_internal;
|
||||||
var end = moment(Grocy.UserSettings.auto_night_mode_time_range_to, "HH:mm", true);
|
|
||||||
var now = moment();
|
|
||||||
|
|
||||||
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))
|
if (!start.isValid() || !end.isValid)
|
||||||
{
|
|
||||||
end.add(1, "day");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now.isBetween(start, end)) // We're INSIDE of night mode time range
|
|
||||||
{
|
|
||||||
if (!$("body").hasClass("night-mode"))
|
|
||||||
{
|
{
|
||||||
$("body").addClass("night-mode");
|
return;
|
||||||
$("#currently-inside-night-mode-range").prop("checked", true);
|
}
|
||||||
$("#currently-inside-night-mode-range").trigger("change");
|
|
||||||
|
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");
|
Grocy.UserSettings.night_mode_enabled_internal = true;
|
||||||
$("#currently-inside-night-mode-range").prop("checked", false);
|
|
||||||
$("#currently-inside-night-mode-range").trigger("change");
|
|
||||||
}
|
}
|
||||||
|
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)
|
if (Grocy.UserId !== -1)
|
||||||
|
@@ -115,7 +115,14 @@
|
|||||||
</script>
|
</script>
|
||||||
</head>
|
</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))
|
@if(!($embedded))
|
||||||
<nav id="mainNav"
|
<nav id="mainNav"
|
||||||
class="navbar navbar-expand-lg navbar-light fixed-top">
|
class="navbar navbar-expand-lg navbar-light fixed-top">
|
||||||
@@ -528,16 +535,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item pt-0">
|
||||||
<div class="form-check">
|
<div>
|
||||||
<input class="form-check-input user-setting-control"
|
{{ $__t('Night mode') }}
|
||||||
type="checkbox"
|
</div>
|
||||||
id="night-mode-enabled"
|
<div class="custom-control custom-radio custom-control-inline">
|
||||||
data-setting-key="night_mode_enabled">
|
<input class="custom-control-input user-setting-control"
|
||||||
<label class="form-check-label"
|
type="radio"
|
||||||
for="night-mode-enabled">
|
name="night-mode"
|
||||||
{{ $__t('Enable night mode') }}
|
id="night-mode-on"
|
||||||
</label>
|
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>
|
</div>
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item">
|
||||||
@@ -575,10 +605,6 @@
|
|||||||
{{ $__t('Time range goes over midnight') }}
|
{{ $__t('Time range goes over midnight') }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</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>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item">
|
||||||
|
Reference in New Issue
Block a user