chore: remove v1 features and old scaffolding
Remove onboarding flow (6 screens), timer engine, audio engine, old components (themed-text/view, parallax-scroll, hello-wave), old constants (theme, shadows, timer), and utility files that were replaced by the v2 architecture. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,112 +0,0 @@
|
||||
import { Image } from 'expo-image';
|
||||
import { Platform, StyleSheet } from 'react-native';
|
||||
|
||||
import { Collapsible } from '@/components/ui/collapsible';
|
||||
import { ExternalLink } from '@/components/external-link';
|
||||
import ParallaxScrollView from '@/components/parallax-scroll-view';
|
||||
import { ThemedText } from '@/components/themed-text';
|
||||
import { ThemedView } from '@/components/themed-view';
|
||||
import { IconSymbol } from '@/components/ui/icon-symbol';
|
||||
import { Fonts } from '@/constants/theme';
|
||||
|
||||
export default function TabTwoScreen() {
|
||||
return (
|
||||
<ParallaxScrollView
|
||||
headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }}
|
||||
headerImage={
|
||||
<IconSymbol
|
||||
size={310}
|
||||
color="#808080"
|
||||
name="chevron.left.forwardslash.chevron.right"
|
||||
style={styles.headerImage}
|
||||
/>
|
||||
}>
|
||||
<ThemedView style={styles.titleContainer}>
|
||||
<ThemedText
|
||||
type="title"
|
||||
style={{
|
||||
fontFamily: Fonts.rounded,
|
||||
}}>
|
||||
Explore
|
||||
</ThemedText>
|
||||
</ThemedView>
|
||||
<ThemedText>This app includes example code to help you get started.</ThemedText>
|
||||
<Collapsible title="File-based routing">
|
||||
<ThemedText>
|
||||
This app has two screens:{' '}
|
||||
<ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '}
|
||||
<ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
|
||||
</ThemedText>
|
||||
<ThemedText>
|
||||
The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '}
|
||||
sets up the tab navigator.
|
||||
</ThemedText>
|
||||
<ExternalLink href="https://docs.expo.dev/router/introduction">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Android, iOS, and web support">
|
||||
<ThemedText>
|
||||
You can open this project on Android, iOS, and the web. To open the web version, press{' '}
|
||||
<ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project.
|
||||
</ThemedText>
|
||||
</Collapsible>
|
||||
<Collapsible title="Images">
|
||||
<ThemedText>
|
||||
For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
|
||||
<ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for
|
||||
different screen densities
|
||||
</ThemedText>
|
||||
<Image
|
||||
source={require('@/assets/images/react-logo.png')}
|
||||
style={{ width: 100, height: 100, alignSelf: 'center' }}
|
||||
/>
|
||||
<ExternalLink href="https://reactnative.dev/docs/images">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Light and dark mode components">
|
||||
<ThemedText>
|
||||
This template has light and dark mode support. The{' '}
|
||||
<ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect
|
||||
what the user's current color scheme is, and so you can adjust UI colors accordingly.
|
||||
</ThemedText>
|
||||
<ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Animations">
|
||||
<ThemedText>
|
||||
This template includes an example of an animated component. The{' '}
|
||||
<ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses
|
||||
the powerful{' '}
|
||||
<ThemedText type="defaultSemiBold" style={{ fontFamily: Fonts.mono }}>
|
||||
react-native-reanimated
|
||||
</ThemedText>{' '}
|
||||
library to create a waving hand animation.
|
||||
</ThemedText>
|
||||
{Platform.select({
|
||||
ios: (
|
||||
<ThemedText>
|
||||
The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '}
|
||||
component provides a parallax effect for the header image.
|
||||
</ThemedText>
|
||||
),
|
||||
})}
|
||||
</Collapsible>
|
||||
</ParallaxScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
headerImage: {
|
||||
color: '#808080',
|
||||
bottom: -90,
|
||||
left: -35,
|
||||
position: 'absolute',
|
||||
},
|
||||
titleContainer: {
|
||||
flexDirection: 'row',
|
||||
gap: 8,
|
||||
},
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
import { Link } from 'expo-router';
|
||||
import { StyleSheet } from 'react-native';
|
||||
|
||||
import { ThemedText } from '@/components/themed-text';
|
||||
import { ThemedView } from '@/components/themed-view';
|
||||
|
||||
export default function ModalScreen() {
|
||||
return (
|
||||
<ThemedView style={styles.container}>
|
||||
<ThemedText type="title">This is a modal</ThemedText>
|
||||
<Link href="/" dismissTo style={styles.link}>
|
||||
<ThemedText type="link">Go to home screen</ThemedText>
|
||||
</Link>
|
||||
</ThemedView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: 20,
|
||||
},
|
||||
link: {
|
||||
marginTop: 15,
|
||||
paddingVertical: 15,
|
||||
},
|
||||
});
|
||||
@@ -1,49 +0,0 @@
|
||||
import { useRouter, Redirect } from 'expo-router'
|
||||
import { Screen1Problem } from '@/src/features/onboarding/screens/Screen1Problem'
|
||||
import { Screen2Empathy } from '@/src/features/onboarding/screens/Screen2Empathy'
|
||||
import { Screen3Solution } from '@/src/features/onboarding/screens/Screen3Solution'
|
||||
import { Screen4WowMoment } from '@/src/features/onboarding/screens/Screen4WowMoment'
|
||||
import { Screen5Personalization } from '@/src/features/onboarding/screens/Screen5Personalization'
|
||||
import { Screen6Paywall } from '@/src/features/onboarding/screens/Screen6Paywall'
|
||||
import { useOnboarding } from '@/src/features/onboarding/hooks/useOnboarding'
|
||||
|
||||
export default function OnboardingRouter() {
|
||||
const router = useRouter()
|
||||
const currentStep = useOnboarding((state) => state.currentStep)
|
||||
const isOnboardingComplete = useOnboarding((state) => state.isOnboardingComplete)
|
||||
const nextStep = useOnboarding((state) => state.nextStep)
|
||||
const completeOnboarding = useOnboarding((state) => state.completeOnboarding)
|
||||
|
||||
const handleNext = () => {
|
||||
nextStep()
|
||||
}
|
||||
|
||||
const handleComplete = () => {
|
||||
completeOnboarding()
|
||||
router.replace('/(tabs)')
|
||||
}
|
||||
|
||||
// Redirect to tabs if onboarding is already complete
|
||||
if (isOnboardingComplete) {
|
||||
return <Redirect href="/(tabs)" />
|
||||
}
|
||||
|
||||
// Render the correct screen based on current step
|
||||
switch (currentStep) {
|
||||
case 0:
|
||||
return <Screen1Problem onNext={handleNext} />
|
||||
case 1:
|
||||
return <Screen2Empathy onNext={handleNext} />
|
||||
case 2:
|
||||
return <Screen3Solution onNext={handleNext} />
|
||||
case 3:
|
||||
return <Screen4WowMoment />
|
||||
case 4:
|
||||
return <Screen5Personalization onNext={handleNext} />
|
||||
case 5:
|
||||
return <Screen6Paywall onComplete={handleComplete} />
|
||||
default:
|
||||
// Fallback to first screen if step is out of bounds
|
||||
return <Screen1Problem onNext={handleNext} />
|
||||
}
|
||||
}
|
||||
105
app/timer.tsx
105
app/timer.tsx
@@ -1,105 +0,0 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useRouter } from 'expo-router'
|
||||
import * as Haptics from 'expo-haptics'
|
||||
import { useTimerEngine } from '@/src/features/timer'
|
||||
import { useAudioEngine } from '@/src/features/audio'
|
||||
import { TimerDisplay } from '@/src/features/timer/components/TimerDisplay'
|
||||
import type { TimerEvent } from '@/src/features/timer/types'
|
||||
|
||||
export default function TimerScreen() {
|
||||
const router = useRouter()
|
||||
const timer = useTimerEngine()
|
||||
const audio = useAudioEngine()
|
||||
|
||||
// Preload audio on mount
|
||||
useEffect(() => {
|
||||
audio.preloadAll()
|
||||
return () => {
|
||||
audio.unloadAll()
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Subscribe to timer events → trigger audio + haptics
|
||||
useEffect(() => {
|
||||
const unsubscribe = timer.addEventListener(async (event: TimerEvent) => {
|
||||
switch (event.type) {
|
||||
case 'PHASE_CHANGED':
|
||||
await handlePhaseChange(event.to)
|
||||
break
|
||||
|
||||
case 'COUNTDOWN_TICK':
|
||||
await audio.playPhaseSound(
|
||||
event.secondsLeft === 1 ? 'count_1' : event.secondsLeft === 2 ? 'count_2' : 'count_3'
|
||||
)
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light)
|
||||
break
|
||||
|
||||
case 'ROUND_COMPLETED':
|
||||
await audio.playPhaseSound('bell')
|
||||
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success)
|
||||
break
|
||||
|
||||
case 'SESSION_COMPLETE':
|
||||
await audio.playPhaseSound('fanfare')
|
||||
await audio.stopMusic(1000)
|
||||
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success)
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
return unsubscribe
|
||||
}, [audio.isLoaded])
|
||||
|
||||
async function handlePhaseChange(to: string) {
|
||||
switch (to) {
|
||||
case 'GET_READY':
|
||||
await audio.startMusic('LOW')
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium)
|
||||
break
|
||||
case 'WORK':
|
||||
await audio.playPhaseSound('beep_long')
|
||||
await audio.switchIntensity('HIGH')
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy)
|
||||
break
|
||||
case 'REST':
|
||||
await audio.playPhaseSound('beep_double')
|
||||
await audio.switchIntensity('LOW')
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function handleStart() {
|
||||
timer.start()
|
||||
}
|
||||
|
||||
function handleStop() {
|
||||
timer.stop()
|
||||
audio.stopMusic(300)
|
||||
router.back()
|
||||
}
|
||||
|
||||
return (
|
||||
<TimerDisplay
|
||||
state={{
|
||||
phase: timer.phase,
|
||||
secondsLeft: timer.secondsLeft,
|
||||
currentRound: timer.currentRound,
|
||||
totalRounds: timer.totalRounds,
|
||||
currentCycle: timer.currentCycle,
|
||||
totalCycles: timer.totalCycles,
|
||||
isRunning: timer.isRunning,
|
||||
isPaused: timer.isPaused,
|
||||
totalElapsedSeconds: timer.totalElapsedSeconds,
|
||||
}}
|
||||
config={timer.config}
|
||||
exerciseName="Burpees"
|
||||
nextExerciseName="Squats"
|
||||
onStart={handleStart}
|
||||
onPause={timer.pause}
|
||||
onResume={timer.resume}
|
||||
onStop={handleStop}
|
||||
onSkip={timer.skip}
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user