feat: migrate icons to SF Symbols, refactor explore tab, add collections/programs data layer
- Replace all Ionicons with native SF Symbols via expo-symbols SymbolView - Create reusable Icon wrapper component (src/shared/components/Icon.tsx) - Remove @expo/vector-icons and lucide-react dependencies - Refactor explore tab with filters, search, and category browsing - Add collections and programs data with Supabase integration - Add explore filter store and filter sheet - Update i18n strings (en, de, es, fr) for new explore features - Update test mocks and remove stale snapshots - Add user fitness level to user store and types
This commit is contained in:
@@ -22,7 +22,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
import { LinearGradient } from 'expo-linear-gradient'
|
||||
import { BlurView } from 'expo-blur'
|
||||
import { useKeepAwake } from 'expo-keep-awake'
|
||||
import Ionicons from '@expo/vector-icons/Ionicons'
|
||||
import { Icon, type IconName } from '@/src/shared/components/Icon'
|
||||
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
@@ -187,7 +187,7 @@ function ControlButton({
|
||||
size = 64,
|
||||
variant = 'primary',
|
||||
}: {
|
||||
icon: keyof typeof Ionicons.glyphMap
|
||||
icon: IconName
|
||||
onPress: () => void
|
||||
size?: number
|
||||
variant?: 'primary' | 'secondary' | 'danger'
|
||||
@@ -228,7 +228,7 @@ function ControlButton({
|
||||
style={[timerStyles.controlButton, { width: size, height: size, borderRadius: size / 2 }]}
|
||||
>
|
||||
<View style={[timerStyles.controlButtonBg, { backgroundColor }]} />
|
||||
<Ionicons name={icon} size={size * 0.4} color={colors.text.primary} />
|
||||
<Icon name={icon} size={size * 0.4} tintColor={colors.text.primary} />
|
||||
</Pressable>
|
||||
</Animated.View>
|
||||
)
|
||||
@@ -423,10 +423,11 @@ export default function PlayerScreen() {
|
||||
}
|
||||
}, [timer.phase])
|
||||
|
||||
// Countdown beep for last 3 seconds
|
||||
// Countdown beep + haptic for last 3 seconds
|
||||
useEffect(() => {
|
||||
if (timer.isRunning && timer.timeRemaining <= 3 && timer.timeRemaining > 0) {
|
||||
audio.countdownBeep()
|
||||
haptics.countdownTick()
|
||||
}
|
||||
}, [timer.timeRemaining])
|
||||
|
||||
@@ -481,7 +482,7 @@ export default function PlayerScreen() {
|
||||
<View style={[styles.header, { paddingTop: insets.top + SPACING[4] }]}>
|
||||
<Pressable onPress={stopWorkout} style={styles.closeButton}>
|
||||
<BlurView intensity={colors.glass.blurLight} tint={colors.glass.blurTint} style={StyleSheet.absoluteFill} />
|
||||
<Ionicons name="close" size={24} color={colors.text.primary} />
|
||||
<Icon name="xmark" size={24} tintColor={colors.text.primary} />
|
||||
</Pressable>
|
||||
<View style={styles.headerCenter}>
|
||||
<Text style={styles.workoutTitle}>{workout?.title ?? 'Workout'}</Text>
|
||||
@@ -541,22 +542,22 @@ export default function PlayerScreen() {
|
||||
{showControls && !timer.isComplete && (
|
||||
<View style={[styles.controls, { paddingBottom: insets.bottom + SPACING[6] }]}>
|
||||
{!timer.isRunning ? (
|
||||
<ControlButton icon="play" onPress={startTimer} size={80} />
|
||||
<ControlButton icon="play.fill" onPress={startTimer} size={80} />
|
||||
) : (
|
||||
<View style={styles.controlsRow}>
|
||||
<ControlButton
|
||||
icon="stop"
|
||||
icon="stop.fill"
|
||||
onPress={stopWorkout}
|
||||
size={56}
|
||||
variant="danger"
|
||||
/>
|
||||
<ControlButton
|
||||
icon={timer.isPaused ? 'play' : 'pause'}
|
||||
icon={timer.isPaused ? 'play.fill' : 'pause.fill'}
|
||||
onPress={togglePause}
|
||||
size={80}
|
||||
/>
|
||||
<ControlButton
|
||||
icon="play-skip-forward"
|
||||
icon="forward.end.fill"
|
||||
onPress={handleSkip}
|
||||
size={56}
|
||||
variant="secondary"
|
||||
@@ -576,7 +577,7 @@ export default function PlayerScreen() {
|
||||
end={{ x: 1, y: 1 }}
|
||||
style={StyleSheet.absoluteFill}
|
||||
/>
|
||||
<Text style={styles.doneButtonText}>Done</Text>
|
||||
<Text style={styles.doneButtonText}>{t('common:done')}</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user