import React, { useEffect, useState, useCallback, useContext, useRef } from 'react'; import { Platform, useWindowDimensions } from 'react-native'; import { Icon, MD3Colors, Button, Text, TextInput, TouchableRipple, ActivityIndicator } from 'react-native-paper'; import { View, AnimatePresence } from 'moti'; import Toast from 'react-native-toast-message'; import * as FileSystem from 'expo-file-system'; import axios from 'axios'; import Theme from '@/constants/theme'; import Dropdown from '@/components/dropdown'; import { CONTEXT } from '@/constants/module/context'; import { store_comic_cover } from '../modules/content'; import Storage from '@/constants/module/storage'; import ComicStorage from '@/constants/module/comic_storage'; import ImageCacheStorage from '@/constants/module/image_cache_storage'; import ChapterStorage from '@/constants/module/chapter_storage'; export const PageNavigationWidget = ({MAX_OFFSET,setPage,CONTENT}:any) =>{ const Dimensions = useWindowDimensions(); const {themeTypeContext, setThemeTypeContext}:any = useContext(CONTEXT) const {widgetContext, setWidgetContext}:any = useContext(CONTEXT) const [goToPage, setGoToPage] = useState(""); const [_feedBack, _setFeedBack] = useState(""); return ( } style={{ backgroundColor:Theme[themeTypeContext].background_color, borderColor:Theme[themeTypeContext].border_color, }} outlineColor={Theme[themeTypeContext].text_input_border_color} value={goToPage} onChange={(event)=>{ const value = event.nativeEvent.text const isInt = /^-?\d+$/.test(value); if (isInt || value === "") { if (parseInt(value) > Math.ceil(CONTENT.chapters.length/MAX_OFFSET)){ _setFeedBack("Page is out of index.") }else{ _setFeedBack("") setGoToPage(value) } } else _setFeedBack("Input is not a valid number.") }} /> {_feedBack ? {_feedBack} : <> } ) } interface RequestChapterWidgetProps { SOURCE: string | string[]; ID: string | string[]; CHAPTER: any; chapterQueue: any; setChapterQueue: any; chapterRequested: any; setChapterRequested: any; get_requested_info: any; } export const RequestChapterWidget: React.FC = ({ SOURCE, ID, CHAPTER, chapterQueue, setChapterQueue, chapterRequested, setChapterRequested, get_requested_info }) => { const Dimensions = useWindowDimensions(); const {themeTypeContext, setThemeTypeContext}:any = useContext(CONTEXT) const {widgetContext, setWidgetContext}:any = useContext(CONTEXT) const {showCloudflareTurnstileContext, setShowCloudflareTurnstileContext}:any = useContext(CONTEXT) const [colorize, setColorize] = useState(false) const [translate, setTranslate] = useState({state:true,target:"ENG"}) const [isRequesting, setIsRequesting] = useState(false) return ( { setColorize(item.value) }} /> { setTranslate({...translate,state:item.value}) }} /> <>{translate.state && <> { setTranslate({...translate,target:item.value}) }} /> } {isRequesting ? : <> } ) } interface BookmarkWidgetProps { onRefresh: any; SOURCE: string | string[]; ID: string | string[]; CONTENT: any; } export const BookmarkWidget: React.FC = ({ onRefresh, SOURCE, ID, CONTENT }) => { const Dimensions = useWindowDimensions(); const {themeTypeContext, setThemeTypeContext}:any = useContext(CONTEXT) const {widgetContext, setWidgetContext}:any = useContext(CONTEXT) const {showCloudflareTurnstileContext, setShowCloudflareTurnstileContext}:any = useContext(CONTEXT) const {apiBaseContext, setApiBaseContext}:any = useContext(CONTEXT) const [BOOKMARK_DATA, SET_BOOKMARK_DATA]: any = useState(null) const [defaultBookmark, setDefaultBookmark]:any = useState("") const [bookmark, setBookmark]:any = useState("") const [createBookmark, setCreateBookmark]:any = useState({state:false,title:""}) const [removeBookmark, setRemoveBookmark]:any = useState({state:false, removing: false}) const controller = new AbortController(); const signal = controller.signal; useEffect(()=>{ (async ()=>{ const stored_comic = await ComicStorage.getByID(SOURCE,CONTENT.id) if (stored_comic) { setDefaultBookmark(stored_comic.tag) setBookmark(stored_comic.tag) } const stored_bookmark_data = await Storage.get("bookmark") || [] if (stored_bookmark_data.length) { const bookmark_data:Array = [] for (const item of stored_bookmark_data) { bookmark_data.push({ label:item, value:item, }) } SET_BOOKMARK_DATA(bookmark_data.sort()) }else SET_BOOKMARK_DATA([]) })() return () => controller.abort(); },[]) return (<>{BOOKMARK_DATA !== null && <>{!createBookmark.state && !removeBookmark.state && <> { setBookmark(item.value) })} /> <>{bookmark && { const stored_comic = await ComicStorage.getByID(SOURCE,CONTENT.id) if (stored_comic) setRemoveBookmark({...removeBookmark,state:true}) else setBookmark("") })} > } } <>{createBookmark.state && <> } style={{ backgroundColor:Theme[themeTypeContext].background_color, borderColor:Theme[themeTypeContext].border_color, }} outlineColor={Theme[themeTypeContext].text_input_border_color} value={createBookmark.title} onChange={(event)=>{ setCreateBookmark({...createBookmark,title:event.nativeEvent.text}) }} /> } <>{removeBookmark.state && <> Are you sure you want to remove this comic from bookmark? This will remove all local saved info and chapters. <>{removeBookmark.removing ? :<> } } }) }