diff --git a/src/screens/reader/ChapterContext.tsx b/src/screens/reader/ChapterContext.tsx new file mode 100644 index 00000000..d418721e --- /dev/null +++ b/src/screens/reader/ChapterContext.tsx @@ -0,0 +1,38 @@ +import React, { createContext, useContext, useState } from 'react'; +import { ChapterInfo, NovelInfo } from '@database/types'; + +const defaultValue = {} as { + novel: NovelInfo; + chapter: ChapterInfo; + setChapter: (chapter: ChapterInfo) => void; +}; + +const ChapterContext = createContext<{ + novel: NovelInfo; + chapter: ChapterInfo; + setChapter: (chapter: ChapterInfo) => void; +}>(defaultValue); + +export function ChapterContextProvider({ + children, + novel, + initialChapter, +}: { + children: JSX.Element; + novel: NovelInfo; + initialChapter: ChapterInfo; +}) { + const [chapter, setChapter] = useState(initialChapter); + return ( + setChapter(c) }} + > + {children} + + ); +} + +export const useChapterContext = () => { + const { novel, chapter, setChapter } = useContext(ChapterContext); + return { novel, chapter, setChapter }; +}; diff --git a/src/screens/reader/ReaderScreen.tsx b/src/screens/reader/ReaderScreen.tsx index 9d59b065..52db2f4d 100644 --- a/src/screens/reader/ReaderScreen.tsx +++ b/src/screens/reader/ReaderScreen.tsx @@ -2,11 +2,7 @@ import React, { useRef, useCallback } from 'react'; import { DrawerLayoutAndroid } from 'react-native'; import { showToast } from '@utils/showToast'; -import { - useChapterGeneralSettings, - useTheme, - useNovel, -} from '@hooks/persisted'; +import { useChapterGeneralSettings, useTheme } from '@hooks/persisted'; import ReaderAppbar from './components/ReaderAppbar'; import ReaderFooter from './components/ReaderFooter'; @@ -21,35 +17,28 @@ import WebView from 'react-native-webview'; import { getString } from '@strings/translations'; import KeepScreenAwake from './components/KeepScreenAwake'; import useChapter from './hooks/useChapter'; +import { ChapterContextProvider, useChapterContext } from './ChapterContext'; const Chapter = ({ route, navigation }: ChapterScreenProps) => { const drawerRef = useRef(null); - const { chapters, novelSettings, pages, setPageIndex } = useNovel( - route.params.novel.path, - route.params.novel.pluginId, - ); return ( - ( - + } + > + - )} - > - - + + ); }; @@ -58,11 +47,10 @@ type ChapterContentProps = ChapterScreenProps & { }; export const ChapterContent = ({ - route, navigation, drawerRef, }: ChapterContentProps) => { - const { novel, chapter } = route.params; + const { novel, chapter } = useChapterContext(); const webViewRef = useRef(null); const readerSheetRef = useRef(null); const theme = useTheme(); @@ -78,10 +66,9 @@ export const ChapterContent = ({ setError, setLoading, getChapter, - setChapter, saveProgress, hideHeader, - } = useChapter(novel, chapter, webViewRef); + } = useChapter(webViewRef); const scrollToStart = () => requestAnimationFrame(() => { @@ -160,7 +147,6 @@ export const ChapterContent = ({ <> {keepScreenOn ? : null} {!hidden ? ( <> - + void; -}; type ButtonProperties = { text: string; index?: number; @@ -35,13 +30,15 @@ type ButtonsProperties = { }; const ChapterDrawer = ({ - route, navigation, - chapters, - novelSettings, - pages, - setPageIndex, -}: ChapterDrawerProps) => { +}: { + navigation: ChapterScreenProps['navigation']; +}) => { + const { novel: novelItem, chapter } = useChapterContext(); + const { chapters, novelSettings, pages, setPageIndex } = useNovel( + novelItem.path, + novelItem.pluginId, + ); const theme = useTheme(); const insets = useSafeAreaInsets(); const { defaultChapterSort } = useAppSettings(); @@ -49,7 +46,6 @@ const ChapterDrawer = ({ const styles = createStylesheet(theme, insets); - const { chapter, novel: novelItem } = route.params; const { sort = defaultChapterSort } = novelSettings; const listAscending = sort === 'ORDER BY position ASC'; diff --git a/src/screens/reader/components/ReaderAppbar.tsx b/src/screens/reader/components/ReaderAppbar.tsx index f40da40b..6ef0dc0c 100644 --- a/src/screens/reader/components/ReaderAppbar.tsx +++ b/src/screens/reader/components/ReaderAppbar.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { StatusBar, StyleSheet, View } from 'react-native'; import color from 'color'; @@ -6,24 +6,20 @@ import { Text } from 'react-native-paper'; import { IconButtonV2 } from '../../../components'; import Animated, { FadeIn, FadeOut } from 'react-native-reanimated'; import { ThemeColors } from '@theme/types'; -import { ChapterInfo } from '@database/types'; import { bookmarkChapter } from '@database/queries/ChapterQueries'; +import { useChapterContext } from '../ChapterContext'; interface ReaderAppbarProps { - novelName: string; - chapter: ChapterInfo; theme: ThemeColors; goBack: () => void; - setChapter: (chapter: ChapterInfo) => void; } -const ReaderAppbar = ({ - novelName, - chapter, - goBack, - theme, - setChapter, -}: ReaderAppbarProps) => { +const ReaderAppbar = ({ goBack, theme }: ReaderAppbarProps) => { + const { chapter, novel } = useChapterContext(); + const [bookmarked, setBookmarked] = useState(chapter.bookmark); + useEffect(() => { + setBookmarked(chapter.bookmark); + }, [chapter]); return ( - {novelName} + {novel.name} { - bookmarkChapter(chapter.id).then(() => - setChapter({ - ...chapter, - bookmark: !chapter.bookmark, - }), - ); + bookmarkChapter(chapter.id).then(() => setBookmarked(!bookmarked)); }} color={theme.onSurface} theme={theme} diff --git a/src/screens/reader/components/ReaderFooter.tsx b/src/screens/reader/components/ReaderFooter.tsx index 2012c1a2..a34ea808 100644 --- a/src/screens/reader/components/ReaderFooter.tsx +++ b/src/screens/reader/components/ReaderFooter.tsx @@ -4,15 +4,14 @@ import { IconButton } from 'react-native-paper'; import color from 'color'; import Animated, { FadeIn, FadeOut } from 'react-native-reanimated'; import { ThemeColors } from '@theme/types'; -import { ChapterInfo, NovelInfo } from '@database/types'; +import { ChapterInfo } from '@database/types'; import { BottomSheetModalMethods } from '@gorhom/bottom-sheet/lib/typescript/types'; import { ChapterScreenProps } from '@navigators/types'; import { useDeviceOrientation } from '@hooks/index'; +import { useChapterContext } from '../ChapterContext'; interface ChapterFooterProps { theme: ThemeColors; - novel: NovelInfo; - chapter: ChapterInfo; nextChapter: ChapterInfo; prevChapter: ChapterInfo; readerSheetRef: React.RefObject; @@ -24,8 +23,6 @@ interface ChapterFooterProps { const ChapterFooter = ({ theme, - novel, - chapter, nextChapter, prevChapter, readerSheetRef, @@ -34,6 +31,7 @@ const ChapterFooter = ({ navigation, openDrawer, }: ChapterFooterProps) => { + const { novel, chapter } = useChapterContext(); const rippleConfig = { color: theme.rippleColor, borderless: true, diff --git a/src/screens/reader/components/WebViewReader.tsx b/src/screens/reader/components/WebViewReader.tsx index 12810f33..1166b499 100644 --- a/src/screens/reader/components/WebViewReader.tsx +++ b/src/screens/reader/components/WebViewReader.tsx @@ -1,5 +1,4 @@ -import * as React from 'react'; -import { useEffect, useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { Dimensions, NativeEventEmitter, @@ -28,6 +27,7 @@ import * as Speech from 'expo-speech'; import * as Clipboard from 'expo-clipboard'; import { showToast } from '@utils/showToast'; import { PLUGIN_STORAGE } from '@utils/Storages'; +import { useChapterContext } from '../ChapterContext'; type WebViewPostEvent = { type: string; @@ -35,12 +35,6 @@ type WebViewPostEvent = { }; type WebViewReaderProps = { - data: { - novel: { - pluginId: string; - }; - chapter: ChapterInfo; - }; html: string; nextChapter: ChapterInfo; webViewRef: React.RefObject; @@ -64,7 +58,6 @@ const onLogMessage = (payload: { nativeEvent: { data: string } }) => { const WebViewReader: React.FC = props => { const { - data: { chapter, novel }, html, nextChapter, webViewRef, @@ -73,6 +66,7 @@ const WebViewReader: React.FC = props => { onPress, navigateToChapterBySwipe, } = props; + const { novel, chapter } = useChapterContext(); const assetsUriPrefix = useMemo( () => (__DEV__ ? 'http://localhost:8081/assets' : 'file:///android_asset'), [], diff --git a/src/screens/reader/hooks/useChapter.ts b/src/screens/reader/hooks/useChapter.ts index 6bbbd401..b3870aa4 100644 --- a/src/screens/reader/hooks/useChapter.ts +++ b/src/screens/reader/hooks/useChapter.ts @@ -5,7 +5,7 @@ import { updateChapterProgress, } from '@database/queries/ChapterQueries'; import { insertHistory } from '@database/queries/HistoryQueries'; -import { ChapterInfo, NovelInfo } from '@database/types'; +import { ChapterInfo } from '@database/types'; import { useChapterGeneralSettings, useLibrarySettings, @@ -25,17 +25,14 @@ import { Dimensions, NativeEventEmitter } from 'react-native'; import VolumeButtonListener from '@native/volumeButtonListener'; import * as Speech from 'expo-speech'; import { defaultTo } from 'lodash-es'; +import { useChapterContext } from '../ChapterContext'; const emmiter = new NativeEventEmitter(VolumeButtonListener); -export default function useChapter( - novel: NovelInfo, - initialChapter: ChapterInfo, - webViewRef: RefObject, -) { +export default function useChapter(webViewRef: RefObject) { + const { novel, chapter } = useChapterContext(); const { setLastRead } = useNovel(novel.path, novel.pluginId); const [hidden, setHidden] = useState(true); - const [chapter, setChapter] = useState(initialChapter); const [chapterText, setChapterText] = useState(''); const [loading, setLoading] = useState(true); const [[nextChapter, prevChapter], setAdjacentChapter] = useState< @@ -186,7 +183,6 @@ export default function useChapter( error, loading, chapterText, - setChapter, setHidden, setLoading, setError,