Chapter footer
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
Text,
|
||||
ActivityIndicator,
|
||||
StatusBar,
|
||||
ScrollView,
|
||||
} from "react-native";
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
@@ -38,10 +39,11 @@ import ReaderSheet from "./components/ReaderSheet";
|
||||
import EmptyView from "../../Components/EmptyView";
|
||||
import FitImage from "react-native-fit-image";
|
||||
|
||||
import {
|
||||
import changeNavigationBarColor, {
|
||||
hideNavigationBar,
|
||||
showNavigationBar,
|
||||
} from "react-native-navigation-bar-color";
|
||||
import ChapterFooter from "./components/ChapterFooter";
|
||||
|
||||
const Chapter = ({ route, navigation }) => {
|
||||
const {
|
||||
@@ -52,8 +54,9 @@ const Chapter = ({ route, navigation }) => {
|
||||
novelUrl,
|
||||
novelName,
|
||||
chapterName,
|
||||
bookmark,
|
||||
} = route.params;
|
||||
let scrollViewRef;
|
||||
let scrollViewRef = useRef(null);
|
||||
let readerSheetRef = useRef(null);
|
||||
|
||||
const theme = useTheme();
|
||||
@@ -63,6 +66,8 @@ const Chapter = ({ route, navigation }) => {
|
||||
(state) => state.settingsReducer.showScrollPercentage
|
||||
);
|
||||
|
||||
const [hidden, setHidden] = useState(true);
|
||||
|
||||
const { tracker, trackedNovels } = useTrackingStatus();
|
||||
const position = usePosition(novelId, chapterId);
|
||||
|
||||
@@ -180,7 +185,7 @@ const Chapter = ({ route, navigation }) => {
|
||||
hideNavigationBar();
|
||||
if (position && firstLayout) {
|
||||
position.percentage < 100 &&
|
||||
scrollViewRef.getNode().scrollTo({
|
||||
scrollViewRef.current.scrollTo({
|
||||
x: 0,
|
||||
y: position.position,
|
||||
animated: false,
|
||||
@@ -206,24 +211,18 @@ const Chapter = ({ route, navigation }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<CollapsibleHeaderScrollView
|
||||
headerContainerBackgroundColor="rgba(0,0,0,0.5)"
|
||||
ref={(ref) => (scrollViewRef = ref)}
|
||||
CollapsibleHeaderComponent={
|
||||
<ChapterAppbar
|
||||
navigation={navigation}
|
||||
sourceId={sourceId}
|
||||
novelId={novelId}
|
||||
novelUrl={novelUrl}
|
||||
novelName={novelName}
|
||||
chapterName={chapterName}
|
||||
chapterId={chapterId}
|
||||
chapter={chapter}
|
||||
theme={theme}
|
||||
readerSheetRef={readerSheetRef}
|
||||
/>
|
||||
}
|
||||
headerHeight={Constants.statusBarHeight + 56}
|
||||
<ChapterAppbar
|
||||
novelName={novelName}
|
||||
chapterName={chapterName}
|
||||
chapterId={chapterId}
|
||||
bookmark={bookmark}
|
||||
readerSheetRef={readerSheetRef}
|
||||
hide={hidden}
|
||||
navigation={navigation}
|
||||
dispatch={dispatch}
|
||||
/>
|
||||
<ScrollView
|
||||
ref={(ref) => (scrollViewRef.current = ref)}
|
||||
contentContainerStyle={[
|
||||
styles.screenContainer,
|
||||
{ backgroundColor: readerBackground(reader.theme) },
|
||||
@@ -267,13 +266,14 @@ const Chapter = ({ route, navigation }) => {
|
||||
<View style={{ flex: 1 }}>
|
||||
{images.length > 0 &&
|
||||
images.map((image, index) => (
|
||||
<FitImage source={{ uri: image }} />
|
||||
<FitImage source={{ uri: image }} key={index} />
|
||||
))}
|
||||
|
||||
<Text
|
||||
style={readerStyles}
|
||||
onLayout={scrollToSavedProgress}
|
||||
selectable={selectText}
|
||||
onPress={() => setHidden(!hidden)}
|
||||
>
|
||||
{chapter.chapterText
|
||||
.trim()
|
||||
@@ -292,7 +292,20 @@ const Chapter = ({ route, navigation }) => {
|
||||
showScrollPercentage={showScrollPercentage}
|
||||
/>
|
||||
</Portal>
|
||||
</CollapsibleHeaderScrollView>
|
||||
</ScrollView>
|
||||
<ChapterFooter
|
||||
sourceId={sourceId}
|
||||
novelId={novelId}
|
||||
novelUrl={novelUrl}
|
||||
chapterId={chapterId}
|
||||
theme={theme}
|
||||
hide={hidden}
|
||||
novelName={novelName}
|
||||
chapterName={chapterName}
|
||||
navigation={navigation}
|
||||
readerSheetRef={readerSheetRef}
|
||||
scrollViewRef={scrollViewRef}
|
||||
/>
|
||||
{showScrollPercentage && (
|
||||
<Text
|
||||
style={[
|
||||
@@ -315,7 +328,7 @@ export default Chapter;
|
||||
const styles = StyleSheet.create({
|
||||
screenContainer: {
|
||||
flexGrow: 1,
|
||||
paddingVertical: 10,
|
||||
paddingTop: StatusBar.currentHeight,
|
||||
},
|
||||
scrollPercentage: {
|
||||
width: "100%",
|
||||
|
||||
@@ -1,95 +1,68 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Dimensions, View } from "react-native";
|
||||
|
||||
import { Appbar } from "react-native-paper";
|
||||
import {
|
||||
getNextChapterFromDB,
|
||||
getPrevChapterFromDB,
|
||||
} from "../../../Database/queries/ChapterQueries";
|
||||
import { bookmarkChapterAction } from "../../../redux/novel/novel.actions";
|
||||
|
||||
const ChapterAppbar = ({
|
||||
navigation,
|
||||
sourceId,
|
||||
novelId,
|
||||
bookmark,
|
||||
novelName,
|
||||
novelUrl,
|
||||
chapterId,
|
||||
chapterName,
|
||||
theme,
|
||||
readerSheetRef,
|
||||
hide,
|
||||
dispatch,
|
||||
}) => {
|
||||
const [nextChapter, setNextChapter] = useState({});
|
||||
const [prevChapter, setPrevChapter] = useState({});
|
||||
const [bookmarked, setBookmarked] = useState(bookmark);
|
||||
|
||||
const setPrevAndNextChap = async () => {
|
||||
const nextChap = await getNextChapterFromDB(novelId, chapterId);
|
||||
const prevChap = await getPrevChapterFromDB(novelId, chapterId);
|
||||
|
||||
setNextChapter(nextChap);
|
||||
setPrevChapter(prevChap);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setPrevAndNextChap();
|
||||
}, []);
|
||||
|
||||
const navigateToPrevChapter = () =>
|
||||
navigation.replace("Chapter", {
|
||||
chapterUrl: prevChapter.chapterUrl,
|
||||
chapterId: prevChapter.chapterId,
|
||||
sourceId,
|
||||
novelUrl,
|
||||
novelId,
|
||||
chapterName: prevChapter.chapterName,
|
||||
novelName,
|
||||
});
|
||||
|
||||
const navigateToNextChapter = () =>
|
||||
navigation.replace("Chapter", {
|
||||
chapterUrl: nextChapter.chapterUrl,
|
||||
sourceId,
|
||||
novelUrl,
|
||||
novelId,
|
||||
chapterId: nextChapter.chapterId,
|
||||
chapterName: nextChapter.chapterName,
|
||||
novelName,
|
||||
});
|
||||
|
||||
return (
|
||||
<Appbar.Header style={{ backgroundColor: "transparent", elevation: 0 }}>
|
||||
<Appbar.BackAction
|
||||
onPress={() => navigation.goBack()}
|
||||
color="#FFFFFF"
|
||||
size={26}
|
||||
style={{ marginRight: 0 }}
|
||||
/>
|
||||
<Appbar.Content
|
||||
title={novelName}
|
||||
titleStyle={{ color: "#FFFFFF" }}
|
||||
subtitle={chapterName}
|
||||
subtitleStyle={{ color: "rgba(255, 255, 255, 0.7)" }}
|
||||
/>
|
||||
<Appbar.Action
|
||||
icon="chevron-left"
|
||||
size={26}
|
||||
disabled={!prevChapter}
|
||||
onPress={navigateToPrevChapter}
|
||||
color="#FFFFFF"
|
||||
/>
|
||||
<Appbar.Action
|
||||
icon="chevron-right"
|
||||
size={26}
|
||||
disabled={!nextChapter}
|
||||
onPress={navigateToNextChapter}
|
||||
color="#FFFFFF"
|
||||
/>
|
||||
<Appbar.Action
|
||||
icon="dots-vertical"
|
||||
size={26}
|
||||
onPress={() => readerSheetRef.current.show()}
|
||||
color="#FFFFFF"
|
||||
/>
|
||||
</Appbar.Header>
|
||||
);
|
||||
if (hide) {
|
||||
return null;
|
||||
} else {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
flex: 1,
|
||||
backgroundColor: "rgba(0,0,0,0.6)",
|
||||
width: Dimensions.get("window").width,
|
||||
top: 0,
|
||||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
<Appbar.Header
|
||||
style={{ backgroundColor: "transparent", elevation: 0 }}
|
||||
>
|
||||
<Appbar.BackAction
|
||||
onPress={() => navigation.goBack()}
|
||||
color="#FFFFFF"
|
||||
size={26}
|
||||
style={{ marginRight: 0 }}
|
||||
/>
|
||||
<Appbar.Content
|
||||
title={novelName}
|
||||
titleStyle={{ color: "#FFFFFF" }}
|
||||
subtitle={chapterName}
|
||||
subtitleStyle={{ color: "rgba(255, 255, 255, 0.7)" }}
|
||||
/>
|
||||
<Appbar.Action
|
||||
icon={bookmarked ? "bookmark" : "bookmark-outline"}
|
||||
size={26}
|
||||
onPress={() => {
|
||||
dispatch(
|
||||
bookmarkChapterAction([{ bookmark, chapterId }])
|
||||
);
|
||||
setBookmarked(!bookmarked);
|
||||
}}
|
||||
color="#FFFFFF"
|
||||
/>
|
||||
</Appbar.Header>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ChapterAppbar;
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Dimensions, Pressable, Text, View } from "react-native";
|
||||
import { IconButton } from "react-native-paper";
|
||||
import {
|
||||
getNextChapterFromDB,
|
||||
getPrevChapterFromDB,
|
||||
} from "../../../Database/queries/ChapterQueries";
|
||||
import { showToast } from "../../../Hooks/showToast";
|
||||
|
||||
const ChapterFooter = ({
|
||||
hide,
|
||||
sourceId,
|
||||
novelId,
|
||||
novelUrl,
|
||||
chapterId,
|
||||
theme,
|
||||
readerSheetRef,
|
||||
navigation,
|
||||
novelName,
|
||||
scrollViewRef,
|
||||
}) => {
|
||||
const [nextChapter, setNextChapter] = useState({});
|
||||
const [prevChapter, setPrevChapter] = useState({});
|
||||
|
||||
const setPrevAndNextChap = async () => {
|
||||
const nextChap = await getNextChapterFromDB(novelId, chapterId);
|
||||
const prevChap = await getPrevChapterFromDB(novelId, chapterId);
|
||||
|
||||
setNextChapter(nextChap);
|
||||
setPrevChapter(prevChap);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setPrevAndNextChap();
|
||||
}, []);
|
||||
|
||||
const navigateToPrevChapter = () =>
|
||||
prevChapter
|
||||
? navigation.replace("Chapter", {
|
||||
chapterUrl: prevChapter.chapterUrl,
|
||||
chapterId: prevChapter.chapterId,
|
||||
sourceId,
|
||||
novelUrl,
|
||||
novelId,
|
||||
chapterName: prevChapter.chapterName,
|
||||
novelName,
|
||||
bookmark: prevChapter.bookmark,
|
||||
})
|
||||
: showToast("'There's no previous chapter");
|
||||
|
||||
const navigateToNextChapter = () =>
|
||||
nextChapter
|
||||
? navigation.replace("Chapter", {
|
||||
chapterUrl: nextChapter.chapterUrl,
|
||||
sourceId,
|
||||
novelUrl,
|
||||
novelId,
|
||||
chapterId: nextChapter.chapterId,
|
||||
chapterName: nextChapter.chapterName,
|
||||
novelName,
|
||||
bookmark: nextChapter.bookmark,
|
||||
})
|
||||
: showToast("'There's no next chapter");
|
||||
|
||||
if (hide) {
|
||||
return null;
|
||||
} else {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
position: "absolute",
|
||||
zIndex: 2,
|
||||
bottom: 0,
|
||||
width: Dimensions.get("window").width,
|
||||
backgroundColor: "rgba(0,0,0,0.6)",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
<Pressable
|
||||
android_ripple={{
|
||||
color: theme.rippleColor,
|
||||
borderless: true,
|
||||
radius: 50,
|
||||
}}
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingVertical: 8,
|
||||
}}
|
||||
onPress={navigateToPrevChapter}
|
||||
>
|
||||
<IconButton
|
||||
icon="chevron-left"
|
||||
size={26}
|
||||
disabled={!prevChapter}
|
||||
color="#FFFFFF"
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
android_ripple={{
|
||||
color: theme.rippleColor,
|
||||
borderless: true,
|
||||
radius: 50,
|
||||
}}
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingVertical: 8,
|
||||
}}
|
||||
onPress={() => scrollViewRef.current.scrollTo({})}
|
||||
>
|
||||
<IconButton
|
||||
icon="format-vertical-align-top"
|
||||
size={26}
|
||||
color="#FFFFFF"
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
android_ripple={{
|
||||
color: theme.rippleColor,
|
||||
borderless: true,
|
||||
radius: 50,
|
||||
}}
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingVertical: 8,
|
||||
}}
|
||||
onPress={() => readerSheetRef.current.show()}
|
||||
>
|
||||
<IconButton icon="cog-outline" size={26} color="#FFFFFF" />
|
||||
</Pressable>
|
||||
<Pressable
|
||||
android_ripple={{
|
||||
color: theme.rippleColor,
|
||||
borderless: true,
|
||||
radius: 50,
|
||||
}}
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingVertical: 8,
|
||||
}}
|
||||
onPress={navigateToNextChapter}
|
||||
>
|
||||
<IconButton
|
||||
icon="chevron-right"
|
||||
size={26}
|
||||
disabled={!nextChapter}
|
||||
color="#FFFFFF"
|
||||
/>
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ChapterFooter;
|
||||
@@ -97,6 +97,7 @@ const ReaderSheet = ({
|
||||
style={{
|
||||
backgroundColor: "#000000",
|
||||
marginHorizontal: 10,
|
||||
borderWidth: 0,
|
||||
borderRadius: 50,
|
||||
borderTopRightRadius: 50,
|
||||
borderBottomRightRadius: 50,
|
||||
|
||||
Reference in New Issue
Block a user