diff --git a/assets/splash.png b/assets/splash.png
index 933cbe56..2e43828c 100644
Binary files a/assets/splash.png and b/assets/splash.png differ
diff --git a/package-lock.json b/package-lock.json
index d8a73937..ededc6f9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2840,6 +2840,11 @@
"resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
"integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
},
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
+ },
"bplist-creator": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz",
@@ -3420,6 +3425,38 @@
"isobject": "^3.0.1"
}
},
+ "css-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
+ "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
+ "requires": {
+ "boolbase": "^1.0.0",
+ "css-what": "^3.2.1",
+ "domutils": "^1.7.0",
+ "nth-check": "^1.0.2"
+ }
+ },
+ "css-tree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+ "requires": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ }
+ }
+ },
+ "css-what": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
+ "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ=="
+ },
"csstype": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz",
@@ -3551,11 +3588,41 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
+ "dom-serializer": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+ "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+ "requires": {
+ "domelementtype": "^2.0.1",
+ "entities": "^2.0.0"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
+ "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
+ }
+ }
+ },
"dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
+ },
+ "domutils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -3592,6 +3659,11 @@
"once": "^1.4.0"
}
},
+ "entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
+ },
"envinfo": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
@@ -3893,6 +3965,11 @@
"fontfaceobserver": "^2.1.0"
}
},
+ "expo-haptics": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/expo-haptics/-/expo-haptics-10.0.0.tgz",
+ "integrity": "sha512-dfl4Fef22B8O49x5JEzILmAhathT14bkN0kic2FpuwssJDX/yZ/R2lD12Iu9XqxdgHAFQRjOSq3dFjrxDGkP6g=="
+ },
"expo-keep-awake": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-9.1.2.tgz",
@@ -5617,6 +5694,11 @@
"buffer-alloc": "^1.1.0"
}
},
+ "mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
+ },
"merge-stream": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
@@ -6460,6 +6542,14 @@
"path-key": "^2.0.0"
}
},
+ "nth-check": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+ "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+ "requires": {
+ "boolbase": "~1.0.0"
+ }
+ },
"nullthrows": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
@@ -7535,6 +7625,15 @@
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.0.0.tgz",
"integrity": "sha512-35II5oxTaVp3OP8y0eLPOPpQkxG4fRKQ+dL1YSE1we5kCZFOU0l/Rn0T79HbyUu1LPwUZr6lZupPs0ULnRyMuQ=="
},
+ "react-native-svg": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-12.1.0.tgz",
+ "integrity": "sha512-1g9qBRci7man8QsHoXn6tP3DhCDiypGgc6+AOWq+Sy+PmP6yiyf8VmvKuoqrPam/tf5x+ZaBT2KI0gl7bptZ7w==",
+ "requires": {
+ "css-select": "^2.1.0",
+ "css-tree": "^1.0.0-alpha.39"
+ }
+ },
"react-native-swipe-list-view": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/react-native-swipe-list-view/-/react-native-swipe-list-view-3.2.7.tgz",
diff --git a/package.json b/package.json
index 97128df6..64a28eb9 100644
--- a/package.json
+++ b/package.json
@@ -55,7 +55,9 @@
"redux-persist": "^6.0.0",
"redux-thunk": "^2.3.0",
"rn-sliding-up-panel": "^2.4.4",
- "expo-speech": "~9.1.0"
+ "expo-speech": "~9.1.0",
+ "react-native-svg": "12.1.0",
+ "expo-haptics": "~10.0.0"
},
"devDependencies": {
"@babel/core": "~7.9.0"
diff --git a/src/Components/Appbar.js b/src/Components/Appbar.js
index 96cd88f3..45b86b4e 100644
--- a/src/Components/Appbar.js
+++ b/src/Components/Appbar.js
@@ -10,7 +10,7 @@ import Constants from "expo-constants";
import { useNavigation } from "@react-navigation/native";
import { useSelector } from "react-redux";
-export const Appbar = ({ title, onBackAction, style }) => {
+export const Appbar = ({ title, onBackAction, style, children }) => {
const theme = useSelector((state) => state.settingsReducer.theme);
return (
@@ -24,6 +24,7 @@ export const Appbar = ({ title, onBackAction, style }) => {
title={title}
titleStyle={{ color: theme.textColorPrimary }}
/>
+ {children}
);
};
diff --git a/src/Navigators/Main.js b/src/Navigators/Main.js
index 5526b835..14de9d68 100644
--- a/src/Navigators/Main.js
+++ b/src/Navigators/Main.js
@@ -45,10 +45,6 @@ const MainNavigator = () => {
name="Novel"
component={Novel}
options={{
- headerTitle: "",
- headerShown: true,
- headerTransparent: true,
- headerTintColor: "white",
...TransitionPresets.RevealFromBottomAndroid,
}}
/>
diff --git a/src/Screens/Browse/Browse.js b/src/Screens/Browse/Browse.js
index 8470707a..755a9a9a 100644
--- a/src/Screens/Browse/Browse.js
+++ b/src/Screens/Browse/Browse.js
@@ -81,7 +81,7 @@ const Browse = ({ navigation }) => {
clearSearchbar={clearSearchbar}
right="book-search"
onPressRight={() => navigation.navigate("GlobalSearch")}
- migrate="weather-cloudy-arrow-right"
+ migrate="swap-vertical-variant"
onPressMigrate={() => navigation.navigate("Migration")}
/>
diff --git a/src/Screens/Chapter/components/ChapterAppbar.js b/src/Screens/Chapter/components/ChapterAppbar.js
index bd7314d5..5896a9e9 100644
--- a/src/Screens/Chapter/components/ChapterAppbar.js
+++ b/src/Screens/Chapter/components/ChapterAppbar.js
@@ -40,18 +40,18 @@ const ChapterAppbar = ({
novelUrl,
novelId,
chapterName: prevChapter.chapterName,
- novelName: novelName,
+ novelName,
});
const navigateToNextChapter = () =>
navigation.replace("Chapter", {
- chapterUrl: nextChapter.nextChapter,
+ chapterUrl: nextChapter.chapterUrl,
sourceId,
novelUrl,
novelId,
chapterId: nextChapter.chapterId,
chapterName: nextChapter.chapterName,
- novelName: novelName,
+ novelName,
});
return (
@@ -64,9 +64,9 @@ const ChapterAppbar = ({
/>
{
+ const ReaderSettingTitle = ({ title }) => (
+
+ {title}
+
+ );
+
return (
{
-
- Text Size
-
+
{
alignItems: "center",
}}
>
-
- Reader Theme
-
+
{
dispatch(
@@ -118,14 +115,7 @@ const ReaderSheet = ({ theme, reader, dispatch, bottomSheetRef }) => {
alignItems: "center",
}}
>
-
- Text Align
-
+
dispatch(
@@ -150,6 +140,8 @@ const ReaderSheet = ({ theme, reader, dispatch, bottomSheetRef }) => {
backgroundColor: "#FFFFFF",
marginHorizontal: 10,
borderWidth: 0,
+ borderTopRightRadius: 4,
+ borderBottomRightRadius: 4,
}}
/>
{
backgroundColor: "#FFFFFF",
marginHorizontal: 10,
borderWidth: 0,
+ borderRadius: 4,
}}
/>
{
backgroundColor: "#FFFFFF",
marginHorizontal: 10,
borderWidth: 0,
+ borderTopLeftRadius: 4,
+ borderBottomLeftRadius: 4,
}}
/>
@@ -241,7 +236,7 @@ const ReaderSheet = ({ theme, reader, dispatch, bottomSheetRef }) => {
style={{
color: "#FFFFFF",
fontWeight: "bold",
- marginTop: 10,
+ marginVertical: 10,
}}
>
Font Style
diff --git a/src/Screens/Novel/Novel.js b/src/Screens/Novel/Novel.js
index 47515231..01b2055f 100644
--- a/src/Screens/Novel/Novel.js
+++ b/src/Screens/Novel/Novel.js
@@ -1,14 +1,29 @@
import React, { useEffect, useRef, useState } from "react";
-import { StyleSheet, View, FlatList, RefreshControl } from "react-native";
+import {
+ StyleSheet,
+ View,
+ FlatList,
+ RefreshControl,
+ StatusBar,
+} from "react-native";
-import { Provider, Portal } from "react-native-paper";
+import {
+ Provider,
+ Portal,
+ Appbar as MaterialAppbar,
+ IconButton,
+} from "react-native-paper";
import { useDispatch } from "react-redux";
import {
bookmarkChapterAction,
+ deleteAllChaptersAction,
+ downloadAllChaptersAction,
getNovelAction,
markChapterReadAction,
+ markChaptersRead,
markChapterUnreadAction,
+ markPreviousChaptersReadAction,
sortAndFilterChapters,
updateNovelAction,
} from "../../redux/novel/novel.actions";
@@ -25,6 +40,7 @@ import NovelInfoHeader from "./components/NovelHeader";
import ChaptersSettingsSheet from "./components/ChaptersSettingsSheet";
import TrackSheet from "./components/Tracker/TrackSheet";
import ChapterActionsSheet from "./components/ChapterActionsSheet";
+import { Appbar } from "../../Components/Appbar";
const Novel = ({ route, navigation }) => {
const item = route.params;
@@ -34,7 +50,7 @@ const Novel = ({ route, navigation }) => {
const dispatch = useDispatch();
const { novel, chapters, loading, updating, downloading } = useNovel();
- const [selected, setSelected] = useState();
+ const [selected, setSelected] = useState([]);
let chaptersSettingsSheetRef = useRef(null);
let trackerSheetRef = useRef(null);
@@ -82,6 +98,7 @@ const Novel = ({ route, navigation }) => {
downloading={downloading}
selected={selected}
novelName={novelName}
+ selected={selected}
setSelected={setSelected}
chapterActionsSheetRef={chapterActionsSheetRef}
/>
@@ -95,6 +112,116 @@ const Novel = ({ route, navigation }) => {
{ backgroundColor: theme.colorPrimaryDark },
]}
>
+ {selected.length > 0 ? (
+
+ {
+ setSelected([]);
+ }}
+ />
+
+ {
+ dispatch(bookmarkChapterAction(selected));
+ setSelected([]);
+ }}
+ />
+
+ {selected.some((obj) => obj.read === 0) && (
+ {
+ dispatch(markChaptersRead(selected));
+ setSelected([]);
+ }}
+ />
+ )}
+ {selected.some((obj) => obj.read === 1) && (
+ {
+ dispatch(markChapterUnreadAction(selected));
+ setSelected([]);
+ }}
+ />
+ )}
+ {selected.length === 1 && (
+ {
+ dispatch(
+ markPreviousChaptersReadAction(
+ selected[0].chapterId,
+ selected[0].novelId
+ )
+ );
+ setSelected([]);
+ }}
+ />
+ )}
+ {selected.some((obj) => obj.downloaded === 1) && (
+ {
+ dispatch(deleteAllChaptersAction(selected));
+ setSelected([]);
+ }}
+ />
+ )}
+
+ {selected.some((obj) => obj.downloaded === 0) && (
+ {
+ dispatch(
+ downloadAllChaptersAction(
+ novel.sourceId,
+ novel.novelUrl,
+ selected
+ )
+ );
+ setSelected([]);
+ }}
+ />
+ )}
+ {
+ setSelected(chapters);
+ }}
+ />
+
+ ) : (
+ navigation.goBack()}
+ style={{
+ position: "absolute",
+ zIndex: 1,
+ top: StatusBar.currentHeight + 8,
+ left: 8,
+ }}
+ />
+ )}
item.chapterId.toString()}
@@ -138,7 +265,7 @@ const Novel = ({ route, navigation }) => {
novelName={novel.novelName}
theme={theme}
/>
- {
markChapterReadAction={markChapterReadAction}
markChapterUnreadAction={markChapterUnreadAction}
bookmarkChapterAction={bookmarkChapterAction}
- />
+ /> */}
)}
diff --git a/src/Screens/Novel/components/ChapterItem.js b/src/Screens/Novel/components/ChapterItem.js
index a20a92bb..dd497dd6 100644
--- a/src/Screens/Novel/components/ChapterItem.js
+++ b/src/Screens/Novel/components/ChapterItem.js
@@ -1,6 +1,8 @@
import React, { useState } from "react";
import { View, Text, ActivityIndicator, StyleSheet } from "react-native";
+
import { TouchableRipple, IconButton, Menu } from "react-native-paper";
+import * as Haptics from "expo-haptics";
import {
deleteChapterAction,
@@ -17,6 +19,7 @@ const ChapterItem = ({
navigation,
downloading,
position,
+ selected,
setSelected,
chapterActionsSheetRef,
}) => {
@@ -112,16 +115,44 @@ const ChapterItem = ({
}
};
+ const isSelected = (chapterId) => {
+ return selected.some((obj) => obj.chapterId === chapterId);
+ };
+
return (
{
+ if (selected.length === 0) {
+ navigateToChapter();
+ } else {
+ if (isSelected(chapter.chapterId)) {
+ setSelected((selected) =>
+ selected.filter(
+ (item) => item.chapterId !== chapter.chapterId
+ )
+ );
+ } else {
+ setSelected((selected) => [...selected, chapter]);
+ }
+ }
+ }}
onLongPress={() => {
- setSelected(chapter);
- chapterActionsSheetRef.current.show();
+ if (isSelected(chapter.chapterId)) {
+ setSelected((selected) =>
+ selected.filter(
+ (item) => item.chapterId !== chapter.chapterId
+ )
+ );
+ } else {
+ setSelected((selected) => [...selected, chapter]);
+ }
+ // chapterActionsSheetRef.current.show();
}}
rippleColor={theme.rippleColor}
>
diff --git a/src/redux/novel/novel.actions.js b/src/redux/novel/novel.actions.js
index 796250e0..d3fc9f6b 100644
--- a/src/redux/novel/novel.actions.js
+++ b/src/redux/novel/novel.actions.js
@@ -36,6 +36,7 @@ import {
bookmarkChapter,
markPreviuschaptersRead,
markPreviousChaptersUnread,
+ getNextChapterFromDB,
} from "../../Database/queries/ChapterQueries";
import { deleteNovelUpdates } from "../../Database/queries/UpdateQueries";
import {
@@ -54,58 +55,66 @@ export const setNovel = (novel) => async (dispatch) => {
export const getNovelAction =
(followed, sourceId, novelUrl, novelId, sort, filter) =>
async (dispatch) => {
- dispatch({ type: LOADING_NOVEL });
+ try {
+ dispatch({ type: LOADING_NOVEL });
- if (followed === 1) {
- /**
- * If novel is followed directly get the chapters from db.
- */
- const chapters = await getChapters(novelId, sort, filter);
-
- dispatch({
- type: GET_CHAPTERS,
- payload: chapters,
- });
- } else {
- dispatch({ type: FETCHING_NOVEL });
-
- /**
- * Check if novel is cached.
- */
- const novel = await getNovel(sourceId, novelUrl);
-
- if (novel) {
+ if (followed === 1) {
/**
- * Get chapters from db.
+ * If novel is followed directly get the chapters from db.
*/
- novel.chapters = await getChapters(novel.novelId, sort, filter);
+ const chapters = await getChapters(novelId, sort, filter);
+
dispatch({
- type: GET_NOVEL,
- payload: novel,
+ type: GET_CHAPTERS,
+ payload: chapters,
});
} else {
- /**
- * Fetch novel from source.
- */
- const fetchedNovel = await fetchNovel(sourceId, novelUrl);
+ dispatch({ type: FETCHING_NOVEL });
/**
- * Insert novel in db.
- */
- const fetchedNovelId = await insertNovel(fetchedNovel);
- await insertChapters(fetchedNovelId, fetchedNovel.chapters);
-
- /**
- * Get novel from db.
+ * Check if novel is cached.
*/
const novel = await getNovel(sourceId, novelUrl);
- novel.chapters = await getChapters(novel.novelId);
- dispatch({
- type: GET_NOVEL,
- payload: novel,
- });
+ if (novel) {
+ /**
+ * Get chapters from db.
+ */
+ novel.chapters = await getChapters(
+ novel.novelId,
+ sort,
+ filter
+ );
+ dispatch({
+ type: GET_NOVEL,
+ payload: novel,
+ });
+ } else {
+ /**
+ * Fetch novel from source.
+ */
+ const fetchedNovel = await fetchNovel(sourceId, novelUrl);
+
+ /**
+ * Insert novel in db.
+ */
+ const fetchedNovelId = await insertNovel(fetchedNovel);
+ await insertChapters(fetchedNovelId, fetchedNovel.chapters);
+
+ /**
+ * Get novel from db.
+ */
+ const novel = await getNovel(sourceId, novelUrl);
+ novel.chapters = await getChapters(novel.novelId);
+
+ dispatch({
+ type: GET_NOVEL,
+ payload: novel,
+ });
+ }
}
+ } catch (error) {
+ showToast(error.message);
}
};
@@ -146,15 +155,19 @@ export const followNovelAction = (novel) => async (dispatch) => {
showToast(!novel.followed ? "Added to library" : "Removed from library");
};
-export const bookmarkChapterAction =
- (bookmark, chapterId) => async (dispatch) => {
- await bookmarkChapter(bookmark, chapterId);
+export const bookmarkChapterAction = (chapters) => async (dispatch) => {
+ chapters.map((chapter) => {
+ bookmarkChapter(chapter.bookmark, chapter.chapterId);
dispatch({
type: BOOKMARK_CHAPTER,
- payload: { bookmark, chapterId },
+ payload: {
+ bookmark: chapter.bookmark,
+ chapterId: chapter.chapterId,
+ },
});
- };
+ });
+};
export const markChapterReadAction =
(chapterId, novelId) => async (dispatch) => {
@@ -165,9 +178,11 @@ export const markChapterReadAction =
payload: { chapterId },
});
+ const nextChapter = await getNextChapterFromDB(novelId, chapterId);
+
dispatch({
type: SET_LAST_READ,
- payload: { novelId, chapterId: chapterId + 1 },
+ payload: { novelId, chapterId: nextChapter.chapterId },
});
/**
@@ -192,8 +207,51 @@ export const markPreviousChaptersReadAction =
type: MARK_PREVIOUS_CHAPTERS_READ,
payload: chapterId,
});
+
+ showToast("Marked previous chapters read");
};
+export const markChaptersRead = (chapters) => async (dispatch) => {
+ try {
+ chapters.map(async (chapter) => {
+ await markChapterRead(chapter.chapterId);
+
+ dispatch({
+ type: CHAPTER_READ,
+ payload: { chapterId: chapter.chapterId },
+ });
+
+ const nextChapter = await getNextChapterFromDB(
+ chapter.novelId,
+ chapter.chapterId
+ );
+
+ dispatch({
+ type: SET_LAST_READ,
+ payload: {
+ novelId: chapter.novelId,
+ chapterId: nextChapter.chapterId,
+ },
+ });
+
+ /**
+ * Reset progress on marked read
+ */
+ dispatch({
+ type: SAVE_SCROLL_POSITION,
+ payload: {
+ position: 0,
+ percentage: 0,
+ chapterId: chapter.chapterId,
+ novelId: chapter.novelId,
+ },
+ });
+ });
+ } catch (error) {
+ showToast(error.message);
+ }
+};
+
export const markPreviousChaptersUnreadAction =
(chapterId, novelId) => async (dispatch) => {
await markPreviousChaptersUnread(chapterId, novelId);
@@ -204,12 +262,14 @@ export const markPreviousChaptersUnreadAction =
});
};
-export const markChapterUnreadAction = (chapterId) => async (dispatch) => {
- await markChapterUnread(chapterId);
+export const markChapterUnreadAction = (chapters) => async (dispatch) => {
+ await chapters.map((chapter) => {
+ markChapterUnread(chapter.chapterId);
- dispatch({
- type: CHAPTER_UNREAD,
- payload: { chapterId },
+ dispatch({
+ type: CHAPTER_UNREAD,
+ payload: { chapterId: chapter.chapterId },
+ });
});
};
@@ -233,30 +293,36 @@ export const downloadChapterAction =
export const downloadAllChaptersAction =
(extensionId, novelUrl, chapters) => async (dispatch) => {
- await chapters.map((chapter, index) => {
- setTimeout(async () => {
- dispatch({
- type: CHAPTER_DOWNLOADING,
- payload: chapter.chapterId,
- });
+ try {
+ await chapters.map((chapter, index) => {
+ setTimeout(async () => {
+ dispatch({
+ type: CHAPTER_DOWNLOADING,
+ payload: chapter.chapterId,
+ });
- if (!chapter.downloaded) {
- await downloadChapter(
- extensionId,
- novelUrl,
- chapter.chapterUrl,
- chapter.chapterId
- );
- }
+ if (!chapter.downloaded) {
+ await downloadChapter(
+ extensionId,
+ novelUrl,
+ chapter.chapterUrl,
+ chapter.chapterId
+ );
+ }
- dispatch({
- type: CHAPTER_DOWNLOADED,
- payload: chapter.chapterId,
- });
- }, 1000 * index);
- });
+ dispatch({
+ type: CHAPTER_DOWNLOADED,
+ payload: chapter.chapterId,
+ });
- showToast(`All chapters downloaded`);
+ if (index + 1 === chapters.length) {
+ showToast(`Download completed `);
+ }
+ }, 1000 * index);
+ });
+ } catch (error) {
+ showToast(error.message);
+ }
};
export const deleteChapterAction =
@@ -281,7 +347,7 @@ export const deleteAllChaptersAction = (chapters) => async (dispatch) => {
});
});
- showToast("Deleted all chapters");
+ showToast("Chapters deleted");
};
export const updateNovelAction =
diff --git a/src/redux/source/source.actions.js b/src/redux/source/source.actions.js
index 2a315599..0f5961fa 100644
--- a/src/redux/source/source.actions.js
+++ b/src/redux/source/source.actions.js
@@ -1,13 +1,18 @@
import { GET_SOURCES, PIN_SOURCES, SEARCH_SOURCES } from "./source.types";
import { fetchSources } from "../../Services/Source/source";
+import { showToast } from "../../Hooks/showToast";
export const getSourcesAction = () => async (dispatch) => {
- const res = await fetchSources();
+ try {
+ const res = await fetchSources();
- dispatch({
- type: GET_SOURCES,
- payload: res,
- });
+ dispatch({
+ type: GET_SOURCES,
+ payload: res,
+ });
+ } catch (error) {
+ showToast(error.message);
+ }
};
export const searchSourcesAction = (searchText) => async (dispatch) => {
diff --git a/src/redux/store.js b/src/redux/store.js
index 3c2017b9..6ffcb53d 100644
--- a/src/redux/store.js
+++ b/src/redux/store.js
@@ -6,7 +6,6 @@ import thunk from "redux-thunk";
import settingsReducer from "./settings/settings.reducer";
import libraryReducer from "./library/library.reducer";
import sourceReducer from "./source/source.reducers";
-import chapterReducer from "./chapter/chapter.reducer";
import novelReducer from "./novel/novel.reducer";
import historyReducer from "./history/history.reducer";
import updatesReducer from "./updates/updates.reducer";
@@ -16,7 +15,7 @@ import preferenceReducer from "./preferences/preference.reducer";
const persistConfig = {
key: "root",
storage: AsyncStorage,
- blacklist: ["novelReducer", "chapterReducer"],
+ blacklist: ["novelReducer"],
};
const persistedReducer = persistReducer(
@@ -27,7 +26,6 @@ const persistedReducer = persistReducer(
sourceReducer,
novelReducer,
historyReducer,
- chapterReducer,
updatesReducer,
trackerReducer,
preferenceReducer,