mobileapp / src /hooks /useThemeMode.ts
Antaram Dev Bot
feat: complete ANTARAM.ORG ride-sharing app frontend
5c876be
import { useState, useEffect, useCallback } from 'react';
import { eq } from 'drizzle-orm';
import { useDatabase } from './useDatabase';
import { currentUser, appState } from '../db/schema';
// ─── Types ─────────────────────────────────────────────────────────────────────
interface UseThemeModeReturn {
isDark: boolean;
toggleTheme: () => Promise<void>;
setDark: (isDark: boolean) => Promise<void>;
loading: boolean;
}
// ─── Hook ──────────────────────────────────────────────────────────────────────
// Reads the dark_mode preference. It first checks the app_state table (key:
// "dark_mode") and falls back to system default (false = light).
const DARK_MODE_KEY = 'dark_mode';
export function useThemeMode(): UseThemeModeReturn {
const { db } = useDatabase();
const [isDark, setIsDark] = useState(false);
const [loading, setLoading] = useState(true);
// ── Load theme preference ────────────────────────────────────────────────────
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 {
// Check current_user table for darkMode field
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]);
// ── Toggle theme ─────────────────────────────────────────────────────────────
const toggleTheme = useCallback(async () => {
const newValue = !isDark;
await setDark(newValue);
}, [isDark]);
// ── Set dark mode explicitly ─────────────────────────────────────────────────
const setDark = useCallback(
async (dark: boolean) => {
try {
setIsDark(dark);
// Upsert into app_state table
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,
};
}