Skip to content

Commit 55fb60b

Browse files
committed
feat(list): adds support to person in lists
1 parent 8e49fd1 commit 55fb60b

File tree

7 files changed

+62
-20
lines changed

7 files changed

+62
-20
lines changed

src/components/common/list/ListItem.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ watch(
9696
if (_item?.poster) return;
9797
if (!_item?.type) return;
9898
99-
const type = _item.type === 'movie' ? 'movie' : 'show';
99+
const type = ['show', 'episode', 'season'].includes(_item.type) ? 'show' : _item.type;
100100
if (!_item?.[type]?.ids?.tmdb) {
101101
console.warn('No tmdb id found', JSON.parse(JSON.stringify(_item?.[_item?.type])));
102102
return;

src/components/common/list/ListItemPanel.vue

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const type = computed(() =>
3838
3939
const title = computed(() => {
4040
const media = item.value;
41+
if (media.person) return media.person.name;
4142
if (media.movie) return media.movie.title;
4243
if (!media.episode) return media.show?.title;
4344
const number = media.episode.number?.toString().padStart(2, '0');

src/components/common/list/ListScroll.model.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export type ListScrollItem = ListScrollSourceItem & {
3232
id: string | number | 'load-more';
3333
index: number;
3434

35-
type?: 'movie' | 'show' | 'season' | 'episode';
35+
type?: 'movie' | 'show' | 'season' | 'episode' | 'person';
3636

3737
poster?: Ref<string | undefined>;
3838

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

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const useListScroll = <D extends string, T extends ListScrollSourceItemWi
2121
else if ('episode' in _item) _item.type = 'episode';
2222
else if ('season' in _item) _item.type = 'season';
2323
else if ('show' in _item) _item.type = 'show';
24+
else if ('person' in _item) _item.type = 'person';
2425

2526
if (!_item || !dateFn) return _item;
2627
const _date = typeof dateFn === 'function' ? dateFn(item) : item[dateFn];

src/i18n/en/common/media.json

+4
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,9 @@
1414
"common__media__type__season": {
1515
"message": "Season",
1616
"description": "Media type for seasons"
17+
},
18+
"common__media__type__person": {
19+
"message": "Person",
20+
"description": "Media type for people"
1721
}
1822
}

src/services/trakt.service.ts

+7
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,13 @@ export class TraktService {
192192
});
193193
return response.json();
194194
},
195+
196+
async person(person_id: string | number) {
197+
const response = await TraktService.tmdbClient.v3.people.images.cached({
198+
person_id,
199+
});
200+
return response.json();
201+
},
195202
};
196203

197204
static async history(query: TraktHistoryGetQuery) {

src/stores/data/image.store.ts

+47-18
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,58 @@ type ImageStore = {
1616
show: Record<string, string>;
1717
season: Record<string, string>;
1818
episode: Record<string, string>;
19+
person: Record<string, string>;
1920
};
2021

2122
type ImageQuery = {
2223
id: number;
2324
season?: number;
2425
episode?: number;
25-
type: 'movie' | 'show' | 'season' | 'episode';
26+
type: keyof ImageStore;
2627
};
2728

28-
type ImagePayload = { posters?: TmdbImage[]; stills?: TmdbImage[] };
29+
type ImagePayload = { posters?: TmdbImage[]; stills?: TmdbImage[]; profiles?: TmdbImage[] };
30+
31+
const EmptyImageStore: ImageStore = {
32+
movie: {},
33+
show: {},
34+
season: {},
35+
episode: {},
36+
person: {},
37+
};
2938

3039
export const useImageStore = defineStore('data.image', () => {
3140
const tmdbConfig = ref<TmdbConfiguration>();
32-
const images = reactive<ImageStore>({
33-
movie: {},
34-
show: {},
35-
season: {},
36-
episode: {},
37-
});
38-
39-
const imageSizes = computed(() => ({
40-
poster: tmdbConfig.value?.images?.poster_sizes,
41-
still: tmdbConfig.value?.images?.still_sizes,
42-
}));
43-
44-
const syncSaveImageStore = debounce((_images = images) => storage.sync.set(`data.image-store`, _images), 1000);
41+
const images = reactive<ImageStore>(EmptyImageStore);
42+
43+
const syncSaveImageStore = debounce(
44+
(_images = images) =>
45+
Promise.all([
46+
storage.sync.set(`data.image-store.movie`, _images.movie),
47+
storage.sync.set(`data.image-store.show`, _images.show),
48+
storage.sync.set(`data.image-store.season`, _images.season),
49+
storage.sync.set(`data.image-store.episode`, _images.episode),
50+
storage.sync.set(`data.image-store.person`, _images.person),
51+
]),
52+
1000,
53+
);
4554

4655
const syncRestoreImageStore = async (seed?: Partial<ImageStore>) => {
47-
const restored = await storage.sync.get<ImageStore>(`data.image-store`);
48-
if (restored) Object.assign(images, { ...seed, ...restored });
56+
const [movie, show, season, episode, person] = await Promise.all([
57+
storage.sync.get<Record<string, string>>(`data.image-store.movie`),
58+
storage.sync.get<Record<string, string>>(`data.image-store.show`),
59+
storage.sync.get<Record<string, string>>(`data.image-store.season`),
60+
storage.sync.get<Record<string, string>>(`data.image-store.episode`),
61+
storage.sync.get<Record<string, string>>(`data.image-store.person`),
62+
]);
63+
if (seed) Object.assign(images, seed);
64+
if (movie) Object.assign(images.movie, movie);
65+
if (show) Object.assign(images.show, show);
66+
if (season) Object.assign(images.season, season);
67+
if (episode) Object.assign(images.episode, episode);
68+
if (person) Object.assign(images.person, person);
69+
70+
console.info('Restored Image Store', images);
4971
};
5072

5173
const initImageStore = async (config?: TmdbConfiguration) => {
@@ -54,6 +76,11 @@ export const useImageStore = defineStore('data.image', () => {
5476
return syncRestoreImageStore();
5577
};
5678

79+
const imageSizes = computed(() => ({
80+
poster: tmdbConfig.value?.images?.poster_sizes,
81+
still: tmdbConfig.value?.images?.still_sizes,
82+
}));
83+
5784
const queue: Record<string, Promise<ImagePayload>> = {};
5885

5986
const queueRequest = async (key: string, request: () => Promise<ImagePayload>) => {
@@ -65,6 +92,8 @@ export const useImageStore = defineStore('data.image', () => {
6592
let payload: ImagePayload;
6693
if (type === 'movie') {
6794
payload = await queueRequest(`${type}-${id}`, () => TraktService.posters.movie(id));
95+
} else if (type === 'person') {
96+
payload = await queueRequest(`${type}-${id}`, () => TraktService.posters.person(id));
6897
} else if (type === 'show') {
6998
payload = await queueRequest(`${type}-${id}`, () => TraktService.posters.show(id));
7099
} else if (type === 'season' && season) {
@@ -73,7 +102,7 @@ export const useImageStore = defineStore('data.image', () => {
73102
payload = await queueRequest(`${type}-${id}-${season}-${episode}`, () => TraktService.posters.episode(id, season, episode));
74103
} else throw new Error('Unsupported type or missing parameters for fetchImageUrl');
75104

76-
const fetchedImages = payload.posters ?? payload.stills;
105+
const fetchedImages = payload.posters ?? payload.stills ?? payload.profiles;
77106
if (!fetchedImages?.length) {
78107
console.warn('No images found for', { id, season, episode, type });
79108
return;

0 commit comments

Comments
 (0)