Skip to content

Commit 2223431

Browse files
committed
Update AbstractController. Add theme switcher to login.
1 parent 84fbc9c commit 2223431

44 files changed

Lines changed: 306 additions & 311 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

public/css/sidebar.css

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
padding: 0.5rem 1rem 0.75rem;
1616
transition: margin-left var(--sidebar-delay) ease-in-out;
1717
overflow: hidden auto;
18-
flex-flow: column nowrap !important;
19-
text-align: left !important;
18+
flex-flow: column nowrap;
19+
text-align: left;
2020
justify-content: initial;
2121
display: flex;
2222
align-items: flex-start;
@@ -39,7 +39,7 @@ body.sidebar-show .navbar-horizontal {
3939
/* menus */
4040
.navbar-vertical .navbar-nav {
4141
list-style: none;
42-
flex-direction: column !important;
42+
flex-direction: column;
4343
margin-bottom: 0;
4444
}
4545

@@ -53,7 +53,7 @@ body.sidebar-show .navbar-horizontal {
5353
.navbar-vertical .dropdown-divider {
5454
margin-top: 0.25rem;
5555
margin-bottom: 0.25rem;
56-
border-top: 1px solid var(--bs-border-color-translucent) !important;
56+
border-top: 1px solid var(--bs-border-color-translucent);
5757
}
5858

5959
.navbar-vertical ul ul {
@@ -129,17 +129,19 @@ html[data-bs-theme=dark] .navbar-vertical::-webkit-scrollbar-thumb {
129129
inline-size: 100%;
130130
color: var(--bs-navbar-color);
131131
white-space: normal;
132-
padding: var(--bs-navbar-toggler-padding-y) 0;
132+
padding-left: 0.25rem;
133+
padding-right: 0.25rem;
133134
text-align: start;
134135
width: 100%;
135136
}
136137

137138
.navbar-vertical ul:not(.dropdown-menu-default) .dropdown-item:active {
138-
color: var(--bs-dropdown-link-active-color) !important;
139+
color: var(--bs-dropdown-link-active-color);
140+
background-color: var(--bs-dropdown-link-active-bg);
139141
}
140142

141143
.navbar-vertical ul:not(.dropdown-menu-default) .dropdown-item:hover {
142-
color: var(--bs-navbar-hover-color) !important;
144+
color: var(--bs-navbar-hover-color);
143145
}
144146

145147
/**
@@ -149,7 +151,6 @@ html[data-bs-theme=dark] .navbar-vertical::-webkit-scrollbar-thumb {
149151
.hide-sidebar {
150152
padding: 0 0.15rem;
151153
border-radius: 50%;
152-
153154
}
154155

155156
.show-sidebar {
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/* globals Toaster, THEME */
2+
3+
/**
4+
* Gets a value indicating if start view transition is supported.
5+
* @return {boolean} true if supported.
6+
*/
7+
function supportTransition() {
8+
'use strict';
9+
return document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
10+
}
11+
12+
/**
13+
* Gets the preferred theme.
14+
* @return {string} the preferred theme.
15+
*/
16+
function getPreferredTheme() {
17+
'use strict';
18+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? THEME.DARK : THEME.LIGHT;
19+
}
20+
21+
/**
22+
* Handle theme input change.
23+
*/
24+
function initThemeInput() {
25+
'use strict';
26+
$('.dropdown-theme-entry').on('click', function (e) {
27+
e.preventDefault();
28+
// get values
29+
const $this = $(this);
30+
const path = document.body.dataset.cookiePath || '/';
31+
const oldTheme = window.Cookie.getValue(THEME.KEY, THEME.AUTO);
32+
let theme = $this.data('value');
33+
34+
// update cookie
35+
if (!theme || theme === THEME.AUTO) {
36+
theme = getPreferredTheme();
37+
window.Cookie.clearValue(THEME.KEY, path);
38+
} else {
39+
window.Cookie.setValue(THEME.KEY, theme, path);
40+
}
41+
42+
// same theme?
43+
if (oldTheme === theme) {
44+
return;
45+
}
46+
47+
// apply theme
48+
const callback = () => {
49+
document.documentElement.setAttribute(THEME.ATTRIBUTE, theme);
50+
};
51+
if (supportTransition()) {
52+
document.startViewTransition(callback);
53+
} else {
54+
callback();
55+
}
56+
57+
// update checked theme and icon
58+
$('.dropdown-theme-entry').removeClass('dropdown-item-checked-right');
59+
$('.btn-theme-dropdown i').attr('class', $this.data('icon'));
60+
$this.addClass('dropdown-item-checked-right');
61+
62+
// update other theme switchers
63+
$('.theme-switcher:not(.dropdown-theme-dialog) .theme-text')
64+
.text($this.text())
65+
$('.theme-switcher:not(.dropdown-theme-dialog) .theme-icon')
66+
.attr('class', $this.data('icon'));
67+
68+
// show success message
69+
const title = $('.btn-theme-dropdown').data('title');
70+
const message = $this.data('success');
71+
Toaster.success(message, title);
72+
});
73+
}
74+
75+
/**
76+
* Handle theme changed event.
77+
*/
78+
function initThemeChanged() {
79+
'use strict';
80+
$('body').on(THEME.EVENT, '.theme-switcher', function (e, theme) {
81+
$('.dropdown-theme-entry').each(function () {
82+
const $this = $(this);
83+
if ($this.data('value') === theme) {
84+
$this.addClass('dropdown-item-checked-right');
85+
$('.btn-theme-dropdown i').attr('class', $this.data('icon'));
86+
} else {
87+
$this.removeClass('dropdown-item-checked-right');
88+
}
89+
})
90+
});
91+
}
92+
93+
function initThemeButtons() {
94+
'use strict';
95+
initThemeInput();
96+
initThemeChanged();
97+
}

public/js/application/user_login.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,7 @@ $(function () {
2323
}
2424
}
2525
});
26+
27+
// theme
28+
initThemeButtons();
2629
});

public/js/application/user_request.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ $(function () {
88
const $captcha = $('#captcha').initCaptcha();
99

1010
// initialize validator
11-
const $form = $("#edit-form");
11+
const $form = $('#edit-form');
1212
const url = $form.data('check-user');
1313
const options = {
1414
showModification: false,
1515
rules: {
1616
'user': {
17-
remote: {
17+
remote: {
1818
url: url,
1919
data: {
2020
user: function () {
@@ -36,4 +36,7 @@ $(function () {
3636
}
3737
};
3838
$form.initValidator(options);
39+
40+
// theme
41+
initThemeButtons();
3942
});

public/js/compiled/user_login.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
* Specific Files
1313
*/
1414
<!--#include file="../application/user_recaptcha.js" -->
15+
<!--#include file="../application/button_themes.js" -->
1516
<!--#include file="../application/user_login.js" -->

public/js/compiled/user_request.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
* Specific Files
1313
*/
1414
<!--#include file="../application/user_recaptcha.js" -->
15+
<!--#include file="../application/button_themes.js" -->
1516
<!--#include file="../application/user_request.js" -->

public/js/extensions/validator-extensions.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@
263263
/**
264264
* Find elements with the same name attribute.
265265
*
266-
* @param {jQuery<Element>} $element the element to search same name for.
266+
* @param {jQuery<Element>} $element the element to search the same name for.
267267
* @return {jQuery[]|jQuery<Element>} the elements, if found; the argument element otherwise.
268268
*/
269269
$.validator.prototype.findNamedElements = function ($element) {
@@ -375,7 +375,6 @@
375375
const $that = $(this);
376376
const toFind = 'input,select,textarea';
377377
const selector = ':visible:enabled:not([readonly]):first';
378-
379378
// find the first invalid field
380379
$that.find('.invalid-feedback').each(function () {
381380
const $group = $(this).closest('.form-group');
@@ -388,8 +387,7 @@
388387
}
389388
return !found;
390389
});
391-
392-
// set focus to first editable field
390+
// set focus on the first editable field
393391
if (!found) {
394392
/** @type {jQuery<HTMLInputElement>} */
395393
let $input = $that.find(toFind).filter(selector);

public/js/plugins/plugin-theme.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,14 @@ $(function () {
3838
*/
3939
constructor(element, options) {
4040
this.$element = $(element);
41-
this.options = $.extend(true, {}, ThemeListener.DEFAULTS, $(element).data(), options);
41+
this.options = $.extend(true, {}, ThemeListener.DEFAULTS, this.$element.data(), options);
4242
this._init();
4343
}
4444

4545
/**
4646
* Remove handlers and data.
4747
*/
4848
destroy() {
49-
//
5049
this.$element.removeData(ThemeListener.NAME);
5150
this.$element.off('click', this.clickProxy);
5251
window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', this.changeProxy);

public/js/test/notification.js

Lines changed: 2 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* globals Toaster, THEME */
1+
/* globals Toaster */
22

33
/**
44
* Display a notification.
@@ -38,69 +38,6 @@ function random() {
3838
$(button).trigger('click');
3939
}
4040

41-
/**
42-
* Gets a value indicating if start view transition is supported.
43-
* @return {boolean} true if supported.
44-
*/
45-
function supportTransition() {
46-
'use strict';
47-
return document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
48-
}
49-
50-
/**
51-
* Gets the preferred theme.
52-
* @return {string} the preferred theme.
53-
*/
54-
function getPreferredTheme() {
55-
'use strict';
56-
return window.matchMedia('(prefers-color-scheme: dark)').matches ? THEME.DARK : THEME.LIGHT;
57-
}
58-
59-
/**
60-
* Handle theme input change.
61-
*/
62-
function initThemeInput() {
63-
'use strict';
64-
$('input[name=radio-theme]').on('change', function () {
65-
const path = document.body.dataset.cookiePath || '/';
66-
const oldTheme = window.Cookie.getValue(THEME.KEY, THEME.AUTO);
67-
const $selection = $('input[name=radio-theme]:checked');
68-
let theme = $selection.val();
69-
if (theme === THEME.AUTO) {
70-
theme = getPreferredTheme();
71-
window.Cookie.clearValue(THEME.KEY, path);
72-
} else {
73-
window.Cookie.setValue(THEME.KEY, theme, path);
74-
}
75-
if (oldTheme !== theme) {
76-
const callback = () => {
77-
document.documentElement.setAttribute(THEME.ATTRIBUTE, theme);
78-
};
79-
if (supportTransition()) {
80-
document.startViewTransition(callback);
81-
} else {
82-
callback();
83-
}
84-
}
85-
const title = $('button.rounded-end-pill').data('title');
86-
const message = $selection.data('success');
87-
Toaster.success(message, title);
88-
});
89-
}
90-
91-
/**
92-
* Handle theme changed event.
93-
*/
94-
function initThemeChanged() {
95-
'use strict';
96-
$('body').on(THEME.EVENT, '.theme-switcher', function (e, theme) {
97-
$('input[name=radio-theme]').each(function () {
98-
const $this = $(this);
99-
$this.setChecked($this.val() === theme);
100-
});
101-
});
102-
}
103-
10441
/**
10542
* Document ready function
10643
*/
@@ -175,6 +112,5 @@ $(function () {
175112
random();
176113

177114
// theme
178-
initThemeInput();
179-
initThemeChanged();
115+
initThemeButtons();
180116
});

src/Controller/AbstractController.php

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -180,25 +180,6 @@ public function getUserParameters(): UserParameters
180180
}
181181
}
182182

183-
/**
184-
* Display a flash message, if defined, and redirect to the home page.
185-
*/
186-
public function redirectToHomePage(
187-
?Request $request = null,
188-
TranslatableFlashMessage|string|null $message = null
189-
): RedirectResponse {
190-
if (\is_string($message)) {
191-
$this->addFlashMessage(FlashType::DEFAULT, $this->trans($message));
192-
} elseif ($message instanceof TranslatableFlashMessage) {
193-
$this->addFlashMessage($message->getType(), $this->trans($message));
194-
}
195-
if ($request instanceof Request) {
196-
return $this->getUrlGenerator()->redirect($request);
197-
}
198-
199-
return $this->redirectToRoute(static::HOME_PAGE);
200-
}
201-
202183
/**
203184
* Creates and returns a form helper instance.
204185
*
@@ -269,4 +250,25 @@ protected function handleRequestForm(Request $request, FormInterface $form): boo
269250

270251
return $form->isSubmitted() && $form->isValid();
271252
}
253+
254+
/**
255+
* Display a flash message, if defined, and redirect to the home page.
256+
*
257+
* This function tries first to get the current request, and if it is not null, redirects using
258+
* the URL generator. Otherwise, it redirects to the home page.
259+
*/
260+
protected function redirectToHomePage(TranslatableFlashMessage|string|null $message = null): RedirectResponse
261+
{
262+
if (\is_string($message)) {
263+
$this->addFlashMessage(FlashType::DEFAULT, $this->trans($message));
264+
} elseif ($message instanceof TranslatableFlashMessage) {
265+
$this->addFlashMessage($message->getType(), $this->trans($message));
266+
}
267+
$request = $this->getRequestStack()->getCurrentRequest();
268+
if ($request instanceof Request) {
269+
return $this->getUrlGenerator()->redirect($request);
270+
}
271+
272+
return $this->redirectToRoute(static::HOME_PAGE);
273+
}
272274
}

0 commit comments

Comments
 (0)