mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-18 08:29:40 +02:00
- Add uload project with apps/web structure
- Reorganize from flat to monorepo structure
- Remove PocketBase binary and local data
- Update to pnpm and @uload/web namespace
- Add picture project to monorepo
- Remove embedded git repository
- Unify all package names to @{project}/{app} schema:
- @maerchenzauber/* (was @storyteller/*)
- @manacore/* (was manacore-*, manacore)
- @manadeck/* (was web, backend, manadeck)
- @memoro/* (was memoro-web, landing, memoro)
- @picture/* (already unified)
- @uload/web
- Add convenient dev scripts for all apps:
- pnpm dev:{project}:web
- pnpm dev:{project}:landing
- pnpm dev:{project}:mobile
- pnpm dev:{project}:backend
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
135 lines
3.7 KiB
TypeScript
135 lines
3.7 KiB
TypeScript
import { create } from 'zustand';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import { useColorScheme } from 'react-native';
|
|
import { createNativeTheme, type NativeTheme, type ThemeVariant, type ColorMode } from '@picture/design-tokens/native';
|
|
|
|
// ThemeMode includes 'system' for automatic light/dark switching
|
|
type ThemeMode = ColorMode | 'system';
|
|
type Theme = NativeTheme;
|
|
|
|
const THEME_VARIANT_KEY = '@picture_app/theme_variant';
|
|
const THEME_MODE_KEY = '@picture_app/theme_mode';
|
|
|
|
interface ThemeStore {
|
|
// State
|
|
variant: ThemeVariant;
|
|
mode: ThemeMode;
|
|
currentTheme: Theme;
|
|
isLoading: boolean;
|
|
|
|
// Actions
|
|
setVariant: (variant: ThemeVariant) => Promise<void>;
|
|
setMode: (mode: ThemeMode) => Promise<void>;
|
|
toggleMode: () => void;
|
|
|
|
// Initialization
|
|
loadTheme: () => Promise<void>;
|
|
|
|
// Internal
|
|
_updateCurrentTheme: () => void;
|
|
}
|
|
|
|
export const useThemeStore = create<ThemeStore>((set, get) => ({
|
|
// Initial state - will be loaded from AsyncStorage
|
|
variant: 'default',
|
|
mode: 'system',
|
|
currentTheme: createNativeTheme('default', 'dark'), // Default fallback
|
|
isLoading: true,
|
|
|
|
// Set theme variant
|
|
setVariant: async (variant: ThemeVariant) => {
|
|
try {
|
|
await AsyncStorage.setItem(THEME_VARIANT_KEY, variant);
|
|
set({ variant });
|
|
get()._updateCurrentTheme();
|
|
} catch (error) {
|
|
console.error('Error saving theme variant:', error);
|
|
}
|
|
},
|
|
|
|
// Set theme mode
|
|
setMode: async (mode: ThemeMode) => {
|
|
try {
|
|
await AsyncStorage.setItem(THEME_MODE_KEY, mode);
|
|
set({ mode });
|
|
get()._updateCurrentTheme();
|
|
} catch (error) {
|
|
console.error('Error saving theme mode:', error);
|
|
}
|
|
},
|
|
|
|
// Toggle between light and dark (not system)
|
|
toggleMode: () => {
|
|
const currentMode = get().mode;
|
|
const newMode: ThemeMode = currentMode === 'dark' ? 'light' : 'dark';
|
|
get().setMode(newMode);
|
|
},
|
|
|
|
// Load theme from AsyncStorage
|
|
loadTheme: async () => {
|
|
try {
|
|
const [savedVariant, savedMode] = await Promise.all([
|
|
AsyncStorage.getItem(THEME_VARIANT_KEY),
|
|
AsyncStorage.getItem(THEME_MODE_KEY),
|
|
]);
|
|
|
|
const variant = (savedVariant as ThemeVariant) || 'default';
|
|
const mode = (savedMode as ThemeMode) || 'system';
|
|
|
|
set({ variant, mode, isLoading: false });
|
|
get()._updateCurrentTheme();
|
|
} catch (error) {
|
|
console.error('Error loading theme:', error);
|
|
set({ isLoading: false });
|
|
}
|
|
},
|
|
|
|
// Internal: Update current theme based on variant and mode
|
|
_updateCurrentTheme: () => {
|
|
const { variant, mode } = get();
|
|
|
|
// Resolve actual mode (light or dark) from mode setting
|
|
let resolvedMode: 'light' | 'dark' = 'dark';
|
|
|
|
if (mode === 'system') {
|
|
// This will be called from component that has access to useColorScheme
|
|
// For now, default to dark
|
|
resolvedMode = 'dark';
|
|
} else {
|
|
resolvedMode = mode;
|
|
}
|
|
|
|
const theme = createNativeTheme(variant, resolvedMode);
|
|
set({ currentTheme: theme });
|
|
},
|
|
}));
|
|
|
|
/**
|
|
* Hook to get theme with system color scheme support
|
|
*/
|
|
export const useTheme = () => {
|
|
const store = useThemeStore();
|
|
const systemColorScheme = useColorScheme();
|
|
|
|
// Determine actual mode
|
|
let actualMode: 'light' | 'dark' = 'dark';
|
|
if (store.mode === 'system') {
|
|
actualMode = systemColorScheme === 'dark' ? 'dark' : 'light';
|
|
} else {
|
|
actualMode = store.mode;
|
|
}
|
|
|
|
// Get the correct theme based on actual mode
|
|
const theme = createNativeTheme(store.variant, actualMode);
|
|
|
|
return {
|
|
theme,
|
|
variant: store.variant,
|
|
mode: store.mode,
|
|
actualMode,
|
|
isLoading: store.isLoading,
|
|
setVariant: store.setVariant,
|
|
setMode: store.setMode,
|
|
toggleMode: store.toggleMode,
|
|
};
|
|
};
|