Showing
7 changed files
with
75 additions
and
145 deletions
| @@ -38,20 +38,13 @@ async function fetchMovies(page: number) { | @@ -38,20 +38,13 @@ async function fetchMovies(page: number) { | ||
| 38 | try { | 38 | try { |
| 39 | isLoadingMore.value = true; | 39 | isLoadingMore.value = true; |
| 40 | const data = await fetchPopularMovies(page); | 40 | const data = await fetchPopularMovies(page); |
| 41 | - // Save in Movie model. | 41 | + // Save in Movie model. If first fetch, erase old data before save or, add to store collection. |
| 42 | - if (isInitialLoading.value) { | 42 | + isInitialLoading.value ? useRepo(Movie).fresh(data.results) : useRepo(Movie).save(data.results); |
| 43 | - // First fetch, erase old data before save. | ||
| 44 | - useRepo(Movie).fresh(data.results); | ||
| 45 | - } | ||
| 46 | - else { | ||
| 47 | - // Add to store collection. | ||
| 48 | - useRepo(Movie).save(data.results); | ||
| 49 | - } | ||
| 50 | totalPages.value = data.total_pages; | 43 | totalPages.value = data.total_pages; |
| 51 | currentPage.value = page; | 44 | currentPage.value = page; |
| 52 | } | 45 | } |
| 53 | catch (error) { | 46 | catch (error) { |
| 54 | - console.error("Error fetching popular movies:", error); | 47 | + throw new Error(`Error fetching popular movies: ${error}`); |
| 55 | } | 48 | } |
| 56 | finally { | 49 | finally { |
| 57 | isInitialLoading.value = false; | 50 | isInitialLoading.value = false; |
| @@ -72,24 +65,16 @@ async function search(query: string, page: number) { | @@ -72,24 +65,16 @@ async function search(query: string, page: number) { | ||
| 72 | } | 65 | } |
| 73 | try { | 66 | try { |
| 74 | isLoadingMore.value = true; | 67 | isLoadingMore.value = true; |
| 75 | - if (page === 1) { | 68 | + if (page === 1) isInitialLoading.value = true; |
| 76 | - isInitialLoading.value = true; | ||
| 77 | - } | ||
| 78 | const data = await searchMovies(query, page); | 69 | const data = await searchMovies(query, page); |
| 79 | - // Save in Movie model. | 70 | + |
| 80 | - if (isInitialLoading.value) { | 71 | + // Save in Movie model. If first fetch, erase old data before save or, add to store collection. |
| 81 | - // First fetch, erase old data before save. | 72 | + isInitialLoading.value ? useRepo(Movie).fresh(data.results) : useRepo(Movie).save(data.results); |
| 82 | - useRepo(Movie).fresh(data.results); | ||
| 83 | - } | ||
| 84 | - else { | ||
| 85 | - // Add to store collection. | ||
| 86 | - useRepo(Movie).save(data.results); | ||
| 87 | - } | ||
| 88 | totalPages.value = data.total_pages; | 73 | totalPages.value = data.total_pages; |
| 89 | currentPage.value = page; | 74 | currentPage.value = page; |
| 90 | } | 75 | } |
| 91 | catch (error) { | 76 | catch (error) { |
| 92 | - console.error("Error searching movies:", error); | 77 | + throw new Error(`Error searching movies: ${error}`); |
| 93 | } | 78 | } |
| 94 | finally { | 79 | finally { |
| 95 | isInitialLoading.value = false; | 80 | isInitialLoading.value = false; |
| @@ -101,16 +86,8 @@ function createIntersectionObserver() { | @@ -101,16 +86,8 @@ function createIntersectionObserver() { | ||
| 101 | return new IntersectionObserver( | 86 | return new IntersectionObserver( |
| 102 | (entries) => { | 87 | (entries) => { |
| 103 | const [entry] = entries; | 88 | const [entry] = entries; |
| 104 | - if (entry.isIntersecting && !isLoadingMore.value && currentPage.value < totalPages.value) { | 89 | + // Continue searching query if already active or, continue fetching popular movies. |
| 105 | - if (searchQuery.value) { | 90 | + if (entry.isIntersecting && !isLoadingMore.value && currentPage.value < totalPages.value) searchQuery.value ? search(searchQuery.value, currentPage.value + 1) : fetchMovies(currentPage.value + 1); |
| 106 | - // Continue searching query if already active. | ||
| 107 | - search(searchQuery.value, currentPage.value + 1); | ||
| 108 | - } | ||
| 109 | - else { | ||
| 110 | - // Continue fetching popular movies. | ||
| 111 | - fetchMovies(currentPage.value + 1); | ||
| 112 | - } | ||
| 113 | - } | ||
| 114 | }, | 91 | }, |
| 115 | { threshold: 1.0 }, | 92 | { threshold: 1.0 }, |
| 116 | ); | 93 | ); |
| @@ -137,21 +114,15 @@ onMounted(() => { | @@ -137,21 +114,15 @@ onMounted(() => { | ||
| 137 | fetchMovies(1); | 114 | fetchMovies(1); |
| 138 | // Création et stockage dans la ref de l'instance IntersectionObserver. | 115 | // Création et stockage dans la ref de l'instance IntersectionObserver. |
| 139 | observer.value = createIntersectionObserver(); | 116 | observer.value = createIntersectionObserver(); |
| 140 | - if (loadMoreTrigger.value) { | 117 | + // Début d'observation de la div pour le défilement infini. |
| 141 | - // Début d'observation de la div pour le défilement infini. | 118 | + if (loadMoreTrigger.value) observer.value.observe(loadMoreTrigger.value); |
| 142 | - observer.value.observe(loadMoreTrigger.value); | ||
| 143 | - } | ||
| 144 | 119 | ||
| 145 | - if (loadMoreTrigger.value) { | 120 | + if (loadMoreTrigger.value) observer.value.observe(loadMoreTrigger.value); |
| 146 | - observer.value.observe(loadMoreTrigger.value); | ||
| 147 | - } | ||
| 148 | }); | 121 | }); |
| 149 | 122 | ||
| 150 | onBeforeUnmount(() => { | 123 | onBeforeUnmount(() => { |
| 151 | // Disconnect the observer when the component is unmounted. | 124 | // Disconnect the observer when the component is unmounted. |
| 152 | - if (observer.value) { | 125 | + if (observer.value) observer.value.disconnect(); |
| 153 | - observer.value.disconnect(); | ||
| 154 | - } | ||
| 155 | }); | 126 | }); |
| 156 | // #endregion | 127 | // #endregion |
| 157 | </script> | 128 | </script> |
| @@ -13,9 +13,7 @@ defineProps<{ | @@ -13,9 +13,7 @@ defineProps<{ | ||
| 13 | * @param count | 13 | * @param count |
| 14 | */ | 14 | */ |
| 15 | function formatVoteCount(count: number) { | 15 | function formatVoteCount(count: number) { |
| 16 | - if (count >= 1000) { | 16 | + if (count >= 1000) return `${(count / 1000).toFixed(1)}k votes`; |
| 17 | - return `${(count / 1000).toFixed(1)}k votes`; | ||
| 18 | - } | ||
| 19 | return `${count} votes`; | 17 | return `${count} votes`; |
| 20 | } | 18 | } |
| 21 | // #endregion | 19 | // #endregion |
| @@ -117,9 +117,7 @@ function handleMessageEvent(event: string) { | @@ -117,9 +117,7 @@ function handleMessageEvent(event: string) { | ||
| 117 | @click=" | 117 | @click=" |
| 118 | async () => { | 118 | async () => { |
| 119 | const validForm = await v$.$validate(); | 119 | const validForm = await v$.$validate(); |
| 120 | - if (validForm) { | 120 | + if (validForm) submitComment(); |
| 121 | - submitComment(); | ||
| 122 | - } | ||
| 123 | } | 121 | } |
| 124 | " | 122 | " |
| 125 | > | 123 | > |
| @@ -69,9 +69,7 @@ watch(content, (newValue) => { | @@ -69,9 +69,7 @@ watch(content, (newValue) => { | ||
| 69 | watch( | 69 | watch( |
| 70 | () => props.modelValue, | 70 | () => props.modelValue, |
| 71 | (newValue) => { | 71 | (newValue) => { |
| 72 | - if (newValue !== content.value) { | 72 | + if (newValue !== content.value) content.value = newValue; |
| 73 | - content.value = newValue; | ||
| 74 | - } | ||
| 75 | }, | 73 | }, |
| 76 | ); | 74 | ); |
| 77 | // #endregion | 75 | // #endregion |
| @@ -12,15 +12,11 @@ export function useTMDB() { | @@ -12,15 +12,11 @@ export function useTMDB() { | ||
| 12 | const fetchPopularMovies = async (page: number) => { | 12 | const fetchPopularMovies = async (page: number) => { |
| 13 | try { | 13 | try { |
| 14 | const response = await fetch(`${apiUrl}/movie/popular?api_key=${apiKey}&language=fr-FR&page=${page}`); | 14 | const response = await fetch(`${apiUrl}/movie/popular?api_key=${apiKey}&language=fr-FR&page=${page}`); |
| 15 | - if (!response.ok) { | 15 | + if (!response.ok) throw new Error("An error occurred when fetching popular movies"); |
| 16 | - console.error("An error occurred when fetching popular movies:"); | 16 | + return await response.json(); |
| 17 | - } | ||
| 18 | - else { | ||
| 19 | - return await response.json(); | ||
| 20 | - } | ||
| 21 | } | 17 | } |
| 22 | catch (error) { | 18 | catch (error) { |
| 23 | - console.error("Error fetching popular movies:", error); | 19 | + throw new Error(`Error fetching popular movies: ${error}`); |
| 24 | } | 20 | } |
| 25 | }; | 21 | }; |
| 26 | 22 | ||
| @@ -34,15 +30,11 @@ export function useTMDB() { | @@ -34,15 +30,11 @@ export function useTMDB() { | ||
| 34 | const response = await fetch( | 30 | const response = await fetch( |
| 35 | `${apiUrl}/search/movie?api_key=${apiKey}&language=fr-FR&query=${encodeURIComponent(query)}&page=${page}`, | 31 | `${apiUrl}/search/movie?api_key=${apiKey}&language=fr-FR&query=${encodeURIComponent(query)}&page=${page}`, |
| 36 | ); | 32 | ); |
| 37 | - if (!response.ok) { | 33 | + if (!response.ok) throw new Error("An error occurred when searching movies"); |
| 38 | - console.error("An error occurred when searching movies:"); | 34 | + return await response.json(); |
| 39 | - } | ||
| 40 | - else { | ||
| 41 | - return await response.json(); | ||
| 42 | - } | ||
| 43 | } | 35 | } |
| 44 | catch (error) { | 36 | catch (error) { |
| 45 | - console.error("Error searching movies:", error); | 37 | + throw new Error(`Error searching movies: ${error}`); |
| 46 | } | 38 | } |
| 47 | }; | 39 | }; |
| 48 | 40 | ||
| @@ -53,15 +45,11 @@ export function useTMDB() { | @@ -53,15 +45,11 @@ export function useTMDB() { | ||
| 53 | const fetchMovieDetails = async (id: number | string) => { | 45 | const fetchMovieDetails = async (id: number | string) => { |
| 54 | try { | 46 | try { |
| 55 | const response = await fetch(`${apiUrl}/movie/${id}?api_key=${apiKey}&language=fr-FR`); | 47 | const response = await fetch(`${apiUrl}/movie/${id}?api_key=${apiKey}&language=fr-FR`); |
| 56 | - if (!response.ok) { | 48 | + if (!response.ok) throw new Error("An error occurred when fetching movie details"); |
| 57 | - console.error("An error occurred when fetching movie details:"); | 49 | + return await response.json(); |
| 58 | - } | ||
| 59 | - else { | ||
| 60 | - return await response.json(); | ||
| 61 | - } | ||
| 62 | } | 50 | } |
| 63 | catch (error) { | 51 | catch (error) { |
| 64 | - console.error("Error fetching details:", error); | 52 | + throw new Error(`Error fetching details: ${error}`); |
| 65 | } | 53 | } |
| 66 | }; | 54 | }; |
| 67 | 55 | ||
| @@ -71,15 +59,11 @@ export function useTMDB() { | @@ -71,15 +59,11 @@ export function useTMDB() { | ||
| 71 | const fetchMovieCredits = async (id: number | string) => { | 59 | const fetchMovieCredits = async (id: number | string) => { |
| 72 | try { | 60 | try { |
| 73 | const response = await fetch(`${apiUrl}/movie/${id}/credits?api_key=${apiKey}&language=fr-FR`); | 61 | const response = await fetch(`${apiUrl}/movie/${id}/credits?api_key=${apiKey}&language=fr-FR`); |
| 74 | - if (!response.ok) { | 62 | + if (!response.ok) throw new Error("An error occurred when fetching movie credits"); |
| 75 | - console.error("An error occurred when fetching movie credits:"); | 63 | + return await response.json(); |
| 76 | - } | ||
| 77 | - else { | ||
| 78 | - return await response.json(); | ||
| 79 | - } | ||
| 80 | } | 64 | } |
| 81 | catch (error) { | 65 | catch (error) { |
| 82 | - console.error("Error fetching movie credits:", error); | 66 | + throw new Error(`Error fetching movie credits: ${error}`); |
| 83 | } | 67 | } |
| 84 | }; | 68 | }; |
| 85 | 69 |
| 1 | import antfu from "@antfu/eslint-config"; | 1 | import antfu from "@antfu/eslint-config"; |
| 2 | 2 | ||
| 3 | export default antfu({ | 3 | export default antfu({ |
| 4 | -// Type of the project. 'lib' for libraries, the default is 'app' | 4 | + // `.eslintignore` is no longer supported in Flat config, use `ignores` instead. |
| 5 | - type: "app", | 5 | + ignores: [ |
| 6 | + "**/fixtures", | ||
| 7 | + "**/.cache", | ||
| 8 | + "**/.data", | ||
| 9 | + "**/.gitignore", | ||
| 10 | + "**/.env", | ||
| 11 | + "**/.env.dist", | ||
| 12 | + "**/.output", | ||
| 13 | + "**/.nitro", | ||
| 14 | + "**/.nuxt", | ||
| 15 | + "**/assets", | ||
| 16 | + "**/dist", | ||
| 17 | + "**/logs", | ||
| 18 | + "**/node_modules", | ||
| 19 | + "**/public", | ||
| 20 | + "**/server", | ||
| 21 | + ], | ||
| 6 | 22 | ||
| 23 | + // Disable jsonc and yaml support. | ||
| 24 | + jsonc: false, | ||
| 25 | + markdown: false, | ||
| 26 | + | ||
| 27 | + // personnal rules. | ||
| 7 | rules: { | 28 | rules: { |
| 8 | "antfu/if-newline": 0, | 29 | "antfu/if-newline": 0, |
| 9 | "antfu/curly": 0, | 30 | "antfu/curly": 0, |
| 10 | }, | 31 | }, |
| 11 | 32 | ||
| 12 | - // Enable stylistic formatting rules | 33 | + // Enable stylistic formatting rules. |
| 13 | // stylistic: true, | 34 | // stylistic: true, |
| 14 | - | 35 | + // Or customize the stylistic rules. |
| 15 | - // Or customize the stylistic rules | ||
| 16 | stylistic: { | 36 | stylistic: { |
| 17 | indent: 2, // 4, or 'tab' | 37 | indent: 2, // 4, or 'tab' |
| 18 | semi: true, | 38 | semi: true, |
| 19 | stylistic: true, | 39 | stylistic: true, |
| 20 | - quotes: "double", // 'single' or 'double' | 40 | + quotes: "double", // 'single' or 'double'. |
| 21 | }, | 41 | }, |
| 22 | 42 | ||
| 43 | + // Type of the project. 'lib' for libraries, the default is 'app'. | ||
| 44 | + type: "app", | ||
| 45 | + | ||
| 23 | // TypeScript and Vue are autodetected, you can also explicitly enable them: | 46 | // TypeScript and Vue are autodetected, you can also explicitly enable them: |
| 24 | typescript: true, | 47 | typescript: true, |
| 25 | vue: true, | 48 | vue: true, |
| 26 | 49 | ||
| 27 | - // Disable jsonc and yaml support | ||
| 28 | - jsonc: false, | ||
| 29 | - markdown: false, | ||
| 30 | yaml: false, | 50 | yaml: false, |
| 31 | - | ||
| 32 | - // `.eslintignore` is no longer supported in Flat config, use `ignores` instead | ||
| 33 | - ignores: [ | ||
| 34 | - "**/fixtures", | ||
| 35 | - "**/.cache", | ||
| 36 | - "**/.data", | ||
| 37 | - "**/.gitignore", | ||
| 38 | - "**/.env", | ||
| 39 | - "**/.env.dist", | ||
| 40 | - "**/.output", | ||
| 41 | - "**/.nitro", | ||
| 42 | - "**/.nuxt", | ||
| 43 | - "**/assets", | ||
| 44 | - "**/dist", | ||
| 45 | - "**/logs", | ||
| 46 | - "**/node_modules", | ||
| 47 | - "**/public", | ||
| 48 | - "**/server", | ||
| 49 | - ], | ||
| 50 | }); | 51 | }); |
| 51 | 52 | ||
| 52 | -// Ancienne config eslint. | 53 | +// Last eslint config. |
| 53 | // import withNuxt from "./.nuxt/eslint.config.mjs"; | 54 | // import withNuxt from "./.nuxt/eslint.config.mjs"; |
| 54 | // import js from "@eslint/js"; | 55 | // import js from "@eslint/js"; |
| 55 | // import eslintPluginVue from "eslint-plugin-vue"; | 56 | // import eslintPluginVue from "eslint-plugin-vue"; |
| @@ -27,47 +27,28 @@ const isSubmitting = ref(false); | @@ -27,47 +27,28 @@ const isSubmitting = ref(false); | ||
| 27 | 27 | ||
| 28 | // #region --Computed--. | 28 | // #region --Computed--. |
| 29 | const movieId = computed(() => { | 29 | const movieId = computed(() => { |
| 30 | - if (currentRoute.value.params.id) { | 30 | + if (!currentRoute.value.params.id) return null; |
| 31 | - if (typeof currentRoute.value.params.id === "string") { | 31 | + if (typeof currentRoute.value.params.id !== "string") return null; |
| 32 | - if (typeof Number(+currentRoute.value.params.id) === "number") { | 32 | + |
| 33 | - return +currentRoute.value.params.id as number; | 33 | + if (typeof Number(+currentRoute.value.params.id) === "number") return +currentRoute.value.params.id as number; |
| 34 | - } | 34 | + return currentRoute.value.params.id as string; |
| 35 | - else { | ||
| 36 | - return currentRoute.value.params.id as string; | ||
| 37 | - } | ||
| 38 | - } | ||
| 39 | - else { | ||
| 40 | - return null; | ||
| 41 | - } | ||
| 42 | - } | ||
| 43 | - else { | ||
| 44 | - return null; | ||
| 45 | - } | ||
| 46 | }); | 35 | }); |
| 47 | 36 | ||
| 48 | const movie = computed(() => { | 37 | const movie = computed(() => { |
| 49 | - if (unref(movieId)) { | 38 | + if (!unref(movieId)) return null; |
| 50 | - return useRepo(Movie) | 39 | + return useRepo(Movie) |
| 51 | - .query() | 40 | + .query() |
| 52 | - .where("id", movieId.value as WhereSecondaryClosure<never> | null | undefined) | 41 | + .where("id", movieId.value as WhereSecondaryClosure<never> | null | undefined) |
| 53 | - .withAll() | 42 | + .withAll() |
| 54 | - .first() as unknown as MovieInterface; | 43 | + .first() as unknown as MovieInterface; |
| 55 | - } | ||
| 56 | - else { | ||
| 57 | - return null; | ||
| 58 | - } | ||
| 59 | }); | 44 | }); |
| 60 | 45 | ||
| 61 | /** | 46 | /** |
| 62 | * Computed property for director | 47 | * Computed property for director |
| 63 | */ | 48 | */ |
| 64 | const director = computed(() => { | 49 | const director = computed(() => { |
| 65 | - if (unref(movie)?.credit?.crew) { | 50 | + if (!unref(movie)?.credit?.crew) return null; |
| 66 | - return movie.value?.credit.crew.find(person => person.job === "Director"); | 51 | + return movie.value?.credit.crew.find(person => person.job === "Director"); |
| 67 | - } | ||
| 68 | - else { | ||
| 69 | - return null; | ||
| 70 | - } | ||
| 71 | }); | 52 | }); |
| 72 | 53 | ||
| 73 | /** | 54 | /** |
| @@ -98,7 +79,7 @@ async function fetchDetails(id: number | string) { | @@ -98,7 +79,7 @@ async function fetchDetails(id: number | string) { | ||
| 98 | useRepo(Movie).save(data); | 79 | useRepo(Movie).save(data); |
| 99 | } | 80 | } |
| 100 | catch (error) { | 81 | catch (error) { |
| 101 | - console.error("Error fetching movie details:", error); | 82 | + throw new Error(`Error fetching movie details: ${error}`); |
| 102 | } | 83 | } |
| 103 | finally { | 84 | finally { |
| 104 | isLoading.value = false; | 85 | isLoading.value = false; |
| @@ -110,8 +91,7 @@ async function fetchDetails(id: number | string) { | @@ -110,8 +91,7 @@ async function fetchDetails(id: number | string) { | ||
| 110 | * @param minutes | 91 | * @param minutes |
| 111 | */ | 92 | */ |
| 112 | function formatRuntime(minutes: number) { | 93 | function formatRuntime(minutes: number) { |
| 113 | - if (!minutes) | 94 | + if (!minutes) return "Durée inconnue"; |
| 114 | - return "Durée inconnue"; | ||
| 115 | // Find nb hours. | 95 | // Find nb hours. |
| 116 | const hours = Math.floor(minutes / 60); | 96 | const hours = Math.floor(minutes / 60); |
| 117 | // Find last minutes. | 97 | // Find last minutes. |
| @@ -128,7 +108,7 @@ async function fetchCredits(id: number | string) { | @@ -128,7 +108,7 @@ async function fetchCredits(id: number | string) { | ||
| 128 | useRepo(Credit).save(data); | 108 | useRepo(Credit).save(data); |
| 129 | } | 109 | } |
| 130 | catch (error) { | 110 | catch (error) { |
| 131 | - console.error("Error fetching movie credits:", error); | 111 | + throw new Error(`Error fetching movie credits: ${error}`); |
| 132 | } | 112 | } |
| 133 | } | 113 | } |
| 134 | 114 |
-
Please register or login to post a comment