From fe860eb17683a0f377d2df2b4ad114595392d59a Mon Sep 17 00:00:00 2001 From: nyagami Date: Fri, 2 Feb 2024 15:48:46 +0700 Subject: [PATCH 1/4] fix: tabview look --- src/screens/library/LibraryScreen.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/screens/library/LibraryScreen.tsx b/src/screens/library/LibraryScreen.tsx index 8d365b24c..e22181eaf 100644 --- a/src/screens/library/LibraryScreen.tsx +++ b/src/screens/library/LibraryScreen.tsx @@ -89,7 +89,7 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => { { }, styles.tabBar, ]} + tabStyle={{ width: 'auto' }} + gap={8} renderLabel={({ route, color }) => ( - {route.title} + {route.title} {showNumberOfNovels && ( { )} inactiveColor={theme.secondary} activeColor={theme.primary} - pressColor={theme.rippleColor} + android_ripple={{ color: theme.rippleColor }} /> ); @@ -314,7 +316,6 @@ const styles = StyleSheet.create({ globalSearchBtn: { margin: 16, }, - fab: { position: 'absolute', margin: 16, @@ -324,8 +325,9 @@ const styles = StyleSheet.create({ badgeCtn: { position: 'relative', borderRadius: 50, - marginHorizontal: 6, + marginLeft: 2, paddingHorizontal: 6, + paddingVertical: 2, }, badgetText: { fontSize: 12, From 68dabdc19740ee19375ad460bd83d5bb1b2cb211 Mon Sep 17 00:00:00 2001 From: nyagami Date: Fri, 2 Feb 2024 16:35:54 +0700 Subject: [PATCH 2/4] fix: error when library is not fetched fully --- src/screens/library/LibraryScreen.tsx | 79 ++++++++++++++------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/src/screens/library/LibraryScreen.tsx b/src/screens/library/LibraryScreen.tsx index e22181eaf..c83311d8d 100644 --- a/src/screens/library/LibraryScreen.tsx +++ b/src/screens/library/LibraryScreen.tsx @@ -85,46 +85,47 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => { const renderTabBar = ( props: SceneRendererProps & { navigationState: State }, - ) => ( - ( - - {route.title} - {showNumberOfNovels && ( - - + library.length ? ( + ( + + {route.title} + {showNumberOfNovels && ( + - {(route as any)?.novels.length} - - - )} - - )} - inactiveColor={theme.secondary} - activeColor={theme.primary} - android_ripple={{ color: theme.rippleColor }} - /> - ); + + {(route as any)?.novels.length} + + + )} + + )} + inactiveColor={theme.secondary} + activeColor={theme.primary} + android_ripple={{ color: theme.rippleColor }} + /> + ) : null; const searchbarPlaceholder = selectedNovelIds.length === 0 From b216b48cfe466303ec539388790cb0208d8aa1ca Mon Sep 17 00:00:00 2001 From: nyagami Date: Fri, 2 Feb 2024 17:04:47 +0700 Subject: [PATCH 3/4] fix: legacy backup --- src/services/backup/legacy/index.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/services/backup/legacy/index.ts b/src/services/backup/legacy/index.ts index d772a4540..4734c7554 100644 --- a/src/services/backup/legacy/index.ts +++ b/src/services/backup/legacy/index.ts @@ -68,7 +68,7 @@ export const restoreBackup = async (filePath?: string) => { let novelsString = ''; if (backup.type === 'success') { - novelsString = await StorageAccessFramework.readAsStringAsync(backup.uri); + novelsString = await RNFS.readFile(backup.uri); } else if (filePath) { if (!(await RNFS.exists(filePath))) { showToast(getString('backupScreen.legacy.noErrorNovel')); @@ -105,11 +105,6 @@ export const restoreBackup = async (filePath?: string) => { if (BackgroundService.isRunning()) { const plugin = getPlugin(novels[i].pluginId); if (!plugin) { - showToast( - getString('backupScreen.legacy.pluginNotExist', { - id: novels[i].pluginId, - }), - ); errorNovels.push(novels[i]); continue; } @@ -169,6 +164,9 @@ export const restoreBackup = async (filePath?: string) => { } }); } + }).finally(() => { + MMKVStorage.delete(BACKGROUND_ACTION); + BackgroundService.stop(); }); if (novels.length > 0) { From fda2c4533310debab5949fdd625319578dbb8fc8 Mon Sep 17 00:00:00 2001 From: nyagami Date: Fri, 2 Feb 2024 21:22:46 +0700 Subject: [PATCH 4/4] fix: handle error for plugin methods --- src/database/queries/ChapterQueries.ts | 3 +- src/database/queries/NovelQueries.ts | 56 +++++++++++-------- .../BrowseSourceScreen/useBrowseSource.ts | 22 +++++--- .../browse/migration/MigrationNovelList.tsx | 4 +- src/screens/reader/ReaderScreen.tsx | 20 ++++--- src/services/backup/legacy/index.ts | 8 +-- src/services/migrate/migrateNovel.ts | 4 +- src/services/plugin/fetch.ts | 18 ++++-- 8 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/database/queries/ChapterQueries.ts b/src/database/queries/ChapterQueries.ts index 5830c3fa5..9851763f6 100644 --- a/src/database/queries/ChapterQueries.ts +++ b/src/database/queries/ChapterQueries.ts @@ -16,7 +16,7 @@ import { getString } from '@strings/translations'; const db = SQLite.openDatabase('lnreader.db'); const insertChapterQuery = ` -INSERT INTO Chapter ( +INSERT OR IGNORE INTO Chapter ( url, name, releaseTime, novelId, chapterNumber ) Values @@ -42,7 +42,6 @@ export const insertChapters = async ( chapter.chapterNumber || null, ], noop, - txnErrorCallback, ); }); }); diff --git a/src/database/queries/NovelQueries.ts b/src/database/queries/NovelQueries.ts index 35ebc853d..258af0f3b 100644 --- a/src/database/queries/NovelQueries.ts +++ b/src/database/queries/NovelQueries.ts @@ -4,7 +4,7 @@ const db = SQLite.openDatabase('lnreader.db'); import * as DocumentPicker from 'expo-document-picker'; import * as RNFS from 'react-native-fs'; -import { fetchChapters, fetchImage, fetchNovel } from '@services/plugin/fetch'; +import { fetchImage, fetchNovel } from '@services/plugin/fetch'; import { insertChapters } from './ChapterQueries'; import { showToast } from '@utils/showToast'; @@ -183,15 +183,18 @@ export const deleteCachedNovels = async () => { }; const restoreFromBackupQuery = - 'INSERT INTO Novel (url, name, pluginId, cover, summary, author, artist, status, genres, inLibrary) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; + 'INSERT OR REPLACE INTO Novel (url, name, pluginId, cover, summary, author, artist, status, genres) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)'; export const restoreLibrary = async (novel: NovelInfo) => { - return new Promise(resolve => { + const sourceNovel = await fetchNovel(novel.pluginId, novel.url).catch(e => { + throw e; + }); + const novelId: number | undefined = await new Promise(resolve => { db.transaction(tx => tx.executeSql( restoreFromBackupQuery, [ - novel.url, + sourceNovel.url, novel.name, novel.pluginId, novel.cover || '', @@ -200,29 +203,36 @@ export const restoreLibrary = async (novel: NovelInfo) => { novel.artist || '', novel.status || '', novel.genres || '', - Number(novel.inLibrary), ], - async (txObj, { insertId }) => { - if (!insertId) { - return; - } - tx.executeSql( - 'INSERT INTO NovelCategory (novelId, categoryId) VALUES (?, (SELECT DISTINCT id FROM Category WHERE sort = 1))', - [insertId], - noop, - txnErrorCallback, - ); - const chapters = await fetchChapters(novel.pluginId, novel.url); - - if (chapters) { - await insertChapters(insertId, chapters); - resolve(insertId); - } - }, - txnErrorCallback, + async (txObj, { insertId }) => resolve(insertId), ), ); }); + if (novelId && novelId > 0) { + await new Promise((resolve, reject) => { + db.transaction(async tx => { + tx.executeSql( + 'INSERT OR REPLACE INTO NovelCategory (novelId, categoryId) VALUES (?, (SELECT DISTINCT id FROM Category WHERE sort = 1))', + [novelId], + () => { + tx.executeSql('UPDATE Novel SET inLibrary = 1 WHERE id = ?', [ + novelId, + ]); + resolve(null); + }, + (txObj, err) => { + reject(err); + return false; + }, + ); + }); + }).catch(e => { + throw e; + }); + if (sourceNovel.chapters) { + await insertChapters(novelId, sourceNovel.chapters); + } + } }; export const updateNovelInfo = async (info: NovelInfo) => { diff --git a/src/screens/BrowseSourceScreen/useBrowseSource.ts b/src/screens/BrowseSourceScreen/useBrowseSource.ts index 55d03424a..9585c791b 100644 --- a/src/screens/BrowseSourceScreen/useBrowseSource.ts +++ b/src/screens/BrowseSourceScreen/useBrowseSource.ts @@ -28,14 +28,20 @@ export const useBrowseSource = ( if (isScreenMounted.current === true) { try { const plugin = getPlugin(pluginId); - const res = await plugin.popularNovels(page, { - showLatestNovels, - filters, - }); - setNovels(prevState => (page === 1 ? res : [...prevState, ...res])); - if (!res.length) { - setHasNextPage(false); - } + await plugin + .popularNovels(page, { + showLatestNovels, + filters, + }) + .then(res => { + setNovels(prevState => + page === 1 ? res : [...prevState, ...res], + ); + if (!res.length) { + setHasNextPage(false); + } + }) + .catch(error => setError(error.message)); setFilterValues(plugin.filters); } catch (err: unknown) { setError(`${err}`); diff --git a/src/screens/browse/migration/MigrationNovelList.tsx b/src/screens/browse/migration/MigrationNovelList.tsx index 849d38240..108ca6084 100644 --- a/src/screens/browse/migration/MigrationNovelList.tsx +++ b/src/screens/browse/migration/MigrationNovelList.tsx @@ -120,7 +120,9 @@ const MigrationNovelList = ({