Skip to content

Commit b0fd7af

Browse files
committed
Implemented theme switcher, added session theme storing/loading from profile
1 parent ca73756 commit b0fd7af

8 files changed

Lines changed: 105 additions & 24 deletions

File tree

src/profiles/apps.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
from django.apps import AppConfig
44
from django.db.models.signals import post_save
55
from django.db.models.signals import pre_save
6+
from allauth.account.signals import user_logged_in
67

78
from .signal_handlers import create_profile
89
from .signal_handlers import profile_pre_save
10+
from .signal_handlers import set_session_on_login
911

1012
logger = logging.getLogger("bornhack.%s" % __name__)
1113

@@ -27,3 +29,8 @@ def ready(self):
2729
sender="profiles.Profile",
2830
dispatch_uid="profile_pre_save_signal",
2931
)
32+
user_logged_in.connect(
33+
set_session_on_login,
34+
sender=User,
35+
dispatch_uid="profile_set_session_on_login_signal",
36+
)

src/profiles/signal_handlers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,8 @@ def nickserv_username_changed(instance, original):
9393
# ok, mark this membership as in need of fixing
9494
membership.irc_acl_fix_needed = True
9595
membership.save()
96+
97+
98+
def set_session_on_login(sender, request, user, **kwargs):
99+
# Set theme from profile
100+
request.session["theme"] = request.user.profile.theme

src/profiles/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
from .views import ProfileDetail
55
from .views import ProfileUpdate
66
from .views import ProfilePermissionList
7+
from .views import ProfileSessionThemeSwitchView
78

89
app_name = "profiles"
910
urlpatterns = [
1011
path("", ProfileDetail.as_view(), name="detail"),
12+
path("theme/", ProfileSessionThemeSwitchView.as_view(), name="theme"),
1113
path("edit/", ProfileUpdate.as_view(), name="update"),
1214
path("api/", ProfileApiView.as_view(), name="api"),
1315
path("permissions/", ProfilePermissionList.as_view(), name="permissions_list"),

src/profiles/views.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
from django.contrib import messages
33
from django.contrib.auth.models import Permission
44
from django.contrib.auth.mixins import LoginRequiredMixin
5+
from django.http import HttpResponseForbidden
56
from django.urls import reverse_lazy
7+
from django.shortcuts import redirect
68
from django.views.generic import DetailView
79
from django.views.generic import ListView
810
from django.views.generic import UpdateView
11+
from django.views import View
912
from jsonview.views import JsonView
1013
from oauth2_provider.views.generic import ScopedProtectedResourceView
1114
from leaflet.forms.widgets import LeafletWidget
@@ -57,6 +60,8 @@ def form_valid(self, form, **kwargs):
5760
# user changed the name (to something non blank)
5861
form.instance.public_credit_name_approved = False
5962
form.instance.save()
63+
if "theme" in form.changed_data and form.cleaned_data["theme"]:
64+
self.request.session["theme"] = form.cleaned_data["theme"]
6065
messages.success(self.request, "Your profile has been updated.")
6166
return super().form_valid(form, **kwargs)
6267

@@ -102,3 +107,18 @@ def get_queryset(self, *args, **kwargs):
102107
)
103108
)
104109
return perms
110+
111+
112+
class ProfileSessionThemeSwitchView(View):
113+
"""
114+
View for setting the Session theme
115+
"""
116+
117+
def get(self, request, *args, **kwargs):
118+
theme = request.GET.get("theme") or "default"
119+
next_url = request.GET.get("next") or "/"
120+
if theme in dict(Profile.THEME_CHOICES) and next_url[:1] == "/":
121+
self.request.session["theme"] = theme
122+
return redirect(next_url)
123+
else:
124+
return HttpResponseForbidden()

src/static_src/css/bornhack.css

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,33 +39,42 @@ strong { font-weight: bold; }
3939
--bs-btn-border-width: unset !important;
4040
}
4141

42+
/* Hide elements if theme is active */
43+
/* Only used for data-bs-theme="light" and prefers-color-scheme: dark */
44+
/* For the other themes these should be defined in the theme css file */
45+
46+
body:not([data-bs-theme]) .bornhack-hide-light {
47+
display: none !important;
48+
}
49+
4250
[data-bs-theme="light"] .bornhack-logo {
4351
-webkit-filter: unset !important;
4452
filter: unset !important;
4553
}
4654

55+
[data-bs-theme="light"] .bornhack-hide-light {
56+
display: none !important;
57+
}
58+
4759
@media (prefers-color-scheme: dark) {
48-
.bornhack-logo {
60+
body:not([data-bs-theme]) .bornhack-logo {
4961
-webkit-filter: invert(1);
5062
filter: invert(1);
5163
}
52-
.sponsor-white {
64+
body:not([data-bs-theme]) .sponsor-white {
5365
background-color: white;
5466
color: black;
5567
border: 20px solid white;
5668
}
69+
body:not([data-bs-theme]) .bornhack-hide-dark {
70+
display: none !important;
71+
}
72+
/* Unset hide when light while being dark */
73+
body:not([data-bs-theme]) .bornhack-hide-light {
74+
display: unset !important;
75+
}
5776
}
58-
59-
[data-bs-theme="dark"] .bornhack-logo {
60-
-webkit-filter: invert(1);
61-
filter: invert(1);
62-
}
63-
64-
[data-bs-theme="dark"] .sponsor-white {
65-
background-color: white;
66-
color: black;
67-
border: 20px solid white;
68-
}
77+
/* end of theme based hiding */
6978

7079
.navbar-fixed-top {
7180
min-height: 70px;
@@ -354,46 +363,59 @@ img {
354363
padding-left: 10px;
355364
padding-right: 10px;
356365
}
357-
.bornhack-2016-gradient {
366+
.bornhack-2016-gradient, .bornhack-2027-gradient {
358367
height: 5px;
359368
background: linear-gradient(0.25turn, var(--bs-body-bg), #004dff, var(--bs-body-bg));
360369
}
361-
.bornhack-2017-gradient {
370+
.bornhack-2017-gradient, .bornhack-2028-gradient {
362371
height: 5px;
363372
background: linear-gradient(0.25turn, var(--bs-body-bg), #750787, var(--bs-body-bg));
364373
}
365-
.bornhack-2018-gradient {
374+
.bornhack-2018-gradient, .bornhack-2029-gradient {
366375
height: 5px;
367376
background: linear-gradient(0.25turn, var(--bs-body-bg), #008026, var(--bs-body-bg));
368377
}
369-
.bornhack-2019-gradient {
378+
.bornhack-2019-gradient, .bornhack-2030-gradient {
370379
height: 5px;
371380
background: linear-gradient(0.25turn, var(--bs-body-bg), #ffed00, var(--bs-body-bg));
372381
}
373-
.bornhack-2020-gradient {
382+
.bornhack-2020-gradient, .bornhack-2031-gradient {
374383
height: 5px;
375384
background: linear-gradient(0.25turn, var(--bs-body-bg), #ff8c00, var(--bs-body-bg));
376385
}
377-
.bornhack-2021-gradient {
386+
.bornhack-2021-gradient, .bornhack-2032-gradient {
378387
height: 5px;
379388
background: linear-gradient(0.25turn, var(--bs-body-bg), #e40303, var(--bs-body-bg));
380389
}
381-
.bornhack-2022-gradient {
390+
.bornhack-2022-gradient, .bornhack-2033-gradient {
382391
height: 5px;
383392
background: linear-gradient(0.25turn, var(--bs-body-bg), #000000, var(--bs-body-bg));
384393
}
385-
.bornhack-2023-gradient {
394+
.bornhack-2023-gradient, .bornhack-2034-gradient {
386395
height: 5px;
387396
background: linear-gradient(0.25turn, var(--bs-body-bg), #613915, var(--bs-body-bg));
388397
}
389-
.bornhack-2024-gradient {
398+
.bornhack-2024-gradient, .bornhack-2035-gradient {
390399
height: 5px;
391400
background: linear-gradient(0.25turn, var(--bs-body-bg), #73d7ee, var(--bs-body-bg));
392401
}
393-
.bornhack-2025-gradient {
402+
.bornhack-2025-gradient, .bornhack-2036-gradient {
394403
height: 5px;
395404
background: linear-gradient(0.25turn, var(--bs-body-bg), #ffafc7, var(--bs-body-bg));
396405
}
406+
.bornhack-2026-gradient, .bornhack-2037-gradient {
407+
height: 5px;
408+
background: linear-gradient(0.25turn, var(--bs-body-bg), #ffffff, var(--bs-body-bg));
409+
}
410+
/* Use a different starting and ending color on light theme */
411+
[data-bs-theme="light"] .bornhack-2026-gradient, [data-bs-theme="light"] .bornhack-2037-gradient {
412+
background: linear-gradient(0.25turn, var(--bs-gray-400), #ffffff, var(--bs-gray-400)) !important;
413+
}
414+
@media (prefers-color-scheme: light) {
415+
.bornhack-2026-gradient, .bornhack-2037-gradient {
416+
background: linear-gradient(0.25turn, var(--bs-gray-400), #ffffff, var(--bs-gray-400)) !important;
417+
}
418+
}
397419
.image-white-bg {
398420
background-color: white;
399421
color: black;

src/static_src/css/theme-slate.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,8 @@
6262
color: black;
6363
border: 20px solid white;
6464
}
65+
66+
.bornhack-hide-dark {
67+
display: none !important;
68+
}
6569
}

src/templates/base.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
{% endblock %}
6767
</head>
6868

69-
<body class="no-js" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' {% if user.is_authenticated and user.profile.theme != "default" %} data-bs-theme="{{user.profile.theme}}"{% endif %}>
69+
<body class="no-js" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' {% if request.session.theme and request.session.theme != "default" %} data-bs-theme="{{request.session.theme}}"{% endif %}>
7070
{% block body %}
7171
<header class="py-1">
7272
<nav class="navbar fixed-top navbar-expand-lg bg-body">
@@ -80,6 +80,11 @@
8080
<img src="{% static 'img/logo-small.png' %}" alt="bornhack" class="bornhack-logo img-responsive" width="200">
8181
</a>
8282
{% endif %}
83+
<!-- Theme switcher for small screens -->
84+
<div class="theme-switch d-lg-none col-1">
85+
{% include 'includes/theme-switch.html' %}
86+
</div>
87+
<!-- END: Theme switcher for small screens -->
8388
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#top-navbar" aria-expanded="false" aria-controls="navbar" aria-label="Toggle navigation">
8489
<span class="navbar-toggler-icon"></span>
8590
</button>
@@ -126,6 +131,11 @@
126131
{% endif %}
127132
</ul>
128133
<div class="nav navbar-nav navbar-right ms-auto d-none d-lg-flex">
134+
<!-- normal/big screen switcher -->
135+
<div class="theme-switch nav-link">
136+
{% include 'includes/theme-switch.html' %}
137+
</div>
138+
<!-- end of switcher -->
129139
{% if user.is_authenticated %}
130140
<li class="nav-item unhide-for-no-js-users"><a class="nav-link" href="{% url 'profiles:detail' %}">Profile</a></li>
131141
<li class="nav-item unhide-for-no-js-users"><a class="nav-link" href="{% url 'account_logout' %}">Logout</a></li>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<a href="{% url 'profiles:theme' %}?theme=slate&next={{ request.get_full_path|urlencode }}" title="Use dark mode" id="dark" class="btn btn-sm btn-default text-secondary bornhack-hide-dark">
2+
<i class="fa fa-moon"></i>
3+
</a>
4+
<a href="{% url 'profiles:theme' %}?theme=light&next={{ request.get_full_path|urlencode }}" title="Use light mode" id="light" class="btn btn-sm btn-default text-secondary bornhack-hide-light">
5+
<i class="fa fa-sun"></i>
6+
</a>
7+
{% if request.session.theme and request.session.theme != "default" %}
8+
<a href="{% url 'profiles:theme' %}?theme=default&next={{ request.get_full_path|urlencode }}" title="Use system preferred mode" id="system" class="btn btn-sm btn-default text-secondary">
9+
<i class="fa fa-display"></i>
10+
</a>
11+
{% endif %}

0 commit comments

Comments
 (0)