Skip to content

Commit 02fe02b

Browse files
seferturanvladjerca
authored andcommitted
feat(summary): displays episode counts for cast
Fixes #2125
1 parent 51d8d67 commit 02fe02b

7 files changed

Lines changed: 105 additions & 15 deletions

File tree

projects/client/src/lib/requests/_internal/mapToMediaCredits.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
PeopleShowCreditsResponse,
1212
ShowResponse,
1313
} from '@trakt/api';
14+
import type { MediaEntry } from '../models/MediaEntry.ts';
1415

1516
type MediaCreditsResponse =
1617
| PeopleMovieCreditsResponse
@@ -49,6 +50,19 @@ function mapToMediaEntry(entryResponse: EntryResponse) {
4950
type CrewResponse = NonNullable<MediaCreditsResponse['crew']>;
5051
type CrewEntry = CrewResponse[string][number];
5152

53+
type CastResponse = NonNullable<MediaCreditsResponse['cast']>;
54+
type CastEntry = CastResponse[number];
55+
56+
function toCredit(media: MediaEntry, entry: CrewEntry | CastEntry) {
57+
return {
58+
media,
59+
key: media.key,
60+
...('episode_count' in entry && entry.episode_count != null
61+
? { episodeCount: entry.episode_count }
62+
: {}),
63+
};
64+
}
65+
5266
export function mapToMediaCredits(
5367
response: MediaCreditsResponse,
5468
): MediaCredits {
@@ -66,10 +80,9 @@ export function mapToMediaCredits(
6680
const media = mapToMediaEntry(entry);
6781

6882
entries?.push({
69-
media,
83+
...toCredit(media, entry),
7084
type: 'cast',
7185
character: entry.character,
72-
key: media.key,
7386
});
7487
});
7588

@@ -78,10 +91,9 @@ export function mapToMediaCredits(
7891
const mediaEntries = entries.map((entry: CrewEntry) => {
7992
const media = mapToMediaEntry(entry);
8093
return {
81-
media,
94+
...toCredit(media, entry),
8295
type: 'crew',
8396
job: entry.job,
84-
key: media.key,
8597
};
8698
});
8799

projects/client/src/lib/requests/_internal/mapToMediaCrew.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,29 @@ export const EMPTY_CREW: Readonly<MediaCrew> = {
1313
cast: [],
1414
};
1515

16+
function toMember(response: CrewResponse | CastResponse) {
17+
return ({
18+
name: response.person.name,
19+
key: response.person.ids.slug,
20+
...(response.episode_count != null ? { episodeCount: response.episode_count } : {}),
21+
});
22+
}
23+
1624
function toCrewMember(
1725
crewResponse: CrewResponse,
1826
): CrewMember {
1927
return ({
28+
...toMember(crewResponse),
2029
jobs: crewResponse.jobs,
21-
name: crewResponse.person.name,
22-
key: crewResponse.person.ids.slug,
2330
});
2431
}
2532

2633
function toCastMember(
2734
castResponse: CastResponse,
2835
): CastMember {
2936
return ({
30-
name: castResponse.person.name,
37+
...toMember(castResponse),
3138
characterName: castResponse.characters.at(0) ?? '',
32-
key: castResponse.person.ids.slug,
3339
headshot: mapToHeadshot(castResponse.person.images),
3440
});
3541
}

projects/client/src/lib/requests/models/MediaCredits.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { crewPositionSchema } from './CrewPosition.ts';
55
const BaseCreditSchema = z.object({
66
media: MediaEntrySchema,
77
key: z.string(),
8+
episodeCount: z.number().optional(),
89
});
910

1011
const CharacterSchema = BaseCreditSchema.extend({

projects/client/src/lib/requests/models/MediaCrew.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ import { ImageUrlsSchema } from './ImageUrlsSchema.ts';
33

44
export type Job = string;
55

6-
export const CrewMemberSchema = z.object({
7-
jobs: z.array(z.string()),
6+
const baseSchema = z.object({
87
name: z.string(),
98
key: z.string(),
9+
episodeCount: z.number().optional(),
10+
});
11+
12+
export const CrewMemberSchema = baseSchema.extend({
13+
jobs: z.array(z.string()),
1014
});
1115
export type CrewMember = z.infer<typeof CrewMemberSchema>;
1216

13-
export const CastMemberSchema = z.object({
14-
name: z.string(),
17+
export const CastMemberSchema = baseSchema.extend({
1518
characterName: z.string(),
16-
key: z.string(),
1719
headshot: z.object({
1820
url: ImageUrlsSchema,
1921
}),

projects/client/src/lib/sections/lists/components/CastMemberItem.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import CardCover from "$lib/components/card/CardCover.svelte";
33
import CardFooter from "$lib/components/card/CardFooter.svelte";
44
import Link from "$lib/components/link/Link.svelte";
5+
import EpisodeCountTag from "$lib/components/media/tags/EpisodeCountTag.svelte";
6+
import { TagIntlProvider } from "$lib/components/media/tags/TagIntlProvider";
57
import PersonCard from "$lib/components/people/card/PersonCard.svelte";
68
import * as m from "$lib/features/i18n/messages";
79
import type { CastMember } from "$lib/requests/models/MediaCrew";
@@ -20,12 +22,23 @@
2022
});
2123
</script>
2224

25+
{#snippet tag()}
26+
{#if type === "show" && castMember.episodeCount}
27+
<EpisodeCountTag
28+
count={castMember.episodeCount}
29+
i18n={TagIntlProvider}
30+
type="tag"
31+
/>
32+
{/if}
33+
{/snippet}
34+
2335
<PersonCard>
2436
<Link focusable={false} href={UrlBuilder.people(castMember.key, params)}>
2537
<CardCover
2638
title={castMember.name}
2739
src={castMember.headshot.url.thumb}
2840
alt={`${m.image_alt_person_headshot({ person: castMember.name })}`}
41+
{tag}
2942
/>
3043
</Link>
3144
<CardFooter>

projects/client/src/lib/sections/lists/components/CreditMediaItem.svelte

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
<script lang="ts">
2+
import AirDateTag from "$lib/components/media/tags/AirDateTag.svelte";
3+
import DurationTag from "$lib/components/media/tags/DurationTag.svelte";
4+
import EpisodeCountTag from "$lib/components/media/tags/EpisodeCountTag.svelte";
5+
import { TagIntlProvider } from "$lib/components/media/tags/TagIntlProvider";
26
import * as m from "$lib/features/i18n/messages";
37
import type { MediaCredit } from "$lib/requests/models/MediaCredits";
48
import { toTranslatedJob } from "$lib/utils/formatting/string/toTranslatedJob";
@@ -23,14 +27,31 @@
2327
2428
return toTranslatedJob(job);
2529
};
30+
31+
const media = $derived(mediaCredit.media);
2632
</script>
2733

34+
{#snippet tag()}
35+
<AirDateTag i18n={TagIntlProvider} airDate={media.airDate} />
36+
37+
{#if media.type === "show" && mediaCredit.episodeCount}
38+
<EpisodeCountTag i18n={TagIntlProvider} count={mediaCredit.episodeCount} />
39+
{/if}
40+
41+
{#if media.type === "movie"}
42+
{#if media.airDate < new Date()}
43+
<DurationTag i18n={TagIntlProvider} runtime={media.runtime} />
44+
{/if}
45+
{/if}
46+
{/snippet}
47+
2848
<DefaultMediaItem
29-
type={mediaCredit.media.type}
30-
media={mediaCredit.media}
49+
type={media.type}
50+
{media}
3151
{source}
3252
variant="credit"
3353
{mode}
54+
{tag}
3455
role={mediaCredit.type === "cast"
3556
? toCharacter(mediaCredit.character)
3657
: toJob(mediaCredit.job)}

0 commit comments

Comments
 (0)