feat: New Bottom Sheet Package (#515)

* setup

* implemented new bottomsheets

* set containerHeight

* NovelBottomSheet fix

* fixed BottomInsets

* edited FilterBottomSheet + cleanup

* TrackSheet + cleanup

* removal of rn-sliding-up-panel

Closes #506
This commit is contained in:
Patrick Loser
2023-01-13 00:32:45 +01:00
committed by GitHub
parent 7880cd0187
commit deefc10d41
17 changed files with 626 additions and 528 deletions
+16 -12
View File
@@ -1,3 +1,4 @@
import 'react-native-gesture-handler';
import { enableFreeze } from 'react-native-screens';
enableFreeze(true);
@@ -16,6 +17,7 @@ import { createDatabase } from './src/database/db';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import LottieSplashScreen from 'react-native-lottie-splash-screen';
import AppErrorBoundary from '@components/AppErrorBoundary/AppErrorBoundary';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const App = () => {
useEffect(() => {
@@ -24,18 +26,20 @@ const App = () => {
}, []);
return (
<AppErrorBoundary>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<SafeAreaProvider>
<PaperProvider>
<StatusBar translucent={true} backgroundColor="transparent" />
<Main />
</PaperProvider>
</SafeAreaProvider>
</PersistGate>
</Provider>
</AppErrorBoundary>
<GestureHandlerRootView style={{ flex: 1 }}>
<AppErrorBoundary>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<SafeAreaProvider>
<PaperProvider>
<StatusBar translucent={true} backgroundColor="transparent" />
<Main />
</PaperProvider>
</SafeAreaProvider>
</PersistGate>
</Provider>
</AppErrorBoundary>
</GestureHandlerRootView>
);
};
+2
View File
@@ -8,6 +8,8 @@
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
-keep class com.swmansion.reanimated.** { *; }
-keep class com.facebook.react.turbomodule.** { *; }
-keep class com.facebook.hermes.unicode.** { *; }
-keep class com.facebook.jni.** { *; }
-keep public class com.dylanvann.fastimage.* {*;}
+1
View File
@@ -20,6 +20,7 @@ module.exports = function (api) {
},
},
],
'react-native-reanimated/plugin',
],
};
};
+461 -386
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -15,6 +15,7 @@
"prepare": "husky install"
},
"dependencies": {
"@gorhom/bottom-sheet": "^4.4.5",
"@react-native-async-storage/async-storage": "^1.15.11",
"@react-native-community/clipboard": "^1.5.1",
"@react-native-community/masked-view": "^0.1.11",
@@ -54,13 +55,13 @@
"react-native-easing-gradient": "^1.0.0",
"react-native-error-boundary": "^1.1.16",
"react-native-fast-image": "^8.5.11",
"react-native-gesture-handler": "~1.10.2",
"react-native-gesture-handler": "~2.1.3",
"react-native-lottie-splash-screen": "^1.0.1",
"react-native-markdown-display": "^7.0.0-alpha.2",
"react-native-mmkv": "^2.4.3",
"react-native-pager-view": "^5.4.9",
"react-native-paper": "^5.1.2",
"react-native-reanimated": "^2.2.4",
"react-native-reanimated": "^2.13.0",
"react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^3.9.0",
@@ -75,7 +76,6 @@
"redux": "^4.1.2",
"redux-persist": "^6.0.0",
"rn-fetch-blob": "^0.12.0",
"rn-sliding-up-panel": "^2.4.4",
"sanitize-html": "^2.7.0"
},
"devDependencies": {
@@ -0,0 +1,49 @@
import React, { ReactElement, Ref, useCallback } from 'react';
import { overlay } from 'react-native-paper';
import { default as BS, BottomSheetBackdrop } from '@gorhom/bottom-sheet';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { MD3ThemeType } from '@theme/types';
import { StyleSheet } from 'react-native';
interface BottomSheetProps {
bottomSheetRef: Ref<BS>;
snapPoints: Array<number>;
height: number;
theme: MD3ThemeType;
children: ReactElement;
}
const BottomSheet: React.FC<BottomSheetProps> = ({
bottomSheetRef,
snapPoints,
height,
theme,
children,
}) => {
const { bottom } = useSafeAreaInsets();
const renderBackdrop = useCallback(
props => <BottomSheetBackdrop {...props} disappearsOnIndex={0} />,
[],
);
return (
<BS
index={-1}
backdropComponent={renderBackdrop}
snapPoints={[0.1].concat(snapPoints)}
enablePanDownToClose={true}
ref={bottomSheetRef}
handleStyle={styles.handle}
containerHeight={height + bottom}
containerStyle={{ paddingBottom: bottom }}
backgroundStyle={{ backgroundColor: overlay(2, theme.surface) }}
>
{children}
</BS>
);
};
const styles = StyleSheet.create({
handle: {
display: 'none',
},
});
export default BottomSheet;
@@ -3,11 +3,11 @@ import { useNavigation } from '@react-navigation/native';
import * as WebBrowser from 'expo-web-browser';
import { FAB, Portal } from 'react-native-paper';
import Bottomsheet from 'rn-sliding-up-panel';
import { Container, ErrorScreenV2, SearchbarV2 } from '@components/index';
import NovelList from '@components/NovelList';
import NovelCover from '@components/NovelCover';
import FilterBottomSheet from './components/BottomSheet';
import Bottomsheet from '@gorhom/bottom-sheet';
import FilterBottomSheet from './components/FilterBottomSheet';
import { useCategorySettings, useSearch } from '../../hooks';
import { useTheme } from '@hooks/useTheme';
@@ -20,6 +20,7 @@ import { useLibraryNovels } from '../../screens/library/hooks/useLibrary';
import { insertNovelInLibrary } from '../../database/queries/NovelQueriesV2';
import { LibraryNovelInfo } from '../../database/types';
import SourceScreenSkeletonLoading from '@screens/browse/loadingAnimation/SourceScreenSkeletonLoading';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
interface BrowseSourceScreenProps {
route: {
@@ -99,8 +100,8 @@ const BrowseSourceScreen: React.FC<BrowseSourceScreenProps> = ({ route }) => {
[sourceId],
);
const { bottom } = useSafeAreaInsets();
const filterSheetRef = useRef<Bottomsheet | null>(null);
return (
<Container>
<SearchbarV2
@@ -173,15 +174,19 @@ const BrowseSourceScreen: React.FC<BrowseSourceScreenProps> = ({ route }) => {
}
/>
)}
{!showLatestNovels && filterValues?.length ? (
<>
<FAB
icon={'filter-variant'}
style={[styles.filterFab, { backgroundColor: theme.primary }]}
style={[
styles.filterFab,
{ backgroundColor: theme.primary, marginBottom: bottom },
]}
label={'Filter'}
uppercase={false}
color={theme.onPrimary}
onPress={() => filterSheetRef?.current?.show()}
onPress={() => filterSheetRef?.current?.expand()}
/>
<Portal>
<FilterBottomSheet
@@ -1,7 +1,9 @@
import React, { LegacyRef, useState } from 'react';
import { Animated, Pressable, StyleSheet, Text, View } from 'react-native';
import React, { Ref, useState } from 'react';
import { Pressable, StyleSheet, Text, View } from 'react-native';
import color from 'color';
import Bottomsheet from 'rn-sliding-up-panel';
import BottomSheet from '../../../components/BottomSheet/BottomSheet';
import BottomSheetType, { BottomSheetView } from '@gorhom/bottom-sheet';
import { useTheme } from '@hooks/useTheme';
import {
@@ -116,41 +118,37 @@ const FilterItem: React.FC<FilterItemProps> = ({
};
interface BottomSheetProps {
filterSheetRef: Ref<BottomSheetType> | null;
filtersValues: SourceFilter[] | undefined;
filterSheetRef: LegacyRef<Bottomsheet> | null;
setFilters: (filters?: SelectedFilter) => void;
clearFilters: () => void;
}
const BottomSheet: React.FC<BottomSheetProps> = ({
const FilterBottomSheet: React.FC<BottomSheetProps> = ({
filterSheetRef,
filtersValues,
clearFilters,
setFilters,
}) => {
const theme = useTheme();
const [animatedValue] = useState(new Animated.Value(0));
const [selectedFilters, setSelectedFilters] = useState<
SelectedFilter | undefined
>();
return (
<Bottomsheet
animatedValue={animatedValue}
ref={filterSheetRef}
draggableRange={{ top: 600, bottom: 0 }}
snappingPoints={[0, 400, 600]}
showBackdrop={true}
backdropOpacity={0.3}
<BottomSheet
bottomSheetRef={filterSheetRef}
snapPoints={[400, 600]}
height={600}
theme={theme}
>
<View
<BottomSheetView
style={[
styles.container,
{ backgroundColor: overlay(2, theme.surface) },
]}
>
<View
<BottomSheetView
style={[
styles.buttonContainer,
{ borderBottomColor: dividerColor(theme.isDark) },
@@ -167,14 +165,14 @@ const BottomSheet: React.FC<BottomSheetProps> = ({
/>
<Button
title={'Filter'}
textColor={theme.colorButtonText}
textColor={theme.textColorPrimary}
onPress={() => {
setFilters(selectedFilters);
filterSheetRef?.current?.hide();
filterSheetRef?.current?.collapse();
}}
theme={theme}
/>
</View>
</BottomSheetView>
<FlatList
contentContainerStyle={styles.filterContainer}
data={filtersValues}
@@ -187,12 +185,12 @@ const BottomSheet: React.FC<BottomSheetProps> = ({
/>
)}
/>
</View>
</Bottomsheet>
</BottomSheetView>
</BottomSheet>
);
};
export default BottomSheet;
export default FilterBottomSheet;
const styles = StyleSheet.create({
container: {
+3 -3
View File
@@ -1,6 +1,6 @@
import React, { useMemo, useRef, useState } from 'react';
import { StyleSheet, Text, useWindowDimensions } from 'react-native';
import Bottomsheet from 'rn-sliding-up-panel';
import BottomSheet from '@gorhom/bottom-sheet';
import {
NavigationState,
SceneRendererProps,
@@ -83,7 +83,7 @@ const LibraryScreen = () => {
const [index, setIndex] = useState(0);
const bottomSheetRef = useRef<Bottomsheet | null>(null);
const bottomSheetRef = useRef<BottomSheet | null>(null);
const renderTabBar = (
props: SceneRendererProps & { navigationState: State },
@@ -165,7 +165,7 @@ const LibraryScreen = () => {
}
: {
iconName: 'filter-variant',
onPress: () => bottomSheetRef.current?.show(),
onPress: () => bottomSheetRef.current?.expand(),
},
]}
theme={theme}
@@ -1,12 +1,5 @@
import React, { LegacyRef, useMemo, useState } from 'react';
import {
Animated,
StyleSheet,
Text,
useWindowDimensions,
View,
} from 'react-native';
import Bottomsheet from 'rn-sliding-up-panel';
import React, { Ref, useMemo, useState } from 'react';
import { StyleSheet, Text, useWindowDimensions, View } from 'react-native';
import { SceneMap, TabBar, TabView } from 'react-native-tab-view';
import color from 'color';
@@ -25,10 +18,14 @@ import {
import { FlashList } from '@shopify/flash-list';
import { RadioButton } from '@components/RadioButton/RadioButton';
import { overlay } from 'react-native-paper';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import {
default as BottomSheetType,
BottomSheetView,
} from '@gorhom/bottom-sheet';
import BottomSheet from '@components/BottomSheet/BottomSheet';
interface LibraryBottomSheetProps {
bottomSheetRef: LegacyRef<Bottomsheet> | null;
bottomSheetRef: Ref<BottomSheetType> | null;
}
const FirstRoute = () => {
@@ -168,7 +165,6 @@ const LibraryBottomSheet: React.FC<LibraryBottomSheetProps> = ({
bottomSheetRef,
}) => {
const theme = useTheme();
const [animatedValue] = useState(new Animated.Value(0));
const layout = useWindowDimensions();
@@ -210,21 +206,14 @@ const LibraryBottomSheet: React.FC<LibraryBottomSheetProps> = ({
third: ThirdRoute,
});
const { bottom } = useSafeAreaInsets();
const bottomSheetHeight = 480 + bottom;
return (
<Bottomsheet
animatedValue={animatedValue}
ref={bottomSheetRef}
draggableRange={{ top: bottomSheetHeight, bottom: 0 }}
snappingPoints={[0, bottomSheetHeight]}
showBackdrop={true}
backdropOpacity={0.3}
height={bottomSheetHeight}
<BottomSheet
bottomSheetRef={bottomSheetRef}
snapPoints={[520]}
height={520}
theme={theme}
>
<View
<BottomSheetView
style={[
styles.bottomSheetCtn,
{ backgroundColor: overlay(2, theme.surface) },
@@ -238,8 +227,8 @@ const LibraryBottomSheet: React.FC<LibraryBottomSheetProps> = ({
initialLayout={{ width: layout.width }}
style={styles.tabView}
/>
</View>
</Bottomsheet>
</BottomSheetView>
</BottomSheet>
);
};
@@ -117,7 +117,7 @@ const NovelInfoHeader = ({
deleteDownloadsSnackbar.setTrue();
}
}}
handleTrackerSheet={() => trackerSheetRef.current.show()}
handleTrackerSheet={() => trackerSheetRef.current.expand()}
theme={theme}
/>
<NovelSummary
@@ -137,7 +137,7 @@ const NovelInfoHeader = ({
/>
<Pressable
style={styles.bottomsheet}
onPress={() => novelBottomSheetRef.current.show()}
onPress={() => novelBottomSheetRef.current.expand()}
android_ripple={{
color: color(theme.primary).alpha(0.12).string(),
}}
@@ -1,16 +1,11 @@
import React, { useState } from 'react';
import {
StyleSheet,
View,
Text,
Animated,
useWindowDimensions,
} from 'react-native';
import { StyleSheet, View, Text, useWindowDimensions } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import color from 'color';
import { TabView, SceneMap, TabBar } from 'react-native-tab-view';
import Bottomsheet from 'rn-sliding-up-panel';
import { BottomSheetView } from '@gorhom/bottom-sheet';
import BottomSheet from '@components/BottomSheet/BottomSheet';
import { getString } from '../../../../strings/translations';
import { Checkbox, SortItem } from '../../../components/Checkbox/Checkbox';
@@ -29,18 +24,12 @@ const ChaptersSettingsSheet = ({
theme,
showChapterTitles,
}) => {
const { bottom } = useSafeAreaInsets();
const bottomSheetHeight = 220 + bottom;
const sortChapters = val =>
dispatch(sortAndFilterChapters(novelId, val, filter));
const filterChapters = val =>
dispatch(sortAndFilterChapters(novelId, sort, val));
const [animatedValue] = useState(new Animated.Value(0));
const FirstRoute = () => (
<View style={{ flex: 1 }}>
<Checkbox
@@ -156,14 +145,13 @@ const ChaptersSettingsSheet = ({
);
return (
<Bottomsheet
animatedValue={animatedValue}
ref={bottomSheetRef}
draggableRange={{ top: bottomSheetHeight, bottom: 0 }}
snappingPoints={[0, bottomSheetHeight]}
backdropOpacity={0.5}
<BottomSheet
snapPoints={[240]}
bottomSheetRef={bottomSheetRef}
height={220}
theme={theme}
>
<View
<BottomSheetView
style={[
styles.contentContainer,
{ backgroundColor: overlay(2, theme.surface) },
@@ -177,8 +165,8 @@ const ChaptersSettingsSheet = ({
initialLayout={{ width: layout.width }}
style={{ borderTopRightRadius: 8, borderTopLeftRadius: 8 }}
/>
</View>
</Bottomsheet>
</BottomSheetView>
</BottomSheet>
);
};
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react';
import { StyleSheet, View, ToastAndroid } from 'react-native';
import { overlay, Portal } from 'react-native-paper';
import Bottomsheet from 'rn-sliding-up-panel';
import BottomSheet from '@components/BottomSheet/BottomSheet';
import { useSelector, useDispatch } from 'react-redux';
import { updateTracker } from '../../../../redux/tracker/tracker.actions';
@@ -11,7 +11,6 @@ import SetTrackStatusDialog from './SetTrackStatusDialog';
import SetTrackScoreDialog from './SetTrackScoreDialog';
import SetTrackChaptersDialog from './SetTrackChaptersDialog';
import { AddMalTrackingCard, MalTrackItemCard } from './MyAnimeListCards';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const TrackSheet = ({ bottomSheetRef, novelId, novelName, theme }) => {
const tracker = useSelector(state => state.trackerReducer.tracker);
@@ -20,8 +19,6 @@ const TrackSheet = ({ bottomSheetRef, novelId, novelName, theme }) => {
);
const dispatch = useDispatch();
const { bottom } = useSafeAreaInsets();
const [trackItem, setTrackItem] = useState();
useEffect(() => {
@@ -106,15 +103,13 @@ const TrackSheet = ({ bottomSheetRef, novelId, novelName, theme }) => {
setTrackScoreDialog(false);
};
const bottomSheetHeight = 120 + bottom;
return (
<>
<Bottomsheet
ref={bottomSheetRef}
draggableRange={{ top: bottomSheetHeight, bottom: 0 }}
snappingPoints={[0, bottomSheetHeight]}
backdropOpacity={0.25}
<BottomSheet
bottomSheetRef={bottomSheetRef}
snapPoints={[130]}
height={130}
theme={theme}
>
<View
style={[
@@ -138,7 +133,7 @@ const TrackSheet = ({ bottomSheetRef, novelId, novelName, theme }) => {
/>
)}
</View>
</Bottomsheet>
</BottomSheet>
<Portal>
{trackItem ? (
<>
+6 -8
View File
@@ -401,19 +401,17 @@ const ChapterContent = ({ route, navigation }) => {
<>
<>
<ReaderAppbar
novelName={novelName}
chapterName={chapterName || chapter.chapterName}
chapterId={chapterId}
bookmark={bookmark}
textToSpeech={ttsStatus}
tts={startTts}
readerSheetRef={readerSheetRef}
novelName={novelName}
chapterId={chapterId}
chapterName={chapterName || chapter.chapterName}
hide={hidden}
navigation={navigation}
dispatch={dispatch}
theme={theme}
tts={startTts}
textToSpeech={ttsStatus}
textToSpeechPosition={ttsPosition}
pauseTts={pauseTts}
theme={theme}
/>
<GestureRecognizer
onSwipeRight={
@@ -17,9 +17,9 @@ const ReaderAppbar = ({
dispatch,
tts,
textToSpeech,
theme,
textToSpeechPosition,
pauseTts,
theme,
}) => {
const { goBack } = useNavigation();
const [bookmarked, setBookmarked] = useState(bookmark);
@@ -1,14 +1,12 @@
import {
Animated,
StyleSheet,
Text,
useWindowDimensions,
View,
} from 'react-native';
import React, { LegacyRef, useMemo, useState } from 'react';
import { StyleSheet, Text, useWindowDimensions, View } from 'react-native';
import React, { Ref, useMemo, useState } from 'react';
import color from 'color';
import Bottomsheet from 'rn-sliding-up-panel';
import {
default as BottomSheetType,
BottomSheetView,
} from '@gorhom/bottom-sheet';
import BottomSheet from '@components/BottomSheet/BottomSheet';
import { useAppDispatch, useSettingsV1 } from '../../../../redux/hooks';
import { useTheme } from '@hooks/useTheme';
import { SceneMap, TabBar, TabView } from 'react-native-tab-view';
@@ -156,16 +154,13 @@ const GeneralTab: React.FC = () => {
};
interface ReaderBottomSheetV2Props {
bottomSheetRef: LegacyRef<Bottomsheet> | null;
bottomSheetRef: Ref<BottomSheetType> | null;
}
const ReaderBottomSheetV2: React.FC<ReaderBottomSheetV2Props> = ({
bottomSheetRef,
}) => {
const theme = useTheme();
// const { bottom: bottomInset } = useSafeAreaInsets();
const [animatedValue] = useState(new Animated.Value(0));
const tabHeaderColor = overlay(2, theme.surface);
const backgroundColor = tabHeaderColor;
@@ -214,16 +209,15 @@ const ReaderBottomSheetV2: React.FC<ReaderBottomSheetV2Props> = ({
);
return (
<Bottomsheet
animatedValue={animatedValue}
ref={bottomSheetRef}
draggableRange={{ top: 600, bottom: 0 }}
snappingPoints={[0, 400, 600]}
showBackdrop={true}
backdropOpacity={0}
height={600}
<BottomSheet
bottomSheetRef={bottomSheetRef}
snapPoints={[360, 560]}
height={560}
theme={theme}
>
<View style={[styles.bottomSheetContainer, { backgroundColor }]}>
<BottomSheetView
style={[styles.bottomSheetContainer, { backgroundColor }]}
>
<TabView
navigationState={{ index, routes }}
renderTabBar={renderTabBar}
@@ -232,8 +226,8 @@ const ReaderBottomSheetV2: React.FC<ReaderBottomSheetV2Props> = ({
initialLayout={{ width: layout.width }}
style={styles.tabView}
/>
</View>
</Bottomsheet>
</BottomSheetView>
</BottomSheet>
);
};
@@ -89,7 +89,7 @@ const ChapterFooter = ({
<Pressable
android_ripple={rippleConfig}
style={styles.buttonStyles}
onPress={() => readerSheetRef.current.show({ toValue: 390 })}
onPress={() => readerSheetRef.current.snapToIndex(1)}
>
<IconButton
icon="cog-outline"