BloodyInside's picture
firsty
947c08e
raw
history blame
14.5 kB
import React, { useEffect, useState, useCallback, useContext, useRef } from 'react';
import { Link, router, useLocalSearchParams, useNavigation, useFocusEffect } from 'expo-router';
import Image from '@/components/Image';
import { StyleSheet, useWindowDimensions, ScrollView, Pressable, RefreshControl, Platform } 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 uuid from 'react-native-uuid';
import Toast from 'react-native-toast-message';
import { View, AnimatePresence } from 'moti';
import * as Clipboard from 'expo-clipboard';
import NetInfo from "@react-native-community/netinfo";
import Theme from '@/constants/theme';
import { __styles } from '../stylesheet/show_styles';
import Storage from '@/constants/module/storage';
import ImageCacheStorage from '@/constants/module/image_cache_storage';
import ChapterStorage from '@/constants/module/chapter_storage';
import ComicStorage from '@/constants/module/comic_storage';
import { CONTEXT } from '@/constants/module/context';
import Dropdown from '@/components/dropdown';
import { RequestChapterWidget, BookmarkWidget } from './widgets';
import { get, store_comic_cover, get_requested_info } from '../modules/content'
import { createSocket, setupSocketNetworkListener } from '../modules/socket';
const ChapterComponent = ({
SOURCE,
ID,
page,
sort,
chapter,
signal,
isDownloading,
chapterRequested,
setChapterRequested,
downloadProgress,
setDownloadProgress,
chapterToDownload,
setChapterToDownload,
setChapterQueue,
chapterQueue,
}:any) => {
const {showMenuContext, setShowMenuContext}:any = useContext(CONTEXT)
const {themeTypeContext, setThemeTypeContext}:any = useContext(CONTEXT)
const {apiBaseContext, setApiBaseContext}:any = useContext(CONTEXT)
const {socketBaseContext, setSocketBaseContext}:any = useContext(CONTEXT)
const {widgetContext, setWidgetContext}:any = useContext(CONTEXT)
const {showCloudflareTurnstileContext, setShowCloudflareTurnstileContext}:any = useContext(CONTEXT)
const Dimensions = useWindowDimensions();
const [styles, setStyles]:any = useState("")
const [is_saved, set_is_saved] = useState(false)
const [is_net_connected, set_is_net_connected]:any = useState(false)
useEffect(() => {(async () => {
const net_info = await NetInfo.fetch()
set_is_net_connected(net_info.isConnected)
setStyles(__styles(themeTypeContext,Dimensions))
const stored_chapter = await ChapterStorage.get(`${SOURCE}-${ID}`,chapter.id, {exclude_fields:["data"]})
if (stored_chapter?.data_state === "completed") set_is_saved(true)
else set_is_saved(false)
})()}, [])
useEffect(()=>{(async () => {
const stored_chapter = await ChapterStorage.get(`${SOURCE}-${ID}`,chapter.id, {exclude_fields:["data"]})
if (stored_chapter?.data_state === "completed") set_is_saved(true)
else set_is_saved(false)
})()},[page,sort])
const Request_Download = async (CHAPTER:any) => {
const stored_comic = await ComicStorage.getByID(SOURCE,ID)
if (stored_comic) {
setWidgetContext({state:true,component:<RequestChapterWidget
SOURCE={SOURCE}
ID={ID}
CHAPTER={CHAPTER}
chapterQueue={chapterQueue}
setChapterQueue={setChapterQueue}
chapterRequested={chapterRequested}
setChapterRequested={setChapterRequested}
get_requested_info={() => get_requested_info(setShowCloudflareTurnstileContext, setChapterRequested, setChapterToDownload, signal, SOURCE, ID)}
/>})
}
else{
Toast.show({
type: 'error',
text1: '🔖 Bookmark required.',
text2: `Add this comic to your bookmark to request download.`,
position: "bottom",
visibilityTime: 8000,
text1Style:{
fontFamily:"roboto-bold",
fontSize:((Dimensions.width+Dimensions.height)/2)*0.025
},
text2Style:{
fontFamily:"roboto-medium",
fontSize:((Dimensions.width+Dimensions.height)/2)*0.0185,
},
});
}
}
return <>{styles && <View
style={{
display:"flex",
flexDirection:"row",
gap:8,
justifyContent:"space-between",
alignItems:"center",
}}
>
<Button mode='outlined'
style={styles.chapter_button}
labelStyle={{
...styles.item_info,
fontSize:((Dimensions.width+Dimensions.height)/2)*0.025,
fontFamily:"roboto-light",
padding:5,
}}
onPress={async () => {
const stored_chapter = await ChapterStorage.get(`${SOURCE}-${ID}`,chapter.id, {exclude_fields:["data"]})
if (stored_chapter?.data_state === "completed") {
const stored_comic = await ComicStorage.getByID(SOURCE,ID)
if (!stored_comic.history.idx || chapter.idx > stored_comic.history.idx) await ComicStorage.updateHistory(SOURCE,ID,{idx:chapter.idx, id:chapter.id, title:chapter.title})
router.push(`/read/${SOURCE}/${ID}/?idx=${chapter.idx}`)
}else{
Toast.show({
type: 'error',
text1: 'Chapter not download yet.',
text2: "Press the button next to chapter title to download.",
position: "bottom",
visibilityTime: 4000,
text1Style:{
fontFamily:"roboto-bold",
fontSize:((Dimensions.width+Dimensions.height)/2)*0.025
},
text2Style:{
fontFamily:"roboto-medium",
fontSize:((Dimensions.width+Dimensions.height)/2)*0.0185,
},
});
}
}}
>
{chapter.title}
</Button>
{is_net_connected || is_saved
? <>{is_saved
? <Icon source={"content-save-check"} size={((Dimensions.width+Dimensions.height)/2)*0.0425} color={Theme[themeTypeContext].icon_color}/>
: <>
<>{chapterRequested[chapter.id]?.state === "queue" && !chapterQueue?.queue?.hasOwnProperty(`${SOURCE}-${ID}-${chapter.idx}`)
&& <ActivityIndicator animating={true} color={Theme[themeTypeContext].icon_color} />
}</>
<>{chapterRequested[chapter.id]?.state === "unkown" && !chapterQueue.queue?.hasOwnProperty(`${SOURCE}-${ID}-${chapter.idx}`)
&& <TouchableRipple
rippleColor={Theme[themeTypeContext].ripple_color_outlined}
style={{
borderRadius:5,
borderWidth:0,
padding:5,
}}
onPress={()=>{
Toast.show({
type: 'error',
text1: '❓Request not found in server.',
text2: "You request this chapter but the server doesn't have this in queue.\nTry request again.",
position: "bottom",
visibilityTime: 12000,
text1Style:{
fontFamily:"roboto-bold",
fontSize:((Dimensions.width+Dimensions.height)/2)*0.025
},
text2Style:{
fontFamily:"roboto-medium",
fontSize:((Dimensions.width+Dimensions.height)/2)*0.0185,
},
});
Request_Download(chapter)
}}
>
<Icon source={"alert-circle"} size={((Dimensions.width+Dimensions.height)/2)*0.04} color={"red"}/>
</TouchableRipple>
}</>
<>{chapterRequested[chapter.id]?.state === "ready"
&& <>{chapterToDownload[chapter.id]?.state === "downloading"
? <CircularProgress
value={downloadProgress[chapter.id]?.current}
maxValue={downloadProgress[chapter.id]?.total}
radius={((Dimensions.width+Dimensions.height)/2)*0.0225}
inActiveStrokeColor={Theme[themeTypeContext].border_color}
showProgressValue={false}
title={"📥"}
titleStyle={{
pointerEvents:"none",
color:Theme[themeTypeContext].text_color,
fontSize:((Dimensions.width+Dimensions.height)/2)*0.025,
fontFamily:"roboto-medium",
textAlign:"center",
}}
onAnimationComplete={async ()=>{
const stored_chapter_requested = (await ComicStorage.getByID(SOURCE,ID)).chapter_requested
const new_chapter_requested = stored_chapter_requested.filter((item:any) => item.chapter_id !== chapter.id);
await ComicStorage.updateChapterQueue(SOURCE,ID,new_chapter_requested)
delete chapterRequested[chapter.id]
setChapterRequested(chapterRequested)
const chapter_to_download = chapterToDownload
delete chapter_to_download[chapter.id]
setChapterToDownload(chapter_to_download)
const download_progress = downloadProgress
delete download_progress[chapter.id]
setDownloadProgress(download_progress)
set_is_saved(true)
isDownloading.current = false
}}
/>
: <ActivityIndicator animating={true} color={"green"} />
}</>
}</>
<>{chapterQueue.queue?.hasOwnProperty(`${SOURCE}-${ID}-${chapter.idx}`) && !(chapterRequested[chapter.id]?.state === "ready")
&& <>{chapterQueue.queue[`${SOURCE}-${ID}-${chapter.idx}`]
? <CircularProgress
value={100 - (((chapterQueue.queue[`${SOURCE}-${ID}-${chapter.idx}`])*100)/chapterQueue.max_queue)}
maxValue={100}
radius={((Dimensions.width+Dimensions.height)/2)*0.0225}
inActiveStrokeColor={Theme[themeTypeContext].border_color}
showProgressValue={false}
title={chapterQueue.queue[`${SOURCE}-${ID}-${chapter.idx}`]}
titleStyle={{
pointerEvents:"none",
color:Theme[themeTypeContext].text_color,
fontSize:((Dimensions.width+Dimensions.height)/2)*0.025,
fontFamily:"roboto-medium",
textAlign:"center",
}}
onAnimationComplete={()=>{
console.log("HAHA",chapterQueue)
get_requested_info(setShowCloudflareTurnstileContext, setChapterRequested, setChapterToDownload, signal, SOURCE, ID)
}}
/>
: <ActivityIndicator animating={true} />
}</>
}</>
<>{!chapterRequested.hasOwnProperty(chapter.id) && !chapterQueue.queue?.hasOwnProperty(`${SOURCE}-${ID}-${chapter.idx}`)
? <TouchableRipple
rippleColor={Theme[themeTypeContext].ripple_color_outlined}
style={{
borderRadius:5,
borderWidth:0,
padding:5,
}}
onPress={()=>{
Request_Download(chapter)
}}
>
<Icon source={"cloud-download"} size={((Dimensions.width+Dimensions.height)/2)*0.04} color={Theme[themeTypeContext].icon_color}/>
</TouchableRipple>
:<></>
}</>
</>
}</>
: <Icon source={"wifi-off"} size={((Dimensions.width+Dimensions.height)/2)*0.0425} color={Theme[themeTypeContext].icon_color}/>
}
</View>}</>
}
export default ChapterComponent