diff options
| author | Kenimarru <[email protected]> | 2024-01-08 19:58:12 +0100 |
|---|---|---|
| committer | Kenimarru <[email protected]> | 2024-01-08 19:58:12 +0100 |
| commit | 4084445a3c1efb825c2adde086cb4d40c9ba9f7a (patch) | |
| tree | cfa45e3ef5a652a38240d44bbbc77ff46a99f508 | |
| parent | v0.3.2 (diff) | |
| download | hiruku-4084445a3c1efb825c2adde086cb4d40c9ba9f7a.tar.xz hiruku-4084445a3c1efb825c2adde086cb4d40c9ba9f7a.zip | |
v0.4.0
| -rw-r--r-- | components/Cards.vue | 32 | ||||
| -rw-r--r-- | components/Details.vue | 21 | ||||
| -rw-r--r-- | components/Featured.vue | 36 | ||||
| -rw-r--r-- | components/Stream.vue | 69 | ||||
| -rw-r--r-- | components/Top.vue | 33 | ||||
| -rw-r--r-- | package-lock.json | 4 | ||||
| -rw-r--r-- | package.json | 2 | ||||
| -rw-r--r-- | pages/index.vue | 23 | ||||
| -rw-r--r-- | server/api/featured.js | 4 |
9 files changed, 136 insertions, 88 deletions
diff --git a/components/Cards.vue b/components/Cards.vue index 1b04d16..558d23e 100644 --- a/components/Cards.vue +++ b/components/Cards.vue @@ -1,13 +1,12 @@ <template> - <section class="space-y-4"> + <section v-if="title !== 'Top 10 Anime'" class="space-y-4"> <section class="flex flex-col"> <h2 class="text-secondary text-xl font-semibold">{{ title }}</h2> <p class="text-primary text-sm">{{ description }}</p> </section> <section class="grid grid-cols-2 md:grid-cols-8 gap-2"> <NuxtLink :to="`/i/${item.id}`" class="w-full space-y-1" v-for="item in data"> - <NuxtImg :src="item.coverImage.large" :alt="item.title.romaji" :title="item.title.romaji" - class="w-full h-44 ms:h-48 mm:h-60 ml:h-64 tb:h-32 lp:h-56 ll:h-60 4k:h-96 + <NuxtImg :src="item.coverImage.large" :alt="item.title.romaji" :title="item.title.romaji" class="w-full h-44 ms:h-48 mm:h-60 ml:h-64 tb:h-32 lp:h-56 ll:h-60 4k:h-96 object-cover rounded-sm hover:scale-95" /> <h6 class="text-primary text-sm truncate">{{ item.title.romaji }}</h6> <div class="flex items-center gap-1"> @@ -17,6 +16,33 @@ </NuxtLink> </section> </section> + <section v-if="title === 'Top 10 Anime'" class="space-y-4"> + <section class="flex flex-col"> + <h2 class="text-secondary text-xl font-semibold">{{ title }}</h2> + <p class="text-primary text-sm">{{ description }}</p> + </section> + <section class="grid grid-cols-1 w-full gap-2"> + <NuxtLink :to="`/i/${item.id}`" class="relative w-full space-y-1" v-for="(item, index) in data"> + <NuxtImg :src="item.bannerImage" :alt="item.title.romaji" :title="item.title.romaji" + class="w-full h-20 object-cover rounded-sm opacity-50" /> + <div class="absolute inset-0 px-2"> + <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> + #{{ index + 1 }}</button> + <h6 class="text-primary text-base font-semibold truncate">{{ item.title.romaji }}</h6> + <div class="flex items-center gap-2"> + <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> + {{ item.averageScore }}%</button> + <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> + {{ item.format }}</button> + <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> + {{ item.season }}</button> + <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> + {{ item.seasonYear }}</button> + </div> + </div> + </NuxtLink> + </section> + </section> </template> <script setup> diff --git a/components/Details.vue b/components/Details.vue index a942c1f..0a6c34f 100644 --- a/components/Details.vue +++ b/components/Details.vue @@ -30,21 +30,23 @@ </div> <div class="flex flex-col gap-2"> <div class="flex items-center gap-1"> - <p v-if="info.season" class="text-primary">{{ info.season === "WINTER" ? "Winter" - : info.season === "SPRING" ? "Spring" - : info.season === "SUMMER" ? "Summer" - : info.season === "FALL" ? "Fall" - : info.season }}</p> + <p v-if="info.season" class="text-primary"> + {{ info.season === "WINTER" ? "Winter" + : info.season === "SPRING" ? "Spring" + : info.season === "SUMMER" ? "Summer" + : info.season === "FALL" ? "Fall" + : info.season }}</p> <p v-if="info.seasonYear" class="text-primary">{{ info.seasonYear }}</p> </div> <div class="flex flex-wrap items-center gap-1"> - <p class="text-primary bg-secondary rounded-sm px-2">{{ info.episodes ? - info.episodes : "?" }} Episodes + <p :class="`text-primary ${info.episodes ? 'bg-secondary' : 'bg-error'} rounded-sm px-2`"> + {{ info.episodes ? info.episodes : "?" }} Episodes </p> <p v-if="info.averageScore" class="text-primary bg-secondary rounded-sm px-2">{{ info.averageScore }}%</p> <p class="text-primary bg-secondary rounded-sm px-2">{{ info.format }}</p> - <p class="text-primary bg-secondary rounded-sm px-2">{{ info.status === "FINISHED" ? "Finished" : + <p :class="`text-primary ${info.status === 'NOT_YET_RELEASED' ? 'bg-error' : 'bg-secondary'} + rounded-sm px-2`">{{ info.status === "FINISHED" ? "Finished" : info.status === "RELEASING" ? "Releasing" : info.status === "NOT_YET_RELEASED" ? "Not Yet Released" : info.status === "CANCELLED" ? "Cancelled" @@ -85,8 +87,7 @@ </section> <section class="grid grid-cols-2 md:grid-cols-8 gap-2"> <NuxtLink :to="`/i/${item.id}`" class="w-full space-y-1" v-for="item in recommendations"> - <NuxtImg :src="item.coverImage.large" :alt="item.title.romaji" :title="item.title.romaji" - class="w-full h-44 ms:h-48 mm:h-60 ml:h-64 tb:h-32 lp:h-56 ll:h-60 4k:h-96 + <NuxtImg :src="item.coverImage.large" :alt="item.title.romaji" :title="item.title.romaji" class="w-full h-44 ms:h-48 mm:h-60 ml:h-64 tb:h-32 lp:h-56 ll:h-60 4k:h-96 object-cover rounded-sm hover:scale-95" /> <h6 class="text-primary text-sm truncate">{{ item.title.romaji }}</h6> <div class="flex items-center gap-1"> diff --git a/components/Featured.vue b/components/Featured.vue new file mode 100644 index 0000000..97f0fe3 --- /dev/null +++ b/components/Featured.vue @@ -0,0 +1,36 @@ +<template> + <section class="hidden md:flex flex-row justify-center items-center gap-4 space-y-4 my-8"> + <div class="flex flex-col w-[800px] gap-2"> + <h2 class="text-secondary text-2xl font-semibold">{{ data.title.romaji }}</h2> + <div class="flex items-center gap-2"> + <h6 class="text-primary"> + {{ data.season === "WINTER" ? "Winter" + : data.season === "SPRING" ? "Spring" + : data.season === "SUMMER" ? "Summer" + : data.season === "FALL" ? "Fall" + : data.season }} + </h6> + <h6 class="text-primary">{{ data.seasonYear }}</h6> + </div> + <div class="flex flex-wrap items-center gap-1"> + <div v-for="(genre, index) in data.genres" :key="index"> + <p class="text-secondary bg-primary rounded-sm px-2">{{ genre }}</p> + </div> + </div> + <p v-html="data.description" class="text-primary w-[800px] h-48 overflow-y-auto pr-2" /> + <div class="my-2"> + <NuxtLink :to="`/i/${data.id}`" + class="text-primary bg-secondary text-center rounded-sm uppercase py-2 px-4 hover:bg-opacity-75"> + Start Watching</NuxtLink> + </div> + </div> + <div> + <NuxtImg :src="data.coverImage.large" :alt="data.title.romaji" :title="data.title.romaji" + class="w-72 h-[420px] object-cover rounded-md" /> + </div> + </section> +</template> + +<script setup> +const { data } = defineProps(["data"]); +</script>
\ No newline at end of file diff --git a/components/Stream.vue b/components/Stream.vue index be9a732..75aae66 100644 --- a/components/Stream.vue +++ b/components/Stream.vue @@ -1,13 +1,14 @@ <template> <section class="space-y-8"> <section class="flex flex-col"> - <h2 class="text-secondary text-2xl font-semibold">{{ stream.info.title }}</h2> - <p class="text-primary">Episode {{ stream.info.episode }}</p> + <h2 class="text-secondary text-2xl font-semibold">{{ data.stream.info.title }}</h2> + <p class="text-primary">Episode {{ data.stream.info.episode }}</p> </section> <section class="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-4"> <div class="flex flex-col gap-2"> - <iframe :src="stream.plyr.default" allowfullscreen frameborder="0" class="w-full h-auto md:h-96 rounded-sm" /> - <NuxtLink :to="download.link" target="_blank" external + <iframe :src="data.stream.plyr.default" allowfullscreen frameborder="0" + class="w-full h-auto md:h-96 rounded-sm" /> + <NuxtLink :to="data.download.link" target="_blank" external class="text-primary bg-secondary text-center rounded-sm py-1 hover:bg-opacity-75"> Download Episode</NuxtLink> </div> @@ -15,40 +16,41 @@ <section class="grid grid-cols-[auto,1fr] gap-4"> <div class="flex flex-col gap-2"> <div class="flex items-center gap-1"> - <p v-if="info.season" class="text-primary">{{ info.season === "WINTER" ? "Winter" - : info.season === "SPRING" ? "Spring" - : info.season === "SUMMER" ? "Summer" - : info.season === "FALL" ? "Fall" - : info.season }}</p> - <p v-if="info.seasonYear" class="text-primary">{{ info.seasonYear }}</p> + <p v-if="data.info.season" class="text-primary">{{ data.info.season === "WINTER" ? "Winter" + : data.info.season === "SPRING" ? "Spring" + : data.info.season === "SUMMER" ? "Summer" + : data.info.season === "FALL" ? "Fall" + : data.info.season }}</p> + <p v-if="data.info.seasonYear" class="text-primary">{{ data.info.seasonYear }}</p> </div> <div class="flex flex-wrap items-center gap-1"> - <p class="text-primary bg-secondary rounded-sm px-2">{{ info.episodes ? - info.episodes : "?" }} Episodes + <p :class="`text-primary ${data.info.episodes ? 'bg-secondary' : 'bg-error'} + rounded-sm px-2`">{{ data.info.episodes ? data.info.episodes : "?" }} Episodes </p> - <p v-if="info.averageScore" class="text-primary bg-secondary rounded-sm px-2">{{ - info.averageScore }}%</p> - <p class="text-primary bg-secondary rounded-sm px-2">{{ info.format }}</p> - <p class="text-primary bg-secondary rounded-sm px-2">{{ info.status === "FINISHED" ? "Finished" - : - info.status === "RELEASING" ? "Releasing" - : info.status === "NOT_YET_RELEASED" ? "Not Yet Released" - : info.status === "CANCELLED" ? "Cancelled" - : info.status === "HIATUS" ? "Hiatsu" - : info.status }}</p> + <p v-if="data.info.averageScore" class="text-primary bg-secondary rounded-sm px-2">{{ + data.info.averageScore }}%</p> + <p class="text-primary bg-secondary rounded-sm px-2">{{ data.info.format }}</p> + <p :class="`text-primary ${data.info.status === 'NOT_YET_RELEASED' ? 'bg-error' : 'bg-secondary'} + rounded-sm px-2`"> + {{ data.info.status === "FINISHED" ? "Finished" + : data.info.status === "RELEASING" ? "Releasing" + : data.info.status === "NOT_YET_RELEASED" ? "Not Yet Released" + : data.info.status === "CANCELLED" ? "Cancelled" + : data.info.status === "HIATUS" ? "Hiatsu" + : data.info.status }}</p> </div> <div class="flex flex-wrap items-center gap-1"> - <div v-for="(genre, index) in info.genres" :key="index"> + <div v-for="(genre, index) in data.info.genres" :key="index"> <p class="text-secondary bg-primary rounded-sm px-2">{{ genre }}</p> </div> </div> - <div v-html="info.description" class="text-primary w-full h-48 overflow-y-auto pr-2" /> + <div v-html="data.info.description" class="text-primary w-full h-48 overflow-y-auto pr-2" /> <section class="space-y-4"> <h2 class="text-secondary text-2xl font-semibold">Episodes</h2> <select class="text-primary bg-sub w-full rounded-sm py-2 px-1" v-model="selected" @change="getEpisode"> <option value="" selected disabled>Select an episode</option> - <option :value="episode.id" v-for="episode in episodes" :key="episode.number"> + <option :value="episode.id" v-for="episode in data.episodes" :key="episode.number"> Episode {{ episode.number }} </option> </select> @@ -58,10 +60,10 @@ <section class="flex md:hidden justify-center items-center"> <div class="flex flex-col w-full gap-2"> <div class="grid grid-cols-2 gap-2"> - <NuxtLink :to="`https://anilist.co/anime/${info.id}`" target="_blank" external + <NuxtLink :to="`https://anilist.co/anime/${data.info.id}`" target="_blank" external class="text-primary bg-secondary text-center rounded-sm py-1 hover:bg-opacity-75"> Anilist</NuxtLink> - <NuxtLink :to="`https://myanimelist.net/anime/${info.idMal}`" target="_blank" external + <NuxtLink :to="`https://myanimelist.net/anime/${data.info.idMal}`" target="_blank" external class="text-primary bg-secondary text-center rounded-sm py-1 hover:bg-opacity-75"> Mal</NuxtLink> </div> @@ -75,10 +77,15 @@ <script setup> const { id, episode } = defineProps(["id", "episode"]); -const { data: stream } = await useFetch("/api/stream?id=" + episode); -const { data: info } = await useFetch("/api/info?id=" + id); -const { data: download } = await useFetch("/api/download?id=" + episode); -const { data: episodes } = await useFetch("/api/episodes?id=" + id); +const { data } = await useAsyncData("data", async () => { + const [stream, info, download, episodes] = await Promise.all([ + $fetch("/api/stream?id=" + episode), + $fetch("/api/info?id=" + id), + $fetch("/api/download?id=" + episode), + $fetch("/api/episodes?id=" + id) + ]); + return { stream, info, download, episodes } +}); const selected = ref(""); const router = useRouter(); const getEpisode = (event) => { diff --git a/components/Top.vue b/components/Top.vue deleted file mode 100644 index 78f1104..0000000 --- a/components/Top.vue +++ /dev/null @@ -1,33 +0,0 @@ -<template> - <section class="space-y-4"> - <section class="flex flex-col"> - <h2 class="text-secondary text-xl font-semibold">{{ title }}</h2> - <p class="text-primary text-sm">{{ description }}</p> - </section> - <section class="grid grid-cols-1 w-full gap-2"> - <NuxtLink :to="`/i/${item.id}`" class="relative w-full space-y-1" v-for="(item, index) in data"> - <NuxtImg :src="item.bannerImage" :alt="item.title.romaji" :title="item.title.romaji" - class="w-full h-20 object-cover rounded-sm opacity-50" /> - <div class="absolute inset-0 px-2"> - <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> - #{{ index + 1 }}</button> - <h6 class="text-primary text-base font-semibold truncate">{{ item.title.romaji }}</h6> - <div class="flex items-center gap-2"> - <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> - {{ item.averageScore }}%</button> - <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> - {{ item.format }}</button> - <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> - {{ item.season }}</button> - <button type="button" class="text-primary bg-secondary text-sm rounded-sm px-2"> - {{ item.seasonYear }}</button> - </div> - </div> - </NuxtLink> - </section> - </section> -</template> - -<script setup> -const { title, description, data } = defineProps(["title", "description", "data"]); -</script>
\ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f19882d..f1c8685 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "hiruki", - "version": "0.3.2", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "hiruki", - "version": "0.3.2", + "version": "0.4.0", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index 115f88a..4a0c070 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hiruki", - "version": "0.3.2", + "version": "0.4.0", "private": true, "type": "module", "scripts": { diff --git a/pages/index.vue b/pages/index.vue index 7e53f51..cb51ea2 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -1,15 +1,22 @@ <template> + <Featured :data="data.featured" /> <section class="space-y-4"> - <Cards title="Trending Now" description="Currently Trending Anime" :data="trending" /> - <Cards title="All Time Popular" description="Most Popular Anime" :data="popular" /> - <Cards title="Upcoming Next Season" description="Upcoming Anime" :data="upcoming" /> - <Top title="Top 10 Anime" description="Top High Rated Anime" :data="top" /> + <Cards title="Trending Now" description="Currently Trending Anime" :data="data.trending" /> + <Cards title="All Time Popular" description="Most Popular Anime" :data="data.popular" /> + <Cards title="Upcoming Next Season" description="Upcoming Anime" :data="data.upcoming" /> + <Cards title="Top 10 Anime" description="Top High Rated Anime" :data="data.top" /> </section> </template> <script setup> -const { data: trending } = await useFetch("/api/trending"); -const { data: popular } = await useFetch("/api/popular"); -const { data: upcoming } = await useFetch("/api/upcoming"); -const { data: top } = await useFetch("/api/top"); +const { data } = await useAsyncData("data", async () => { + const [featured, trending, popular, upcoming, top] = await Promise.all([ + $fetch("/api/featured"), + $fetch("/api/trending"), + $fetch("/api/popular"), + $fetch("/api/upcoming"), + $fetch("/api/top") + ]); + return { featured, trending, popular, upcoming, top } +}); </script>
\ No newline at end of file diff --git a/server/api/featured.js b/server/api/featured.js new file mode 100644 index 0000000..5810a82 --- /dev/null +++ b/server/api/featured.js @@ -0,0 +1,4 @@ +export default defineEventHandler(async () => { + const { API } = useRuntimeConfig(); + return await $fetch(API + "/featured"); +});
\ No newline at end of file |