From 22f9533d205c3eba39867ff44a9198741d65d337 Mon Sep 17 00:00:00 2001 From: Rajarshee Chatterjee Date: Thu, 24 Dec 2020 10:03:21 +0530 Subject: [PATCH] Add chapter screen --- package-lock.json | 18 +++ package.json | 2 + src/navigation/Router.js | 8 ++ src/screens/ChapterItem.js | 119 +++++++++++++++++ src/screens/NovelItem.js | 266 +++++++++++++++++++++++++++++++------ src/theming/theme.js | 9 ++ 6 files changed, 384 insertions(+), 38 deletions(-) create mode 100644 src/screens/ChapterItem.js create mode 100644 src/theming/theme.js diff --git a/package-lock.json b/package-lock.json index ec85fe4e..75fdc685 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3766,6 +3766,11 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "optional": true }, + "fast-memoize": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==" + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -7124,6 +7129,14 @@ } } }, + "react-native-collapsible-header-views": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-native-collapsible-header-views/-/react-native-collapsible-header-views-1.1.2.tgz", + "integrity": "sha512-HjhIKkJa3tkPC6i1G9hh9IdjiG4Df2aB3jU1z1RbNIWBqrCa83BfkstwtbzeAADJVkTBkLTldDd6EbMybbm0DA==", + "requires": { + "fast-memoize": "^2.5.1" + } + }, "react-native-gesture-handler": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.8.0.tgz", @@ -7150,6 +7163,11 @@ "react-native-iphone-x-helper": "^1.3.1" } }, + "react-native-read-more-text": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-native-read-more-text/-/react-native-read-more-text-1.1.2.tgz", + "integrity": "sha512-FIQhOpvikUanwPRl9QVBYmx6Wx7IXxXH/jlzElOLcP+NSgFLw2fRzSekQUq0yicymZsi7cAWW5TtIj8FHWtNDw==" + }, "react-native-reanimated": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-1.13.2.tgz", diff --git a/package.json b/package.json index 851b59f1..cac01181 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,10 @@ "react": "16.13.1", "react-dom": "16.13.1", "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz", + "react-native-collapsible-header-views": "^1.1.2", "react-native-gesture-handler": "~1.8.0", "react-native-paper": "^4.5.0", + "react-native-read-more-text": "^1.1.2", "react-native-reanimated": "~1.13.0", "react-native-safe-area-context": "3.1.9", "react-native-screens": "~2.15.0", diff --git a/src/navigation/Router.js b/src/navigation/Router.js index 9f1920b8..3f88a363 100644 --- a/src/navigation/Router.js +++ b/src/navigation/Router.js @@ -10,6 +10,7 @@ import Latest from "../screens/Latest"; import More from "../screens/More"; import Search from "../screens/Search"; import NovelItem from "../screens/NovelItem"; +import ChapterItem from "../screens/ChapterItem"; const Stack = createStackNavigator(); @@ -70,6 +71,13 @@ const SearchStack = () => { headerShown: false, }} /> + ); }; diff --git a/src/screens/ChapterItem.js b/src/screens/ChapterItem.js new file mode 100644 index 00000000..204d1211 --- /dev/null +++ b/src/screens/ChapterItem.js @@ -0,0 +1,119 @@ +import React, { useState, useEffect } from "react"; +import { + StyleSheet, + View, + Image, + ImageBackground, + Text, + FlatList, + ScrollView, + RefreshControl, +} from "react-native"; +import { Appbar } from "react-native-paper"; +import { theme } from "../theming/theme"; + +const ChapterItem = ({ route, navigation }) => { + const { chapterName, chapterUrl } = route.params; + + const [loading, setLoading] = useState(true); + const [refreshing, setRefreshing] = useState(true); + + const [chapter, setChapter] = useState(); + + useEffect(() => { + getChapter(); + }, []); + + const getChapter = () => { + fetch(`http://192.168.1.38:5000/api/${chapterUrl}`) + .then((response) => response.json()) + .then((json) => setChapter(json)) + .catch((error) => console.error(error)) + .finally(() => { + setRefreshing(false); + setLoading(false); + }); + }; + + const onRefresh = async () => { + setRefreshing(true); + getChapter(); + }; + return ( + <> + + { + navigation.goBack(); + }} + color={"white"} + size={26} + style={{ marginRight: 0 }} + /> + + {!loading && ( + <> + { + navigation.navigate("ChapterItem", { + chapterUrl: chapter.prevChapter, + }); + }} + color={"white"} + /> + { + navigation.navigate("ChapterItem", { + chapterUrl: chapter.nextChapter, + }); + }} + color={"white"} + /> + + )} + + + } + > + {!loading && ( + + {chapter.chapterText.trim()} + + )} + + + ); +}; + +export default ChapterItem; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "#202125", + paddingHorizontal: 10, + paddingVertical: 10, + }, +}); diff --git a/src/screens/NovelItem.js b/src/screens/NovelItem.js index 42770238..4fb2419d 100644 --- a/src/screens/NovelItem.js +++ b/src/screens/NovelItem.js @@ -3,33 +3,49 @@ import { StyleSheet, View, Image, - ActivityIndicator, ImageBackground, Text, FlatList, + ScrollView, + RefreshControl, } from "react-native"; -import { Appbar } from "react-native-paper"; +import { Appbar, TouchableRipple } from "react-native-paper"; import { LinearGradient } from "expo-linear-gradient"; -import { ScrollView } from "react-native-gesture-handler"; + +import { theme } from "../theming/theme"; const NovelItem = ({ route, navigation }) => { const item = route.params; const [loading, setLoading] = useState(true); - const [novel, setNovel] = useState(); + const [refreshing, setRefreshing] = useState(true); - useEffect(() => { + const [novel, setNovel] = useState(); + const [more, setMore] = useState(false); + + const getNovel = () => { fetch(`http://192.168.1.38:5000/api/novel/${item.novelUrl}`) .then((response) => response.json()) .then((json) => setNovel(json)) .catch((error) => console.error(error)) .finally(() => { + setRefreshing(false); setLoading(false); }); + }; + + useEffect(() => { + getNovel(); }, []); + + const onRefresh = async () => { + setRefreshing(true); + getNovel(); + }; + return ( <> - + { navigation.goBack(); @@ -40,10 +56,20 @@ const NovelItem = ({ route, navigation }) => { /> - + + } + > { }} style={styles.logo} /> + + + {item.novelName} + + {!loading && ( + <> + + {novel.novelDetails[ + "Alternative" + ].replace(",", ", ")} + + + {novel.novelDetails[ + "Author(s)" + ].replace(",", ", ")} + + + {novel.novelDetails["Release"]} + + + {novel.novelDetails["Status"] + + " • " + + novel.novelDetails["Type"]} + + + )} + - {loading ? ( - - - - ) : ( + {!loading && ( <> + + + About + + setMore(!more)} + ellipsizeMode="clip" + > + {novel.novelSummary} + + setMore(!more)} + > + {more ? "Less" : "More"} + + + + item} + renderItem={({ item }) => ( + + {item} + + )} + /> + + + {novel.novelChapters.length + " Chapters"} + item.chapterUrl} + removeClippedSubviews={true} + maxToRenderPerBatch={10} + initialNumToRender={10} renderItem={({ item }) => ( - <> - - {item.chapterName} - - - {item.releaseDate} - - + + navigation.navigate("ChapterItem", { + chapterName: item.chapterName, + chapterUrl: item.chapterUrl, + }) + } + rippleColor={theme.rippleColorDark} + > + <> + + {item.chapterName} + + + {item.releaseDate} + + + )} /> @@ -115,6 +285,12 @@ const styles = StyleSheet.create({ flex: 1, backgroundColor: "#202125", }, + nameContainer: { + flex: 1, + width: "100%", + marginHorizontal: 15, + // justifyContent: "center", + }, background: { height: 240, }, @@ -125,7 +301,7 @@ const styles = StyleSheet.create({ detailsContainer: { flex: 1, flexDirection: "row", - margin: 17, + margin: 15, }, logo: { height: 180, @@ -133,4 +309,18 @@ const styles = StyleSheet.create({ margin: 3.2, borderRadius: 6, }, + genre: { + borderRadius: 24, + borderWidth: 1, + paddingHorizontal: 10, + marginHorizontal: 2, + fontSize: 13, + paddingVertical: 1, + justifyContent: "center", + flex: 1, + }, + name: { + fontWeight: "bold", + fontSize: 20, + }, }); diff --git a/src/theming/theme.js b/src/theming/theme.js new file mode 100644 index 00000000..c41af600 --- /dev/null +++ b/src/theming/theme.js @@ -0,0 +1,9 @@ +export const theme = { + colorDarkPrimary: "#242529", + colorDarkPrimaryDark: "#202125", + colorAccentDark: "#3399FF", + textColorPrimaryDark: "#FFFFFF", + textColorSecondaryDark: "rgba(265,265,265,0.7)", + textColorHintDark: "rgba(265,265,265,0.5)", + rippleColorDark: "rgba(265,265,265,0.2)", +};