feat(discover): support filtering by tmdb user vote count on discover page (#3407)

pull/3455/head
Shane Friedman 2 years ago committed by GitHub
parent e051b1dfea
commit aa84977680
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4186,6 +4186,16 @@ paths:
schema: schema:
type: number type: number
example: 10 example: 10
- in: query
name: voteCountGte
schema:
type: number
example: 7
- in: query
name: voteCountLte
schema:
type: number
example: 10
- in: query - in: query
name: watchRegion name: watchRegion
schema: schema:
@ -4465,6 +4475,16 @@ paths:
schema: schema:
type: number type: number
example: 10 example: 10
- in: query
name: voteCountGte
schema:
type: number
example: 7
- in: query
name: voteCountLte
schema:
type: number
example: 10
- in: query - in: query
name: watchRegion name: watchRegion
schema: schema:

@ -65,6 +65,8 @@ interface DiscoverMovieOptions {
withRuntimeLte?: string; withRuntimeLte?: string;
voteAverageGte?: string; voteAverageGte?: string;
voteAverageLte?: string; voteAverageLte?: string;
voteCountGte?: string;
voteCountLte?: string;
originalLanguage?: string; originalLanguage?: string;
genre?: string; genre?: string;
studio?: string; studio?: string;
@ -83,6 +85,8 @@ interface DiscoverTvOptions {
withRuntimeLte?: string; withRuntimeLte?: string;
voteAverageGte?: string; voteAverageGte?: string;
voteAverageLte?: string; voteAverageLte?: string;
voteCountGte?: string;
voteCountLte?: string;
includeEmptyReleaseDate?: boolean; includeEmptyReleaseDate?: boolean;
originalLanguage?: string; originalLanguage?: string;
genre?: string; genre?: string;
@ -460,6 +464,8 @@ class TheMovieDb extends ExternalAPI {
withRuntimeLte, withRuntimeLte,
voteAverageGte, voteAverageGte,
voteAverageLte, voteAverageLte,
voteCountGte,
voteCountLte,
watchProviders, watchProviders,
watchRegion, watchRegion,
}: DiscoverMovieOptions = {}): Promise<TmdbSearchMovieResponse> => { }: DiscoverMovieOptions = {}): Promise<TmdbSearchMovieResponse> => {
@ -504,6 +510,8 @@ class TheMovieDb extends ExternalAPI {
'with_runtime.lte': withRuntimeLte, 'with_runtime.lte': withRuntimeLte,
'vote_average.gte': voteAverageGte, 'vote_average.gte': voteAverageGte,
'vote_average.lte': voteAverageLte, 'vote_average.lte': voteAverageLte,
'vote_count.gte': voteCountGte,
'vote_count.lte': voteCountLte,
watch_region: watchRegion, watch_region: watchRegion,
with_watch_providers: watchProviders, with_watch_providers: watchProviders,
}, },
@ -530,6 +538,8 @@ class TheMovieDb extends ExternalAPI {
withRuntimeLte, withRuntimeLte,
voteAverageGte, voteAverageGte,
voteAverageLte, voteAverageLte,
voteCountGte,
voteCountLte,
watchProviders, watchProviders,
watchRegion, watchRegion,
}: DiscoverTvOptions = {}): Promise<TmdbSearchTvResponse> => { }: DiscoverTvOptions = {}): Promise<TmdbSearchTvResponse> => {
@ -574,6 +584,8 @@ class TheMovieDb extends ExternalAPI {
'with_runtime.lte': withRuntimeLte, 'with_runtime.lte': withRuntimeLte,
'vote_average.gte': voteAverageGte, 'vote_average.gte': voteAverageGte,
'vote_average.lte': voteAverageLte, 'vote_average.lte': voteAverageLte,
'vote_count.gte': voteCountGte,
'vote_count.lte': voteCountLte,
with_watch_providers: watchProviders, with_watch_providers: watchProviders,
watch_region: watchRegion, watch_region: watchRegion,
}, },

@ -65,6 +65,8 @@ const QueryFilterOptions = z.object({
withRuntimeLte: z.coerce.string().optional(), withRuntimeLte: z.coerce.string().optional(),
voteAverageGte: z.coerce.string().optional(), voteAverageGte: z.coerce.string().optional(),
voteAverageLte: z.coerce.string().optional(), voteAverageLte: z.coerce.string().optional(),
voteCountGte: z.coerce.string().optional(),
voteCountLte: z.coerce.string().optional(),
network: z.coerce.string().optional(), network: z.coerce.string().optional(),
watchProviders: z.coerce.string().optional(), watchProviders: z.coerce.string().optional(),
watchRegion: z.coerce.string().optional(), watchRegion: z.coerce.string().optional(),
@ -96,6 +98,8 @@ discoverRoutes.get('/movies', async (req, res, next) => {
withRuntimeLte: query.withRuntimeLte, withRuntimeLte: query.withRuntimeLte,
voteAverageGte: query.voteAverageGte, voteAverageGte: query.voteAverageGte,
voteAverageLte: query.voteAverageLte, voteAverageLte: query.voteAverageLte,
voteCountGte: query.voteCountGte,
voteCountLte: query.voteCountLte,
watchProviders: query.watchProviders, watchProviders: query.watchProviders,
watchRegion: query.watchRegion, watchRegion: query.watchRegion,
}); });
@ -371,6 +375,8 @@ discoverRoutes.get('/tv', async (req, res, next) => {
withRuntimeLte: query.withRuntimeLte, withRuntimeLte: query.withRuntimeLte,
voteAverageGte: query.voteAverageGte, voteAverageGte: query.voteAverageGte,
voteAverageLte: query.voteAverageLte, voteAverageLte: query.voteAverageLte,
voteCountGte: query.voteCountGte,
voteCountLte: query.voteCountLte,
watchProviders: query.watchProviders, watchProviders: query.watchProviders,
watchRegion: query.watchRegion, watchRegion: query.watchRegion,
}); });

@ -35,8 +35,10 @@ const messages = defineMessages({
ratingText: 'Ratings between {minValue} and {maxValue}', ratingText: 'Ratings between {minValue} and {maxValue}',
clearfilters: 'Clear Active Filters', clearfilters: 'Clear Active Filters',
tmdbuserscore: 'TMDB User Score', tmdbuserscore: 'TMDB User Score',
tmdbuservotecount: 'TMDB User Vote Count',
runtime: 'Runtime', runtime: 'Runtime',
streamingservices: 'Streaming Services', streamingservices: 'Streaming Services',
voteCount: 'Number of votes between {minValue} and {maxValue}',
}); });
type FilterSlideoverProps = { type FilterSlideoverProps = {
@ -246,6 +248,45 @@ const FilterSlideover = ({
})} })}
/> />
</div> </div>
<span className="text-lg font-semibold">
{intl.formatMessage(messages.tmdbuservotecount)}
</span>
<div className="relative z-0">
<MultiRangeSlider
min={0}
max={1000}
defaultMaxValue={
currentFilters.voteCountLte
? Number(currentFilters.voteCountLte)
: undefined
}
defaultMinValue={
currentFilters.voteCountGte
? Number(currentFilters.voteCountGte)
: undefined
}
onUpdateMin={(min) => {
updateQueryParams(
'voteCountGte',
min !== 0 && Number(currentFilters.voteCountLte) !== 1000
? min.toString()
: undefined
);
}}
onUpdateMax={(max) => {
updateQueryParams(
'voteCountLte',
max !== 1000 && Number(currentFilters.voteCountGte) !== 0
? max.toString()
: undefined
);
}}
subText={intl.formatMessage(messages.voteCount, {
minValue: currentFilters.voteCountGte ?? 0,
maxValue: currentFilters.voteCountLte ?? 1000,
})}
/>
</div>
<span className="text-lg font-semibold"> <span className="text-lg font-semibold">
{intl.formatMessage(messages.streamingservices)} {intl.formatMessage(messages.streamingservices)}
</span> </span>

@ -104,6 +104,8 @@ export const QueryFilterOptions = z.object({
withRuntimeLte: z.string().optional(), withRuntimeLte: z.string().optional(),
voteAverageGte: z.string().optional(), voteAverageGte: z.string().optional(),
voteAverageLte: z.string().optional(), voteAverageLte: z.string().optional(),
voteCountLte: z.string().optional(),
voteCountGte: z.string().optional(),
watchRegion: z.string().optional(), watchRegion: z.string().optional(),
watchProviders: z.string().optional(), watchProviders: z.string().optional(),
}); });
@ -169,6 +171,14 @@ export const prepareFilterValues = (
filterValues.voteAverageLte = values.voteAverageLte; filterValues.voteAverageLte = values.voteAverageLte;
} }
if (values.voteCountGte) {
filterValues.voteCountGte = values.voteCountGte;
}
if (values.voteCountLte) {
filterValues.voteCountLte = values.voteCountLte;
}
if (values.watchProviders) { if (values.watchProviders) {
filterValues.watchProviders = values.watchProviders; filterValues.watchProviders = values.watchProviders;
} }
@ -190,6 +200,12 @@ export const countActiveFilters = (filterValues: FilterOptions): number => {
delete clonedFilters.voteAverageLte; delete clonedFilters.voteAverageLte;
} }
if (clonedFilters.voteCountGte || filterValues.voteCountLte) {
totalCount += 1;
delete clonedFilters.voteCountGte;
delete clonedFilters.voteCountLte;
}
if (clonedFilters.withRuntimeGte || filterValues.withRuntimeLte) { if (clonedFilters.withRuntimeGte || filterValues.withRuntimeLte) {
totalCount += 1; totalCount += 1;
delete clonedFilters.withRuntimeGte; delete clonedFilters.withRuntimeGte;

@ -76,7 +76,9 @@
"components.Discover.FilterSlideover.streamingservices": "Streaming Services", "components.Discover.FilterSlideover.streamingservices": "Streaming Services",
"components.Discover.FilterSlideover.studio": "Studio", "components.Discover.FilterSlideover.studio": "Studio",
"components.Discover.FilterSlideover.tmdbuserscore": "TMDB User Score", "components.Discover.FilterSlideover.tmdbuserscore": "TMDB User Score",
"components.Discover.FilterSlideover.tmdbuservotecount": "TMDB User Vote Count",
"components.Discover.FilterSlideover.to": "To", "components.Discover.FilterSlideover.to": "To",
"components.Discover.FilterSlideover.voteCount": "Number of votes between {minValue} and {maxValue}",
"components.Discover.MovieGenreList.moviegenres": "Movie Genres", "components.Discover.MovieGenreList.moviegenres": "Movie Genres",
"components.Discover.MovieGenreSlider.moviegenres": "Movie Genres", "components.Discover.MovieGenreSlider.moviegenres": "Movie Genres",
"components.Discover.NetworkSlider.networks": "Networks", "components.Discover.NetworkSlider.networks": "Networks",

Loading…
Cancel
Save