mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat: add production countries to movie/TV detail pages (#2170)
* feat: add production countries to movie/TV detail pages * feat: add country flags to production countries
This commit is contained in:
@@ -909,6 +909,15 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ProductionCompany'
|
||||
productionCountries:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
iso_3166_1:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
spokenLanguages:
|
||||
type: array
|
||||
items:
|
||||
|
@@ -251,6 +251,10 @@ export interface TmdbTvDetails {
|
||||
name: string;
|
||||
origin_country: string;
|
||||
}[];
|
||||
production_countries: {
|
||||
iso_3166_1: string;
|
||||
name: string;
|
||||
}[];
|
||||
spoken_languages: {
|
||||
english_name: string;
|
||||
iso_639_1: string;
|
||||
|
@@ -90,6 +90,10 @@ export interface TvDetails {
|
||||
overview: string;
|
||||
popularity: number;
|
||||
productionCompanies: ProductionCompany[];
|
||||
productionCountries: {
|
||||
iso_3166_1: string;
|
||||
name: string;
|
||||
}[];
|
||||
spokenLanguages: SpokenLanguage[];
|
||||
seasons: Season[];
|
||||
status: string;
|
||||
@@ -187,6 +191,7 @@ export const mapTvDetails = (
|
||||
originCountry: company.origin_country,
|
||||
logoPath: company.logo_path,
|
||||
})),
|
||||
productionCountries: show.production_countries,
|
||||
contentRatings: show.content_ratings,
|
||||
spokenLanguages: show.spoken_languages.map((language) => ({
|
||||
englishName: language.english_name,
|
||||
|
@@ -11,6 +11,8 @@ import {
|
||||
ChevronDoubleDownIcon,
|
||||
ChevronDoubleUpIcon,
|
||||
} from '@heroicons/react/solid';
|
||||
import { hasFlag } from 'country-flag-icons';
|
||||
import 'country-flag-icons/3x2/flags.css';
|
||||
import { uniqBy } from 'lodash';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -69,6 +71,8 @@ const messages = defineMessages({
|
||||
showmore: 'Show More',
|
||||
showless: 'Show Less',
|
||||
streamingproviders: 'Currently Streaming On',
|
||||
productioncountries:
|
||||
'Production {countryCount, plural, one {Country} other {Countries}}',
|
||||
});
|
||||
|
||||
interface MovieDetailsProps {
|
||||
@@ -596,6 +600,37 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{data.productionCountries.length > 0 && (
|
||||
<div className="media-fact">
|
||||
<span>
|
||||
{intl.formatMessage(messages.productioncountries, {
|
||||
countryCount: data.productionCountries.length,
|
||||
})}
|
||||
</span>
|
||||
<span className="media-fact-value">
|
||||
{data.productionCountries.map((c) => {
|
||||
return (
|
||||
<span
|
||||
className="flex items-center justify-end"
|
||||
key={`prodcountry-${c.iso_3166_1}`}
|
||||
>
|
||||
{hasFlag(c.iso_3166_1) && (
|
||||
<span
|
||||
className={`mr-1.5 text-xs leading-5 flag:${c.iso_3166_1}`}
|
||||
/>
|
||||
)}
|
||||
<span>
|
||||
{intl.formatDisplayName(c.iso_3166_1, {
|
||||
type: 'region',
|
||||
fallback: 'none',
|
||||
}) ?? c.name}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{data.productionCompanies.length > 0 && (
|
||||
<div className="media-fact">
|
||||
<span>
|
||||
|
@@ -5,6 +5,8 @@ import {
|
||||
FilmIcon,
|
||||
PlayIcon,
|
||||
} from '@heroicons/react/outline';
|
||||
import { hasFlag } from 'country-flag-icons';
|
||||
import 'country-flag-icons/3x2/flags.css';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
@@ -63,6 +65,8 @@ const messages = defineMessages({
|
||||
episodeRuntime: 'Episode Runtime',
|
||||
episodeRuntimeMinutes: '{runtime} minutes',
|
||||
streamingproviders: 'Currently Streaming On',
|
||||
productioncountries:
|
||||
'Production {countryCount, plural, one {Country} other {Countries}}',
|
||||
});
|
||||
|
||||
interface TvDetailsProps {
|
||||
@@ -533,6 +537,37 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{data.productionCountries.length > 0 && (
|
||||
<div className="media-fact">
|
||||
<span>
|
||||
{intl.formatMessage(messages.productioncountries, {
|
||||
countryCount: data.productionCountries.length,
|
||||
})}
|
||||
</span>
|
||||
<span className="media-fact-value">
|
||||
{data.productionCountries.map((c) => {
|
||||
return (
|
||||
<span
|
||||
className="flex items-center justify-end"
|
||||
key={`prodcountry-${c.iso_3166_1}`}
|
||||
>
|
||||
{hasFlag(c.iso_3166_1) && (
|
||||
<span
|
||||
className={`mr-1.5 text-xs leading-5 flag:${c.iso_3166_1}`}
|
||||
/>
|
||||
)}
|
||||
<span>
|
||||
{intl.formatDisplayName(c.iso_3166_1, {
|
||||
type: 'region',
|
||||
fallback: 'none',
|
||||
}) ?? c.name}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{data.networks.length > 0 && (
|
||||
<div className="media-fact">
|
||||
<span>
|
||||
@@ -552,7 +587,10 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
))
|
||||
.reduce((prev, curr) => (
|
||||
<>
|
||||
{prev}, {curr}
|
||||
{intl.formatMessage(globalMessages.delimitedlist, {
|
||||
a: prev,
|
||||
b: curr,
|
||||
})}
|
||||
</>
|
||||
))}
|
||||
</span>
|
||||
|
@@ -155,6 +155,7 @@
|
||||
"components.MovieDetails.overviewunavailable": "Overview unavailable.",
|
||||
"components.MovieDetails.play4konplex": "Play in 4K on Plex",
|
||||
"components.MovieDetails.playonplex": "Play on Plex",
|
||||
"components.MovieDetails.productioncountries": "Production {countryCount, plural, one {Country} other {Countries}}",
|
||||
"components.MovieDetails.recommendations": "Recommendations",
|
||||
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Release Date} other {Release Dates}}",
|
||||
"components.MovieDetails.revenue": "Revenue",
|
||||
@@ -793,6 +794,7 @@
|
||||
"components.TvDetails.overviewunavailable": "Overview unavailable.",
|
||||
"components.TvDetails.play4konplex": "Play in 4K on Plex",
|
||||
"components.TvDetails.playonplex": "Play on Plex",
|
||||
"components.TvDetails.productioncountries": "Production {countryCount, plural, one {Country} other {Countries}}",
|
||||
"components.TvDetails.recommendations": "Recommendations",
|
||||
"components.TvDetails.seasons": "{seasonCount, plural, one {# Season} other {# Seasons}}",
|
||||
"components.TvDetails.showtype": "Series Type",
|
||||
|
Reference in New Issue
Block a user