Redo previous changes
This commit is contained in:
@@ -9,14 +9,14 @@ import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityI
|
||||
|
||||
import Library from "../screens/Library/Library";
|
||||
import History from "../screens/History/History";
|
||||
import Browse from "../screens/Browse";
|
||||
import Browse from "../screens/Browse/Browse";
|
||||
|
||||
import More from "../screens/More/More";
|
||||
import About from "../screens/More/About";
|
||||
import Settings from "../screens/More/Settings";
|
||||
|
||||
import NovelItem from "../screens/NovelItem";
|
||||
import ChapterItem from "../screens/ChapterItem";
|
||||
import NovelItem from "../screens/Novel/Novel";
|
||||
import ChapterItem from "../screens/Chapter/Chapter";
|
||||
|
||||
// Extensions
|
||||
import BoxNovel from "../screens/extensions/boxnovel/BoxNovel";
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
ActivityIndicator,
|
||||
} from "react-native";
|
||||
import { TouchableRipple, Button } from "react-native-paper";
|
||||
import { CustomAppbar } from "../components/common/Appbar";
|
||||
import { CustomAppbar } from "../../components/common/Appbar";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
@@ -2,17 +2,17 @@ import React, { useState, useEffect } from "react";
|
||||
import { StyleSheet, View, Text, ActivityIndicator } from "react-native";
|
||||
|
||||
import { Appbar, Provider, Portal } from "react-native-paper";
|
||||
import { theme } from "../theme/theme";
|
||||
import { theme } from "../../theme/theme";
|
||||
import { CollapsibleHeaderScrollView } from "react-native-collapsible-header-views";
|
||||
|
||||
import BottomSheet from "../components/chapter/BottomSheet";
|
||||
import BottomSheet from "./components/BottomSheet";
|
||||
|
||||
import * as SQLite from "expo-sqlite";
|
||||
const db = SQLite.openDatabase("lnreader.db");
|
||||
|
||||
import { fetchChapterFromSource } from "../services/api";
|
||||
import { fetchChapterFromSource } from "../../services/api";
|
||||
|
||||
import { getReaderTheme } from "../services/asyncStorage";
|
||||
import { getReaderTheme } from "../../services/asyncStorage";
|
||||
|
||||
const ChapterItem = ({ route, navigation }) => {
|
||||
const { extensionId, chapterUrl, novelUrl, chapterName } = route.params;
|
||||
+1
-1
@@ -7,7 +7,7 @@ import Bottomsheet from "rn-sliding-up-panel";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import { saveReaderTheme } from "../../services/asyncStorage";
|
||||
import { saveReaderTheme } from "../../../services/asyncStorage";
|
||||
|
||||
const ChapterBottomSheet = ({
|
||||
bottomSheetRef,
|
||||
@@ -10,15 +10,16 @@ import {
|
||||
} from "react-native";
|
||||
|
||||
import { CustomAppbar } from "../../components/common/Appbar";
|
||||
import HistoryCard from "../../components/history/HistoryCard";
|
||||
import HistoryCard from "./components/HistoryCard";
|
||||
|
||||
import { getHistoryFromDb, deleteChapterHistory } from "../../services/db";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
import EmptyView from "./components/EmptyView";
|
||||
|
||||
const History = ({ navigation }) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [history, setHistory] = useState();
|
||||
const [history, setHistory] = useState([]);
|
||||
|
||||
const theme = useSelector((state) => state.themeReducer.theme);
|
||||
|
||||
@@ -38,6 +39,14 @@ const History = ({ navigation }) => {
|
||||
}, [])
|
||||
);
|
||||
|
||||
const renderHistoryCard = ({ item }) => (
|
||||
<HistoryCard
|
||||
item={item}
|
||||
deleteHistory={deleteHistory}
|
||||
navigation={navigation}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CustomAppbar title="History" />
|
||||
@@ -51,13 +60,7 @@ const History = ({ navigation }) => {
|
||||
contentContainerStyle={{ flex: 1 }}
|
||||
data={history}
|
||||
keyExtractor={(item) => item.historyId.toString()}
|
||||
renderItem={({ item }) => (
|
||||
<HistoryCard
|
||||
item={item}
|
||||
deleteHistory={deleteHistory}
|
||||
navigation={navigation}
|
||||
/>
|
||||
)}
|
||||
renderItem={renderHistoryCard}
|
||||
ListFooterComponent={
|
||||
loading && (
|
||||
<ActivityIndicator
|
||||
@@ -66,38 +69,7 @@ const History = ({ navigation }) => {
|
||||
/>
|
||||
)
|
||||
}
|
||||
ListEmptyComponent={
|
||||
!loading && (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.textColorSecondaryDark,
|
||||
fontSize: 45,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
(˘・_・˘)
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.textColorSecondaryDark,
|
||||
fontWeight: "bold",
|
||||
marginTop: 10,
|
||||
textAlign: "center",
|
||||
paddingHorizontal: 30,
|
||||
}}
|
||||
>
|
||||
Nothing read recently.
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
ListEmptyComponent={!loading && <EmptyView />}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
@@ -111,10 +83,4 @@ const styles = StyleSheet.create({
|
||||
flex: 1,
|
||||
padding: 10,
|
||||
},
|
||||
historyCard: {
|
||||
marginTop: 10,
|
||||
borderRadius: 4,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
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 (
|
||||
<View style={styles.emptyViewContainer}>
|
||||
<Text
|
||||
style={[
|
||||
styles.emptyViewIcon,
|
||||
{
|
||||
color: theme.textColorSecondaryDark,
|
||||
},
|
||||
]}
|
||||
>
|
||||
(˘・_・˘)
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
styles.emptyViewText,
|
||||
{
|
||||
color: theme.textColorSecondaryDark,
|
||||
},
|
||||
]}
|
||||
>
|
||||
Nothing read recently.
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
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,
|
||||
},
|
||||
});
|
||||
+14
-21
@@ -12,10 +12,7 @@ const HistoryCard = ({ item, deleteHistory, navigation }) => {
|
||||
|
||||
return (
|
||||
<TouchableRipple
|
||||
style={[
|
||||
styles.historyCard,
|
||||
// { backgroundColor: theme.colorDarkPrimary },
|
||||
]}
|
||||
style={styles.historyCard}
|
||||
rippleColor={theme.rippleColorDark}
|
||||
borderless
|
||||
onPress={() =>
|
||||
@@ -31,20 +28,9 @@ const HistoryCard = ({ item, deleteHistory, navigation }) => {
|
||||
<>
|
||||
<Image
|
||||
source={{ uri: item.novelCover }}
|
||||
style={{
|
||||
height: 80,
|
||||
width: 57,
|
||||
borderRadius: 4,
|
||||
}}
|
||||
style={styles.historyCover}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
marginLeft: 15,
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<View style={styles.historyText}>
|
||||
<View style={{ flex: 0.9 }}>
|
||||
<Text
|
||||
style={{
|
||||
@@ -110,13 +96,20 @@ export default HistoryCard;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
historyCard: {
|
||||
// backgroundColor: theme.colorDarkPrimary,
|
||||
// paddingVertical: 10,
|
||||
// marginVertical: 5,
|
||||
// paddingHorizontal: 20,
|
||||
marginBottom: 15,
|
||||
borderRadius: 4,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
historyCover: {
|
||||
height: 80,
|
||||
width: 57,
|
||||
borderRadius: 4,
|
||||
},
|
||||
historyText: {
|
||||
marginLeft: 15,
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
});
|
||||
@@ -9,13 +9,11 @@ import {
|
||||
} from "react-native";
|
||||
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 { connect } from "react-redux";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
import EmptyView from "./components/EmptyView";
|
||||
|
||||
import {
|
||||
getLibraryNovels,
|
||||
@@ -24,27 +22,28 @@ import {
|
||||
|
||||
const LibraryScreen = ({
|
||||
navigation,
|
||||
theme,
|
||||
novels,
|
||||
loading,
|
||||
getLibraryNovels,
|
||||
searchLibraryNovels,
|
||||
}) => {
|
||||
const theme = useSelector((state) => state.themeReducer.theme);
|
||||
|
||||
// const itemsPerRow = useSelector((state) => state.settingsReducer.itemsPerRow);
|
||||
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
const [searchBar, setSearchBar] = useState(false);
|
||||
const [searchText, setSearchText] = useState("");
|
||||
const [search, setSearch] = useState({ searching: false, searchText: "" });
|
||||
|
||||
const resetSearch = () => setSearch({ searching: false, searchText: "" });
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
setSearchBar(false);
|
||||
resetSearch();
|
||||
getLibraryNovels();
|
||||
}, [])
|
||||
);
|
||||
|
||||
/**
|
||||
* TODO: fix refreshing
|
||||
*/
|
||||
const onRefresh = () => {
|
||||
ToastAndroid.show("Updating library", ToastAndroid.SHORT);
|
||||
setRefreshing(true);
|
||||
@@ -52,13 +51,17 @@ const LibraryScreen = ({
|
||||
setRefreshing(false);
|
||||
};
|
||||
|
||||
const redirectToNovel = (item) =>
|
||||
navigation.navigate("NovelItem", {
|
||||
...item,
|
||||
navigatingFrom: 1,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Appbar
|
||||
searchBar={searchBar}
|
||||
setSearchBar={setSearchBar}
|
||||
searchText={searchText}
|
||||
setSearchText={setSearchText}
|
||||
search={search}
|
||||
setSearch={setSearch}
|
||||
getLibraryNovels={getLibraryNovels}
|
||||
searchLibraryNovels={searchLibraryNovels}
|
||||
/>
|
||||
@@ -68,93 +71,57 @@ const LibraryScreen = ({
|
||||
{ backgroundColor: theme.colorDarkPrimaryDark },
|
||||
]}
|
||||
>
|
||||
<FlatList
|
||||
contentContainerStyle={{ flex: 1 }}
|
||||
numColumns={3}
|
||||
data={novels}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyExtractor={(item) => item.novelUrl}
|
||||
renderItem={({ item }) => (
|
||||
<NovelCover
|
||||
item={item}
|
||||
onPress={() =>
|
||||
navigation.navigate("NovelItem", {
|
||||
...item,
|
||||
navigatingFrom: 1,
|
||||
})
|
||||
{loading ? (
|
||||
<ActivityIndicator
|
||||
size="small"
|
||||
color={theme.colorAccentDark}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<FlatList
|
||||
numColumns={3}
|
||||
data={novels}
|
||||
keyExtractor={(item) => item.novelUrl}
|
||||
renderItem={({ item }) => (
|
||||
<NovelCover
|
||||
item={item}
|
||||
onPress={() => redirectToNovel(item)}
|
||||
/>
|
||||
)}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={onRefresh}
|
||||
colors={["white"]}
|
||||
progressBackgroundColor={
|
||||
theme.colorAccentDark
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={onRefresh}
|
||||
colors={["white"]}
|
||||
progressBackgroundColor={theme.colorAccentDark}
|
||||
/>
|
||||
}
|
||||
ListEmptyComponent={
|
||||
!loading ? (
|
||||
!searchBar ? (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
ListEmptyComponent={
|
||||
search.searchText === "" ? (
|
||||
<EmptyView />
|
||||
) : (
|
||||
<Text
|
||||
style={{
|
||||
color: theme.textColorSecondaryDark,
|
||||
fontSize: 45,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
style={[
|
||||
styles.emptySearch,
|
||||
{ color: theme.colorAccentDark },
|
||||
]}
|
||||
>
|
||||
Σ(ಠ_ಠ)
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
color: theme.textColorSecondaryDark,
|
||||
fontWeight: "bold",
|
||||
marginTop: 10,
|
||||
textAlign: "center",
|
||||
paddingHorizontal: 30,
|
||||
}}
|
||||
>
|
||||
Your library is empty. Add series to
|
||||
your library from Browse.
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
searchBar &&
|
||||
searchText !== "" && (
|
||||
<Text
|
||||
style={{
|
||||
color: theme.colorAccentDark,
|
||||
fontWeight: "bold",
|
||||
marginTop: 10,
|
||||
textAlign: "center",
|
||||
paddingHorizontal: 30,
|
||||
}}
|
||||
>
|
||||
{`"${searchText}" not in library`}
|
||||
{`"${search.searchText}" not in library`}
|
||||
</Text>
|
||||
)
|
||||
)
|
||||
) : (
|
||||
<ActivityIndicator
|
||||
size="small"
|
||||
color={theme.colorAccentDark}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
theme: state.themeReducer.theme,
|
||||
novels: state.libraryReducer.novels,
|
||||
loading: state.libraryReducer.loading,
|
||||
});
|
||||
@@ -169,4 +136,10 @@ const styles = StyleSheet.create({
|
||||
flex: 1,
|
||||
padding: 4,
|
||||
},
|
||||
emptySearch: {
|
||||
fontWeight: "bold",
|
||||
marginTop: 10,
|
||||
textAlign: "center",
|
||||
paddingHorizontal: 30,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import React from "react";
|
||||
import { TextInput } from "react-native";
|
||||
import { StyleSheet, TextInput } from "react-native";
|
||||
import { Appbar } from "react-native-paper";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
const LibraryAppbar = ({
|
||||
searchBar,
|
||||
setSearchBar,
|
||||
searchText,
|
||||
setSearchText,
|
||||
search,
|
||||
setSearch,
|
||||
getLibraryNovels,
|
||||
searchLibraryNovels,
|
||||
}) => {
|
||||
const theme = useSelector((state) => state.themeReducer.theme);
|
||||
|
||||
const { searching, searchText } = search;
|
||||
|
||||
return (
|
||||
<Appbar.Header style={{ backgroundColor: theme.colorDarkPrimary }}>
|
||||
{!searchBar ? (
|
||||
{!searching ? (
|
||||
<>
|
||||
<Appbar.Content
|
||||
title="Library"
|
||||
@@ -24,7 +24,9 @@ const LibraryAppbar = ({
|
||||
/>
|
||||
<Appbar.Action
|
||||
icon="magnify"
|
||||
onPress={() => setSearchBar(true)}
|
||||
onPress={() =>
|
||||
setSearch({ ...search, searching: true })
|
||||
}
|
||||
color={theme.textColorPrimaryDark}
|
||||
/>
|
||||
<Appbar.Action
|
||||
@@ -38,8 +40,7 @@ const LibraryAppbar = ({
|
||||
<>
|
||||
<Appbar.BackAction
|
||||
onPress={() => {
|
||||
setSearchBar(false);
|
||||
setSearchText("");
|
||||
setSearch({ searching: false, searchText: "" });
|
||||
getLibraryNovels();
|
||||
}}
|
||||
color={theme.textColorPrimaryDark}
|
||||
@@ -48,17 +49,17 @@ const LibraryAppbar = ({
|
||||
<TextInput
|
||||
placeholder="Search..."
|
||||
defaultValue={searchText}
|
||||
style={{
|
||||
fontSize: 18,
|
||||
flex: 1,
|
||||
color: theme.textColorPrimaryDark,
|
||||
marginLeft: 15,
|
||||
}}
|
||||
style={[
|
||||
styles.searchBar,
|
||||
{
|
||||
color: theme.textColorPrimaryDark,
|
||||
},
|
||||
]}
|
||||
autoFocus
|
||||
placeholderTextColor={theme.textColorHintDark}
|
||||
blurOnSubmit={true}
|
||||
onChangeText={(text) => {
|
||||
setSearchText(text);
|
||||
setSearch({ ...search, searchText: text });
|
||||
searchLibraryNovels(text);
|
||||
}}
|
||||
/>
|
||||
@@ -66,7 +67,7 @@ const LibraryAppbar = ({
|
||||
<Appbar.Action
|
||||
icon="close"
|
||||
onPress={() => {
|
||||
setSearchText("");
|
||||
setSearch({ ...search, searchText: "" });
|
||||
getLibraryNovels();
|
||||
}}
|
||||
color={theme.textColorPrimaryDark}
|
||||
@@ -79,3 +80,7 @@ const LibraryAppbar = ({
|
||||
};
|
||||
|
||||
export default LibraryAppbar;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
searchBar: { fontSize: 18, flex: 1, marginLeft: 15 },
|
||||
});
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
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 (
|
||||
<View style={styles.emptyViewContainer}>
|
||||
<Text
|
||||
style={[
|
||||
styles.emptyViewIcon,
|
||||
{
|
||||
color: theme.textColorSecondaryDark,
|
||||
},
|
||||
]}
|
||||
>
|
||||
Σ(ಠ_ಠ)
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
styles.emptyViewText,
|
||||
{
|
||||
color: theme.textColorSecondaryDark,
|
||||
},
|
||||
]}
|
||||
>
|
||||
Your library is empty. Add series to your library from Browse.
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
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,
|
||||
},
|
||||
});
|
||||
@@ -9,11 +9,14 @@ import {
|
||||
} from "react-native";
|
||||
import { Provider, Portal } from "react-native-paper";
|
||||
|
||||
import ChapterCard from "../components/novel/ChapterCard";
|
||||
import NovelInfoHeader from "../components/novel/NovelHeader";
|
||||
import { BottomSheet } from "../components/novel/BottomSheet";
|
||||
import ChapterCard from "./components/ChapterCard";
|
||||
import NovelInfoHeader from "./components/NovelHeader";
|
||||
import { BottomSheet } from "./components/BottomSheet";
|
||||
|
||||
import { fetchNovelFromSource, fetchChaptersFromSource } from "../services/api";
|
||||
import {
|
||||
fetchNovelFromSource,
|
||||
fetchChaptersFromSource,
|
||||
} from "../../services/api";
|
||||
import {
|
||||
insertNovelInfoInDb,
|
||||
insertChaptersInDb,
|
||||
@@ -22,7 +25,7 @@ import {
|
||||
getNovelInfoFromDb,
|
||||
toggleFavourite,
|
||||
downloadOrDeleteChapter,
|
||||
} from "../services/db";
|
||||
} from "../../services/db";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
Reference in New Issue
Block a user