fix: categories and update library on novel import (#1498)
* update epub * fix categorization of novels * fix: update library when importing novel * update categories on change
This commit is contained in:
Generated
+21
-119
@@ -8,7 +8,7 @@
|
||||
"name": "lnreader",
|
||||
"version": "2.0.0",
|
||||
"dependencies": {
|
||||
"@cd-z/react-native-epub-creator": "^2.0.4",
|
||||
"@cd-z/react-native-epub-creator": "^3.0.0",
|
||||
"@gorhom/bottom-sheet": "^5.1.4",
|
||||
"@legendapp/list": "^1.0.0-beta.24",
|
||||
"@react-native-community/slider": "4.5.6",
|
||||
@@ -48,6 +48,7 @@
|
||||
"react-native-drawer-layout": "^4.0.3",
|
||||
"react-native-edge-to-edge": "^1.6.0",
|
||||
"react-native-error-boundary": "^1.1.16",
|
||||
"react-native-file-access": "^3.1.1",
|
||||
"react-native-gesture-handler": "~2.25.0",
|
||||
"react-native-lottie-splash-screen": "^1.0.1",
|
||||
"react-native-mmkv": "^3.1.0",
|
||||
@@ -2252,22 +2253,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@cd-z/epub-constructor": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@cd-z/epub-constructor/-/epub-constructor-2.2.5.tgz",
|
||||
"integrity": "sha512-THLKTB3TppEPBE9I9M6IPEo3JGrD575/Wt2dEUig9hzIKox4vEWqygXFbnJgibjI3SudUeSnhUyLkh4S7pEBzg==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@cd-z/epub-constructor/-/epub-constructor-3.0.1.tgz",
|
||||
"integrity": "sha512-gI8eZ2+YnkflO48p+IjRVjFMJXv/86MYNdL6cxZUNd+GPEv3XBebg/hrHKXvTGTcBA3502CnwBf0hWoQyx3OoQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-html-parser": "^4.1.4"
|
||||
"sanitize-html": "^2.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cd-z/react-native-epub-creator": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@cd-z/react-native-epub-creator/-/react-native-epub-creator-2.0.4.tgz",
|
||||
"integrity": "sha512-bVCE0J9lNjT2JaEVqfjU4kI5Fq4cI4KObWnNfo0NBeCjU89s6+3oHme1yKI/Xm2cq7QDWIklRW/WPXGAO4IE1A==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@cd-z/react-native-epub-creator/-/react-native-epub-creator-3.0.0.tgz",
|
||||
"integrity": "sha512-vpI3viNxkSJWuSCuotFKfe1Ulg7Z+VPBTSt4GkGSGwHwpZxkNnh/UOZqyHBTtn3yvjaq2PK3GABDZlxlDhiQvA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cd-z/epub-constructor": "^2.1.0",
|
||||
"expo-file-system": "^15.2.2",
|
||||
"@cd-z/epub-constructor": "^3.0.0",
|
||||
"react-native-file-access": "^3.1.0",
|
||||
"react-native-saf-x": "^2.2.1",
|
||||
"react-native-zip-archive": "^6.0.3"
|
||||
},
|
||||
@@ -2276,18 +2277,6 @@
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@cd-z/react-native-epub-creator/node_modules/expo-file-system": {
|
||||
"version": "15.9.0",
|
||||
"resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-15.9.0.tgz",
|
||||
"integrity": "sha512-ikzqBGpbSzp/57+aruXzRR2s0HEVYxdd1o3RxfswJRujjT/6X128xmUTTFDaQUr+zydyvxvY7Mo0szWpXhPyLA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uuid": "^3.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@cd-z/react-native-epub-creator/node_modules/react-native-zip-archive": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-zip-archive/-/react-native-zip-archive-6.1.2.tgz",
|
||||
@@ -2298,16 +2287,6 @@
|
||||
"react-native": ">=0.60.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cd-z/react-native-epub-creator/node_modules/uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@egjs/hammerjs": {
|
||||
"version": "2.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
|
||||
@@ -9794,15 +9773,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/he": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"he": "bin/he"
|
||||
}
|
||||
},
|
||||
"node_modules/hermes-estree": {
|
||||
"version": "0.25.1",
|
||||
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
|
||||
@@ -12697,84 +12667,6 @@
|
||||
"node": ">= 6.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-html-parser": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-4.1.5.tgz",
|
||||
"integrity": "sha512-NLgqUXtftqnBqIjlRjYSaApaqE7TTxfTiH4VqKCjdUJKFOtUzRwney83EHz2qYc0XoxXAkYdmLjENCuZHvsIFg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"css-select": "^4.1.3",
|
||||
"he": "1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-html-parser/node_modules/css-select": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
|
||||
"integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"boolbase": "^1.0.0",
|
||||
"css-what": "^6.0.1",
|
||||
"domhandler": "^4.3.1",
|
||||
"domutils": "^2.8.0",
|
||||
"nth-check": "^2.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
},
|
||||
"node_modules/node-html-parser/node_modules/dom-serializer": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
|
||||
"integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.2.0",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/node-html-parser/node_modules/domhandler": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
|
||||
"integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/node-html-parser/node_modules/domutils": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
|
||||
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"dom-serializer": "^1.0.1",
|
||||
"domelementtype": "^2.2.0",
|
||||
"domhandler": "^4.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/node-html-parser/node_modules/entities": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
|
||||
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
|
||||
"license": "BSD-2-Clause",
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/node-int64": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
|
||||
@@ -14091,6 +13983,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-file-access": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-file-access/-/react-native-file-access-3.1.1.tgz",
|
||||
"integrity": "sha512-4KUpBAsnWJa+AQf1tUbLdHO+1pyiZMTeq3NPf5XOGdz1O5CwIrVkrzl+gkN7ffmUa5JyoYHyXUtwScmA+z0Tlg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-gesture-handler": {
|
||||
"version": "2.25.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.25.0.tgz",
|
||||
|
||||
+2
-1
@@ -25,7 +25,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@cd-z/react-native-epub-creator": "^2.0.4",
|
||||
"@cd-z/react-native-epub-creator": "^3.0.0",
|
||||
"@gorhom/bottom-sheet": "^5.1.4",
|
||||
"@legendapp/list": "^1.0.0-beta.24",
|
||||
"@react-native-community/slider": "4.5.6",
|
||||
@@ -65,6 +65,7 @@
|
||||
"react-native-drawer-layout": "^4.0.3",
|
||||
"react-native-edge-to-edge": "^1.6.0",
|
||||
"react-native-error-boundary": "^1.1.16",
|
||||
"react-native-file-access": "^3.1.1",
|
||||
"react-native-gesture-handler": "~2.25.0",
|
||||
"react-native-lottie-splash-screen": "^1.0.1",
|
||||
"react-native-mmkv": "^3.1.0",
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { useLibraryContext } from '@components/Context/LibraryContext';
|
||||
import ServiceManager, { BackgroundTask } from '@services/ServiceManager';
|
||||
import { DocumentPickerResult } from 'expo-document-picker';
|
||||
import { useMemo } from 'react';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useMMKVObject } from 'react-native-mmkv';
|
||||
|
||||
export default function useImport() {
|
||||
const { refetchLibrary } = useLibraryContext();
|
||||
const [queue] = useMMKVObject<BackgroundTask[]>(
|
||||
ServiceManager.manager.STORE_KEY,
|
||||
);
|
||||
@@ -12,7 +14,11 @@ export default function useImport() {
|
||||
[queue],
|
||||
);
|
||||
|
||||
const importNovel = (pickedNovel: DocumentPickerResult) => {
|
||||
useEffect(() => {
|
||||
refetchLibrary();
|
||||
}, [importQueue, refetchLibrary]);
|
||||
|
||||
const importNovel = useCallback((pickedNovel: DocumentPickerResult) => {
|
||||
if (pickedNovel.canceled) return;
|
||||
ServiceManager.manager.addTask(
|
||||
pickedNovel.assets.map(asset => ({
|
||||
@@ -23,7 +29,7 @@ export default function useImport() {
|
||||
},
|
||||
})),
|
||||
);
|
||||
};
|
||||
}, []);
|
||||
const resumeImport = () => ServiceManager.manager.resume();
|
||||
|
||||
const pauseImport = () => ServiceManager.manager.pause();
|
||||
|
||||
@@ -1,31 +1,28 @@
|
||||
import { FlatList, StyleSheet } from 'react-native';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { FAB } from 'react-native-paper';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
|
||||
import { Appbar, EmptyView, SafeAreaView } from '@components/index';
|
||||
import AddCategoryModal from './components/AddCategoryModal';
|
||||
|
||||
import {
|
||||
getCategoriesFromDb,
|
||||
updateCategoryOrderInDb,
|
||||
} from '@database/queries/CategoryQueries';
|
||||
import { updateCategoryOrderInDb } from '@database/queries/CategoryQueries';
|
||||
import { useBoolean } from '@hooks';
|
||||
import { useTheme } from '@hooks/persisted';
|
||||
import { getString } from '@strings/translations';
|
||||
|
||||
import { Category } from '@database/types';
|
||||
import CategoryCard from './components/CategoryCard';
|
||||
import { orderBy } from 'lodash-es';
|
||||
import CategorySkeletonLoading from './components/CategorySkeletonLoading';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useLibraryContext } from '@components/Context/LibraryContext';
|
||||
|
||||
const CategoriesScreen = () => {
|
||||
const { categories, setCategories, refreshCategories, isLoading } =
|
||||
useLibraryContext();
|
||||
const theme = useTheme();
|
||||
const { goBack } = useNavigation();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [categories, setCategories] = useState<Category[]>();
|
||||
const { bottom, right } = useSafeAreaInsets();
|
||||
|
||||
const {
|
||||
@@ -34,25 +31,17 @@ const CategoriesScreen = () => {
|
||||
setFalse: closeCategoryModal,
|
||||
} = useBoolean();
|
||||
|
||||
const getCategories = async () => {
|
||||
try {
|
||||
const res = getCategoriesFromDb();
|
||||
setCategories(res);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getCategories();
|
||||
}, []);
|
||||
refreshCategories();
|
||||
}, [refreshCategories]);
|
||||
|
||||
const updateCategorySort = (currentIndex: number, newIndex: number) => {
|
||||
// Do not set local as default one
|
||||
if (
|
||||
(newIndex === 0 &&
|
||||
currentIndex == 1 &&
|
||||
currentIndex === 1 &&
|
||||
categories?.[currentIndex].id === 2) ||
|
||||
(newIndex === 1 && currentIndex == 0 && categories?.[newIndex].id === 2)
|
||||
(newIndex === 1 && currentIndex === 0 && categories?.[newIndex].id === 2)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -91,7 +80,7 @@ const CategoriesScreen = () => {
|
||||
renderItem={({ item, index }) => (
|
||||
<CategoryCard
|
||||
category={item}
|
||||
getCategories={getCategories}
|
||||
getCategories={refreshCategories}
|
||||
categoryIndex={index}
|
||||
updateCategorySort={updateCategorySort}
|
||||
totalCategories={categories?.length || 0}
|
||||
@@ -118,7 +107,7 @@ const CategoriesScreen = () => {
|
||||
<AddCategoryModal
|
||||
visible={categoryModalVisible}
|
||||
closeModal={closeCategoryModal}
|
||||
onSuccess={getCategories}
|
||||
onSuccess={refreshCategories}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
||||
@@ -37,6 +37,10 @@ const AddCategoryModal: React.FC<AddCategoryModalProps> = ({
|
||||
setCategoryName('');
|
||||
closeModal();
|
||||
}
|
||||
function finalize() {
|
||||
onSuccess();
|
||||
close();
|
||||
}
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
@@ -69,8 +73,7 @@ const AddCategoryModal: React.FC<AddCategoryModalProps> = ({
|
||||
} else {
|
||||
createCategory(categoryName);
|
||||
}
|
||||
onSuccess();
|
||||
close();
|
||||
finalize();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -289,6 +289,18 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => {
|
||||
],
|
||||
);
|
||||
|
||||
const navigationState = useMemo(
|
||||
() => ({
|
||||
index,
|
||||
routes: categories.map(category => ({
|
||||
key: String(category.id),
|
||||
title: category.name,
|
||||
...category,
|
||||
})),
|
||||
}),
|
||||
[categories, index],
|
||||
);
|
||||
|
||||
return (
|
||||
<SafeAreaView excludeBottom>
|
||||
<SearchbarV2
|
||||
@@ -372,14 +384,7 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => {
|
||||
label: renderLabel,
|
||||
}}
|
||||
lazy
|
||||
navigationState={{
|
||||
index,
|
||||
routes: categories.map(category => ({
|
||||
key: String(category.id),
|
||||
title: category.name,
|
||||
...category,
|
||||
})),
|
||||
}}
|
||||
navigationState={navigationState}
|
||||
renderTabBar={renderTabBar}
|
||||
renderScene={renderScene}
|
||||
onIndexChange={setIndex}
|
||||
|
||||
@@ -12,7 +12,6 @@ import { getString } from '@strings/translations';
|
||||
import { useTheme } from '@hooks/persisted';
|
||||
import { LibraryScreenProps } from '@navigators/types';
|
||||
import ServiceManager from '@services/ServiceManager';
|
||||
import { useLibraryContext } from '@components/Context/LibraryContext';
|
||||
|
||||
interface Props {
|
||||
categoryId: number;
|
||||
@@ -31,8 +30,8 @@ export const LibraryView: React.FC<Props> = ({
|
||||
setSelectedNovelIds,
|
||||
pickAndImport,
|
||||
navigation,
|
||||
novels,
|
||||
}) => {
|
||||
const { library } = useLibraryContext();
|
||||
const theme = useTheme();
|
||||
const renderItem = ({ item }: { item: NovelInfo }) => {
|
||||
return (
|
||||
@@ -80,7 +79,7 @@ export const LibraryView: React.FC<Props> = ({
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<NovelList
|
||||
data={library}
|
||||
data={novels}
|
||||
extraData={[selectedNovelIds]}
|
||||
renderItem={renderItem as NovelListRenderItem}
|
||||
ListEmptyComponent={
|
||||
|
||||
@@ -16,6 +16,8 @@ export type UseLibraryReturnType = {
|
||||
library: NovelInfo[];
|
||||
categories: ExtendedCategory[];
|
||||
isLoading: boolean;
|
||||
setCategories: React.Dispatch<React.SetStateAction<ExtendedCategory[]>>;
|
||||
refreshCategories: () => Promise<void>;
|
||||
setLibrary: React.Dispatch<React.SetStateAction<NovelInfo[]>>;
|
||||
novelInLibrary: (pluginId: string, novelPath: string) => boolean;
|
||||
switchNovelToLibrary: (novelPath: string, pluginId: string) => Promise<void>;
|
||||
@@ -35,26 +37,30 @@ export const useLibrary = (): UseLibraryReturnType => {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
|
||||
const getLibrary = useCallback(async () => {
|
||||
if (searchText) {
|
||||
setIsLoading(true);
|
||||
}
|
||||
const refreshCategories = useCallback(async () => {
|
||||
const dbCategories = getCategoriesFromDb();
|
||||
|
||||
const [categories, novels] = await Promise.all([
|
||||
getCategoriesFromDb(),
|
||||
getLibraryNovelsFromDb(sortOrder, filter, searchText, downloadedOnlyMode),
|
||||
// getLibraryNovelsFromDb(),
|
||||
]);
|
||||
|
||||
const res = categories.map(c => ({
|
||||
const res = dbCategories.map(c => ({
|
||||
...c,
|
||||
novelIds: (c.novelIds ?? '').split(',').map(Number),
|
||||
}));
|
||||
|
||||
setCategories(res);
|
||||
}, []);
|
||||
|
||||
const getLibrary = useCallback(async () => {
|
||||
if (searchText) {
|
||||
setIsLoading(true);
|
||||
}
|
||||
|
||||
const [_, novels] = await Promise.all([
|
||||
refreshCategories(),
|
||||
getLibraryNovelsFromDb(sortOrder, filter, searchText, downloadedOnlyMode),
|
||||
]);
|
||||
|
||||
setLibrary(novels);
|
||||
setIsLoading(false);
|
||||
}, [downloadedOnlyMode, filter, searchText, sortOrder]);
|
||||
}, [downloadedOnlyMode, filter, refreshCategories, searchText, sortOrder]);
|
||||
|
||||
const novelInLibrary = useCallback(
|
||||
(pluginId: string, novelPath: string) =>
|
||||
@@ -91,6 +97,8 @@ export const useLibrary = (): UseLibraryReturnType => {
|
||||
categories,
|
||||
isLoading,
|
||||
setLibrary,
|
||||
setCategories,
|
||||
refreshCategories,
|
||||
novelInLibrary,
|
||||
switchNovelToLibrary,
|
||||
refetchLibrary: getLibrary,
|
||||
|
||||
Reference in New Issue
Block a user