New: External links for search results

pull/1951/head
Bogdan 6 months ago
parent 7b5e1f40ba
commit df89450428

@ -0,0 +1,13 @@
.links {
margin: 0;
}
.link {
white-space: nowrap;
}
.linkLabel {
composes: label from '~Components/Label.css';
cursor: pointer;
}

@ -0,0 +1,9 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'link': string;
'linkLabel': string;
'links': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -0,0 +1,90 @@
import React from 'react';
import Label from 'Components/Label';
import Link from 'Components/Link/Link';
import { kinds, sizes } from 'Helpers/Props';
import { IndexerCategory } from 'Indexer/Indexer';
import styles from './ReleaseLinks.css';
interface ReleaseLinksProps {
categories: IndexerCategory[];
imdbId?: string;
tmdbId?: number;
tvdbId?: number;
tvMazeId?: number;
}
function ReleaseLinks(props: ReleaseLinksProps) {
const { categories = [], imdbId, tmdbId, tvdbId, tvMazeId } = props;
const categoryNames = categories
.filter((item) => item.id < 100000)
.map((c) => c.name);
return (
<div className={styles.links}>
{imdbId ? (
<Link
className={styles.link}
to={`https://imdb.com/title/tt${imdbId.toString().padStart(7, '0')}/`}
>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
IMDb
</Label>
</Link>
) : null}
{tmdbId ? (
<Link
className={styles.link}
to={`https://www.themoviedb.org/${
categoryNames.includes('Movies') ? 'movie' : 'tv'
}/${tmdbId}`}
>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
TMDb
</Label>
</Link>
) : null}
{tvdbId ? (
<Link
className={styles.link}
to={`https://www.thetvdb.com/?tab=series&id=${tvdbId}`}
>
<Label
className={styles.linkLabel}
kind={kinds.INFO}
size={sizes.LARGE}
>
TVDb
</Label>
</Link>
) : null}
{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}
</div>
);
}
export default ReleaseLinks;

@ -63,7 +63,7 @@
} }
.externalLinks { .externalLinks {
margin: 0 2px; composes: button from '~Components/Link/IconButton.css';
width: 22px;
text-align: center; color: var(--textColor);
} }

@ -16,6 +16,7 @@ import titleCase from 'Utilities/String/titleCase';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import CategoryLabel from './CategoryLabel'; import CategoryLabel from './CategoryLabel';
import Peers from './Peers'; import Peers from './Peers';
import ReleaseLinks from './ReleaseLinks';
import styles from './SearchIndexRow.css'; import styles from './SearchIndexRow.css';
function getDownloadIcon(isGrabbing, isGrabbed, grabError) { function getDownloadIcon(isGrabbing, isGrabbed, grabError) {
@ -118,6 +119,10 @@ class SearchIndexRow extends Component {
grabs, grabs,
seeders, seeders,
leechers, leechers,
imdbId,
tmdbId,
tvdbId,
tvMazeId,
indexerFlags, indexerFlags,
columns, columns,
isGrabbing, isGrabbing,
@ -343,6 +348,32 @@ class SearchIndexRow extends Component {
/> : /> :
null null
} }
{
imdbId || tmdbId || tvdbId || tvMazeId ? (
<Popover
anchor={
<Icon
className={styles.externalLinks}
name={icons.EXTERNAL_LINK}
size={12}
/>
}
title={translate('Links')}
body={
<ReleaseLinks
categories={categories}
imdbId={imdbId}
tmdbId={tmdbId}
tvdbId={tvdbId}
tvMazeId={tvMazeId}
/>
}
kind={kinds.INVERSE}
position={tooltipPositions.TOP}
/>
) : null
}
</VirtualTableRowCell> </VirtualTableRowCell>
); );
} }
@ -375,6 +406,10 @@ SearchIndexRow.propTypes = {
grabs: PropTypes.number, grabs: PropTypes.number,
seeders: PropTypes.number, seeders: PropTypes.number,
leechers: PropTypes.number, leechers: PropTypes.number,
imdbId: PropTypes.number,
tmdbId: PropTypes.number,
tvdbId: PropTypes.number,
tvMazeId: PropTypes.number,
indexerFlags: PropTypes.arrayOf(PropTypes.string).isRequired, indexerFlags: PropTypes.arrayOf(PropTypes.string).isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired, columns: PropTypes.arrayOf(PropTypes.object).isRequired,
onGrabPress: PropTypes.func.isRequired, onGrabPress: PropTypes.func.isRequired,

@ -23,8 +23,10 @@ namespace Prowlarr.Api.V1.Search
public string ReleaseHash { get; set; } public string ReleaseHash { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string SortTitle { get; set; } public string SortTitle { get; set; }
public bool Approved { get; set; }
public int ImdbId { get; set; } public int ImdbId { get; set; }
public int TmdbId { get; set; }
public int TvdbId { get; set; }
public int TvMazeId { get; set; }
public DateTime PublishDate { get; set; } public DateTime PublishDate { get; set; }
public string CommentUrl { get; set; } public string CommentUrl { get; set; }
public string DownloadUrl { get; set; } public string DownloadUrl { get; set; }
@ -80,6 +82,9 @@ namespace Prowlarr.Api.V1.Search
Title = releaseInfo.Title, Title = releaseInfo.Title,
SortTitle = releaseInfo.Title.NormalizeTitle(), SortTitle = releaseInfo.Title.NormalizeTitle(),
ImdbId = releaseInfo.ImdbId, ImdbId = releaseInfo.ImdbId,
TmdbId = releaseInfo.TmdbId,
TvdbId = releaseInfo.TvdbId,
TvMazeId = releaseInfo.TvMazeId,
PublishDate = releaseInfo.PublishDate, PublishDate = releaseInfo.PublishDate,
CommentUrl = releaseInfo.CommentUrl, CommentUrl = releaseInfo.CommentUrl,
DownloadUrl = releaseInfo.DownloadUrl, DownloadUrl = releaseInfo.DownloadUrl,

Loading…
Cancel
Save