|
@@ -0,0 +1,145 @@
|
|
|
+import React, { useCallback, useEffect, useState } from 'react';
|
|
|
+import { ActivityIndicator } from 'react-native';
|
|
|
+import { useNavigation } from '@react-navigation/native';
|
|
|
+import { FlashList } from '@shopify/flash-list';
|
|
|
+
|
|
|
+import {
|
|
|
+ Header,
|
|
|
+ HorizontalTabView,
|
|
|
+ Loading,
|
|
|
+ PageWrapper,
|
|
|
+ WarningModal
|
|
|
+} from '../../../../components';
|
|
|
+import SeriesRankingItem from '../Components/SeriesRankingItem';
|
|
|
+
|
|
|
+import { useGetSeriesRanking } from '@api/series';
|
|
|
+import { useConnection } from 'src/contexts/ConnectionContext';
|
|
|
+import { NAVIGATION_PAGES } from 'src/types';
|
|
|
+import { StoreType, storage } from 'src/storage';
|
|
|
+import { Colors } from 'src/theme';
|
|
|
+import { SeriesRanking } from '../utils/types';
|
|
|
+
|
|
|
+const SeriesRankingListScreen = ({ route }: { route: any }) => {
|
|
|
+ const name = route.params.name;
|
|
|
+ const id = route.params.id;
|
|
|
+ const series = route.params.series;
|
|
|
+ const [index, setIndex] = useState(0);
|
|
|
+ const [routes, setRoutes] = useState<{ key: string; title: string }[]>([]);
|
|
|
+ const [loading, setLoading] = useState(true);
|
|
|
+ const [seriesId, setSeriesId] = useState(id);
|
|
|
+ const [page, setPage] = useState(0);
|
|
|
+ const { data } = useGetSeriesRanking(seriesId, page, 50, true);
|
|
|
+ const [allData, setAllData] = useState<SeriesRanking[]>([]);
|
|
|
+ const netInfo = useConnection();
|
|
|
+ const navigation = useNavigation();
|
|
|
+ const token = storage.get('token', StoreType.STRING);
|
|
|
+ const [modalType, setModalType] = useState<string | null>(null);
|
|
|
+ const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (series) {
|
|
|
+ const parsedRoutes = series.map((item: { id: string; name: string }) => ({
|
|
|
+ key: item.id,
|
|
|
+ title: item.name
|
|
|
+ }));
|
|
|
+
|
|
|
+ setRoutes([{ key: id, title: ' All ' }, ...(parsedRoutes || [])]);
|
|
|
+ }
|
|
|
+ setLoading(false);
|
|
|
+ }, [series]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (data && data.result == 'OK') {
|
|
|
+ if (page === 0) {
|
|
|
+ setAllData(data.data.ranking);
|
|
|
+ setIsLoadingMore(false);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ setAllData((prevData) => [...prevData, ...data.data.ranking]);
|
|
|
+ setIsLoadingMore(false);
|
|
|
+ }
|
|
|
+ }, [data]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (routes[index]) {
|
|
|
+ setSeriesId(routes[index].key);
|
|
|
+ setPage(0);
|
|
|
+ }
|
|
|
+ }, [index]);
|
|
|
+
|
|
|
+ const handlePress = useCallback(
|
|
|
+ (userId: number) => {
|
|
|
+ if (!netInfo?.isInternetReachable) {
|
|
|
+ setModalType('offline');
|
|
|
+ } else if (!token) {
|
|
|
+ setModalType('unauthorized');
|
|
|
+ } else {
|
|
|
+ navigation.navigate(...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId }] as never));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [netInfo, token, navigation]
|
|
|
+ );
|
|
|
+
|
|
|
+ const handleEndReached = useCallback(() => {
|
|
|
+ if (
|
|
|
+ data &&
|
|
|
+ data.result === 'OK' &&
|
|
|
+ page < data.data.max_pages &&
|
|
|
+ netInfo?.isInternetReachable
|
|
|
+ ) {
|
|
|
+ setIsLoadingMore(true);
|
|
|
+ setPage((prevPage) => prevPage + 1);
|
|
|
+ }
|
|
|
+ }, [data, page, netInfo?.isInternetReachable]);
|
|
|
+
|
|
|
+ if (loading) return <Loading />;
|
|
|
+
|
|
|
+ const ListFooter = ({ isLoading }: { isLoading: boolean }) =>
|
|
|
+ isLoading ? <ActivityIndicator size="large" color={Colors.DARK_BLUE} /> : null;
|
|
|
+
|
|
|
+ const renderSeriesList = () => (
|
|
|
+ <FlashList
|
|
|
+ viewabilityConfig={{
|
|
|
+ waitForInteraction: true,
|
|
|
+ itemVisiblePercentThreshold: 50,
|
|
|
+ minimumViewTime: 1000
|
|
|
+ }}
|
|
|
+ estimatedItemSize={50}
|
|
|
+ contentContainerStyle={{ paddingVertical: 16 }}
|
|
|
+ data={allData}
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ keyExtractor={(item, index) => index.toString()}
|
|
|
+ renderItem={({ item, index }: { item: SeriesRanking; index: number }) => (
|
|
|
+ <SeriesRankingItem item={item} index={index} onPress={handlePress} />
|
|
|
+ )}
|
|
|
+ onEndReached={handleEndReached}
|
|
|
+ onEndReachedThreshold={0.1}
|
|
|
+ ListFooterComponent={<ListFooter isLoading={isLoadingMore} />}
|
|
|
+ />
|
|
|
+ );
|
|
|
+
|
|
|
+ return (
|
|
|
+ <PageWrapper style={{ flex: 1 }}>
|
|
|
+ <Header label={name} />
|
|
|
+ {series ? (
|
|
|
+ <HorizontalTabView
|
|
|
+ index={index}
|
|
|
+ setIndex={setIndex}
|
|
|
+ routes={routes}
|
|
|
+ renderScene={({ route }: { route: { key: string; title: string } }) =>
|
|
|
+ allData && allData.length ? renderSeriesList() : <Loading />
|
|
|
+ }
|
|
|
+ lazy={true}
|
|
|
+ />
|
|
|
+ ) : allData && allData.length ? (
|
|
|
+ renderSeriesList()
|
|
|
+ ) : null}
|
|
|
+ {modalType && (
|
|
|
+ <WarningModal type={modalType} isVisible={true} onClose={() => setModalType(null)} />
|
|
|
+ )}
|
|
|
+ </PageWrapper>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default SeriesRankingListScreen;
|