mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-08 14:43:24 +00:00
fix: theme persistence
save user theme preferences in session instead of localStorage
This commit is contained in:
1
app/constants/session.ts
Normal file
1
app/constants/session.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const PREFER_DARK_THEME = 'prefer_dark_theme';
|
||||||
@@ -1,7 +1,17 @@
|
|||||||
|
import { PREFER_DARK_THEME } from '#constants/session';
|
||||||
|
import { updateUserThemeValidator } from '#validators/user_theme';
|
||||||
import type { HttpContext } from '@adonisjs/core/http';
|
import type { HttpContext } from '@adonisjs/core/http';
|
||||||
|
|
||||||
export default class AppsController {
|
export default class AppsController {
|
||||||
index({ inertia }: HttpContext) {
|
index({ inertia }: HttpContext) {
|
||||||
return inertia.render('home');
|
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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
app/validators/user_theme.ts
Normal file
7
app/validators/user_theme.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import vine from '@vinejs/vine';
|
||||||
|
|
||||||
|
export const updateUserThemeValidator = vine.compile(
|
||||||
|
vine.object({
|
||||||
|
preferDarkTheme: vine.boolean(),
|
||||||
|
})
|
||||||
|
);
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { PREFER_DARK_THEME } from '#constants/session';
|
||||||
import { defineConfig } from '@adonisjs/inertia';
|
import { defineConfig } from '@adonisjs/inertia';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -11,6 +12,7 @@ export default defineConfig({
|
|||||||
*/
|
*/
|
||||||
sharedData: {
|
sharedData: {
|
||||||
errors: (ctx) => ctx.session?.flashMessages.get('errors'),
|
errors: (ctx) => ctx.session?.flashMessages.get('errors'),
|
||||||
|
preferDarkTheme: (ctx) => ctx.session.get(PREFER_DARK_THEME, true),
|
||||||
auth: async (ctx) => {
|
auth: async (ctx) => {
|
||||||
await ctx.auth?.check();
|
await ctx.auth?.check();
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ export default function LinkControls({ link }: { link: Link }) {
|
|||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(link.favorite, link.favorite ? 'oui' : 'non');
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
label={<BsThreeDotsVertical css={{ color: theme.colors.grey }} />}
|
label={<BsThreeDotsVertical css={{ color: theme.colors.grey }} />}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
import { usePage } from '@inertiajs/react';
|
||||||
import { ReactNode, createContext, useEffect, useState } from 'react';
|
import { ReactNode, createContext, useEffect, useState } from 'react';
|
||||||
|
import { makeRequest } from '~/lib/request';
|
||||||
|
|
||||||
const LS_KEY = 'dark_theme';
|
const LS_KEY = 'dark_theme';
|
||||||
|
|
||||||
@@ -12,18 +14,18 @@ export default function DarkThemeContextProvider({
|
|||||||
}: {
|
}: {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}) {
|
}) {
|
||||||
const [isDarkTheme, setDarkTheme] = useState<boolean>(() => {
|
const { preferDarkTheme } = usePage<{ preferDarkTheme: boolean }>().props;
|
||||||
if (typeof window === 'undefined' || typeof localStorage === 'undefined')
|
const [isDarkTheme, setDarkTheme] = useState<boolean>(preferDarkTheme);
|
||||||
return true;
|
const toggleDarkTheme = (value: boolean) => {
|
||||||
|
setDarkTheme(value);
|
||||||
const doUserPreferDarkTheme = window?.matchMedia(
|
makeRequest({
|
||||||
'(prefers-color-scheme: dark)'
|
method: 'POST',
|
||||||
).matches;
|
url: '/user/theme',
|
||||||
return (
|
body: {
|
||||||
localStorage.getItem(LS_KEY) === 'true' ?? doUserPreferDarkTheme ?? true
|
preferDarkTheme: value,
|
||||||
);
|
},
|
||||||
});
|
});
|
||||||
const toggleDarkTheme = (value: boolean) => setDarkTheme(value);
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
localStorage.setItem(LS_KEY, String(isDarkTheme));
|
localStorage.setItem(LS_KEY, String(isDarkTheme));
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const AppsController = () => import('#controllers/apps_controller');
|
|||||||
const FaviconsController = () => import('#controllers/favicons_controller');
|
const FaviconsController = () => import('#controllers/favicons_controller');
|
||||||
|
|
||||||
router.get(PATHS.HOME, [AppsController, 'index']);
|
router.get(PATHS.HOME, [AppsController, 'index']);
|
||||||
|
router.post('/user/theme', [AppsController, 'updateUserTheme']);
|
||||||
router.get(PATHS.AUTH.LOGIN, [UsersController, 'login']);
|
router.get(PATHS.AUTH.LOGIN, [UsersController, 'login']);
|
||||||
router.get(PATHS.AUTH.GOOGLE, [UsersController, 'google']);
|
router.get(PATHS.AUTH.GOOGLE, [UsersController, 'google']);
|
||||||
router.get('/auth/callback', [UsersController, 'callbackAuth']);
|
router.get('/auth/callback', [UsersController, 'callbackAuth']);
|
||||||
|
|||||||
Reference in New Issue
Block a user