Skip to content

Commit 018bf04

Browse files
authored
Develop (#82)
* Feature/fasting times (#79) * CICD update to broader v tags * feat: cross-platform Lottie fireworks animation and improved date/time picker for fasting * Feature/fasting history (#81) * CICD update to broader v tags * feat: cross-platform Lottie fireworks animation and improved date/time picker for fasting * fasting history added, navigation icon changes * fasting history added, navigation icon changes * fasting history added, navigation icon changes
1 parent 499d3a6 commit 018bf04

File tree

9 files changed

+1542
-3450
lines changed

9 files changed

+1542
-3450
lines changed

.github/workflows/CICD-Full.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
cache: 'npm'
2525

2626
- name: Install dependencies
27-
run: npm ci
27+
run: npm ci --legacy-peer-deps
2828

2929
- name: ESLint
3030
run: npx eslint . --ext .js,.jsx,.ts,.tsx

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"java.configuration.updateBuildConfiguration": "automatic"
3+
}

package-lock.json

Lines changed: 1122 additions & 3398 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,45 @@
1313
"build:web": "expo export --platform web",
1414
"build:android:dev": "eas build --platform android --profile development --non-interactive --no-wait",
1515
"build:android:staging": "eas build --platform android --profile preview --non-interactive --no-wait",
16-
"build:android:prod": "eas build --platform android --profile production --non-interactive"
16+
"build:android:prod": "eas build --platform android --profile production --non-interactive",
17+
"postinstall": "echo 'Postinstall completed' || true"
1718
},
1819
"dependencies": {
19-
"@expo/metro-runtime": "~4.0.1",
20+
"@expo/metro-runtime": "~5.0.4",
2021
"@lottiefiles/dotlottie-react": "^0.6.5",
21-
"@react-native-async-storage/async-storage": "1.23.1",
22-
"@react-native-community/datetimepicker": "8.2.0",
22+
"@react-native-async-storage/async-storage": "2.1.2",
23+
"@react-native-community/datetimepicker": "8.3.0",
2324
"@react-native-firebase/app": "^21.13.0",
2425
"@react-native-firebase/auth": "^21.13.0",
25-
"@react-native-google-signin/google-signin": "^13.2.0",
26+
"@react-native-google-signin/google-signin": "^13.3.1",
2627
"@react-navigation/bottom-tabs": "^7.3.10",
2728
"@react-navigation/native": "^7.1.5",
2829
"@react-navigation/native-stack": "^7.3.10",
2930
"@react-navigation/stack": "^7.2.9",
30-
"expo": "~52.0.42",
31-
"expo-auth-session": "^6.0.3",
32-
"expo-dev-client": "~5.0.19",
33-
"expo-linear-gradient": "^14.0.2",
34-
"expo-status-bar": "~2.0.1",
35-
"expo-updates": "~0.27.4",
36-
"expo-web-browser": "^14.0.2",
31+
"apexcharts": "^4.7.0",
32+
"expo": "^53.0.9",
33+
"expo-auth-session": "~6.1.5",
34+
"expo-dev-client": "~5.1.8",
35+
"expo-linear-gradient": "~14.1.4",
36+
"expo-status-bar": "~2.2.3",
37+
"expo-updates": "~0.28.12",
38+
"expo-web-browser": "~14.1.6",
3739
"firebase": "^11.6.0",
38-
"lottie-react-native": "7.1.0",
40+
"lottie-react-native": "7.2.2",
3941
"moment": "^2.30.1",
4042
"number-flow": "^0.5.7",
41-
"react": "18.3.1",
43+
"react": "19.0.0",
44+
"react-apexcharts": "^1.7.0",
4245
"react-datetime": "^3.3.1",
43-
"react-dom": "18.3.1",
44-
"react-native": "0.76.9",
45-
"react-native-gesture-handler": "~2.20.2",
46-
"react-native-reanimated": "~3.16.1",
47-
"react-native-safe-area-context": "4.12.0",
48-
"react-native-screens": "~4.4.0",
46+
"react-dom": "19.0.0",
47+
"react-native": "0.79.2",
48+
"react-native-gesture-handler": "~2.24.0",
49+
"react-native-reanimated": "~3.17.4",
50+
"react-native-safe-area-context": "5.4.0",
51+
"react-native-screens": "~4.10.0",
4952
"react-native-shared-element": "^0.8.9",
50-
"react-native-svg": "15.8.0",
51-
"react-native-web": "~0.19.13",
53+
"react-native-svg": "15.11.2",
54+
"react-native-web": "^0.20.0",
5255
"react-navigation-shared-element": "^3.1.3",
5356
"react-svg": "^16.3.0"
5457
},
@@ -72,5 +75,10 @@
7275
"typescript": "^5.3.3",
7376
"typescript-eslint": "^8.29.0"
7477
},
75-
"private": true
78+
"private": true,
79+
"overrides": {
80+
"@lottiefiles/dotlottie-react": {
81+
"react": "$react"
82+
}
83+
}
7684
}

src/context/FastContext.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ interface FastState {
2121
targetDuration: number | null;
2222
}
2323

24-
interface CompletedFast {
25-
id?: string;
24+
export interface CompletedFast {
25+
id: string;
2626
startTime: Timestamp;
2727
endTime: Timestamp;
2828
duration: number;
@@ -105,7 +105,7 @@ export const FastProvider = ({ children }: { children: React.ReactNode }) => {
105105
history.push({ id: docSnap.id, ...docSnap.data() } as CompletedFast);
106106
});
107107

108-
setFastHistory(history.toReversed());
108+
setFastHistory(history.slice().reverse());
109109
setLoading(false);
110110
}, () => {
111111

@@ -161,12 +161,12 @@ export const FastProvider = ({ children }: { children: React.ReactNode }) => {
161161
const endTime = customEndTime ? Timestamp.fromMillis(customEndTime) : Timestamp.now();
162162
const duration = endTime.toMillis() - fastState.startTime.toMillis();
163163

164-
const completedFast: CompletedFast = {
164+
const completedFast = {
165165
startTime: fastState.startTime,
166166
endTime: endTime,
167167
duration: duration,
168-
targetDuration: fastState.targetDuration,
169-
};
168+
targetDuration: fastState.targetDuration,
169+
} as Omit<CompletedFast, 'id'>;
170170

171171
try {
172172
const historyCollectionRef = collection(db, USERS_COLLECTION, userId, HISTORY_SUBCOLLECTION);

src/navigation/MainTabNavigator.tsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
22
import { RouteProp } from '@react-navigation/native';
33
import React from 'react';
4+
import { useWindowDimensions } from 'react-native';
45

56
import AccountIcon from '../../assets/icons/account.svg';
67
import ChartIcon from '../../assets/icons/chart.svg';
@@ -11,7 +12,6 @@ import HomeScreen from '../screens/HomeScreen';
1112
import ProfileScreen from '../screens/ProfileScreen';
1213
import StatisticsScreen from '../screens/StatisticsScreen';
1314

14-
1515
type TabParamList = {
1616
Home: undefined;
1717
Goals: undefined;
@@ -25,9 +25,9 @@ interface TabBarIconProps {
2525
color: string;
2626
size: number;
2727
routeName: keyof TabParamList;
28-
focused: boolean;
2928
}
3029

30+
3131
function TabBarIcon({ color, size, routeName }: Readonly<TabBarIconProps>) {
3232
switch (routeName) {
3333
case 'Home':
@@ -43,16 +43,26 @@ function TabBarIcon({ color, size, routeName }: Readonly<TabBarIconProps>) {
4343
}
4444
}
4545

46-
const screenOptions = ({ route }: { route: RouteProp<TabParamList, keyof TabParamList> }) => ({
47-
tabBarIcon: ({ focused, color, size }: { focused: boolean; color: string; size: number }) => (
48-
<TabBarIcon focused={focused} color={color} size={size} routeName={route.name} />
49-
),
50-
tabBarActiveTintColor: '#0a7ea4',
51-
tabBarInactiveTintColor: 'gray',
52-
headerShown: false,
53-
});
46+
47+
const renderTabBarIcon = (route: RouteProp<TabParamList, keyof TabParamList>, focused: boolean, color: string, size: number) => {
48+
49+
return <TabBarIcon color={color} size={size} routeName={route.name} />;
50+
};
5451

5552
export default function MainTabNavigator() {
53+
const { width } = useWindowDimensions();
54+
const isMobile = width < 768;
55+
56+
57+
const screenOptions = ({ route }: { route: RouteProp<TabParamList, keyof TabParamList> }) => ({
58+
tabBarIcon: ({ focused, color, size }: { focused: boolean; color: string; size: number }) =>
59+
renderTabBarIcon(route, focused, color, size),
60+
tabBarActiveTintColor: '#0a7ea4',
61+
tabBarInactiveTintColor: 'gray',
62+
headerShown: false,
63+
tabBarLabel: isMobile ? '' : route.name,
64+
});
65+
5666
return (
5767
<Tab.Navigator screenOptions={screenOptions}>
5868
<Tab.Screen name="Home" component={HomeScreen} />

src/navigation/Navigation.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { NavigationContainer } from '@react-navigation/native';
2+
import { createStackNavigator } from '@react-navigation/stack';
23
import React from 'react';
3-
import { Animated } from 'react-native';
4+
import { Animated, Platform } from 'react-native';
45
import { createSharedElementStackNavigator } from 'react-navigation-shared-element';
56

67
import MainTabNavigator from './MainTabNavigator';
@@ -25,7 +26,10 @@ export type RootStackParamList = {
2526
FastingStages: { currentElapsedHours?: number; selectedStageName?: string; sharedId?: string };
2627
};
2728

28-
const Stack = createSharedElementStackNavigator<RootStackParamList>();
29+
30+
const Stack = Platform.OS === 'web'
31+
? createStackNavigator<RootStackParamList>()
32+
: createSharedElementStackNavigator<RootStackParamList>();
2933

3034
export default function Navigation() {
3135
const { hasCompletedOnboarding } = useAppContext();
@@ -61,6 +65,7 @@ export default function Navigation() {
6165
}),
6266
}}
6367

68+
6469
sharedElements={(route) => {
6570
const { sharedId } = route.params;
6671

0 commit comments

Comments
 (0)