| import { useState, useEffect, useCallback } from 'react'; |
| import { eq } from 'drizzle-orm'; |
| import { useDatabase } from './useDatabase'; |
| import { currentUser, appState } from '../db/schema'; |
|
|
| |
|
|
| interface UseThemeModeReturn { |
| isDark: boolean; |
| toggleTheme: () => Promise<void>; |
| setDark: (isDark: boolean) => Promise<void>; |
| loading: boolean; |
| } |
|
|
| |
| |
| |
|
|
| const DARK_MODE_KEY = 'dark_mode'; |
|
|
| export function useThemeMode(): UseThemeModeReturn { |
| const { db } = useDatabase(); |
| const [isDark, setIsDark] = useState(false); |
| const [loading, setLoading] = useState(true); |
|
|
| |
|
|
| const loadTheme = useCallback(async () => { |
| try { |
| const rows = await db |
| .select() |
| .from(appState) |
| .where(eq(appState.key, DARK_MODE_KEY)) |
| .all(); |
|
|
| if (rows.length > 0) { |
| setIsDark(rows[0].value === 'true'); |
| } else { |
| |
| const userRows = await db.select().from(currentUser).limit(1).all(); |
| if (userRows.length > 0) { |
| const userData = userRows[0] as Record<string, unknown>; |
| if (typeof userData.darkMode === 'number') { |
| setIsDark(userData.darkMode === 1); |
| } else if (typeof userData.darkMode === 'boolean') { |
| setIsDark(userData.darkMode); |
| } |
| } |
| } |
| } catch (error) { |
| console.error('[useThemeMode] Failed to load theme preference:', error); |
| setIsDark(false); |
| } finally { |
| setLoading(false); |
| } |
| }, [db]); |
|
|
| useEffect(() => { |
| loadTheme(); |
| }, [loadTheme]); |
|
|
| |
|
|
| const toggleTheme = useCallback(async () => { |
| const newValue = !isDark; |
| await setDark(newValue); |
| }, [isDark]); |
|
|
| |
|
|
| const setDark = useCallback( |
| async (dark: boolean) => { |
| try { |
| setIsDark(dark); |
|
|
| |
| await db |
| .insert(appState) |
| .values({ key: DARK_MODE_KEY, value: String(dark) }) |
| .onConflictDoUpdate({ |
| target: appState.key, |
| set: { value: String(dark), updatedAt: new Date().toISOString() }, |
| }) |
| .run(); |
| } catch (error) { |
| console.error('[useThemeMode] Failed to save theme preference:', error); |
| } |
| }, |
| [db], |
| ); |
|
|
| return { |
| isDark, |
| toggleTheme, |
| setDark, |
| loading, |
| }; |
| } |
|
|