Skip to content

Commit

Permalink
separat feed fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
pinocchio-life-like committed Sep 9, 2024
1 parent 44b5ad1 commit 174f70a
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 162 deletions.
17 changes: 13 additions & 4 deletions packages/app/modules/feed/hooks/useFeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import { useUserPacks, useSimilarPacks } from 'app/modules/pack';
import { useUserTrips } from 'app/modules/trip';
import { useSimilarItems } from 'app/modules/item';

interface UseFeedResult {
data: any[] | null;
isLoading: boolean;
refetch?: () => void;
setPage?: (page: number) => void;
hasMore?: boolean;
fetchNextPage?: (isInitialFetch?: boolean) => Promise<void>;
}

export const useFeed = ({
queryString = 'Most Recent',
ownerId,
Expand All @@ -15,10 +24,10 @@ export const useFeed = ({
feedType: string;
selectedTypes: Object;
id: string;
}> = {}) => {
}> = {}): UseFeedResult => {
switch (feedType) {
case 'public':
return usePublicFeed(queryString, selectedTypes);
return usePublicFeed(queryString, selectedTypes); // Use the typed return from usePublicFeed
case 'userPacks':
return useUserPacks(ownerId || undefined, queryString);
case 'userTrips':
Expand All @@ -28,6 +37,6 @@ export const useFeed = ({
case 'similarItems':
return useSimilarItems(id);
default:
return { data: null, error: null, isLoading: true };
return { data: null, isLoading: true };
}
};
};
139 changes: 82 additions & 57 deletions packages/app/modules/feed/hooks/usePublicFeed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { queryTrpc } from 'app/trpc';
import { useState, useEffect } from 'react';

type DataType = {
type: string;
Expand All @@ -11,66 +12,90 @@ type DataType = {
pack_id: string | null;
owner_id: string | null;
is_public: boolean | null;
// ... rest
}[];

type OptionalDataType = {
[K in keyof DataType]?: DataType[K];
}[];
type OptionalDataType = DataType[];

export const usePublicFeed = (queryString, selectedTypes) => {
let data: OptionalDataType = [];
let isLoading = true;
let refetch = () => {};
try {
const queryOptions = {
refetchOnWindowFocus: false,
keepPreviousData: true,
staleTime: 1000 * 60, // 1 min
cacheTime: 1000 * 60 * 5, // 5 min
};
const publicPacks = queryTrpc.getPublicPacks.useQuery(
{ queryBy: queryString ?? 'Favorite' },
{
...queryOptions,
onSuccess: (data) =>
console.log('Successfully fetched public packs!', data),
onError: (error) =>
console.error('Error fetching public packs:', error),
},
);

const publicTrips = queryTrpc.getPublicTripsRoute.useQuery(
{ queryBy: queryString ?? 'Favorite' },
{
...queryOptions,
enabled: publicPacks?.status === 'success',
},
);

isLoading =
publicPacks?.status !== 'success' && publicTrips?.status !== 'success';

if (selectedTypes.pack && publicPacks?.status === 'success')
data = [
...data,
...publicPacks.data.map((item) => ({ ...item, type: 'pack' })),
];

if (selectedTypes.trip && publicTrips?.status === 'success')
data = [
...data,
...publicTrips.data.map((item) => ({ ...item, type: 'trip' })),
];

refetch = () => {
publicPacks.refetch();
publicTrips.refetch();
export const usePublicFeed = (
queryString: string,
selectedTypes,
initialPage = 1,
initialLimit = 4
) => {
const [page, setPage] = useState(initialPage);
const [data, setData] = useState<OptionalDataType>([]);
const [hasMore, setHasMore] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [isFetchingNextPage, setIsFetchingNextPage] = useState(false);

// Fetch public packs using the useQuery hook
const {
data: publicPacksData,
isLoading: isPacksLoading,
refetch: refetchPacks,
} = queryTrpc.getPublicPacks.useQuery(
{ queryBy: queryString ?? 'Favorite', page, limit: initialLimit },
{ keepPreviousData: true, enabled: selectedTypes.pack }
);

// Fetch public trips using the useQuery hook
const {
data: publicTripsData,
isLoading: isTripsLoading,
refetch: refetchTrips,
} = queryTrpc.getPublicTripsRoute.useQuery(
{ queryBy: queryString ?? 'Favorite' },
{ enabled: selectedTypes.trip && publicPacksData?.length > 0 }
);

// Ensure that fetching logic behaves consistently
useEffect(() => {
const processFetchedData = () => {
if (!isPacksLoading && !isTripsLoading && (publicPacksData || publicTripsData)) {
let newData: OptionalDataType = [];

// Fetch and append packs
if (selectedTypes.pack && publicPacksData) {
newData = [...newData, ...publicPacksData.map((item) => ({ ...item, type: 'pack' }))];
}

// Fetch and append trips
if (selectedTypes.trip && publicTripsData) {
newData = [...newData, ...publicTripsData.map((item) => ({ ...item, type: 'trip' }))];
}

// Update data in state
setData((prevData) => {
return page === initialPage ? newData : [...prevData, ...newData]; // Append for subsequent pages
});

// Set `hasMore` based on the data fetched
setHasMore(newData.length === initialLimit);

// Reset loading states
setIsLoading(false);
setIsFetchingNextPage(false);
}
};
} catch (error) {
console.error(error);
return { data: null, error, isLoading, refetch };
}

return { data, error: null, isLoading, refetch };
processFetchedData();
}, [publicPacksData, publicTripsData, page, selectedTypes]);

// Fetch the next page of data
const fetchNextPage = async () => {
if (hasMore && !isLoading && !isFetchingNextPage) {
setIsFetchingNextPage(true);
setPage((prevPage) => prevPage + 1); // Increment the page before fetching new data

// Fetch packs and trips for the next page
await refetchPacks();
if (selectedTypes.trip) {
await refetchTrips();
}

setIsFetchingNextPage(false); // Reset fetching state after data fetch
}
};

return { data, isLoading, hasMore, fetchNextPage, refetch: refetchPacks };
};
Loading

0 comments on commit 174f70a

Please sign in to comment.