@@ -4,6 +4,7 @@ import { deCapitalise } from '@dvcol/common-utils/common/string';
4
4
import {
5
5
NEllipsis ,
6
6
NFlex ,
7
+ NIcon ,
7
8
NProgress ,
8
9
NSkeleton ,
9
10
NTag ,
@@ -15,9 +16,12 @@ import { computed, defineProps, type PropType, ref, toRefs } from 'vue';
15
16
import PosterPlaceholder from ' ~/assets/images/poster-placholder.webp' ;
16
17
import TagLink from ' ~/components/common/buttons/TagLink.vue' ;
17
18
import ProgressTooltip from ' ~/components/common/tooltip/ProgressTooltip.vue' ;
19
+ import IconGrid from ' ~/components/icons/IconGrid.vue' ;
20
+ import IconPlayFilled from ' ~/components/icons/IconPlayFilled.vue' ;
18
21
import { type ListScrollItem , type ShowProgress } from ' ~/models/list-scroll.model' ;
19
22
20
23
import { ProgressType } from ' ~/models/progress-type.model' ;
24
+ import { useMovieStore } from ' ~/stores/data/movie.store' ;
21
25
import { useShowStore } from ' ~/stores/data/show.store' ;
22
26
import { useExtensionSettingsStoreRefs } from ' ~/stores/settings/extension.store' ;
23
27
import { useLinksStore } from ' ~/stores/settings/links.store' ;
@@ -57,9 +61,19 @@ const props = defineProps({
57
61
required: false ,
58
62
default: false ,
59
63
},
64
+ showPlayed: {
65
+ type: Boolean ,
66
+ required: false ,
67
+ default: false ,
68
+ },
69
+ showCollected: {
70
+ type: Boolean ,
71
+ required: false ,
72
+ default: false ,
73
+ },
60
74
});
61
75
62
- const { item, hideDate } = toRefs (props );
76
+ const { item, hideDate, showProgress, showPlayed, showCollected } = toRefs (props );
63
77
64
78
const type = computed (() =>
65
79
item .value .type ? i18n (item .value .type , ' common' , ' media' , ' type' ) : item .value .type ,
@@ -84,15 +98,61 @@ const tags = computed(
84
98
}),
85
99
);
86
100
87
- const { getShowWatchedProgress } = useShowStore ();
101
+ const { getShowWatchedProgress, getShowCollectionProgress } = useShowStore ();
88
102
89
103
const progress = computed <ShowProgress | undefined >(() => {
104
+ if (! showProgress .value && ! showPlayed .value && ! showCollected .value ) return ;
90
105
if (item ?.value ?.progress ) return item .value ?.progress ;
91
106
if (item ?.value ?.progressRef ) return item .value ?.progressRef .value ;
92
107
if (! item ?.value ?.getProgressQuery ) return ;
93
- const { id, cacheOptions } = item .value ?.getProgressQuery () ?? {};
108
+ const { id, cacheOptions, noFetch } = item .value ?.getProgressQuery () ?? {};
94
109
if (! id ) return ;
95
- return getShowWatchedProgress (id , cacheOptions ).value ;
110
+ return getShowWatchedProgress (id , cacheOptions , noFetch ).value ;
111
+ });
112
+
113
+ const collection = computed <ShowProgress | undefined >(() => {
114
+ if (! showCollected .value ) return ;
115
+ if (! item ?.value ?.getProgressQuery ) return ;
116
+ const { id, noFetch } = item .value ?.getProgressQuery () ?? {};
117
+ if (! id ) return ;
118
+ return getShowCollectionProgress (id , noFetch ).value ;
119
+ });
120
+
121
+ const { getMovieWatched, getMovieCollected } = useMovieStore ();
122
+
123
+ const played = computed (() => {
124
+ if (! showPlayed .value ) return false ;
125
+ const _item = item ?.value ;
126
+ if (_item ?.type === ' movie' && _item ?.meta ?.ids ?.movie ?.trakt ) {
127
+ return getMovieWatched (_item .meta .ids .movie .trakt )?.value ;
128
+ }
129
+ if (_item ?.type !== ' episode' ) return false ;
130
+ const _progress = progress .value ;
131
+ if (! _progress ) return false ;
132
+ const _season = _item .meta ?.number ?.season ;
133
+ const _episode = _item .meta ?.number ?.episode ;
134
+ if (! _season || ! _episode ) return false ;
135
+ return _progress .seasons
136
+ ?.find (s => s .number === _season )
137
+ ?.episodes ?.find (e => e .number === _episode )?.completed ;
138
+ });
139
+
140
+ const collected = computed (() => {
141
+ if (! showCollected .value ) return false ;
142
+ const _item = item ?.value ;
143
+ if (_item ?.type === ' movie' && _item ?.meta ?.ids ?.movie ?.trakt ) {
144
+ return getMovieCollected (_item .meta .ids .movie .trakt )?.value ;
145
+ }
146
+ if (_item ?.type !== ' episode' ) return false ;
147
+ const _collection = collection .value ;
148
+
149
+ if (! _collection ) return false ;
150
+ const _season = _item .meta ?.number ?.season ;
151
+ const _episode = _item .meta ?.number ?.episode ;
152
+ if (! _season || ! _episode ) return false ;
153
+ return _collection .seasons
154
+ ?.find (s => s .number === _season )
155
+ ?.episodes ?.find (e => e .number === _episode )?.completed ;
96
156
});
97
157
98
158
const { progressType } = useExtensionSettingsStoreRefs ();
@@ -144,17 +204,60 @@ const onTagClick = (url?: string) => {
144
204
content
145
205
}}</NEllipsis >
146
206
</div >
147
- <NFlex v-if =" (!hideTime && date) || tags?.length" size =" medium" class =" tags" >
207
+ <NFlex
208
+ v-if =" (!hideTime && date) || tags?.length || showCollected || showPlayed"
209
+ size =" medium"
210
+ class =" tags"
211
+ >
148
212
<template v-for =" (tag , i ) of tags " :key =" ` ${i }-${tag .label } ` " >
149
213
<NSkeleton v-if =" loading" text style =" width : 6% " />
150
214
<TagLink :tag =" tag" @on-click =" onTagClick" />
151
215
</template >
152
216
<template v-if =" ! hideTime && date " >
153
- <NSkeleton v-if =" loading" text style =" width : 6% " />
154
- <NTag v-else class =" tag" size =" small" type =" default" :bordered =" false" >
217
+ <NSkeleton v-if =" loading" key =" date-loader" text style =" width : 6% " />
218
+ <NTag
219
+ v-else
220
+ key =" date"
221
+ class =" tag"
222
+ size =" small"
223
+ type =" default"
224
+ :bordered =" false"
225
+ >
155
226
{{ date }}
156
227
</NTag >
157
228
</template >
229
+ <template v-if =" showCollected && collected " >
230
+ <NSkeleton v-if =" loading" key =" collected-loader" text style =" width : 3% " />
231
+ <NTag
232
+ v-else
233
+ key =" collected"
234
+ class =" tag badge"
235
+ size =" small"
236
+ type =" info"
237
+ :bordered =" false"
238
+ :title =" i18n('collected', 'common', 'tooltip')"
239
+ >
240
+ <template #icon >
241
+ <NIcon :component =" IconGrid" />
242
+ </template >
243
+ </NTag >
244
+ </template >
245
+ <template v-if =" showPlayed && played " >
246
+ <NSkeleton v-if =" loading" key =" played-loader" text style =" width : 3% " />
247
+ <NTag
248
+ v-else
249
+ key =" played"
250
+ class =" tag badge"
251
+ size =" small"
252
+ type =" primary"
253
+ :bordered =" false"
254
+ :title =" i18n('watched', 'common', 'tooltip')"
255
+ >
256
+ <template #icon >
257
+ <NIcon :component =" IconPlayFilled" />
258
+ </template >
259
+ </NTag >
260
+ </template >
158
261
</NFlex >
159
262
<div v-if =" showProgress && !loading" class =" panel-progress" >
160
263
<ProgressTooltip :progress =" progress" :to =" innerContainer" placement =" top-end" >
@@ -222,4 +325,9 @@ const onTagClick = (url?: string) => {
222
325
.panel-progress-tooltip.n-tooltip.n-tooltip {
223
326
background : var (--bg-color-80 );
224
327
}
328
+
329
+ // stylelint-disable-next-line selector-class-pattern -- framework overriding
330
+ .n-tag.n-tag--icon.tag.badge .n-tag__icon {
331
+ margin : 0 ;
332
+ }
225
333
</style >
0 commit comments