Translate Frontend InteractiveSearch
This commit is contained in:
parent
78d4dee461
commit
efca704388
|
@ -139,10 +139,9 @@ function InteractiveSearch(props) {
|
|||
{
|
||||
errorMessage ?
|
||||
<Fragment>
|
||||
Search failed because its {errorMessage.charAt(0).toLowerCase() + errorMessage.slice(1)}.
|
||||
Try refreshing the series info and verify the necessary information is present before searching again
|
||||
{translate('InteractiveSearchResultsFailedErrorMessage', { message: errorMessage.charAt(0).toLowerCase() + errorMessage.slice(1) })}
|
||||
</Fragment> :
|
||||
'Unable to load results for this episode search. Try again later'
|
||||
translate('EpisodeSearchResultsLoadError')
|
||||
}
|
||||
</div> :
|
||||
null
|
||||
|
|
|
@ -20,6 +20,7 @@ import formatDateTime from 'Utilities/Date/formatDateTime';
|
|||
import formatAge from 'Utilities/Number/formatAge';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import OverrideMatchModal from './OverrideMatch/OverrideMatchModal';
|
||||
import Peers from './Peers';
|
||||
import ReleaseEpisode from './ReleaseEpisode';
|
||||
|
@ -62,12 +63,12 @@ function getDownloadTooltip(
|
|||
if (isGrabbing) {
|
||||
return '';
|
||||
} else if (isGrabbed) {
|
||||
return 'Added to download queue';
|
||||
return translate('AddToDownloadQueue');
|
||||
} else if (grabError) {
|
||||
return grabError;
|
||||
}
|
||||
|
||||
return 'Add to download queue';
|
||||
return translate('AddedToDownloadQueue');
|
||||
}
|
||||
|
||||
interface InteractiveSearchRowProps {
|
||||
|
@ -261,7 +262,7 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
|
|||
{rejections.length ? (
|
||||
<Popover
|
||||
anchor={<Icon name={icons.DANGER} kind={kinds.DANGER} />}
|
||||
title="Release Rejected"
|
||||
title={translate('ReleaseRejected')}
|
||||
body={
|
||||
<ul>
|
||||
{rejections.map((rejection, index) => {
|
||||
|
@ -285,7 +286,7 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
|
|||
|
||||
<Link
|
||||
className={styles.manualDownloadContent}
|
||||
title="Override and add to download queue"
|
||||
title={translate('OverrideAndAddToDownloadQueue')}
|
||||
onPress={onOverridePress}
|
||||
>
|
||||
<div className={styles.manualDownloadContent}>
|
||||
|
@ -307,9 +308,9 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
|
|||
<ConfirmModal
|
||||
isOpen={isConfirmGrabModalOpen}
|
||||
kind={kinds.WARNING}
|
||||
title="Grab Release"
|
||||
message={`Sonarr was unable to determine which series and episode this release was for. Sonarr may be unable to automatically import this release. Do you want to grab '${title}'?`}
|
||||
confirmLabel="Grab"
|
||||
title={translate('GrabRelease')}
|
||||
message={translate('GrabReleaseMessageText', { title })}
|
||||
confirmLabel={translate('Grab')}
|
||||
onConfirm={onGrabConfirm}
|
||||
onCancel={onGrabCancel}
|
||||
/>
|
||||
|
|
|
@ -32,13 +32,17 @@ function SelectDownloadClientModalContent(
|
|||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>{modalTitle} - Select Download Client</ModalHeader>
|
||||
<ModalHeader>
|
||||
{translate('SelectDownloadClientModalTitle', { modalTitle })}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
{isFetching ? <LoadingIndicator /> : null}
|
||||
|
||||
{!isFetching && error ? (
|
||||
<Alert kind={kinds.DANGER}>Unable to load download clients</Alert>
|
||||
<Alert kind={kinds.DANGER}>
|
||||
{translate('DownloadClientsLoadError')}
|
||||
</Alert>
|
||||
) : null}
|
||||
|
||||
{isPopulated && !error ? (
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import Link from 'Components/Link/Link';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './SelectDownloadClientRow.css';
|
||||
|
||||
interface SelectSeasonRowProps {
|
||||
|
@ -23,7 +24,7 @@ function SelectDownloadClientRow(props: SelectSeasonRowProps) {
|
|||
onPress={onSeasonSelectWrapper}
|
||||
>
|
||||
<div>{name}</div>
|
||||
<div>Priority: {priority}</div>
|
||||
<div>{translate('PrioritySettings', { priority })}</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ interface OverrideMatchModalContentProps {
|
|||
}
|
||||
|
||||
function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
|
||||
const modalTitle = 'Manual Grab';
|
||||
const modalTitle = translate('ManualGrab');
|
||||
const {
|
||||
indexerId,
|
||||
title,
|
||||
|
@ -185,16 +185,16 @@ function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
|
|||
|
||||
const onGrabPress = useCallback(() => {
|
||||
if (!seriesId) {
|
||||
setError('Series must be selected');
|
||||
setError(translate('OverrideGrabNoSeries'));
|
||||
return;
|
||||
} else if (!episodes.length) {
|
||||
setError('At least one episode must be selected');
|
||||
setError(translate('OverrideGrabNoEpisode'));
|
||||
return;
|
||||
} else if (!quality) {
|
||||
setError('Quality must be selected');
|
||||
setError(translate('OverrideGrabNoQuality'));
|
||||
return;
|
||||
} else if (!languages.length) {
|
||||
setError('At least one language must be selected');
|
||||
setError(translate('OverrideGrabNoLanguage'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
|
|||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>
|
||||
{translate('Override and Grab - {title}', { title })}
|
||||
{translate('OverrideGrabModalTitle', { title })}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
|
@ -257,7 +257,7 @@ function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
|
|||
|
||||
<DescriptionListItem
|
||||
className={styles.item}
|
||||
title={translate('Season Number')}
|
||||
title={translate('SeasonNumber')}
|
||||
data={
|
||||
<OverrideMatchData
|
||||
value={seasonNumber}
|
||||
|
@ -311,13 +311,13 @@ function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
|
|||
{downloadClients.length > 1 ? (
|
||||
<DescriptionListItem
|
||||
className={styles.item}
|
||||
title={translate('Download Client')}
|
||||
title={translate('DownloadClient')}
|
||||
data={
|
||||
<OverrideMatchData
|
||||
value={
|
||||
downloadClients.find(
|
||||
(downloadClient) => downloadClient.id === downloadClientId
|
||||
)?.name ?? 'Default'
|
||||
)?.name ?? translate('Default')
|
||||
}
|
||||
onPress={onSelectDownloadClientPress}
|
||||
/>
|
||||
|
@ -338,7 +338,7 @@ function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
|
|||
error={grabError}
|
||||
onPress={onGrabPress}
|
||||
>
|
||||
{translate('Grab Release')}
|
||||
{translate('GrabRelease')}
|
||||
</SpinnerErrorButton>
|
||||
</div>
|
||||
</ModalFooter>
|
||||
|
|
|
@ -6,6 +6,7 @@ import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'
|
|||
import Icon from 'Components/Icon';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, tooltipPositions } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './ReleaseSceneIndicator.css';
|
||||
|
||||
function formatReleaseNumber(
|
||||
|
@ -32,7 +33,7 @@ function formatReleaseNumber(
|
|||
}
|
||||
|
||||
if (seasonNumber !== undefined) {
|
||||
return `Season ${seasonNumber}`;
|
||||
return translate('SeasonNumberToken', { seasonNumber });
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -112,22 +113,28 @@ function ReleaseSceneIndicator(props: ReleaseSceneIndicatorProps) {
|
|||
level = styles.levelMixed;
|
||||
messages.push(
|
||||
<div key="source">
|
||||
{comment ?? 'Source'} releases exist with ambiguous numbering, unable to
|
||||
reliably identify episode.
|
||||
{translate('ReleaseSceneIndicatorSourceMessage', {
|
||||
message: comment ?? 'Source',
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
} else if (isUnknown) {
|
||||
level = styles.levelUnknown;
|
||||
messages.push(
|
||||
<div key="unknown">
|
||||
Numbering varies for this episode and release does not match any known
|
||||
mappings.
|
||||
{translate('ReleaseSceneIndicatorUnknownMessage')}
|
||||
</div>
|
||||
);
|
||||
if (sceneOrigin === 'unknown') {
|
||||
messages.push(<div key="origin">Assuming Scene numbering.</div>);
|
||||
messages.push(
|
||||
<div key="origin">
|
||||
{translate('ReleaseSceneIndicatorAssumingScene')}.
|
||||
</div>
|
||||
);
|
||||
} else if (sceneOrigin === 'unknown:tvdb') {
|
||||
messages.push(<div key="origin">Assuming TheTVDB numbering.</div>);
|
||||
messages.push(
|
||||
<div key="origin">{translate('ReleaseSceneIndicatorAssumingTvdb')}</div>
|
||||
);
|
||||
}
|
||||
} else if (mappingDifferent) {
|
||||
level = styles.levelMapped;
|
||||
|
@ -142,11 +149,15 @@ function ReleaseSceneIndicator(props: ReleaseSceneIndicatorProps) {
|
|||
if (mappedNumber) {
|
||||
messages.push(
|
||||
<div key="not-requested">
|
||||
Mapped episode wasn't requested in this search.
|
||||
{translate('ReleaseSceneIndicatorMappedNotRequested')}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
messages.push(<div key="unknown-series">Unknown episode or series.</div>);
|
||||
messages.push(
|
||||
<div key="unknown-series">
|
||||
{translate('ReleaseSceneIndicatorUnknownSeries')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +167,7 @@ function ReleaseSceneIndicator(props: ReleaseSceneIndicatorProps) {
|
|||
<DescriptionListItem
|
||||
titleClassName={styles.title}
|
||||
descriptionClassName={styles.description}
|
||||
title="Mapping"
|
||||
title={translate('Mapping')}
|
||||
data={comment}
|
||||
/>
|
||||
)}
|
||||
|
@ -165,7 +176,7 @@ function ReleaseSceneIndicator(props: ReleaseSceneIndicatorProps) {
|
|||
<DescriptionListItem
|
||||
titleClassName={styles.title}
|
||||
descriptionClassName={styles.description}
|
||||
title="Title"
|
||||
title={translate('Title')}
|
||||
data={title}
|
||||
/>
|
||||
)}
|
||||
|
@ -174,7 +185,7 @@ function ReleaseSceneIndicator(props: ReleaseSceneIndicatorProps) {
|
|||
<DescriptionListItem
|
||||
titleClassName={styles.title}
|
||||
descriptionClassName={styles.description}
|
||||
title="Release"
|
||||
title={translate('Release')}
|
||||
data={releaseNumber ?? 'unknown'}
|
||||
/>
|
||||
)}
|
||||
|
@ -183,7 +194,7 @@ function ReleaseSceneIndicator(props: ReleaseSceneIndicatorProps) {
|
|||
<DescriptionListItem
|
||||
titleClassName={styles.title}
|
||||
descriptionClassName={styles.description}
|
||||
title="TheTVDB"
|
||||
title={translate('TheTvdb')}
|
||||
data={mappedNumber ?? 'unknown'}
|
||||
/>
|
||||
)}
|
||||
|
@ -197,7 +208,7 @@ function ReleaseSceneIndicator(props: ReleaseSceneIndicatorProps) {
|
|||
<Icon name={icons.SCENE_MAPPING} />
|
||||
</div>
|
||||
}
|
||||
title="Scene Info"
|
||||
title={translate('SceneInfo')}
|
||||
body={
|
||||
<div>
|
||||
{table}
|
||||
|
|
|
@ -48,7 +48,9 @@
|
|||
"AddRemotePathMappingError": "Unable to add a new remote path mapping, please try again.",
|
||||
"AddRootFolder": "Add Root Folder",
|
||||
"AddSeriesWithTitle": "Add {title}",
|
||||
"AddToDownloadQueue": "Add to download queue",
|
||||
"Added": "Added",
|
||||
"AddedToDownloadQueue": "Added to download queue",
|
||||
"AddingTag": "Adding tag",
|
||||
"AfterManualRefresh": "After Manual Refresh",
|
||||
"Age": "Age",
|
||||
|
@ -241,6 +243,7 @@
|
|||
"Dates": "Dates",
|
||||
"Day": "Day",
|
||||
"Debug": "Debug",
|
||||
"Default": "Default",
|
||||
"DefaultCase": "Default Case",
|
||||
"DefaultDelayProfile": "This is the default profile. It applies to all series that don't have an explicit profile.",
|
||||
"DefaultNotFoundMessage": "You must be lost, nothing to see here.",
|
||||
|
@ -494,7 +497,10 @@
|
|||
"GeneralSettingsSummary": "Port, SSL, username/password, proxy, analytics and updates",
|
||||
"Genres": "Genres",
|
||||
"Global": "Global",
|
||||
"Grab": "Grab",
|
||||
"GrabId": "Grab ID",
|
||||
"GrabRelease": "GrabRelease",
|
||||
"GrabReleaseMessageText": "Sonarr was unable to determine which series and episode this release was for. Sonarr may be unable to automatically import this release. Do you want to grab '{title}'?",
|
||||
"GrabSelected": "Grab Selected",
|
||||
"Grabbed": "Grabbed",
|
||||
"GrabbedHistoryTooltip": "Episode grabbed from {indexer} and sent to {downloadClient}",
|
||||
|
@ -602,6 +608,7 @@
|
|||
"InteractiveImportNoSeason": "Season must be chosen for each selected file",
|
||||
"InteractiveImportNoSeries": "Series must be chosen for each selected file",
|
||||
"InteractiveSearch": "Interactive Search",
|
||||
"InteractiveSearchResultsFailedErrorMessage": "Search failed because its {message}. Try refreshing the series info and verify the necessary information is present before searching again.",
|
||||
"Interval": "Interval",
|
||||
"InvalidFormat": "Invalid Format",
|
||||
"KeyboardShortcuts": "Keyboard Shortcuts",
|
||||
|
@ -653,9 +660,11 @@
|
|||
"ManageIndexers": "Manage Indexers",
|
||||
"ManageLists": "Manage Lists",
|
||||
"Manual": "Manual",
|
||||
"ManualGrab": "Manual Grab",
|
||||
"ManualImport": "Manual Import",
|
||||
"ManualImportItemsLoadError": "Unable to load manual import items",
|
||||
"MappedNetworkDrivesWindowsService": "Mapped network drives are not available when running as a Windows Service, see the [FAQ](https://wiki.servarr.com/sonarr/faq#why-cant-sonarr-see-my-files-on-a-remote-server) for more information.",
|
||||
"Mapping": "Mapping",
|
||||
"MarkAsFailed": "Mark as Failed",
|
||||
"MarkAsFailedConfirmation": "Are you sure you want to mark '{sourceTitle}' as failed?",
|
||||
"MatchedToEpisodes": "Matched to Episodes",
|
||||
|
@ -811,6 +820,12 @@
|
|||
"OriginalLanguage": "Original Language",
|
||||
"Other": "Other",
|
||||
"OutputPath": "Output Path",
|
||||
"OverrideAndAddToDownloadQueue": "Override and add to download queue",
|
||||
"OverrideGrabModalTitle": "Override and Grab - {title}",
|
||||
"OverrideGrabNoEpisode": "At least one episode must be selected",
|
||||
"OverrideGrabNoLanguage": "At least one language must be selected",
|
||||
"OverrideGrabNoQuality": "Quality must be selected",
|
||||
"OverrideGrabNoSeries": "Series must be selected",
|
||||
"PackageVersion": "Package Version",
|
||||
"PackageVersionInfo": "{packageVersion} by {packageAuthor}",
|
||||
"PartialSeason": "Partial Season",
|
||||
|
@ -907,6 +922,12 @@
|
|||
"ReleaseProfiles": "Release Profiles",
|
||||
"ReleaseProfilesLoadError": "Unable to load Release Profiles",
|
||||
"ReleaseRejected": "Release Rejected",
|
||||
"ReleaseSceneIndicatorAssumingScene": "Assuming Scene numbering.",
|
||||
"ReleaseSceneIndicatorAssumingTvdb": "Assuming TVDB numbering.",
|
||||
"ReleaseSceneIndicatorMappedNotRequested": "Mapped episode wasn't requested in this search.",
|
||||
"ReleaseSceneIndicatorSourceMessage": "{message} releases exist with ambiguous numbering, unable to reliably identify episode.",
|
||||
"ReleaseSceneIndicatorUnknownMessage": "Numbering varies for this episode and release does not match any known mappings.",
|
||||
"ReleaseSceneIndicatorUnknownSeries": "Unknown episode or series.",
|
||||
"ReleaseTitle": "Release Title",
|
||||
"Reload": "Reload",
|
||||
"RemotePath": "Remote Path",
|
||||
|
@ -1017,6 +1038,7 @@
|
|||
"SaveChanges": "Save Changes",
|
||||
"SaveSettings": "Save Settings",
|
||||
"Scene": "Scene",
|
||||
"SceneInfo": "Scene Info",
|
||||
"SceneInformation": "Scene Information",
|
||||
"SceneNumberNotVerified": "Scene number hasn't been verified yet",
|
||||
"SceneNumbering": "Scene Numbering",
|
||||
|
@ -1044,6 +1066,7 @@
|
|||
"Seasons": "Seasons",
|
||||
"Security": "Security",
|
||||
"Seeders": "Seeders",
|
||||
"SelectDownloadClientModalTitle": "{modalTitle} - Select Download Client",
|
||||
"SelectDropdown": "Select...",
|
||||
"SelectEpisodes": "Select Episode(s)",
|
||||
"SelectEpisodesModalTitle": "{modalTitle} - Select Episode(s)",
|
||||
|
|
Loading…
Reference in New Issue