feat: anime profile support (#384)

closes #266
This commit is contained in:
sct
2020-12-18 14:32:40 +09:00
committed by GitHub
parent 1f0486eba2
commit 0972f40a4e
10 changed files with 222 additions and 14 deletions

View File

@@ -36,6 +36,8 @@ const messages = defineMessages({
baseUrlPlaceholder: 'Example: /sonarr',
qualityprofile: 'Quality Profile',
rootfolder: 'Root Folder',
animequalityprofile: 'Anime Quality Profile',
animerootfolder: 'Anime Root Folder',
seasonfolders: 'Season Folders',
server4k: '4K Server',
selectQualityProfile: 'Select a Quality Profile',
@@ -182,6 +184,8 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
baseUrl: sonarr?.baseUrl,
activeProfileId: sonarr?.activeProfileId,
rootFolder: sonarr?.activeDirectory,
activeAnimeProfileId: sonarr?.activeAnimeProfileId,
activeAnimeRootFolder: sonarr?.activeAnimeDirectory,
isDefault: sonarr?.isDefault ?? false,
is4k: sonarr?.is4k ?? false,
enableSeasonFolders: sonarr?.enableSeasonFolders ?? false,
@@ -192,6 +196,9 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
const profileName = testResponse.profiles.find(
(profile) => profile.id === Number(values.activeProfileId)
)?.name;
const animeProfileName = testResponse.profiles.find(
(profile) => profile.id === Number(values.activeAnimeProfileId)
)?.name;
const submission = {
name: values.name,
@@ -203,6 +210,11 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
activeProfileId: Number(values.activeProfileId),
activeProfileName: profileName,
activeDirectory: values.rootFolder,
activeAnimeProfileId: values.activeAnimeProfileId
? Number(values.activeAnimeProfileId)
: undefined,
activeAnimeProfileName: animeProfileName ?? undefined,
activeAnimeDirectory: values.activeAnimeRootFolder,
is4k: values.is4k,
isDefault: values.isDefault,
enableSeasonFolders: values.enableSeasonFolders,
@@ -528,6 +540,92 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
)}
</div>
</div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label
htmlFor="activeAnimeProfileId"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
{intl.formatMessage(messages.animequalityprofile)}
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm">
<Field
as="select"
id="activeAnimeProfileId"
name="activeAnimeProfileId"
disabled={!isValidated || isTesting}
className="mt-1 form-select rounded-md block w-full pl-3 pr-10 py-2 text-base leading-6 bg-gray-700 border-gray-500 focus:outline-none focus:ring-blue focus:border-gray-500 sm:text-sm sm:leading-5 disabled:opacity-50"
>
<option value="">
{isTesting
? intl.formatMessage(messages.loadingprofiles)
: !isValidated
? intl.formatMessage(
messages.testFirstQualityProfiles
)
: intl.formatMessage(messages.selectQualityProfile)}
</option>
{testResponse.profiles.length > 0 &&
testResponse.profiles.map((profile) => (
<option
key={`loaded-profile-${profile.id}`}
value={profile.id}
>
{profile.name}
</option>
))}
</Field>
</div>
{errors.activeAnimeProfileId &&
touched.activeAnimeProfileId && (
<div className="text-red-500 mt-2">
{errors.activeAnimeProfileId}
</div>
)}
</div>
</div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label
htmlFor="activeAnimeRootFolder"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
{intl.formatMessage(messages.animerootfolder)}
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm">
<Field
as="select"
id="activeAnimeRootFolder"
name="activeAnimeRootFolder"
disabled={!isValidated || isTesting}
className="mt-1 form-select block rounded-md w-full pl-3 pr-10 py-2 text-base leading-6 bg-gray-700 border-gray-500 focus:outline-none focus:ring-blue focus:border-gray-500 sm:text-sm sm:leading-5 disabled:opacity-50"
>
<option value="">
{isTesting
? intl.formatMessage(messages.loadingrootfolders)
: !isValidated
? intl.formatMessage(messages.testFirstRootFolders)
: intl.formatMessage(messages.selectRootFolder)}
</option>
{testResponse.rootFolders.length > 0 &&
testResponse.rootFolders.map((folder) => (
<option
key={`loaded-profile-${folder.id}`}
value={folder.path}
>
{folder.path}
</option>
))}
</Field>
</div>
{errors.activeAnimeRootFolder &&
touched.activeAnimeRootFolder && (
<div className="text-red-500 mt-2">
{errors.rootFolder}
</div>
)}
</div>
</div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label
htmlFor="is4k"

View File

@@ -28,6 +28,7 @@ import RTAudRotten from '../../assets/rt_aud_rotten.svg';
import type { RTRating } from '../../../server/api/rottentomatoes';
import Head from 'next/head';
import globalMessages from '../../i18n/globalMessages';
import { ANIME_KEYWORD_ID } from '../../../server/api/themoviedb';
const messages = defineMessages({
userrating: 'User Rating',
@@ -56,6 +57,8 @@ const messages = defineMessages({
'This will remove all media data including all requests for this item. This action is irreversible. If this item exists in your Plex library, the media information will be recreated next sync.',
approve: 'Approve',
decline: 'Decline',
showtype: 'Show Type',
anime: 'Anime',
});
interface TvDetailsProps {
@@ -431,6 +434,18 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
)}
</div>
)}
{data.keywords.some(
(keyword) => keyword.id === ANIME_KEYWORD_ID
) && (
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
<span className="text-sm">
{intl.formatMessage(messages.showtype)}
</span>
<span className="flex-1 text-right text-gray-400 text-sm">
{intl.formatMessage(messages.anime)}
</span>
</div>
)}
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
<span className="text-sm">
<FormattedMessage {...messages.status} />