Bruno Predot

Gestion des recherches de film vie le composable et implémentation dans le composant MoviesList.

... ... @@ -10,7 +10,7 @@ import { useDateFormat } from "@vueuse/core";
//#endregion
//#region --Declaration--.
const { fetchPopularMovies } = useTMDB();
const { fetchPopularMovies, searchMovies } = useTMDB();
//#endregion
//#region --Data/refs--.
... ... @@ -18,6 +18,7 @@ const isInitialLoading = ref(true);
const isLoadingMore = ref(false);
const currentPage = ref(1);
const totalPages = ref(0);
const searchQuery = ref("");
/** Elément observé pour le défilement infini. */
const loadMoreTrigger = ref<HTMLElement | null>(null);
/** Instance de IntersectionObserver */
... ... @@ -41,11 +42,12 @@ const fetchMovies = async (page: number) => {
const data = await fetchPopularMovies(page);
// Save in Movie model.
if (isInitialLoading.value) {
// First fetch, erase old data before save.
useRepo(Movie).fresh(data.results);
} else {
// Add to store collection.
useRepo(Movie).save(data.results);
}
totalPages.value = data.total_pages;
currentPage.value = page;
} catch (error) {
... ... @@ -56,24 +58,69 @@ const fetchMovies = async (page: number) => {
}
};
/**
* Search movies
* @param query
* @param page
*/
const search = async (query: string, page: number) => {
// If empty search, fetch popular movies.
if (!query.trim()) {
await fetchMovies(1);
return;
}
try {
isLoadingMore.value = true;
if (page === 1) {
isInitialLoading.value = true;
}
const data = await searchMovies(query, page);
// Save in Movie model.
if (isInitialLoading.value) {
// First fetch, erase old data before save.
useRepo(Movie).fresh(data.results);
} else {
// Add to store collection.
useRepo(Movie).save(data.results);
}
totalPages.value = data.total_pages;
currentPage.value = page;
} catch (error) {
console.error("Error searching movies:", error);
} finally {
isInitialLoading.value = false;
isLoadingMore.value = false;
}
};
function createIntersectionObserver() {
return new IntersectionObserver(
(entries) => {
const [entry] = entries;
if (entry.isIntersecting && !isLoadingMore.value && currentPage.value < totalPages.value) {
if (searchQuery.value) {
// Continue searching query if already active.
search(searchQuery.value, currentPage.value + 1)
} else {
// Continue fetching popular movies.
fetchMovies(currentPage.value + 1);
}
}
},
{ threshold: 1.0 },
);
}
function handleSearchEvent(event: string) {
console.log(event);
currentPage.value = 1;
searchQuery.value = event;
search(event, 1);
}
function handleClearSearchEvent() {
console.log("clear event");
searchQuery.value = '';
// Fetch popular movies after clear.
fetchMovies(1);
}
//#endregion
... ...
... ... @@ -15,7 +15,7 @@ export const useTMDB = function() {
`${apiUrl}/movie/popular?api_key=${apiKey}&language=fr-FR&page=${page}`,
);
if (!response.ok) {
console.error("An error occured when fetching popular movies:");
console.error("An error occurred when fetching popular movies:");
} else {
return await response.json();
}
... ... @@ -24,5 +24,25 @@ export const useTMDB = function() {
}
};
return { fetchPopularMovies }
/**
* Search movies
* @param query
* @param page
*/
const searchMovies = async (query: string, page: number) => {
try {
const response = await fetch(
`${apiUrl}/search/movie?api_key=${apiKey}&language=fr-FR&query=${encodeURIComponent(query)}&page=${page}`,
);
if (!response.ok) {
console.error("An error occurred when searching movies:");
} else {
return await response.json();
}
} catch (error) {
console.error("Error searching movies:", error);
}
};
return { fetchPopularMovies, searchMovies }
}
\ No newline at end of file
... ...