Skip to content

Commit 9e5b600

Browse files
committed
refactor(ui): bottom sheets
1 parent 9272e1e commit 9e5b600

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+503
-467
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
diff --git a/node_modules/@gorhom/bottom-sheet/lib/typescript/types.d.ts b/node_modules/@gorhom/bottom-sheet/lib/typescript/types.d.ts
2+
index 27f39a1..74223d9 100644
3+
--- a/node_modules/@gorhom/bottom-sheet/lib/typescript/types.d.ts
4+
+++ b/node_modules/@gorhom/bottom-sheet/lib/typescript/types.d.ts
5+
@@ -91,6 +91,14 @@ export interface BottomSheetModalMethods extends BottomSheetMethods {
6+
* @see {WithTimingConfig}
7+
*/
8+
dismiss: (animationConfigs?: WithSpringConfig | WithTimingConfig) => void;
9+
+ /**
10+
+ * Get the current index of the bottom sheet modal.
11+
+ */
12+
+ getCurrentIndex: () => number;
13+
+ /**
14+
+ * Check if the bottom sheet modal is open.
15+
+ */
16+
+ isOpen: boolean;
17+
}
18+
//#endregion
19+
20+
diff --git a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheetModal/BottomSheetModal.tsx b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheetModal/BottomSheetModal.tsx
21+
index 275ce50..80cd2b8 100644
22+
--- a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheetModal/BottomSheetModal.tsx
23+
+++ b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheetModal/BottomSheetModal.tsx
24+
@@ -363,6 +363,8 @@ const BottomSheetModalComponent = forwardRef<
25+
// internal
26+
minimize: handleMinimize,
27+
restore: handleRestore,
28+
+ getCurrentIndex: () => currentIndexRef.current,
29+
+ isOpen: animateOnMount ? currentIndexRef.current !== -1 : false,
30+
}));
31+
//#endregion
32+

src/App.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { ThemeProvider } from 'styled-components/native';
1515
import './utils/i18n';
1616
import './utils/quick-actions';
1717
import AppOnboarded from './AppOnboarded';
18-
import { SlashtagsProvider } from './components/SlashtagsProvider';
1918
import { toastConfig } from './components/Toast';
2019
import { useAppSelector } from './hooks/redux';
2120
import AppUpdate from './screens/AppUpdate';
@@ -78,9 +77,7 @@ const App = (): ReactElement => {
7877
) : hasCriticalUpdate ? (
7978
<AppUpdate />
8079
) : walletExists && !requiresRemoteRestore ? (
81-
<SlashtagsProvider>
82-
<AppOnboarded />
83-
</SlashtagsProvider>
80+
<AppOnboarded />
8481
) : (
8582
<Suspense fallback={null}>
8683
<OnboardingNavigator />

src/AppOnboarded.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
12
import React, { memo, ReactElement } from 'react';
3+
24
import InactivityTracker from './components/InactivityTracker';
5+
import { SlashtagsProvider } from './components/SlashtagsProvider';
36
import { useAppStateHandler } from './hooks/useAppStateHandler';
47
import { useNetworkConnectivity } from './hooks/useNetworkConnectivity';
58
import { useWalletStartup } from './hooks/useWalletStartup';
9+
import { SheetRefsProvider } from './navigation/bottom-sheet/SheetRefsProvider';
610
import DrawerNavigator from './navigation/root/DrawerNavigator';
711
import RootNavigationContainer from './navigation/root/RootNavigationContainer';
812

@@ -12,11 +16,17 @@ const AppOnboarded = (): ReactElement => {
1216
useNetworkConnectivity();
1317

1418
return (
15-
<InactivityTracker>
16-
<RootNavigationContainer>
17-
<DrawerNavigator />
18-
</RootNavigationContainer>
19-
</InactivityTracker>
19+
<SlashtagsProvider>
20+
<SheetRefsProvider>
21+
<InactivityTracker>
22+
<RootNavigationContainer>
23+
<BottomSheetModalProvider>
24+
<DrawerNavigator />
25+
</BottomSheetModalProvider>
26+
</RootNavigationContainer>
27+
</InactivityTracker>
28+
</SheetRefsProvider>
29+
</SlashtagsProvider>
2030
);
2131
};
2232

Lines changed: 100 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,119 @@
1-
/***********************************************************************************
2-
* This component wraps the @gorhom/bottom-sheet library
3-
* to more easily take advantage of it throughout the app.
4-
*
5-
* Implementation:
6-
* const snapPoints = useSnapPoints('medium');
7-
*
8-
* <BottomSheetWrapper view="viewName" snapPoints={snapPoints}>
9-
* <View>...</View>
10-
* </BottomSheetWrapper>
11-
*
12-
* Usage Throughout App:
13-
* dispatch(showBottomSheet('viewName'));
14-
* dispatch(showBottomSheet('viewName', { option1: 'value' }));
15-
* dispatch(closeSheet('viewName'));
16-
*
17-
* Check if a given view is open:
18-
* getStore().user.viewController['viewName'].isOpen;
19-
***********************************************************************************/
20-
21-
import BottomSheet, {
22-
BottomSheetView,
1+
import {
232
BottomSheetBackdrop,
24-
BottomSheetBackgroundProps,
253
BottomSheetBackdropProps,
4+
BottomSheetBackgroundProps,
5+
BottomSheetModal,
6+
BottomSheetView,
267
} from '@gorhom/bottom-sheet';
27-
import React, {
28-
memo,
29-
ReactElement,
30-
forwardRef,
31-
useImperativeHandle,
32-
useRef,
33-
useEffect,
34-
useCallback,
35-
useMemo,
36-
useState,
37-
} from 'react';
8+
import React, { ReactNode, useCallback, useEffect, useMemo } from 'react';
389
import { StyleSheet } from 'react-native';
3910
import { useReducedMotion } from 'react-native-reanimated';
40-
import { useTheme } from 'styled-components/native';
4111

4212
import { __E2E__ } from '../constants/env';
13+
import useColors from '../hooks/colors';
4314
import { useAppDispatch, useAppSelector } from '../hooks/redux';
15+
import {
16+
SheetId,
17+
useSheetRef,
18+
} from '../navigation/bottom-sheet/SheetRefsProvider';
4419
import { viewControllerSelector } from '../store/reselect/ui';
45-
import { closeSheet } from '../store/slices/ui';
46-
import { TViewController } from '../store/types/ui';
20+
import { resetSheet } from '../store/slices/ui';
4721
import BottomSheetBackground from './BottomSheetBackground';
4822

49-
export interface BottomSheetWrapperProps {
50-
children: ReactElement;
51-
view: TViewController;
23+
type SheetProps = {
24+
view: SheetId;
5225
snapPoints: number[];
53-
backdrop?: boolean;
26+
children: ReactNode;
5427
testID?: string;
5528
onOpen?: () => void;
5629
onClose?: () => void;
57-
}
58-
59-
const BottomSheetWrapper = forwardRef(
60-
(
61-
{
62-
children,
63-
view,
64-
snapPoints,
65-
backdrop = true,
66-
testID,
67-
onOpen,
68-
onClose,
69-
}: BottomSheetWrapperProps,
70-
ref,
71-
): ReactElement => {
72-
const bottomSheetRef = useRef<BottomSheet>(null);
73-
const reducedMotion = useReducedMotion();
74-
const dispatch = useAppDispatch();
75-
const data = useAppSelector((state) => viewControllerSelector(state, view));
76-
const theme = useTheme();
77-
const handleIndicatorStyle = useMemo(
78-
() => ({ backgroundColor: theme.colors.gray2 }),
79-
[theme.colors.gray2],
80-
);
81-
const [mounted, setMounted] = useState(false);
82-
83-
// https://github.com/gorhom/react-native-bottom-sheet/issues/770#issuecomment-1072113936
84-
// do not activate BottomSheet if swipe horizontally, this allows using Swiper inside of it
85-
const activeOffsetX = useMemo(() => [-999, 999], []);
86-
const activeOffsetY = useMemo(() => [-10, 10], []);
87-
88-
useEffect(() => {
89-
if (data.isOpen) {
90-
bottomSheetRef.current?.snapToIndex(0);
91-
} else {
92-
bottomSheetRef.current?.close();
93-
}
94-
setTimeout(() => setMounted(true), 500);
95-
}, [data.isOpen]);
96-
97-
useImperativeHandle(ref, () => ({
98-
snapToIndex(index = 0): void {
99-
bottomSheetRef.current?.snapToIndex(index);
100-
},
101-
expand(): void {
102-
bottomSheetRef.current?.snapToIndex(1);
103-
},
104-
close(): void {
105-
bottomSheetRef.current?.close();
106-
},
107-
}));
108-
109-
const _onOpen = useCallback(() => onOpen?.(), [onOpen]);
110-
111-
const _onClose = useCallback(() => {
112-
if (data.isOpen) {
113-
dispatch(closeSheet(view));
114-
}
115-
onClose?.();
116-
}, [data.isOpen, view, onClose, dispatch]);
117-
118-
// callbacks
119-
const handleSheetChanges = useCallback(
120-
(index: number) => {
121-
if (index === -1) {
122-
_onClose();
123-
} else if (index >= 0) {
124-
_onOpen();
125-
}
126-
},
127-
[_onClose, _onOpen],
128-
);
129-
130-
const renderBackdrop = useCallback(
131-
(props: BottomSheetBackdropProps) => {
132-
if (!backdrop) {
133-
return null;
134-
}
135-
return (
136-
<BottomSheetBackdrop
137-
{...props}
138-
disappearsOnIndex={-1}
139-
appearsOnIndex={0}
140-
accessibilityLabel="Close"
141-
/>
142-
);
143-
},
144-
[backdrop],
145-
);
146-
147-
const backgroundComponent = useCallback(
148-
({ style }: BottomSheetBackgroundProps) => (
149-
<BottomSheetBackground style={style} />
150-
),
151-
[],
152-
);
153-
154-
const style = useMemo(
155-
() => [styles.container, !mounted && { minHeight: snapPoints[0] - 30 }],
156-
[snapPoints, mounted],
157-
);
158-
159-
// Determine initial snapPoint index based on provided data.
160-
const index = useMemo((): number => (data.isOpen ? 0 : -1), [data.isOpen]);
161-
30+
};
31+
32+
const Sheet = ({
33+
view,
34+
snapPoints,
35+
children,
36+
testID,
37+
onOpen,
38+
onClose,
39+
}: SheetProps) => {
40+
const colors = useColors();
41+
const sheetRef = useSheetRef(view);
42+
const isReducedMotion = useReducedMotion();
43+
const dispatch = useAppDispatch();
44+
const data = useAppSelector((state) => viewControllerSelector(state, view));
45+
46+
// https://github.com/gorhom/react-native-bottom-sheet/issues/770#issuecomment-1072113936
47+
// do not activate BottomSheet if swipe horizontally, this allows using Swiper inside of it
48+
const activeOffsetX = useMemo(() => [-999, 999], []);
49+
const activeOffsetY = useMemo(() => [-10, 10], []);
50+
51+
const backdropComponent = useCallback((props: BottomSheetBackdropProps) => {
16252
return (
163-
<BottomSheet
164-
ref={bottomSheetRef}
165-
backgroundComponent={backgroundComponent}
166-
backdropComponent={renderBackdrop}
167-
handleIndicatorStyle={handleIndicatorStyle}
168-
handleStyle={styles.handle}
169-
index={index}
170-
snapPoints={snapPoints}
171-
animateOnMount={!reducedMotion && !__E2E__}
172-
enablePanDownToClose={true}
173-
keyboardBlurBehavior="restore"
174-
// @ts-ignore
175-
activeOffsetX={activeOffsetX}
176-
// @ts-ignore
177-
activeOffsetY={activeOffsetY}
178-
onChange={handleSheetChanges}>
179-
<BottomSheetView style={style} testID={testID}>
180-
{children}
181-
</BottomSheetView>
182-
</BottomSheet>
53+
<BottomSheetBackdrop
54+
{...props}
55+
disappearsOnIndex={-1}
56+
appearsOnIndex={0}
57+
accessibilityLabel="Close"
58+
/>
18359
);
184-
},
185-
);
60+
}, []);
61+
62+
const backgroundComponent = useCallback(
63+
({ style }: BottomSheetBackgroundProps) => (
64+
<BottomSheetBackground style={style} />
65+
),
66+
[],
67+
);
68+
69+
// biome-ignore lint/correctness/useExhaustiveDependencies: sheetRef doesn't change
70+
useEffect(() => {
71+
if (data.isOpen) {
72+
sheetRef.current?.present();
73+
} else {
74+
sheetRef.current?.close();
75+
}
76+
// setTimeout(() => setMounted(true), 500);
77+
}, [data.isOpen]);
78+
79+
const onChange = useCallback(
80+
(index: number) => {
81+
if (index === -1) {
82+
onClose?.();
83+
// clear sheet params
84+
dispatch(resetSheet(view));
85+
} else if (index >= 0) {
86+
onOpen?.();
87+
}
88+
},
89+
[onOpen, onClose, dispatch, view],
90+
);
91+
92+
return (
93+
<BottomSheetModal
94+
name={view}
95+
ref={sheetRef}
96+
snapPoints={snapPoints}
97+
handleStyle={styles.handle}
98+
handleIndicatorStyle={{ backgroundColor: colors.gray2 }}
99+
backdropComponent={backdropComponent}
100+
backgroundComponent={backgroundComponent}
101+
stackBehavior="push"
102+
animateOnMount={!isReducedMotion && !__E2E__}
103+
enablePanDownToClose={true}
104+
keyboardBlurBehavior="restore"
105+
// enableDismissOnClose={false}
106+
// @ts-ignore
107+
activeOffsetX={activeOffsetX}
108+
// @ts-ignore
109+
activeOffsetY={activeOffsetY}
110+
onChange={onChange}>
111+
<BottomSheetView style={styles.container} testID={testID}>
112+
{children}
113+
</BottomSheetView>
114+
</BottomSheetModal>
115+
);
116+
};
186117

187118
const styles = StyleSheet.create({
188119
container: {
@@ -198,4 +129,4 @@ const styles = StyleSheet.create({
198129
},
199130
});
200131

201-
export default memo(BottomSheetWrapper);
132+
export default Sheet;

src/components/Dialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const Dialog = ({
8686
activeOpacity={0.7}
8787
testID="DialogConfirm"
8888
onPress={onConfirm}>
89-
<Text style={[buttonStyles, {}]}>{confirmText}</Text>
89+
<Text style={buttonStyles}>{confirmText}</Text>
9090
</TouchableOpacity>
9191
)}
9292
</View>

0 commit comments

Comments
 (0)