Skip to content

Commit e08aea3

Browse files
committed
feat(tags): rework tags and episode display
1 parent deca6c5 commit e08aea3

File tree

6 files changed

+74
-49
lines changed

6 files changed

+74
-49
lines changed

src/components/common/list/ListItemPanel.vue

+7-5
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,6 @@ const tags = computed(
7979
<NEllipsis v-else :line-clamp="2">{{ content }}</NEllipsis>
8080
</div>
8181
<NFlex v-if="date || tags?.length" size="medium" class="tags">
82-
<template v-if="date">
83-
<NSkeleton v-if="loading" text style="width: 6%" />
84-
<NTag v-else class="tag meta" size="small"> {{ date }} </NTag>
85-
</template>
8682
<template v-for="tag of tags" :key="tag.label">
8783
<NSkeleton v-if="loading" text style="width: 6%" />
8884
<NTag
@@ -91,11 +87,17 @@ const tags = computed(
9187
:class="{ meta: tag.meta }"
9288
size="small"
9389
:type="tag.type"
94-
:bordered="tag.bordered ?? true"
90+
:bordered="tag.bordered ?? false"
9591
>
9692
{{ tag.label }}
9793
</NTag>
9894
</template>
95+
<template v-if="date">
96+
<NSkeleton v-if="loading" text style="width: 6%" />
97+
<NTag v-else class="tag" size="small" type="default" :bordered="false">
98+
{{ date }}
99+
</NTag>
100+
</template>
99101
</NFlex>
100102
</NFlex>
101103
</template>

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

+37-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { TraktClientPagination } from '~/models/trakt/trakt-client.model';
77
import type { ImageQuery } from '~/stores/data/image.store';
88

99
import { type ListScrollItem, ListScrollItemType, type ListScrollSourceItem, type OnScroll, type OnUpdated } from '~/models/list-scroll.model';
10+
import { useI18n } from '~/utils';
1011

1112
export type ListScrollSourceItemWithDate<T extends string> = ListScrollSourceItem & Partial<Record<T, string | number | Date>>;
1213

@@ -15,8 +16,7 @@ export const getTitle = (media: Pick<ListScrollSourceItem, 'person' | 'movie' |
1516
if (media.person) return media.person.name;
1617
if (media.movie) return media.movie.title;
1718
if (!media.episode) return media.show?.title;
18-
const number = media.episode.number?.toString().padStart(2, '0');
19-
return `${media.episode.season}x${number} - ${media.episode.title}`;
19+
return media.episode.title;
2020
};
2121

2222
export const getContent = (media: Pick<ListScrollSourceItem, 'movie' | 'episode' | 'show'>): ListScrollItem['content'] => {
@@ -79,6 +79,38 @@ export const getPosterQuery =
7979
} satisfies ImageQuery;
8080
};
8181

82+
const i18n = useI18n('common', 'tag');
83+
export const getTags = (item: Pick<ListScrollSourceItem, 'episode' | 'season'>, type: ListScrollItem['type']): ListScrollItem['tags'] => {
84+
const tags: ListScrollItem['tags'] = [];
85+
if (type === 'episode' && item.episode) {
86+
let premiere: 'season' | 'series' | 'mid_season' | null = null;
87+
// let finale: 'season' | 'series' | 'mid_season';
88+
if (item.episode.season === 1 && item.episode.number === 1) premiere = 'series';
89+
else if (item.episode.number === 1) premiere = 'season';
90+
91+
if (premiere) {
92+
tags.push({
93+
label: premiere,
94+
i18n: ['calendar', 'tag', 'label', 'premiere'],
95+
type: premiere === 'season' ? 'info' : 'primary',
96+
});
97+
}
98+
tags.push({
99+
label: `${i18n('season')} ${item.episode.season.toString().padStart(2, '0')} ${i18n('episode')} ${item.episode.number
100+
.toString()
101+
.padStart(2, '0')}`,
102+
type: 'warning',
103+
});
104+
} else if (type === 'season' && item.season) {
105+
tags.push({
106+
label: `Season ${item.season.number.toString().padStart(2, '0')}`,
107+
type: 'warning',
108+
});
109+
}
110+
111+
return tags;
112+
};
113+
82114
export const useListScroll = <T extends ListScrollSourceItemWithDate<D>, D extends string | never = never>(
83115
items: Ref<T[]>,
84116
dateFn?: D | ((item: T) => T[D]),
@@ -94,8 +126,11 @@ export const useListScroll = <T extends ListScrollSourceItemWithDate<D>, D exten
94126
if (!_item.content) _item.content = getContent(item);
95127
if (!_item.posterRef) _item.posterRef = ref<string | undefined>(undefined);
96128
if (!_item.getPosterQuery) _item.getPosterQuery = getPosterQuery(item, _item.type);
129+
if (!_item.tags) _item.tags = getTags(item, _item.type);
130+
97131
_item.date = getDate(item, array, index, dateFn);
98132
_item.meta = {
133+
source: item,
99134
ids: {
100135
movie: item.movie?.ids,
101136
show: item.show?.ids,

src/i18n/en/common/tag.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"common__tag__season": {
3+
"message": "Season",
4+
"description": "The label for the season tag"
5+
},
6+
"common__tag__episode": {
7+
"message": "Episode",
8+
"description": "The label for the episode tag"
9+
}
10+
}

src/models/list-scroll.model.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ export const ListScrollItemType = {
5454
placeholder: 'placeholder',
5555
} as const;
5656

57-
export type ListScrollItem = {
57+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- meta is intentionally weakly typed
58+
export type ListScrollItem<T = Record<string, any>> = {
5859
id: string | number;
5960
index: number;
6061

@@ -63,11 +64,11 @@ export type ListScrollItem = {
6364
content?: string;
6465
tags?: ListScrollItemTag[];
6566

66-
poster?: ImageStoreMedias;
67+
poster?: string;
6768
posterRef?: Ref<ImageStoreMedias | undefined>;
6869
getPosterQuery?: () => ImageQuery | undefined;
6970

70-
meta?: Record<string, unknown>;
71+
meta?: T;
7172

7273
loading?: boolean;
7374
date?: {

src/models/progress.model.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { ListScrollItem, ListScrollSourceItem } from '~/models/list-scroll.
22
import type { TraktEpisode } from '~/models/trakt/trakt-episode.model';
33
import type { TraktShow } from '~/models/trakt/trakt-show.model';
44

5-
import { getContent, getTitle } from '~/components/common/list/use-list-scroll';
5+
import { getContent, getTags, getTitle } from '~/components/common/list/use-list-scroll';
66

77
export type ProgressItem = {
88
episodeId: string;
@@ -55,15 +55,16 @@ export const progressToListItem = (progress: ProgressItem): Omit<ListScrollItem,
5555
current: new Date(progress.firstAired),
5656
},
5757
type: progress.type,
58+
tags: getTags({ episode }, progress.type),
5859
meta: {
60+
source: progress,
61+
episode,
62+
show,
5963
ids: {
6064
show: progress.showId ? Number(progress.showId) : undefined,
6165
season: progress.seasonId ? Number(progress.seasonId) : undefined,
6266
episode: progress.episodeId ? Number(progress.episodeId) : undefined,
6367
},
64-
show,
65-
episode,
66-
source: progress,
6768
},
6869
};
6970
};

src/stores/data/calendar.store.ts

+11-35
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ import { useSearchFilter } from '~/utils/store.utils';
1313
export type CalendarItem = (TraktCalendarShow | TraktCalendarMovie | Record<never, never>) & {
1414
id: ListScrollItem['id'];
1515
type?: ListScrollItem['type'];
16-
premiere?: 'season' | 'series' | 'mid_season';
17-
finale?: 'season' | 'series' | 'mid_season';
18-
day: 1 | 2 | 3 | 4 | 5 | 6 | 7;
1916
date: Date;
2017
tags?: ListScrollItemTag[];
2118
};
@@ -25,7 +22,7 @@ export const CalendarPlaceholder: Partial<CalendarItem> = {
2522
type: ListScrollItemType.placeholder,
2623
} as const;
2724

28-
const getPlaceholder = (date: Date) => ({ ...CalendarPlaceholder, id: `empty-${date.getTime()}`, date, day: date.getDay() }) as CalendarItem;
25+
const getPlaceholder = (date: Date) => ({ ...CalendarPlaceholder, id: `empty-${date.getTime()}`, date }) as CalendarItem;
2926
const getLoadingPlaceholder = (date: Date) =>
3027
({ ...getPlaceholder(date), id: `loading-${date.getTime()}`, type: ListScrollItemType.loading }) as CalendarItem;
3128

@@ -162,37 +159,16 @@ export const useCalendarStore = defineStore('data.calendar', () => {
162159
TraktService.calendar({ start_date, days: days.value }, 'movies'),
163160
]);
164161
const newData: CalendarItem[] = [
165-
...(shows as TraktCalendarShow[]).map(show => {
166-
const date = new Date(show.first_aired);
167-
let premiere: CalendarItem['premiere'] | undefined;
168-
if (show.episode.season === 1 && show.episode.number === 1) premiere = 'series';
169-
else if (show.episode.number === 1) premiere = 'season';
170-
return {
171-
...show,
172-
id: show.episode.ids.trakt ?? show.show.ids.trakt,
173-
date,
174-
day: date.getDay(),
175-
premiere,
176-
tags: premiere
177-
? [
178-
{
179-
label: premiere,
180-
i18n: ['calendar', 'tag', 'label', 'premiere'],
181-
type: premiere === 'season' ? 'info' : 'primary',
182-
},
183-
]
184-
: undefined,
185-
} as CalendarItem;
186-
}),
187-
...(movies as TraktCalendarMovie[]).map(movie => {
188-
const date = new Date(movie.released);
189-
return {
190-
...movie,
191-
id: movie.movie.ids.trakt,
192-
date,
193-
day: date.getDay() as CalendarItem['day'],
194-
};
195-
}),
162+
...(shows as TraktCalendarShow[]).map(show => ({
163+
...show,
164+
id: show.episode.ids.trakt ?? show.show.ids.trakt,
165+
date: new Date(show.first_aired),
166+
})),
167+
...(movies as TraktCalendarMovie[]).map(movie => ({
168+
...movie,
169+
id: movie.movie.ids.trakt,
170+
date: new Date(movie.released),
171+
})),
196172
].sort((a, b) => a.date.getTime() - b.date.getTime());
197173

198174
const spacedData = spaceDate(newData, startDate, endDate);

0 commit comments

Comments
 (0)