diff --git a/src/hooks/persisted/useNovel.ts b/src/hooks/persisted/useNovel.ts index 2bdb4b788..8fb6d81a7 100644 --- a/src/hooks/persisted/useNovel.ts +++ b/src/hooks/persisted/useNovel.ts @@ -336,9 +336,6 @@ export const useNovel = (novelPath: string, pluginId: string) => { return; } } - - setNovel(novel); - let pages: string[]; if (novel.totalPages > 0) { pages = Array(novel.totalPages) @@ -347,38 +344,51 @@ export const useNovel = (novelPath: string, pluginId: string) => { } else { pages = (await getCustomPages(novel.id)).map(c => c.page); } + if (pages.length) { + setPages(pages); + } else { + setPages(['1']); + } + setNovel(novel); + setLoading(false); + }, []); - setPages(pages.length ? pages : ['1']); - - const page = pages[pageIndex] || '1'; - let chapters = await _getPageChapters( - novel.id, - sort, - novelSettings.filter, - page, - ); - - if (!chapters.length && Number(page)) { - const sourcePage = await fetchPage(pluginId, novelPath, page); - const sourceChapters = sourcePage.chapters.map(ch => ({ - ...ch, - page, - })); - await insertChapters(novel.id, sourceChapters); - chapters = await _getPageChapters( + const getChapters = useCallback(async () => { + const page = pages[pageIndex]; + if (novel && page) { + let chapters = await _getPageChapters( novel.id, sort, novelSettings.filter, page, ); + if (!chapters.length && Number(page)) { + const sourcePage = await fetchPage(pluginId, novelPath, page); + const sourceChapters = sourcePage.chapters.map(ch => { + return { + ...ch, + page, + }; + }); + await insertChapters(novel.id, sourceChapters); + chapters = await _getPageChapters( + novel.id, + sort, + novelSettings.filter, + page, + ); + } + setChapters(chapters); } - setChapters(chapters); - setLoading(false); - }, [novelPath, pluginId, pageIndex, sort, novelSettings.filter]); + }, [novel, novelSettings, pageIndex]); useEffect(() => { getNovel(); - }, [getNovel]); + }, []); + + useEffect(() => { + getChapters().catch(e => showToast(e.message)); + }, [getChapters]); return { loading, diff --git a/src/screens/history/HistoryScreen.tsx b/src/screens/history/HistoryScreen.tsx index 899a09981..5f40155a5 100644 --- a/src/screens/history/HistoryScreen.tsx +++ b/src/screens/history/HistoryScreen.tsx @@ -105,9 +105,7 @@ const HistoryScreen = ({ navigation }: HistoryScreenProps) => { renderItem={({ item }) => ( )} ListEmptyComponent={ diff --git a/src/screens/history/components/HistoryCard/HistoryCard.tsx b/src/screens/history/components/HistoryCard/HistoryCard.tsx index c32bd434b..8c41a7b90 100644 --- a/src/screens/history/components/HistoryCard/HistoryCard.tsx +++ b/src/screens/history/components/HistoryCard/HistoryCard.tsx @@ -1,37 +1,38 @@ import React from 'react'; -import { Pressable, StyleSheet, Text, View } from 'react-native'; +import { Image, Pressable, StyleSheet, Text, View } from 'react-native'; +import { useNavigation } from '@react-navigation/native'; import dayjs from 'dayjs'; -import { Image } from 'react-native'; import { IconButtonV2 } from '@components'; -import { History, NovelInfo } from '@database/types'; -import { ThemeColors } from '@theme/types'; -import { coverPlaceholderColor } from '@theme/colors'; +import { defaultCover } from '@plugins/helpers/constants'; import { getString } from '@strings/translations'; +import { useTheme } from '@hooks/persisted'; + +import { History, NovelInfo } from '@database/types'; import { HistoryScreenProps } from '@navigators/types'; -import { defaultCover } from '@plugins/helpers/constants'; + +import { coverPlaceholderColor } from '@theme/colors'; interface HistoryCardProps { history: History; handleRemoveFromHistory: (chapterId: number) => void; - navigation: HistoryScreenProps['navigation']; - theme: ThemeColors; } const HistoryCard: React.FC = ({ history, - navigation, handleRemoveFromHistory, - theme, }) => { + const theme = useTheme(); + const { navigate } = useNavigation(); + return ( - navigation.navigate('Chapter', { + navigate('Chapter', { novel: { path: history.novelPath, name: history.novelName, @@ -44,7 +45,7 @@ const HistoryCard: React.FC = ({ - navigation.navigate('Novel', { + navigate('Novel', { name: history.name, path: history.novelPath, pluginId: history.pluginId, @@ -110,7 +111,6 @@ const styles = StyleSheet.create({ novelName: { marginBottom: 4, }, - chapterName: {}, imageAndNameContainer: { flex: 1, flexDirection: 'row', diff --git a/src/screens/history/components/HistorySkeletonLoading.tsx b/src/screens/history/components/HistorySkeletonLoading.tsx index 3846053de..f093e5bbe 100644 --- a/src/screens/history/components/HistorySkeletonLoading.tsx +++ b/src/screens/history/components/HistorySkeletonLoading.tsx @@ -13,74 +13,62 @@ interface Props { const HistorySkeletonLoading: React.FC = ({ theme }) => { const { disableLoadingAnimations } = useAppSettings(); const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient); - const [highlightColor, backgroundColor] = getLoadingColors(theme); - const renderLoadingChapter = (item: number, index: number) => { - return ( - - {index === 0 || Math.random() > 0.6 ? ( + const renderLoadingChapter = (index: number) => ( + + {index === 0 || Math.random() > 0.6 ? ( + + ) : null} + + + - ) : null} - - - - - - - - - + + + {Array.from({ length: 2 }).map((_, buttonIndex) => ( - + ))} - ); - }; + + ); - const items = []; - for (let index = 0; index < Math.random() * 3 + 3; index++) { - items.push(index); - } + const items = Array.from({ length: Math.floor(Math.random() * 3 + 3) }); - return {items.map(renderLoadingChapter)}; + return {items.map((_, index) => renderLoadingChapter(index))}; }; const styles = StyleSheet.create({ diff --git a/src/screens/library/LibraryScreen.tsx b/src/screens/library/LibraryScreen.tsx index 9200d32db..c508d55ed 100644 --- a/src/screens/library/LibraryScreen.tsx +++ b/src/screens/library/LibraryScreen.tsx @@ -102,7 +102,7 @@ const LibraryScreen = ({ navigation }: LibraryScreenProps) => { }, styles.tabBar, ]} - tabStyle={{ width: 'auto' }} + tabStyle={{ width: 'auto', minWidth: 100 }} gap={8} renderLabel={({ route, color }) => ( diff --git a/src/screens/novel/components/LoadingAnimation/NovelInfoLoading.tsx b/src/screens/novel/components/LoadingAnimation/NovelInfoLoading.tsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/screens/novel/components/LoadingAnimation/NovelScreenLoading.tsx b/src/screens/novel/components/LoadingAnimation/NovelScreenLoading.tsx index a212e4d28..39d45ced4 100644 --- a/src/screens/novel/components/LoadingAnimation/NovelScreenLoading.tsx +++ b/src/screens/novel/components/LoadingAnimation/NovelScreenLoading.tsx @@ -1,249 +1,160 @@ import React, { memo } from 'react'; -import { View, Dimensions, StyleSheet } from 'react-native'; +import { View, StyleSheet } from 'react-native'; import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'; import { LinearGradient } from 'expo-linear-gradient'; import { ThemeColors } from '@theme/types'; import getLoadingColors from '@utils/getLoadingColors'; -import { useAppSettings } from '@hooks/persisted/index'; +import { useAppSettings, useTheme } from '@hooks/persisted/index'; interface Props { theme: ThemeColors; } -const NovelScreenLoading: React.FC = ({ theme }) => { - const { disableLoadingAnimations } = useAppSettings(); - const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient); - const styles = createStyleSheet(); - - const [highlightColor, backgroundColor] = getLoadingColors(theme); +const LoadingShimmer = memo( + ({ + style, + height, + width, + }: { + style?: any; + height: number; + width: number | string; + }) => { + const { disableLoadingAnimations } = useAppSettings(); + const theme = useTheme(); + const [highlightColor, backgroundColor] = getLoadingColors(theme); + const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient); - const RenderLoadingNovelTop = () => { return ( - - - - - - - - + ); - }; + }, +); - const RenderLoadingNovelInformation = () => { - return ( - - - - - - - - - - - - - - - - ); - }; +const NovelTop = memo(() => ( + + + + + + + + +)); - const renderLoadingChapter = (item: number, index: number) => { - return ( - - - - - ); - }; +const NovelInformation = memo(() => ( + + + {[...Array(3)].map((_, i) => ( + + ))} + + + {[...Array(2)].map((_, i) => ( + + ))} + + + {[...Array(2)].map((_, i) => ( + + ))} + + +)); - const RenderLoadingChapters = () => { - const items = [1, 2, 3, 4, 5, 6, 7]; - return ( - - - {items.map(renderLoadingChapter)} - - ); - }; +const ChapterItem = memo(({ index }: { index: number }) => ( + + + + +)); - const RenderLoading = () => { - return ( - <> - - - - - ); - }; +const Chapters = memo(() => ( + + + {[...Array(7)].map((_, i) => ( + + ))} + +)); +const NovelScreenLoading: React.FC = ({ theme }) => { return ( - + + + ); }; -const createStyleSheet = () => { - return StyleSheet.create({ - novelTopContainer: { - paddingTop: 118, - height: 268, - width: '100%', - flexDirection: 'row', - justifyContent: 'space-evenly', - }, - novelTopText: { - height: 100, - paddingTop: 30, - justifyContent: 'center', - }, - novelInformationContainer: { - marginVertical: 4, - }, - icons: { - paddingVertical: 4, - flexDirection: 'row', - justifyContent: 'space-around', - }, - icon: { - borderRadius: 30, - }, - novelInformationText: { - margin: 16, - marginTop: 8, - height: 62, - }, - novelInformationChips: { - flexDirection: 'row', - paddingBottom: 6, - paddingLeft: 8, - }, - chip: { - marginLeft: 8, - borderRadius: 8, - }, - chapterContainer: { - marginHorizontal: 16, - }, - chapter: { - paddingVertical: 8, - }, - container: { - flexGrow: 1, - marginHorizontal: 4, - marginBottom: 8, - overflow: 'hidden', - }, - loadingContainer: { - padding: 4.8, - width: 124.2, - height: 229.1, - overflow: 'hidden', - }, - text: { - borderRadius: 8, - marginTop: 5, - }, - loadingText: { - margin: 10, - height: 10, - width: Dimensions.get('window').width - 140, - }, - row: { - flexDirection: 'row', - justifyContent: 'space-between', - }, - picture: { - borderRadius: 8, - }, - }); -}; +const styles = StyleSheet.create({ + headerContainer: { + paddingTop: 118, + height: 268, + width: '100%', + flexDirection: 'row', + justifyContent: 'space-evenly', + }, + headerText: { + height: 100, + paddingTop: 30, + justifyContent: 'center', + }, + metadataContainer: { + marginVertical: 4, + }, + statsContainer: { + paddingVertical: 4, + flexDirection: 'row', + justifyContent: 'space-around', + }, + icon: { + borderRadius: 30, + }, + novelInformationText: { + margin: 16, + marginTop: 8, + height: 62, + }, + novelInformationChips: { + flexDirection: 'row', + paddingBottom: 6, + paddingLeft: 8, + }, + chip: { + marginLeft: 8, + borderRadius: 8, + }, + chapterContainer: { + marginHorizontal: 16, + }, + chapter: { + paddingVertical: 8, + }, + container: { + flexGrow: 1, + marginHorizontal: 4, + marginBottom: 8, + overflow: 'hidden', + }, + text: { + borderRadius: 8, + marginTop: 5, + }, + picture: { + borderRadius: 8, + }, +}); export default memo(NovelScreenLoading); diff --git a/src/screens/onboarding/OnboardingScreen.tsx b/src/screens/onboarding/OnboardingScreen.tsx index 96c957612..02befb8e0 100644 --- a/src/screens/onboarding/OnboardingScreen.tsx +++ b/src/screens/onboarding/OnboardingScreen.tsx @@ -49,7 +49,7 @@ export default function OnboardingScreen() { color: theme.onBackground, }} > - Yaholo! + Welcome { const highlightColor = color(theme.primary).alpha(0.08).string(); - let backgroundColor = theme.surface; + const backgroundColor = color(theme.surface); - backgroundColor = color(backgroundColor).isDark() - ? color(backgroundColor).luminosity() !== 0 - ? color(backgroundColor).lighten(0.1).toString() - : color(backgroundColor).negate().darken(0.98).toString() - : color(backgroundColor).darken(0.04).toString(); + let adjustedBackgroundColor; - return [highlightColor, backgroundColor]; + if (backgroundColor.isDark()) { + adjustedBackgroundColor = + backgroundColor.luminosity() !== 0 + ? backgroundColor.lighten(0.1).toString() + : backgroundColor.negate().darken(0.98).toString(); + } else { + adjustedBackgroundColor = backgroundColor.darken(0.04).toString(); + } + + return [highlightColor, adjustedBackgroundColor]; }; export default getLoadingColors;