Add jump to chapter
This commit is contained in:
@@ -38,6 +38,7 @@ import ChaptersSettingsSheet from "./components/ChaptersSettingsSheet";
|
||||
import TrackSheet from "./components/Tracker/TrackSheet";
|
||||
import ChapterActionsSheet from "./components/ChapterActionsSheet";
|
||||
import { Row } from "../../components/Common";
|
||||
import JumpToChapterModal from "./components/JumpToChapterModal";
|
||||
|
||||
const Novel = ({ route, navigation }) => {
|
||||
const item = route.params;
|
||||
@@ -51,6 +52,7 @@ const Novel = ({ route, navigation }) => {
|
||||
const [selected, setSelected] = useState([]);
|
||||
const [downloadMenu, showDownloadMenu] = useState(false);
|
||||
|
||||
let flatlistRef = useRef(null);
|
||||
let chaptersSettingsSheetRef = useRef(null);
|
||||
let trackerSheetRef = useRef(null);
|
||||
let chapterActionsSheetRef = useRef(null);
|
||||
@@ -86,6 +88,8 @@ const Novel = ({ route, navigation }) => {
|
||||
/>
|
||||
);
|
||||
|
||||
const [jumpToChapterModal, showJumpToChapterModal] = useState(false);
|
||||
|
||||
const renderItem = ({ item, index }) => (
|
||||
<ChapterItem
|
||||
theme={theme}
|
||||
@@ -231,10 +235,21 @@ const Novel = ({ route, navigation }) => {
|
||||
})
|
||||
}
|
||||
/>
|
||||
<IconButton
|
||||
icon="text-box-search-outline"
|
||||
color="white"
|
||||
size={21}
|
||||
style={{
|
||||
marginTop: StatusBar.currentHeight + 8,
|
||||
marginRight: 16,
|
||||
}}
|
||||
onPress={() => showJumpToChapterModal(true)}
|
||||
/>
|
||||
</Row>
|
||||
</View>
|
||||
)}
|
||||
<FlatList
|
||||
ref={(ref) => (flatlistRef.current = ref)}
|
||||
data={!loading && chapters}
|
||||
keyExtractor={(item) => item.chapterId.toString()}
|
||||
removeClippedSubviews={true}
|
||||
@@ -362,6 +377,14 @@ const Novel = ({ route, navigation }) => {
|
||||
)}
|
||||
{!loading && (
|
||||
<Portal>
|
||||
<JumpToChapterModal
|
||||
modalVisible={jumpToChapterModal}
|
||||
hideModal={() => showJumpToChapterModal(false)}
|
||||
theme={theme}
|
||||
chapters={chapters}
|
||||
novel={novel}
|
||||
navigation={navigation}
|
||||
/>
|
||||
<ChaptersSettingsSheet
|
||||
novelUrl={novelUrl}
|
||||
bottomSheetRef={chaptersSettingsSheetRef}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
import React, { useState } from "react";
|
||||
import { StyleSheet, Text, View } from "react-native";
|
||||
|
||||
import { Modal, Portal, Switch, TextInput } from "react-native-paper";
|
||||
|
||||
const JumpToChapterModal = ({
|
||||
theme,
|
||||
hideModal,
|
||||
modalVisible,
|
||||
chapters,
|
||||
navigation,
|
||||
novel,
|
||||
}) => {
|
||||
const [mode, setMode] = useState(0);
|
||||
|
||||
const [text, setText] = useState();
|
||||
const [error, setError] = useState();
|
||||
|
||||
const onDismiss = () => {
|
||||
hideModal();
|
||||
setText();
|
||||
setError();
|
||||
};
|
||||
|
||||
const onSubmit = () => {
|
||||
if (!mode) {
|
||||
if (text <= chapters.length) {
|
||||
navigation.navigate("Chapter", {
|
||||
sourceId: novel.sourceId,
|
||||
novelUrl: novel.novelUrl,
|
||||
novelId: novel.novelId,
|
||||
chapterId: chapters[text - 1].chapterId,
|
||||
chapterUrl: chapters[text - 1].chapterUrl,
|
||||
chapterName: chapters[text - 1].chapterName,
|
||||
novelName: novel.novelName,
|
||||
bookmark: chapters[text - 1].bookmark,
|
||||
});
|
||||
hideModal();
|
||||
} else {
|
||||
setError(
|
||||
`Enter a valid chapter number (<= ${chapters.length})`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const chapter = chapters.find((chap) =>
|
||||
chap.chapterName.includes(text)
|
||||
);
|
||||
|
||||
if (chapter) {
|
||||
navigation.navigate("Chapter", {
|
||||
sourceId: novel.sourceId,
|
||||
novelUrl: novel.novelUrl,
|
||||
novelId: chapter.novelId,
|
||||
chapterId: chapter.chapterId,
|
||||
chapterUrl: chapter.chapterUrl,
|
||||
chapterName: chapter.chapterName,
|
||||
novelName: novel.novelName,
|
||||
bookmark: chapter.bookmark,
|
||||
});
|
||||
hideModal();
|
||||
} else {
|
||||
setError(`Enter a valid chapter name`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onChangeText = (text) => setText(text);
|
||||
|
||||
const textInputTheme = {
|
||||
colors: {
|
||||
primary: theme.colorAccent,
|
||||
placeholder: theme.textColorHint,
|
||||
text: theme.textColorPrimary,
|
||||
background: theme.colorPrimary,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<Modal
|
||||
visible={modalVisible}
|
||||
onDismiss={onDismiss}
|
||||
contentContainerStyle={[
|
||||
styles.modalContainer,
|
||||
{ backgroundColor: theme.colorPrimary },
|
||||
]}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.modalTitle,
|
||||
{ color: theme.textColorPrimary },
|
||||
]}
|
||||
>
|
||||
Jump to Chapter
|
||||
</Text>
|
||||
<TextInput
|
||||
value={text}
|
||||
placeholder={
|
||||
mode
|
||||
? "Chapter Name"
|
||||
: `Chapter Number (<= ${chapters.length})`
|
||||
}
|
||||
onChangeText={onChangeText}
|
||||
onSubmitEditing={onSubmit}
|
||||
mode="outlined"
|
||||
theme={textInputTheme}
|
||||
underlineColor={theme.textColorHint}
|
||||
dense
|
||||
error={error}
|
||||
/>
|
||||
<Text style={styles.errorText}>{error}</Text>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: theme.textColorPrimary }}>
|
||||
Chapter Name
|
||||
</Text>
|
||||
<Switch
|
||||
value={mode}
|
||||
onValueChange={() => setMode(!mode)}
|
||||
color={theme.colorAccent}
|
||||
/>
|
||||
</View>
|
||||
</Modal>
|
||||
</Portal>
|
||||
);
|
||||
};
|
||||
|
||||
export default JumpToChapterModal;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
modalContainer: {
|
||||
margin: 30,
|
||||
padding: 20,
|
||||
borderRadius: 8,
|
||||
},
|
||||
modalTitle: {
|
||||
fontSize: 18,
|
||||
marginBottom: 16,
|
||||
},
|
||||
errorText: {
|
||||
color: "#FF0033",
|
||||
paddingTop: 8,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user