1
1
<script setup lang="ts">
2
- import { NFlex , NH2 , NH4 , NSkeleton } from ' naive-ui' ;
3
- import { computed , onMounted , onUnmounted , ref , toRefs , Transition , watch } from ' vue' ;
2
+ import { NFlex , NSkeleton } from ' naive-ui' ;
3
+ import { computed , onMounted , onUnmounted , ref , toRefs , watch } from ' vue' ;
4
4
5
- import type { TraktEpisodeExtended } from ' ~/models/trakt/trakt-episode.model' ;
5
+ import type {
6
+ TraktEpisodeExtended ,
7
+ TraktEpisodeShort ,
8
+ } from ' ~/models/trakt/trakt-episode.model' ;
6
9
import type { TraktShowExtended } from ' ~/models/trakt/trakt-show.model' ;
7
10
11
+ import TitleLink from ' ~/components/common/buttons/TitleLink.vue' ;
12
+ import ShowPanelOverview from ' ~/components/views/panel/ShowPanelOverview.vue' ;
8
13
import ShowPanelPicker from ' ~/components/views/panel/ShowPanelPicker.vue' ;
9
14
import ShowPanelPoster from ' ~/components/views/panel/ShowPanelPoster.vue' ;
15
+ import { ResolveExternalLinks } from ' ~/settings/external.links' ;
10
16
import { type ShowSeasons , useShowStore } from ' ~/stores/data/show.store' ;
17
+ import { useExtensionSettingsStore } from ' ~/stores/settings/extension.store' ;
11
18
import { deCapitalise } from ' ~/utils/string.utils' ;
12
19
13
20
const props = defineProps ({
@@ -25,10 +32,9 @@ const props = defineProps({
25
32
},
26
33
});
27
34
28
- const { getShowRef, getShowSeasonsRef, getShowEpisodeRef } = useShowStore ();
29
-
30
35
const show = ref <TraktShowExtended >();
31
36
const seasons = ref <ShowSeasons >();
37
+ const episodes = ref <TraktEpisodeShort []>();
32
38
const episode = ref <TraktEpisodeExtended >();
33
39
34
40
const { showId, seasonNumber, episodeNumber } = toRefs (props );
@@ -47,50 +53,65 @@ const episodeNb = computed(() => {
47
53
return _episodeNumber ;
48
54
});
49
55
56
+ const panelType = computed <' show' | ' season' | ' episode' >(() => {
57
+ if (episodeNb ?.value !== undefined && seasonNb ?.value !== undefined ) return ' episode' ;
58
+ if (seasonNb ?.value !== undefined ) return ' season' ;
59
+ return ' show' ;
60
+ });
61
+
50
62
const showTitle = computed (() => {
51
63
if (! show .value ?.title ) return ;
52
64
return deCapitalise (show .value .title );
53
65
});
54
66
55
- const episodeTitle = computed (() => {
56
- if (! episode .value ?.title ) return ;
57
- return deCapitalise (episode .value ?.title );
58
- });
59
-
60
67
const subscriptions = new Set <() => void >();
61
68
69
+ const { getShowRef, getShowSeasonsRef, getShowSeasonEpisodesRef, getShowEpisodeRef } =
70
+ useShowStore ();
71
+
62
72
const watchData = () =>
63
73
watch (
64
- props ,
74
+ [ showId , seasonNb , episodeNb ] ,
65
75
(next , prev ) => {
66
- if (next .showId !== prev ?.showId ) {
76
+ // show changes
77
+ if (next .at (0 ) !== prev ?.at (0 )) {
67
78
show .value = undefined ;
68
79
seasons .value = undefined ;
80
+ episodes .value = undefined ;
69
81
episode .value = undefined ;
70
- } else if (next .episodeNumber !== prev ?.episodeNumber ) {
82
+ }
83
+ // season changes
84
+ else if (next .at (1 ) !== prev ?.at (1 )) {
71
85
episode .value = undefined ;
72
- } else if (next .seasonNumber !== prev ?.seasonNumber ) {
86
+ episodes .value = undefined ;
87
+ }
88
+ // episode changes
89
+ else if (next .at (2 ) !== prev ?.at (2 )) {
73
90
episode .value = undefined ;
74
91
}
75
92
76
- if (showId ?.value ) subscriptions . add ( getShowRef ( showId . value , show ). unsub );
77
- if ( showId ? .value )
93
+ if (showId ?.value ) {
94
+ subscriptions . add ( getShowRef ( showId .value , show ). unsub );
78
95
subscriptions .add (getShowSeasonsRef (showId .value , seasons ).unsub );
79
- if (
80
- showId ?.value &&
81
- seasonNb ?.value !== undefined &&
82
- episodeNb ?.value !== undefined
83
- ) {
84
- subscriptions .add (
85
- getShowEpisodeRef (
86
- {
87
- id: showId .value ,
88
- season: seasonNb .value ,
89
- episode: episodeNb .value ,
90
- },
91
- episode ,
92
- ).unsub ,
93
- );
96
+
97
+ if (seasonNb ?.value !== undefined ) {
98
+ subscriptions .add (
99
+ getShowSeasonEpisodesRef (showId .value , seasonNb ?.value , episodes ).unsub ,
100
+ );
101
+ }
102
+
103
+ if (seasonNb ?.value !== undefined && episodeNb ?.value !== undefined ) {
104
+ subscriptions .add (
105
+ getShowEpisodeRef (
106
+ {
107
+ id: showId .value ,
108
+ season: seasonNb .value ,
109
+ episode: episodeNb .value ,
110
+ },
111
+ episode ,
112
+ ).unsub ,
113
+ );
114
+ }
94
115
}
95
116
},
96
117
{ immediate: true },
@@ -104,41 +125,40 @@ onUnmounted(() => {
104
125
subscriptions .forEach (unsub => unsub ());
105
126
subscriptions .clear ();
106
127
});
128
+
129
+ const { openTab } = useExtensionSettingsStore ();
130
+
131
+ const titleUrl = computed (() => {
132
+ if (! show .value ?.ids ?.trakt ) return ;
133
+ return ResolveExternalLinks .search ({
134
+ type: ' show' ,
135
+ source: ' trakt' ,
136
+ id: show .value .ids .trakt ,
137
+ });
138
+ });
107
139
</script >
108
140
109
141
<template >
110
142
<NFlex justify =" center" align =" center" vertical >
111
- <NH2 v-if =" showTitle" class =" show-title" >{{ showTitle }}</NH2 >
112
- <NSkeleton v-else />
143
+ <TitleLink v-if =" showTitle" class =" show-title" :href =" titleUrl" @on-click =" openTab" >
144
+ {{ showTitle }}
145
+ </TitleLink >
146
+ <NSkeleton v-else class =" show-title-skeleton" style =" width : 50 dvh" round />
113
147
114
- <ShowPanelPicker :seasons =" seasons" :season-number = " seasonNb " />
148
+ <ShowPanelPicker :seasons =" seasons" :episodes = " episodes " :mode = " panelType " />
115
149
116
150
<ShowPanelPoster
117
151
:show-id =" show?.ids.tmdb"
118
152
:season-number =" seasonNb"
119
153
:episode-number =" episodeNb"
120
154
/>
121
155
122
- <Transition name =" scale" mode =" out-in" >
123
- <NFlex
124
- v-if =" episodeNumber !== undefined"
125
- :key =" `season-${seasonNb}-episode-${episodeNb}`"
126
- justify =" center"
127
- align =" center"
128
- vertical
129
- class =" episode-container"
130
- >
131
- <NH4 v-if =" episodeTitle" class =" episode-title" >{{ episodeTitle }}</NH4 >
132
- <NSkeleton v-else />
133
-
134
- <div v-if =" episode" >{{ episode?.overview }}</div >
135
- <NSkeleton v-else />
136
- </NFlex >
137
- </Transition >
156
+ <ShowPanelOverview v-if =" panelType === 'episode'" :episode =" episode" />
138
157
</NFlex >
139
158
</template >
140
159
141
160
<style lang="scss" scoped>
161
+ @use ' ~/styles/z-index' as layers ;
142
162
@use ' ~/styles/transition' as transition ;
143
163
@include transition .scale ;
144
164
@@ -156,19 +176,13 @@ onUnmounted(() => {
156
176
box-shadow : var (--image-box-shadow );
157
177
}
158
178
159
- .show-title {
179
+ .show-title :deep(h2 ),
180
+ .show-title-skeleton {
160
181
margin-bottom : 0.5rem ;
161
182
}
162
183
163
- .episode {
164
- & -container {
165
- width : 100% ;
166
- }
167
-
168
- & -title {
169
- margin-top : 1rem ;
170
- margin-bottom : 1rem ;
171
- font-weight : bold ;
172
- }
184
+ .show-title-skeleton {
185
+ height : 1.5rem ;
186
+ margin-top : 0.625rem ;
173
187
}
174
188
</style >
0 commit comments