Translate frontend/AddSeries

This commit is contained in:
Stevie Robinson 2023-08-04 14:16:29 +02:00 committed by Mark McDowall
parent f6c05d4456
commit 02b0710814
13 changed files with 161 additions and 94 deletions

View File

@ -9,6 +9,7 @@ import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody'; import PageContentBody from 'Components/Page/PageContentBody';
import { icons, kinds } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import getErrorMessage from 'Utilities/Object/getErrorMessage'; import getErrorMessage from 'Utilities/Object/getErrorMessage';
import translate from 'Utilities/String/translate';
import AddNewSeriesSearchResultConnector from './AddNewSeriesSearchResultConnector'; import AddNewSeriesSearchResultConnector from './AddNewSeriesSearchResultConnector';
import styles from './AddNewSeries.css'; import styles from './AddNewSeries.css';
@ -87,7 +88,7 @@ class AddNewSeries extends Component {
const isFetching = this.state.isFetching; const isFetching = this.state.isFetching;
return ( return (
<PageContent title="Add New Series"> <PageContent title={translate('AddNewSeries')}>
<PageContentBody> <PageContentBody>
<div className={styles.searchContainer}> <div className={styles.searchContainer}>
<div className={styles.searchIconContainer}> <div className={styles.searchIconContainer}>
@ -126,7 +127,7 @@ class AddNewSeries extends Component {
!isFetching && !!error ? !isFetching && !!error ?
<div className={styles.message}> <div className={styles.message}>
<div className={styles.helpText}> <div className={styles.helpText}>
Failed to load search results, please try again. {translate('AddNewSeriesError')}
</div> </div>
<div>{getErrorMessage(error)}</div> <div>{getErrorMessage(error)}</div>
</div> : null </div> : null
@ -151,11 +152,11 @@ class AddNewSeries extends Component {
{ {
!isFetching && !error && !items.length && !!term && !isFetching && !error && !items.length && !!term &&
<div className={styles.message}> <div className={styles.message}>
<div className={styles.noResults}>Couldn't find any results for '{term}'</div> <div className={styles.noResults}>{translate('CouldNotFindResults', { term })}</div>
<div>You can also search using TVDB ID of a show. eg. tvdb:71663</div> <div>{translate('SearchByTvdbId')}</div>
<div> <div>
<Link to="https://wiki.servarr.com/sonarr/faq#why-cant-i-add-a-new-series-when-i-know-the-tvdb-id"> <Link to="https://wiki.servarr.com/sonarr/faq#why-cant-i-add-a-new-series-when-i-know-the-tvdb-id">
Why can't I find my show? {translate('WhyCantIFindMyShow')}
</Link> </Link>
</div> </div>
</div> </div>
@ -166,9 +167,9 @@ class AddNewSeries extends Component {
null : null :
<div className={styles.message}> <div className={styles.message}>
<div className={styles.helpText}> <div className={styles.helpText}>
It's easy to add a new series, just start typing the name the series you want to add. {translate('AddNewSeriesHelpText')}
</div> </div>
<div>You can also search using TVDB ID of a show. eg. tvdb:71663</div> <div>{translate('SearchByTvdbId')}</div>
</div> </div>
} }
@ -176,14 +177,14 @@ class AddNewSeries extends Component {
!term && !hasExistingSeries ? !term && !hasExistingSeries ?
<div className={styles.message}> <div className={styles.message}>
<div className={styles.noSeriesText}> <div className={styles.noSeriesText}>
You haven't added any series yet, do you want to import some or all of your series first? {translate('NoSeriesHaveBeenAdded')}
</div> </div>
<div> <div>
<Button <Button
to="/add/import" to="/add/import"
kind={kinds.PRIMARY} kind={kinds.PRIMARY}
> >
Import Existing Series {translate('ImportExistingSeries')}
</Button> </Button>
</div> </div>
</div> : </div> :

View File

@ -120,7 +120,7 @@ class AddNewSeriesModalContent extends Component {
<Form {...otherProps}> <Form {...otherProps}>
<FormGroup> <FormGroup>
<FormLabel>Root Folder</FormLabel> <FormLabel>{translate('RootFolder')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.ROOT_FOLDER_SELECT} type={inputTypes.ROOT_FOLDER_SELECT}
@ -133,7 +133,7 @@ class AddNewSeriesModalContent extends Component {
seriesFolder: folder, seriesFolder: folder,
isWindows isWindows
}} }}
helpText={`'${folder}' subfolder will be created automatically`} helpText={translate('AddNewSeriesRootFolderHelpText', { folder })}
onChange={onInputChange} onChange={onInputChange}
{...rootFolderPath} {...rootFolderPath}
/> />
@ -141,7 +141,7 @@ class AddNewSeriesModalContent extends Component {
<FormGroup> <FormGroup>
<FormLabel> <FormLabel>
Monitor {translate('Monitor')}
<Popover <Popover
anchor={ anchor={
@ -150,7 +150,7 @@ class AddNewSeriesModalContent extends Component {
name={icons.INFO} name={icons.INFO}
/> />
} }
title="Monitoring Options" title={translate('MonitoringOptions')}
body={<SeriesMonitoringOptionsPopoverContent />} body={<SeriesMonitoringOptionsPopoverContent />}
position={tooltipPositions.RIGHT} position={tooltipPositions.RIGHT}
/> />
@ -165,7 +165,7 @@ class AddNewSeriesModalContent extends Component {
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Quality Profile</FormLabel> <FormLabel>{translate('QualityProfile')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.QUALITY_PROFILE_SELECT} type={inputTypes.QUALITY_PROFILE_SELECT}
@ -177,7 +177,7 @@ class AddNewSeriesModalContent extends Component {
<FormGroup> <FormGroup>
<FormLabel> <FormLabel>
Series Type {translate('SeriesType')}
<Popover <Popover
anchor={ anchor={
@ -186,7 +186,7 @@ class AddNewSeriesModalContent extends Component {
name={icons.INFO} name={icons.INFO}
/> />
} }
title="Series Types" title={translate('SeriesTypes')}
body={<SeriesTypePopoverContent />} body={<SeriesTypePopoverContent />}
position={tooltipPositions.RIGHT} position={tooltipPositions.RIGHT}
/> />
@ -198,14 +198,12 @@ class AddNewSeriesModalContent extends Component {
onChange={onInputChange} onChange={onInputChange}
{...seriesType} {...seriesType}
value={this.state.seriesType} value={this.state.seriesType}
helpText={translate( helpText={translate('SeriesTypesHelpText')}
'Series type is used for renaming, parsing and searching'
)}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Season Folder</FormLabel> <FormLabel>{translate('SeasonFolder')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
@ -216,7 +214,7 @@ class AddNewSeriesModalContent extends Component {
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Tags</FormLabel> <FormLabel>{translate('Tags')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.TAG} type={inputTypes.TAG}
@ -234,7 +232,7 @@ class AddNewSeriesModalContent extends Component {
<div> <div>
<label className={styles.searchLabelContainer}> <label className={styles.searchLabelContainer}>
<span className={styles.searchLabel}> <span className={styles.searchLabel}>
Start search for missing episodes {translate('AddNewSeriesSearchForMissingEpisodes')}
</span> </span>
<CheckInput <CheckInput
@ -248,7 +246,7 @@ class AddNewSeriesModalContent extends Component {
<label className={styles.searchLabelContainer}> <label className={styles.searchLabelContainer}>
<span className={styles.searchLabel}> <span className={styles.searchLabel}>
Start search for cutoff unmet episodes {translate('AddNewSeriesSearchForCutoffUnmetEpisodes')}
</span> </span>
<CheckInput <CheckInput
@ -267,7 +265,7 @@ class AddNewSeriesModalContent extends Component {
isSpinning={isAdding} isSpinning={isAdding}
onPress={this.onAddSeriesPress} onPress={this.onAddSeriesPress}
> >
Add {title} {translate('AddSeriesWithTitle', { title })}
</SpinnerButton> </SpinnerButton>
</ModalFooter> </ModalFooter>
</ModalContent> </ModalContent>

View File

@ -7,6 +7,7 @@ import Link from 'Components/Link/Link';
import MetadataAttribution from 'Components/MetadataAttribution'; import MetadataAttribution from 'Components/MetadataAttribution';
import { icons, kinds, sizes } from 'Helpers/Props'; import { icons, kinds, sizes } from 'Helpers/Props';
import SeriesPoster from 'Series/SeriesPoster'; import SeriesPoster from 'Series/SeriesPoster';
import translate from 'Utilities/String/translate';
import AddNewSeriesModal from './AddNewSeriesModal'; import AddNewSeriesModal from './AddNewSeriesModal';
import styles from './AddNewSeriesSearchResult.css'; import styles from './AddNewSeriesSearchResult.css';
@ -72,10 +73,10 @@ class AddNewSeriesSearchResult extends Component {
} = this.state; } = this.state;
const linkProps = isExistingSeries ? { to: `/series/${titleSlug}` } : { onPress: this.onPress }; const linkProps = isExistingSeries ? { to: `/series/${titleSlug}` } : { onPress: this.onPress };
let seasons = '1 Season'; let seasons = translate('OneSeason');
if (seasonCount > 1) { if (seasonCount > 1) {
seasons = `${seasonCount} Seasons`; seasons = translate('CountSeasons', { count: seasonCount });
} }
return ( return (
@ -121,14 +122,14 @@ class AddNewSeriesSearchResult extends Component {
className={styles.alreadyExistsIcon} className={styles.alreadyExistsIcon}
name={icons.CHECK_CIRCLE} name={icons.CHECK_CIRCLE}
size={36} size={36}
title="Already in your library" title={translate('AlreadyInYourLibrary')}
/> : /> :
null null
} }
<Link <Link
className={styles.tvdbLink} className={styles.tvdbLink}
to={`http://www.thetvdb.com/?tab=series&id=${tvdbId}`} to={`https://www.thetvdb.com/?tab=series&id=${tvdbId}`}
onPress={this.onTVDBLinkPress} onPress={this.onTVDBLinkPress}
> >
<Icon <Icon
@ -170,7 +171,7 @@ class AddNewSeriesSearchResult extends Component {
kind={kinds.DANGER} kind={kinds.DANGER}
size={sizes.LARGE} size={sizes.LARGE}
> >
Ended {translate('Ended')}
</Label> : </Label> :
null null
} }
@ -181,7 +182,7 @@ class AddNewSeriesSearchResult extends Component {
kind={kinds.INFO} kind={kinds.INFO}
size={sizes.LARGE} size={sizes.LARGE}
> >
Upcoming {translate('Upcoming')}
</Label> : </Label> :
null null
} }

View File

@ -6,6 +6,7 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody'; import PageContentBody from 'Components/Page/PageContentBody';
import { kinds } from 'Helpers/Props'; import { kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import selectAll from 'Utilities/Table/selectAll'; import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected'; import toggleSelected from 'Utilities/Table/toggleSelected';
import ImportSeriesFooterConnector from './ImportSeriesFooterConnector'; import ImportSeriesFooterConnector from './ImportSeriesFooterConnector';
@ -97,7 +98,7 @@ class ImportSeries extends Component {
} = this.state; } = this.state;
return ( return (
<PageContent title="Import Series"> <PageContent title={translate('ImportSeries')}>
<PageContentBody ref={this.scrollerRef} > <PageContentBody ref={this.scrollerRef} >
{ {
rootFoldersFetching ? <LoadingIndicator /> : null rootFoldersFetching ? <LoadingIndicator /> : null
@ -106,7 +107,7 @@ class ImportSeries extends Component {
{ {
!rootFoldersFetching && !!rootFoldersError ? !rootFoldersFetching && !!rootFoldersError ?
<Alert kind={kinds.DANGER}> <Alert kind={kinds.DANGER}>
Unable to load root folders {translate('RootFoldersLoadError')}
</Alert> : </Alert> :
null null
} }
@ -117,7 +118,7 @@ class ImportSeries extends Component {
rootFoldersPopulated && rootFoldersPopulated &&
!unmappedFolders.length ? !unmappedFolders.length ?
<Alert kind={kinds.INFO}> <Alert kind={kinds.INFO}>
All series in {path} have been imported {translate('AllSeriesInRootFolderHaveBeenImported', { path })}
</Alert> : </Alert> :
null null
} }

View File

@ -10,6 +10,7 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContentFooter from 'Components/Page/PageContentFooter'; import PageContentFooter from 'Components/Page/PageContentFooter';
import Popover from 'Components/Tooltip/Popover'; import Popover from 'Components/Tooltip/Popover';
import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props'; import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './ImportSeriesFooter.css'; import styles from './ImportSeriesFooter.css';
const MIXED = 'mixed'; const MIXED = 'mixed';
@ -124,7 +125,7 @@ class ImportSeriesFooter extends Component {
<PageContentFooter> <PageContentFooter>
<div className={styles.inputContainer}> <div className={styles.inputContainer}>
<div className={styles.label}> <div className={styles.label}>
Monitor {translate('Monitor')}
</div> </div>
<FormInputGroup <FormInputGroup
@ -139,7 +140,7 @@ class ImportSeriesFooter extends Component {
<div className={styles.inputContainer}> <div className={styles.inputContainer}>
<div className={styles.label}> <div className={styles.label}>
Quality Profile {translate('QualityProfile')}
</div> </div>
<FormInputGroup <FormInputGroup
@ -154,7 +155,7 @@ class ImportSeriesFooter extends Component {
<div className={styles.inputContainer}> <div className={styles.inputContainer}>
<div className={styles.label}> <div className={styles.label}>
Series Type {translate('SeriesType')}
</div> </div>
<FormInputGroup <FormInputGroup
@ -169,7 +170,7 @@ class ImportSeriesFooter extends Component {
<div className={styles.inputContainer}> <div className={styles.inputContainer}>
<div className={styles.label}> <div className={styles.label}>
Season Folder {translate('SeasonFolder')}
</div> </div>
<CheckInput <CheckInput
@ -193,7 +194,7 @@ class ImportSeriesFooter extends Component {
isDisabled={!selectedCount || isLookingUpSeries} isDisabled={!selectedCount || isLookingUpSeries}
onPress={onImportPress} onPress={onImportPress}
> >
Import {selectedCount} Series {translate('ImportCountSeries', { selectedCount })}
</SpinnerButton> </SpinnerButton>
{ {
@ -203,7 +204,7 @@ class ImportSeriesFooter extends Component {
kind={kinds.WARNING} kind={kinds.WARNING}
onPress={onCancelLookupPress} onPress={onCancelLookupPress}
> >
Cancel Processing {translate('CancelProcessing')}
</Button> : </Button> :
null null
} }
@ -215,7 +216,7 @@ class ImportSeriesFooter extends Component {
kind={kinds.SUCCESS} kind={kinds.SUCCESS}
onPress={onLookupPress} onPress={onLookupPress}
> >
Start Processing {translate('StartProcessing')}
</Button> : </Button> :
null null
} }
@ -231,7 +232,7 @@ class ImportSeriesFooter extends Component {
{ {
isLookingUpSeries ? isLookingUpSeries ?
'Processing Folders' : translate('ProcessingFolders') :
null null
} }
@ -245,7 +246,7 @@ class ImportSeriesFooter extends Component {
kind={kinds.WARNING} kind={kinds.WARNING}
/> />
} }
title="Import Errors" title={translate('ImportErrors')}
body={ body={
<ul> <ul>
{ {

View File

@ -8,6 +8,7 @@ import VirtualTableHeaderCell from 'Components/Table/VirtualTableHeaderCell';
import VirtualTableSelectAllHeaderCell from 'Components/Table/VirtualTableSelectAllHeaderCell'; import VirtualTableSelectAllHeaderCell from 'Components/Table/VirtualTableSelectAllHeaderCell';
import Popover from 'Components/Tooltip/Popover'; import Popover from 'Components/Tooltip/Popover';
import { icons, tooltipPositions } from 'Helpers/Props'; import { icons, tooltipPositions } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './ImportSeriesHeader.css'; import styles from './ImportSeriesHeader.css';
function ImportSeriesHeader(props) { function ImportSeriesHeader(props) {
@ -29,14 +30,14 @@ function ImportSeriesHeader(props) {
className={styles.folder} className={styles.folder}
name="folder" name="folder"
> >
Folder {translate('Folder')}
</VirtualTableHeaderCell> </VirtualTableHeaderCell>
<VirtualTableHeaderCell <VirtualTableHeaderCell
className={styles.monitor} className={styles.monitor}
name="monitor" name="monitor"
> >
Monitor {translate('Monitor')}
<Popover <Popover
anchor={ anchor={
@ -45,7 +46,7 @@ function ImportSeriesHeader(props) {
name={icons.INFO} name={icons.INFO}
/> />
} }
title="Monitoring Options" title={translate('MonitoringOptions')}
body={<SeriesMonitoringOptionsPopoverContent />} body={<SeriesMonitoringOptionsPopoverContent />}
position={tooltipPositions.RIGHT} position={tooltipPositions.RIGHT}
/> />
@ -55,14 +56,14 @@ function ImportSeriesHeader(props) {
className={styles.qualityProfile} className={styles.qualityProfile}
name="qualityProfileId" name="qualityProfileId"
> >
Quality Profile {translate('QualityProfile')}
</VirtualTableHeaderCell> </VirtualTableHeaderCell>
<VirtualTableHeaderCell <VirtualTableHeaderCell
className={styles.seriesType} className={styles.seriesType}
name="seriesType" name="seriesType"
> >
Series Type {translate('SeriesType')}
<Popover <Popover
anchor={ anchor={
@ -71,7 +72,7 @@ function ImportSeriesHeader(props) {
name={icons.INFO} name={icons.INFO}
/> />
} }
title="Series Type" title={translate('SeriesType')}
body={<SeriesTypePopoverContent />} body={<SeriesTypePopoverContent />}
position={tooltipPositions.RIGHT} position={tooltipPositions.RIGHT}
/> />
@ -81,14 +82,14 @@ function ImportSeriesHeader(props) {
className={styles.seasonFolder} className={styles.seasonFolder}
name="seasonFolder" name="seasonFolder"
> >
Season Folder {translate('SeasonFolder')}
</VirtualTableHeaderCell> </VirtualTableHeaderCell>
<VirtualTableHeaderCell <VirtualTableHeaderCell
className={styles.series} className={styles.series}
name="series" name="series"
> >
Series {translate('Series')}
</VirtualTableHeaderCell> </VirtualTableHeaderCell>
</VirtualTableHeader> </VirtualTableHeader>
); );

View File

@ -34,7 +34,7 @@ function ImportSeriesSearchResult(props) {
<Link <Link
className={styles.tvdbLink} className={styles.tvdbLink}
to={`http://www.thetvdb.com/?tab=series&id=${tvdbId}`} to={`https://www.thetvdb.com/?tab=series&id=${tvdbId}`}
> >
<Icon <Icon
className={styles.tvdbLinkIcon} className={styles.tvdbLinkIcon}

View File

@ -8,7 +8,8 @@ import Link from 'Components/Link/Link';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Portal from 'Components/Portal'; import Portal from 'Components/Portal';
import { icons, kinds } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import getUniqueElememtId from 'Utilities/getUniqueElementId'; import getUniqueElementId from 'Utilities/getUniqueElementId';
import translate from 'Utilities/String/translate';
import ImportSeriesSearchResultConnector from './ImportSeriesSearchResultConnector'; import ImportSeriesSearchResultConnector from './ImportSeriesSearchResultConnector';
import ImportSeriesTitle from './ImportSeriesTitle'; import ImportSeriesTitle from './ImportSeriesTitle';
import styles from './ImportSeriesSelectSeries.css'; import styles from './ImportSeriesSelectSeries.css';
@ -23,8 +24,8 @@ class ImportSeriesSelectSeries extends Component {
this._seriesLookupTimeout = null; this._seriesLookupTimeout = null;
this._scheduleUpdate = null; this._scheduleUpdate = null;
this._buttonId = getUniqueElememtId(); this._buttonId = getUniqueElementId();
this._contentId = getUniqueElememtId(); this._contentId = getUniqueElementId();
this.state = { this.state = {
term: props.id, term: props.id,
@ -174,7 +175,7 @@ class ImportSeriesSelectSeries extends Component {
kind={kinds.WARNING} kind={kinds.WARNING}
/> />
No match found! {translate('NoMatchFound')}
</div> : </div> :
null null
} }
@ -189,7 +190,7 @@ class ImportSeriesSelectSeries extends Component {
kind={kinds.WARNING} kind={kinds.WARNING}
/> />
Search failed, please try again later. {translate('SearchFailedError')}
</div> : </div> :
null null
} }

View File

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import Label from 'Components/Label'; import Label from 'Components/Label';
import { kinds } from 'Helpers/Props'; import { kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './ImportSeriesTitle.css'; import styles from './ImportSeriesTitle.css';
function ImportSeriesTitle(props) { function ImportSeriesTitle(props) {
@ -38,7 +39,7 @@ function ImportSeriesTitle(props) {
<Label <Label
kind={kinds.WARNING} kind={kinds.WARNING}
> >
Existing {translate('Existing')}
</Label> : </Label> :
null null
} }

View File

@ -6,10 +6,12 @@ import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal';
import Icon from 'Components/Icon'; import Icon from 'Components/Icon';
import Button from 'Components/Link/Button'; import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import InlineMarkdown from 'Components/Markdown/InlineMarkdown';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody'; import PageContentBody from 'Components/Page/PageContentBody';
import { icons, kinds, sizes } from 'Helpers/Props'; import { icons, kinds, sizes } from 'Helpers/Props';
import RootFolders from 'RootFolder/RootFolders'; import RootFolders from 'RootFolder/RootFolders';
import translate from 'Utilities/String/translate';
import styles from './ImportSeriesSelectFolder.css'; import styles from './ImportSeriesSelectFolder.css';
class ImportSeriesSelectFolder extends Component { class ImportSeriesSelectFolder extends Component {
@ -55,9 +57,11 @@ class ImportSeriesSelectFolder extends Component {
} = this.props; } = this.props;
const hasRootFolders = items.length > 0; const hasRootFolders = items.length > 0;
const goodFolderExample = (isWindows) ? 'C:\\tv shows' : '/tv shows';
const badFolderExample = (isWindows) ? 'C:\\tv shows\\the simpsons' : '/tv shows/the simpsons';
return ( return (
<PageContent title="Import Series"> <PageContent title={translate('ImportSeries')}>
<PageContentBody> <PageContentBody>
{ {
isFetching && !isPopulated ? isFetching && !isPopulated ?
@ -67,7 +71,7 @@ class ImportSeriesSelectFolder extends Component {
{ {
!isFetching && error ? !isFetching && error ?
<Alert kind={kinds.DANGER}>Unable to load root folders</Alert> : <Alert kind={kinds.DANGER}>{translate('RootFoldersLoadError')}</Alert> :
null null
} }
@ -75,20 +79,20 @@ class ImportSeriesSelectFolder extends Component {
!error && isPopulated && !error && isPopulated &&
<div> <div>
<div className={styles.header}> <div className={styles.header}>
Import series you already have {translate('LibraryImportHeader')}
</div> </div>
<div className={styles.tips}> <div className={styles.tips}>
Some tips to ensure the import goes smoothly: {translate('LibraryImportTips')}
<ul> <ul>
<li className={styles.tip}> <li className={styles.tip}>
Make sure that your files include the quality in their filenames. eg. <span className={styles.code}>episode.s02e15.bluray.mkv</span> <InlineMarkdown data={translate('LibraryImportTipsQualityInFilename')} />
</li> </li>
<li className={styles.tip}> <li className={styles.tip}>
Point Sonarr to the folder containing all of your tv shows, not a specific one. eg. <span className={styles.code}>"{isWindows ? 'C:\\tv shows' : '/tv shows'}"</span> and not <span className={styles.code}>"{isWindows ? 'C:\\tv shows\\the simpsons' : '/tv shows/the simpsons'}"</span> Additionally, each series must be in its own folder within the root/library folder. <InlineMarkdown data={translate('LibraryImportTipsUseRootFolder', { goodFolderExample, badFolderExample })} />
</li> </li>
<li className={styles.tip}> <li className={styles.tip}>
Do not use for importing downloads from your download client, this is only for existing organized libraries, not unsorted files. {translate('LibraryImportTipsDontUseDownloadsFolder')}
</li> </li>
</ul> </ul>
</div> </div>
@ -96,7 +100,7 @@ class ImportSeriesSelectFolder extends Component {
{ {
hasRootFolders ? hasRootFolders ?
<div className={styles.recentFolders}> <div className={styles.recentFolders}>
<FieldSet legend="Root Folders"> <FieldSet legend={translate('RootFolders')}>
<RootFolders <RootFolders
isFetching={isFetching} isFetching={isFetching}
isPopulated={isPopulated} isPopulated={isPopulated}
@ -114,7 +118,7 @@ class ImportSeriesSelectFolder extends Component {
className={styles.addErrorAlert} className={styles.addErrorAlert}
kind={kinds.DANGER} kind={kinds.DANGER}
> >
Unable to add root folder {translate('RootFolderLoadError')}
<ul> <ul>
{ {
@ -149,8 +153,8 @@ class ImportSeriesSelectFolder extends Component {
/> />
{ {
hasRootFolders ? hasRootFolders ?
'Choose another folder' : translate('ChooseAnotherFolder') :
'Start Import' translate('StartImport')
} }
</Button> </Button>
</div> </div>

View File

@ -1,53 +1,54 @@
import React from 'react'; import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList'; import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import translate from 'Utilities/String/translate';
function SeriesMonitoringOptionsPopoverContent() { function SeriesMonitoringOptionsPopoverContent() {
return ( return (
<DescriptionList> <DescriptionList>
<DescriptionListItem <DescriptionListItem
title="All Episodes" title={translate('MonitorAllEpisodes')}
data="Monitor all episodes except specials" data={translate('MonitorAllEpisodesDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="Future Episodes" title={translate('MonitorFutureEpisodes')}
data="Monitor episodes that have not aired yet" data={translate('MonitorFutureEpisodesDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="Missing Episodes" title={translate('MonitorMissingEpisodes')}
data="Monitor episodes that do not have files or have not aired yet" data={translate('MonitorMissingEpisodesDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="Existing Episodes" title={translate('MonitorExistingEpisodes')}
data="Monitor episodes that have files or have not aired yet" data={translate('MonitorExistingEpisodesDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="First Season" title={translate('MonitorFirstSeason')}
data="Monitor all episodes of the first season. All other seasons will be ignored" data={translate('MonitorFirstSeasonDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="Latest Season" title={translate('MonitorLatestSeason')}
data="Monitor all episodes of the latest season and future seasons" data={translate('MonitorLatestSeasonDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="Monitor Specials" title={translate('MonitorSpecials')}
data="Monitor all special episodes without changing the monitored status of other episodes" data={translate('MonitorSpecialsDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="Unmonitor Specials" title={translate('UnmonitorSpecials')}
data="Unmonitor all special episodes without changing the monitored status of other episodes" data={translate('UnmonitorSpecialsDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="None" title={translate('MonitorNone')}
data="No episodes will be monitored" data={translate('MonitorNoneDescription')}
/> />
</DescriptionList> </DescriptionList>
); );

View File

@ -1,23 +1,24 @@
import React from 'react'; import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList'; import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import translate from 'Utilities/String/translate';
function SeriesTypePopoverContent() { function SeriesTypePopoverContent() {
return ( return (
<DescriptionList> <DescriptionList>
<DescriptionListItem <DescriptionListItem
title="Anime" title={translate('Anime')}
data="Episodes released using an absolute episode number" data={translate('AnimeTypeDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="Daily" title={translate('Daily')}
data="Episodes released daily or less frequently that use year-month-day (2017-05-25)" data={translate('DailyTypeDescription')}
/> />
<DescriptionListItem <DescriptionListItem
title="Standard" title={translate('Standard')}
data="Episodes released with SxxEyy pattern" data={translate('StandardTypeDescription')}
/> />
</DescriptionList> </DescriptionList>
); );

View File

@ -26,6 +26,12 @@
"AddListExclusionError": "Unable to add a new list exclusion, please try again.", "AddListExclusionError": "Unable to add a new list exclusion, please try again.",
"AddNew": "Add New", "AddNew": "Add New",
"AddNewRestriction": "Add new restriction", "AddNewRestriction": "Add new restriction",
"AddNewSeries": "Add New Series",
"AddNewSeriesError": "Failed to load search results, please try again.",
"AddNewSeriesHelpText": "It's easy to add a new series, just start typing the name the series you want to add.",
"AddNewSeriesRootFolderHelpText": "'{folder}' subfolder will be created automatically",
"AddNewSeriesSearchForCutoffUnmetEpisodes": "Start search for cutoff unmet episodes",
"AddNewSeriesSearchForMissingEpisodes": "Start search for missing episodes",
"AddNotification": "Add Notification", "AddNotification": "Add Notification",
"AddNotificationError": "Unable to add a new notification, please try again.", "AddNotificationError": "Unable to add a new notification, please try again.",
"AddQualityProfile": "Add Quality Profile", "AddQualityProfile": "Add Quality Profile",
@ -34,6 +40,7 @@
"AddRemotePathMapping": "Add Remote Path Mapping", "AddRemotePathMapping": "Add Remote Path Mapping",
"AddRemotePathMappingError": "Unable to add a new remote path mapping, please try again.", "AddRemotePathMappingError": "Unable to add a new remote path mapping, please try again.",
"AddRootFolder": "Add Root Folder", "AddRootFolder": "Add Root Folder",
"AddSeriesWithTitle": "Add {title}",
"Added": "Added", "Added": "Added",
"AddingTag": "Adding tag", "AddingTag": "Adding tag",
"AfterManualRefresh": "After Manual Refresh", "AfterManualRefresh": "After Manual Refresh",
@ -41,13 +48,17 @@
"AirDate": "Air Date", "AirDate": "Air Date",
"All": "All", "All": "All",
"AllResultsAreHiddenByTheAppliedFilter": "All results are hidden by the applied filter", "AllResultsAreHiddenByTheAppliedFilter": "All results are hidden by the applied filter",
"AllSeriesInRootFolderHaveBeenImported": "All series in {path} have been imported",
"AllTitles": "All Titles", "AllTitles": "All Titles",
"AlreadyInYourLibrary": "Already in your library",
"Always": "Always", "Always": "Always",
"AnalyseVideoFiles": "Analyse video files", "AnalyseVideoFiles": "Analyse video files",
"AnalyseVideoFilesHelpText": "Extract video information such as resolution, runtime and codec information from files. This requires Sonarr to read parts of the file which may cause high disk or network activity during scans.", "AnalyseVideoFilesHelpText": "Extract video information such as resolution, runtime and codec information from files. This requires Sonarr to read parts of the file which may cause high disk or network activity during scans.",
"Analytics": "Analytics", "Analytics": "Analytics",
"AnalyticsEnabledHelpText": "Send anonymous usage and error information to Sonarr's servers. This includes information on your browser, which Sonarr WebUI pages you use, error reporting as well as OS and runtime version. We will use this information to prioritize features and bug fixes.", "AnalyticsEnabledHelpText": "Send anonymous usage and error information to Sonarr's servers. This includes information on your browser, which Sonarr WebUI pages you use, error reporting as well as OS and runtime version. We will use this information to prioritize features and bug fixes.",
"Anime": "Anime",
"AnimeEpisodeFormat": "Anime Episode Format", "AnimeEpisodeFormat": "Anime Episode Format",
"AnimeTypeDescription": "Episodes released using an absolute episode number",
"ApiKey": "API Key", "ApiKey": "API Key",
"ApiKeyValidationHealthCheckMessage": "Please update your API key to be at least {0} characters long. You can do this via settings or the config file", "ApiKeyValidationHealthCheckMessage": "Please update your API key to be at least {0} characters long. You can do this via settings or the config file",
"AppDataDirectory": "AppData directory", "AppDataDirectory": "AppData directory",
@ -114,6 +125,7 @@
"CalendarLoadError": "Unable to load the calendar", "CalendarLoadError": "Unable to load the calendar",
"Cancel": "Cancel", "Cancel": "Cancel",
"CancelPendingTask": "Are you sure you want to cancel this pending task?", "CancelPendingTask": "Are you sure you want to cancel this pending task?",
"CancelProcessing": "Cancel Processing",
"CertificateValidation": "Certificate Validation", "CertificateValidation": "Certificate Validation",
"CertificateValidationHelpText": "Change how strict HTTPS certification validation is. Do not change unless you understand the risks.", "CertificateValidationHelpText": "Change how strict HTTPS certification validation is. Do not change unless you understand the risks.",
"Certification": "Certification", "Certification": "Certification",
@ -122,6 +134,7 @@
"ChmodFolder": "chmod Folder", "ChmodFolder": "chmod Folder",
"ChmodFolderHelpText": "Octal, applied during import/rename to media folders and files (without execute bits)", "ChmodFolderHelpText": "Octal, applied during import/rename to media folders and files (without execute bits)",
"ChmodFolderHelpTextWarning": "This only works if the user running sonarr is the owner of the file. It's better to ensure the download client sets the permissions properly.", "ChmodFolderHelpTextWarning": "This only works if the user running sonarr is the owner of the file. It's better to ensure the download client sets the permissions properly.",
"ChooseAnotherFolder": "Choose another folder",
"ChownGroup": "chown Group", "ChownGroup": "chown Group",
"ChownGroupHelpText": "Group name or gid. Use gid for remote file systems.", "ChownGroupHelpText": "Group name or gid. Use gid for remote file systems.",
"ChownGroupHelpTextWarning": "This only works if the user running sonarr is the owner of the file. It's better to ensure the download client uses the same group as sonarr.", "ChownGroupHelpTextWarning": "This only works if the user running sonarr is the owner of the file. It's better to ensure the download client uses the same group as sonarr.",
@ -150,10 +163,11 @@
"CopyToClipboard": "Copy to Clipboard", "CopyToClipboard": "Copy to Clipboard",
"CopyUsingHardlinksHelpText": "Hardlinks allow Sonarr to import seeding torrents to the series folder without taking extra disk space or copying the entire contents of the file. Hardlinks will only work if the source and destination are on the same volume", "CopyUsingHardlinksHelpText": "Hardlinks allow Sonarr to import seeding torrents to the series folder without taking extra disk space or copying the entire contents of the file. Hardlinks will only work if the source and destination are on the same volume",
"CopyUsingHardlinksHelpTextWarning": "Occasionally, file locks may prevent renaming files that are being seeded. You may temporarily disable seeding and use Sonarr's rename function as a work around.", "CopyUsingHardlinksHelpTextWarning": "Occasionally, file locks may prevent renaming files that are being seeded. You may temporarily disable seeding and use Sonarr's rename function as a work around.",
"CouldNotFindResults": "Couldn't find any results for '{term}'",
"CountDownloadClientsSelected": "{count} download client(s) selected", "CountDownloadClientsSelected": "{count} download client(s) selected",
"CountImportListsSelected": "{count} import list(s) selected", "CountImportListsSelected": "{count} import list(s) selected",
"CountIndexersSelected": "{count} indexer(s) selected", "CountIndexersSelected": "{count} indexer(s) selected",
"CountSeasons": "{count} seasons", "CountSeasons": "{count} Seasons",
"CreateEmptySeriesFolders": "Create Empty Series Folders", "CreateEmptySeriesFolders": "Create Empty Series Folders",
"CreateEmptySeriesFoldersHelpText": "Create missing series folders during disk scan", "CreateEmptySeriesFoldersHelpText": "Create missing series folders during disk scan",
"CreateGroup": "Create Group", "CreateGroup": "Create Group",
@ -172,6 +186,7 @@
"CutoffUnmet": "Cutoff Unmet", "CutoffUnmet": "Cutoff Unmet",
"Daily": "Daily", "Daily": "Daily",
"DailyEpisodeFormat": "Daily Episode Format", "DailyEpisodeFormat": "Daily Episode Format",
"DailyTypeDescription": "Episodes released daily or less frequently that use year-month-day (2023-08-04)",
"Dash": "Dash", "Dash": "Dash",
"Date": "Date", "Date": "Date",
"Dates": "Dates", "Dates": "Dates",
@ -320,6 +335,7 @@
"Events": "Events", "Events": "Events",
"Example": "Example", "Example": "Example",
"Exception": "Exception", "Exception": "Exception",
"Existing": "Existing",
"ExistingTag": "Existing tag", "ExistingTag": "Existing tag",
"ExportCustomFormat": "Export Custom Format", "ExportCustomFormat": "Export Custom Format",
"Extend": "Extend", "Extend": "Extend",
@ -370,7 +386,10 @@
"Images": "Images", "Images": "Images",
"Implementation": "Implementation", "Implementation": "Implementation",
"Import": "Import", "Import": "Import",
"ImportCountSeries": "Import {selectedCount} Series",
"ImportCustomFormat": "Import Custom Format", "ImportCustomFormat": "Import Custom Format",
"ImportErrors": "Import Errors",
"ImportExistingSeries": "Import Existing Series",
"ImportExtraFiles": "Import Extra Files", "ImportExtraFiles": "Import Extra Files",
"ImportExtraFilesHelpText": "Import matching extra files (subtitles, nfo, etc) after importing an episode file", "ImportExtraFilesHelpText": "Import matching extra files (subtitles, nfo, etc) after importing an episode file",
"ImportList": "Import List", "ImportList": "Import List",
@ -389,6 +408,7 @@
"ImportMechanismHandlingDisabledHealthCheckMessage": "Enable Completed Download Handling", "ImportMechanismHandlingDisabledHealthCheckMessage": "Enable Completed Download Handling",
"ImportScriptPath": "Import Script Path", "ImportScriptPath": "Import Script Path",
"ImportScriptPathHelpText": "The path to the script to use for importing", "ImportScriptPathHelpText": "The path to the script to use for importing",
"ImportSeries": "Import Series",
"ImportUsingScript": "Import Using Script", "ImportUsingScript": "Import Using Script",
"ImportUsingScriptHelpText": "Copy files for importing using a script (ex. for transcoding)", "ImportUsingScriptHelpText": "Copy files for importing using a script (ex. for transcoding)",
"Imported": "Imported", "Imported": "Imported",
@ -436,6 +456,11 @@
"LatestSeason": "Latest Season", "LatestSeason": "Latest Season",
"LiberaWebchat": "Libera Webchat", "LiberaWebchat": "Libera Webchat",
"LibraryImport": "Library Import", "LibraryImport": "Library Import",
"LibraryImportHeader": "Import series you already have",
"LibraryImportTips": "Some tips to ensure the import goes smoothly:",
"LibraryImportTipsDontUseDownloadsFolder": "Do not use for importing downloads from your download client, this is only for existing organized libraries, not unsorted files.",
"LibraryImportTipsQualityInFilename": "Make sure that your files include the quality in their filenames. eg. `episode.s02e15.bluray.mkv`",
"LibraryImportTipsUseRootFolder": "Point Sonarr to the folder containing all of your tv shows, not a specific one. eg. \"`{goodFolderExample}`\" and not \"`{badFolderExample}`\". Additionally, each series must be in its own folder within the root/library folder.",
"ListExclusionsLoadError": "Unable to load List Exclusions", "ListExclusionsLoadError": "Unable to load List Exclusions",
"ListOptionsLoadError": "Unable to load list options", "ListOptionsLoadError": "Unable to load list options",
"ListQualityProfileHelpText": "Quality Profile list items will be added with", "ListQualityProfileHelpText": "Quality Profile list items will be added with",
@ -502,6 +527,23 @@
"MissingEpisodes": "Missing Episodes", "MissingEpisodes": "Missing Episodes",
"Mode": "Mode", "Mode": "Mode",
"Monday": "Monday", "Monday": "Monday",
"Monitor": "Monitor",
"MonitorAllEpisodes": "All Episodes",
"MonitorAllEpisodesDescription": "Monitor all episodes except specials",
"MonitorExistingEpisodes": "Existing Episodes",
"MonitorExistingEpisodesDescription": "Monitor episodes that have files or have not aired yet",
"MonitorFirstSeason": "First Season",
"MonitorFirstSeasonDescription": "Monitor all episodes of the first season. All other seasons will be ignored",
"MonitorFutureEpisodes": "Future Episodes",
"MonitorFutureEpisodesDescription": "Monitor episodes that have not aired yet",
"MonitorLatestSeason": "Latest Season",
"MonitorLatestSeasonDescription": "Monitor all episodes of the latest season that aired within the last 90 days and all future seasons",
"MonitorMissingEpisodes": "Missing Episodes",
"MonitorMissingEpisodesDescription": "Monitor episodes that do not have files or have not aired yet",
"MonitorNone": "None",
"MonitorNoneDescription": "No episodes will be monitored",
"MonitorSpecials": "Monitor Specials",
"MonitorSpecialsDescription": "Monitor all special episodes without changing the monitored status of other episodes",
"Monitored": "Monitored", "Monitored": "Monitored",
"MonitoredOnly": "Monitored Only", "MonitoredOnly": "Monitored Only",
"MonitoringOptions": "Monitoring Options", "MonitoringOptions": "Monitoring Options",
@ -542,9 +584,11 @@
"NoLimitForAnyRuntime": "No limit for any runtime", "NoLimitForAnyRuntime": "No limit for any runtime",
"NoLinks": "No links", "NoLinks": "No links",
"NoLogFiles": "No log files", "NoLogFiles": "No log files",
"NoMatchFound": "No match found!",
"NoMinimumForAnyRuntime": "No minimum for any runtime", "NoMinimumForAnyRuntime": "No minimum for any runtime",
"NoResultsFound": "No results found", "NoResultsFound": "No results found",
"NoSeasons": "No seasons", "NoSeasons": "No seasons",
"NoSeriesHaveBeenAdded": "You haven't added any series yet, do you want to import some or all of your series first?",
"NoTagsHaveBeenAddedYet": "No tags have been added yet", "NoTagsHaveBeenAddedYet": "No tags have been added yet",
"NoUpdatesAreAvailable": "No updates are available", "NoUpdatesAreAvailable": "No updates are available",
"None": "None", "None": "None",
@ -567,7 +611,7 @@
"OnSeriesDelete": "On Series Delete", "OnSeriesDelete": "On Series Delete",
"OnUpgrade": "On Upgrade", "OnUpgrade": "On Upgrade",
"OneMinute": "1 Minute", "OneMinute": "1 Minute",
"OneSeason": "1 season", "OneSeason": "1 Season",
"OnlyForBulkSeasonReleases": "Only for Bulk Season Releases", "OnlyForBulkSeasonReleases": "Only for Bulk Season Releases",
"OnlyTorrent": "Only Torrent", "OnlyTorrent": "Only Torrent",
"OnlyUsenet": "Only Usenet", "OnlyUsenet": "Only Usenet",
@ -605,6 +649,7 @@
"Priority": "Priority", "Priority": "Priority",
"PriorityHelpText": "Prioritize multiple Download Clients. Round-Robin is used for clients with the same priority.", "PriorityHelpText": "Prioritize multiple Download Clients. Round-Robin is used for clients with the same priority.",
"PrioritySettings": "Priority: {priority}", "PrioritySettings": "Priority: {priority}",
"ProcessingFolders": "Processing Folders",
"Profiles": "Profiles", "Profiles": "Profiles",
"ProfilesSettingsSummary": "Quality, Language Delay and Release profiles", "ProfilesSettingsSummary": "Quality, Language Delay and Release profiles",
"Progress": "Progress", "Progress": "Progress",
@ -767,6 +812,8 @@
"Score": "Score", "Score": "Score",
"Script": "Script", "Script": "Script",
"ScriptPath": "Script Path", "ScriptPath": "Script Path",
"SearchByTvdbId": "You can also search using TVDB ID of a show. eg. tvdb:71663",
"SearchFailedError": "Search failed, please try again later.",
"SearchForMonitoredEpisodes": "Search for monitored episodes", "SearchForMonitoredEpisodes": "Search for monitored episodes",
"SearchIsNotSupportedWithThisIndexer": "Search is not supported with this indexer", "SearchIsNotSupportedWithThisIndexer": "Search is not supported with this indexer",
"Season": "Season", "Season": "Season",
@ -791,6 +838,7 @@
"SeriesTitleToExcludeHelpText": "The name of the series to exclude", "SeriesTitleToExcludeHelpText": "The name of the series to exclude",
"SeriesType": "Series Type", "SeriesType": "Series Type",
"SeriesTypes": "Series Types", "SeriesTypes": "Series Types",
"SeriesTypesHelpText": "Series type is used for renaming, parsing and searching",
"SetPermissions": "Set Permissions", "SetPermissions": "Set Permissions",
"SetPermissionsLinuxHelpText": "Should chmod be run when files are imported/renamed?", "SetPermissionsLinuxHelpText": "Should chmod be run when files are imported/renamed?",
"SetPermissionsLinuxHelpTextWarning": "If you're unsure what these settings do, do not alter them.", "SetPermissionsLinuxHelpTextWarning": "If you're unsure what these settings do, do not alter them.",
@ -826,7 +874,11 @@
"SslCertPath": "SSL Cert Path", "SslCertPath": "SSL Cert Path",
"SslCertPathHelpText": "Path to pfx file", "SslCertPathHelpText": "Path to pfx file",
"SslPort": "SSL Port", "SslPort": "SSL Port",
"Standard": "Standard",
"StandardEpisodeFormat": "Standard Episode Format", "StandardEpisodeFormat": "Standard Episode Format",
"StandardTypeDescription": "Episodes released with SxxEyy pattern",
"StartImport": "Start Import",
"StartProcessing": "Start Processing",
"Started": "Started", "Started": "Started",
"StartupDirectory": "Startup directory", "StartupDirectory": "Startup directory",
"Status": "Status", "Status": "Status",
@ -894,9 +946,12 @@
"UnmappedFolders": "Unmapped Folders", "UnmappedFolders": "Unmapped Folders",
"UnmonitorDeletedEpisodes": "Unmonitor Deleted Episodes", "UnmonitorDeletedEpisodes": "Unmonitor Deleted Episodes",
"UnmonitorDeletedEpisodesHelpText": "Episodes deleted from disk are automatically unmonitored in Sonarr", "UnmonitorDeletedEpisodesHelpText": "Episodes deleted from disk are automatically unmonitored in Sonarr",
"UnmonitorSpecials": "Unmonitor Specials",
"UnmonitorSpecialsDescription": "Unmonitor all special episodes without changing the monitored status of other episodes",
"Unmonitored": "Unmonitored", "Unmonitored": "Unmonitored",
"UnmonitoredOnly": "Unmonitored Only", "UnmonitoredOnly": "Unmonitored Only",
"UnsavedChanges": "Unsaved Changes", "UnsavedChanges": "Unsaved Changes",
"Upcoming": "Upcoming",
"UpdateAutomaticallyHelpText": "Automatically download and install updates. You will still be able to install from System: Updates", "UpdateAutomaticallyHelpText": "Automatically download and install updates. You will still be able to install from System: Updates",
"UpdateAvailableHealthCheckMessage": "New update is available", "UpdateAvailableHealthCheckMessage": "New update is available",
"UpdateMechanismHelpText": "Use Sonarr's built-in updater or a script", "UpdateMechanismHelpText": "Use Sonarr's built-in updater or a script",
@ -937,6 +992,7 @@
"Warn": "Warn", "Warn": "Warn",
"WeekColumnHeader": "Week Column Header", "WeekColumnHeader": "Week Column Header",
"WeekColumnHeaderHelpText": "Shown above each column when week is the active view", "WeekColumnHeaderHelpText": "Shown above each column when week is the active view",
"WhyCantIFindMyShow": "Why can't I find my show?",
"Wiki": "Wiki", "Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Would you like to restore the backup '{name}'?", "WouldYouLikeToRestoreBackup": "Would you like to restore the backup '{name}'?",
"Year": "Year", "Year": "Year",