From 99376b1fc41787bf83c1caea03a04255b99cbe55 Mon Sep 17 00:00:00 2001 From: Rajarshee Chatterjee Date: Sat, 26 Dec 2020 17:19:30 +0530 Subject: [PATCH] Rewrite NovelItem Screen --- App.js | 21 ++ src/navigation/Router.js | 6 + src/screens/Library.js | 36 +-- src/screens/LibraryNovelItem.js | 122 +++++--- src/screens/NovelItem.js | 13 - src/screens/NovelItemRewrite.js | 507 ++++++++++++++++++++++++++++++++ src/screens/Updates.js | 5 +- 7 files changed, 633 insertions(+), 77 deletions(-) create mode 100644 src/screens/NovelItemRewrite.js diff --git a/App.js b/App.js index 6b8e80eb..4d41cb44 100644 --- a/App.js +++ b/App.js @@ -1,3 +1,5 @@ +console.disableYellowBox = true; + import React, { useState, useEffect } from "react"; import Router from "./src/navigation/Router"; import { NavigationContainer } from "@react-navigation/native"; @@ -5,6 +7,9 @@ import { StatusBar } from "expo-status-bar"; import * as Font from "expo-font"; import AppLoading from "expo-app-loading"; +import * as SQLite from "expo-sqlite"; +const db = SQLite.openDatabase("lnreader.db"); + const getFonts = () => Font.loadAsync({ "pt-sans-bold": require("./assets/fonts/PTSansNarrow-Bold.ttf"), @@ -13,6 +18,22 @@ const getFonts = () => export default function App() { const [fontsLoaded, setFontsLoaded] = useState(false); + const createTables = () => + db.transaction((tx) => { + tx.executeSql( + "CREATE TABLE IF NOT EXISTS LibraryTable (novelUrl VARCHAR(255) NOT NULL PRIMARY KEY, novelName VARCHAR(255), novelCover VARCHAR(255), novelSummary TEXT, Alternative VARCHAR(255), `Author(s)` VARCHAR(255), `Genre(s)` VARCHAR(255), Type VARCHAR(255), `Release` VARCHAR(255), Status VARCHAR(255))" + ); + console.log("Library Table Created"); + + tx.executeSql( + "CREATE TABLE IF NOT EXISTS ChapterTable (chapterUrl VARCHAR(255), chapterName VARCHAR(255), releaseDate VARCHAR(255), novelUrl VARCHAR(255), FOREIGN KEY (novelUrl) REFERENCES LibraryTable(novelUrl) ON DELETE CASCADE)" + ); + }); + + useEffect(() => { + createTables(); + }); + if (fontsLoaded) { return ( <> diff --git a/src/navigation/Router.js b/src/navigation/Router.js index 1e13352d..393533d1 100644 --- a/src/navigation/Router.js +++ b/src/navigation/Router.js @@ -15,6 +15,7 @@ import ChapterItem from "../screens/ChapterItem"; import About from "../screens/About"; import LibraryNovelItem from "../screens/LibraryNovelItem"; import { theme } from "../theming/theme"; +import NovelItemRewrite from "../screens/NovelItemRewrite"; const Stack = createStackNavigator(); @@ -172,6 +173,11 @@ const MainStack = () => { + + { }); }; - // const deleted = () => { - // db.transaction((tx) => { - // tx.executeSql( - // "DROP TABLE LibraryTable", - // null, - // (txObj, { rows: { _array } }) => { - // console.log("DELETED TABLE"); - // }, - // (txObj, error) => console.log("Error ", error) - // ); - // }); - // setNovels([]); - // }; + const deleted = () => { + db.transaction((tx) => { + tx.executeSql( + "DROP TABLE LibraryTable", + null, + (txObj, { rows: { _array } }) => { + console.log("DELETED TABLE"); + }, + (txObj, error) => console.log("Error ", error) + ); + }); + setNovels([]); + }; useFocusEffect( useCallback(() => { @@ -110,7 +110,7 @@ const UpdatesScreen = ({ navigation }) => { numColumns={3} data={novels} showsVerticalScrollIndicator={false} - keyExtractor={(item) => item.novelId} + keyExtractor={(item) => item.novelUrl} renderItem={({ item }) => ( { style={styles.opac} onPress={() => navigation.navigate( - "LibraryNovelItem", + "NovelItemRewrite", item ) } @@ -139,9 +139,9 @@ const UpdatesScreen = ({ navigation }) => { } /> )} - {/* */} + )} diff --git a/src/screens/LibraryNovelItem.js b/src/screens/LibraryNovelItem.js index 1aad8e43..e3b3f342 100644 --- a/src/screens/LibraryNovelItem.js +++ b/src/screens/LibraryNovelItem.js @@ -8,6 +8,7 @@ import { FlatList, ScrollView, RefreshControl, + ToastAndroid, } from "react-native"; import { Appbar, @@ -36,19 +37,20 @@ const NovelItem = ({ route, navigation }) => { const fetchNovel = () => { db.transaction((tx) => { tx.executeSql( - "SELECT * FROM LibraryTable WHERE novelId=?", - [item.novelId], + "SELECT * FROM LibraryTable WHERE novelUrl=?", + [item.novelUrl], (txObj, { rows: { _array } }) => { setNovel(_array); - setRefreshing(false); }, (txObj, error) => console.log("Error ", error) ); tx.executeSql( - "SELECT * FROM ChapterTable WHERE novelId=?", - [item.novelId], + "SELECT * FROM ChapterTable WHERE novelUrl=?", + [item.novelUrl], (txObj, { rows: { _array } }) => { setChapters(_array); + // !_array.length && getChapters(); + setRefreshing(false); setLoading(false); }, (txObj, error) => console.log("Error ", error) @@ -56,18 +58,27 @@ const NovelItem = ({ route, navigation }) => { }); }; + // const getChapters = () => { + // fetch(`http://192.168.1.39:5000/api/novel/${item.novelUrl}`) + // .then((response) => response.json()) + // .then((json) => { + // setChapters(json.novelChapters); + // }) + // .catch((error) => console.error(error)); + // }; + const checkIfExistsInLibrary = (id) => { db.transaction((tx) => { tx.executeSql( - "SELECT * FROM LibraryTable WHERE novelId=?", + "SELECT * FROM LibraryTable WHERE novelUrl=?", [id], (txObj, res) => { - console.log(res.rows.length); + // console.log(res.rows.length); if (res.rows.length === 0) { - console.log("Not In Library"); + // console.log("Not In Library"); setlibraryStatus(0); } else { - console.log("In Library"); + // console.log("In Library"); setlibraryStatus(1); } }, @@ -79,8 +90,8 @@ const NovelItem = ({ route, navigation }) => { const sortChapters = () => { db.transaction((tx) => { tx.executeSql( - "SELECT * FROM ChapterTable WHERE novelId=? ORDER BY chapterName ASC", - [item.novelId], + "SELECT * FROM ChapterTable WHERE novelUrl=? ORDER BY chapterName ASC", + [item.novelUrl], (txObj, { rows: { _array } }) => { setChapters(_array); setLoading(false); @@ -94,57 +105,71 @@ const NovelItem = ({ route, navigation }) => { if (libraryStatus === 0) { db.transaction((tx) => { tx.executeSql( - "INSERT INTO LibraryTable (novelId, novelName, novelCover, novelSummary, alternative, author, genre, type, releaseDate, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + "INSERT INTO LibraryTable (novelUrl, novelName, novelCover, novelSummary, alternative, author, genre, type, releaseDate, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [ - item.novelId, + item.novelUrl, item.novelName, item.novelCover, item.novelSummary, - item.alternative, - item.author, - item.genre, - item.type, - item.releaseDate, - item.status, - ] + item.Alternative, + item["Author(s)"], + item["Genres(s)"], + item.Type, + item.Release, + item.Status, + ], + (txObj, res) => { + console.log("Novel Inserted"); + }, + (txObj, error) => console.log("Error ", error) ); - console.log("Inserted Novel"); - // chapters.map((chap) => - // tx.executeSql( - // "INSERT INTO ChapterTable (chapterId, chapterName, releaseDate, novelId) values (?, ?, ?, ?)", - // [ - // chap.chapterId, - // chap.chapterName, - // chap.releaseDate, - // item.novelId, - // ] - // ) - // ); + chapters.map((chap) => + tx.executeSql( + "INSERT INTO ChapterTable (chapterUrl, chapterName, releaseDate, novelUrl) values (?, ?, ?, ?)", + [ + chap.chapterUrl, + chap.chapterName, + chap.releaseDate, + item.novelUrl, + ], + (txObj, res) => { + // console.log("Chapters Inserted"); + }, + (txObj, error) => console.log("Error ", error) + ) + ); setlibraryStatus(1); + ToastAndroid.show("Added to library", ToastAndroid.SHORT); }); } else { db.transaction((tx) => { tx.executeSql( - "DELETE FROM LibraryTable WHERE novelId=?", - [item.novelId], + "DELETE FROM LibraryTable WHERE novelUrl=?", + [item.novelUrl], (txObj, res) => { console.log("DELETED NOVEL FROM TABLE"); }, (txObj, error) => console.log("Error ", error) ); - // tx.executeSql("DELETE FROM ChapterTable WHERE novelId=?", [ - // item.novelId, - // ]); + tx.executeSql( + "DELETE FROM ChapterTable WHERE novelUrl=?", + [item.novelUrl], + (txObj, res) => { + console.log("DELETED Chapters FROM TABLE"); + }, + (txObj, error) => console.log("Error ", error) + ); console.log("Removed Novel"); setlibraryStatus(0); + ToastAndroid.show("Removed from library", ToastAndroid.SHORT); }); } }; useEffect(() => { fetchNovel(); - checkIfExistsInLibrary(item.novelId); + checkIfExistsInLibrary(item.novelUrl); }, []); const onRefresh = async () => { @@ -218,7 +243,7 @@ const NovelItem = ({ route, navigation }) => { }} numberOfLines={1} > - {item.alternative.replace( + {item.Alternative.replace( ",", ", " )} @@ -231,7 +256,10 @@ const NovelItem = ({ route, navigation }) => { fontSize: 15, }} > - {item.author.replace(",", ", ")} + {item["Author(s)"].replace( + ",", + ", " + )} { fontSize: 15, }} > - {item.releaseDate} + {item.Release} { fontSize: 15, }} > - {item.status + " • " + item.type} + {item.Status + " • " + item.Type} )} @@ -328,7 +356,7 @@ const NovelItem = ({ route, navigation }) => { marginBottom: 15, }} horizontal - data={item.genre.split(",")} + data={item["Genre(s)"].split(",")} keyExtractor={(item) => item} renderItem={({ item }) => ( { data={chapters} extraData={chapters} showsVerticalScrollIndicator={false} - keyExtractor={(item) => item.chapterId} + keyExtractor={(item) => + item.chapterUrl + ? item.chapterUrl + : item.chapterUrl + } removeClippedSubviews={true} maxToRenderPerBatch={10} initialNumToRender={10} @@ -392,7 +424,7 @@ const NovelItem = ({ route, navigation }) => { }} onPress={() => navigation.navigate("ChapterItem", { - chapterUrl: item.chapterId, + chapterUrl: item.chapterUrl, }) } rippleColor={theme.rippleColorDark} diff --git a/src/screens/NovelItem.js b/src/screens/NovelItem.js index 8801bda5..f1ea6839 100644 --- a/src/screens/NovelItem.js +++ b/src/screens/NovelItem.js @@ -101,18 +101,6 @@ const NovelItem = ({ route, navigation }) => { } }; - const createTables = () => - db.transaction((tx) => { - tx.executeSql( - "CREATE TABLE IF NOT EXISTS LibraryTable (novelId VARCHAR(255) NOT NULL PRIMARY KEY, novelName VARCHAR(255), novelCover VARCHAR(255), novelSummary TEXT, alternative VARCHAR(255), author VARCHAR(255), genre VARCHAR(255), type VARCHAR(255), releaseDate VARCHAR(255), status VARCHAR(255))" - ); - console.log("Library Table Created"); - - tx.executeSql( - "CREATE TABLE IF NOT EXISTS ChapterTable (chapterId VARCHAR(255), chapterName VARCHAR(255), releaseDate VARCHAR(255), novelId VARCHAR(255), FOREIGN KEY (novelId) REFERENCES LibraryTable(novelId) ON DELETE CASCADE)" - ); - }); - const checkIfExistsInLibrary = (id) => { db.transaction((tx) => { tx.executeSql( @@ -134,7 +122,6 @@ const NovelItem = ({ route, navigation }) => { }; useEffect(() => { - createTables(); getNovel(); }, []); diff --git a/src/screens/NovelItemRewrite.js b/src/screens/NovelItemRewrite.js new file mode 100644 index 00000000..b0bd9ace --- /dev/null +++ b/src/screens/NovelItemRewrite.js @@ -0,0 +1,507 @@ +import React, { useState, useEffect } from "react"; +import { + StyleSheet, + View, + Image, + ImageBackground, + Text, + FlatList, + ScrollView, + RefreshControl, +} from "react-native"; +import { + Appbar, + TouchableRipple, + IconButton, + Button, +} from "react-native-paper"; +import { LinearGradient } from "expo-linear-gradient"; + +import { theme } from "../theming/theme"; + +import * as SQLite from "expo-sqlite"; +const db = SQLite.openDatabase("lnreader.db"); + +const NovelItem = ({ route, navigation }) => { + const item = route.params; + + const [loading, setLoading] = useState(true); + const [refreshing, setRefreshing] = useState(false); + + const [novel, setNovel] = useState(item); + const [chapters, setChapters] = useState(); + const [more, setMore] = useState(false); + + const [libraryStatus, setlibraryStatus] = useState(); + // const [dbFlag, setDbFlag] = useState(0); + + const getNovel = () => { + fetch(`http://192.168.1.39:5000/api/novel/${item.novelUrl}`) + .then((response) => response.json()) + .then((json) => { + setNovel(json); + setChapters(json.novelChapters); + }) + .catch((error) => console.error(error)) + .finally(() => { + setRefreshing(false); + setLoading(false); + }); + }; + + const getNovelFromDb = () => { + db.transaction((tx) => { + // tx.executeSql( + // "SELECT * FROM LibraryTable WHERE novelUrl=?", + // [item.novelUrl], + // (txObj, { rows: _array }) => { + // // setNovel(_array); + // // console.log(_array); + // }, + // (txObj, error) => console.log("Error ", error) + // ); + tx.executeSql( + "SELECT * FROM ChapterTable WHERE novelUrl=?", + [item.novelUrl], + (txObj, { rows: { _array } }) => { + setChapters(_array); + // console.log(_array); + setRefreshing(false); + setLoading(false); + }, + (txObj, error) => console.log("Error ", error) + ); + }); + }; + + const insertToLibrary = () => { + if (libraryStatus === 0) { + db.transaction((tx) => { + tx.executeSql( + "INSERT INTO LibraryTable (novelUrl, novelName, novelCover, novelSummary, Alternative, `Author(s)`, `Genre(s)`, Type, `Release`, Status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + [ + item.novelUrl, + novel.novelName, + novel.novelCover, + novel.novelSummary, + novel.Alternative, + novel["Author(s)"], + novel["Genre(s)"], + novel.Type, + novel.Release, + novel.Status, + ], + (tx, res) => console.log("Inserted Novel"), + (txObj, error) => console.log("Error ", error) + ); + + chapters.map((chap) => + tx.executeSql( + "INSERT INTO ChapterTable (chapterUrl, chapterName, releaseDate, novelUrl) values (?, ?, ?, ?)", + [ + chap.chapterUrl, + chap.chapterName, + chap.releaseDate, + item.novelUrl, + ] + ) + ); + setlibraryStatus(1); + }); + } else { + db.transaction((tx) => { + tx.executeSql( + "DELETE FROM LibraryTable WHERE novelUrl=?", + [item.novelUrl], + (txObj, res) => { + console.log("DELETED NOVEL FROM TABLE"); + }, + (txObj, error) => console.log("Error ", error) + ); + tx.executeSql("DELETE FROM ChapterTable WHERE novelUrl=?", [ + item.novelUrl, + ]); + console.log("Removed Novel"); + setlibraryStatus(0); + }); + } + }; + + const checkIfExistsInLibrary = (id) => { + db.transaction((tx) => { + tx.executeSql( + "SELECT * FROM LibraryTable WHERE novelUrl=?", + [id], + (txObj, res) => { + console.log(res.rows.length); + if (res.rows.length === 0) { + console.log("Not In Library"); + getNovel(); + setlibraryStatus(0); + } else { + console.log("In Library"); + getNovelFromDb(); + setlibraryStatus(1); + } + }, + (txObj, error) => console.log("Error ", error) + ); + }); + }; + + useEffect(() => { + checkIfExistsInLibrary(item.novelUrl); + }, []); + + const onRefresh = async () => { + setRefreshing(true); + checkIfExistsInLibrary(item.novelUrl); + }; + + return ( + <> + + { + navigation.goBack(); + }} + color={"white"} + size={26} + style={{ marginRight: 0 }} + /> + + + + + } + > + + + + + + + {item.novelName} + + {!loading && ( + <> + + {novel.Alternative.replace( + ",", + ", " + )} + + + {novel["Author(s)"].replace( + ",", + ", " + )} + + + {novel["Release"]} + + + {novel["Status"] + + " • " + + novel["Type"]} + + + )} + + + + + {!loading && ( + <> + + {/* */} + {novel.novelSummary.length > 0 && ( + + + About + + setMore(!more)} + ellipsizeMode="clip" + > + {novel.novelSummary} + + setMore(!more)} + > + {more ? "Less" : "More"} + + + )} + item} + renderItem={({ item }) => ( + + {item} + + )} + /> + + + // setChapters((chapters) => chapters.reverse()) + // } + rippleColor={theme.rippleColorDark} + > + <> + + {chapters.length + " Chapters"} + + + // setChapters((chapters) => + // chapters.reverse() + // ) + // } + /> + + + novel.chapterUrl} + removeClippedSubviews={true} + maxToRenderPerBatch={10} + initialNumToRender={10} + renderItem={({ item }) => ( + + navigation.navigate("ChapterItem", { + chapterUrl: item.chapterUrl, + }) + } + rippleColor={theme.rippleColorDark} + > + <> + + {item.chapterName} + + + {item.releaseDate} + + + + )} + /> + + )} + + + ); +}; + +export default NovelItem; + +const styles = StyleSheet.create({ + container: { + flex: 1, + // backgroundColor: "#202125", + backgroundColor: "#000000", + }, + nameContainer: { + flex: 1, + width: "100%", + marginHorizontal: 15, + // justifyContent: "center", + }, + background: { + height: 240, + }, + linearGradient: { + height: "100%", + backgroundColor: "rgba(256, 256, 256, 0.5)", + }, + detailsContainer: { + flex: 1, + flexDirection: "row", + margin: 15, + }, + logo: { + height: 180, + width: 120, + margin: 3.2, + borderRadius: 6, + }, + genre: { + borderRadius: 24, + borderWidth: 1, + paddingHorizontal: 10, + marginHorizontal: 2, + fontSize: 13, + paddingVertical: 2, + justifyContent: "center", + flex: 1, + }, + name: { + fontWeight: "bold", + fontSize: 20, + }, +}); diff --git a/src/screens/Updates.js b/src/screens/Updates.js index 6a89f444..6b0a625e 100644 --- a/src/screens/Updates.js +++ b/src/screens/Updates.js @@ -116,7 +116,10 @@ const AllNovels = ({ navigation }) => { rippleColor="rgba(256,256,256,0.3)" style={styles.opac} onPress={() => - navigation.navigate("NovelItem", item) + navigation.navigate( + "NovelItemRewrite", + item + ) } >