Skip to content

Commit

Permalink
fix: handle search results with collections (sct#3393)
Browse files Browse the repository at this point in the history
* feat: handle search collection

* Update server/utils/typeHelpers.ts

Co-authored-by: Danshil Kokil Mungur <danshil.mungur@gmail.com>

* fix: modified title card to show collection instead of movies

---------

Co-authored-by: Danshil Kokil Mungur <danshil.mungur@gmail.com>
Co-authored-by: Brandon <cohbrandon@gmail.com>
  • Loading branch information
3 people authored and Mike Kao committed Jan 3, 2024
1 parent 97660cd commit 845e1ce
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 13 deletions.
19 changes: 18 additions & 1 deletion server/api/themoviedb/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ export interface TmdbTvResult extends TmdbMediaResult {
first_air_date: string;
}

export interface TmdbCollectionResult {
id: number;
media_type: 'collection';
title: string;
original_title: string;
adult: boolean;
poster_path?: string;
backdrop_path?: string;
overview: string;
original_language: string;
}

export interface TmdbPersonResult {
id: number;
name: string;
Expand All @@ -45,7 +57,12 @@ interface TmdbPaginatedResponse {
}

export interface TmdbSearchMultiResponse extends TmdbPaginatedResponse {
results: (TmdbMovieResult | TmdbTvResult | TmdbPersonResult)[];
results: (
| TmdbMovieResult
| TmdbTvResult
| TmdbPersonResult
| TmdbCollectionResult
)[];
}

export interface TmdbSearchMovieResponse extends TmdbPaginatedResponse {
Expand Down
40 changes: 37 additions & 3 deletions server/models/Search.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
TmdbCollectionResult,
TmdbMovieDetails,
TmdbMovieResult,
TmdbPersonDetails,
Expand All @@ -9,7 +10,7 @@ import type {
import { MediaType as MainMediaType } from '@server/constants/media';
import type Media from '@server/entity/Media';

export type MediaType = 'tv' | 'movie' | 'person';
export type MediaType = 'tv' | 'movie' | 'person' | 'collection';

interface SearchResult {
id: number;
Expand Down Expand Up @@ -43,6 +44,18 @@ export interface TvResult extends SearchResult {
firstAirDate: string;
}

export interface CollectionResult {
id: number;
mediaType: 'collection';
title: string;
originalTitle: string;
adult: boolean;
posterPath?: string;
backdropPath?: string;
overview: string;
originalLanguage: string;
}

export interface PersonResult {
id: number;
name: string;
Expand All @@ -53,7 +66,7 @@ export interface PersonResult {
knownFor: (MovieResult | TvResult)[];
}

export type Results = MovieResult | TvResult | PersonResult;
export type Results = MovieResult | TvResult | PersonResult | CollectionResult;

export const mapMovieResult = (
movieResult: TmdbMovieResult,
Expand Down Expand Up @@ -99,6 +112,20 @@ export const mapTvResult = (
mediaInfo: media,
});

export const mapCollectionResult = (
collectionResult: TmdbCollectionResult
): CollectionResult => ({
id: collectionResult.id,
mediaType: collectionResult.media_type || 'collection',
adult: collectionResult.adult,
originalLanguage: collectionResult.original_language,
originalTitle: collectionResult.original_title,
title: collectionResult.title,
overview: collectionResult.overview,
backdropPath: collectionResult.backdrop_path,
posterPath: collectionResult.poster_path,
});

export const mapPersonResult = (
personResult: TmdbPersonResult
): PersonResult => ({
Expand All @@ -118,7 +145,12 @@ export const mapPersonResult = (
});

export const mapSearchResults = (
results: (TmdbMovieResult | TmdbTvResult | TmdbPersonResult)[],
results: (
| TmdbMovieResult
| TmdbTvResult
| TmdbPersonResult
| TmdbCollectionResult
)[],
media?: Media[]
): Results[] =>
results.map((result) => {
Expand All @@ -139,6 +171,8 @@ export const mapSearchResults = (
req.tmdbId === result.id && req.mediaType === MainMediaType.TV
)
);
case 'collection':
return mapCollectionResult(result);
default:
return mapPersonResult(result);
}
Expand Down
5 changes: 4 additions & 1 deletion server/routes/discover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import { getSettings } from '@server/lib/settings';
import logger from '@server/logger';
import { mapProductionCompany } from '@server/models/Movie';
import {
mapCollectionResult,
mapMovieResult,
mapPersonResult,
mapTvResult,
} from '@server/models/Search';
import { mapNetwork } from '@server/models/Tv';
import { isMovie, isPerson } from '@server/utils/typeHelpers';
import { isCollection, isMovie, isPerson } from '@server/utils/typeHelpers';
import { Router } from 'express';
import { sortBy } from 'lodash';
import { z } from 'zod';
Expand Down Expand Up @@ -647,6 +648,8 @@ discoverRoutes.get('/trending', async (req, res, next) => {
)
: isPerson(result)
? mapPersonResult(result)
: isCollection(result)
? mapCollectionResult(result)
: mapTvResult(
result,
media.find(
Expand Down
23 changes: 21 additions & 2 deletions server/utils/typeHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
TmdbCollectionResult,
TmdbMovieDetails,
TmdbMovieResult,
TmdbPersonDetails,
Expand All @@ -8,17 +9,35 @@ import type {
} from '@server/api/themoviedb/interfaces';

export const isMovie = (
movie: TmdbMovieResult | TmdbTvResult | TmdbPersonResult
movie:
| TmdbMovieResult
| TmdbTvResult
| TmdbPersonResult
| TmdbCollectionResult
): movie is TmdbMovieResult => {
return (movie as TmdbMovieResult).title !== undefined;
};

export const isPerson = (
person: TmdbMovieResult | TmdbTvResult | TmdbPersonResult
person:
| TmdbMovieResult
| TmdbTvResult
| TmdbPersonResult
| TmdbCollectionResult
): person is TmdbPersonResult => {
return (person as TmdbPersonResult).known_for !== undefined;
};

export const isCollection = (
collection:
| TmdbMovieResult
| TmdbTvResult
| TmdbPersonResult
| TmdbCollectionResult
): collection is TmdbCollectionResult => {
return (collection as TmdbCollectionResult).media_type === 'collection';
};

export const isMovieDetails = (
movie: TmdbMovieDetails | TmdbTvDetails | TmdbPersonDetails
): movie is TmdbMovieDetails => {
Expand Down
15 changes: 14 additions & 1 deletion src/components/Common/ListView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import useVerticalScroll from '@app/hooks/useVerticalScroll';
import globalMessages from '@app/i18n/globalMessages';
import type { WatchlistItem } from '@server/interfaces/api/discoverInterfaces';
import type {
CollectionResult,
MovieResult,
PersonResult,
TvResult,
} from '@server/models/Search';
import { useIntl } from 'react-intl';

type ListViewProps = {
items?: (TvResult | MovieResult | PersonResult)[];
items?: (TvResult | MovieResult | PersonResult | CollectionResult)[];
plexItems?: WatchlistItem[];
isEmpty?: boolean;
isLoading?: boolean;
Expand Down Expand Up @@ -90,6 +91,18 @@ const ListView = ({
/>
);
break;
case 'collection':
titleCard = (
<TitleCard
id={title.id}
image={title.posterPath}
summary={title.overview}
title={title.title}
mediaType={title.mediaType}
canExpand
/>
);
break;
case 'person':
titleCard = (
<PersonCard
Expand Down
28 changes: 23 additions & 5 deletions src/components/TitleCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface TitleCardProps {
summary?: string;
year?: string;
title: string;
userScore: number;
userScore?: number;
mediaType: MediaType;
status?: MediaStatus;
canExpand?: boolean;
Expand Down Expand Up @@ -73,7 +73,9 @@ const TitleCard = ({
const showRequestButton = hasPermission(
[
Permission.REQUEST,
mediaType === 'movie' ? Permission.REQUEST_MOVIE : Permission.REQUEST_TV,
mediaType === 'movie' || mediaType === 'collection'
? Permission.REQUEST_MOVIE
: Permission.REQUEST_TV,
],
{ type: 'or' }
);
Expand All @@ -86,7 +88,13 @@ const TitleCard = ({
<RequestModal
tmdbId={id}
show={showRequestModal}
type={mediaType === 'movie' ? 'movie' : 'tv'}
type={
mediaType === 'movie'
? 'movie'
: mediaType === 'collection'
? 'collection'
: 'tv'
}
onComplete={requestComplete}
onUpdating={requestUpdating}
onCancel={closeModal}
Expand Down Expand Up @@ -130,14 +138,16 @@ const TitleCard = ({
<div className="absolute left-0 right-0 flex items-center justify-between p-2">
<div
className={`pointer-events-none z-40 rounded-full border bg-opacity-80 shadow-md ${
mediaType === 'movie'
mediaType === 'movie' || mediaType === 'collection'
? 'border-blue-500 bg-blue-600'
: 'border-purple-600 bg-purple-600'
}`}
>
<div className="flex h-4 items-center px-2 py-2 text-center text-xs font-medium uppercase tracking-wider text-white sm:h-5">
{mediaType === 'movie'
? intl.formatMessage(globalMessages.movie)
: mediaType === 'collection'
? intl.formatMessage(globalMessages.collection)
: intl.formatMessage(globalMessages.tvshow)}
</div>
</div>
Expand Down Expand Up @@ -177,7 +187,15 @@ const TitleCard = ({
leaveTo="opacity-0"
>
<div className="absolute inset-0 overflow-hidden rounded-xl">
<Link href={mediaType === 'movie' ? `/movie/${id}` : `/tv/${id}`}>
<Link
href={
mediaType === 'movie'
? `/movie/${id}`
: mediaType === 'collection'
? `/collection/${id}`
: `/tv/${id}`
}
>
<a
className="absolute inset-0 h-full w-full cursor-pointer overflow-hidden text-left"
style={{
Expand Down
1 change: 1 addition & 0 deletions src/i18n/globalMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const globalMessages = defineMessages({
approved: 'Approved',
movie: 'Movie',
movies: 'Movies',
collection: 'Collection',
tvshow: 'Series',
tvshows: 'Series',
cancel: 'Cancel',
Expand Down

0 comments on commit 845e1ce

Please sign in to comment.