BTHLABS-60: Appearance settings

Co-authored-by: Tomek Wójcik <labs@tomekwojcik.pl>
Co-committed-by: Tomek Wójcik <labs@tomekwojcik.pl>
This commit is contained in:
Tomek Wójcik 2025-10-07 04:42:58 +00:00 committed by Tomek Wójcik
parent b4d5375954
commit 2e8b8d7330
11 changed files with 102 additions and 9 deletions

View File

@ -68,4 +68,10 @@ class Account(AbstractUser):
else:
result['auto_load_embeds'] = auto_load_embeds
light_mode = result.get('light_mode', None)
if isinstance(light_mode, str) is True:
result['light_mode'] = (light_mode == 'True')
else:
result['light_mode'] = light_mode
return result

View File

@ -46,3 +46,33 @@ def version(request: HttpRequest) -> dict:
return {
'VERSION': backend_version,
}
def appearance_settings(request: HttpRequest) -> dict:
theme = 'hotpocket'
result = {
'theme': theme,
'light_mode': False,
'theme_css': 'ui/css/bootstrap-hotpocket.min.css',
}
if request.user.is_anonymous is False:
theme = request.user.settings.get('theme', 'hotpocket')
result.update({
'theme': theme,
'light_mode': request.user.settings['light_mode'],
})
match theme:
case 'bootstrap':
result['theme_css'] = 'ui/css/bootstrap.min.css'
case 'cosmo':
result['theme_css'] = 'ui/css/cosmo.min.css'
case 'solar':
result['theme_css'] = 'ui/css/solar.min.css'
return {
'APPEARANCE_SETTINGS': result,
}

View File

@ -143,13 +143,18 @@ class SettingsForm(Form):
theme = forms.ChoiceField(
label=_('Theme'),
disabled=True,
disabled=False,
required=False,
choices=[
(None, _('Bootstrap')),
(None, _('BTHLabs')),
('bootstrap', _('Bootstrap')),
('cosmo', _('Cosmo')),
('solar', _('Solar')),
],
show_hidden_initial=True,
)
light_mode = forms.BooleanField(
label=_('Use light mode'),
required=False,
)
auto_load_embeds = forms.ChoiceField(
label=_('Auto load embedded content'),
@ -168,6 +173,7 @@ class SettingsForm(Form):
def get_layout_fields(self) -> list[str]:
return [
'theme',
'light_mode',
'auto_load_embeds',
]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,14 +10,18 @@
|_|
production
-->
<html lang="en" data-bs-theme="dark">
<html lang="en" data-bs-theme="{% if APPEARANCE_SETTINGS.light_mode %}light{% else %}dark{% endif %}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover,user-scalable=no">
<meta name="generator" content="pl.bthlabs.HotPocket.backend@{{ IMAGE_ID }}">
{% if APPEARANCE_SETTINGS.light_mode %}
<meta name="theme-color" content="#f8f9fa" />
{% else %}
<meta name="theme-color" content="#2b3035" />
{% endif %}
<title>{% block title %}{% translate 'Not Found' %}{% endblock %} | {{ SITE_TITLE }}</title>
<link href="{% static 'ui/css/bootstrap.min.css' %}" rel="stylesheet">
<link href="{% static APPEARANCE_SETTINGS.theme_css %}" rel="stylesheet">
<link href="{% static 'ui/css/bootstrap-icons.min.css' %}" rel="stylesheet">
<link href="{% static 'ui/css/hotpocket-backend.css' %}" rel="stylesheet">
<meta name="apple-mobile-web-app-capable" content="yes">

View File

@ -9,6 +9,10 @@ from hotpocket_backend.apps.core.conf import settings
def manifest_json(request: HttpRequest) -> JsonResponse:
light_theme = False
if request.user.is_anonymous is False:
light_theme = request.user.settings.get('light_theme', None) or False
result = {
'name': settings.SITE_TITLE,
'short_name': settings.SITE_SHORT_TITLE,
@ -16,8 +20,17 @@ def manifest_json(request: HttpRequest) -> JsonResponse:
reverse('ui.associations.browse'),
),
'display': 'standalone',
'background_color': '#212529',
'theme_color': '#2b3035',
'background_color': (
'#212529'
if light_theme is False
else '#ffffff'
),
'theme_color': (
'#2b3035'
if light_theme is False
else
'#f8f9fa'
),
'icons': [
{
'src': request.build_absolute_uri(

View File

@ -67,6 +67,7 @@ TEMPLATES = [
'hotpocket_backend.apps.ui.context_processors.htmx',
'hotpocket_backend.apps.ui.context_processors.debug',
'hotpocket_backend.apps.ui.context_processors.version',
'hotpocket_backend.apps.ui.context_processors.appearance_settings',
],
},
},

View File

@ -16,6 +16,7 @@ from hotpocket_backend_testing.services.accounts import AccountsTestingService
def payload():
return {
'theme': 'cosmo',
'light_mode': True,
'auto_load_embeds': 'True',
}
@ -41,7 +42,8 @@ def test_ok(authenticated_client: Client,
AccountsTestingService().assert_settings_edited(
pk=account.pk,
update={
'theme': None, # TODO: Themes!
'theme': 'cosmo',
'light_mode': True,
'auto_load_embeds': True,
},
reference=account,