feat(discover): add 'Popular People' slider

pull/2166/head
TheCatLady 3 years ago
parent 33fe0bdd1e
commit 05e14da472
No known key found for this signature in database
GPG Key ID: 9DAC5971F01EE4AE

@ -3584,6 +3584,12 @@ paths:
tags:
- search
parameters:
- in: query
name: sortBy
schema:
type: string
enum: [popularity.asc, popularity.desc, release_date.asc, release_date.desc, revenue.asc, revenue.desc, primary_release_date.asc, primary_release_date.desc, original_title.asc, original_title.desc, vote_average.asc, vote_average.desc, vote_count.asc, vote_count.desc]
default: popularity.desc
- in: query
name: page
schema:
@ -3813,6 +3819,12 @@ paths:
tags:
- search
parameters:
- in: query
name: sortBy
schema:
type: string
enum: [popularity.asc, popularity.desc, vote_average.asc, vote_average.desc, vote_count.asc, vote_count.desc, first_air_date.asc, first_air_date.desc]
default: popularity.desc
- in: query
name: page
schema:
@ -4186,6 +4198,45 @@ paths:
name:
type: string
example: Genre Name
/discover/people:
get:
summary: Discover people
description: Returns a list of people in a JSON object.
tags:
- search
parameters:
- in: query
name: page
schema:
type: number
example: 1
default: 1
- in: query
name: language
schema:
type: string
example: en
responses:
'200':
description: Results
content:
application/json:
schema:
type: object
properties:
page:
type: number
example: 1
totalPages:
type: number
example: 20
totalResults:
type: number
example: 200
results:
type: array
items:
$ref: '#/components/schemas/PersonResult'
/request:
get:
summary: Get all requests

@ -15,6 +15,7 @@ import {
TmdbRegion,
TmdbSearchMovieResponse,
TmdbSearchMultiResponse,
TmdbSearchPeopleResponse,
TmdbSearchTvResponse,
TmdbSeasonWithEpisodes,
TmdbTvDetails,
@ -801,6 +802,27 @@ class TheMovieDb extends ExternalAPI {
throw new Error(`[TMDb] Failed to fetch TV genres: ${e.message}`);
}
}
public async getDiscoverPeople({
page = 1,
language = 'en',
}: {
page?: number;
language?: string;
}): Promise<TmdbSearchPeopleResponse> {
try {
const data = await this.get<TmdbSearchPeopleResponse>('/person/popular', {
params: {
page,
language,
},
});
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch popular people: ${e.message}`);
}
}
}
export default TheMovieDb;

@ -56,6 +56,10 @@ export interface TmdbSearchTvResponse extends TmdbPaginatedResponse {
results: TmdbTvResult[];
}
export interface TmdbSearchPeopleResponse extends TmdbPaginatedResponse {
results: TmdbPersonResult[];
}
export interface TmdbUpcomingMoviesResponse extends TmdbPaginatedResponse {
dates: {
maximum: string;

@ -103,7 +103,7 @@ export const mapPersonResult = (
name: personResult.name,
popularity: personResult.popularity,
adult: personResult.adult,
mediaType: personResult.media_type,
mediaType: personResult.media_type || 'person',
profilePath: personResult.profile_path,
knownFor: personResult.known_for.map((result) => {
if (result.media_type === 'movie') {

@ -567,4 +567,22 @@ discoverRoutes.get<{ language: string }, GenreSliderItem[]>(
}
);
discoverRoutes.get('/people', async (req, res) => {
const tmdb = new TheMovieDb();
const data = await tmdb.getDiscoverPeople({
page: Number(req.query.page),
language: req.locale ?? (req.query.language as string),
});
return res.status(200).json({
page: data.page,
totalPages: data.total_pages,
totalResults: data.total_results,
results: data.results
.map((result) => mapPersonResult(result))
.filter((item) => !item.adult),
});
});
export default discoverRoutes;

@ -0,0 +1,49 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import type { PersonResult } from '../../../server/models/Search';
import useDiscover from '../../hooks/useDiscover';
import Error from '../../pages/_error';
import Header from '../Common/Header';
import ListView from '../Common/ListView';
import PageTitle from '../Common/PageTitle';
const messages = defineMessages({
popularpeople: 'Popular People',
});
const DiscoverPeople: React.FC = () => {
const intl = useIntl();
const {
isLoadingInitialData,
isEmpty,
isLoadingMore,
isReachingEnd,
titles,
fetchMore,
error,
} = useDiscover<PersonResult>('/api/v1/discover/people');
if (error) {
return <Error statusCode={500} />;
}
return (
<>
<PageTitle title={intl.formatMessage(messages.popularpeople)} />
<div className="mt-1 mb-5">
<Header>{intl.formatMessage(messages.popularpeople)}</Header>
</div>
<ListView
items={titles}
isEmpty={isEmpty}
isLoading={
isLoadingInitialData || (isLoadingMore && (titles?.length ?? 0) > 0)
}
isReachingEnd={isReachingEnd}
onScrollBottom={fetchMore}
/>
</>
);
};
export default DiscoverPeople;

@ -25,6 +25,7 @@ const messages = defineMessages({
noRequests: 'No requests.',
upcoming: 'Upcoming Movies',
trending: 'Trending',
popularpeople: 'Popular People',
});
const Discover: React.FC = () => {
@ -116,6 +117,12 @@ const Discover: React.FC = () => {
linkUrl="/discover/tv/upcoming"
/>
<NetworkSlider />
<MediaSlider
sliderKey="popular-people"
title={intl.formatMessage(messages.popularpeople)}
url="/api/v1/discover/people"
linkUrl="/discover/people"
/>
</>
);
};

@ -24,6 +24,7 @@
"components.Discover.discovertv": "Popular Series",
"components.Discover.noRequests": "No requests.",
"components.Discover.popularmovies": "Popular Movies",
"components.Discover.popularpeople": "Popular People",
"components.Discover.populartv": "Popular Series",
"components.Discover.recentlyAdded": "Recently Added",
"components.Discover.recentrequests": "Recent Requests",

@ -0,0 +1,9 @@
import { NextPage } from 'next';
import React from 'react';
import DiscoverPeople from '../../../components/Discover/DiscoverPeople';
const DiscoverPeoplePage: NextPage = () => {
return <DiscoverPeople />;
};
export default DiscoverPeoplePage;
Loading…
Cancel
Save