Rewrite NovelItem Screen
This commit is contained in:
@@ -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 (
|
||||
<>
|
||||
|
||||
@@ -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 = () => {
|
||||
<Stack.Screen name="MainStack" component={Router} />
|
||||
<Stack.Screen name="ChapterItem" component={ChapterItem} />
|
||||
<Stack.Screen name="NovelItem" component={NovelItem} />
|
||||
<Stack.Screen
|
||||
name="NovelItemRewrite"
|
||||
component={NovelItemRewrite}
|
||||
/>
|
||||
|
||||
<Stack.Screen
|
||||
name="LibraryNovelItem"
|
||||
component={LibraryNovelItem}
|
||||
|
||||
+18
-18
@@ -38,19 +38,19 @@ const UpdatesScreen = ({ navigation }) => {
|
||||
});
|
||||
};
|
||||
|
||||
// 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 }) => (
|
||||
<TouchableRipple
|
||||
borderless
|
||||
@@ -119,7 +119,7 @@ const UpdatesScreen = ({ navigation }) => {
|
||||
style={styles.opac}
|
||||
onPress={() =>
|
||||
navigation.navigate(
|
||||
"LibraryNovelItem",
|
||||
"NovelItemRewrite",
|
||||
item
|
||||
)
|
||||
}
|
||||
@@ -139,9 +139,9 @@ const UpdatesScreen = ({ navigation }) => {
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{/* <Button mode="contained" onPress={() => deleted()}>
|
||||
Delete Table
|
||||
</Button> */}
|
||||
<Button mode="contained" onPress={() => deleted()}>
|
||||
Delete Library Table
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
|
||||
@@ -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(
|
||||
",",
|
||||
", "
|
||||
)}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
@@ -241,7 +269,7 @@ const NovelItem = ({ route, navigation }) => {
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{item.releaseDate}
|
||||
{item.Release}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
@@ -251,7 +279,7 @@ const NovelItem = ({ route, navigation }) => {
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{item.status + " • " + item.type}
|
||||
{item.Status + " • " + item.Type}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
@@ -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 }) => (
|
||||
<Text
|
||||
@@ -380,7 +408,11 @@ const NovelItem = ({ route, navigation }) => {
|
||||
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}
|
||||
|
||||
@@ -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();
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<>
|
||||
<Appbar.Header style={{ backgroundColor: theme.colorDarkPrimary }}>
|
||||
<Appbar.BackAction
|
||||
onPress={() => {
|
||||
navigation.goBack();
|
||||
}}
|
||||
color={"white"}
|
||||
size={26}
|
||||
style={{ marginRight: 0 }}
|
||||
/>
|
||||
<Appbar.Content
|
||||
title={item.novelName}
|
||||
titleStyle={{ color: theme.textColorPrimaryDark }}
|
||||
/>
|
||||
</Appbar.Header>
|
||||
|
||||
<ScrollView
|
||||
style={styles.container}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={onRefresh}
|
||||
colors={["white"]}
|
||||
progressBackgroundColor={theme.colorAccentDark}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<ImageBackground
|
||||
source={{
|
||||
uri: item.novelCover,
|
||||
}}
|
||||
style={styles.background}
|
||||
>
|
||||
<LinearGradient
|
||||
colors={["transparent", "#000000"]}
|
||||
style={styles.linearGradient}
|
||||
>
|
||||
<View style={styles.detailsContainer}>
|
||||
<Image
|
||||
source={{
|
||||
uri: item.novelCover,
|
||||
}}
|
||||
style={styles.logo}
|
||||
/>
|
||||
<View style={styles.nameContainer}>
|
||||
<Text
|
||||
numberOfLines={4}
|
||||
style={[
|
||||
styles.name,
|
||||
{ color: theme.textColorPrimaryDark },
|
||||
]}
|
||||
>
|
||||
{item.novelName}
|
||||
</Text>
|
||||
{!loading && (
|
||||
<>
|
||||
<Text
|
||||
style={{
|
||||
color:
|
||||
theme.textColorSecondaryDark,
|
||||
marginVertical: 3,
|
||||
fontSize: 15,
|
||||
}}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{novel.Alternative.replace(
|
||||
",",
|
||||
", "
|
||||
)}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color:
|
||||
theme.textColorSecondaryDark,
|
||||
marginVertical: 3,
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{novel["Author(s)"].replace(
|
||||
",",
|
||||
", "
|
||||
)}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color:
|
||||
theme.textColorSecondaryDark,
|
||||
marginVertical: 3,
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{novel["Release"]}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color:
|
||||
theme.textColorSecondaryDark,
|
||||
marginVertical: 3,
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{novel["Status"] +
|
||||
" • " +
|
||||
novel["Type"]}
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
</ImageBackground>
|
||||
{!loading && (
|
||||
<>
|
||||
<Button
|
||||
color={theme.textColorPrimaryDark}
|
||||
style={[
|
||||
{
|
||||
backgroundColor: theme.colorAccentDark,
|
||||
marginHorizontal: 15,
|
||||
},
|
||||
novel.novelSummary.length === 0 && {
|
||||
marginBottom: 20,
|
||||
},
|
||||
]}
|
||||
uppercase={false}
|
||||
labelStyle={{ letterSpacing: 0 }}
|
||||
onPress={() => insertToLibrary()}
|
||||
>
|
||||
{libraryStatus === 0
|
||||
? "Add to library"
|
||||
: "In Library"}
|
||||
</Button>
|
||||
{/* <Button
|
||||
color={theme.textColorPrimaryDark}
|
||||
style={{
|
||||
backgroundColor: theme.colorAccentDark,
|
||||
marginHorizontal: 15,
|
||||
}}
|
||||
uppercase={false}
|
||||
labelStyle={{ letterSpacing: 0 }}
|
||||
onPress={() =>
|
||||
checkIfExistsInLibrary(novel.novelUrl)
|
||||
}
|
||||
>
|
||||
Check
|
||||
</Button> */}
|
||||
{novel.novelSummary.length > 0 && (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 15,
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.textColorPrimaryDark,
|
||||
marginTop: 5,
|
||||
paddingVertical: 5,
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
About
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.textColorSecondaryDark,
|
||||
lineHeight: 20,
|
||||
}}
|
||||
numberOfLines={more ? 100 : 2}
|
||||
onPress={() => setMore(!more)}
|
||||
ellipsizeMode="clip"
|
||||
>
|
||||
{novel.novelSummary}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colorAccentDark,
|
||||
fontWeight: "bold",
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right: 15,
|
||||
}}
|
||||
onPress={() => setMore(!more)}
|
||||
>
|
||||
{more ? "Less" : "More"}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<FlatList
|
||||
contentContainerStyle={{
|
||||
paddingHorizontal: 15,
|
||||
marginBottom: 15,
|
||||
}}
|
||||
horizontal
|
||||
data={novel["Genre(s)"].split(",")}
|
||||
keyExtractor={(item) => item}
|
||||
renderItem={({ item }) => (
|
||||
<Text
|
||||
style={[
|
||||
styles.genre,
|
||||
{
|
||||
color: theme.colorAccentDark,
|
||||
borderColor: theme.colorAccentDark,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{item}
|
||||
</Text>
|
||||
)}
|
||||
/>
|
||||
|
||||
<TouchableRipple
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
// onPress={() =>
|
||||
// setChapters((chapters) => chapters.reverse())
|
||||
// }
|
||||
rippleColor={theme.rippleColorDark}
|
||||
>
|
||||
<>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.textColorPrimaryDark,
|
||||
paddingHorizontal: 15,
|
||||
paddingVertical: 5,
|
||||
fontSize: 15,
|
||||
}}
|
||||
>
|
||||
{chapters.length + " Chapters"}
|
||||
</Text>
|
||||
<IconButton
|
||||
icon="filter-variant"
|
||||
color={theme.textColorPrimaryDark}
|
||||
size={20}
|
||||
// onPress={() =>
|
||||
// setChapters((chapters) =>
|
||||
// chapters.reverse()
|
||||
// )
|
||||
// }
|
||||
/>
|
||||
</>
|
||||
</TouchableRipple>
|
||||
<FlatList
|
||||
data={chapters}
|
||||
extraData={chapters}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyExtractor={(item) => novel.chapterUrl}
|
||||
removeClippedSubviews={true}
|
||||
maxToRenderPerBatch={10}
|
||||
initialNumToRender={10}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableRipple
|
||||
style={{
|
||||
paddingHorizontal: 15,
|
||||
paddingVertical: 12,
|
||||
}}
|
||||
onPress={() =>
|
||||
navigation.navigate("ChapterItem", {
|
||||
chapterUrl: item.chapterUrl,
|
||||
})
|
||||
}
|
||||
rippleColor={theme.rippleColorDark}
|
||||
>
|
||||
<>
|
||||
<Text
|
||||
style={{
|
||||
color:
|
||||
theme.textColorPrimaryDark,
|
||||
}}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{item.chapterName}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color:
|
||||
theme.textColorSecondaryDark,
|
||||
marginTop: 5,
|
||||
fontSize: 13,
|
||||
}}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{item.releaseDate}
|
||||
</Text>
|
||||
</>
|
||||
</TouchableRipple>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</ScrollView>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
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,
|
||||
},
|
||||
});
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
>
|
||||
<NovelCover item={item} />
|
||||
|
||||
Reference in New Issue
Block a user