diff --git a/App.js b/App.js
index fffb58c9..6b8e80eb 100644
--- a/App.js
+++ b/App.js
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useState, useEffect } from "react";
import Router from "./src/navigation/Router";
import { NavigationContainer } from "@react-navigation/native";
import { StatusBar } from "expo-status-bar";
diff --git a/debug.log b/debug.log
new file mode 100644
index 00000000..5457bfb3
--- /dev/null
+++ b/debug.log
@@ -0,0 +1 @@
+[1225/135759.273:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3)
diff --git a/package-lock.json b/package-lock.json
index 0860aded..9790eabc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7191,6 +7191,11 @@
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-2.15.0.tgz",
"integrity": "sha512-qTSQPy0WKHtlb8xt5gY0Gt6sdvfQUQAnFSqgsggW9UEvySbkHzpqOrOYNA79Ca8oXO0dCFwp6X8buIiDefa7+Q=="
},
+ "react-native-sqlite-storage": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/react-native-sqlite-storage/-/react-native-sqlite-storage-5.0.0.tgz",
+ "integrity": "sha512-c1Joq3/tO1nmIcP8SkRZNolPSbfvY8uZg5lXse0TmjIPC0qHVbk96IMvWGyly1TmYCIpxpuDRc0/xCffDbYIvg=="
+ },
"react-native-vector-icons": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-7.1.0.tgz",
diff --git a/package.json b/package.json
index 700efe7a..1809a08c 100644
--- a/package.json
+++ b/package.json
@@ -1,40 +1,42 @@
{
- "main": "node_modules/expo/AppEntry.js",
- "scripts": {
- "start": "expo start",
- "android": "expo start --android",
- "ios": "expo start --ios",
- "web": "expo start --web",
- "eject": "expo eject"
- },
- "dependencies": {
- "@react-native-community/masked-view": "0.1.10",
- "@react-native-community/slider": "^3.0.3",
- "@react-navigation/material-bottom-tabs": "^5.3.10",
- "@react-navigation/native": "^5.8.10",
- "@react-navigation/stack": "^5.12.8",
- "cheerio-without-node-native": "^0.20.2",
- "expo": "~40.0.0",
- "expo-app-loading": "^1.0.1",
- "expo-font": "^8.4.0",
- "expo-linear-gradient": "^8.4.0",
- "expo-status-bar": "~1.0.3",
- "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-reanimated": "^1.13.2",
- "react-native-safe-area-context": "3.1.9",
- "react-native-screens": "~2.15.0",
- "react-native-vector-icons": "^7.1.0",
- "react-native-web": "~0.13.12",
- "rn-sliding-up-panel": "^2.4.4"
- },
- "devDependencies": {
- "@babel/core": "~7.9.0"
- },
- "private": true,
- "proxy": "http://192.168.1.38:5000"
+ "main": "node_modules/expo/AppEntry.js",
+ "scripts": {
+ "start": "expo start",
+ "android": "expo start --android",
+ "ios": "expo start --ios",
+ "web": "expo start --web",
+ "eject": "expo eject"
+ },
+ "dependencies": {
+ "@react-native-community/masked-view": "0.1.10",
+ "@react-native-community/slider": "^3.0.3",
+ "@react-navigation/material-bottom-tabs": "^5.3.10",
+ "@react-navigation/native": "^5.8.10",
+ "@react-navigation/stack": "^5.12.8",
+ "cheerio-without-node-native": "^0.20.2",
+ "expo": "~40.0.0",
+ "expo-app-loading": "^1.0.1",
+ "expo-font": "^8.4.0",
+ "expo-linear-gradient": "^8.4.0",
+ "expo-status-bar": "~1.0.3",
+ "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-reanimated": "^1.13.2",
+ "react-native-safe-area-context": "3.1.9",
+ "react-native-screens": "~2.15.0",
+ "react-native-sqlite-storage": "^5.0.0",
+ "react-native-vector-icons": "^7.1.0",
+ "react-native-web": "~0.13.12",
+ "rn-sliding-up-panel": "^2.4.4",
+ "expo-sqlite": "~8.5.0"
+ },
+ "devDependencies": {
+ "@babel/core": "~7.9.0"
+ },
+ "private": true,
+ "proxy": "http://192.168.1.38:5000"
}
diff --git a/src/navigation/Router.js b/src/navigation/Router.js
index c9dddd2f..77b4d54f 100644
--- a/src/navigation/Router.js
+++ b/src/navigation/Router.js
@@ -13,7 +13,7 @@ import Search from "../screens/Search";
import NovelItem from "../screens/NovelItem";
import ChapterItem from "../screens/ChapterItem";
import About from "../screens/About";
-
+import LibraryNovelItem from "../screens/LibraryNovelItem";
import { theme } from "../theming/theme";
const Stack = createStackNavigator();
@@ -182,6 +182,10 @@ const MainStack = () => {
+
{
- const { chapterName, chapterUrl } = route.params;
+ const { chapterUrl } = route.params;
const [loading, setLoading] = useState(true);
@@ -115,24 +115,18 @@ const ChapterItem = ({ route, navigation }) => {
diff --git a/src/screens/Library.js b/src/screens/Library.js
index 64313246..2e8fb413 100644
--- a/src/screens/Library.js
+++ b/src/screens/Library.js
@@ -162,10 +162,4 @@ const styles = StyleSheet.create({
contentContainer: {
flex: 1,
},
- fab: {
- position: "absolute",
- margin: 16,
- right: 0,
- bottom: 0,
- },
});
diff --git a/src/screens/LibraryNovelItem.js b/src/screens/LibraryNovelItem.js
new file mode 100644
index 00000000..13a3da9d
--- /dev/null
+++ b/src/screens/LibraryNovelItem.js
@@ -0,0 +1,387 @@
+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();
+ const [chapters, setChapters] = useState();
+ const [more, setMore] = useState(false);
+
+ const fetchNovel = () => {
+ db.transaction((tx) => {
+ tx.executeSql(
+ "SELECT * FROM LibraryTable WHERE novelId=?",
+ [item.novelId],
+ (txObj, { rows: { _array } }) => {
+ setNovel(_array);
+ setRefreshing(false);
+ },
+ (txObj, error) => console.log("Error ", error)
+ );
+ tx.executeSql(
+ "SELECT * FROM ChapterTable WHERE novelId=?",
+ [item.novelId],
+ (txObj, { rows: { _array } }) => {
+ setChapters(_array);
+ setLoading(false);
+ },
+ (txObj, error) => console.log("Error ", error)
+ );
+ });
+ };
+
+ useEffect(() => {
+ fetchNovel();
+ }, []);
+
+ const onRefresh = async () => {
+ setRefreshing(true);
+ fetchNovel();
+ };
+
+ return (
+ <>
+
+ {
+ navigation.goBack();
+ }}
+ color={"white"}
+ size={26}
+ style={{ marginRight: 0 }}
+ />
+
+
+
+
+ }
+ >
+
+
+
+
+
+
+ {item.novelName}
+
+ {!loading && (
+ <>
+
+ {item.alternative.replace(
+ ",",
+ ", "
+ )}
+
+
+ {item.author.replace(",", ", ")}
+
+
+ {item.releaseDate}
+
+
+ {item.status + " • " + item.type}
+
+ >
+ )}
+
+
+
+
+ {!loading && (
+ <>
+ {/* */}
+ {item.novelSummary.length > 0 && (
+
+
+ About
+
+ setMore(!more)}
+ ellipsizeMode="clip"
+ >
+ {item.novelSummary}
+
+ setMore(!more)}
+ >
+ {more ? "Less" : "More"}
+
+
+ )}
+ item}
+ renderItem={({ item }) => (
+
+ {item}
+
+ )}
+ />
+
+
+ setChapters((chapters) => chapters.reverse())
+ }
+ rippleColor={theme.rippleColorDark}
+ >
+ <>
+
+ {chapters.length + " Chapters"}
+
+
+ setChapters((chapters) =>
+ chapters.reverse()
+ )
+ }
+ />
+ >
+
+ item.chapterId}
+ removeClippedSubviews={true}
+ maxToRenderPerBatch={10}
+ initialNumToRender={10}
+ renderItem={({ item }) => (
+
+ navigation.navigate("ChapterItem", {
+ chapterUrl: item.chapterId,
+ })
+ }
+ 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/NovelItem.js b/src/screens/NovelItem.js
index c2b77406..4df5e9cf 100644
--- a/src/screens/NovelItem.js
+++ b/src/screens/NovelItem.js
@@ -9,11 +9,19 @@ import {
ScrollView,
RefreshControl,
} from "react-native";
-import { Appbar, TouchableRipple, IconButton } from "react-native-paper";
+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;
@@ -38,6 +46,52 @@ const NovelItem = ({ route, navigation }) => {
});
};
+ const insertToLibrary = () => {
+ createTables();
+ db.transaction((tx) => {
+ tx.executeSql(
+ "INSERT INTO LibraryTable (novelId, novelName, novelCover, novelSummary, alternative, author, genre, type, releaseDate, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ [
+ novel.novelUrl,
+ novel.novelName,
+ novel.novelCover,
+ novel.novelSummary,
+ novel.novelDetails.Alternative,
+ novel.novelDetails["Author(s)"],
+ novel.novelDetails["Genre(s)"],
+ novel.novelDetails.Type,
+ novel.novelDetails.Release,
+ novel.novelDetails.Status,
+ ]
+ );
+ console.log("Inserted Novel");
+
+ novel.novelChapters.map((chap) =>
+ tx.executeSql(
+ "INSERT INTO ChapterTable (chapterId, chapterName, releaseDate, novelId) values (?, ?, ?, ?)",
+ [
+ chap.chapterUrl,
+ chap.chapterName,
+ chap.releaseDate,
+ novel.novelUrl,
+ ]
+ )
+ );
+ });
+ };
+
+ 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)"
+ );
+ });
+
useEffect(() => {
getNovel();
}, []);
@@ -159,6 +213,18 @@ const NovelItem = ({ route, navigation }) => {
{!loading && (
<>
+
{novel.novelSummary.length > 0 && (
{
}}
onPress={() =>
navigation.navigate("ChapterItem", {
- chapterName: item.chapterName,
chapterUrl: item.chapterUrl,
})
}
diff --git a/src/screens/Updates.js b/src/screens/Updates.js
index 708194f8..dfd7b308 100644
--- a/src/screens/Updates.js
+++ b/src/screens/Updates.js
@@ -1,12 +1,78 @@
-import React from "react";
+import React, { useState, useCallback } from "react";
import { StyleSheet, Text, View } from "react-native";
+import { FlatList } from "react-native-gesture-handler";
+import { theme } from "../theming/theme";
+import { useFocusEffect } from "@react-navigation/native";
+
+import { Button } from "react-native-paper";
+
+import * as SQLite from "expo-sqlite";
+
+const db = SQLite.openDatabase("lnreader.db");
+
+const UpdatesScreen = ({ navigation }) => {
+ const [novels, setNovels] = useState();
+
+ const getLibraryNovels = () => {
+ db.transaction((tx) => {
+ tx.executeSql(
+ "SELECT * FROM LibraryTable",
+ null,
+ (txObj, { rows: { _array } }) => {
+ setNovels(_array);
+ // console.log(_array);
+ },
+ (txObj, error) => console.log("Error ", error)
+ );
+ // tx.executeSql(
+ // "SELECT * FROM Chaptertable",
+ // null,
+ // (txObj, { rows: { _array } }) => {
+ // console.log(_array);
+ // },
+ // (txObj, error) => console.log("Error ", error)
+ // );
+ });
+ };
+
+ // const deleted = () => {
+ // db.transaction((tx) => {
+ // tx.executeSql(
+ // "DROP TABLE LibraryTable",
+ // null,
+ // (txObj) => {
+ // console.log("Deleted");
+ // },
+ // (txObj, error) => console.log("Error ", error)
+ // );
+ // });
+ // };
+
+ useFocusEffect(
+ useCallback(() => {
+ getLibraryNovels();
+ }, [])
+ );
-const UpdatesScreen = () => {
return (
-
- Updates Screen
-
+ item.novelId}
+ renderItem={({ item }) => (
+
+ navigation.navigate("LibraryNovelItem", item)
+ }
+ >
+ {item.novelId}
+
+ )}
+ />
+ {/* */}
);
};