From dffb8c80ff21913e116a480e0af6e22407a6a2d5 Mon Sep 17 00:00:00 2001 From: Rajarshee Chatterjee Date: Sat, 2 Jan 2021 22:37:01 +0530 Subject: [PATCH] Merge search and source screen --- src/components/NovelInfoHeader.js | 18 +-- src/navigation/Router.js | 7 - src/screens/Browse.js | 27 +++- src/screens/NovelItem.js | 37 ++--- src/screens/Sources/BoxNovel/BoxNovel.js | 125 +++++++--------- .../Sources/ReadLightNovel/ReadLightNovel.js | 139 +++++++++++------- src/utils/api.js | 28 +++- src/utils/db/NovelQueries.js | 0 8 files changed, 194 insertions(+), 187 deletions(-) create mode 100644 src/utils/db/NovelQueries.js diff --git a/src/components/NovelInfoHeader.js b/src/components/NovelInfoHeader.js index be99135b..0ffeae28 100644 --- a/src/components/NovelInfoHeader.js +++ b/src/components/NovelInfoHeader.js @@ -215,7 +215,7 @@ const NovelInfoHeader = ({ onPress={() => setMore(!more)} ellipsizeMode="clip" > - {/* {novel.novelSummary} */} + {novel.novelSummary} )} - {more && ( + {(more || novel.novelSummary === "") && ( { return ( - ); }; @@ -60,10 +57,6 @@ const ReadLightNovelStack = () => { return ( - ); }; diff --git a/src/screens/Browse.js b/src/screens/Browse.js index 012ee6fc..1d77178b 100644 --- a/src/screens/Browse.js +++ b/src/screens/Browse.js @@ -1,6 +1,6 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import { StyleSheet, View, Text, FlatList, Image } from "react-native"; -import { TouchableRipple, IconButton } from "react-native-paper"; +import { TouchableRipple, IconButton, Button } from "react-native-paper"; import { CustomAppbar } from "../components/Appbar"; import { theme } from "../theming/theme"; import { sources } from "../utils/sources"; @@ -27,8 +27,8 @@ const Browse = ({ navigation }) => { uri: item.sourceCover, }} style={{ - width: 60, - height: 60, + width: 40, + height: 40, borderRadius: 6, }} resizeMode="contain" @@ -47,7 +47,7 @@ const Browse = ({ navigation }) => { style={{ color: theme.textColorPrimaryDark, - fontSize: 16, + fontSize: 14, }} > {item.sourceName} @@ -56,13 +56,14 @@ const Browse = ({ navigation }) => { style={{ color: theme.textColorSecondaryDark, + fontSize: 12, }} > {item.sourceLanguage} - { } ) } - /> + /> */} + diff --git a/src/screens/NovelItem.js b/src/screens/NovelItem.js index 3ada876c..14f6036a 100644 --- a/src/screens/NovelItem.js +++ b/src/screens/NovelItem.js @@ -15,6 +15,8 @@ import ChapterCard from "../components/ChapterCard"; import NovelInfoHeader from "../components/NovelInfoHeader"; import { BottomSheet } from "../components/NovelItemBottomSheet"; +import { getNovelDetails } from "../utils/api"; + import * as SQLite from "expo-sqlite"; const db = SQLite.openDatabase("lnreader.db"); @@ -40,31 +42,14 @@ const NovelItem = ({ route, navigation }) => { const [sort, setSort] = useState(""); const [filter, setFilter] = useState(""); - const getNovel = () => { - fetch( - `https://lnreader-extensions.herokuapp.com/api/${extensionId}/novel/${item.novelUrl}` - ) - .then((response) => response.json()) - .then((json) => { - let novelObj = { - novelSummary: json.novelSummary, - "Author(s)": json["Author(s)"], - "Genre(s)": json["Genre(s)"], - Status: json.Status, - sourceUrl: json.sourceUrl, - source: json.sourceName, - unread: 1, - lastRead: json.novelChapters[0].chapterUrl, - lastReadName: json.novelChapters[0].chapterName, - }; - setNovel(novelObj); - setChapters(json.novelChapters); - setLoading(false); - setRefreshing(false); - insertIntoDb(novelObj, json.novelChapters); - console.log("Setdb"); - }) - .catch((error) => console.error(error)); + const getNovel = (extensionId, novelUrl) => { + getNovelDetails(extensionId, novelUrl).then((response) => { + setNovel(response.novel); + setChapters(response.chapters); + setLoading(false); + setRefreshing(false); + insertIntoDb(response.novel, response.chapters); + }); }; const getChaptersFromDb = () => { @@ -235,7 +220,7 @@ const NovelItem = ({ route, navigation }) => { console.log("Not in db"); // Not in database setlibraryStatus(0); - getNovel(); + getNovel(extensionId, novelUrl); } else { // In database setNovel(res.rows.item(0)); diff --git a/src/screens/Sources/BoxNovel/BoxNovel.js b/src/screens/Sources/BoxNovel/BoxNovel.js index a415b4f3..75b354b9 100644 --- a/src/screens/Sources/BoxNovel/BoxNovel.js +++ b/src/screens/Sources/BoxNovel/BoxNovel.js @@ -20,43 +20,40 @@ import HeaderSearchBar from "../../../components/HeaderSearchBar"; const AllNovels = ({ navigation }) => { const [loading, setLoading] = useState(true); - const [refreshing, setRefreshing] = useState(true); + const [loadingMore, setLoadingMore] = useState(false); - const [novels, setNovels] = useState(); + const [novels, setNovels] = useState([]); const [sort, setSort] = useState("rating"); - const [pageNo, setPageNo] = useState(2); + const [pageNo, setPageNo] = useState(1); const [searchBar, setSearchBar] = useState(false); - const [searchText, setSearchText] = useState(); + const [searchText, setSearchText] = useState(""); + + const [searched, setSearched] = useState(0); const getNovels = () => { - fetch( - `https://lnreader-extensions.herokuapp.com/api/1/novels/1/?o=${sort}` - ) - .then((response) => response.json()) - .then((json) => setNovels(json)) - .catch((error) => console.error(error)) - .finally(() => { - setPageNo(2); - setRefreshing(false); - setLoading(false); - }); - }; - - const loadMore = () => { - setRefreshing(true); fetch( `https://lnreader-extensions.herokuapp.com/api/1/novels/${pageNo}/?o=${sort}` ) .then((response) => response.json()) - .then((json) => setNovels((novels) => novels.concat(json))) - .catch((error) => console.error(error)) - .finally(() => { - setRefreshing(false); + .then((json) => { + setNovels((novels) => novels.concat(json)); setLoading(false); - setPageNo(pageNo + 1); - }); + }) + .finally(() => setPageNo(pageNo + 1)); + }; + + const onEndReached = ({ + layoutMeasurement, + contentOffset, + contentSize, + }) => { + const paddingToBottom = 10; + return ( + layoutMeasurement.height + contentOffset.y >= + contentSize.height - paddingToBottom + ); }; const getSearchResults = (searchText) => { @@ -65,21 +62,16 @@ const AllNovels = ({ navigation }) => { `https://lnreader-extensions.herokuapp.com/api/1/search/?s=${searchText}&?o=rating` ) .then((response) => response.json()) - .then((json) => setNovels(json)) - .catch((error) => console.error(error)) - .finally(() => setLoading(false)); + .then((json) => { + setNovels(json); + setLoading(false); + }); }; useEffect(() => { getNovels(); }, [sort]); - const onRefresh = () => { - setRefreshing(true); - setPageNo(2); - getNovels(); - }; - return ( @@ -104,26 +96,30 @@ const AllNovels = ({ navigation }) => { onPress={() => _panel.show({ velocity: -1.5 })} color={theme.textColorPrimaryDark} /> - onRefresh()} - color={theme.textColorPrimaryDark} - /> ) : ( <> { - setSearchBar(false); - setLoading(true); - getNovels(); + if (searched) { + setLoading(true); + setPageNo(1); + getNovels(); + } else { + setSearchBar(false); + setSearchText(""); + } }} color={theme.textColorPrimaryDark} /> setSearchText(text)} - onSubmitEditing={() => getSearchResults(searchText)} + onSubmitEditing={() => { + setSort("rating"); + getSearchResults(searchText); + setSearched(true); + }} /> {searchText !== "" && ( { showsVerticalScrollIndicator={false} keyExtractor={(item) => item.novelUrl} ListFooterComponent={() => - !searchBar && ( - - - + loadingMore && ( + ) } renderItem={({ item }) => ( @@ -187,14 +168,13 @@ const AllNovels = ({ navigation }) => { } /> )} - refreshControl={ - - } + onScroll={({ nativeEvent }) => { + if (onEndReached(nativeEvent)) { + setLoadingMore(true); + getNovels(); + console.log("End Reached"); + } + }} /> )} @@ -203,7 +183,6 @@ const AllNovels = ({ navigation }) => { bottomSheetRef={(c) => (_panel = c)} setSort={setSort} sort={sort} - setRefreshing={setRefreshing} /> diff --git a/src/screens/Sources/ReadLightNovel/ReadLightNovel.js b/src/screens/Sources/ReadLightNovel/ReadLightNovel.js index 2e527d99..2ef7f6ee 100644 --- a/src/screens/Sources/ReadLightNovel/ReadLightNovel.js +++ b/src/screens/Sources/ReadLightNovel/ReadLightNovel.js @@ -6,23 +6,23 @@ import { ActivityIndicator, RefreshControl, } from "react-native"; -import { - TouchableRipple, - Appbar, - Provider, - Portal, - Button, -} from "react-native-paper"; -import NovelCover from "../../../components/NovelCover"; -import { theme } from "../../../theming/theme"; -import { BottomSheet } from "../../../components/BottomSheet"; +import { Appbar, Provider } from "react-native-paper"; -const AllNovels = ({ navigation }) => { +import NovelCover from "../../../components/NovelCover"; +import HeaderSearchBar from "../../../components/HeaderSearchBar"; + +import { theme } from "../../../theming/theme"; + +const ReadLightNovel = ({ navigation }) => { const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(true); + const [novels, setNovels] = useState(); - const [sort, setSort] = useState("rating"); - const [pageNo, setPageNo] = useState(2); + + const [searchBar, setSearchBar] = useState(false); + const [searchText, setSearchText] = useState(""); + + const [searched, setSearched] = useState(false); const getNovels = () => { fetch(`https://lnreader-extensions.herokuapp.com/api/2/novels/`) @@ -30,64 +30,97 @@ const AllNovels = ({ navigation }) => { .then((json) => setNovels(json)) .catch((error) => console.error(error)) .finally(() => { - setPageNo(2); setRefreshing(false); setLoading(false); }); }; - // const loadMore = () => { - // setRefreshing(true); - // fetch(`https://lnreader-extensions.herokuapp.com/api/1/novels/${pageNo}/?o=${sort}`) - // .then((response) => response.json()) - // .then((json) => setNovels((novels) => novels.concat(json))) - // .catch((error) => console.error(error)) - // .finally(() => { - // setRefreshing(false); - // setLoading(false); - // setPageNo(pageNo + 1); - // }); - // }; + const getSearchResults = (searchText) => { + setLoading(true); + fetch( + `https://lnreader-extensions.herokuapp.com/api/2/search/?s=${searchText}` + ) + .then((response) => response.json()) + .then((json) => { + setNovels(json); + setLoading(false); + }); + }; useEffect(() => { getNovels(); - }, [sort]); + }, []); const onRefresh = () => { setRefreshing(true); - setPageNo(2); getNovels(); }; return ( - navigation.goBack()} /> + {!searchBar ? ( + <> + navigation.goBack()} + /> - - - navigation.navigate("ReadLightNovelStack", { - screen: "ReadLightNovelSearch", - }) - } - /> - _panel.show({ velocity: -1.5 })} - /> - onRefresh()} /> + + setSearchBar(true)} + /> + + + ) : ( + <> + { + if (searched) { + setLoading(true); + getNovels(); + } else { + setSearchBar(false); + setSearchText(""); + } + }} + color={theme.textColorPrimaryDark} + /> + setSearchText(text)} + onSubmitEditing={() => { + getSearchResults(searchText); + setSearched(true); + }} + /> + {searchText !== "" && ( + { + setSearchText(""); + }} + color={theme.textColorPrimaryDark} + /> + )} + + )} {loading ? ( @@ -142,19 +175,11 @@ const AllNovels = ({ navigation }) => { /> )} - - (_panel = c)} - setSort={setSort} - sort={sort} - setRefreshing={setRefreshing} - /> - ); }; -export default AllNovels; +export default ReadLightNovel; const styles = StyleSheet.create({ container: { diff --git a/src/utils/api.js b/src/utils/api.js index e3f2e247..d0ef9519 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -1,12 +1,24 @@ -import cheerio from "cheerio-without-node-native"; +export const getNovelDetails = (extensionId, novelUrl) => { + const url = `https://lnreader-extensions.herokuapp.com/api/${extensionId}/novel/${novelUrl}`; -const baseUrl = "https://boxnovel.com/"; + return fetch(url) + .then((response) => response.json()) + .then((json) => { + let novel = { + novelSummary: json.novelSummary, + "Author(s)": json["Author(s)"], + "Genre(s)": json["Genre(s)"], + Status: json.Status, + sourceUrl: json.sourceUrl, + source: json.sourceName, + unread: 1, + lastRead: json.novelChapters[0].chapterUrl, + lastReadName: json.novelChapters[0].chapterName, + }; -export const getLatest = async () => { - const response = await fetch(baseUrl); // fetch page - const htmlString = await response.text(); // get response text - const $ = cheerio.load(htmlString); // parse HTML string - let title = $("title"); + let chapters = json.novelChapters; - console.log(title.text()); + return { novel, chapters }; + }) + .catch((error) => console.error(error)); }; diff --git a/src/utils/db/NovelQueries.js b/src/utils/db/NovelQueries.js new file mode 100644 index 00000000..e69de29b