mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat(ui): display movie/series original title (#1240)
* feat(ui): display movie/series original title * fix(ui): remove extra margin when tagline is missing * fix(ui): simply don't show overview when unavailable * fix(ui): overview heading color should match that of sliders * fix: revert overview removal on movie/series detail pages
This commit is contained in:
@@ -25,7 +25,6 @@ import TitleCard from '../TitleCard';
|
|||||||
import Transition from '../Transition';
|
import Transition from '../Transition';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
overviewunavailable: 'Overview unavailable.',
|
|
||||||
overview: 'Overview',
|
overview: 'Overview',
|
||||||
numberofmovies: '{count} Movies',
|
numberofmovies: '{count} Movies',
|
||||||
requestcollection: 'Request Collection',
|
requestcollection: 'Request Collection',
|
||||||
@@ -417,16 +416,14 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="media-overview">
|
{data.overview && (
|
||||||
<div className="flex-1">
|
<div className="media-overview">
|
||||||
<h2>{intl.formatMessage(messages.overview)}</h2>
|
<div className="flex-1">
|
||||||
<p>
|
<h2>{intl.formatMessage(messages.overview)}</h2>
|
||||||
{data.overview
|
<p>{data.overview}</p>
|
||||||
? data.overview
|
</div>
|
||||||
: intl.formatMessage(messages.overviewunavailable)}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
<div className="slider-header">
|
<div className="slider-header">
|
||||||
<div className="slider-title">
|
<div className="slider-title">
|
||||||
<span>{intl.formatMessage(globalMessages.movies)}</span>
|
<span>{intl.formatMessage(globalMessages.movies)}</span>
|
||||||
|
@@ -35,6 +35,7 @@ import Slider from '../Slider';
|
|||||||
import StatusBadge from '../StatusBadge';
|
import StatusBadge from '../StatusBadge';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
originaltitle: 'Original Title',
|
||||||
releasedate: 'Release Date',
|
releasedate: 'Release Date',
|
||||||
revenue: 'Revenue',
|
revenue: 'Revenue',
|
||||||
budget: 'Budget',
|
budget: 'Budget',
|
||||||
@@ -489,45 +490,47 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="media-overview">
|
<div className="media-overview">
|
||||||
<div className="media-overview-left">
|
<div className="media-overview-left">
|
||||||
<div className="tagline">{data.tagline}</div>
|
{data.tagline && <div className="tagline">{data.tagline}</div>}
|
||||||
<h2>{intl.formatMessage(messages.overview)}</h2>
|
<h2>{intl.formatMessage(messages.overview)}</h2>
|
||||||
<p>
|
<p>
|
||||||
{data.overview
|
{data.overview
|
||||||
? data.overview
|
? data.overview
|
||||||
: intl.formatMessage(messages.overviewunavailable)}
|
: intl.formatMessage(messages.overviewunavailable)}
|
||||||
</p>
|
</p>
|
||||||
<ul className="media-crew">
|
|
||||||
{sortedCrew.slice(0, 6).map((person) => (
|
|
||||||
<li key={`crew-${person.job}-${person.id}`}>
|
|
||||||
<span>{person.job}</span>
|
|
||||||
<Link href={`/person/${person.id}`}>
|
|
||||||
<a className="crew-name">{person.name}</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
{sortedCrew.length > 0 && (
|
{sortedCrew.length > 0 && (
|
||||||
<div className="flex justify-end mt-4">
|
<>
|
||||||
<Link href={`/movie/${data.id}/crew`}>
|
<ul className="media-crew">
|
||||||
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
{sortedCrew.slice(0, 6).map((person) => (
|
||||||
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
<li key={`crew-${person.job}-${person.id}`}>
|
||||||
<svg
|
<span>{person.job}</span>
|
||||||
className="inline-block w-5 h-5 ml-1"
|
<Link href={`/person/${person.id}`}>
|
||||||
fill="none"
|
<a className="crew-name">{person.name}</a>
|
||||||
stroke="currentColor"
|
</Link>
|
||||||
viewBox="0 0 24 24"
|
</li>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
))}
|
||||||
>
|
</ul>
|
||||||
<path
|
<div className="flex justify-end mt-4">
|
||||||
strokeLinecap="round"
|
<Link href={`/movie/${data.id}/crew`}>
|
||||||
strokeLinejoin="round"
|
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
||||||
strokeWidth={2}
|
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
||||||
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
<svg
|
||||||
/>
|
className="inline-block w-5 h-5 ml-1"
|
||||||
</svg>
|
fill="none"
|
||||||
</a>
|
stroke="currentColor"
|
||||||
</Link>
|
viewBox="0 0 24 24"
|
||||||
</div>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="media-overview-right">
|
<div className="media-overview-right">
|
||||||
@@ -601,6 +604,13 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{data.originalTitle &&
|
||||||
|
data.originalLanguage !== locale.slice(0, 2) && (
|
||||||
|
<div className="media-fact">
|
||||||
|
<span>{intl.formatMessage(messages.originaltitle)}</span>
|
||||||
|
<span className="media-fact-value">{data.originalTitle}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="media-fact">
|
<div className="media-fact">
|
||||||
<span>{intl.formatMessage(globalMessages.status)}</span>
|
<span>{intl.formatMessage(globalMessages.status)}</span>
|
||||||
<span className="media-fact-value">{data.status}</span>
|
<span className="media-fact-value">{data.status}</span>
|
||||||
|
@@ -53,6 +53,7 @@ const messages = defineMessages({
|
|||||||
manageModalClearMedia: 'Clear All Media Data',
|
manageModalClearMedia: 'Clear All Media Data',
|
||||||
manageModalClearMediaWarning:
|
manageModalClearMediaWarning:
|
||||||
'* This will irreversibly remove all data for this TV series, including any requests. If this item exists in your Plex library, the media information will be recreated during the next scan.',
|
'* This will irreversibly remove all data for this TV series, including any requests. If this item exists in your Plex library, the media information will be recreated during the next scan.',
|
||||||
|
originaltitle: 'Original Title',
|
||||||
showtype: 'Series Type',
|
showtype: 'Series Type',
|
||||||
anime: 'Anime',
|
anime: 'Anime',
|
||||||
network: '{networkCount, plural, one {Network} other {Networks}}',
|
network: '{networkCount, plural, one {Network} other {Networks}}',
|
||||||
@@ -526,59 +527,61 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="media-overview">
|
<div className="media-overview">
|
||||||
<div className="media-overview-left">
|
<div className="media-overview-left">
|
||||||
<div className="tagline">{data.tagline}</div>
|
{data.tagline && <div className="tagline">{data.tagline}</div>}
|
||||||
<h2>{intl.formatMessage(messages.overview)}</h2>
|
<h2>{intl.formatMessage(messages.overview)}</h2>
|
||||||
<p>
|
<p>
|
||||||
{data.overview
|
{data.overview
|
||||||
? data.overview
|
? data.overview
|
||||||
: intl.formatMessage(messages.overviewunavailable)}
|
: intl.formatMessage(messages.overviewunavailable)}
|
||||||
</p>
|
</p>
|
||||||
<ul className="media-crew">
|
|
||||||
{(data.createdBy.length > 0
|
|
||||||
? [
|
|
||||||
...data.createdBy.map(
|
|
||||||
(person): Partial<Crew> => ({
|
|
||||||
id: person.id,
|
|
||||||
job: 'Creator',
|
|
||||||
name: person.name,
|
|
||||||
})
|
|
||||||
),
|
|
||||||
...sortedCrew,
|
|
||||||
]
|
|
||||||
: sortedCrew
|
|
||||||
)
|
|
||||||
.slice(0, 6)
|
|
||||||
.map((person) => (
|
|
||||||
<li key={`crew-${person.job}-${person.id}`}>
|
|
||||||
<span>{person.job}</span>
|
|
||||||
<Link href={`/person/${person.id}`}>
|
|
||||||
<a className="crew-name">{person.name}</a>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
{sortedCrew.length > 0 && (
|
{sortedCrew.length > 0 && (
|
||||||
<div className="flex justify-end mt-4">
|
<>
|
||||||
<Link href={`/tv/${data.id}/crew`}>
|
<ul className="media-crew">
|
||||||
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
{(data.createdBy.length > 0
|
||||||
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
? [
|
||||||
<svg
|
...data.createdBy.map(
|
||||||
className="inline-block w-5 h-5 ml-1"
|
(person): Partial<Crew> => ({
|
||||||
fill="none"
|
id: person.id,
|
||||||
stroke="currentColor"
|
job: 'Creator',
|
||||||
viewBox="0 0 24 24"
|
name: person.name,
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
})
|
||||||
>
|
),
|
||||||
<path
|
...sortedCrew,
|
||||||
strokeLinecap="round"
|
]
|
||||||
strokeLinejoin="round"
|
: sortedCrew
|
||||||
strokeWidth={2}
|
)
|
||||||
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
.slice(0, 6)
|
||||||
/>
|
.map((person) => (
|
||||||
</svg>
|
<li key={`crew-${person.job}-${person.id}`}>
|
||||||
</a>
|
<span>{person.job}</span>
|
||||||
</Link>
|
<Link href={`/person/${person.id}`}>
|
||||||
</div>
|
<a className="crew-name">{person.name}</a>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<div className="flex justify-end mt-4">
|
||||||
|
<Link href={`/tv/${data.id}/crew`}>
|
||||||
|
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
||||||
|
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
||||||
|
<svg
|
||||||
|
className="inline-block w-5 h-5 ml-1"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="media-overview-right">
|
<div className="media-overview-right">
|
||||||
@@ -615,6 +618,12 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{data.originalName && data.originalLanguage !== locale.slice(0, 2) && (
|
||||||
|
<div className="media-fact">
|
||||||
|
<span>{intl.formatMessage(messages.originaltitle)}</span>
|
||||||
|
<span className="media-fact-value">{data.originalName}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{data.keywords.some(
|
{data.keywords.some(
|
||||||
(keyword) => keyword.id === ANIME_KEYWORD_ID
|
(keyword) => keyword.id === ANIME_KEYWORD_ID
|
||||||
) && (
|
) && (
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
"components.AppDataWarning.dockerVolumeMissingDescription": "The <code>{appDataPath}</code> volume mount was not configured properly. All data will be cleared when the container is stopped or restarted.",
|
"components.AppDataWarning.dockerVolumeMissingDescription": "The <code>{appDataPath}</code> volume mount was not configured properly. All data will be cleared when the container is stopped or restarted.",
|
||||||
"components.CollectionDetails.numberofmovies": "{count} Movies",
|
"components.CollectionDetails.numberofmovies": "{count} Movies",
|
||||||
"components.CollectionDetails.overview": "Overview",
|
"components.CollectionDetails.overview": "Overview",
|
||||||
"components.CollectionDetails.overviewunavailable": "Overview unavailable.",
|
|
||||||
"components.CollectionDetails.requestSuccess": "<strong>{title}</strong> requested successfully!",
|
"components.CollectionDetails.requestSuccess": "<strong>{title}</strong> requested successfully!",
|
||||||
"components.CollectionDetails.requestcollection": "Request Collection",
|
"components.CollectionDetails.requestcollection": "Request Collection",
|
||||||
"components.CollectionDetails.requestcollection4k": "Request Collection in 4K",
|
"components.CollectionDetails.requestcollection4k": "Request Collection in 4K",
|
||||||
@@ -70,6 +69,7 @@
|
|||||||
"components.MovieDetails.openradarr": "Open Movie in Radarr",
|
"components.MovieDetails.openradarr": "Open Movie in Radarr",
|
||||||
"components.MovieDetails.openradarr4k": "Open Movie in 4K Radarr",
|
"components.MovieDetails.openradarr4k": "Open Movie in 4K Radarr",
|
||||||
"components.MovieDetails.originallanguage": "Original Language",
|
"components.MovieDetails.originallanguage": "Original Language",
|
||||||
|
"components.MovieDetails.originaltitle": "Original Title",
|
||||||
"components.MovieDetails.overview": "Overview",
|
"components.MovieDetails.overview": "Overview",
|
||||||
"components.MovieDetails.overviewunavailable": "Overview unavailable.",
|
"components.MovieDetails.overviewunavailable": "Overview unavailable.",
|
||||||
"components.MovieDetails.play4konplex": "Play 4K on Plex",
|
"components.MovieDetails.play4konplex": "Play 4K on Plex",
|
||||||
@@ -614,6 +614,7 @@
|
|||||||
"components.TvDetails.opensonarr": "Open Series in Sonarr",
|
"components.TvDetails.opensonarr": "Open Series in Sonarr",
|
||||||
"components.TvDetails.opensonarr4k": "Open Series in 4K Sonarr",
|
"components.TvDetails.opensonarr4k": "Open Series in 4K Sonarr",
|
||||||
"components.TvDetails.originallanguage": "Original Language",
|
"components.TvDetails.originallanguage": "Original Language",
|
||||||
|
"components.TvDetails.originaltitle": "Original Title",
|
||||||
"components.TvDetails.overview": "Overview",
|
"components.TvDetails.overview": "Overview",
|
||||||
"components.TvDetails.overviewunavailable": "Overview unavailable.",
|
"components.TvDetails.overviewunavailable": "Overview unavailable.",
|
||||||
"components.TvDetails.play4konplex": "Play 4K on Plex",
|
"components.TvDetails.play4konplex": "Play 4K on Plex",
|
||||||
|
@@ -134,11 +134,11 @@ h1 > .media-year {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.media-overview h2 {
|
.media-overview h2 {
|
||||||
@apply text-xl sm:text-2xl;
|
@apply text-xl text-gray-300 sm:text-2xl;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-overview p {
|
.media-overview p {
|
||||||
@apply pt-2 text-sm text-gray-400 lg:text-base;
|
@apply pt-2 text-sm text-gray-400 sm:text-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.media-crew {
|
ul.media-crew {
|
||||||
|
Reference in New Issue
Block a user