Skip to content

Commit 95781a2

Browse files
committed
feat(drawer): initial aside panel commit
1 parent fd3c7db commit 95781a2

16 files changed

+188
-26
lines changed

src/components/AppComponent.vue

+61-14
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,86 @@
11
<script setup lang="ts">
2-
import { Transition } from 'vue';
3-
import { RouterView } from 'vue-router';
2+
import { NDrawer, NDrawerContent } from 'naive-ui';
3+
import { ref, Transition, watch } from 'vue';
4+
import { RouterView, useRouter } from 'vue-router';
45
56
import { NavbarComponent } from '~/components/common';
67
import GridBackground from '~/components/common/background/GridBackground.vue';
78
import PageLoading from '~/components/common/loading/PageLoading.vue';
9+
import DrawerHeader from '~/components/views/drawer/DrawerHeader.vue';
810
import { useAuthSettingsStoreRefs } from '~/stores/settings/auth.store';
911
1012
const { isAuthenticated } = useAuthSettingsStoreRefs();
13+
const { currentRoute, push } = useRouter();
14+
15+
const origin = ref();
16+
const drawer = ref(false);
17+
18+
watch(
19+
currentRoute,
20+
(_next, _prev) => {
21+
const isDrawer = !!_next.meta?.drawer;
22+
drawer.value = isDrawer;
23+
origin.value = isDrawer ? _prev : undefined;
24+
},
25+
{
26+
immediate: true,
27+
},
28+
);
29+
30+
const asideRef = ref();
31+
32+
const onClose = () => {
33+
if (!origin.value) return;
34+
push(origin.value);
35+
origin.value = undefined;
36+
};
1137
</script>
1238

1339
<template>
14-
<header>
15-
<RouterView v-slot="{ Component, route }" name="navbar">
40+
<header :class="{ open: drawer }">
41+
<RouterView v-slot="{ Component }" name="navbar">
1642
<NavbarComponent v-if="isAuthenticated">
1743
<template v-if="Component" #drawer="{ parentElement }">
1844
<Transition name="scale" mode="out-in">
1945
<KeepAlive>
20-
<component
21-
:is="Component"
22-
:key="route.path"
23-
:parent-element="parentElement"
24-
/>
46+
<component :is="Component" :parent-element="parentElement" />
2547
</KeepAlive>
2648
</Transition>
2749
</template>
2850
</NavbarComponent>
2951
</RouterView>
3052
</header>
31-
<main>
32-
<RouterView v-slot="{ Component, route }">
53+
<RouterView v-slot="{ Component }">
54+
<main ref="asideRef" style="position: relative">
3355
<GridBackground v-if="!Component" :size="20" />
3456
<Transition name="scale" mode="out-in">
3557
<KeepAlive>
36-
<component :is="Component ?? PageLoading" :key="route.path" />
58+
<component :is="Component ?? PageLoading" />
3759
</KeepAlive>
3860
</Transition>
39-
</RouterView>
40-
</main>
61+
</main>
62+
<aside>
63+
<RouterView v-slot="{ Component: DrawerComponent }">
64+
<NDrawer
65+
v-model:show="drawer"
66+
:to="asideRef"
67+
width="100%"
68+
close-on-esc
69+
:on-after-leave="onClose"
70+
auto-focus
71+
>
72+
<NDrawerContent closable>
73+
<template #header> <DrawerHeader /> </template>
74+
<template #default>
75+
<KeepAlive>
76+
<component :is="DrawerComponent" />
77+
</KeepAlive>
78+
</template>
79+
</NDrawerContent>
80+
</NDrawer>
81+
</RouterView>
82+
</aside>
83+
</RouterView>
4184
</template>
4285

4386
<style lang="scss" scoped>
@@ -60,6 +103,10 @@ header {
60103
> :first-child {
61104
@include mixin.hover-background;
62105
}
106+
107+
&.open > :first-child {
108+
background: var(--bg-color-hover);
109+
}
63110
}
64111
65112
main {

src/components/common/list/ListItem.vue

+4
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ const props = defineProps({
7676
7777
const emit = defineEmits<{
7878
(e: 'onHover', event: { item: ListScrollItem; hover: boolean }): void;
79+
(e: 'onItemClick', event: { item: ListScrollItem }): void;
7980
(e: 'onScrollIntoView', event: { item: ListScrollItem; ref?: HTMLDivElement }): void;
8081
(e: 'onScrollOutOfView', event: { item: ListScrollItem; ref?: HTMLDivElement }): void;
8182
}>();
@@ -173,6 +174,8 @@ onBeforeUnmount(() => {
173174
});
174175
175176
const itemHeight = computed(() => (height?.value ? `${height.value}px` : undefined));
177+
178+
const onClick = () => emit('onItemClick', { item: item?.value });
176179
</script>
177180

178181
<template>
@@ -193,6 +196,7 @@ const itemHeight = computed(() => (height?.value ? `${height.value}px` : undefin
193196
:data-type="item.type"
194197
:line-type="loading ? 'dashed' : lineType"
195198
:color="loading ? 'grey' : color"
199+
@click="onClick"
196200
@mouseenter="onHover(true)"
197201
@mouseleave="onHover(false)"
198202
>

src/components/common/list/ListItemPanel.vue

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ const tooltipOptions = computed<PopoverProps>(() => ({
9595
const { openLinksInNewTab } = useExtensionSettingsStoreRefs();
9696
const onTagClick = (e: MouseEvent, url?: string) => {
9797
e.preventDefault();
98+
e.stopPropagation();
9899
if (!url) return;
99100
createTab({ url, active: openLinksInNewTab.value });
100101
};

src/components/common/list/ListScroll.vue

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const emits = defineEmits<{
7878
pageSize: number;
7979
},
8080
): void;
81+
(e: 'onItemClick', event: { item: ListScrollItem }): void;
8182
(e: 'onScrollIntoView', event: { item: ListScrollItem; ref?: HTMLDivElement }): void;
8283
(e: 'onScrollOutOfView', event: { item: ListScrollItem; ref?: HTMLDivElement }): void;
8384
}>();
@@ -178,6 +179,7 @@ const onLoadMore = (payload: { page: number; pageCount: number; pageSize: number
178179
:scroll-into-view="scrollIntoView?.includes(item.id)"
179180
:show-progress="showProgress"
180181
@on-hover="onHover"
182+
@on-item-click="(...args) => $emit('onItemClick', ...args)"
181183
@on-scroll-into-view="(...args) => $emit('onScrollIntoView', ...args)"
182184
@on-scroll-out-of-view="(...args) => $emit('onScrollOutOfView', ...args)"
183185
>

src/components/common/navbar/NavbarComponent.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const router = useRouter();
1414
const slots = useSlots();
1515
1616
const navigate = (to: Route) => {
17-
router.push(to);
17+
router.push({ name: to });
1818
};
1919
2020
const routes = [

src/components/container/ContainerComponent.ce.vue

+5
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ const root = ref<HTMLElement>();
114114
}
115115
}
116116
117+
.n-drawer {
118+
background: linear-gradient(to right, var(--bg-color-60) 5%, var(--bg-color-90));
119+
backdrop-filter: blur(var(--bg-blur));
120+
}
121+
117122
.n-tooltip.n-tooltip,
118123
.n-popover-arrow.n-popover-arrow.n-popover-arrow {
119124
background: var(--bg-color-60);

src/components/views/calendar/CalendarComponent.vue

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +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';
1516
import { useCalendarStore, useCalendarStoreRefs } from '~/stores/data/calendar.store';
1617
import { useI18n } from '~/utils';
1718
import { watchUserChange } from '~/utils/store.utils';
@@ -94,9 +95,12 @@ const onScrollTop = async () => {
9495
top: (list.value.findIndex(item => item.id === first.id) - 1) * 145,
9596
});
9697
};
98+
9799
const onScrollBottom = async () => {
98100
await fetchCalendar('end');
99101
};
102+
103+
const { onItemClick } = useItemDrawer();
100104
</script>
101105

102106
<template>
@@ -107,6 +111,7 @@ const onScrollBottom = async () => {
107111
:loading="loading"
108112
episode
109113
:scroll-into-view="centerItem?.id ? [centerItem?.id] : []"
114+
@on-item-click="onItemClick"
110115
@on-scroll-into-view="e => onScrollIntoOutOfView(false, e.ref)"
111116
@on-scroll-out-of-view="e => onScrollIntoOutOfView(true, e.ref)"
112117
@on-scroll-top="onScrollTop"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { useRouter } from 'vue-router';
2+
3+
import type { ListScrollItem } from '~/models/list-scroll.model';
4+
5+
export const useItemDrawer = () => {
6+
const { push, currentRoute } = useRouter();
7+
8+
const onItemClick = ({ item }: { item: ListScrollItem }) => {
9+
const type = item?.type;
10+
if (!type) return;
11+
const { path } = currentRoute.value;
12+
if (!path) return;
13+
const id = item?.meta?.ids?.[type]?.trakt;
14+
const showId = item?.meta?.ids?.show?.trakt;
15+
const seasonId = item?.meta?.ids?.season?.trakt;
16+
const episodeId = item?.meta?.ids?.episode?.trakt;
17+
switch (type) {
18+
case 'person':
19+
case 'movie':
20+
case 'show':
21+
if (!id) return;
22+
return push(`${path}/${type}/${id}`);
23+
case 'season':
24+
if (!showId || !seasonId) return;
25+
return push({ path: `${path}/show/${showId}/${type}/${seasonId}` });
26+
case 'episode':
27+
if (!showId || !episodeId) return;
28+
return push({
29+
path: `${path}/show/${showId}/${type}/${episodeId}`,
30+
});
31+
default:
32+
break;
33+
}
34+
};
35+
36+
return { onItemClick, currentRoute, push };
37+
};

src/components/views/history/HistoryComponent.vue

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +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';
1011
import { useHistoryStore, useHistoryStoreRefs } from '~/stores/data/history.store';
1112
import { useI18n } from '~/utils';
1213
import { watchUserChange } from '~/utils/store.utils';
@@ -34,6 +35,7 @@ const { onScroll, onUpdated, onLoadMore } = useListScrollEvents(fetchHistory, {
3435
});
3536
3637
const { scrolled, listRef, onClick } = useBackToTop();
38+
const { onItemClick } = useItemDrawer();
3739
</script>
3840

3941
<template>
@@ -49,6 +51,7 @@ const { scrolled, listRef, onClick } = useBackToTop();
4951
@on-scroll-bottom="onScroll"
5052
@on-updated="onUpdated"
5153
@onload-more="onLoadMore"
54+
@on-item-click="onItemClick"
5255
>
5356
<template #default>
5457
<!-- TODO buttons here-->

src/components/views/progress/ProgressComponent.vue

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import FloatingButton from '~/components/common/buttons/FloatingButton.vue';
66
import { useBackToTop } from '~/components/common/buttons/use-back-to-top';
77
import ListScroll from '~/components/common/list/ListScroll.vue';
88
9+
import { useItemDrawer } from '~/components/views/drawer/use-item-drawer';
910
import LoginCard from '~/components/views/login/LoginCard.vue';
1011
import { ExternaLinks } from '~/settings/external.links';
1112
import { useProgressStore, useProgressStoreRefs } from '~/stores/data/progress.store';
@@ -21,6 +22,7 @@ onMounted(async () => {
2122
});
2223
2324
const { scrolled, listRef, onClick } = useBackToTop();
25+
const { onItemClick } = useItemDrawer();
2426
</script>
2527

2628
<template>
@@ -47,6 +49,7 @@ const { scrolled, listRef, onClick } = useBackToTop();
4749
show-progress
4850
@on-scroll="scrolled = true"
4951
@on-scroll-top="scrolled = false"
52+
@on-item-click="onItemClick"
5053
>
5154
<template #default>
5255
<!-- TODO buttons here-->

src/components/views/search/SearchComponent.vue

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
useListScroll,
1010
useListScrollEvents,
1111
} from '~/components/common/list/use-list-scroll';
12+
import { useItemDrawer } from '~/components/views/drawer/use-item-drawer';
1213
import {
1314
type SearchResult,
1415
useSearchStore,
@@ -34,6 +35,7 @@ const { onScroll } = useListScrollEvents(fetchSearchResults, {
3435
});
3536
3637
const { scrolled, listRef, onClick } = useBackToTop();
38+
const { onItemClick } = useItemDrawer();
3739
</script>
3840

3941
<template>
@@ -46,6 +48,7 @@ const { scrolled, listRef, onClick } = useBackToTop();
4648
@on-scroll="scrolled = true"
4749
@on-scroll-top="scrolled = false"
4850
@on-scroll-bottom="onScroll"
51+
@on-item-click="onItemClick"
4952
>
5053
<template #default>
5154
<!-- TODO buttons here-->

src/components/views/watchlist/WatchlistComponent.vue

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +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';
1011
import {
1112
type AnyList,
1213
anyListDateGetter,
@@ -43,6 +44,7 @@ const { onScroll, onUpdated, onLoadMore } = useListScrollEvents(fetchListItems,
4344
});
4445
4546
const { scrolled, listRef, onClick } = useBackToTop();
47+
const { onItemClick } = useItemDrawer();
4648
</script>
4749

4850
<template>
@@ -59,6 +61,7 @@ const { scrolled, listRef, onClick } = useBackToTop();
5961
@on-scroll-bottom="onScroll"
6062
@on-updated="onUpdated"
6163
@onload-more="onLoadMore"
64+
@on-item-click="onItemClick"
6265
>
6366
<template #default>
6467
<!-- TODO buttons here-->

0 commit comments

Comments
 (0)