-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start working on TMDB linking page (#1010)
* Start working on TMDB linking page * Refactor types
- Loading branch information
1 parent
3098e93
commit e587bd3
Showing
32 changed files
with
682 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import React, { useMemo } from 'react'; | ||
import cx from 'classnames'; | ||
import { find } from 'lodash'; | ||
|
||
import MatchRating from '@/components/Collection/Tmdb/MatchRating'; | ||
import { getEpisodePrefixAlt } from '@/core/utilities/getEpisodePrefix'; | ||
|
||
import type { EpisodeType } from '@/core/types/api/episode'; | ||
import type { TmdbEpisodeXRefType, TmdbMovieXRefType } from '@/core/types/api/tmdb'; | ||
|
||
const Episode = React.memo(({ episode, xref }: { episode: EpisodeType, xref?: TmdbEpisodeXRefType }) => { | ||
const tmdbEpisode = useMemo(() => { | ||
if (!xref || !episode.TMDB) return undefined; | ||
return find(episode.TMDB.Episodes, { ID: xref.TmdbEpisodeID }); | ||
}, [episode, xref]); | ||
|
||
return ( | ||
<> | ||
{/* eslint-disable-next-line no-nested-ternary */} | ||
{tmdbEpisode ? (tmdbEpisode.SeasonNumber === 0 ? 'SP' : `S${tmdbEpisode.SeasonNumber}`) : 'XX'} | ||
<div>{tmdbEpisode?.EpisodeNumber.toString().padStart(2, '0') ?? 'XX'}</div> | ||
{tmdbEpisode?.Title ?? 'Entry Not Linked'} | ||
</> | ||
); | ||
}); | ||
|
||
const Movie = React.memo(({ episode, xref }: { episode: EpisodeType, xref?: TmdbMovieXRefType }) => { | ||
const tmdbMovie = useMemo(() => { | ||
if (!xref || !episode.TMDB) return undefined; | ||
return find(episode.TMDB.Movies, { ID: xref.TmdbMovieID }); | ||
}, [episode, xref]); | ||
|
||
return ( | ||
<> | ||
Movie | ||
<div> | ||
{tmdbMovie?.Title ?? 'Entry Not Linked'} | ||
</div> | ||
</> | ||
); | ||
}); | ||
|
||
type Props = { | ||
episode: EpisodeType; | ||
type: 'tv' | 'movie' | null; | ||
xrefs: TmdbEpisodeXRefType[] | TmdbMovieXRefType[]; | ||
isOdd: boolean; | ||
}; | ||
|
||
const EpisodeRow = ({ episode, isOdd, type, xrefs }: Props) => { | ||
// TODO: Add support for 1-n (1 AniDB - n TMDB) mapping | ||
const xref = useMemo( | ||
() => xrefs.find(ref => ref.AnidbEpisodeID === episode.IDs.AniDB), | ||
[episode.IDs.AniDB, xrefs], | ||
); | ||
|
||
return ( | ||
<> | ||
<div | ||
className={cx( | ||
'flex grow basis-0 gap-x-6 rounded-lg border border-panel-border p-4 leading-5', | ||
isOdd ? 'bg-panel-background-alt' : 'bg-panel-background', | ||
)} | ||
> | ||
{getEpisodePrefixAlt(episode.AniDB?.Type)} | ||
<div>{episode.AniDB?.EpisodeNumber.toString().padStart(2, '0')}</div> | ||
{episode.Name} | ||
</div> | ||
|
||
{type === 'tv' && <MatchRating rating={(xref as TmdbEpisodeXRefType | undefined)?.Rating} />} | ||
|
||
<div | ||
className={cx( | ||
'flex grow basis-0 gap-x-6 rounded-lg border border-panel-border p-4 leading-5', | ||
isOdd ? 'bg-panel-background-alt' : 'bg-panel-background', | ||
)} | ||
> | ||
{type === 'tv' && <Episode episode={episode} xref={xref as TmdbEpisodeXRefType | undefined} />} | ||
{type === 'movie' && <Movie episode={episode} xref={xref as TmdbMovieXRefType | undefined} />} | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default EpisodeRow; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import React from 'react'; | ||
import cx from 'classnames'; | ||
|
||
import { MatchRatingType } from '@/core/types/api/episode'; | ||
|
||
const getAbbreviation = (rating?: MatchRatingType) => { | ||
switch (rating) { | ||
case MatchRatingType.DateAndTitleMatches: | ||
return 'DT'; | ||
case MatchRatingType.DateMatches: | ||
case MatchRatingType.TitleMatches: | ||
return 'D/T'; | ||
case MatchRatingType.UserVerified: | ||
return 'UO'; | ||
case MatchRatingType.FirstAvailable: | ||
return 'BG'; | ||
default: | ||
return ''; | ||
} | ||
}; | ||
|
||
const MatchRating = ({ rating }: { rating?: MatchRatingType }) => ( | ||
<div | ||
className={cx( | ||
'flex justify-center items-center rounded-md w-14 text-button-primary-text', | ||
{ | ||
'bg-panel-text-important': rating === MatchRatingType.DateAndTitleMatches, | ||
'bg-panel-text-warning': rating === MatchRatingType.DateMatches || rating === MatchRatingType.TitleMatches, | ||
'bg-panel-text-primary': rating === MatchRatingType.UserVerified, | ||
'bg-panel-text-danger': rating === MatchRatingType.FirstAvailable, | ||
}, | ||
)} | ||
> | ||
{getAbbreviation(rating)} | ||
</div> | ||
); | ||
|
||
export default MatchRating; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React, { useMemo } from 'react'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { mdiLinkPlus } from '@mdi/js'; | ||
import { Icon } from '@mdi/react'; | ||
import { countBy } from 'lodash'; | ||
|
||
import Button from '@/components/Input/Button'; | ||
import ShokoPanel from '@/components/Panels/ShokoPanel'; | ||
import ItemCount from '@/components/Utilities/ItemCount'; | ||
|
||
import type { MatchRatingType } from '@/core/types/api/episode'; | ||
import type { TmdbXrefType } from '@/core/types/api/tmdb'; | ||
|
||
const TopPanel = (props: { seriesId: string, xrefs: TmdbXrefType[], xrefsCount: number }) => { | ||
const { seriesId, xrefs, xrefsCount } = props; | ||
const navigate = useNavigate(); | ||
|
||
const matchRatingCounts = useMemo( | ||
() => countBy(xrefs, 'Rating'), | ||
[xrefs], | ||
) as Record<MatchRatingType, number>; | ||
|
||
return ( | ||
<ShokoPanel title="Metadata Linking" options={<ItemCount count={xrefsCount} suffix="Entries" />}> | ||
<div className="flex items-center gap-x-3"> | ||
<div className="flex grow items-center gap-x-4 rounded-lg border border-panel-border bg-panel-background-alt px-4 py-3"> | ||
<div className="flex items-center gap-x-2"> | ||
<div className="rounded-md bg-panel-text-important px-2 text-button-primary-text"> | ||
{matchRatingCounts.DateAndTitleMatches ?? 0} | ||
</div> | ||
Dates and Title Match (DT) | ||
</div> | ||
<div className="flex items-center gap-x-2"> | ||
<div className="rounded-md bg-panel-text-warning px-2 text-button-primary-text"> | ||
{(matchRatingCounts.DateMatches ?? 0) + (matchRatingCounts.TitleMatches ?? 0)} | ||
</div> | ||
Dates or Title Match (D/T) | ||
</div> | ||
<div className="flex items-center gap-x-2"> | ||
<div className="rounded-md bg-panel-text-primary px-2 text-button-primary-text"> | ||
{matchRatingCounts.UserVerified ?? 0} | ||
</div> | ||
User Overridden (UO) | ||
</div> | ||
<div className="flex items-center gap-x-2"> | ||
<div className="rounded-md bg-panel-text-danger px-2 text-button-primary-text"> | ||
{matchRatingCounts.FirstAvailable ?? 0} | ||
</div> | ||
Best Guess (BG) | ||
</div> | ||
</div> | ||
<Button | ||
buttonType="secondary" | ||
buttonSize="normal" | ||
className="flex flex-row flex-wrap items-center gap-x-2 py-3" | ||
onClick={() => navigate(`/webui/collection/series/${seriesId}`)} | ||
> | ||
Cancel | ||
</Button> | ||
<Button | ||
buttonType="primary" | ||
buttonSize="normal" | ||
className="flex flex-row flex-wrap items-center gap-x-2 py-3" | ||
onClick={() => {}} | ||
> | ||
<Icon path={mdiLinkPlus} size={1} /> | ||
Create Links | ||
</Button> | ||
</div> | ||
</ShokoPanel> | ||
); | ||
}; | ||
|
||
export default TopPanel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.