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,