}
@include color-mode(dark) {
- .leaflet-tile-container .leaflet-tile,
- .mapkey-table-entry td:first-child > * {
- filter: brightness(.8);
- }
-
.leaflet-container .leaflet-control-attribution a {
color: var(--bs-link-color);
}
}
}
+@mixin dark-map-color-scheme {
+ .leaflet-tile-container .leaflet-tile,
+ .mapkey-table-entry td:first-child > * {
+ filter: brightness(.8);
+ }
+}
+
+body[data-map-theme="dark"] {
+ @include dark-map-color-scheme;
+}
+
+@include color-mode(dark) {
+ body:not([data-map-theme]) {
+ @include dark-map-color-scheme;
+ }
+}
+
/* Rules for attribution text under the main map shown on printouts */
.donate-attr { color: darken($green, 10%) !important; }
$list-group-hover-bg: rgba(var(--bs-emphasis-color-rgb), .075);
$enable-negative-margins: true;
-$color-mode-type: media-query;
--- /dev/null
+@use "common" with (
+ $color-mode-type: media-query
+);
--- /dev/null
+@use "common" with (
+ $color-mode-type: media-query
+);
+++ /dev/null
-@import "common";
--- /dev/null
+@use "common" with (
+ $color-mode-type: data
+);
--- /dev/null
+@use "common" with (
+ $color-mode-type: data
+);
+++ /dev/null
-@import "common";
end
end
- helper_method :preferred_editor
+ def preferred_color_scheme(subject)
+ if current_user
+ current_user.preferences.find_by(:k => "#{subject}.color_scheme")&.v || "auto"
+ else
+ "auto"
+ end
+ end
+
+ helper_method :preferred_editor, :preferred_color_scheme
def update_totp
if Settings.key?(:totp_key)
else
params[:user][:preferred_editor]
end
- if current_user.save
+
+ success = current_user.save
+
+ if params[:site_color_scheme]
+ site_color_scheme_preference = current_user.preferences.find_or_create_by(:k => "site.color_scheme")
+ success &= site_color_scheme_preference.update(:v => params[:site_color_scheme])
+ end
+
+ if params[:map_color_scheme]
+ map_color_scheme_preference = current_user.preferences.find_or_create_by(:k => "map.color_scheme")
+ success &= map_color_scheme_preference.update(:v => params[:map_color_scheme])
+ end
+
+ if success
# Use a partial so that it is rendered during the next page load in the correct language.
flash[:notice] = { :partial => "preferences/update_success_flash" }
redirect_to preferences_path
<%= javascript_include_tag "turbo", :type => "module" %>
<%= javascript_include_tag "application" %>
<%= javascript_include_tag "i18n/#{I18n.locale}" %>
- <%= stylesheet_link_tag "screen-#{dir}", :media => "screen" %>
+ <% if preferred_color_scheme(:site) == "auto" %>
+ <%= stylesheet_link_tag "screen-auto-#{dir}", :media => "screen" %>
+ <% else %>
+ <%= stylesheet_link_tag "screen-manual-#{dir}", :media => "screen" %>
+ <% end %>
<%= stylesheet_link_tag "print-#{dir}", :media => "print" %>
<%= stylesheet_link_tag "leaflet-all", :media => "screen, print" %>
<%= render :partial => "layouts/meta" %>
<!DOCTYPE html>
-<html lang="<%= I18n.locale %>" dir="<%= dir %>">
+<%= tag.html :lang => I18n.locale,
+ :dir => dir,
+ :data => { :bs_theme => (preferred_color_scheme(:site) if preferred_color_scheme(:site) != "auto") } do %>
<%= render :partial => "layouts/head" %>
- <body class="<%= body_class %>">
+ <%= tag.body :class => body_class,
+ :data => { :map_theme => (preferred_color_scheme(:map) if preferred_color_scheme(:map) != "auto") } do %>
<%= render :partial => "layouts/header" %>
<%= render :partial => "layouts/content" %>
<% if defined?(Settings.matomo) -%>
<noscript><p><img src="<%= request.protocol %><%= Settings.matomo["location"] %>/matomo.php?idsite=<%= Settings.matomo["site"] %>" class="matomo" alt="" /></p></noscript>
<% end -%>
- </body>
-</html>
+ <% end %>
+<% end %>
<%= f.text_field :languages %>
+ <div class="mb-3">
+ <%= label_tag "site_color_scheme", t("preferences.show.preferred_site_color_scheme"), :class => "form-label" %>
+ <%= select_tag "site_color_scheme",
+ options_for_select(%w[auto light dark].map { |scheme| [t("preferences.show.site_color_schemes.#{scheme}"), scheme] },
+ preferred_color_scheme(:site)),
+ :class => "form-select" %>
+ </div>
+
+ <div class="mb-3">
+ <%= label_tag "map_color_scheme", t("preferences.show.preferred_map_color_scheme"), :class => "form-label" %>
+ <%= select_tag "map_color_scheme",
+ options_for_select(%w[auto light dark].map { |scheme| [t("preferences.show.map_color_schemes.#{scheme}"), scheme] },
+ preferred_color_scheme(:map)),
+ :class => "form-select" %>
+ </div>
+
<%= f.primary t(".save") %>
<%= link_to t(".cancel"), preferences_path, :class => "btn btn-link" %>
<% end %>
<li><%= locale %></li>
<% end %>
</ul>
+ </dd>
+ <dt class="col-sm-4"><%= t ".preferred_site_color_scheme" %></dt>
+ <dd class="col-sm-8">
+ <%= t ".site_color_schemes.#{preferred_color_scheme(:site)}" %>
+ </dd>
+
+ <dt class="col-sm-4"><%= t ".preferred_map_color_scheme" %></dt>
+ <dd class="col-sm-8">
+ <%= t ".map_color_schemes.#{preferred_color_scheme(:map)}" %>
</dd>
</dl>
title: My Preferences
preferred_editor: Preferred Editor
preferred_languages: Preferred Languages
+ preferred_site_color_scheme: Preferred Website Color Scheme
+ site_color_schemes:
+ auto: Auto
+ light: Light
+ dark: Dark
+ preferred_map_color_scheme: Preferred Map Color Scheme
+ map_color_schemes:
+ auto: Auto
+ light: Light
+ dark: Dark
edit_preferences: Edit Preferences
edit:
title: Edit Preferences
def test_update_preferred_editor
user = create(:user, :languages => [])
+ user.preferences.create(:k => "site.color_scheme", :v => "light")
+ user.preferences.create(:k => "map.color_scheme", :v => "light")
session_for(user)
# Changing to a invalid editor should fail
assert_select ".alert-success", false
assert_select ".alert-danger", true
assert_select "form > div > select#user_preferred_editor > option[selected]", false
+ assert_equal "light", user.preferences.find_by(:k => "site.color_scheme")&.v
+ assert_equal "light", user.preferences.find_by(:k => "map.color_scheme")&.v
# Changing to a valid editor should work
user.preferred_editor = "id"
assert_template :show
assert_select ".alert-success", /^Preferences updated/
assert_select "dd", "iD (in-browser editor)"
+ assert_equal "light", user.preferences.find_by(:k => "site.color_scheme")&.v
+ assert_equal "light", user.preferences.find_by(:k => "map.color_scheme")&.v
# Changing to the default editor should work
user.preferred_editor = "default"
assert_template :show
assert_select ".alert-success", /^Preferences updated/
assert_select "dd", "Default (currently iD)"
+ assert_equal "light", user.preferences.find_by(:k => "site.color_scheme")&.v
+ assert_equal "light", user.preferences.find_by(:k => "map.color_scheme")&.v
+ end
+
+ def test_update_preferred_site_color_scheme
+ user = create(:user, :languages => [])
+ session_for(user)
+ assert_nil user.preferences.find_by(:k => "site.color_scheme")
+
+ # Changing when previously not defined
+ put preferences_path, :params => { :user => user.attributes, :site_color_scheme => "light" }
+ assert_redirected_to preferences_path
+ follow_redirect!
+ assert_template :show
+ assert_select ".alert-success", /^Preferences updated/
+ assert_equal "light", user.preferences.find_by(:k => "site.color_scheme")&.v
+
+ # Changing when previously defined
+ put preferences_path, :params => { :user => user.attributes, :site_color_scheme => "auto" }
+ assert_redirected_to preferences_path
+ follow_redirect!
+ assert_template :show
+ assert_select ".alert-success", /^Preferences updated/
+ assert_equal "auto", user.preferences.find_by(:k => "site.color_scheme")&.v
+ end
+
+ def test_update_preferred_map_color_scheme
+ user = create(:user, :languages => [])
+ session_for(user)
+ assert_nil user.preferences.find_by(:k => "map.color_scheme")
+
+ # Changing when previously not defined
+ put preferences_path, :params => { :user => user.attributes, :map_color_scheme => "light" }
+ assert_redirected_to preferences_path
+ follow_redirect!
+ assert_template :show
+ assert_select ".alert-success", /^Preferences updated/
+ assert_equal "light", user.preferences.find_by(:k => "map.color_scheme")&.v
+
+ # Changing when previously defined
+ put preferences_path, :params => { :user => user.attributes, :map_color_scheme => "auto" }
+ assert_redirected_to preferences_path
+ follow_redirect!
+ assert_template :show
+ assert_select ".alert-success", /^Preferences updated/
+ assert_equal "auto", user.preferences.find_by(:k => "map.color_scheme")&.v
end
end