1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-27 23:06:29 -04:00

Add Translations to Settings Pages

This commit is contained in:
Stevie Robinson
2023-07-22 21:14:33 +02:00
committed by Mark McDowall
parent 8008610d47
commit f2c31e92ce
102 changed files with 1697 additions and 802 deletions
@@ -17,27 +17,87 @@ import NamingConnector from './Naming/NamingConnector';
import AddRootFolder from './RootFolder/AddRootFolder';
const episodeTitleRequiredOptions = [
{ key: 'always', value: 'Always' },
{ key: 'bulkSeasonReleases', value: 'Only for Bulk Season Releases' },
{ key: 'never', value: 'Never' }
{
key: 'always',
get value() {
return translate('Always');
}
},
{
key: 'bulkSeasonReleases',
get value() {
return translate('OnlyForBulkSeasonReleases');
}
},
{
key: 'never',
get value() {
return translate('Never');
}
}
];
const rescanAfterRefreshOptions = [
{ key: 'always', value: 'Always' },
{ key: 'afterManual', value: 'After Manual Refresh' },
{ key: 'never', value: 'Never' }
{
key: 'always',
get value() {
return translate('Always');
}
},
{
key: 'afterManual',
get value() {
return translate('AfterManualRefresh');
}
},
{
key: 'never',
get value() {
return translate('Never');
}
}
];
const downloadPropersAndRepacksOptions = [
{ key: 'preferAndUpgrade', value: 'Prefer and Upgrade' },
{ key: 'doNotUpgrade', value: 'Do not Upgrade Automatically' },
{ key: 'doNotPrefer', value: 'Do not Prefer' }
{
key: 'preferAndUpgrade',
get value() {
return translate('PreferAndUpgrade');
}
},
{
key: 'doNotUpgrade',
get value() {
return translate('DoNotUpgradeAutomatically');
}
},
{
key: 'doNotPrefer',
get value() {
return translate('DoNotPrefer');
}
}
];
const fileDateOptions = [
{ key: 'none', value: 'None' },
{ key: 'localAirDate', value: 'Local Air Date' },
{ key: 'utcAirDate', value: 'UTC Air Date' }
{
key: 'none',
get value() {
return translate('None');
}
},
{
key: 'localAirDate',
get value() {
return translate('LocalAirDate');
}
},
{
key: 'utcAirDate',
get value() {
return translate('UtcAirDate');
}
}
];
class MediaManagement extends Component {
@@ -59,7 +119,7 @@ class MediaManagement extends Component {
} = this.props;
return (
<PageContent title="Media Management Settings">
<PageContent title={translate('MediaManagementSettings')}>
<SettingsToolbarConnector
advancedSettings={advancedSettings}
{...otherProps}
@@ -71,15 +131,17 @@ class MediaManagement extends Component {
{
isFetching ?
<FieldSet legend="Naming Settings">
<FieldSet legend={translate('NamingSettings')}>
<LoadingIndicator />
</FieldSet> : null
}
{
!isFetching && error ?
<FieldSet legend="Naming Settings">
<Alert kind={kinds.DANGER}>Unable to load Media Management settings</Alert>
<FieldSet legend={translate('NamingSettings')}>
<Alert kind={kinds.DANGER}>
{translate('MediaManagementSettingsLoadError')}
</Alert>
</FieldSet> : null
}
@@ -91,18 +153,18 @@ class MediaManagement extends Component {
>
{
advancedSettings ?
<FieldSet legend="Folders">
<FieldSet legend={translate('Folders')}>
<FormGroup
advancedSettings={advancedSettings}
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Create empty series folders</FormLabel>
<FormLabel>{translate('CreateEmptySeriesFolders')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="createEmptySeriesFolders"
helpText="Create missing series folders during disk scan"
helpText={translate('CreateEmptySeriesFoldersHelpText')}
onChange={onInputChange}
{...settings.createEmptySeriesFolders}
/>
@@ -113,12 +175,12 @@ class MediaManagement extends Component {
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Delete empty folders</FormLabel>
<FormLabel>{translate('DeleteEmptyFolders')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="deleteEmptyFolders"
helpText="Delete empty series and season folders during disk scan and when episode files are deleted"
helpText={translate('DeleteEmptyFoldersHelpText')}
onChange={onInputChange}
{...settings.deleteEmptyFolders}
/>
@@ -129,19 +191,19 @@ class MediaManagement extends Component {
{
advancedSettings ?
<FieldSet
legend="Importing"
legend={translate('Importing')}
>
<FormGroup
advancedSettings={advancedSettings}
isAdvanced={true}
size={sizes.SMALL}
>
<FormLabel>Episode Title Required</FormLabel>
<FormLabel>{translate('EpisodeTitleRequired')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="episodeTitleRequired"
helpText="Prevent importing for up to 48 hours if the episode title is in the naming format and the episode title is TBA"
helpText={translate('EpisodeTitleRequiredHelpText')}
values={episodeTitleRequiredOptions}
onChange={onInputChange}
{...settings.episodeTitleRequired}
@@ -156,12 +218,12 @@ class MediaManagement extends Component {
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Skip Free Space Check</FormLabel>
<FormLabel>{translate('SkipFreeSpaceCheck')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="skipFreeSpaceCheckWhenImporting"
helpText="Use when Sonarr is unable to detect free space from your series root folder"
helpText={translate('SkipFreeSpaceCheckWhenImportingHelpText')}
onChange={onInputChange}
{...settings.skipFreeSpaceCheckWhenImporting}
/>
@@ -173,13 +235,13 @@ class MediaManagement extends Component {
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Minimum Free Space</FormLabel>
<FormLabel>{translate('MinimumFreeSpace')}</FormLabel>
<FormInputGroup
type={inputTypes.NUMBER}
unit='MB'
name="minimumFreeSpaceWhenImporting"
helpText="Prevent import if it would leave less than this amount of disk space available"
helpText={translate('MinimumFreeSpaceHelpText')}
onChange={onInputChange}
{...settings.minimumFreeSpaceWhenImporting}
/>
@@ -190,13 +252,13 @@ class MediaManagement extends Component {
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Use Hardlinks instead of Copy</FormLabel>
<FormLabel>{translate('UseHardlinksInsteadOfCopy')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="copyUsingHardlinks"
helpText="Hardlinks allow Sonarr to import seeding torrents to the 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"
helpTextWarning="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."
helpText={translate('CopyUsingHardlinksHelpText')}
helpTextWarning={translate('CopyUsingHardlinksHelpTextWarning')}
onChange={onInputChange}
{...settings.copyUsingHardlinks}
/>
@@ -207,12 +269,12 @@ class MediaManagement extends Component {
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Import Using Script</FormLabel>
<FormLabel>{translate('ImportUsingScript')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="useScriptImport"
helpText="Copy files for importing using a script (ex. for transcoding)"
helpText={translate('ImportUsingScriptHelpText')}
onChange={onInputChange}
{...settings.useScriptImport}
/>
@@ -224,13 +286,13 @@ class MediaManagement extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>Import Script Path</FormLabel>
<FormLabel>{translate('ImportScriptPath')}</FormLabel>
<FormInputGroup
type={inputTypes.PATH}
includeFiles={true}
name="scriptImportPath"
helpText="The path to the script to use for importing"
helpText={translate('ImportScriptPathHelpText')}
onChange={onInputChange}
{...settings.scriptImportPath}
/>
@@ -238,12 +300,12 @@ class MediaManagement extends Component {
}
<FormGroup size={sizes.MEDIUM}>
<FormLabel>Import Extra Files</FormLabel>
<FormLabel>{translate('ImportExtraFiles')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="importExtraFiles"
helpText="Import matching extra files (subtitles, nfo, etc) after importing an episode file"
helpText={translate('ImportExtraFilesHelpText')}
onChange={onInputChange}
{...settings.importExtraFiles}
/>
@@ -255,14 +317,14 @@ class MediaManagement extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>Import Extra Files</FormLabel>
<FormLabel>{translate('ImportExtraFiles')}</FormLabel>
<FormInputGroup
type={inputTypes.TEXT}
name="extraFileExtensions"
helpTexts={[
'Comma separated list of extra files to import (.nfo will be imported as .nfo-orig)',
'Examples: ".sub, .nfo" or "sub,nfo"'
translate('ExtraFileExtensionsHelpText'),
translate('ExtraFileExtensionsHelpTextsExamples')
]}
onChange={onInputChange}
{...settings.extraFileExtensions}
@@ -273,15 +335,15 @@ class MediaManagement extends Component {
}
<FieldSet
legend="File Management"
legend={translate('FileManagement')}
>
<FormGroup size={sizes.MEDIUM}>
<FormLabel>Unmonitor Deleted Episodes</FormLabel>
<FormLabel>{translate('UnmonitorDeletedEpisodes')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="autoUnmonitorPreviouslyDownloadedEpisodes"
helpText="Episodes deleted from disk are automatically unmonitored in Sonarr"
helpText={translate('UnmonitorDeletedEpisodesHelpText')}
onChange={onInputChange}
{...settings.autoUnmonitorPreviouslyDownloadedEpisodes}
/>
@@ -292,18 +354,18 @@ class MediaManagement extends Component {
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Propers and Repacks</FormLabel>
<FormLabel>{translate('DownloadPropersAndRepacks')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="downloadPropersAndRepacks"
helpTexts={[
'Whether or not to automatically upgrade to Propers/Repacks',
'Use \'Do not Prefer\' to sort by custom format score over propers/repacks'
translate('DownloadPropersAndRepacksHelpText'),
translate('DownloadPropersAndRepacksHelpTextCustomFormat')
]}
helpTextWarning={
settings.downloadPropersAndRepacks.value === 'doNotPrefer' ?
'Use custom formats for automatic upgrades to propers/repacks' :
translate('DownloadPropersAndRepacksHelpTextWarning') :
undefined
}
values={downloadPropersAndRepacksOptions}
@@ -317,12 +379,12 @@ class MediaManagement extends Component {
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Analyse video files</FormLabel>
<FormLabel>{translate('AnalyseVideoFiles')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="enableMediaInfo"
helpText="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."
helpText={translate('AnalyseVideoFilesHelpText')}
onChange={onInputChange}
{...settings.enableMediaInfo}
/>
@@ -332,13 +394,13 @@ class MediaManagement extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>Rescan Series Folder after Refresh</FormLabel>
<FormLabel>{translate('RescanSeriesFolderAfterRefresh')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="rescanAfterRefresh"
helpText="Rescan the series folder after refreshing the series"
helpTextWarning="Sonarr will not automatically detect changes to files when not set to 'Always'"
helpText={translate('RescanAfterRefreshHelpText')}
helpTextWarning={translate('RescanAfterRefreshHelpTextWarning')}
values={rescanAfterRefreshOptions}
onChange={onInputChange}
{...settings.rescanAfterRefresh}
@@ -349,12 +411,12 @@ class MediaManagement extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>Change File Date</FormLabel>
<FormLabel>{translate('ChangeFileDate')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="fileDate"
helpText="Change file date on import/rescan"
helpText={translate('ChangeFileDateHelpText')}
values={fileDateOptions}
onChange={onInputChange}
{...settings.fileDate}
@@ -365,12 +427,12 @@ class MediaManagement extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>Recycling Bin</FormLabel>
<FormLabel>{translate('RecyclingBin')}</FormLabel>
<FormInputGroup
type={inputTypes.PATH}
name="recycleBin"
helpText="Episode files will go here when deleted instead of being permanently deleted"
helpText={translate('RecyclingBinHelpText')}
onChange={onInputChange}
{...settings.recycleBin}
/>
@@ -380,13 +442,13 @@ class MediaManagement extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>Recycling Bin Cleanup</FormLabel>
<FormLabel>{translate('RecyclingBinCleanup')}</FormLabel>
<FormInputGroup
type={inputTypes.NUMBER}
name="recycleBinCleanupDays"
helpText="Set to 0 to disable automatic cleanup"
helpTextWarning="Files in the recycle bin older than the selected number of days will be cleaned up automatically"
helpText={translate('RecyclingBinCleanupHelpText')}
helpTextWarning={translate('RecyclingBinCleanupHelpTextWarning')}
min={0}
onChange={onInputChange}
{...settings.recycleBinCleanupDays}
@@ -397,20 +459,20 @@ class MediaManagement extends Component {
{
advancedSettings && !isWindows ?
<FieldSet
legend="Permissions"
legend={translate('Permissions')}
>
<FormGroup
advancedSettings={advancedSettings}
isAdvanced={true}
size={sizes.MEDIUM}
>
<FormLabel>Set Permissions</FormLabel>
<FormLabel>{translate('SetPermissions')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="setPermissionsLinux"
helpText="Should chmod be run when files are imported/renamed?"
helpTextWarning="If you're unsure what these settings do, do not alter them."
helpText={translate('SetPermissionsLinuxHelpText')}
helpTextWarning={translate('SetPermissionsLinuxHelpTextWarning')}
onChange={onInputChange}
{...settings.setPermissionsLinux}
/>
@@ -420,13 +482,13 @@ class MediaManagement extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>chmod Folder</FormLabel>
<FormLabel>{translate('ChmodFolder')}</FormLabel>
<FormInputGroup
type={inputTypes.UMASK}
name="chmodFolder"
helpText="Octal, applied during import/rename to media folders and files (without execute bits)"
helpTextWarning="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."
helpText={translate('ChmodFolderHelpText')}
helpTextWarning={translate('ChmodFolderHelpTextWarning')}
onChange={onInputChange}
{...settings.chmodFolder}
/>
@@ -436,13 +498,13 @@ class MediaManagement extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>chown Group</FormLabel>
<FormLabel>{translate('ChownGroup')}</FormLabel>
<FormInputGroup
type={inputTypes.TEXT}
name="chownGroup"
helpText="Group name or gid. Use gid for remote file systems."
helpTextWarning="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."
helpText={translate('ChownGroupHelpText')}
helpTextWarning={translate('ChownGroupHelpTextWarning')}
values={fileDateOptions}
onChange={onInputChange}
{...settings.chownGroup}
@@ -9,6 +9,7 @@ import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import { inputTypes, kinds, sizes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import NamingModal from './NamingModal';
import styles from './Naming.css';
@@ -124,20 +125,20 @@ class Naming extends Component {
const replaceIllegalCharacters = hasSettings && settings.replaceIllegalCharacters.value;
const multiEpisodeStyleOptions = [
{ key: 0, value: 'Extend', hint: 'S01E01-02-03' },
{ key: 1, value: 'Duplicate', hint: 'S01E01.S01E02' },
{ key: 2, value: 'Repeat', hint: 'S01E01E02E03' },
{ key: 3, value: 'Scene', hint: 'S01E01-E02-E03' },
{ key: 4, value: 'Range', hint: 'S01E01-03' },
{ key: 5, value: 'Prefixed Range', hint: 'S01E01-E03' }
{ key: 0, value: translate('Extend'), hint: 'S01E01-02-03' },
{ key: 1, value: translate('Duplicate'), hint: 'S01E01.S01E02' },
{ key: 2, value: translate('Repeat'), hint: 'S01E01E02E03' },
{ key: 3, value: translate('Scene'), hint: 'S01E01-E02-E03' },
{ key: 4, value: translate('Range'), hint: 'S01E01-03' },
{ key: 5, value: translate('PrefixedRange'), hint: 'S01E01-E03' }
];
const colonReplacementOptions = [
{ key: 0, value: 'Delete' },
{ key: 1, value: 'Replace with Dash' },
{ key: 2, value: 'Replace with Space Dash' },
{ key: 3, value: 'Replace with Space Dash Space' },
{ key: 4, value: 'Smart Replace', hint: 'Dash or Space Dash depending on name' }
{ key: 0, value: translate('Delete') },
{ key: 1, value: translate('ReplaceWithDash') },
{ key: 2, value: translate('ReplaceWithSpaceDash') },
{ key: 3, value: translate('ReplaceWithSpaceDashSpace') },
{ key: 4, value: translate('SmartReplace'), hint: translate('SmartReplaceHint') }
];
const standardEpisodeFormatHelpTexts = [];
@@ -155,56 +156,56 @@ class Naming extends Component {
if (examplesPopulated) {
if (examples.singleEpisodeExample) {
standardEpisodeFormatHelpTexts.push(`Single Episode: ${examples.singleEpisodeExample}`);
standardEpisodeFormatHelpTexts.push(`${translate('SingleEpisode')}: ${examples.singleEpisodeExample}`);
} else {
standardEpisodeFormatErrors.push({ message: 'Single Episode: Invalid Format' });
standardEpisodeFormatErrors.push({ message: translate('SingleEpisodeInvalidFormat') });
}
if (examples.multiEpisodeExample) {
standardEpisodeFormatHelpTexts.push(`Multi Episode: ${examples.multiEpisodeExample}`);
standardEpisodeFormatHelpTexts.push(`${translate('MultiEpisode')}: ${examples.multiEpisodeExample}`);
} else {
standardEpisodeFormatErrors.push({ message: 'Multi Episode: Invalid Format' });
standardEpisodeFormatErrors.push({ message: translate('MultiEpisodeInvalidFormat') });
}
if (examples.dailyEpisodeExample) {
dailyEpisodeFormatHelpTexts.push(`Example: ${examples.dailyEpisodeExample}`);
dailyEpisodeFormatHelpTexts.push(`${translate('Example')}: ${examples.dailyEpisodeExample}`);
} else {
dailyEpisodeFormatErrors.push({ message: 'Invalid Format' });
dailyEpisodeFormatErrors.push({ message: translate('InvalidFormat') });
}
if (examples.animeEpisodeExample) {
animeEpisodeFormatHelpTexts.push(`Single Episode: ${examples.animeEpisodeExample}`);
animeEpisodeFormatHelpTexts.push(`${translate('SingleEpisode')}: ${examples.animeEpisodeExample}`);
} else {
animeEpisodeFormatErrors.push({ message: 'Single Episode: Invalid Format' });
animeEpisodeFormatErrors.push({ message: translate('SingleEpisodeInvalidFormat') });
}
if (examples.animeMultiEpisodeExample) {
animeEpisodeFormatHelpTexts.push(`Multi Episode: ${examples.animeMultiEpisodeExample}`);
animeEpisodeFormatHelpTexts.push(`${translate('MultiEpisode')}: ${examples.animeMultiEpisodeExample}`);
} else {
animeEpisodeFormatErrors.push({ message: 'Multi Episode: Invalid Format' });
animeEpisodeFormatErrors.push({ message: translate('MultiEpisodeInvalidFormat') });
}
if (examples.seriesFolderExample) {
seriesFolderFormatHelpTexts.push(`Example: ${examples.seriesFolderExample}`);
seriesFolderFormatHelpTexts.push(`${translate('Example')}: ${examples.seriesFolderExample}`);
} else {
seriesFolderFormatErrors.push({ message: 'Invalid Format' });
seriesFolderFormatErrors.push({ message: translate('InvalidFormat') });
}
if (examples.seasonFolderExample) {
seasonFolderFormatHelpTexts.push(`Example: ${examples.seasonFolderExample}`);
seasonFolderFormatHelpTexts.push(`${translate('Example')}: ${examples.seasonFolderExample}`);
} else {
seasonFolderFormatErrors.push({ message: 'Invalid Format' });
seasonFolderFormatErrors.push({ message: translate('InvalidFormat') });
}
if (examples.specialsFolderExample) {
specialsFolderFormatHelpTexts.push(`Example: ${examples.specialsFolderExample}`);
specialsFolderFormatHelpTexts.push(`${translate('Example')}: ${examples.specialsFolderExample}`);
} else {
specialsFolderFormatErrors.push({ message: 'Invalid Format' });
specialsFolderFormatErrors.push({ message: translate('InvalidFormat') });
}
}
return (
<FieldSet legend="Episode Naming">
<FieldSet legend={translate('EpisodeNaming')}>
{
isFetching &&
<LoadingIndicator />
@@ -212,31 +213,33 @@ class Naming extends Component {
{
!isFetching && error &&
<Alert kind={kinds.DANGER}>Unable to load Naming settings</Alert>
<Alert kind={kinds.DANGER}>
{translate('NamingSettingsLoadError')}
</Alert>
}
{
hasSettings && !isFetching && !error &&
<Form>
<FormGroup size={sizes.MEDIUM}>
<FormLabel>Rename Episodes</FormLabel>
<FormLabel>{translate('RenameEpisodes')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="renameEpisodes"
helpText="Sonarr will use the existing file name if renaming is disabled"
helpText={translate('RenameEpisodesHelpText')}
onChange={onInputChange}
{...settings.renameEpisodes}
/>
</FormGroup>
<FormGroup size={sizes.MEDIUM}>
<FormLabel>Replace Illegal Characters</FormLabel>
<FormLabel>{translate('ReplaceIllegalCharacters')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="replaceIllegalCharacters"
helpText="Replace illegal characters. If unchecked, Sonarr will remove them instead"
helpText={translate('ReplaceIllegalCharactersHelpText')}
onChange={onInputChange}
{...settings.replaceIllegalCharacters}
/>
@@ -245,12 +248,13 @@ class Naming extends Component {
{
replaceIllegalCharacters ?
<FormGroup>
<FormLabel>Colon Replacement</FormLabel>
<FormLabel>{translate('ColonReplacement')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="colonReplacementFormat"
values={colonReplacementOptions}
helpText={translate('ColonReplacementFormatHelpText')}
onChange={onInputChange}
{...settings.colonReplacementFormat}
/>
@@ -262,7 +266,7 @@ class Naming extends Component {
renameEpisodes &&
<div>
<FormGroup size={sizes.LARGE}>
<FormLabel>Standard Episode Format</FormLabel>
<FormLabel>{translate('StandardEpisodeFormat')}</FormLabel>
<FormInputGroup
inputClassName={styles.namingInput}
@@ -277,7 +281,7 @@ class Naming extends Component {
</FormGroup>
<FormGroup size={sizes.LARGE}>
<FormLabel>Daily Episode Format</FormLabel>
<FormLabel>{translate('DailyEpisodeFormat')}</FormLabel>
<FormInputGroup
inputClassName={styles.namingInput}
@@ -292,7 +296,7 @@ class Naming extends Component {
</FormGroup>
<FormGroup size={sizes.LARGE}>
<FormLabel>Anime Episode Format</FormLabel>
<FormLabel>{translate('DailyEpisodeFormat')}</FormLabel>
<FormInputGroup
inputClassName={styles.namingInput}
@@ -312,7 +316,7 @@ class Naming extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>Series Folder Format</FormLabel>
<FormLabel>{translate('SeriesFolderFormat')}</FormLabel>
<FormInputGroup
inputClassName={styles.namingInput}
@@ -321,13 +325,13 @@ class Naming extends Component {
buttons={<FormInputButton onPress={this.onSeriesFolderNamingModalOpenClick}>?</FormInputButton>}
onChange={onInputChange}
{...settings.seriesFolderFormat}
helpTexts={['Used when adding a new series or moving series via the series editor', ...seriesFolderFormatHelpTexts]}
helpTexts={[translate('SeriesFolderFormatHelpText'), ...seriesFolderFormatHelpTexts]}
errors={[...seriesFolderFormatErrors, ...settings.seriesFolderFormat.errors]}
/>
</FormGroup>
<FormGroup>
<FormLabel>Season Folder Format</FormLabel>
<FormLabel>{translate('SeasonFolderFormat')}</FormLabel>
<FormInputGroup
inputClassName={styles.namingInput}
@@ -345,7 +349,7 @@ class Naming extends Component {
advancedSettings={advancedSettings}
isAdvanced={true}
>
<FormLabel>Specials Folder Format</FormLabel>
<FormLabel>{translate('SpecialsFolderFormat')}</FormLabel>
<FormInputGroup
inputClassName={styles.namingInput}
@@ -360,7 +364,7 @@ class Naming extends Component {
</FormGroup>
<FormGroup>
<FormLabel>Multi-Episode Style</FormLabel>
<FormLabel>{translate('MultiEpisodeStyle')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
@@ -11,20 +11,57 @@ import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { icons, sizes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import InlineMarkdown from '../../../Components/Markdown/InlineMarkdown';
import NamingOption from './NamingOption';
import styles from './NamingModal.css';
const separatorOptions = [
{ key: ' ', value: 'Space ( )' },
{ key: '.', value: 'Period (.)' },
{ key: '_', value: 'Underscore (_)' },
{ key: '-', value: 'Dash (-)' }
{
key: ' ',
get value() {
return `${translate('Space')} ( )`;
}
},
{
key: '.',
get value() {
return `${translate('Period')} (.)`;
}
},
{
key: '_',
get value() {
return `${translate('Underscore')} (_)`;
}
},
{
key: '-',
get value() {
return `${translate('Dash')} (-)`;
}
}
];
const caseOptions = [
{ key: 'title', value: 'Default Case' },
{ key: 'lower', value: 'Lowercase' },
{ key: 'upper', value: 'Uppercase' }
{
key: 'title',
get value() {
return translate('DefaultCase');
}
},
{
key: 'lower',
get value() {
return translate('Lowercase');
}
},
{
key: 'upper',
get value() {
return translate('Uppercase');
}
}
];
const fileNameTokens = [
@@ -208,7 +245,7 @@ class NamingModal extends Component {
>
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
File Name Tokens
{translate('FileNameTokens')}
</ModalHeader>
<ModalBody>
@@ -232,7 +269,7 @@ class NamingModal extends Component {
{
!advancedSettings &&
<FieldSet legend="File Names">
<FieldSet legend={translate('FileNames')}>
<div className={styles.groups}>
{
fileNameTokens.map(({ token, example }) => {
@@ -257,7 +294,7 @@ class NamingModal extends Component {
</FieldSet>
}
<FieldSet legend="Series">
<FieldSet legend={translate('Series')}>
<div className={styles.groups}>
{
seriesTokens.map(({ token, example }) => {
@@ -279,7 +316,7 @@ class NamingModal extends Component {
</div>
</FieldSet>
<FieldSet legend="Series ID">
<FieldSet legend={translate('SeriesID')}>
<div className={styles.groups}>
{
seriesIdTokens.map(({ token, example }) => {
@@ -303,7 +340,7 @@ class NamingModal extends Component {
{
season &&
<FieldSet legend="Season">
<FieldSet legend={translate('Season')}>
<div className={styles.groups}>
{
seasonTokens.map(({ token, example }) => {
@@ -329,7 +366,7 @@ class NamingModal extends Component {
{
episode &&
<div>
<FieldSet legend="Episode">
<FieldSet legend={translate('Episode')}>
<div className={styles.groups}>
{
episodeTokens.map(({ token, example }) => {
@@ -351,7 +388,7 @@ class NamingModal extends Component {
</div>
</FieldSet>
<FieldSet legend="Air-Date">
<FieldSet legend={translate('AirDate')}>
<div className={styles.groups}>
{
airDateTokens.map(({ token, example }) => {
@@ -375,7 +412,7 @@ class NamingModal extends Component {
{
anime &&
<FieldSet legend="Absolute Episode Number">
<FieldSet legend={translate('AbsoluteEpisodeNumber')}>
<div className={styles.groups}>
{
absoluteTokens.map(({ token, example }) => {
@@ -403,7 +440,7 @@ class NamingModal extends Component {
{
additional &&
<div>
<FieldSet legend="Episode Title">
<FieldSet legend={translate('EpisodeTitle')}>
<div className={styles.groups}>
{
episodeTitleTokens.map(({ token, example }) => {
@@ -425,7 +462,7 @@ class NamingModal extends Component {
</div>
</FieldSet>
<FieldSet legend="Quality">
<FieldSet legend={translate('Quality')}>
<div className={styles.groups}>
{
qualityTokens.map(({ token, example }) => {
@@ -447,7 +484,7 @@ class NamingModal extends Component {
</div>
</FieldSet>
<FieldSet legend="Media Info">
<FieldSet legend={translate('MediaInfo')}>
<div className={styles.groups}>
{
mediaInfoTokens.map(({ token, example, footNote }) => {
@@ -471,14 +508,11 @@ class NamingModal extends Component {
<div className={styles.footNote}>
<Icon className={styles.icon} name={icons.FOOTNOTE} />
<div>
MediaInfo Full/AudioLanguages/SubtitleLanguages support a <code>:EN+DE</code> suffix allowing you to filter the languages included in the filename. Use <code>-DE</code> to exclude specific languages.
Appending <code>+</code> (eg <code>:EN+</code>) will output <code>[EN]</code>/<code>[EN+--]</code>/<code>[--]</code> depending on excluded languages. For example <code>{'{'}MediaInfo Full:EN+DE{'}'}</code>.
</div>
<InlineMarkdown data={translate('MediaInfoFootNote')} />
</div>
</FieldSet>
<FieldSet legend="Other">
<FieldSet legend={translate('Other')}>
<div className={styles.groups}>
{
otherTokens.map(({ token, example }) => {
@@ -500,7 +534,7 @@ class NamingModal extends Component {
</div>
</FieldSet>
<FieldSet legend="Original">
<FieldSet legend={translate('Original')}>
<div className={styles.groups}>
{
originalTokens.map(({ token, example }) => {
@@ -534,7 +568,7 @@ class NamingModal extends Component {
onSelectionChange={this.onInputSelectionChange}
/>
<Button onPress={onModalClose}>
Close
{translate('Close')}
</Button>
</ModalFooter>
</ModalContent>