Skip to content

Commit e9733d4

Browse files
committed
feat(panel): adds progress to picker
1 parent d16a742 commit e9733d4

12 files changed

+68
-42
lines changed

src/components/AppComponent.vue

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ header {
131131
132132
&.open > :first-child {
133133
background: var(--bg-color-hover);
134+
backdrop-filter: blur(var(--bg-blur-20));
134135
}
135136
}
136137

src/components/common/buttons/ButtonLink.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ defineProps({
2424
>
2525
<NButton
2626
tag="a"
27-
quaternary
27+
:secondary="isActive"
28+
:quaternary="!isActive"
2829
class="button-link"
2930
:class="$attrs.class"
30-
:type="isActive ? 'primary' : 'default'"
3131
round
3232
size="small"
3333
:href="href"

src/components/common/list/ListItemPanel.vue

+7-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { computed, defineProps, type PropType, ref, toRefs } from 'vue';
1313
1414
import PosterPlaceholder from '~/assets/images/poster-placholder.webp';
1515
import TagLink from '~/components/common/buttons/TagLink.vue';
16-
import { type ListScrollItem } from '~/models/list-scroll.model';
16+
import { type ListScrollItem, type ShowProgress } from '~/models/list-scroll.model';
1717
1818
import { useShowStore } from '~/stores/data/show.store';
1919
import { useExtensionSettingsStore } from '~/stores/settings/extension.store';
@@ -76,11 +76,11 @@ const tags = computed(
7676
7777
const { getShowProgress } = useShowStore();
7878
79-
const progress = computed(() => {
80-
if (item?.value?.progress) return item.value.progress;
81-
if (item?.value?.progressRef) return item.value.progressRef.value;
79+
const progress = computed<ShowProgress | undefined>(() => {
80+
if (item?.value?.progress) return item.value?.progress;
81+
if (item?.value?.progressRef) return item.value?.progressRef.value;
8282
if (!item?.value?.getProgressQuery) return;
83-
const id = item.value.getProgressQuery();
83+
const id = item.value?.getProgressQuery();
8484
if (!id) return;
8585
return getShowProgress(id).value;
8686
});
@@ -148,7 +148,7 @@ const onTagClick = (url?: string) => {
148148
<div>
149149
<span class="metric">{{ progress?.completed }}</span>
150150
<span> / </span>
151-
<span class="metric">{{ progress?.total }}</span>
151+
<span class="metric">{{ progress?.aired }}</span>
152152
<span>&nbsp;</span>
153153
<span>{{ i18n('tooltip_episodes') }}</span>
154154
</div>
@@ -159,7 +159,7 @@ const onTagClick = (url?: string) => {
159159
<span>{{ i18n('tooltip_watched') }}</span>
160160
</div>
161161
<div>
162-
<span class="metric">{{ progress?.total - progress?.completed }}</span>
162+
<span class="metric">{{ progress?.aired - progress?.completed }}</span>
163163
<span>&nbsp;</span>
164164
<span>{{ i18n('tooltip_remaining') }}</span>
165165
</div>

src/components/container/ContainerComponent.ce.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ const root = ref<HTMLElement>();
166166
167167
.n-drawer {
168168
background: linear-gradient(to right, var(--bg-color-60) 5%, var(--bg-color-90));
169-
backdrop-filter: blur(var(--bg-blur));
169+
backdrop-filter: blur(var(--bg-blur-20));
170170
}
171171
172172
.n-message-wrapper .n-message,

src/components/views/panel/ShowPanel.vue

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ const episode = ref<TraktEpisodeExtended>();
4040
4141
const { showId, seasonNumber, episodeNumber } = toRefs(props);
4242
43+
const { getShowProgress } = useShowStore();
44+
45+
const progress = computed(() => {
46+
if (!showId?.value) return;
47+
return getShowProgress(showId.value).value;
48+
});
49+
4350
const seasonNb = computed(() => {
4451
if (seasonNumber?.value === undefined) return;
4552
const _seasonNumber = Number(seasonNumber.value);

src/components/views/panel/ShowPanelPicker.vue

+25-11
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@ import { computed, type PropType, toRefs } from 'vue';
55
66
import { useRoute } from 'vue-router';
77
8+
import type { ShowProgress } from '~/models/list-scroll.model';
89
import type { TraktEpisodeShort } from '~/models/trakt/trakt-episode.model';
910
import type { ShowSeasons } from '~/stores/data/show.store';
1011
1112
import ButtonLink from '~/components/common/buttons/ButtonLink.vue';
1213
import { useI18n } from '~/utils';
1314
1415
const props = defineProps({
16+
mode: {
17+
type: String as PropType<'show' | 'season' | 'episode'>,
18+
required: false,
19+
default: 'episode',
20+
},
1521
seasons: {
1622
type: Object as PropType<ShowSeasons>,
1723
required: false,
@@ -20,34 +26,40 @@ const props = defineProps({
2026
type: Array as PropType<TraktEpisodeShort[]>,
2127
required: false,
2228
},
23-
mode: {
24-
type: String as PropType<'show' | 'season' | 'episode'>,
29+
progress: {
30+
type: Object as PropType<ShowProgress>,
2531
required: false,
26-
default: 'episode',
2732
},
2833
});
2934
30-
const { seasons, episodes } = toRefs(props);
35+
const { seasons, episodes, progress } = toRefs(props);
3136
3237
const { meta } = useRoute();
3338
3439
const seasonsLinks = computed(() => {
3540
if (!seasons?.value) return;
36-
return Object.entries(seasons.value).map(([_number, _season]) => ({
37-
number: Number(_number),
38-
link: { name: `${meta.base}-season`, params: { seasonNumber: _number } },
39-
}));
41+
return Object.entries(seasons.value).map(([_number, _season]) => {
42+
const number = Number(_number);
43+
return {
44+
number,
45+
link: { name: `${meta.base}-season`, params: { seasonNumber: _number } },
46+
finished: progress?.value?.seasons?.find(s => s.number === number)?.finished,
47+
};
48+
});
4049
});
4150
4251
const episodeLinks = computed(() => {
4352
if (!episodes?.value) return;
4453
if (!episodes?.value?.length) return [];
45-
return episodes.value.map(_episode => ({
54+
return episodes.value.map((_episode, i) => ({
4655
number: _episode.number,
4756
link: {
4857
name: `${meta.base}-episode`,
4958
params: { episodeNumber: _episode.number, seasonNumber: _episode.season },
5059
},
60+
finished: progress?.value?.seasons
61+
?.find(s => s.number === _episode.season)
62+
?.episodes?.find(e => e.number === _episode.number)?.completed,
5163
}));
5264
});
5365
@@ -62,9 +74,10 @@ const i18n = useI18n('panel', 'picker');
6274
<NFlex class="numbers" size="small">
6375
<template v-if="seasonsLinks?.length">
6476
<ButtonLink
65-
v-for="{ link, number } in seasonsLinks"
77+
v-for="{ link, number, finished } in seasonsLinks"
6678
:key="`season-${number}`"
6779
:link="{ to: link }"
80+
:button="{ type: finished ? 'primary' : undefined }"
6881
>
6982
{{ number }}
7083
</ButtonLink>
@@ -80,10 +93,11 @@ const i18n = useI18n('panel', 'picker');
8093
<NFlex class="numbers episodes" size="small">
8194
<template v-if="episodeLinks?.length">
8295
<ButtonLink
83-
v-for="{ link, number } in episodeLinks"
96+
v-for="{ link, number, finished } in episodeLinks"
8497
:key="`episode-${ number }`"
8598
v-slot="{ isActive }"
8699
:link="{ to: link }"
100+
:button="{ type: finished ? 'primary' : undefined }"
87101
class="link"
88102
>
89103
<span class="label" :class="{ active: isActive }">{{ number }}</span>

src/components/views/panel/use-panel-item.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const usePanelItem = () => {
2525
params: { [`${type}Id`]: id },
2626
});
2727
case 'season':
28-
if (!showId || !seasonNumber) return;
28+
if (showId === undefined || seasonNumber === undefined) return;
2929
return push({
3030
name: `${base}-${type}`,
3131
params: {
@@ -34,7 +34,7 @@ export const usePanelItem = () => {
3434
},
3535
});
3636
case 'episode':
37-
if (!showId || !seasonNumber || !episodeNumber) return;
37+
if (showId === undefined || seasonNumber === undefined || episodeNumber === undefined) return;
3838
return push({
3939
name: `${base}-${type}`,
4040
params: {

src/models/list-scroll.model.ts

+10-9
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,28 @@ export type ListScrollItemTag = {
4040
i18n?: boolean | string[];
4141
} & TagLink;
4242

43-
export type ListScrollItemProgressEpisode = BaseTraktProgressEpisode & {
43+
export type EpisodeProgress = BaseTraktProgressEpisode & {
4444
date: Date;
4545
};
4646

47-
export type ListScrollItemProgressSeason = BaseTraktProgressSeason & {
48-
episodes: ListScrollItemProgressEpisode[];
47+
export type SeasonProgress = BaseTraktProgressSeason & {
48+
episodes: EpisodeProgress[];
49+
percentage: number;
50+
finished: boolean;
4951
};
5052

5153
export const ListScrollItemProgressType = {
5254
collection: 'collection',
5355
watched: 'watched',
5456
} as const;
5557

56-
export type ListScrollItemProgress = BaseTraktProgress & {
58+
export type ShowProgress = BaseTraktProgress & {
5759
id: string | number;
5860
type: (typeof ListScrollItemProgressType)[keyof typeof ListScrollItemProgressType];
5961
date: Date;
60-
seasons: ListScrollItemProgressSeason[];
62+
seasons: SeasonProgress[];
6163
percentage: number;
62-
completed: number;
63-
total: number;
64+
finished: boolean;
6465
};
6566

6667
export const ListScrollItemType = {
@@ -85,8 +86,8 @@ export type ListScrollItem<T = Record<string, any>> = Omit<PosterItem, 'type'> &
8586
content?: string;
8687
tags?: ListScrollItemTag[];
8788

88-
progress?: ListScrollItemProgress;
89-
progressRef?: Ref<ListScrollItemProgress | undefined>;
89+
progress?: ShowProgress;
90+
progressRef?: Ref<ShowProgress | undefined>;
9091
getProgressQuery?: () => string | number | undefined;
9192

9293
meta?: T;

src/services/trakt.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ export class TraktService {
312312
},
313313

314314
async show(showId: string | number) {
315-
const response = await TraktService.traktClient.shows.progress.watched.cached({ id: showId });
315+
const response = await TraktService.traktClient.shows.progress.watched.cached({ id: showId, specials: true, count_specials: false });
316316
return response.json();
317317
},
318318
};

src/stores/data/show.store.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { TraktWatchedProgress } from '~/models/trakt/trakt-progress.model';
77
import type { TraktSeasonExtended } from '~/models/trakt/trakt-season.model';
88
import type { TraktShowExtended } from '~/models/trakt/trakt-show.model';
99

10-
import { type ListScrollItemProgress, ListScrollItemProgressType } from '~/models/list-scroll.model';
10+
import { ListScrollItemProgressType, type ShowProgress } from '~/models/list-scroll.model';
1111
import { NotificationService } from '~/services/notification.service';
1212
import { TraktService } from '~/services/trakt.service';
1313
import { asyncRefGetter } from '~/utils/vue.utils';
@@ -24,19 +24,18 @@ type LoadingDictionary = Record<string, boolean>;
2424
type SeasonEpisodesLoadingDictionary = Record<string, Record<number, boolean>>;
2525
type EpisodeLoadingDictionary = Record<string, Record<number, Record<number, boolean>>>;
2626

27-
const watchProgressToListProgress = (progress: TraktWatchedProgress, id: string | number): ListScrollItemProgress => {
28-
const total: number = progress.aired;
29-
const { completed } = progress;
30-
const percentage = (completed / total) * 100;
27+
const watchProgressToListProgress = (progress: TraktWatchedProgress, id: string | number): ShowProgress => {
3128
return {
3229
id,
33-
percentage,
34-
total,
3530
...progress,
31+
percentage: (progress.completed / progress.aired) * 100,
32+
finished: progress.completed === progress.aired,
3633
type: ListScrollItemProgressType.watched,
3734
date: new Date(progress.last_watched_at),
3835
seasons: progress.seasons.map(season => ({
3936
...season,
37+
percentage: (season.completed / season.aired) * 100,
38+
finished: season.completed === season.aired,
4039
episodes: season.episodes.map(episode => ({
4140
...episode,
4241
date: new Date(episode.last_watched_at),

src/styles/base.scss

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
--vt-c-text-dark-2: rgb(235 235 235 / 64%);
1818

1919
/* ui color variables */
20-
--bg-blur: 2px;
20+
--bg-blur: 1px;
21+
--bg-blur-20: 20px;
22+
--bg-blur-40: 40px;
2123
--bg-black: rgba(0 0 0);
2224
--bg-black-20: rgba(0 0 0 / 20%);
2325
--bg-black-30: rgba(0 0 0 / 30%);

src/styles/mixin.scss

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22
$from: var(--bg-color),
33
$to: var(--bg-color-hover),
44
$blur: var(--bg-blur),
5+
$blur-hover: var(--bg-blur-20),
56
$transition: 0.5s var(--n-bezier),
67
$additional-transition: ""
78
) {
89
background: $from;
910
backdrop-filter: blur($blur);
1011
transition: all $transition;
1112
will-change: color, background, background-color, backdrop-filter, box-shadow,
12-
border-color, scale, opacity;
13+
border-color, scale, opacity, backdrop-filter;
1314

1415
&:hover {
1516
background: $to;
17+
backdrop-filter: blur($blur-hover);
1618
}
1719
}

0 commit comments

Comments
 (0)