feat: ThemeContext + Settings tabs (Interface / App / Sync)

- ThemeContext: dynamic palette (Default/Giro/Tour/Vuelta), font size
  (small/medium/large), bold labels — all persisted to AsyncStorage
- Settings: three top tabs; Interface tab has palette picker + font
  size pills + bold labels toggle; App tab has km notifications;
  Sync tab has bincio instance login + autarchive placeholder
- RecordingScreen: stat labels now use theme accent colour and scale
  with fontSize; font weight follows boldLabels setting
- All accent/accentDim usages migrated from static colors to useTheme()
This commit is contained in:
Davide Scaini
2026-06-03 10:00:27 +02:00
parent ea938e5644
commit efc7af4a4a
8 changed files with 366 additions and 197 deletions
+17 -15
View File
@@ -4,16 +4,17 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Text } from 'react-native';
import { RecordingScreen } from '../screens/RecordingScreen';
import { PostRecordingScreen } from '../screens/PostRecordingScreen';
import { SensorPairingScreen } from '../screens/SensorPairingScreen';
import { RecordingScreen } from '../screens/RecordingScreen';
import { PostRecordingScreen } from '../screens/PostRecordingScreen';
import { SensorPairingScreen } from '../screens/SensorPairingScreen';
import { SavedRecordingsScreen } from '../screens/SavedRecordingsScreen';
import { SettingsScreen } from '../screens/SettingsScreen';
import { SettingsScreen } from '../screens/SettingsScreen';
import { RootStackParamList, TabParamList } from '../types';
import { colors } from '../theme';
import { useTheme } from '../ThemeContext';
const Stack = createNativeStackNavigator<RootStackParamList>();
const Tab = createBottomTabNavigator<TabParamList>();
const Tab = createBottomTabNavigator<TabParamList>();
const TAB_ICONS: Record<string, string> = {
Recording: '◉',
@@ -22,13 +23,14 @@ const TAB_ICONS: Record<string, string> = {
};
function Tabs() {
const { accent } = useTheme();
return (
<Tab.Navigator
screenOptions={({ route }) => ({
headerStyle: { backgroundColor: colors.bg },
headerTintColor: colors.text,
tabBarStyle: { backgroundColor: colors.surface, borderTopColor: colors.border },
tabBarActiveTintColor: colors.accent,
headerStyle: { backgroundColor: colors.bg },
headerTintColor: colors.text,
tabBarStyle: { backgroundColor: colors.surface, borderTopColor: colors.border },
tabBarActiveTintColor: accent,
tabBarInactiveTintColor: colors.textMuted,
tabBarIcon: ({ color }) => (
<Text style={{ color, fontSize: 18 }}>{TAB_ICONS[route.name]}</Text>
@@ -36,8 +38,8 @@ function Tabs() {
})}
>
<Tab.Screen name="Recording" component={RecordingScreen} />
<Tab.Screen name="Saved" component={SavedRecordingsScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
<Tab.Screen name="Saved" component={SavedRecordingsScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
@@ -47,14 +49,14 @@ export function AppNavigator() {
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerStyle: { backgroundColor: colors.bg },
headerStyle: { backgroundColor: colors.bg },
headerTintColor: colors.text,
contentStyle: { backgroundColor: colors.bg },
contentStyle: { backgroundColor: colors.bg },
}}
>
<Stack.Screen name="Tabs" component={Tabs} options={{ headerShown: false }} />
<Stack.Screen name="Tabs" component={Tabs} options={{ headerShown: false }} />
<Stack.Screen name="PostRecording" component={PostRecordingScreen} options={{ title: 'Save Recording', presentation: 'modal' }} />
<Stack.Screen name="SensorPairing" component={SensorPairingScreen} options={{ title: 'Sensors', presentation: 'modal' }} />
<Stack.Screen name="SensorPairing" component={SensorPairingScreen} options={{ title: 'Sensors', presentation: 'modal' }} />
</Stack.Navigator>
</NavigationContainer>
);