UPDATE: Use popular content if recommended content amount is lacking
This commit is contained in:
@@ -102,25 +102,184 @@ export function useStreams(customUrl?: string): {
|
||||
error: string | null;
|
||||
} {
|
||||
const { isLoggedIn } = useAuth();
|
||||
const url = customUrl || (isLoggedIn ? "/api/streams/recommended" : "/api/streams/popular/4");
|
||||
const [streams, setStreams] = useState<StreamType[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const { data, isLoading, error } = useFetchContent<StreamType>(url, processStreamData, [isLoggedIn, customUrl]);
|
||||
useEffect(() => {
|
||||
const fetchStreams = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
// Always fetch the recommended streams if logged in
|
||||
if (isLoggedIn && !customUrl) {
|
||||
const recommendedResponse = await fetch("/api/streams/recommended");
|
||||
if (!recommendedResponse.ok) {
|
||||
throw new Error(`Error fetching recommended streams: ${recommendedResponse.status}`);
|
||||
}
|
||||
|
||||
return { streams: data, isLoading, error };
|
||||
const recommendedData = await recommendedResponse.json();
|
||||
const processedRecommended = processStreamData(recommendedData);
|
||||
|
||||
// If we have at least 4 recommended streams, use just those
|
||||
if (processedRecommended.length >= 4) {
|
||||
setStreams(processedRecommended);
|
||||
}
|
||||
// If we have fewer than 4, fetch popular streams to fill the gap
|
||||
else {
|
||||
const popularResponse = await fetch(`/api/streams/popular/8`);
|
||||
|
||||
if (!popularResponse.ok) {
|
||||
throw new Error(`Error fetching popular streams: ${popularResponse.status}`);
|
||||
}
|
||||
|
||||
const popularData = await popularResponse.json();
|
||||
const processedPopular = processStreamData(popularData);
|
||||
|
||||
// Combine recommended and popular, ensuring no duplicates
|
||||
const combinedStreams = [...processedRecommended];
|
||||
|
||||
// Add popular streams if they're not already in recommended
|
||||
for (const popularStream of processedPopular) {
|
||||
if (!combinedStreams.some((stream) => stream.id === popularStream.id)) {
|
||||
combinedStreams.push(popularStream);
|
||||
}
|
||||
}
|
||||
|
||||
setStreams(combinedStreams);
|
||||
}
|
||||
}
|
||||
// For custom URL or not logged in, use the original approach
|
||||
else {
|
||||
const url = customUrl || "/api/streams/popular/4";
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error fetching streams: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
setStreams(processStreamData(data));
|
||||
}
|
||||
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
console.error("Error in useStreams:", err);
|
||||
setError(err instanceof Error ? err.message : "Unknown error");
|
||||
// Fallback to popular streams on error
|
||||
if (!customUrl) {
|
||||
try {
|
||||
const fallbackResponse = await fetch("/api/streams/popular/4");
|
||||
if (fallbackResponse.ok) {
|
||||
const fallbackData = await fallbackResponse.json();
|
||||
setStreams(processStreamData(fallbackData));
|
||||
}
|
||||
} catch (fallbackErr) {
|
||||
console.error("Error fetching fallback streams:", fallbackErr);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchStreams();
|
||||
}, [isLoggedIn, customUrl]);
|
||||
|
||||
return { streams, isLoading, error };
|
||||
}
|
||||
|
||||
export function useCategories(customUrl?: string): {
|
||||
categories: CategoryType[];
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
} {
|
||||
} {
|
||||
const { isLoggedIn } = useAuth();
|
||||
const url = customUrl || (isLoggedIn ? "/api/categories/recommended" : "/api/categories/popular/4");
|
||||
const [categories, setCategories] = useState<CategoryType[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const { data, isLoading, error } = useFetchContent<CategoryType>(url, processCategoryData, [isLoggedIn, customUrl]);
|
||||
useEffect(() => {
|
||||
const fetchCategories = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
// Always fetch the recommended categories if logged in
|
||||
if (isLoggedIn && !customUrl) {
|
||||
const recommendedResponse = await fetch("/api/categories/recommended");
|
||||
if (!recommendedResponse.ok) {
|
||||
throw new Error(`Error fetching recommended categories: ${recommendedResponse.status}`);
|
||||
}
|
||||
|
||||
return { categories: data, isLoading, error };
|
||||
}
|
||||
const recommendedData = await recommendedResponse.json();
|
||||
const processedRecommended = processCategoryData(recommendedData);
|
||||
|
||||
// If we have at least 4 recommended categories, use just those
|
||||
if (processedRecommended.length >= 4) {
|
||||
setCategories(processedRecommended);
|
||||
}
|
||||
// If we have fewer than 4, fetch popular categories to fill the gap
|
||||
else {
|
||||
const popularResponse = await fetch(`/api/categories/popular/8`);
|
||||
|
||||
if (!popularResponse.ok) {
|
||||
throw new Error(`Error fetching popular categories: ${popularResponse.status}`);
|
||||
}
|
||||
|
||||
const popularData = await popularResponse.json();
|
||||
const processedPopular = processCategoryData(popularData);
|
||||
|
||||
// Get IDs of recommended categories to avoid duplicates
|
||||
const recommendedIds = processedRecommended.map(cat => cat.id);
|
||||
|
||||
// Filter popular categories to only include ones not in recommended
|
||||
const uniquePopularCategories = processedPopular.filter(
|
||||
popularCat => !recommendedIds.includes(popularCat.id)
|
||||
);
|
||||
|
||||
// Combine with recommended categories first to maintain priority
|
||||
const combinedCategories = [...processedRecommended, ...uniquePopularCategories];
|
||||
|
||||
setCategories(combinedCategories);
|
||||
}
|
||||
}
|
||||
// For custom URL or not logged in, use the original approach
|
||||
else {
|
||||
const url = customUrl || "/api/categories/popular/4";
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error fetching categories: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
setCategories(processCategoryData(data));
|
||||
}
|
||||
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
console.error("Error in useCategories:", err);
|
||||
setError(err instanceof Error ? err.message : "Unknown error");
|
||||
// Fallback to popular categories on error
|
||||
if (!customUrl) {
|
||||
try {
|
||||
const fallbackResponse = await fetch("/api/categories/popular/4");
|
||||
if (fallbackResponse.ok) {
|
||||
const fallbackData = await fallbackResponse.json();
|
||||
setCategories(processCategoryData(fallbackData));
|
||||
}
|
||||
} catch (fallbackErr) {
|
||||
console.error("Error fetching fallback categories:", fallbackErr);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchCategories();
|
||||
}, [isLoggedIn, customUrl]);
|
||||
|
||||
return { categories, isLoading, error };
|
||||
}
|
||||
|
||||
export function useVods(customUrl?: string): {
|
||||
vods: VodType[];
|
||||
|
||||
Reference in New Issue
Block a user