MediaContextHandle
Ручка для взаимодействия с медиа контентом
This commit is contained in:
parent
c760b48719
commit
068794b4a6
@ -1,117 +1,90 @@
|
|||||||
import { createContext, useContext, useState, useCallback } from "react";
|
import React, { createContext, useContext, useState } from 'react';
|
||||||
import {
|
import { searchMedia, getMediaDetails, validateMediaData, formatMediaData } from '../services/mediaService';
|
||||||
getTrendingMedia,
|
import { createMedia } from '../services/supabase';
|
||||||
getMediaById,
|
|
||||||
searchMedia,
|
|
||||||
} from "../services/mediaService";
|
|
||||||
|
|
||||||
const MediaContext = createContext();
|
const MediaContext = createContext();
|
||||||
|
|
||||||
export function useMedia() {
|
export const useMedia = () => {
|
||||||
const context = useContext(MediaContext);
|
const context = useContext(MediaContext);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error("useMedia must be used within a MediaProvider");
|
throw new Error('useMedia must be used within a MediaProvider');
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function MediaProvider({ children }) {
|
export const MediaProvider = ({ children }) => {
|
||||||
const [trendingMovies, setTrendingMovies] = useState([]);
|
const [searchResults, setSearchResults] = useState([]);
|
||||||
const [trendingTvShows, setTrendingTvShows] = useState([]);
|
const [selectedMedia, setSelectedMedia] = useState(null);
|
||||||
const [trendingGames, setTrendingGames] = useState([]);
|
|
||||||
const [currentMedia, setCurrentMedia] = useState(null);
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
const [searchResults, setSearchResults] = useState([]);
|
|
||||||
|
|
||||||
const fetchTrendingMedia = useCallback(async () => {
|
|
||||||
setLoading(true);
|
|
||||||
setError(null);
|
|
||||||
|
|
||||||
|
const handleSearch = async (query, type = 'movie') => {
|
||||||
try {
|
try {
|
||||||
const [movies, tvShows, games] = await Promise.all([
|
setLoading(true);
|
||||||
getTrendingMedia("movie"),
|
setError(null);
|
||||||
getTrendingMedia("tv"),
|
const results = await searchMedia(query, type);
|
||||||
getTrendingMedia("game"),
|
setSearchResults(results);
|
||||||
]);
|
} catch (error) {
|
||||||
|
console.error('Search error:', error);
|
||||||
setTrendingMovies(movies || []);
|
setError('Ошибка при поиске медиа');
|
||||||
setTrendingTvShows(tvShows || []);
|
|
||||||
setTrendingGames(games || []);
|
|
||||||
} catch (err) {
|
|
||||||
setError(err.message || "Failed to fetch trending media");
|
|
||||||
console.error("Fetch trending error:", err);
|
|
||||||
// Сброс состояний на случай частичного успеха
|
|
||||||
setTrendingMovies([]);
|
|
||||||
setTrendingTvShows([]);
|
|
||||||
setTrendingGames([]);
|
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}, []);
|
};
|
||||||
|
|
||||||
const fetchMediaDetails = useCallback(async (id) => {
|
|
||||||
if (!id) {
|
|
||||||
setError("Invalid media ID");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setLoading(true);
|
|
||||||
setError(null);
|
|
||||||
setCurrentMedia(null);
|
|
||||||
|
|
||||||
|
const handleSelectMedia = async (tmdbId, type) => {
|
||||||
try {
|
try {
|
||||||
const data = await getMediaById(id);
|
setLoading(true);
|
||||||
if (!data) {
|
setError(null);
|
||||||
throw new Error("Media not found");
|
const details = await getMediaDetails(tmdbId, type);
|
||||||
|
setSelectedMedia(details);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching media details:', error);
|
||||||
|
setError('Ошибка при получении деталей медиа');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCreateMedia = async (mediaData) => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
setError(null);
|
||||||
|
|
||||||
|
// Валидация данных
|
||||||
|
const errors = validateMediaData(mediaData);
|
||||||
|
if (errors.length > 0) {
|
||||||
|
throw new Error(errors.join('\n'));
|
||||||
}
|
}
|
||||||
setCurrentMedia(data);
|
|
||||||
} catch (err) {
|
// Форматирование данных
|
||||||
setError(err.message || "Failed to fetch media details");
|
const formattedData = formatMediaData(mediaData);
|
||||||
console.error("Fetch details error:", err);
|
|
||||||
|
// Создание медиа
|
||||||
|
const newMedia = await createMedia(formattedData);
|
||||||
|
return newMedia;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating media:', error);
|
||||||
|
setError(error.message || 'Ошибка при создании медиа');
|
||||||
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}, []);
|
};
|
||||||
|
|
||||||
const handleSearch = useCallback(async (query) => {
|
|
||||||
if (!query || !query.trim()) {
|
|
||||||
setSearchResults([]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setLoading(true);
|
|
||||||
setError(null);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const results = await searchMedia(query);
|
|
||||||
setSearchResults(Array.isArray(results) ? results : []);
|
|
||||||
} catch (err) {
|
|
||||||
setError(err.message || "Search failed");
|
|
||||||
console.error("Search error:", err);
|
|
||||||
setSearchResults([]);
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
trendingMovies,
|
searchResults,
|
||||||
trendingTvShows,
|
selectedMedia,
|
||||||
trendingGames,
|
|
||||||
currentMedia,
|
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
searchResults,
|
|
||||||
fetchTrendingMedia,
|
|
||||||
fetchMediaDetails,
|
|
||||||
handleSearch,
|
handleSearch,
|
||||||
clearError: () => setError(null),
|
handleSelectMedia,
|
||||||
clearCurrentMedia: () => setCurrentMedia(null),
|
handleCreateMedia
|
||||||
clearSearchResults: () => setSearchResults([]),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MediaContext.Provider value={value}>{children}</MediaContext.Provider>
|
<MediaContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
</MediaContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user