From 7f971d47ac032c8f5731303b3a29dac5cf90c9d3 Mon Sep 17 00:00:00 2001 From: Yashizzle <16638776+Yashizzle@users.noreply.github.com> Date: Mon, 2 Mar 2026 04:48:15 +1100 Subject: [PATCH] New: Include External IDs for series with links Closes #7927 --- .../src/Components/Link/ClipboardButton.css | 4 + .../Components/Link/ClipboardButton.css.d.ts | 1 + .../src/Components/Link/ClipboardButton.tsx | 3 + .../src/Series/Details/SeriesDetailsLinks.css | 16 +- .../Details/SeriesDetailsLinks.css.d.ts | 1 + .../src/Series/Details/SeriesDetailsLinks.tsx | 152 +++++++++--------- 6 files changed, 97 insertions(+), 80 deletions(-) diff --git a/frontend/src/Components/Link/ClipboardButton.css b/frontend/src/Components/Link/ClipboardButton.css index 438489155..a524dec26 100644 --- a/frontend/src/Components/Link/ClipboardButton.css +++ b/frontend/src/Components/Link/ClipboardButton.css @@ -4,6 +4,10 @@ position: relative; } +.buttonText { + margin: 0 5px; +} + .stateIconContainer { position: absolute; top: 50%; diff --git a/frontend/src/Components/Link/ClipboardButton.css.d.ts b/frontend/src/Components/Link/ClipboardButton.css.d.ts index c1ad078d8..8a5347352 100644 --- a/frontend/src/Components/Link/ClipboardButton.css.d.ts +++ b/frontend/src/Components/Link/ClipboardButton.css.d.ts @@ -2,6 +2,7 @@ // Please do not change this file! interface CssExports { 'button': string; + 'buttonText': string; 'clipboardIconContainer': string; 'showStateIcon': string; 'stateIconContainer': string; diff --git a/frontend/src/Components/Link/ClipboardButton.tsx b/frontend/src/Components/Link/ClipboardButton.tsx index dfce115ac..3b9e1beba 100644 --- a/frontend/src/Components/Link/ClipboardButton.tsx +++ b/frontend/src/Components/Link/ClipboardButton.tsx @@ -8,6 +8,7 @@ import styles from './ClipboardButton.css'; export interface ClipboardButtonProps extends Omit { value: string; + label?: string | number; } export type ClipboardState = 'success' | 'error' | null; @@ -15,6 +16,7 @@ export type ClipboardState = 'success' | 'error' | null; export default function ClipboardButton({ id, value, + label, className = styles.button, ...otherProps }: ClipboardButtonProps) { @@ -68,6 +70,7 @@ export default function ClipboardButton({ ) : null} + {label ? {label} : null} diff --git a/frontend/src/Series/Details/SeriesDetailsLinks.css b/frontend/src/Series/Details/SeriesDetailsLinks.css index 4ccb0e70e..c364ea98e 100644 --- a/frontend/src/Series/Details/SeriesDetailsLinks.css +++ b/frontend/src/Series/Details/SeriesDetailsLinks.css @@ -1,4 +1,6 @@ .links { + display: flex; + flex-wrap: wrap; margin: 0; } @@ -9,12 +11,22 @@ .linkLabel { composes: label from '~Components/Label.css'; - cursor: pointer; + margin: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + + &:hover { + cursor: pointer; + } +} + +.linkBlock { + display: flex; + margin: 3px; } @media only screen and (max-width: $breakpointExtraSmall) { .links { - display: flex; flex-flow: column wrap; } } diff --git a/frontend/src/Series/Details/SeriesDetailsLinks.css.d.ts b/frontend/src/Series/Details/SeriesDetailsLinks.css.d.ts index 9f91f93a4..c8855831b 100644 --- a/frontend/src/Series/Details/SeriesDetailsLinks.css.d.ts +++ b/frontend/src/Series/Details/SeriesDetailsLinks.css.d.ts @@ -2,6 +2,7 @@ // Please do not change this file! interface CssExports { 'link': string; + 'linkBlock': string; 'linkLabel': string; 'links': string; } diff --git a/frontend/src/Series/Details/SeriesDetailsLinks.tsx b/frontend/src/Series/Details/SeriesDetailsLinks.tsx index b2a725a68..7bad2f91b 100644 --- a/frontend/src/Series/Details/SeriesDetailsLinks.tsx +++ b/frontend/src/Series/Details/SeriesDetailsLinks.tsx @@ -1,8 +1,10 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import Label from 'Components/Label'; +import ClipboardButton from 'Components/Link/ClipboardButton'; import Link from 'Components/Link/Link'; import { kinds, sizes } from 'Helpers/Props'; import Series from 'Series/Series'; +import translate from 'Utilities/String/translate'; import styles from './SeriesDetailsLinks.css'; type SeriesDetailsLinksProps = Pick< @@ -10,96 +12,90 @@ type SeriesDetailsLinksProps = Pick< 'tvdbId' | 'tvMazeId' | 'imdbId' | 'tmdbId' >; +interface SeriesDetailsLink { + externalId: string | number; + name: string; + url: string; +} + function SeriesDetailsLinks(props: SeriesDetailsLinksProps) { const { tvdbId, tvMazeId, imdbId, tmdbId } = props; + const links = useMemo(() => { + const validLinks: SeriesDetailsLink[] = []; + + if (tvdbId) { + validLinks.push( + { + externalId: tvdbId, + name: 'The TVDB', + url: `https://www.thetvdb.com/?tab=series&id=${tvdbId}`, + }, + { + externalId: tvdbId, + name: 'Trakt', + url: `https://trakt.tv/search/tvdb/${tvdbId}?id_type=show`, + } + ); + } + + if (tvMazeId) { + validLinks.push({ + externalId: tvMazeId, + name: 'TV Maze', + url: `https://www.tvmaze.com/shows/${tvMazeId}/_`, + }); + } + + if (imdbId) { + validLinks.push( + { + externalId: imdbId, + name: 'IMDB', + url: `https://imdb.com/title/${imdbId}/`, + }, + { + externalId: imdbId, + name: 'MDBList', + url: `https://mdblist.com/show/${imdbId}`, + } + ); + } + + if (tmdbId) { + validLinks.push({ + externalId: tmdbId, + name: 'TMDB', + url: `https://www.themoviedb.org/tv/${tmdbId}`, + }); + } + + return validLinks; + }, [tvdbId, tvMazeId, imdbId, tmdbId]); + return (
- - - - - - - - - {tvMazeId ? ( - - - - ) : null} - - {imdbId ? ( - <> - + {links.map((link) => ( +
+ - - - - - ) : null} - - {tmdbId ? ( - - - - ) : null} + +
+ ))}
); }