import React, { useEffect, useState, useCallback, useContext, useRef, useMemo } from 'react'; import { Link, router, useLocalSearchParams, useFocusEffect } from 'expo-router'; import { Image as RNImage, StyleSheet, useWindowDimensions, ScrollView, Pressable, RefreshControl, Platform, FlatList, TouchableOpacity } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { Icon, MD3Colors, Button, Text, TextInput, TouchableRipple } from 'react-native-paper'; import CircularProgress from 'react-native-circular-progress-indicator'; import { ActivityIndicator } from 'react-native-paper'; import { FlashList } from "@shopify/flash-list"; import uuid from 'react-native-uuid'; import Toast from 'react-native-toast-message'; import { View, AnimatePresence } from 'moti'; import * as Clipboard from 'expo-clipboard'; import * as FileSystem from 'expo-file-system'; import NetInfo from "@react-native-community/netinfo"; import { Marquee } from '@animatereactnative/marquee'; import { Slider } from '@rneui/themed-edge'; import BookmarkComponent from './components/bookmark_component'; import ComicComponent from './components/comic_component'; import BookmarkWidget from './components/widgets/bookmark'; import { __styles } from './stylesheet/styles'; import Storage from '@/constants/module/storages/storage'; import ChapterStorage from '@/constants/module/storages/chapter_storage'; import Image from '@/components/Image'; import {CONTEXT} from '@/constants/module/context'; import {blobToBase64, base64ToBlob, getImageLayout} from "@/constants/module/file_manager"; import Theme from '@/constants/theme'; import ComicStorage from '@/constants/module/storages/comic_storage'; const Index = ({}:any) => { const Dimensions = useWindowDimensions(); const controller = new AbortController(); const signal = controller.signal; const {showMenuContext, setShowMenuContext}:any = useContext(CONTEXT) const {themeTypeContext, setThemeTypeContext}:any = useContext(CONTEXT) const {apiBaseContext, setApiBaseContext}:any = useContext(CONTEXT) const {widgetContext, setWidgetContext}:any = useContext(CONTEXT) const {showCloudflareTurnstileContext, setShowCloudflareTurnstileContext}:any = useContext(CONTEXT) const [styles, setStyles]:any = useState("") const [isLoading, setIsLoading] = useState(true) const [onRefresh, setOnRefresh] = useState(false) const [search, setSearch] = useState({state:false,text:""}) const [BOOKMARK_DATA, SET_BOOKMARK_DATA]:any = useState([]) const [SELECTED_BOOKMARK, SET_SELECTED_BOOKMARK] = useState("") const [COMIC_DATA, SET_COMIC_DATA] = useState([]) const [reRender, setReRender] = useState(false) const max_column = useRef(0) useFocusEffect(useCallback(() => { if (!reRender) return else setReRender(false) },[reRender])) useFocusEffect(useCallback(() => { const item_box = Math.max(((Dimensions.width+Dimensions.height)/2)*0.225,100) + (Math.max((Dimensions.width+Dimensions.height)/2*0.015,8))*2; const number_of_column = Math.floor((Dimensions.width-(((Dimensions.width+Dimensions.height)/2)*0.035)-32)/item_box) if (max_column.current !== number_of_column) { max_column.current = number_of_column setReRender(true) } }, [Dimensions])) // First load + Refresh -> useFocusEffect(useCallback(() => { (async ()=>{ if (!onRefresh) return else setOnRefresh(false) })() },[onRefresh])) useFocusEffect(useCallback(() => { (async ()=>{ if (!SELECTED_BOOKMARK) return const stored_comic = await ComicStorage.getByTag(SELECTED_BOOKMARK) SET_COMIC_DATA(stored_comic) })() },[SELECTED_BOOKMARK])) useFocusEffect(useCallback(() => { (async ()=>{ setIsLoading(true) const stored_bookmark = await Storage.get("bookmark") || [] SET_BOOKMARK_DATA(stored_bookmark) if (stored_bookmark.length) { SET_SELECTED_BOOKMARK(stored_bookmark[0]) } setIsLoading(false) })() },[onRefresh])) const renderBookmarkComponent = useCallback(({item,index}:any) => { return },[SELECTED_BOOKMARK]) const renderComicComponent = useCallback(({item,index}:any) => { return },[SELECTED_BOOKMARK]) useFocusEffect(useCallback(() => { setIsLoading(true) setShowMenuContext(true) setStyles(__styles(themeTypeContext,Dimensions)) return () => { controller.abort(); }; },[])) // <- End return (<>{styles && ! isLoading ? <> Bookmark { setSearch({...search,state:!search.state}) }} > <>{search.state && ( { setSearch({...search,text:event.nativeEvent.text}) }} /> )} { setWidgetContext({state:true,component: {setOnRefresh(true)}} /> }) }} > <>{!reRender && ( item.info.title.toLowerCase().includes(search.text.toLowerCase()))} ListEmptyComponent={ <>{BOOKMARK_DATA.length ? <> {search.text && COMIC_DATA.length ? <> Search no result : <> This tag is empty. } : No tag found. {"\n"}Press{" "} {" "}to create bookmark tag. } } /> )} : }) } export default Index;