diff --git a/src/components/common/Appbar.js b/src/components/common/Appbar.js
index f9f23edf3..e7f618c22 100644
--- a/src/components/common/Appbar.js
+++ b/src/components/common/Appbar.js
@@ -1,19 +1,136 @@
-import React from "react";
-
-import { Appbar } from "react-native-paper";
+import React, { useRef } from "react";
+import { View, TextInput, StyleSheet } from "react-native";
+import {
+ TouchableRipple,
+ IconButton,
+ Appbar as MaterialAppbar,
+} from "react-native-paper";
+import Constants from "expo-constants";
+import { useNavigation } from "@react-navigation/native";
import { useSelector } from "react-redux";
-export const CustomAppbar = ({ title, onBackAction }) => {
+export const Appbar = ({ title, onBackAction }) => {
const theme = useSelector((state) => state.themeReducer.theme);
return (
-
- {onBackAction && }
-
+ {onBackAction && (
+
+ )}
+
-
+
+ );
+};
+
+export const SearchAppbar = ({
+ placeholder,
+ getSearchResults,
+ setSearchText,
+ searchText,
+ getNovels,
+ setLoading,
+ screen,
+ onFilter,
+}) => {
+ const searchRef = useRef(null);
+
+ const navigation = useNavigation();
+
+ const theme = useSelector((state) => state.themeReducer.theme);
+
+ return (
+ searchRef.current.focus()}
+ style={[
+ styles.searchAppbarContainer,
+ { backgroundColor: theme.searchBarColor },
+ ]}
+ >
+
+
+ {
+ if (screen === "Extension") {
+ navigation.goBack();
+ }
+ }}
+ />
+ {
+ setSearchText(text);
+ if (screen === "Library") {
+ getSearchResults(text);
+ }
+ }}
+ onSubmitEditing={() => {
+ if (screen === "Extension") {
+ getSearchResults(searchText);
+ }
+ }}
+ defaultValue={searchText}
+ />
+
+ {searchText !== "" && (
+ {
+ setLoading?.(true);
+ getNovels();
+ setSearchText("");
+ }}
+ />
+ )}
+ onFilter?.()}
+ />
+
+
);
};
+
+const styles = StyleSheet.create({
+ searchAppbarContainer: {
+ marginTop: Constants.statusBarHeight + 4,
+ height: 48,
+ flexDirection: "row",
+ alignItems: "center",
+ paddingHorizontal: 16,
+ marginBottom: 8,
+ borderRadius: 8,
+ marginHorizontal: 12,
+ elevation: 2,
+ },
+});
diff --git a/src/screens/History/components/EmptyView.js b/src/components/common/EmptyView.js
similarity index 82%
rename from src/screens/History/components/EmptyView.js
rename to src/components/common/EmptyView.js
index 4c27be870..73b4252f8 100644
--- a/src/screens/History/components/EmptyView.js
+++ b/src/components/common/EmptyView.js
@@ -2,7 +2,7 @@ import React from "react";
import { StyleSheet, Text, View } from "react-native";
import { useSelector } from "react-redux";
-const EmptyView = () => {
+const EmptyView = ({ icon, description }) => {
const theme = useSelector((state) => state.themeReducer.theme);
return (
@@ -11,21 +11,21 @@ const EmptyView = () => {
style={[
styles.emptyViewIcon,
{
- color: theme.textColorSecondaryDark,
+ color: theme.textColorSecondary,
},
]}
>
- (˘・_・˘)
+ {icon}
- Nothing read recently.
+ {description}
);
diff --git a/src/components/common/NovelCover.js b/src/components/common/NovelCover.js
index 42612ae55..e02c035d8 100644
--- a/src/components/common/NovelCover.js
+++ b/src/components/common/NovelCover.js
@@ -21,20 +21,18 @@ const NovelCover = ({ item, onPress, libraryStatus }) => {
<>
- {item.novelCover ? (
+ {item.novelCover && (
@@ -53,7 +51,7 @@ const NovelCover = ({ item, onPress, libraryStatus }) => {
styles.title,
{
color:
- theme.textColorPrimaryDark,
+ "rgba(255,255,255,1)",
},
]}
>
@@ -63,19 +61,16 @@ const NovelCover = ({ item, onPress, libraryStatus }) => {
)}
- ) : (
-
-
- Novel Cover Doesn't Exist
-
-
)}
{displayMode === 1 && (
{item.novelName}
@@ -91,8 +86,7 @@ export default NovelCover;
const styles = StyleSheet.create({
logo: {
- height: 183,
- borderRadius: 4,
+ height: 180,
},
titleContainer: {
flex: 1,
diff --git a/src/components/settings/Checkbox.js b/src/components/settings/Checkbox.js
index ea8ba16d0..835d3d2ec 100644
--- a/src/components/settings/Checkbox.js
+++ b/src/components/settings/Checkbox.js
@@ -13,10 +13,10 @@ export const DisplayCheckbox = ({ displayMode, onPress, value }) => {
return (
@@ -29,10 +29,10 @@ export const ThemeCheckbox = ({ onPress, label, checked }) => {
return (
diff --git a/src/navigation/Router.js b/src/navigation/Router.js
index 937eb73ea..f12d8a559 100644
--- a/src/navigation/Router.js
+++ b/src/navigation/Router.js
@@ -4,6 +4,7 @@ import {
TransitionPresets,
} from "@react-navigation/stack";
import { createMaterialBottomTabNavigator } from "@react-navigation/material-bottom-tabs";
+import { Provider } from "react-native-paper";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
@@ -64,7 +65,7 @@ const BottomNavigator = () => {
return (
{
const Router = () => {
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
);
};
diff --git a/src/redux/actions/extension.js b/src/redux/actions/extension.js
new file mode 100644
index 000000000..f85981bff
--- /dev/null
+++ b/src/redux/actions/extension.js
@@ -0,0 +1,11 @@
+import { GET_EXTENSIONS } from "./types";
+import { fetchExtensionList } from "../../services/api";
+
+export const getExtensions = () => async (dispatch) => {
+ const res = await fetchExtensionList();
+
+ dispatch({
+ type: GET_EXTENSIONS,
+ payload: res,
+ });
+};
diff --git a/src/redux/actions/types.js b/src/redux/actions/types.js
index 05ddb2977..25425fefa 100644
--- a/src/redux/actions/types.js
+++ b/src/redux/actions/types.js
@@ -5,3 +5,5 @@ export const GET_LIBRARY_NOVELS = "GET_LIBRARY_NOVELS";
export const SET_DISPLAY_MODE = "SET_DISPLAY_MODE";
export const SET_ITEMS_PER_ROW = "SET_ITEMS_PER_ROW";
+
+export const GET_EXTENSIONS = "GET_EXTENSIONS";
diff --git a/src/redux/reducers/extension.js b/src/redux/reducers/extension.js
new file mode 100644
index 000000000..49feeee35
--- /dev/null
+++ b/src/redux/reducers/extension.js
@@ -0,0 +1,19 @@
+import { GET_EXTENSIONS } from "../actions/types";
+
+const initialState = {
+ extensions: [],
+ loading: true,
+};
+
+const libraryReducer = (state = initialState, action) => {
+ const { type, payload } = action;
+
+ switch (type) {
+ case GET_EXTENSIONS:
+ return { extensions: payload, loading: false };
+ default:
+ return state;
+ }
+};
+
+export default libraryReducer;
diff --git a/src/redux/store/configureStore.js b/src/redux/store/configureStore.js
index 0643b8609..12d7f82e6 100644
--- a/src/redux/store/configureStore.js
+++ b/src/redux/store/configureStore.js
@@ -6,6 +6,7 @@ import thunk from "redux-thunk";
import themeReducer from "../reducers/theme";
import settingsReducer from "../reducers/settings";
import libraryReducer from "../reducers/library";
+import extensionReducer from "../reducers/extension";
const persistConfig = {
key: "root",
@@ -14,7 +15,12 @@ const persistConfig = {
const persistedReducer = persistReducer(
persistConfig,
- combineReducers({ themeReducer, settingsReducer, libraryReducer })
+ combineReducers({
+ themeReducer,
+ settingsReducer,
+ libraryReducer,
+ extensionReducer,
+ })
);
export const store = createStore(persistedReducer, applyMiddleware(thunk));
diff --git a/src/screens/Browse/Browse.js b/src/screens/Browse/Browse.js
index 58e6e59d0..159ce3b40 100644
--- a/src/screens/Browse/Browse.js
+++ b/src/screens/Browse/Browse.js
@@ -1,144 +1,56 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect } from "react";
+import { StyleSheet, View, FlatList, ActivityIndicator } from "react-native";
+import { Appbar } from "../../components/common/Appbar";
+import { connect } from "react-redux";
-import {
- StyleSheet,
- View,
- Text,
- FlatList,
- Image,
- ActivityIndicator,
-} from "react-native";
-import { TouchableRipple, Button } from "react-native-paper";
-import { CustomAppbar } from "../../components/common/Appbar";
+import { getExtensions } from "../../redux/actions/extension";
-import { useSelector } from "react-redux";
-
-const Browse = ({ navigation }) => {
- const theme = useSelector((state) => state.themeReducer.theme);
-
- const [loading, setLoading] = useState(true);
- const [extensions, setExtensions] = useState();
+import ExtensionCard from "./components/ExtensionCard";
+const Browse = ({ theme, extensions, loading, getExtensions }) => {
useEffect(() => {
- fetch(`https://lnreader-extensions.herokuapp.com/api/`)
- .then((response) => response.json())
- .then((json) => {
- setExtensions(json);
- setLoading(false);
- });
+ getExtensions();
}, []);
return (
<>
-
+
- {!loading ? (
- item.sourceId.toString()}
- renderItem={({ item }) => (
-
- navigation.navigate(
- item.sourceName + "Stack"
- )
- }
- rippleColor={theme.rippleColorDark}
- >
- <>
-
-
-
-
- {item.sourceName}
-
-
- {item.sourceLanguage}
-
-
-
-
-
-
- >
-
- )}
- />
- ) : (
-
-
-
- )}
+ item.sourceId.toString()}
+ renderItem={({ item }) => }
+ ListEmptyComponent={
+ loading && (
+
+ )
+ }
+ />
>
);
};
-export default Browse;
+const mapStateToProps = (state) => ({
+ theme: state.themeReducer.theme,
+ extensions: state.extensionReducer.extensions,
+ loading: state.extensionReducer.loading,
+});
+
+export default connect(mapStateToProps, { getExtensions })(Browse);
const styles = StyleSheet.create({
container: {
flex: 1,
- },
- sourceCard: {
- paddingVertical: 10,
- marginVertical: 5,
- paddingHorizontal: 20,
- borderRadius: 6,
- flexDirection: "row",
- alignItems: "center",
+ paddingHorizontal: 4,
},
});
diff --git a/src/screens/Browse/components/ExtensionCard.js b/src/screens/Browse/components/ExtensionCard.js
new file mode 100644
index 000000000..527be6477
--- /dev/null
+++ b/src/screens/Browse/components/ExtensionCard.js
@@ -0,0 +1,91 @@
+import React from "react";
+import { View, Text, Image, StyleSheet } from "react-native";
+import { TouchableRipple, Button } from "react-native-paper";
+
+import { useNavigation } from "@react-navigation/native";
+import { useSelector } from "react-redux";
+
+const ExtensionCard = ({ item }) => {
+ const { sourceName, sourceCover, sourceLanguage } = item;
+
+ const navigation = useNavigation();
+
+ const theme = useSelector((state) => state.themeReducer.theme);
+
+ return (
+ navigation.navigate(sourceName + "Stack")}
+ rippleColor={theme.rippleColor}
+ >
+ <>
+
+
+
+
+ {sourceName}
+
+
+ {sourceLanguage}
+
+
+
+
+
+
+ >
+
+ );
+};
+
+export default ExtensionCard;
+
+const styles = StyleSheet.create({
+ extensionCard: {
+ flexDirection: "row",
+ alignItems: "center",
+ marginVertical: 4,
+ paddingVertical: 8,
+ paddingHorizontal: 20,
+ borderRadius: 6,
+ },
+ extensionIcon: {
+ width: 40,
+ height: 40,
+ borderRadius: 8,
+ },
+ extensionDetails: {
+ flex: 1,
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ marginLeft: 16,
+ },
+});
diff --git a/src/screens/Chapter/Chapter.js b/src/screens/Chapter/Chapter.js
index 919d51525..8f7816774 100644
--- a/src/screens/Chapter/Chapter.js
+++ b/src/screens/Chapter/Chapter.js
@@ -193,7 +193,7 @@ const ChapterItem = ({ route, navigation }) => {
/>
{!loading && (
<>
@@ -241,7 +241,7 @@ const ChapterItem = ({ route, navigation }) => {
contentContainerStyle={[
styles.container,
readerTheme === 1 && {
- backgroundColor: theme.colorDarkPrimary,
+ backgroundColor: theme.colorPrimary,
},
readerTheme === 2 && {
backgroundColor: "white",
@@ -277,7 +277,7 @@ const ChapterItem = ({ route, navigation }) => {
fontSize: size,
},
readerTheme === 1
- ? { color: theme.textColorSecondaryDark }
+ ? { color: theme.textColorSecondary }
: { color: "black" },
size === 16
? { lineHeight: 25 }
diff --git a/src/screens/Chapter/components/BottomSheet.js b/src/screens/Chapter/components/BottomSheet.js
index 4965911f0..7718c4132 100644
--- a/src/screens/Chapter/components/BottomSheet.js
+++ b/src/screens/Chapter/components/BottomSheet.js
@@ -48,7 +48,7 @@ const ChapterBottomSheet = ({
@@ -70,7 +70,7 @@ const ChapterBottomSheet = ({
/>
diff --git a/src/screens/History/History.js b/src/screens/History/History.js
index a55093ee5..f88264bc6 100644
--- a/src/screens/History/History.js
+++ b/src/screens/History/History.js
@@ -9,13 +9,13 @@ import {
ActivityIndicator,
} from "react-native";
-import { CustomAppbar } from "../../components/common/Appbar";
+import { Appbar } from "../../components/common/Appbar";
import HistoryCard from "./components/HistoryCard";
import { getHistoryFromDb, deleteChapterHistory } from "../../services/db";
import { useSelector } from "react-redux";
-import EmptyView from "./components/EmptyView";
+import EmptyView from "../../components/common/EmptyView";
const History = ({ navigation }) => {
const [loading, setLoading] = useState(true);
@@ -49,15 +49,14 @@ const History = ({ navigation }) => {
return (
<>
-
+
item.historyId.toString()}
renderItem={renderHistoryCard}
@@ -69,7 +68,14 @@ const History = ({ navigation }) => {
/>
)
}
- ListEmptyComponent={!loading && }
+ ListEmptyComponent={
+ !loading && (
+
+ )
+ }
/>
>
diff --git a/src/screens/History/components/HistoryCard.js b/src/screens/History/components/HistoryCard.js
index c77fac432..1d8f01768 100644
--- a/src/screens/History/components/HistoryCard.js
+++ b/src/screens/History/components/HistoryCard.js
@@ -13,7 +13,7 @@ const HistoryCard = ({ item, deleteHistory, navigation }) => {
return (
navigation.navigate("NovelItem", {
@@ -34,7 +34,7 @@ const HistoryCard = ({ item, deleteHistory, navigation }) => {
{
{
{
navigation.navigate("ChapterItem", {
diff --git a/src/screens/Library/Library.js b/src/screens/Library/Library.js
index 2b33fa6df..daa60aa3d 100644
--- a/src/screens/Library/Library.js
+++ b/src/screens/Library/Library.js
@@ -11,14 +11,14 @@ import { FlatList } from "react-native-gesture-handler";
import { useFocusEffect } from "@react-navigation/native";
import { connect } from "react-redux";
-import Appbar from "./components/Appbar";
import NovelCover from "../../components/common/NovelCover";
-import EmptyView from "./components/EmptyView";
+import EmptyView from "../../components/common/EmptyView";
import {
getLibraryNovels,
searchLibraryNovels,
} from "../../redux/actions/library";
+import { SearchAppbar } from "../../components/common/Appbar";
const LibraryScreen = ({
navigation,
@@ -30,13 +30,11 @@ const LibraryScreen = ({
}) => {
const [refreshing, setRefreshing] = useState(false);
- const [search, setSearch] = useState({ searching: false, searchText: "" });
-
- const resetSearch = () => setSearch({ searching: false, searchText: "" });
+ const [searchText, setSearchText] = useState("");
useFocusEffect(
useCallback(() => {
- resetSearch();
+ setSearchText("");
getLibraryNovels();
}, [])
);
@@ -59,61 +57,62 @@ const LibraryScreen = ({
return (
<>
-
+
{loading ? (
) : (
- <>
- item.novelUrl}
- renderItem={({ item }) => (
- redirectToNovel(item)}
- />
- )}
- refreshControl={
- item.novelUrl}
+ renderItem={({ item }) => (
+ redirectToNovel(item)}
+ />
+ )}
+ refreshControl={
+
+ }
+ ListEmptyComponent={
+ searchText !== "" ? (
+
+ {`"${searchText}" not in library`}
+
+ ) : (
+
- }
- ListEmptyComponent={
- search.searchText === "" ? (
-
- ) : (
-
- {`"${search.searchText}" not in library`}
-
- )
- }
- />
- >
+ )
+ }
+ />
)}
>
@@ -137,9 +136,8 @@ const styles = StyleSheet.create({
padding: 4,
},
emptySearch: {
- fontWeight: "bold",
- marginTop: 10,
+ marginTop: 8,
textAlign: "center",
- paddingHorizontal: 30,
+ paddingHorizontal: 16,
},
});
diff --git a/src/screens/Library/components/Appbar.js b/src/screens/Library/components/Appbar.js
index 18941827c..1102d3344 100644
--- a/src/screens/Library/components/Appbar.js
+++ b/src/screens/Library/components/Appbar.js
@@ -15,22 +15,22 @@ const LibraryAppbar = ({
const { searching, searchText } = search;
return (
-
+
{!searching ? (
<>
setSearch({ ...search, searching: true })
}
- color={theme.textColorPrimaryDark}
+ color={theme.textColorPrimary}
/>
_panel.show({ velocity: -1.5 })}
@@ -43,7 +43,7 @@ const LibraryAppbar = ({
setSearch({ searching: false, searchText: "" });
getLibraryNovels();
}}
- color={theme.textColorPrimaryDark}
+ color={theme.textColorPrimary}
size={24}
/>
)}
>
diff --git a/src/screens/Library/components/EmptyView.js b/src/screens/Library/components/EmptyView.js
deleted file mode 100644
index 4ee24872f..000000000
--- a/src/screens/Library/components/EmptyView.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from "react";
-import { StyleSheet, Text, View } from "react-native";
-import { useSelector } from "react-redux";
-
-const EmptyView = () => {
- const theme = useSelector((state) => state.themeReducer.theme);
-
- return (
-
-
- Σ(ಠ_ಠ)
-
-
- Your library is empty. Add series to your library from Browse.
-
-
- );
-};
-
-export default EmptyView;
-
-const styles = StyleSheet.create({
- emptyViewContainer: {
- flex: 1,
- justifyContent: "center",
- alignItems: "center",
- },
- emptyViewIcon: {
- fontSize: 45,
- fontWeight: "bold",
- },
- emptyViewText: {
- fontWeight: "bold",
- marginTop: 10,
- textAlign: "center",
- paddingHorizontal: 30,
- },
-});
diff --git a/src/screens/More/About.js b/src/screens/More/About.js
index 74892b4df..1b0cb8888 100644
--- a/src/screens/More/About.js
+++ b/src/screens/More/About.js
@@ -2,7 +2,7 @@ import React from "react";
import * as Linking from "expo-linking";
import { List, Divider } from "react-native-paper";
-import { CustomAppbar } from "../../components/common/Appbar";
+import { Appbar } from "../../components/common/Appbar";
import { useSelector } from "react-redux";
@@ -11,46 +11,43 @@ const AboutScreen = ({ navigation }) => {
return (
<>
- navigation.goBack()}
- />
+ navigation.goBack()} />
Linking.openURL(
"https://github.com/rajarsheechatterjee/lnreader/commits/main"
)
}
- rippleColor={theme.rippleColorDark}
+ rippleColor={theme.rippleColor}
/>
@@ -58,11 +55,11 @@ const AboutScreen = ({ navigation }) => {
"https://github.com/rajarsheechatterjee/lnreader"
)
}
- rippleColor={theme.rippleColorDark}
+ rippleColor={theme.rippleColor}
/>
{
"https://github.com/rajarsheechatterjee/lnreader-extensions"
)
}
- rippleColor={theme.rippleColorDark}
+ rippleColor={theme.rippleColor}
/>
>
diff --git a/src/screens/More/More.js b/src/screens/More/More.js
index 4e7d0deaa..28765351e 100644
--- a/src/screens/More/More.js
+++ b/src/screens/More/More.js
@@ -3,7 +3,7 @@ import React from "react";
import { StyleSheet } from "react-native";
import { List } from "react-native-paper";
-import { CustomAppbar } from "../../components/common/Appbar";
+import { Appbar } from "../../components/common/Appbar";
import { useSelector } from "react-redux";
@@ -12,17 +12,17 @@ const MoreScreen = ({ navigation }) => {
return (
<>
-
+
(
{
onPress={() => navigation.navigate("Settings")}
/>
(
{
- const label = {
+ const display = {
0: "Compact",
1: "Comfortable",
};
- const themes = {
- 0: "AMOLED Dark Theme",
- 1: "Light Theme",
- 2: "Dark Theme",
- 3: "Midnight Dusk Theme",
- };
+ const themes = [
+ { themeCode: 0, label: "AMOLED Dark Theme", statusBar: "light" },
+ { themeCode: 1, label: "Light Theme", statusBar: "dark" },
+ { themeCode: 2, label: "Dark Theme", statusBar: "light" },
+ { themeCode: 3, label: "Midnight Dusk Theme", statusBar: "light" },
+ ];
const desciptionStyles = {
- color: theme.textColorSecondaryDark,
+ color: theme.textColorSecondary,
};
- const titleStyles = { color: theme.textColorPrimaryDark };
+ const titleStyles = { color: theme.textColorPrimary };
- // Display Mode Modal
+ /**
+ * Display Mode Modal
+ */
const [displayModalVisible, setDisplayModalVisible] = useState(false);
const showDisplayModal = () => setDisplayModalVisible(true);
const hideDisplayModal = () => setDisplayModalVisible(false);
- // Theme Modal
+ /**
+ * Change Theme Modal
+ */
const [themeModalVisible, setthemeModalVisible] = useState(false);
const showthemeModal = () => setthemeModalVisible(true);
const hidethemeModal = () => setthemeModalVisible(false);
- // Items Modal
- const [itemsModalVisible, setitemsModalVisible] = useState(false);
- const showitemsModal = () => setitemsModalVisible(true);
- const hideitemsModal = () => setitemsModalVisible(false);
-
return (
-
- navigation.goBack()}
- />
-
+ <>
+ navigation.goBack()} />
+
deleteNovelsNotInLibrary()}
- rippleColor={theme.rippleColorDark}
+ rippleColor={theme.rippleColor}
/>
deleteHistory()}
- rippleColor={theme.rippleColorDark}
+ rippleColor={theme.rippleColor}
/>
-
- setDisplayMode(1)}
- />
-
-
- setDisplayMode(0)}
- />
-
+ setDisplayMode(1)}
+ />
+ setDisplayMode(0)}
+ />
- {/*
-
-
- setItemsPerRow(1)}
- >
- 1
-
- setItemsPerRow(2)}
- >
- 2
-
- setItemsPerRow(3)}
- >
- 3
-
- setItemsPerRow(4)}
- >
- 4
-
-
- */}
{/* deleteDatabase()}
/> */}
@@ -229,58 +161,40 @@ const SettingsScreen = ({
titleStyle={titleStyles}
title="Theme"
descriptionStyle={desciptionStyles}
- description={themes[themeCode]}
+ description={themes[themeCode].label}
onPress={showthemeModal}
- rippleColor={theme.rippleColorDark}
+ rippleColor={theme.rippleColor}
/>
- {
- switchTheme(1);
- setStatusBarStyle("dark");
- }}
- />
- {
- switchTheme(2);
- setStatusBarStyle("light");
- }}
- />
- {
- switchTheme(0);
- setStatusBarStyle("light");
- }}
- />
- {
- switchTheme(3);
- setStatusBarStyle("light");
- }}
- />
+ {themes.map((item) => (
+ {
+ switchTheme(item.themeCode);
+ setStatusBarStyle(item.statusBar);
+ }}
+ />
+ ))}
-
+ >
);
};
diff --git a/src/screens/Novel/Novel.js b/src/screens/Novel/Novel.js
index de4497288..628fefadd 100644
--- a/src/screens/Novel/Novel.js
+++ b/src/screens/Novel/Novel.js
@@ -195,7 +195,7 @@ const NovelItem = ({ route, navigation }) => {
{
}
/>
diff --git a/src/screens/Novel/components/BottomSheet.js b/src/screens/Novel/components/BottomSheet.js
index 72b8b685b..6c7c26e96 100644
--- a/src/screens/Novel/components/BottomSheet.js
+++ b/src/screens/Novel/components/BottomSheet.js
@@ -39,14 +39,14 @@ export const BottomSheet = ({
style={[
styles.contentContainer,
{
- backgroundColor: theme.colorDarkPrimary,
+ backgroundColor: theme.colorPrimary,
},
]}
>
@@ -77,7 +77,7 @@ export const BottomSheet = ({
/>
Newest to oldest
@@ -96,7 +96,7 @@ export const BottomSheet = ({
/>
Oldest to newest
@@ -108,7 +108,7 @@ export const BottomSheet = ({
filterChapters("")}
/>
-
+
Show all
@@ -135,7 +135,7 @@ export const BottomSheet = ({
color={theme.colorAccentDark}
onPress={() => filterChapters("AND `read`=1")}
/>
-
+
Show read chapters
@@ -148,7 +148,7 @@ export const BottomSheet = ({
color={theme.colorAccentDark}
onPress={() => filterChapters("AND `read`=0")}
/>
-
+
Show unread chapters
@@ -163,7 +163,7 @@ export const BottomSheet = ({
color={theme.colorAccentDark}
onPress={() => filterChapters("AND downloaded=1")}
/>
-
+
Show downloaded chapters
@@ -175,5 +175,7 @@ export const BottomSheet = ({
const styles = StyleSheet.create({
contentContainer: {
flex: 1,
+ borderTopRightRadius: 8,
+ borderTopLeftRadius: 8,
},
});
diff --git a/src/screens/Novel/components/ChapterCard.js b/src/screens/Novel/components/ChapterCard.js
index c494469a4..1f405d2c4 100644
--- a/src/screens/Novel/components/ChapterCard.js
+++ b/src/screens/Novel/components/ChapterCard.js
@@ -36,14 +36,14 @@ const ChapterCard = ({
chapterName: chapter.chapterName,
})
}
- rippleColor={theme.rippleColorDark}
+ rippleColor={theme.rippleColor}
>
<>
@@ -55,7 +55,7 @@ const NovelInfoHeader = ({
style={styles.background}
>
@@ -73,7 +73,7 @@ const NovelInfoHeader = ({
style={[
styles.name,
{
- color: theme.textColorPrimaryDark,
+ color: theme.textColorPrimary,
},
]}
>
@@ -83,7 +83,7 @@ const NovelInfoHeader = ({
<>
insertNovelInLib()}
style={[
{
- backgroundColor: theme.colorDarkPrimaryDark,
+ backgroundColor: theme.colorPrimaryDark,
marginRight: 2,
// borderColor: "rgba(255,255,255,0.121)",
- // borderWidth: 1,
+ borderWidth: 0,
justifyContent: "center",
height: 30,
alignItems: "center",
@@ -165,7 +165,7 @@ const NovelInfoHeader = ({
]}
textStyle={{
fontWeight: "bold",
- color: theme.textColorPrimaryDark,
+ color: theme.textColorPrimary,
}}
>
{libraryStatus ? "In Library" : "Add to library"}
@@ -202,7 +202,7 @@ const NovelInfoHeader = ({
>
setMore(!more)}
@@ -291,12 +291,12 @@ const NovelInfoHeader = ({
onPress={() =>
bottomSheetRef.current.show({ velocity: -1.5 })
}
- rippleColor={theme.rippleColorDark}
+ rippleColor={theme.rippleColor}
>
<>
>
@@ -332,7 +332,7 @@ const styles = StyleSheet.create({
},
background: {
height: 285,
- // backgroundColor: theme.colorDarkPrimaryDark,
+ // backgroundColor: theme.colorPrimaryDark,
},
linearGradient: {
// flex: 1,
diff --git a/src/screens/extensions/boxnovel/BoxNovel.js b/src/screens/extensions/boxnovel/BoxNovel.js
index 3f0adb006..2572f54a1 100644
--- a/src/screens/extensions/boxnovel/BoxNovel.js
+++ b/src/screens/extensions/boxnovel/BoxNovel.js
@@ -1,70 +1,38 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect, useState, useRef } from "react";
import { StyleSheet, View, FlatList, ActivityIndicator } from "react-native";
-import { Appbar, Provider, Portal } from "react-native-paper";
+import { Provider, Portal } from "react-native-paper";
import NovelCover from "../../../components/common/NovelCover";
-import SearchBar from "../../../components/common/SearchBar";
+import { SearchAppbar } from "../../../components/common/Appbar";
import { BottomSheet } from "./filters/BottomSheet";
import { useSelector } from "react-redux";
-import * as SQLite from "expo-sqlite";
-const db = SQLite.openDatabase("lnreader.db");
+const BoxNovel = ({ navigation }) => {
+ const theme = useSelector((state) => state.themeReducer.theme);
+
+ const library = useSelector((state) => state.libraryReducer.novels);
-const AllNovels = ({ navigation }) => {
const [loading, setLoading] = useState(true);
- const [loadingMore, setLoadingMore] = useState(false);
const [novels, setNovels] = useState([]);
- const [libraryNovels, setlibraryNovels] = useState([]);
-
const [sort, setSort] = useState("rating");
- const [pageNo, setPageNo] = useState(1);
- const [searchBar, setSearchBar] = useState(false);
const [searchText, setSearchText] = useState("");
- const [searched, setSearched] = useState(0);
-
- const theme = useSelector((state) => state.themeReducer.theme);
+ let bottomSheetRef = useRef(null);
const getNovels = () => {
fetch(
- `https://lnreader-extensions.herokuapp.com/api/1/novels/${pageNo}/?o=${sort}`
+ `https://lnreader-extensions.herokuapp.com/api/1/novels/1/?o=${sort}`
)
.then((response) => response.json())
.then((json) => {
- setPageNo(pageNo + 1);
- setNovels((novels) => novels.concat(json));
+ setNovels(json);
setLoading(false);
});
};
- const getLibraryNovels = () => {
- db.transaction((tx) => {
- tx.executeSql(
- "SELECT novelUrl FROM LibraryTable WHERE libraryStatus = 1 AND extensionId = 1",
- null,
- (tx, { rows: { _array } }) => {
- setlibraryNovels(_array);
- },
- (tx, error) => console.log(error)
- );
- });
- };
-
- const onEndReached = ({
- layoutMeasurement,
- contentOffset,
- contentSize,
- }) => {
- const paddingToBottom = 5;
- return (
- layoutMeasurement.height + contentOffset.y >=
- contentSize.height - paddingToBottom
- );
- };
-
const getSearchResults = (searchText) => {
setLoading(true);
fetch(
@@ -78,92 +46,33 @@ const AllNovels = ({ navigation }) => {
};
const checkIFInLibrary = (id) => {
- return libraryNovels.some((obj) => obj.novelUrl === id);
+ return library.some((obj) => obj.novelUrl === id);
};
useEffect(() => {
- getLibraryNovels();
getNovels();
}, [sort]);
- const sortNovels = () => {
- setLoading(true);
- if (searched) {
- getSearchResults();
- } else {
- getNovels();
- }
- };
-
return (
-
- {!searchBar ? (
- <>
- navigation.goBack()}
- color={theme.textColorPrimaryDark}
- />
-
-
- setSearchBar(true)}
- color={theme.textColorPrimaryDark}
- />
- _panel.show({ velocity: -1.5 })}
- color={theme.textColorPrimaryDark}
- />
- >
- ) : (
- <>
- {
- if (searched) {
- setLoading(true);
- setPageNo(1);
- setNovels([]);
- getNovels();
- }
- setSearchBar(false);
- setSearchText("");
- }}
- color={theme.textColorPrimaryDark}
- />
- setSearchText(text)}
- onSubmitEditing={() => {
- if (searchText !== "") {
- setSort("rating");
- getSearchResults(searchText);
- setSearched(true);
- }
- }}
- />
- {searchText !== "" && (
- {
- setSearchText("");
- }}
- color={theme.textColorPrimaryDark}
- />
- )}
- >
- )}
-
+
+ bottomSheetRef.current.show({ velocity: -1.5 })
+ }
+ />
{loading ? (
{
data={novels}
showsVerticalScrollIndicator={false}
keyExtractor={(item) => item.novelUrl}
- ListFooterComponent={() =>
- loadingMore && (
-
- )
- }
renderItem={({ item }) => (
{
}
/>
)}
- onScroll={({ nativeEvent }) => {
- if (onEndReached(nativeEvent)) {
- setLoadingMore(true);
- getNovels();
- console.log("End Reached");
- }
- }}
/>
)}
(_panel = c)}
+ bottomSheetRef={bottomSheetRef}
setSort={setSort}
sort={sort}
+ setLoading={setLoading}
/>
);
};
-export default AllNovels;
+export default BoxNovel;
const styles = StyleSheet.create({
container: {
flex: 1,
- padding: 3,
+ padding: 4,
},
contentContainer: {
diff --git a/src/screens/extensions/boxnovel/filters/BottomSheet.js b/src/screens/extensions/boxnovel/filters/BottomSheet.js
index fd83dd27c..2688a7a31 100644
--- a/src/screens/extensions/boxnovel/filters/BottomSheet.js
+++ b/src/screens/extensions/boxnovel/filters/BottomSheet.js
@@ -5,14 +5,18 @@ import Bottomsheet from "rn-sliding-up-panel";
import { useSelector } from "react-redux";
-export const BottomSheet = ({
- bottomSheetRef,
- setSort,
- sort,
- setRefreshing,
-}) => {
+export const BottomSheet = ({ bottomSheetRef, setSort, sort, setLoading }) => {
const theme = useSelector((state) => state.themeReducer.theme);
+ const sorting = [
+ { label: "Latest", sortFlag: "latest" },
+ { label: "A-Z", sortFlag: "aplhabet" },
+ { label: "Rating", sortFlag: "rating" },
+ { label: "Trending", sortFlag: "trending" },
+ { label: "Most Views", sortFlag: "views" },
+ { label: "New", sortFlag: "new-manga" },
+ ];
+
return (
@@ -49,129 +53,31 @@ export const BottomSheet = ({
}}
expanded
>
-
- sort === "latest" && (
-
- )
- }
- title="Latest"
- titleStyle={{
- fontSize: 15,
- color: theme.textColorPrimaryDark,
- }}
- onPress={() => setSort("latest")}
- />
-
- sort === "alphabet" && (
-
- )
- }
- title="A-Z"
- titleStyle={{
- fontSize: 15,
- color: theme.textColorPrimaryDark,
- }}
- onPress={() => {
- setSort("alphabet");
- setRefreshing(true);
- }}
- />
-
- sort === "rating" && (
-
- )
- }
- title="Rating"
- titleStyle={{
- fontSize: 15,
- color: theme.textColorPrimaryDark,
- }}
- onPress={() => {
- setSort("rating");
- setRefreshing(true);
- }}
- />
-
- sort === "trending" && (
-
- )
- }
- title="Trending"
- titleStyle={{
- fontSize: 15,
- color: theme.textColorPrimaryDark,
- }}
- onPress={() => {
- setSort("trending");
- setRefreshing(true);
- }}
- />
-
- sort === "views" && (
-
- )
- }
- title="Most Views"
- titleStyle={{
- fontSize: 15,
- color: theme.textColorPrimaryDark,
- }}
- onPress={() => {
- setSort("views");
- setRefreshing(true);
- }}
- />
-
- sort === "new-manga" && (
-
- )
- }
- title="New"
- titleStyle={{
- fontSize: 15,
- color: theme.textColorPrimaryDark,
- }}
- onPress={() => {
- setSort("new-manga");
- setRefreshing(true);
- }}
- />
+ {sorting.map((item) => (
+
+ sort === item.sortFlag && (
+
+ )
+ }
+ title={item.label}
+ titleStyle={{
+ fontSize: 15,
+ color: theme.textColorPrimary,
+ }}
+ onPress={() => {
+ setLoading(true);
+ setSort(item.sortFlag);
+ }}
+ />
+ ))}
diff --git a/src/screens/extensions/readlightnovel/ReadLightNovel.js b/src/screens/extensions/readlightnovel/ReadLightNovel.js
index ef5632f2d..7c930bf42 100644
--- a/src/screens/extensions/readlightnovel/ReadLightNovel.js
+++ b/src/screens/extensions/readlightnovel/ReadLightNovel.js
@@ -1,28 +1,23 @@
import React, { useEffect, useState } from "react";
import { StyleSheet, View, FlatList, ActivityIndicator } from "react-native";
-import { Appbar, Provider } from "react-native-paper";
+import { Provider } from "react-native-paper";
import NovelCover from "../../../components/common/NovelCover";
-import SearchBar from "../../../components/common/SearchBar";
+import { SearchAppbar } from "../../../components/common/Appbar";
import { useSelector } from "react-redux";
-
-import * as SQLite from "expo-sqlite";
-const db = SQLite.openDatabase("lnreader.db");
+import EmptyView from "../../../components/common/EmptyView";
const ReadLightNovel = ({ navigation }) => {
const theme = useSelector((state) => state.themeReducer.theme);
+ const library = useSelector((state) => state.libraryReducer.novels);
const [loading, setLoading] = useState(true);
const [novels, setNovels] = useState();
- const [libraryNovels, setlibraryNovels] = useState([]);
- 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/`)
.then((response) => response.json())
@@ -44,95 +39,32 @@ const ReadLightNovel = ({ navigation }) => {
});
};
- const getLibraryNovels = () => {
- db.transaction((tx) => {
- tx.executeSql(
- "SELECT novelUrl FROM LibraryTable WHERE libraryStatus = 1 AND extensionId = 2",
- null,
- (tx, { rows: { _array } }) => {
- setlibraryNovels(_array);
- },
- (tx, error) => console.log(error)
- );
- });
- };
-
const checkIFInLibrary = (id) => {
- return libraryNovels.some((obj) => obj.novelUrl === id);
+ return library.some((obj) => obj.novelUrl === id);
};
useEffect(() => {
getNovels();
- getLibraryNovels();
}, []);
return (
-
- {!searchBar ? (
- <>
- navigation.goBack()}
- />
-
-
- setSearchBar(true)}
- />
-
- >
- ) : (
- <>
- {
- if (searched) {
- setLoading(true);
- getNovels();
- }
- setSearchBar(false);
- setSearchText("");
- }}
- color={theme.textColorPrimaryDark}
- />
- setSearchText(text)}
- onSubmitEditing={() => {
- if (searchText !== "") {
- getSearchResults(searchText);
- setSearched(true);
- }
- }}
- />
- {searchText !== "" && (
- {
- setSearchText("");
- }}
- color={theme.textColorPrimaryDark}
- />
- )}
- >
- )}
-
+
+
{loading ? (
{
) : (
{
}
/>
)}
+ ListEmptyComponent={
+ searchText !== "" &&
+ novels.length === 0 && (
+
+ )
+ }
/>
)}
diff --git a/src/services/api.js b/src/services/api.js
index a63036a42..70ca9730e 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -53,12 +53,22 @@ export const fetchChapterFromSource = async (
chapterUrl
) => {
const url = `https://lnreader-extensions.herokuapp.com/api/${extensionId}/novel/${novelUrl}${chapterUrl}`;
- console.log(
- `https://lnreader-extensions.herokuapp.com/api/${extensionId}/novel/${novelUrl}${chapterUrl}`
- );
let res = await fetch(url);
let chapter = await res.json();
return chapter;
};
+
+/**
+ * Fetch list of extensions
+ */
+
+export const fetchExtensionList = async () => {
+ const url = `https://lnreader-extensions.herokuapp.com/api/`;
+
+ let res = await fetch(url);
+ let extensions = await res.json();
+
+ return extensions;
+};
diff --git a/src/theme/theme.js b/src/theme/theme.js
index 9d6279a69..ea943e6a8 100644
--- a/src/theme/theme.js
+++ b/src/theme/theme.js
@@ -2,63 +2,67 @@
* Application Colors
*/
export const theme = {
- colorDarkPrimary: "#000000",
- colorDarkPrimaryDark: "#000000",
+ colorPrimary: "#000000",
+ colorPrimaryDark: "#000000",
colorAccentDark: "#3399FF",
- textColorPrimaryDark: "#FFFFFF",
- textColorSecondaryDark: "rgba(255,255,255,0.7)",
+ textColorPrimary: "#FFFFFF",
+ textColorSecondary: "rgba(255,255,255,0.7)",
textColorHintDark: "rgba(255,255,255,0.5)",
- rippleColorDark: "rgba(255,255,255,0.2)",
+ rippleColor: "rgba(255,255,255,0.2)",
};
/**
* Light Theme
*/
export const lightTheme = {
- colorDarkPrimary: "#FFFFFF",
- colorDarkPrimaryDark: "#FAFAFA",
+ colorPrimary: "#FFFFFF",
+ colorPrimaryDark: "#FAFAFA",
colorAccentDark: "#2979FF",
- textColorPrimaryDark: "#000000",
- textColorSecondaryDark: "rgba(0,0,0,0.54)",
+ textColorPrimary: "#000000",
+ textColorSecondary: "rgba(0,0,0,0.54)",
textColorHintDark: "rgba(0,0,0,0.38)",
- rippleColorDark: "#C2C2C2",
+ rippleColor: "#C2C2C2",
+ searchBarColor: "#FFFFFF",
};
/**
* Dark Theme
*/
export const darkTheme = {
- colorDarkPrimary: "#242529",
- colorDarkPrimaryDark: "#202125",
+ colorPrimary: "#242529",
+ colorPrimaryDark: "#202125",
colorAccentDark: "#3399FF",
- textColorPrimaryDark: "#FFFFFF",
- textColorSecondaryDark: "rgba(255,255,255,0.7)",
+ textColorPrimary: "#FFFFFF",
+ textColorSecondary: "rgba(255,255,255,0.7)",
textColorHintDark: "rgba(255,255,255,0.5)",
- rippleColorDark: "rgba(255,255,255,0.2)",
+ rippleColor: "rgba(255,255,255,0.2)",
+ searchBarColor: "#303135",
};
/**
* Amoled Dark Theme
*/
export const amoledDarkTheme = {
- colorDarkPrimary: "#000000",
- colorDarkPrimaryDark: "#000000",
+ colorPrimary: "#000000",
+ colorPrimaryDark: "#000000",
colorAccentDark: "#3399FF",
- textColorPrimaryDark: "#FFFFFF",
- textColorSecondaryDark: "rgba(255,255,255,0.7)",
+ textColorPrimary: "#FFFFFF",
+ textColorSecondary: "rgba(255,255,255,0.7)",
textColorHintDark: "rgba(255,255,255,0.5)",
- rippleColorDark: "rgba(255,255,255,0.2)",
+ rippleColor: "rgba(255,255,255,0.2)",
+ searchBarColor: "#1F1F1F",
};
/**
* Midnight Dusk Theme
*/
export const midnightDuskTheme = {
- colorDarkPrimary: "#201F27",
- colorDarkPrimaryDark: "#16151D",
+ colorPrimary: "#201F27",
+ colorPrimaryDark: "#16151D",
colorAccentDark: "#F02475",
- textColorPrimaryDark: "#FFFFFF",
- textColorSecondaryDark: "rgba(255,255,255,0.7)",
+ textColorPrimary: "#FFFFFF",
+ textColorSecondary: "rgba(255,255,255,0.7)",
textColorHintDark: "rgba(255,255,255,0.5)",
- rippleColorDark: "rgba(255,255,255,0.2)",
+ rippleColor: "rgba(255,255,255,0.2)",
+ searchBarColor: "#201F27",
};