1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-03-05 13:20:20 -05:00

New: Include External IDs for series with links

Closes #7927
This commit is contained in:
Yashizzle
2026-03-02 04:48:15 +11:00
committed by GitHub
parent db9ef92a80
commit 7f971d47ac
6 changed files with 97 additions and 80 deletions

View File

@@ -4,6 +4,10 @@
position: relative;
}
.buttonText {
margin: 0 5px;
}
.stateIconContainer {
position: absolute;
top: 50%;

View File

@@ -2,6 +2,7 @@
// Please do not change this file!
interface CssExports {
'button': string;
'buttonText': string;
'clipboardIconContainer': string;
'showStateIcon': string;
'stateIconContainer': string;

View File

@@ -8,6 +8,7 @@ import styles from './ClipboardButton.css';
export interface ClipboardButtonProps extends Omit<ButtonProps, 'children'> {
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}
<span className={styles.clipboardIconContainer}>
{label ? <span className={styles.buttonText}>{label}</span> : null}
<Icon name={icons.CLIPBOARD} />
</span>
</span>

View File

@@ -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;
}
}

View File

@@ -2,6 +2,7 @@
// Please do not change this file!
interface CssExports {
'link': string;
'linkBlock': string;
'linkLabel': string;
'links': string;
}

View File

@@ -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 (
<div className={styles.links}>
<Link
className={styles.link}
to={`https://www.thetvdb.com/?tab=series&id=${tvdbId}`}
>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
The TVDB
</Label>
</Link>
<Link
className={styles.link}
to={`https://trakt.tv/search/tvdb/${tvdbId}?id_type=show`}
>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
Trakt
</Label>
</Link>
{tvMazeId ? (
<Link
className={styles.link}
to={`https://www.tvmaze.com/shows/${tvMazeId}/_`}
>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
TV Maze
</Label>
</Link>
) : null}
{imdbId ? (
<>
<Link
className={styles.link}
to={`https://imdb.com/title/${imdbId}/`}
>
{links.map((link) => (
<div key={link.name} className={styles.linkBlock}>
<Link className={styles.link} to={link.url}>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
IMDB
{link.name}
</Label>
</Link>
<Link
className={styles.link}
to={`http://mdblist.com/show/${imdbId}`}
>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
MDBList
</Label>
</Link>
</>
) : null}
{tmdbId ? (
<Link
className={styles.link}
to={`https://www.themoviedb.org/tv/${tmdbId}`}
>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
TMDB
</Label>
</Link>
) : null}
<ClipboardButton
value={`${link.externalId}`}
title={translate('CopyToClipboard')}
kind={kinds.DEFAULT}
size={sizes.SMALL}
label={link.externalId}
/>
</div>
))}
</div>
);
}