Skip to content

Commit

Permalink
feat(discover): hide available media filter
Browse files Browse the repository at this point in the history
  • Loading branch information
leejayhsu committed Jul 31, 2024
1 parent 676a8c9 commit 2521a1e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 3 deletions.
10 changes: 10 additions & 0 deletions overseerr-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4244,6 +4244,11 @@ paths:
schema:
type: string
example: 8|9
- in: query
name: hideAvailable
schema:
type: boolean
example: true
responses:
'200':
description: Results
Expand Down Expand Up @@ -4533,6 +4538,11 @@ paths:
schema:
type: string
example: 8|9
- in: query
name: hideAvailable
schema:
type: boolean
example: true
responses:
'200':
description: Results
Expand Down
25 changes: 22 additions & 3 deletions server/routes/discover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import PlexTvAPI from '@server/api/plextv';
import type { SortOptions } from '@server/api/themoviedb';
import TheMovieDb from '@server/api/themoviedb';
import type { TmdbKeyword } from '@server/api/themoviedb/interfaces';
import { MediaType } from '@server/constants/media';
import { MediaStatus, MediaType } from '@server/constants/media';
import { getRepository } from '@server/datasource';
import Media from '@server/entity/Media';
import { User } from '@server/entity/User';
Expand Down Expand Up @@ -70,6 +70,7 @@ const QueryFilterOptions = z.object({
network: z.coerce.string().optional(),
watchProviders: z.coerce.string().optional(),
watchRegion: z.coerce.string().optional(),
hideAvailable: z.coerce.boolean().optional(),
});

export type FilterOptions = z.infer<typeof QueryFilterOptions>;
Expand Down Expand Up @@ -108,6 +109,15 @@ discoverRoutes.get('/movies', async (req, res, next) => {
data.results.map((result) => result.id)
);

let filteredResults = data.results;

if (query.hideAvailable) {
filteredResults = filteredResults.filter((result) => {
const mediaItem = media.find((req) => req.tmdbId === result.id);
return !(mediaItem?.status === MediaStatus.AVAILABLE);
});
}

let keywordData: TmdbKeyword[] = [];
if (keywords) {
const splitKeywords = keywords.split(',');
Expand All @@ -124,7 +134,7 @@ discoverRoutes.get('/movies', async (req, res, next) => {
totalPages: data.total_pages,
totalResults: data.total_results,
keywords: keywordData,
results: data.results.map((result) =>
results: filteredResults.map((result) =>
mapMovieResult(
result,
media.find(
Expand Down Expand Up @@ -385,6 +395,15 @@ discoverRoutes.get('/tv', async (req, res, next) => {
data.results.map((result) => result.id)
);

let filteredResults = data.results;

if (query.hideAvailable) {
filteredResults = filteredResults.filter((result) => {
const mediaItem = media.find((req) => req.tmdbId === result.id);
return !(mediaItem?.status === MediaStatus.AVAILABLE);
});
}

let keywordData: TmdbKeyword[] = [];
if (keywords) {
const splitKeywords = keywords.split(',');
Expand All @@ -401,7 +420,7 @@ discoverRoutes.get('/tv', async (req, res, next) => {
totalPages: data.total_pages,
totalResults: data.total_results,
keywords: keywordData,
results: data.results.map((result) =>
results: filteredResults.map((result) =>
mapTvResult(
result,
media.find(
Expand Down
16 changes: 16 additions & 0 deletions src/components/Discover/FilterSlideover/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Button from '@app/components/Common/Button';
import MultiRangeSlider from '@app/components/Common/MultiRangeSlider';
import SlideCheckbox from '@app/components/Common/SlideCheckbox';
import SlideOver from '@app/components/Common/SlideOver';
import type { FilterOptions } from '@app/components/Discover/constants';
import { countActiveFilters } from '@app/components/Discover/constants';
Expand Down Expand Up @@ -39,6 +40,7 @@ const messages = defineMessages({
runtime: 'Runtime',
streamingservices: 'Streaming Services',
voteCount: 'Number of votes between {minValue} and {maxValue}',
hideAvailable: 'Hide available titles',
});

type FilterSlideoverProps = {
Expand Down Expand Up @@ -287,6 +289,20 @@ const FilterSlideover = ({
})}
/>
</div>
<div className="flex items-center justify-between">
<span className="text-lg font-semibold">
{intl.formatMessage(messages.hideAvailable)}
</span>
<SlideCheckbox
checked={currentFilters.hideAvailable === 'true'}
onClick={() => {
updateQueryParams(
'hideAvailable',
currentFilters.hideAvailable === 'true' ? undefined : 'true'
);
}}
/>
</div>
<span className="text-lg font-semibold">
{intl.formatMessage(messages.streamingservices)}
</span>
Expand Down
5 changes: 5 additions & 0 deletions src/components/Discover/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export const QueryFilterOptions = z.object({
voteCountGte: z.string().optional(),
watchRegion: z.string().optional(),
watchProviders: z.string().optional(),
hideAvailable: z.string().optional(),
});

export type FilterOptions = z.infer<typeof QueryFilterOptions>;
Expand Down Expand Up @@ -187,6 +188,10 @@ export const prepareFilterValues = (
filterValues.watchRegion = values.watchRegion;
}

if (values.hideAvailable) {
filterValues.hideAvailable = values.hideAvailable;
}

return filterValues;
};

Expand Down

0 comments on commit 2521a1e

Please sign in to comment.