Skip to content

Commit

Permalink
Prevent FOUT when using System Theme
Browse files Browse the repository at this point in the history
When system theme is selected, we apply the right theme in the client, because system settings can only be accessed from the client. That results in FOUT (flash of unstyled text) when navigating
between pages if the system theme is Light, because Pontoon defaults to the dark theme and then immediatelly changes it to light when the JS executed.

This patch prevents that by storing the system theme setting in a cookie. Cookie is read by the server, so we set the theme accordingly already in a template.

+    Storing system theme setting in a cookie makes the setting available to the server.
+    That allows us to set the theme class already in the Django template, which (unlike
+    setting it on the client) prevents FOUC.
  • Loading branch information
mathjazz committed Oct 26, 2023
1 parent a2d3d2e commit aca82c9
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 7 deletions.
19 changes: 16 additions & 3 deletions pontoon/base/static/js/theme-switcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,33 @@ $(function () {
.addClass(`${newTheme}-theme`);
}

/*
Storing system theme setting in a cookie makes the setting available to the server.
That allows us to set the theme class already in the Django template, which (unlike
setting it on the client) prevents FOUC.
*/
function storeSystemTheme(systemTheme) {
document.cookie = `system_theme=${systemTheme}; path=/; max-age=${
60 * 60 * 24 * 365
}; Secure`;
}

window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', function (e) {
// Check the 'data-theme' attribute on the body element
let userThemeSetting = $('body').data('theme');

if (userThemeSetting === 'system') {
applyTheme(e.matches ? 'dark' : 'light');
const systemTheme = e.matches ? 'dark' : 'light';
applyTheme(systemTheme);
storeSystemTheme(systemTheme);
}
});

if ($('body').hasClass('system-theme')) {
if ($('body').data('theme') === 'system') {
let systemTheme = getSystemTheme();
$('body').removeClass('system-theme').addClass(`${systemTheme}-theme`);
storeSystemTheme(systemTheme);
}

$('.appearance .toggle-button button').click(function (e) {
Expand Down
4 changes: 2 additions & 2 deletions pontoon/base/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
</head>

<body
class="{% block class %}{% endblock %} {{ theme(request.user) }}-theme"
class="{% block class %}{% endblock %} {{ theme_class(request) }}"
{% if csrf_token %}data-csrf="{{ csrf_token }}"{% endif %}
data-theme="{{ theme(request.user) }}"
data-theme="{{ user_theme(request.user) }}"
>
{% block content %}

Expand Down
17 changes: 16 additions & 1 deletion pontoon/base/templatetags/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,28 @@ def return_url(request):


@library.global_function
def theme(user):
def user_theme(user):
"""Get user's theme or return 'dark' if user is not authenticated."""
if user.is_authenticated:
return user.profile.theme
return "dark"


@library.global_function
def theme_class(request):
"""Get theme class name based on user preferences and system settings."""
theme = "dark"
user = request.user

if user.is_authenticated:
theme = user.profile.theme

if theme == "system":
theme = request.COOKIES.get("system_theme", "dark")

return f"{theme}-theme"


@library.global_function
def static(path):
return staticfiles_storage.url(path)
Expand Down
2 changes: 1 addition & 1 deletion translate/public/translate.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

{% include "tracker.html" %}
</head>
<body class="{% block class %}{% endblock %} {{ theme(request.user) }}-theme" data-theme="{{ theme(request.user) }}">
<body class="{% block class %}{% endblock %} {{ theme_class(request) }}" data-theme="{{ user_theme(request.user) }}">
<noscript>
You need to enable JavaScript to run this app.
</noscript>
Expand Down

0 comments on commit aca82c9

Please sign in to comment.