Skip to content

Commit

Permalink
🎨 Improve local storage management and episode navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
Xen0Xys committed Oct 21, 2024
1 parent 559f861 commit d180ae8
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 73 deletions.
6 changes: 4 additions & 2 deletions components/webtoons/episodes/EpisodeItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import {sumToImageUrl} from "~/utils/api";
import {Badge} from "~/components/ui/badge";
import {isEpisodeStarted} from "~/utils/storage";
import {useEpisode} from "~/utils/storage";
const {episode} = defineProps<{
episode: any,
}>();
const isStarted = ref<boolean>(isEpisodeStarted(episode.id));
const episodeStorage = useEpisode();
const isStarted = ref<boolean>(episodeStorage.isEpisodeStarted(episode.id));
</script>

Expand Down
7 changes: 3 additions & 4 deletions components/webtoons/episodes/EpisodeList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import EpisodeItem from "~/components/webtoons/episodes/EpisodeItem.vue";
import {Skeleton} from "~/components/ui/skeleton";
import EpisodeSkeleton from "~/components/webtoons/episodes/EpisodeSkeleton.vue";
import VisibilityObserver from "~/components/utils/VisibilityObserver.vue";
import {getOrder, saveOrder} from "~/utils/storage";
useSeoMeta({
title: "OWR",
Expand All @@ -17,8 +16,8 @@ const id = useRoute().params.id as any as number;
const title = ref("");
const episodes = ref<any[]>([]);
const maxIndex = ref<number>(30);
const order = ref<boolean>(getOrder(id));
const orderStorage = useOrder();
const order = ref<boolean>(orderStorage.getOrder(id));
function loadEpisodes(){
const webtoonState: any = useState(`webtoon-${id}`);
Expand Down Expand Up @@ -48,7 +47,7 @@ function increaseMaxIndex(){
function toggleOrder(){
order.value = !order.value;
saveOrder(id, order.value);
orderStorage.saveOrder(id, order.value);
}
const orderedEpisodes = computed(() => {
Expand Down
19 changes: 13 additions & 6 deletions pages/episode/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as apiurlMiddleware from "~/middleware/apiurl.middleware";
import {getEpisodeImages, getEpisodeInfos} from "~/utils/api";
import VisibilityObserver from "~/components/utils/VisibilityObserver.vue";
import {getEpisodeProgression, setEpisodeProgression, startEpisode} from "~/utils/storage";
import {useEpisode} from "~/utils/storage";
definePageMeta({
middleware: [
Expand All @@ -17,20 +17,21 @@ useSeoMeta({
});
const id = useRoute().params.id as any as number;
const episodeStorage = useEpisode();
const isCancelled = ref(false);
new Promise((resolve) => {
setTimeout(() => {
if (isCancelled.value) return;
startEpisode(id);
episodeStorage.startEpisode(id);
resolve();
}, 2500);
});
onBeforeRouteLeave(() => {
isCancelled.value = true;
});
const episodeProgression = getEpisodeProgression(id);
const episodeProgression = episodeStorage.getEpisodeProgression(id);
const episodeImages = ref<string[]>([]);
const episodeInfos = ref<any>({});
Expand Down Expand Up @@ -83,7 +84,7 @@ async function loadEpisodeInfos(){
function updateProgression(index: number){
if(index > 5 && index > episodeProgression)
setEpisodeProgression(id, index - 1);
episodeStorage.setEpisodeProgression(id, index - 1);
}
onMounted(async() => {
Expand All @@ -94,8 +95,14 @@ onMounted(async() => {

<template>
<div class="flex flex-col items-center w-full md:w-2/3 lg:w-1/2 xl:w-1/3">
<div id="header" class="flex border-[1px] border-t-0 w-full justify-center">
<div id="header" class="flex border-[1px] border-t-0 w-full items-center justify-around">
<Button variant="secondary" :disabled="!episodeInfos.previousEpisodeId" @click="navigateTo(`/episode/${episodeInfos.previousEpisodeId}`, {replace: true})">
<Icon name="iconoir:arrow-left"/>
</Button>
<h3 class="m-2">{{ episodeInfos.title }}</h3>
<Button variant="secondary" :disabled="!episodeInfos.nextEpisodeId" @click="navigateTo(`/episode/${episodeInfos.nextEpisodeId}`, {replace: true})">
<Icon name="iconoir:arrow-right"/>
</Button>
</div>
<div v-for="(image, index) of episodeImages.slice(0, maxIndex)" :key="index" class="w-full">
<VisibilityObserver @on-display="updateProgression(index)">
Expand All @@ -122,7 +129,7 @@ onMounted(async() => {
</VisibilityObserver>
</VisibilityObserver>
</div>
<div id="footer" class="w-full flex flex-row justify-between py-4 px-8 border-[1px]">
<div id="footer" class="w-full flex flex-row justify-around py-4 px-8 border-[1px]">
<Button variant="secondary" :disabled="!episodeInfos.previousEpisodeId" @click="navigateTo(`/episode/${episodeInfos.previousEpisodeId}`, {replace: true})">
<Icon name="iconoir:arrow-left"/>
</Button>
Expand Down
92 changes: 31 additions & 61 deletions utils/storage.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,45 @@
export function saveOrder(webtoonId: number, order: boolean): void{
if(import.meta.server)
return;
let orders = localStorage.getItem("order");
if(orders){
orders = JSON.parse(orders);
orders[webtoonId] = order;
localStorage.setItem("order", JSON.stringify(orders));
} else {
localStorage.setItem("order", JSON.stringify({[webtoonId]: order}));
import {useLocalStorage} from "@vueuse/core";

export function useOrder(){
const orders = useLocalStorage<Record<number, boolean>>("order", {});

function saveOrder(webtoonId: number, order: boolean): void{
orders.value[webtoonId] = order;
}
}

export function getOrder(webtoonId: number): boolean{
if(import.meta.server)
return;
let orders = localStorage.getItem("order");
if(orders){
orders = JSON.parse(orders);
if(orders[webtoonId] === undefined)
return true;
return orders[webtoonId];
function getOrder(webtoonId: number): boolean{
return orders.value[webtoonId] ?? true;
}
return true;

return {saveOrder, getOrder};
}

export function startEpisode(episodeId: number): void{
if(import.meta.server)
return;
let episodes = localStorage.getItem("episode");
if(episodes){
episodes = JSON.parse(episodes);
if(!episodes.includes(episodeId)){
episodes.push(episodeId);
localStorage.setItem("episode", JSON.stringify(episodes));
export function useEpisode(){
const episodes = useLocalStorage<number[]>("episode", []);
const progressions = useLocalStorage<Record<number, number>>("progression", {});

function startEpisode(episodeId: number): void{
if (!episodes.value.includes(episodeId)){
episodes.value.push(episodeId);
}
} else {
localStorage.setItem("episode", JSON.stringify([episodeId]));
}
}

export function isEpisodeStarted(episodeId: number): boolean{
if(import.meta.server)
return;
let episodes = localStorage.getItem("episode");
if(episodes){
episodes = JSON.parse(episodes);
return episodes.includes(episodeId.toString());
function isEpisodeStarted(episodeId: number): boolean{
return episodes.value.includes(episodeId.toString());
}
return false;
}

export function setEpisodeProgression(episodeId: number, progression: number): void{
if(import.meta.server)
return;
let progressions = localStorage.getItem("progression");
if(progressions){
progressions = JSON.parse(progressions);
progressions[episodeId] = progression;
localStorage.setItem("progression", JSON.stringify(progressions));
} else {
localStorage.setItem("progression", JSON.stringify({[episodeId]: progression}));
function setEpisodeProgression(episodeId: number, progression: number): void{
progressions.value[episodeId] = progression;
}
}

export function getEpisodeProgression(episodeId: number): number{
if(import.meta.server)
return;
let progressions = localStorage.getItem("progression");
if(progressions){
progressions = JSON.parse(progressions);
return progressions[episodeId] || 0;
function getEpisodeProgression(episodeId: number): number{
return progressions.value[episodeId] || 0;
}
return 0;

return {
startEpisode,
isEpisodeStarted,
setEpisodeProgression,
getEpisodeProgression,
};
}

0 comments on commit d180ae8

Please sign in to comment.