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
+ )
}
>