From 0e62adf1cdd297c8271c83df5622a93f783a4f4e Mon Sep 17 00:00:00 2001 From: Ali Shair Date: Thu, 12 Feb 2026 14:45:22 +0500 Subject: [PATCH] feat: add theme switching and group client settings Add theme selector Dark/Light in settings page Group Mouse Sensitivity, Invert Scroll, and Theme under 'Client Settings' section Persist theme to localStorage (rein-theme) --- src/routes/__root.tsx | 16 +++++- src/routes/settings.tsx | 124 +++++++++++++++++++++++++--------------- 2 files changed, 93 insertions(+), 47 deletions(-) diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 686b73c..ab35248 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -1,6 +1,7 @@ import { Outlet, createRootRoute, Link, Scripts, HeadContent } from '@tanstack/react-router' // import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' -import * as React from 'react' +import { useEffect } from 'react' +import { APP_CONFIG, THEMES } from '../config' import '../styles.css' export const Route = createRootRoute({ @@ -24,6 +25,16 @@ function RootComponent() { ) } +function ThemeInit() { + useEffect(() => { + if (typeof localStorage === 'undefined') return; + const saved = localStorage.getItem(APP_CONFIG.THEME_STORAGE_KEY); + const theme = saved === THEMES.LIGHT || saved === THEMES.DARK ? saved : THEMES.DEFAULT; + document.documentElement.setAttribute('data-theme', theme); + }, []); + return null; +} + function RootDocument({ children }: { children: React.ReactNode }) { return ( @@ -34,7 +45,8 @@ function RootDocument({ children }: { children: React.ReactNode }) { Rein Remote - + +
diff --git a/src/routes/settings.tsx b/src/routes/settings.tsx index e755324..faaeb16 100644 --- a/src/routes/settings.tsx +++ b/src/routes/settings.tsx @@ -1,7 +1,7 @@ import { createFileRoute } from '@tanstack/react-router' import { useState, useEffect } from 'react' import QRCode from 'qrcode'; -import { CONFIG } from '../config'; +import { CONFIG, APP_CONFIG, THEMES } from '../config'; export const Route = createFileRoute('/settings')({ component: SettingsPage, @@ -29,6 +29,16 @@ function SettingsPage() { return Number.isFinite(parsed) ? parsed : 1.0; }); + const [theme, setTheme] = useState(() => { + if (typeof window === 'undefined') return THEMES.DEFAULT; + try { + const saved = localStorage.getItem(APP_CONFIG.THEME_STORAGE_KEY); + return saved === THEMES.LIGHT || saved === THEMES.DARK ? saved : THEMES.DEFAULT; + } catch { + return THEMES.DEFAULT; + } + }); + const [qrData, setQrData] = useState(''); // Load initial state @@ -49,6 +59,12 @@ function SettingsPage() { localStorage.setItem('rein_invert', JSON.stringify(invertScroll)); }, [invertScroll]); + useEffect(() => { + if (typeof window === 'undefined') return; + localStorage.setItem(APP_CONFIG.THEME_STORAGE_KEY, theme); + document.documentElement.setAttribute('data-theme', theme); + }, [theme]); + // Effect: Update LocalStorage and Generate QR useEffect(() => { if (!ip) return; @@ -123,50 +139,6 @@ function SettingsPage() {
-
- - - setSensitivity(parseFloat(e.target.value))} - className="range range-primary range-sm w-full" - /> - -
- Slow - Default - Fast -
-
- -
- -
- -
-