Skip to content

Commit

Permalink
Merge pull request #18 from Open-Webtoon-Reader/feature/better-naviga…
Browse files Browse the repository at this point in the history
…tion

Merge navigation improvements to Main
  • Loading branch information
Xen0Xys authored Jun 19, 2024
2 parents 5ab37bc + 12a9e05 commit 68621c2
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
19 changes: 16 additions & 3 deletions components/webtoons/episodes/EpisodeList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import VisibilityObserver from "~/components/utils/VisibilityObserver.vue";
const title = ref("");
const episodes = ref<any[]>([]);
const maxIndex = ref<number>(30);
const newFirst = ref<boolean>(true);
const id = useRoute().params.id as any as number;
Expand All @@ -34,6 +35,14 @@ function increaseMaxIndex(){
maxIndex.value += 30;
}
function toggleOrder(){
newFirst.value = !newFirst.value;
}
const orderedEpisodes = computed(() => {
return newFirst.value ? episodes.value : [...episodes.value].reverse();
});
onMounted(() => {
loadTitle();
loadEpisodes();
Expand All @@ -42,7 +51,11 @@ onMounted(() => {

<template>
<div class="h-full w-full md:w-3/4 lg:w-1/2 2xl:w-1/3 border-x-[1px]">
<div id="header" class="flex gap-4 py-4 px-10 justify-center">
<div id="header" class="relative flex gap-4 py-4 px-10 justify-center items-center">
<Button variant="outline" class="absolute left-0 ml-4" @click="toggleOrder">
<Icon v-if="newFirst" name="iconoir:arrow-up"/>
<Icon v-else name="iconoir:arrow-down"/>
</Button>
<h4 v-if="title">{{ title }}</h4>
<Skeleton v-else class="w-1/2 h-8"/>
</div>
Expand All @@ -54,8 +67,8 @@ onMounted(() => {
<Separator/>
</div>
</div>
<div v-for="episode in episodes.slice(0, maxIndex)" :key="episode.id">
<EpisodeItem v-if="episodes.indexOf(episode) < maxIndex - 1" :episode="episode"/>
<div v-for="episode in orderedEpisodes.slice(0, maxIndex)" :key="episode.id">
<EpisodeItem v-if="orderedEpisodes.indexOf(episode) < maxIndex - 1" :episode="episode"/>
<VisibilityObserver v-else @on-display="increaseMaxIndex">
<EpisodeItem :episode="episode"/>
</VisibilityObserver>
Expand Down
2 changes: 1 addition & 1 deletion layouts/FreeNavLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Toaster} from "~/components/ui/toast";
<template>
<div>
<Toaster/>
<div class="flex flex-col min-h-dvh min-w-vw max-h-dvh max-w-vw">
<div class="flex flex-col items-center min-h-dvh min-w-vw max-h-dvh max-w-vw">
<TopMenu class="w-full bg-background z-10"/>
<slot/>
</div>
Expand Down
39 changes: 33 additions & 6 deletions pages/episode/[id].vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import * as apiurlMiddleware from "~/middleware/apiurl.middleware";
import {getEpisodeImages} from "~/utils/api";
import {getEpisodeImages, getEpisodeInfos} from "~/utils/api";
import VisibilityObserver from "~/components/utils/VisibilityObserver.vue";
definePageMeta({
Expand All @@ -13,13 +13,14 @@ definePageMeta({
const id = useRoute().params.id as any as number;
const episodeImages = ref<string[]>([]);
const episodeInfos = ref<any>({});
const maxIndex = ref<number>(10);
function increaseMaxIndex(){
maxIndex.value += 10;
}
onMounted(async() => {
async function loadEpisodeImages(){
const episodeState: any = useState(`episode-${id}`);
if (episodeState.value && episodeState.value.length){
episodeImages.value = episodeState.value;
Expand All @@ -28,17 +29,43 @@ onMounted(async() => {
const response = await getEpisodeImages(id);
episodeImages.value = response.data;
episodeState.value = episodeImages.value;
}
async function loadEpisodeInfos(){
const episodeState: any = useState(`episode-infos-${id}`);
if (episodeState.value && episodeState.value.length){
episodeInfos.value = episodeState.value;
return;
}
const response = await getEpisodeInfos(id);
episodeInfos.value = response.data;
episodeState.value = episodeInfos.value;
}
onMounted(async() => {
loadEpisodeImages();
loadEpisodeInfos();
});
</script>

<template>
<div class="flex flex-col">
<div v-for="image of episodeImages.slice(0, maxIndex)" :key="episodeImages.indexOf(image)" class="flex justify-center">
<NuxtImg v-if="episodeImages.indexOf(image) < maxIndex - 1" :src="sumToImageUrl(image)" alt="Episode Image" class="w-full md:w-2/3 lg:w-1/2 xl:w-1/3"/>
<div class="flex flex-col items-center w-full md:w-2/3 lg:w-1/2 xl:w-1/3">
<h3 class="m-2">{{ episodeInfos.title }}</h3>
<div v-for="image of episodeImages.slice(0, maxIndex)" :key="episodeImages.indexOf(image)" class="w-full">
<NuxtImg v-if="episodeImages.indexOf(image) < maxIndex - 1" :src="sumToImageUrl(image)" alt="Episode Image" class="w-full"/>
<VisibilityObserver v-else @on-display="increaseMaxIndex">
<NuxtImg :src="sumToImageUrl(image)" alt="Episode Image" class="w-full md:w-2/3 lg:w-1/2 xl:w-1/3"/>
<NuxtImg :src="sumToImageUrl(image)" alt="Episode Image" class=""/>
</VisibilityObserver>
</div>
<Separator/>
<div id="footer" class="w-full flex flex-row justify-between py-4 px-8">
<Button variant="outline" :disabled="!episodeInfos.previousEpisodeId" @click="navigateTo(`/episode/${episodeInfos.previousEpisodeId}`, {replace: true})">
<Icon name="iconoir:arrow-left"/>
</Button>
<Button variant="outline" :disabled="!episodeInfos.nextEpisodeId" @click="navigateTo(`/episode/${episodeInfos.nextEpisodeId}`, {replace: true})">
<Icon name="iconoir:arrow-right"/>
</Button>
</div>
</div>
</template>

Expand Down
4 changes: 4 additions & 0 deletions utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export function getWebtoon(webtoonId: number): Promise<any>{
return axios.get(`/webtoons/${webtoonId}`);
}

export function getEpisodeInfos(episodeId: number): Promise<any>{
return axios.get(`/webtoons/episodes/${episodeId}`);
}

export function getEpisodeImages(episodeId: number): Promise<any>{
return axios.get(`/webtoons/episodes/${episodeId}/images`);
}

0 comments on commit 68621c2

Please sign in to comment.