Skip to content

Commit 5bddb01

Browse files
committed
feat(panel): connect store to show panel
1 parent a69babf commit 5bddb01

25 files changed

+466
-104
lines changed

src/components/AppComponent.vue

+38-12
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
<script setup lang="ts">
2-
import { NDrawer, NDrawerContent } from 'naive-ui';
2+
import { NButton, NDrawer, NDrawerContent, NFlex, NIcon } from 'naive-ui';
33
import { ref, Transition, watch } from 'vue';
44
import { RouterView, useRouter } from 'vue-router';
55
66
import { NavbarComponent } from '~/components/common';
77
import GridBackground from '~/components/common/background/GridBackground.vue';
88
import PageLoading from '~/components/common/loading/PageLoading.vue';
9+
import IconChevronLeft from '~/components/icons/IconChevronLeft.vue';
10+
import IconClose from '~/components/icons/IconClose.vue';
911
import { useAuthSettingsStoreRefs } from '~/stores/settings/auth.store';
1012
1113
const { isAuthenticated } = useAuthSettingsStoreRefs();
12-
const { currentRoute, push, getRoutes } = useRouter();
14+
const { currentRoute, push, back } = useRouter();
1315
1416
const origin = ref();
15-
const drawer = ref(false);
17+
const panel = ref(false);
1618
1719
watch(
1820
currentRoute,
1921
(_next, _prev) => {
20-
const isDrawer = !!_next.meta?.drawer;
21-
drawer.value = isDrawer;
22-
if (origin.value && isDrawer) return;
23-
origin.value = isDrawer ? _prev : undefined;
22+
const isPanel = !!_next.meta?.panel;
23+
panel.value = isPanel;
24+
if (origin.value && isPanel) return;
25+
origin.value = isPanel ? _prev : undefined;
2426
},
2527
{
2628
immediate: true,
@@ -36,12 +38,17 @@ const onAfterLeave = () => {
3638
};
3739
3840
const onClose = () => {
39-
drawer.value = false;
41+
panel.value = false;
42+
};
43+
44+
const onBack = () => {
45+
if (window.history.length > 1) return back();
46+
return onClose();
4047
};
4148
</script>
4249

4350
<template>
44-
<header :class="{ open: drawer }">
51+
<header :class="{ open: panel }">
4552
<RouterView v-slot="{ Component }" name="navbar">
4653
<NavbarComponent v-if="isAuthenticated">
4754
<template v-if="Component" #drawer="{ parentElement }">
@@ -64,18 +71,37 @@ const onClose = () => {
6471
</Transition>
6572
</main>
6673
<aside>
67-
<RouterView v-slot="{ Component: DrawerComponent }">
74+
<RouterView v-slot="{ Component: PanelComponent }">
6875
<NDrawer
69-
v-model:show="drawer"
76+
v-model:show="panel"
7077
:to="asideRef"
7178
width="100%"
7279
close-on-esc
7380
:on-after-leave="onAfterLeave"
7481
auto-focus
7582
>
7683
<NDrawerContent>
84+
<!-- Header -->
85+
<NFlex justify="space-between">
86+
<NButton circle quaternary @click="onBack">
87+
<template #icon>
88+
<NIcon>
89+
<IconChevronLeft />
90+
</NIcon>
91+
</template>
92+
</NButton>
93+
<NButton circle quaternary @click="onClose">
94+
<template #icon>
95+
<NIcon>
96+
<IconClose />
97+
</NIcon>
98+
</template>
99+
</NButton>
100+
</NFlex>
101+
102+
<!-- Content -->
77103
<KeepAlive>
78-
<component :is="DrawerComponent" @close="onClose" />
104+
<component :is="PanelComponent" />
79105
</KeepAlive>
80106
</NDrawerContent>
81107
</NDrawer>

src/components/common/list/use-list-scroll.ts

+7
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ export const useListScroll = <T extends ListScrollSourceItemWithDate<D>, D exten
158158
},
159159
};
160160

161+
if (_item.type === 'episode' || _item.type === 'season') {
162+
_item.meta.number = {
163+
season: item.episode?.season ?? item.season?.number,
164+
episode: item.episode?.number,
165+
};
166+
}
167+
161168
return _item;
162169
});
163170
});
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
3+
<path
4+
fill="none"
5+
stroke="currentColor"
6+
stroke-dasharray="10"
7+
stroke-dashoffset="10"
8+
stroke-linecap="round"
9+
stroke-width="2"
10+
d="M8 12L15 5M8 12L15 19"
11+
>
12+
<animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="10;0" />
13+
</path>
14+
</svg>
15+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
3+
<path
4+
stroke="currentColor"
5+
stroke-dasharray="8"
6+
stroke-dashoffset="8"
7+
stroke-linecap="round"
8+
stroke-width="2"
9+
d="M9 12L14 7M9 12L14 17"
10+
fill="currentColor"
11+
>
12+
<animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="8;0" />
13+
</path>
14+
</svg>
15+
</template>

src/components/icons/IconClose.vue

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
3+
<path
4+
fill="none"
5+
stroke="currentColor"
6+
stroke-dasharray="12"
7+
stroke-dashoffset="12"
8+
stroke-linecap="round"
9+
stroke-width="2"
10+
d="M12 12L19 19M12 12L5 5M12 12L5 19M12 12L19 5"
11+
>
12+
<animate fill="freeze" attributeName="stroke-dashoffset" dur="0.4s" values="12;0" />
13+
</path>
14+
</svg>
15+
</template>
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
3+
<g
4+
fill="none"
5+
stroke="currentColor"
6+
stroke-dasharray="16"
7+
stroke-dashoffset="16"
8+
stroke-linecap="round"
9+
stroke-width="2"
10+
>
11+
<path d="M7 7L17 17">
12+
<animate
13+
fill="freeze"
14+
attributeName="stroke-dashoffset"
15+
dur="0.4s"
16+
values="16;0"
17+
/>
18+
</path>
19+
<path d="M17 7L7 17">
20+
<animate
21+
fill="freeze"
22+
attributeName="stroke-dashoffset"
23+
begin="0.4s"
24+
dur="0.4s"
25+
values="16;0"
26+
/>
27+
</path>
28+
</g>
29+
</svg>
30+
</template>

src/components/views/calendar/CalendarComponent.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useListScroll } from '~/components/common/list/use-list-scroll';
1212
import IconChevronDown from '~/components/icons/IconChevronDown.vue';
1313
import IconChevronUp from '~/components/icons/IconChevronUp.vue';
1414
15-
import { useItemDrawer } from '~/components/views/drawer/use-item-drawer';
15+
import { usePanelItem } from '~/components/views/panel/use-panel-item';
1616
import { useCalendarStore, useCalendarStoreRefs } from '~/stores/data/calendar.store';
1717
import { useI18n } from '~/utils';
1818
import { watchUserChange } from '~/utils/store.utils';
@@ -100,7 +100,7 @@ const onScrollBottom = async () => {
100100
await fetchCalendar('end');
101101
};
102102
103-
const { onItemClick } = useItemDrawer();
103+
const { onItemClick } = usePanelItem();
104104
</script>
105105

106106
<template>

src/components/views/drawer/ListItemDrawer.vue

-45
This file was deleted.

src/components/views/history/HistoryComponent.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
useListScroll,
88
useListScrollEvents,
99
} from '~/components/common/list/use-list-scroll';
10-
import { useItemDrawer } from '~/components/views/drawer/use-item-drawer';
10+
import { usePanelItem } from '~/components/views/panel/use-panel-item';
1111
import { useHistoryStore, useHistoryStoreRefs } from '~/stores/data/history.store';
1212
import { useI18n } from '~/utils';
1313
import { watchUserChange } from '~/utils/store.utils';
@@ -35,7 +35,7 @@ const { onScroll, onUpdated, onLoadMore } = useListScrollEvents(fetchHistory, {
3535
});
3636
3737
const { scrolled, listRef, onClick } = useBackToTop();
38-
const { onItemClick } = useItemDrawer();
38+
const { onItemClick } = usePanelItem();
3939
</script>
4040

4141
<template>
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script setup lang="ts">
2+
import { onActivated } from 'vue';
3+
4+
const props = defineProps({
5+
movieId: {
6+
type: String,
7+
required: false,
8+
},
9+
});
10+
11+
onActivated(() => {
12+
console.info('MovieDrawer activated', props.movieId);
13+
});
14+
</script>
15+
16+
<template>
17+
<div>movie {{ movieId }}</div>
18+
</template>
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script setup lang="ts">
2+
import { onActivated } from 'vue';
3+
4+
const props = defineProps({
5+
personId: {
6+
type: String,
7+
required: false,
8+
},
9+
});
10+
11+
onActivated(() => {
12+
console.info('PersonPanel activated', props.personId);
13+
});
14+
</script>
15+
16+
<template>
17+
<div>person {{ personId }}</div>
18+
</template>
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<script setup lang="ts">
2+
import { NFlex, NSkeleton } from 'naive-ui';
3+
import { onActivated, onDeactivated, ref, toRefs } from 'vue';
4+
5+
import type { TraktEpisodeExtended } from '~/models/trakt/trakt-episode.model';
6+
import type { TraktShowExtended } from '~/models/trakt/trakt-show.model';
7+
8+
import { type ShowSeasons, useShowStore } from '~/stores/data/show.store';
9+
10+
const props = defineProps({
11+
showId: {
12+
type: String,
13+
required: false,
14+
},
15+
seasonNumber: {
16+
type: String,
17+
required: false,
18+
},
19+
episodeNumber: {
20+
type: String,
21+
required: false,
22+
},
23+
});
24+
25+
const { getShowRef, getShowSeasonsRef, getShowEpisodeRef } = useShowStore();
26+
27+
const show = ref<TraktShowExtended>();
28+
const seasons = ref<ShowSeasons>();
29+
const episode = ref<TraktEpisodeExtended>();
30+
31+
const { showId, seasonNumber, episodeNumber } = toRefs(props);
32+
33+
const subscriptions = new Set<() => void>();
34+
35+
onActivated(() => {
36+
if (showId?.value) subscriptions.add(getShowRef(showId.value, show).unsub);
37+
if (showId?.value) subscriptions.add(getShowSeasonsRef(showId.value, seasons).unsub);
38+
if (showId?.value && seasonNumber?.value && episodeNumber?.value) {
39+
subscriptions.add(
40+
getShowEpisodeRef(
41+
{
42+
id: showId.value,
43+
season: Number(seasonNumber.value),
44+
episode: Number(episodeNumber.value),
45+
},
46+
episode,
47+
).unsub,
48+
);
49+
}
50+
});
51+
52+
onDeactivated(() => {
53+
subscriptions.forEach(unsub => unsub());
54+
subscriptions.clear();
55+
show.value = undefined;
56+
seasons.value = undefined;
57+
episode.value = undefined;
58+
});
59+
</script>
60+
61+
<template>
62+
<NFlex justify="center" align="center"> </NFlex>
63+
<div>show {{ showId }}</div>
64+
<div v-if="show">show : {{ show?.title }}</div>
65+
<NSkeleton v-else />
66+
<div>season {{ seasonNumber }}</div>
67+
<div v-if="seasons">season {{ Object.keys(seasons) }}</div>
68+
<NSkeleton v-else />
69+
<div>episode {{ episodeNumber }}</div>
70+
<div v-if="episode">episode {{ episode?.title }}</div>
71+
<NSkeleton v-else />
72+
</template>

0 commit comments

Comments
 (0)