|
@@ -1,4 +1,4 @@
|
|
|
-import React, { useCallback, useEffect, useState } from 'react';
|
|
|
+import React, { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react';
|
|
|
import { ActivityIndicator } from 'react-native';
|
|
|
import { useNavigation } from '@react-navigation/native';
|
|
|
import { FlashList } from '@shopify/flash-list';
|
|
@@ -26,15 +26,7 @@ const SeriesRankingListScreen = ({ route }: { route: any }) => {
|
|
|
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) {
|
|
@@ -48,77 +40,8 @@ const SeriesRankingListScreen = ({ route }: { route: any }) => {
|
|
|
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} />
|
|
@@ -127,14 +50,14 @@ const SeriesRankingListScreen = ({ route }: { route: any }) => {
|
|
|
index={index}
|
|
|
setIndex={setIndex}
|
|
|
routes={routes}
|
|
|
- renderScene={({ route }: { route: { key: string; title: string } }) =>
|
|
|
- allData && allData.length ? renderSeriesList() : <Loading />
|
|
|
- }
|
|
|
+ renderScene={({ route }: { route: { key: string; title: string } }) => (
|
|
|
+ <SeriesList groupId={+route.key} setModalType={setModalType} />
|
|
|
+ )}
|
|
|
lazy={true}
|
|
|
/>
|
|
|
- ) : allData && allData.length ? (
|
|
|
- renderSeriesList()
|
|
|
- ) : null}
|
|
|
+ ) : (
|
|
|
+ <SeriesList groupId={id} setModalType={setModalType} />
|
|
|
+ )}
|
|
|
{modalType && (
|
|
|
<WarningModal type={modalType} isVisible={true} onClose={() => setModalType(null)} />
|
|
|
)}
|
|
@@ -142,4 +65,83 @@ const SeriesRankingListScreen = ({ route }: { route: any }) => {
|
|
|
);
|
|
|
};
|
|
|
|
|
|
+const SeriesList = React.memo(
|
|
|
+ ({
|
|
|
+ groupId,
|
|
|
+ setModalType
|
|
|
+ }: {
|
|
|
+ groupId: number;
|
|
|
+ setModalType: Dispatch<SetStateAction<string | null>>;
|
|
|
+ }) => {
|
|
|
+ const [loading, setLoading] = useState(true);
|
|
|
+ const [page, setPage] = useState(0);
|
|
|
+ const { data } = useGetSeriesRanking(groupId, page, 50, true);
|
|
|
+ const [allData, setAllData] = useState<SeriesRanking[]>([]);
|
|
|
+ const netInfo = useConnection();
|
|
|
+ const navigation = useNavigation();
|
|
|
+ const token = storage.get('token', StoreType.STRING);
|
|
|
+ const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (data && data.result == 'OK') {
|
|
|
+ setAllData((prevData) => [...prevData, ...data.data.ranking]);
|
|
|
+ setLoading(false);
|
|
|
+ setIsLoadingMore(false);
|
|
|
+ }
|
|
|
+ }, [data]);
|
|
|
+
|
|
|
+ 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, data]
|
|
|
+ );
|
|
|
+
|
|
|
+ const handleEndReached = useCallback(() => {
|
|
|
+ if (
|
|
|
+ data &&
|
|
|
+ data.result === 'OK' &&
|
|
|
+ page < data.data.max_pages &&
|
|
|
+ isLoadingMore &&
|
|
|
+ netInfo?.isInternetReachable
|
|
|
+ ) {
|
|
|
+ setIsLoadingMore(true);
|
|
|
+ setPage((prevPage) => prevPage + 1);
|
|
|
+ }
|
|
|
+ }, [data, page, isLoadingMore, netInfo?.isInternetReachable]);
|
|
|
+
|
|
|
+ const ListFooter = ({ isLoading }: { isLoading: boolean }) =>
|
|
|
+ isLoading ? <ActivityIndicator size="large" color={Colors.DARK_BLUE} /> : null;
|
|
|
+
|
|
|
+ if (loading) return <Loading />;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <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} />}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
export default SeriesRankingListScreen;
|