fix: theme persistence

save user theme preferences  in session instead of localStorage
This commit is contained in:
Sonny
2024-05-13 23:58:08 +02:00
committed by Sonny
parent f0e64c19fd
commit 243984ca66
7 changed files with 35 additions and 13 deletions

1
app/constants/session.ts Normal file
View File

@@ -0,0 +1 @@
export const PREFER_DARK_THEME = 'prefer_dark_theme';

View File

@@ -1,7 +1,17 @@
import { PREFER_DARK_THEME } from '#constants/session';
import { updateUserThemeValidator } from '#validators/user_theme';
import type { HttpContext } from '@adonisjs/core/http';
export default class AppsController {
index({ inertia }: HttpContext) {
return inertia.render('home');
}
async updateUserTheme({ request, session, response }: HttpContext) {
const { preferDarkTheme } = await request.validateUsing(
updateUserThemeValidator
);
session.put(PREFER_DARK_THEME, preferDarkTheme);
return response.ok('ok');
}
}

View File

@@ -0,0 +1,7 @@
import vine from '@vinejs/vine';
export const updateUserThemeValidator = vine.compile(
vine.object({
preferDarkTheme: vine.boolean(),
})
);

View File

@@ -1,3 +1,4 @@
import { PREFER_DARK_THEME } from '#constants/session';
import { defineConfig } from '@adonisjs/inertia';
export default defineConfig({
@@ -11,6 +12,7 @@ export default defineConfig({
*/
sharedData: {
errors: (ctx) => ctx.session?.flashMessages.get('errors'),
preferDarkTheme: (ctx) => ctx.session.get(PREFER_DARK_THEME, true),
auth: async (ctx) => {
await ctx.auth?.check();
return {

View File

@@ -66,7 +66,6 @@ export default function LinkControls({ link }: { link: Link }) {
.catch(console.error);
};
console.log(link.favorite, link.favorite ? 'oui' : 'non');
return (
<Dropdown
label={<BsThreeDotsVertical css={{ color: theme.colors.grey }} />}

View File

@@ -1,4 +1,6 @@
import { usePage } from '@inertiajs/react';
import { ReactNode, createContext, useEffect, useState } from 'react';
import { makeRequest } from '~/lib/request';
const LS_KEY = 'dark_theme';
@@ -12,18 +14,18 @@ export default function DarkThemeContextProvider({
}: {
children: ReactNode;
}) {
const [isDarkTheme, setDarkTheme] = useState<boolean>(() => {
if (typeof window === 'undefined' || typeof localStorage === 'undefined')
return true;
const doUserPreferDarkTheme = window?.matchMedia(
'(prefers-color-scheme: dark)'
).matches;
return (
localStorage.getItem(LS_KEY) === 'true' ?? doUserPreferDarkTheme ?? true
);
const { preferDarkTheme } = usePage<{ preferDarkTheme: boolean }>().props;
const [isDarkTheme, setDarkTheme] = useState<boolean>(preferDarkTheme);
const toggleDarkTheme = (value: boolean) => {
setDarkTheme(value);
makeRequest({
method: 'POST',
url: '/user/theme',
body: {
preferDarkTheme: value,
},
});
const toggleDarkTheme = (value: boolean) => setDarkTheme(value);
};
useEffect(() => {
localStorage.setItem(LS_KEY, String(isDarkTheme));

View File

@@ -10,6 +10,7 @@ const AppsController = () => import('#controllers/apps_controller');
const FaviconsController = () => import('#controllers/favicons_controller');
router.get(PATHS.HOME, [AppsController, 'index']);
router.post('/user/theme', [AppsController, 'updateUserTheme']);
router.get(PATHS.AUTH.LOGIN, [UsersController, 'login']);
router.get(PATHS.AUTH.GOOGLE, [UsersController, 'google']);
router.get('/auth/callback', [UsersController, 'callbackAuth']);