Skip to content

Commit 3e665e9

Browse files
authored
Reverting the expo 53 bump due to various issues related to react native architecture (#971)
* Revert "A few more udpates to support expo 53 SDK (#967)" This reverts commit 805d059. * Revert "package.json: bump to Expo 53.0.20 (#955)" This reverts commit 41ce487.
1 parent f24f40d commit 3e665e9

27 files changed

Lines changed: 1644 additions & 1488 deletions

.github/actions/setup/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ runs:
1717
- name: 🏗 Setup Node
1818
uses: actions/setup-node@v3
1919
with:
20-
node-version: 20.x
20+
node-version: 18.x
2121
cache: yarn
2222
- name: 🏗 Setup Expo
2323
uses: expo/expo-github-action@v7

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,3 @@ android
2424

2525
# Ignore changes to the package-lock
2626
package-lock.json
27-
.yarn/install-state.gz
28-
.yarnrc.yml

App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import {TabNavigatorParamList} from 'routes';
3939
import {colorLookup} from 'theme';
4040
import {AvalancheCenterID, AvalancheCenterWebsites} from 'types/nationalAvalancheCenter';
4141

42-
import 'date-time-format-timezone';
42+
require('date-time-format-timezone');
4343

4444
import axios, {AxiosRequestConfig} from 'axios';
4545
import {QUERY_CACHE_ASYNC_STORAGE_KEY} from 'data/asyncStorageKeys';
@@ -412,7 +412,7 @@ const BaseApp: React.FunctionComponent<{
412412
height: '100%',
413413
resizeMode: Constants.expoConfig?.splash?.resizeMode || 'contain',
414414
}}
415-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports
415+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
416416
source={require('./assets/splash.png')}
417417
/>
418418
<Center style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}>

Preferences.test.tsx

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import AsyncStorage from '@react-native-async-storage/async-storage';
22
import {renderHook} from '@testing-library/react-hooks';
3-
import {waitFor} from '@testing-library/react-native';
43

54
import {PREFERENCES_KEY} from 'data/asyncStorageKeys';
65
import {PreferencesProvider, resetPreferencesForTests, usePreferences} from 'Preferences';
76

87
// Mock out AsyncStorage for tests
9-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-require-imports
8+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
109
jest.mock('@react-native-async-storage/async-storage', () => require('@react-native-async-storage/async-storage/jest/async-storage-mock'));
1110

1211
describe('Preferences', () => {
@@ -22,12 +21,11 @@ describe('Preferences', () => {
2221

2322
it('updates after preferences are loaded', async () => {
2423
await AsyncStorage.setItem(PREFERENCES_KEY, JSON.stringify({center: 'BAC', hasSeenCenterPicker: true}));
25-
const {result} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
24+
const {result, waitForNextUpdate} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
2625
expect(result.current.preferences.center).toEqual('NWAC');
2726

28-
await waitFor(() => {
29-
expect(result.current.preferences.center).toEqual('BAC');
30-
});
27+
await waitForNextUpdate();
28+
expect(result.current.preferences.center).toEqual('BAC');
3129
});
3230

3331
it('falls back to defaults if preferences cannot be parsed', async () => {
@@ -50,68 +48,61 @@ describe('Preferences', () => {
5048

5149
it('updates to a default value after loading', async () => {
5250
await AsyncStorage.setItem(PREFERENCES_KEY, JSON.stringify({center: 'BAC', hasSeenCenterPicker: true}));
53-
const {result} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
51+
const {result, waitForNextUpdate} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
5452
expect(result.current.preferences.mixpanelUserId).toBeUndefined();
5553

56-
await waitFor(() => {
57-
expect(result.current.preferences.mixpanelUserId).toMatch(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/);
58-
});
54+
await waitForNextUpdate();
55+
expect(result.current.preferences.mixpanelUserId).toMatch(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/);
5956
});
6057

6158
it('does not overwrite a previously saved id', async () => {
6259
await AsyncStorage.setItem(PREFERENCES_KEY, JSON.stringify({center: 'BAC', hasSeenCenterPicker: true, mixpanelUserId: '00000000-0000-0000-0000-000000000000'}));
63-
const {result} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
60+
const {result, waitForNextUpdate} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
6461
expect(result.current.preferences.mixpanelUserId).toBeUndefined();
6562

66-
await waitFor(() => {
67-
expect(result.current.preferences.mixpanelUserId).toEqual('00000000-0000-0000-0000-000000000000');
68-
});
63+
await waitForNextUpdate();
64+
expect(result.current.preferences.mixpanelUserId).toEqual('00000000-0000-0000-0000-000000000000');
6965
});
7066

7167
it('is preserved when clearPreferences is called', async () => {
7268
const userId = 'CE998943-7231-42C4-A22F-24845B2CF567';
7369
await AsyncStorage.setItem(PREFERENCES_KEY, JSON.stringify({center: 'BAC', hasSeenCenterPicker: true, mixpanelUserId: userId}));
7470

7571
// Render the hook to load the preferences. First we'll see the default value, then the saved value
76-
const {result} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
72+
const {result, waitForNextUpdate} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
7773
expect(result.current.preferences.mixpanelUserId).toBeUndefined();
78-
await waitFor(() => {
79-
expect(result.current.preferences.center).toEqual('BAC');
80-
expect(result.current.preferences.mixpanelUserId).toEqual(userId);
81-
});
74+
await waitForNextUpdate();
75+
expect(result.current.preferences.center).toEqual('BAC');
76+
expect(result.current.preferences.mixpanelUserId).toEqual(userId);
8277

8378
// Now clear the preferences. This is not async - we clear them in memory immediately, and lazily persist the change.
8479
result.current.clearPreferences();
8580

86-
await waitFor(() => {
87-
// After clearing, the center is reset to the default, but the userId is preserved
88-
expect(result.current.preferences.center).toEqual('NWAC');
89-
expect(result.current.preferences.mixpanelUserId).toEqual(userId);
90-
});
81+
// After clearing, the center is reset to the default, but the userId is preserved
82+
expect(result.current.preferences.center).toEqual('NWAC');
83+
expect(result.current.preferences.mixpanelUserId).toEqual(userId);
9184
});
9285

9386
it('is lost when preferences are damaged', async () => {
9487
const userId = 'CE998943-7231-42C4-A22F-24845B2CF567';
9588
await AsyncStorage.setItem(PREFERENCES_KEY, JSON.stringify({mixpanelUserId: userId, center: 'this is not a valid center'}));
9689

9790
// Render the hook to load the preferences. First we'll see the default value, then the saved value
98-
const {result} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
91+
const {result, waitForNextUpdate} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
9992
expect(result.current.preferences.mixpanelUserId).toBeUndefined();
100-
await waitFor(() => {
101-
// The center is invalid, so preferences parsing will fail. The previous user id is lost, and we get a different UUID in its place.
102-
expect(result.current.preferences.mixpanelUserId).toMatch(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/);
103-
expect(result.current.preferences.mixpanelUserId).not.toEqual(userId);
104-
});
93+
await waitForNextUpdate();
94+
// The center is invalid, so preferences parsing will fail. The previous user id is lost, and we get a different UUID in its place.
95+
expect(result.current.preferences.mixpanelUserId).toMatch(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/);
96+
expect(result.current.preferences.mixpanelUserId).not.toEqual(userId);
10597
});
10698

10799
it('does overwrite an invalid id', async () => {
108100
await AsyncStorage.setItem(PREFERENCES_KEY, JSON.stringify({center: 'BAC', hasSeenCenterPicker: true, mixpanelUserId: 'not a uuid'}));
109-
const {result} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
101+
const {result, waitForNextUpdate} = renderHook(() => usePreferences(), {wrapper: PreferencesProvider});
110102
expect(result.current.preferences.mixpanelUserId).toBeUndefined();
111103

112-
await waitFor(() => {
113-
expect(result.current.preferences.mixpanelUserId).toMatch(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/);
114-
});
104+
await waitForNextUpdate();
105+
expect(result.current.preferences.mixpanelUserId).toMatch(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/);
115106
});
116107
});
117108

clientContext.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,7 @@ export const stagingHosts = {
2828
export const ClientContext: Context<ClientProps> = React.createContext<ClientProps>({
2929
...productionHosts,
3030
requestedTime: 'latest',
31-
setRequestedTime: () => {},
31+
setRequestedTime: () => {
32+
undefined;
33+
},
3234
});

components/AvalancheCenterLogo.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ export interface AvalancheCenterLogoProps {
2020
}
2121

2222
export const AvalancheCenterLogo: React.FunctionComponent<AvalancheCenterLogoProps> = ({style, avalancheCenterId}: AvalancheCenterLogoProps) => {
23-
/* eslint-disable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-require-imports */
24-
23+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
24+
/* eslint-disable @typescript-eslint/no-var-requires */
2525
const source: Record<AvalancheCenterID, ImageResolvedAssetSource> = {
2626
['BAC']: Image.resolveAssetSource(require('../assets/logos/BAC.png')),
2727
['BTAC']: Image.resolveAssetSource(require('../assets/logos/BTAC.png')),
@@ -122,6 +122,7 @@ export const AvalancheCenterLogo: React.FunctionComponent<AvalancheCenterLogoPro
122122
};
123123

124124
export const preloadAvalancheCenterLogo = async (queryClient: QueryClient, logger: Logger, avalancheCenter: AvalancheCenterID) => {
125+
/* eslint-disable @typescript-eslint/no-var-requires */
125126
switch (avalancheCenter) {
126127
case 'BAC':
127128
return ImageCache.prefetch(queryClient, logger, Image.resolveAssetSource(require('../assets/logos/BAC.png')).uri);

components/AvalancheDangerIcon.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface AvalancheDangerIconProps {
1212
}
1313

1414
const icons: Record<DangerLevel, ImageSourcePropType> = {
15-
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports */
15+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
1616
[DangerLevel.GeneralInformation]: require('../assets/danger-icons/0.png'),
1717
[DangerLevel.None]: require('../assets/danger-icons/0.png'),
1818
[DangerLevel.Low]: require('../assets/danger-icons/1.png'),
@@ -23,7 +23,8 @@ const icons: Record<DangerLevel, ImageSourcePropType> = {
2323
};
2424

2525
const sizes: Record<DangerLevel, ImageResolvedAssetSource> = {
26-
/* eslint-disable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-require-imports */
26+
/* eslint-disable @typescript-eslint/no-var-requires */
27+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
2728
[DangerLevel.GeneralInformation]: Image.resolveAssetSource(require('../assets/danger-icons/0.png')),
2829
[DangerLevel.None]: Image.resolveAssetSource(require('../assets/danger-icons/0.png')),
2930
[DangerLevel.Low]: Image.resolveAssetSource(require('../assets/danger-icons/1.png')),
@@ -56,6 +57,7 @@ export const AvalancheDangerIcon: React.FunctionComponent<AvalancheDangerIconPro
5657
};
5758

5859
export const preloadAvalancheDangerIcons = async (queryClient: QueryClient, logger: Logger) => {
60+
/* eslint-disable @typescript-eslint/no-var-requires */
5961
return Promise.all([
6062
ImageCache.prefetch(queryClient, logger, Image.resolveAssetSource(require('../assets/danger-icons/0.png')).uri),
6163
ImageCache.prefetch(queryClient, logger, Image.resolveAssetSource(require('../assets/danger-icons/1.png')).uri),

components/AvalancheForecastZoneMap.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export const AvalancheForecastZoneMap: React.FunctionComponent<MapProps> = ({cen
108108

109109
// useRef has to be used here. Animation and gesture handlers can't use props and state,
110110
// and aren't re-evaluated on render. Fun!
111-
const mapView = useRef<AnimatedMapView | null>(null);
111+
const mapView = useRef<AnimatedMapView>(null);
112112
const controller = useRef<AnimatedMapWithDrawerController>(new AnimatedMapWithDrawerController(AnimatedDrawerState.Hidden, avalancheCenterMapRegion, mapView, logger)).current;
113113
React.useEffect(() => {
114114
controller.animateUsingUpdatedAvalancheCenterMapRegion(avalancheCenterMapRegion);
@@ -184,7 +184,7 @@ export const AvalancheForecastZoneMap: React.FunctionComponent<MapProps> = ({cen
184184
.map(result => result.data) // get data from the results
185185
.filter(data => data) // only operate on results that have succeeded
186186
.forEach(forecast => {
187-
if (forecast && forecast.forecast_zone) {
187+
forecast &&
188188
forecast.forecast_zone?.forEach(({id}) => {
189189
if (zonesById[id]) {
190190
// the map layer will expose old forecasts with their danger level as appropriate, but the map expects to show a card
@@ -219,7 +219,6 @@ export const AvalancheForecastZoneMap: React.FunctionComponent<MapProps> = ({cen
219219
}
220220
}
221221
});
222-
}
223222
});
224223
warningResults
225224
.map(result => result.data) // get data from the results

components/AvalancheProblemIcon.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface AvalancheProblemIconProps {
1111
}
1212

1313
const icons: Record<AvalancheProblemType, ImageSourcePropType> = {
14-
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports */
14+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
1515
[AvalancheProblemType.DryLoose]: require('../assets/problem-icons/DryLoose.png'),
1616
[AvalancheProblemType.StormSlab]: require('../assets/problem-icons/StormSlab.png'),
1717
[AvalancheProblemType.WindSlab]: require('../assets/problem-icons/WindSlab.png'),
@@ -24,8 +24,8 @@ const icons: Record<AvalancheProblemType, ImageSourcePropType> = {
2424
};
2525

2626
const sizes: Record<AvalancheProblemType, ImageResolvedAssetSource> = {
27-
/* eslint-disable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-require-imports */
28-
27+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
28+
/* eslint-disable @typescript-eslint/no-var-requires */
2929
[AvalancheProblemType.DryLoose]: Image.resolveAssetSource(require('../assets/problem-icons/DryLoose.png')),
3030
[AvalancheProblemType.StormSlab]: Image.resolveAssetSource(require('../assets/problem-icons/StormSlab.png')),
3131
[AvalancheProblemType.WindSlab]: Image.resolveAssetSource(require('../assets/problem-icons/WindSlab.png')),
@@ -55,6 +55,7 @@ export const AvalancheProblemIcon: React.FunctionComponent<AvalancheProblemIconP
5555
};
5656

5757
export const preloadAvalancheProblemIcons = async (queryClient: QueryClient, logger: Logger) => {
58+
/* eslint-disable @typescript-eslint/no-var-requires */
5859
return Promise.all([
5960
ImageCache.prefetch(queryClient, logger, Image.resolveAssetSource(require('../assets/problem-icons/DryLoose.png')).uri),
6061
ImageCache.prefetch(queryClient, logger, Image.resolveAssetSource(require('../assets/problem-icons/StormSlab.png')).uri),

components/content/NavigationHeader.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {AntDesign, Entypo} from '@expo/vector-icons';
22
import {getHeaderTitle} from '@react-navigation/elements';
3-
import {NativeStackHeaderProps} from '@react-navigation/native-stack';
3+
import {NativeStackHeaderProps} from '@react-navigation/native-stack/lib/typescript/src/types';
44
import {HStack, View} from 'components/core';
55
import {GenerateObservationShareLink} from 'components/observations/ObservationUrlMapping';
66
import {Title1Black, Title3Black} from 'components/text';
@@ -28,7 +28,7 @@ export const NavigationHeader: React.FunctionComponent<
2828
if (!back) {
2929
firstOpen = true;
3030
// set back to not be null since we want a shared obs to have a back button
31-
back = {title: 'Observations', href: undefined};
31+
back = {title: 'Observations'};
3232
}
3333

3434
shareCenterId = reverseLookup(AvalancheCenterWebsites, shareParams.share_url) as AvalancheCenterID;

0 commit comments

Comments
 (0)