UPDATE: Use popular content if recommended content amount is lacking

This commit is contained in:
Chris-1010
2025-03-03 12:41:31 +00:00
parent 3012e8ebd1
commit 9c5cbf5e53

View File

@@ -102,11 +102,90 @@ 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): {
@@ -115,11 +194,91 @@ export function useCategories(customUrl?: string): {
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): {