From 0cf75fd6f951a1bba442fb71d6ee83f94fc30c95 Mon Sep 17 00:00:00 2001 From: nyagami Date: Mon, 22 Jan 2024 23:08:27 +0700 Subject: [PATCH] Fix: pre-alpha-patch-1 (#905) * fix: wrong version checker, update lastused * fix: only show update dialog if newer version * fix: remove chapter id in chapter item * fix: date in chapter drawer * fix: decode uri for local epub * fix: simpler SetCategoriesModal * fix: not allow local as default * fix: no delay on selfhost backup/restore --- src/database/queries/CategoryQueries.ts | 36 ++++++++++++- src/database/queries/NovelQueries.ts | 53 ++++++------------- src/database/types/index.ts | 4 ++ src/hooks/common/githubUpdateChecker.ts | 4 +- src/hooks/persisted/usePlugins.ts | 15 ++++-- src/plugins/pluginManager.ts | 3 +- src/screens/Categories/CategoriesScreen.tsx | 14 ++++- .../Categories/components/CategoryCard.tsx | 13 +++-- src/screens/novel/components/ChapterItem.tsx | 2 +- .../novel/components/SetCategoriesModal.tsx | 45 ++++------------ .../reader/components/ChapterDrawer.tsx | 48 +++++++++-------- src/services/backup/remote/index.ts | 2 - src/services/epub/import.ts | 3 +- src/utils/compareVersion.ts | 5 +- 14 files changed, 130 insertions(+), 117 deletions(-) diff --git a/src/database/queries/CategoryQueries.ts b/src/database/queries/CategoryQueries.ts index 69420668..3a98bfd9 100644 --- a/src/database/queries/CategoryQueries.ts +++ b/src/database/queries/CategoryQueries.ts @@ -1,6 +1,6 @@ import * as SQLite from 'expo-sqlite'; import { noop } from 'lodash-es'; -import { BackupCategory, Category, NovelCategory } from '../types'; +import { BackupCategory, Category, NovelCategory, CCategory } from '../types'; import { showToast } from '@utils/showToast'; import { txnErrorCallback } from '../utils/helpers'; const db = SQLite.openDatabase('lnreader.db'); @@ -22,6 +22,33 @@ export const getCategoriesFromDb = async (): Promise => { ); }; +export const getCategoriesWithCount = async ( + novelIds: number[], +): Promise => { + const getCategoriesWithCountQuery = ` + SELECT *, novelsCount + FROM Category LEFT JOIN + ( + SELECT categoryId, COUNT(novelId) as novelsCount + FROM NovelCategory WHERE novelId in (${novelIds.join( + ',', + )}) GROUP BY categoryId + ) as NC ON Category.id = NC.categoryId + ORDER BY sort + `; + + return new Promise(resolve => + db.transaction(tx => { + tx.executeSql( + getCategoriesWithCountQuery, + [], + (txObj, { rows }) => resolve((rows as any)._array), + txnErrorCallback, + ); + }), + ); +}; + const createCategoryQuery = 'INSERT INTO Category (name) VALUES (?)'; export const createCategory = (categoryName: string): void => @@ -94,7 +121,11 @@ export const isCategoryNameDuplicate = ( const updateCategoryOrderQuery = 'UPDATE Category SET sort = ? WHERE id = ?'; -export const updateCategoryOrderInDb = (categories: Category[]): void => +export const updateCategoryOrderInDb = (categories: Category[]): void => { + // Do not set local as default one + if (categories.length && categories[0].id == 2) { + return; + } db.transaction(tx => { categories.map(category => { tx.executeSql( @@ -105,6 +136,7 @@ export const updateCategoryOrderInDb = (categories: Category[]): void => ); }); }); +}; export const getAllNovelCategories = (): Promise => { return new Promise(resolve => diff --git a/src/database/queries/NovelQueries.ts b/src/database/queries/NovelQueries.ts index 73056cc9..8c8ee96c 100644 --- a/src/database/queries/NovelQueries.ts +++ b/src/database/queries/NovelQueries.ts @@ -100,9 +100,6 @@ export const switchNovelToLibrary = async ( ) => { const novel = await getNovel(novelUrl); if (novel) { - if (novel.isLocal) { - return; - } db.transaction(tx => { tx.executeSql( 'UPDATE Novel SET inLibrary = ? WHERE id = ?', @@ -288,45 +285,25 @@ export const updateNovelCategoryById = async ( export const updateNovelCategories = async ( novelIds: number[], categoryIds: number[], - option: string, ): Promise => { let queries: string[] = []; - // allow local novels have other categories, but not the revesre + // not allow others have local id; categoryIds = categoryIds.filter(id => id !== 2); - if (option === 'KEEP_OLD') { - novelIds.forEach(novelId => { - categoryIds.forEach(categoryId => - queries.push( - `INSERT OR REPLACE INTO NovelCategory (novelId, categoryId) VALUES (${novelId}, ${categoryId})`, - ), - ); - }); - } else { - novelIds.forEach(novelId => - queries.push(`DELETE FROM NovelCategory WHERE novelId = ${novelId}`), + queries.push( + `DELETE FROM NovelCategory WHERE novelId IN (${novelIds.join( + ',', + )}) AND categoryId != 2`, + ); + novelIds.forEach(novelId => { + categoryIds.forEach(categoryId => + queries.push( + `INSERT INTO NovelCategory (novelId, categoryId) VALUES (${novelId}, ${categoryId})`, + ), ); - novelIds.forEach(novelId => { - categoryIds.forEach(categoryId => - queries.push( - `INSERT INTO NovelCategory (novelId, categoryId) VALUES (${novelId}, ${categoryId})`, - ), - ); - }); - } - return new Promise(resolve => { - db.transaction(tx => { - queries.forEach((query, index) => { - tx.executeSql( - query, - [], - () => { - if (index === queries.length - 1) { - resolve(); - } - }, - txnErrorCallback, - ); - }); + }); + db.transaction(tx => { + queries.forEach(query => { + tx.executeSql(query); }); }); }; diff --git a/src/database/types/index.ts b/src/database/types/index.ts index 13368f56..9c637776 100644 --- a/src/database/types/index.ts +++ b/src/database/types/index.ts @@ -73,6 +73,10 @@ export interface NovelCategory { categoryId: number; } +export interface CCategory extends Category { + novelsCount: number; +} + export interface LibraryStats { novelsCount?: number; chaptersCount?: number; diff --git a/src/hooks/common/githubUpdateChecker.ts b/src/hooks/common/githubUpdateChecker.ts index da157023..de48e953 100644 --- a/src/hooks/common/githubUpdateChecker.ts +++ b/src/hooks/common/githubUpdateChecker.ts @@ -1,5 +1,6 @@ import { useState, useEffect } from 'react'; import { appVersion } from '../../utils/versionUtils'; +import { newer } from '@utils/compareVersion'; interface GithubUpdate { isNewVersion: boolean; @@ -32,9 +33,8 @@ export const useGithubUpdateChecker = (): GithubUpdate => { const regex = /[^\\d.]/; let newVersion = versionTag.replace(regex, ''); - currentVersion = currentVersion; - return newVersion !== currentVersion; + return newer(newVersion, currentVersion); }; useEffect(() => { diff --git a/src/hooks/persisted/usePlugins.ts b/src/hooks/persisted/usePlugins.ts index 6e3a24b0..15945527 100644 --- a/src/hooks/persisted/usePlugins.ts +++ b/src/hooks/persisted/usePlugins.ts @@ -73,6 +73,10 @@ export default function usePlugins() { if (newer(plg.version, finded.version)) { finded.hasUpdate = true; finded.iconUrl = plg.iconUrl; + finded.url = plg.url; + if (finded.id === lastUsedPlugin?.id) { + setLastUsedPlugin(finded); + } } return false; } @@ -161,16 +165,17 @@ export default function usePlugins() { if (plugin.id !== plg.id) { return plg; } - return { - id: plugin.id, - url: plugin.url, - lang: plugin.lang, - iconUrl: plugin.iconUrl, + const newPlugin: PluginItem = { + ...plugin, site: _plg.site, name: _plg.name, version: _plg.version, hasUpdate: false, }; + if (newPlugin.id === lastUsedPlugin?.id) { + setLastUsedPlugin(newPlugin); + } + return newPlugin; }), ); filterPlugins(languagesFilter); diff --git a/src/plugins/pluginManager.ts b/src/plugins/pluginManager.ts index e55d5a98..d82fce2e 100644 --- a/src/plugins/pluginManager.ts +++ b/src/plugins/pluginManager.ts @@ -70,8 +70,7 @@ const installPlugin = async (url: string): Promise => { const oldPlugin = plugins[plugin.id]; if (oldPlugin) { if (newer(plugin.version, oldPlugin.version)) { - delete plugins[oldPlugin.id]; - plugins[plugin.id] = plugin; + plugins[oldPlugin.id] = plugin; await RNFS.writeFile(plugin.path, rawCode, 'utf8'); return plugin; } else { diff --git a/src/screens/Categories/CategoriesScreen.tsx b/src/screens/Categories/CategoriesScreen.tsx index fc586ced..e442b5e1 100644 --- a/src/screens/Categories/CategoriesScreen.tsx +++ b/src/screens/Categories/CategoriesScreen.tsx @@ -43,10 +43,22 @@ const CategoriesScreen = () => { getCategories(); }, []); const updateCategorySort = (currentIndex: number, newIndex: number) => { + // Do not set local as default one + if ( + (newIndex === 0 && + currentIndex == 1 && + categories?.[currentIndex].id === 2) || + (newIndex === 1 && currentIndex == 0 && categories?.[newIndex].id === 2) + ) { + return; + } const updatedOrderCategories = orderBy( categories?.map((category, index) => { + // + 1 because in db, sort start from 1 + + // swap adjacent cards if (index === currentIndex) { - return { ...category, sort: newIndex + 1 }; // + 1 because in db, sort start from 1 + return { ...category, sort: newIndex + 1 }; } if (index === newIndex) { return { ...category, sort: currentIndex + 1 }; diff --git a/src/screens/Categories/components/CategoryCard.tsx b/src/screens/Categories/components/CategoryCard.tsx index 3cc7821c..5959e906 100644 --- a/src/screens/Categories/components/CategoryCard.tsx +++ b/src/screens/Categories/components/CategoryCard.tsx @@ -44,11 +44,14 @@ const CategoryCard: React.FC = ({ style={[ styles.cardCtn, { - backgroundColor: theme.isDark - ? overlay(2, category.sort === 1 ? theme.surface2 : theme.surface) - : category.sort === 1 - ? theme.primaryContainer - : theme.secondaryContainer, + backgroundColor: + category.sort === 1 + ? theme.isDark + ? overlay(2, theme.surface2) + : theme.primaryContainer + : category.id === 2 + ? theme.tertiaryContainer + : theme.secondaryContainer, }, ]} > diff --git a/src/screens/novel/components/ChapterItem.tsx b/src/screens/novel/components/ChapterItem.tsx index e3db28d4..23e9ff76 100644 --- a/src/screens/novel/components/ChapterItem.tsx +++ b/src/screens/novel/components/ChapterItem.tsx @@ -114,7 +114,7 @@ const ChapterItem: React.FC = ({ ]} numberOfLines={1} > - {showChapterTitles ? name : `Chapter ${chapNum} • ID: ${id}`} + {showChapterTitles ? name : `Chapter ${chapNum}`} diff --git a/src/screens/novel/components/SetCategoriesModal.tsx b/src/screens/novel/components/SetCategoriesModal.tsx index 07e7573b..f76a8073 100644 --- a/src/screens/novel/components/SetCategoriesModal.tsx +++ b/src/screens/novel/components/SetCategoriesModal.tsx @@ -1,18 +1,19 @@ import React, { useEffect, useState } from 'react'; import { Dimensions, FlatList, StyleSheet, Text, View } from 'react-native'; import { Divider, Modal, overlay, Portal } from 'react-native-paper'; -import { useNavigation } from '@react-navigation/native'; +import { NavigationProp, useNavigation } from '@react-navigation/native'; import { Button } from '@components/index'; import { useTheme } from '@hooks/persisted'; import { getString } from '@strings/translations'; -import { getCategoriesFromDb } from '@database/queries/CategoryQueries'; +import { getCategoriesWithCount } from '@database/queries/CategoryQueries'; import { updateNovelCategories } from '@database/queries/NovelQueries'; -import { Category } from '@database/types'; +import { CCategory, Category } from '@database/types'; import { Checkbox } from '@components/Checkbox/Checkbox'; import { xor } from 'lodash-es'; +import { RootStackParamList } from '@navigators/types'; interface SetCategoryModalProps { novelIds: number[]; @@ -30,15 +31,14 @@ const SetCategoryModal: React.FC = ({ onEditCategories, }) => { const theme = useTheme(); - const { navigate } = useNavigation(); - const [option, setOption] = useState('KEEP_OLD'); + const { navigate } = useNavigation>(); const [selectedCategories, setSelectedCategories] = useState([]); - const [categories = [], setCategories] = useState(); + const [categories = [], setCategories] = useState(); const getCategories = async () => { - const res = await getCategoriesFromDb(); - + const res = await getCategoriesWithCount(novelIds); setCategories(res); + setSelectedCategories(res.filter(c => c.novelsCount)); }; useEffect(() => { @@ -95,35 +95,13 @@ const SetCategoryModal: React.FC = ({ backgroundColor: theme.onSurfaceDisabled, }} /> - - - {'Option'} - - setOption('KEEP_OLD')} - viewStyle={styles.checkboxView} - theme={theme} - /> - setOption('REMOVE_OLD')} - viewStyle={styles.checkboxView} - theme={theme} - /> -