Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix tabiew #939

Merged
merged 4 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/database/queries/ChapterQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -42,7 +42,6 @@ export const insertChapters = async (
chapter.chapterNumber || null,
],
noop,
txnErrorCallback,
);
});
});
Expand Down
56 changes: 33 additions & 23 deletions src/database/queries/NovelQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 || '',
Expand All @@ -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) => {
Expand Down
22 changes: 14 additions & 8 deletions src/screens/BrowseSourceScreen/useBrowseSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
Expand Down
4 changes: 3 additions & 1 deletion src/screens/browse/migration/MigrationNovelList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ const MigrationNovelList = ({
<Button
onPress={() => {
hideMigrateNovelDialog();
migrateNovel(pluginId, fromNovel, selectedNovel.url);
migrateNovel(pluginId, fromNovel, selectedNovel.url).catch(
error => showToast(error.message),
);
}}
title={getString('novelScreen.migrate')}
/>
Expand Down
81 changes: 42 additions & 39 deletions src/screens/library/LibraryScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,44 +85,47 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => {

const renderTabBar = (
props: SceneRendererProps & { navigationState: State },
) => (
<TabBar
{...props}
scrollEnabled
indicatorStyle={{ backgroundColor: theme.primary }}
style={[
{
backgroundColor: theme.surface,
borderBottomColor: color(theme.isDark ? '#FFFFFF' : '#000000')
.alpha(0.12)
.string(),
},
styles.tabBar,
]}
renderLabel={({ route, color }) => (
<Row>
<Text style={{ color }}>{route.title}</Text>
{showNumberOfNovels && (
<View
style={[
styles.badgeCtn,
{ backgroundColor: theme.surfaceVariant },
]}
>
<Text
style={[styles.badgetText, { color: theme.onSurfaceVariant }]}
) =>
library.length ? (
<TabBar
{...props}
scrollEnabled
indicatorStyle={{ backgroundColor: theme.primary, height: 3 }}
style={[
{
backgroundColor: theme.surface,
borderBottomColor: color(theme.isDark ? '#FFFFFF' : '#000000')
.alpha(0.12)
.string(),
},
styles.tabBar,
]}
tabStyle={{ width: 'auto' }}
gap={8}
renderLabel={({ route, color }) => (
<Row>
<Text style={{ color, fontWeight: '600' }}>{route.title}</Text>
{showNumberOfNovels && (
<View
style={[
styles.badgeCtn,
{ backgroundColor: theme.surfaceVariant },
]}
>
{(route as any)?.novels.length}
</Text>
</View>
)}
</Row>
)}
inactiveColor={theme.secondary}
activeColor={theme.primary}
pressColor={theme.rippleColor}
/>
);
<Text
style={[styles.badgetText, { color: theme.onSurfaceVariant }]}
>
{(route as any)?.novels.length}
</Text>
</View>
)}
</Row>
)}
inactiveColor={theme.secondary}
activeColor={theme.primary}
android_ripple={{ color: theme.rippleColor }}
/>
) : null;

const searchbarPlaceholder =
selectedNovelIds.length === 0
Expand Down Expand Up @@ -314,7 +317,6 @@ const styles = StyleSheet.create({
globalSearchBtn: {
margin: 16,
},

fab: {
position: 'absolute',
margin: 16,
Expand All @@ -324,8 +326,9 @@ const styles = StyleSheet.create({
badgeCtn: {
position: 'relative',
borderRadius: 50,
marginHorizontal: 6,
marginLeft: 2,
paddingHorizontal: 6,
paddingVertical: 2,
},
badgetText: {
fontSize: 12,
Expand Down
20 changes: 12 additions & 8 deletions src/screens/reader/ReaderScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,11 @@ export const ChapterContent = ({
if (await RNFS.exists(filePath)) {
sourceChapter.chapterText = await RNFS.readFile(filePath);
} else {
sourceChapter.chapterText = await fetchChapter(
novel.pluginId,
chapter.url,
);
await fetchChapter(novel.pluginId, chapter.url)
.then(res => {
sourceChapter.chapterText = res;
})
.catch(e => setError(e.message));
}
const [nextChap, prevChap] = await Promise.all([
getNextChapter(chapter.novelId, chapter.id),
Expand Down Expand Up @@ -276,10 +277,13 @@ export const ChapterContent = ({
const onWebViewNavigationStateChange = async ({ url }: WebViewNavigation) => {
if (url !== 'about:blank') {
setLoading(true);
const res = await fetchChapter(novel.pluginId, chapter.url);
sourceChapter.chapterText = res;
setChapter(sourceChapter);
setLoading(false);
fetchChapter(novel.pluginId, chapter.url)
.then(res => {
sourceChapter.chapterText = res;
setChapter(sourceChapter);
})
.catch(e => setError(e.message))
.finally(() => setLoading(false));
}
};

Expand Down
18 changes: 8 additions & 10 deletions src/services/backup/legacy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
Expand Down Expand Up @@ -105,20 +105,17 @@ 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;
}
await restoreLibrary(novels[i]);
await BackgroundService.updateNotification({
taskTitle: novels[i].name,
taskDesc: '(' + (i + 1) + '/' + novels.length + ')',
progressBar: { max: novels.length, value: i + 1 },
});
await restoreLibrary(novels[i]).catch(error => {
throw error;
});

if (novels.length === i + 1) {
Notifications.scheduleNotificationAsync({
Expand All @@ -130,7 +127,6 @@ export const restoreBackup = async (filePath?: string) => {
},
trigger: null,
});
MMKVStorage.delete(BACKGROUND_ACTION);
resolve();
}

Expand All @@ -143,8 +139,7 @@ export const restoreBackup = async (filePath?: string) => {
await sleep(taskData?.delay || 0);
}
}
} catch (error: any) {
showToast(novels[i].name + ': ' + error.message);
} catch (e) {
errorNovels.push(novels[i]);
continue;
}
Expand All @@ -169,6 +164,9 @@ export const restoreBackup = async (filePath?: string) => {
}
});
}
}).finally(() => {
MMKVStorage.delete(BACKGROUND_ACTION);
BackgroundService.stop();
});

if (novels.length > 0) {
Expand Down
4 changes: 3 additions & 1 deletion src/services/migrate/migrateNovel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ export const migrateNovel = async (
if (toNovel) {
toChapters = await getChapters(toNovel.id, '', '');
} else {
const fetchedNovel = await fetchNovel(pluginId, toNovelUrl);
const fetchedNovel = await fetchNovel(pluginId, toNovelUrl).catch(e => {
throw e;
});
await insertNovelAndChapters(pluginId, fetchedNovel);
toNovel = await getNovel(toNovelUrl);
if (!toNovel) {
Expand Down
18 changes: 14 additions & 4 deletions src/services/plugin/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,36 @@ import { getPlugin } from '@plugins/pluginManager';

export const fetchNovel = async (pluginId: string, novelUrl: string) => {
const plugin = getPlugin(pluginId);
const res = await plugin.parseNovelAndChapters(novelUrl);
const res = await plugin.parseNovelAndChapters(novelUrl).catch(e => {
throw e;
});
return res;
};

export const fetchImage = async (pluginId: string, imageUrl: string) => {
return getPlugin(pluginId).fetchImage(imageUrl);
return getPlugin(pluginId)
.fetchImage(imageUrl)
.catch(e => {
throw e;
});
};

export const fetchChapter = async (pluginId: string, chapterUrl: string) => {
const plugin = getPlugin(pluginId);
let chapterText = `Not found plugin with id: ${pluginId}`;
if (plugin) {
chapterText = await plugin.parseChapter(chapterUrl);
chapterText = await plugin.parseChapter(chapterUrl).catch(e => {
throw e;
});
}
return chapterText;
};

export const fetchChapters = async (pluginId: string, novelUrl: string) => {
const plugin = getPlugin(pluginId);
const res = await plugin.parseNovelAndChapters(novelUrl);
const res = await plugin.parseNovelAndChapters(novelUrl).catch(e => {
throw e;
});

const chapters = res.chapters;

Expand Down
Loading