mirror of
https://github.com/ruvnet/RuView
synced 2026-08-07 20:01:43 +00:00
feat: Implement RSSI service for iOS and Web platforms
- Added IosRssiService to handle synthetic RSSI data for iOS. - Created WebRssiService to simulate RSSI scanning on the web. - Defined shared types for WifiNetwork and RssiService in rssi.service.ts. - Introduced simulation service to generate synthetic sensing data. - Implemented WebSocket service for real-time data handling with reconnection logic. - Established Zustand stores for managing application state related to MAT and pose data. - Developed theme context and utility functions for consistent styling and formatting. - Added type definitions for various application entities including API responses and sensing data. - Created utility functions for color mapping and URL validation. - Configured TypeScript settings for the mobile application.
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import React, { PropsWithChildren, useEffect, useState } from 'react';
|
||||
import { useColorScheme } from 'react-native';
|
||||
import { colors } from './colors';
|
||||
import { spacing } from './spacing';
|
||||
import { typography } from './typography';
|
||||
|
||||
export type ThemeMode = 'light' | 'dark' | 'system';
|
||||
|
||||
export type ThemeContextValue = {
|
||||
colors: typeof colors;
|
||||
typography: typeof typography;
|
||||
spacing: typeof spacing;
|
||||
isDark: boolean;
|
||||
};
|
||||
|
||||
const fallbackThemeValue: ThemeContextValue = {
|
||||
colors,
|
||||
typography,
|
||||
spacing,
|
||||
isDark: true,
|
||||
};
|
||||
|
||||
export const ThemeContext = React.createContext<ThemeContextValue>(fallbackThemeValue);
|
||||
|
||||
const isValidThemeMode = (value: unknown): value is ThemeMode => {
|
||||
return value === 'light' || value === 'dark' || value === 'system';
|
||||
};
|
||||
|
||||
const readThemeFromSettings = async (): Promise<ThemeMode> => {
|
||||
try {
|
||||
const settingsStore = (await import('../stores/settingsStore')) as Record<string, unknown>;
|
||||
const stateAccessors = [settingsStore.useSettingsStore, (settingsStore as { useStore?: unknown }).useStore].filter(
|
||||
(candidate): candidate is { getState: () => { theme?: unknown } } =>
|
||||
typeof candidate === 'function' &&
|
||||
typeof (candidate as { getState?: unknown }).getState === 'function',
|
||||
);
|
||||
|
||||
for (const accessor of stateAccessors) {
|
||||
const state = accessor.getState?.() as { theme?: unknown } | undefined;
|
||||
const candidateTheme = state?.theme;
|
||||
if (isValidThemeMode(candidateTheme)) {
|
||||
return candidateTheme;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// No-op if store is unavailable during bootstrap.
|
||||
}
|
||||
|
||||
return 'system';
|
||||
};
|
||||
|
||||
export const ThemeProvider = ({ children }: PropsWithChildren<object>) => {
|
||||
const [themeMode, setThemeMode] = useState<ThemeMode>('system');
|
||||
const systemScheme = useColorScheme() ?? 'light';
|
||||
|
||||
useEffect(() => {
|
||||
void readThemeFromSettings().then(setThemeMode);
|
||||
}, []);
|
||||
|
||||
const isDark = themeMode === 'dark' || (themeMode === 'system' && systemScheme === 'dark');
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider
|
||||
value={{
|
||||
colors,
|
||||
typography,
|
||||
spacing,
|
||||
isDark,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user