Translate Calendar Frontend

This commit is contained in:
Stevie Robinson 2023-08-10 21:13:12 +02:00 committed by Mark McDowall
parent b1d12b8ee9
commit bf43453c04
10 changed files with 137 additions and 76 deletions

View File

@ -11,6 +11,7 @@ import episodeEntities from 'Episode/episodeEntities';
import { icons, kinds } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import formatTime from 'Utilities/Date/formatTime'; import formatTime from 'Utilities/Date/formatTime';
import padNumber from 'Utilities/Number/padNumber'; import padNumber from 'Utilities/Number/padNumber';
import translate from 'Utilities/String/translate';
import styles from './AgendaEvent.css'; import styles from './AgendaEvent.css';
class AgendaEvent extends Component { class AgendaEvent extends Component {
@ -129,7 +130,7 @@ class AgendaEvent extends Component {
<Icon <Icon
className={styles.statusIcon} className={styles.statusIcon}
name={icons.WARNING} name={icons.WARNING}
title="Episode does not have an absolute episode number" title={translate('EpisodeMissingAbsoluteNumber')}
/> />
} }
@ -138,7 +139,7 @@ class AgendaEvent extends Component {
<Icon <Icon
className={styles.statusIcon} className={styles.statusIcon}
name={icons.WARNING} name={icons.WARNING}
title="Scene number hasn't been verified yet" title={translate('SceneNumberNotVerified')}
/> : /> :
null null
} }
@ -160,7 +161,7 @@ class AgendaEvent extends Component {
<Icon <Icon
className={styles.statusIcon} className={styles.statusIcon}
name={icons.DOWNLOADING} name={icons.DOWNLOADING}
title="Episode is downloading" title={translate('EpisodeIsDownloading')}
/> />
} }
@ -172,7 +173,7 @@ class AgendaEvent extends Component {
className={styles.statusIcon} className={styles.statusIcon}
name={icons.EPISODE_FILE} name={icons.EPISODE_FILE}
kind={kinds.WARNING} kind={kinds.WARNING}
title="Quality cutoff has not been met" title={translate('QualityCutoffNotMet')}
/> />
} }
@ -182,7 +183,7 @@ class AgendaEvent extends Component {
className={styles.statusIcon} className={styles.statusIcon}
name={icons.INFO} name={icons.INFO}
kind={kinds.INFO} kind={kinds.INFO}
title={seasonNumber === 1 ? 'Series Premiere' : 'Season Premiere'} title={seasonNumber === 1 ? translate('SeriesPremiere') : translate('SeasonPremiere')}
/> />
} }
@ -195,7 +196,7 @@ class AgendaEvent extends Component {
className={styles.statusIcon} className={styles.statusIcon}
name={icons.INFO} name={icons.INFO}
kind={kinds.WARNING} kind={kinds.WARNING}
title={series.status === 'ended' ? 'Series finale' : 'Season finale'} title={series.status === 'ended' ? translate('SeriesFinale') : translate('SeasonFinale')}
/> />
} }
@ -206,7 +207,7 @@ class AgendaEvent extends Component {
className={styles.statusIcon} className={styles.statusIcon}
name={icons.INFO} name={icons.INFO}
kind={kinds.PINK} kind={kinds.PINK}
title="Special" title={translate('Special')}
/> />
} }
</div> </div>

View File

@ -3,6 +3,7 @@ import React, { Component } from 'react';
import Alert from 'Components/Alert'; import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import { kinds } from 'Helpers/Props'; import { kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import AgendaConnector from './Agenda/AgendaConnector'; import AgendaConnector from './Agenda/AgendaConnector';
import * as calendarViews from './calendarViews'; import * as calendarViews from './calendarViews';
import CalendarDaysConnector from './Day/CalendarDaysConnector'; import CalendarDaysConnector from './Day/CalendarDaysConnector';
@ -32,7 +33,7 @@ class Calendar extends Component {
{ {
!isFetching && !!error && !isFetching && !!error &&
<Alert kind={kinds.DANGER}>Unable to load the calendar</Alert> <Alert kind={kinds.DANGER}>{translate('CalendarLoadError')}</Alert>
} }
{ {

View File

@ -10,6 +10,7 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
import { align, icons } from 'Helpers/Props'; import { align, icons } from 'Helpers/Props';
import NoSeries from 'Series/NoSeries'; import NoSeries from 'Series/NoSeries';
import translate from 'Utilities/String/translate';
import CalendarConnector from './CalendarConnector'; import CalendarConnector from './CalendarConnector';
import CalendarFilterModal from './CalendarFilterModal'; import CalendarFilterModal from './CalendarFilterModal';
import CalendarLinkModal from './iCal/CalendarLinkModal'; import CalendarLinkModal from './iCal/CalendarLinkModal';
@ -95,11 +96,11 @@ class CalendarPage extends Component {
const PageComponent = hasSeries ? CalendarConnector : NoSeries; const PageComponent = hasSeries ? CalendarConnector : NoSeries;
return ( return (
<PageContent title="Calendar"> <PageContent title={translate('Calendar')}>
<PageToolbar> <PageToolbar>
<PageToolbarSection> <PageToolbarSection>
<PageToolbarButton <PageToolbarButton
label="iCal Link" label={translate('ICalLink')}
iconName={icons.CALENDAR} iconName={icons.CALENDAR}
onPress={this.onGetCalendarLinkPress} onPress={this.onGetCalendarLinkPress}
/> />
@ -107,14 +108,14 @@ class CalendarPage extends Component {
<PageToolbarSeparator /> <PageToolbarSeparator />
<PageToolbarButton <PageToolbarButton
label="RSS Sync" label={translate('RssSync')}
iconName={icons.RSS} iconName={icons.RSS}
isSpinning={isRssSyncExecuting} isSpinning={isRssSyncExecuting}
onPress={onRssSyncPress} onPress={onRssSyncPress}
/> />
<PageToolbarButton <PageToolbarButton
label="Search for Missing" label={translate('SearchForMissing')}
iconName={icons.SEARCH} iconName={icons.SEARCH}
isDisabled={!missingEpisodeIds.length} isDisabled={!missingEpisodeIds.length}
isSpinning={isSearchingForMissing} isSpinning={isSearchingForMissing}
@ -124,7 +125,7 @@ class CalendarPage extends Component {
<PageToolbarSection alignContent={align.RIGHT}> <PageToolbarSection alignContent={align.RIGHT}>
<PageToolbarButton <PageToolbarButton
label="Options" label={translate('Options')}
iconName={icons.POSTER} iconName={icons.POSTER}
onPress={this.onOptionsPress} onPress={this.onOptionsPress}
/> />

View File

@ -10,6 +10,7 @@ import episodeEntities from 'Episode/episodeEntities';
import { icons, kinds } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import formatTime from 'Utilities/Date/formatTime'; import formatTime from 'Utilities/Date/formatTime';
import padNumber from 'Utilities/Number/padNumber'; import padNumber from 'Utilities/Number/padNumber';
import translate from 'Utilities/String/translate';
import CalendarEventQueueDetails from './CalendarEventQueueDetails'; import CalendarEventQueueDetails from './CalendarEventQueueDetails';
import styles from './CalendarEvent.css'; import styles from './CalendarEvent.css';
@ -107,7 +108,7 @@ class CalendarEvent extends Component {
<Icon <Icon
className={styles.statusIcon} className={styles.statusIcon}
name={icons.WARNING} name={icons.WARNING}
title="Episode does not have an absolute episode number" title={translate('EpisodeMissingAbsoluteNumber')}
/> : /> :
null null
} }
@ -117,7 +118,7 @@ class CalendarEvent extends Component {
<Icon <Icon
className={styles.statusIcon} className={styles.statusIcon}
name={icons.WARNING} name={icons.WARNING}
title="Scene number hasn't been verified yet" title={translate('SceneNumberNotVerified')}
/> : /> :
null null
} }
@ -137,7 +138,7 @@ class CalendarEvent extends Component {
<Icon <Icon
className={styles.statusIcon} className={styles.statusIcon}
name={icons.DOWNLOADING} name={icons.DOWNLOADING}
title="Episode is downloading" title={translate('EpisodeIsDownloading')}
/> : /> :
null null
} }
@ -150,7 +151,7 @@ class CalendarEvent extends Component {
className={styles.statusIcon} className={styles.statusIcon}
name={icons.EPISODE_FILE} name={icons.EPISODE_FILE}
kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING} kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING}
title="Quality cutoff has not been met" title={translate('QualityCutoffNotMet')}
/> : /> :
null null
} }
@ -162,7 +163,7 @@ class CalendarEvent extends Component {
name={icons.INFO} name={icons.INFO}
kind={kinds.INFO} kind={kinds.INFO}
darken={fullColorEvents} darken={fullColorEvents}
title={seasonNumber === 1 ? 'Series premiere' : 'Season premiere'} title={seasonNumber === 1 ? translate('SeriesPremiere') : translate('SeasonPremiere')}
/> : /> :
null null
} }
@ -176,7 +177,7 @@ class CalendarEvent extends Component {
className={styles.statusIcon} className={styles.statusIcon}
name={icons.INFO} name={icons.INFO}
kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING} kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING}
title={series.status === 'ended' ? 'Series finale' : 'Season finale'} title={series.status === 'ended' ? translate('SeriesFinale') : translate('SeasonFinale')}
/> : /> :
null null
} }
@ -189,7 +190,7 @@ class CalendarEvent extends Component {
name={icons.INFO} name={icons.INFO}
kind={kinds.PINK} kind={kinds.PINK}
darken={fullColorEvents} darken={fullColorEvents}
title="Special" title={translate('Special')}
/> : /> :
null null
} }
@ -249,7 +250,7 @@ CalendarEvent.propTypes = {
hasFile: PropTypes.bool.isRequired, hasFile: PropTypes.bool.isRequired,
grabbed: PropTypes.bool, grabbed: PropTypes.bool,
queueItem: PropTypes.object, queueItem: PropTypes.object,
// These props come from the connector, not marked as required to apease TS for now. // These props come from the connector, not marked as required to appease TS for now.
showEpisodeInformation: PropTypes.bool, showEpisodeInformation: PropTypes.bool,
showFinaleIcon: PropTypes.bool, showFinaleIcon: PropTypes.bool,
showSpecialIcon: PropTypes.bool, showSpecialIcon: PropTypes.bool,

View File

@ -9,6 +9,7 @@ import Link from 'Components/Link/Link';
import { icons, kinds } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import formatTime from 'Utilities/Date/formatTime'; import formatTime from 'Utilities/Date/formatTime';
import padNumber from 'Utilities/Number/padNumber'; import padNumber from 'Utilities/Number/padNumber';
import translate from '../../Utilities/String/translate';
import styles from './CalendarEventGroup.css'; import styles from './CalendarEventGroup.css';
function getEventsInfo(series, events) { function getEventsInfo(series, events) {
@ -148,7 +149,7 @@ class CalendarEventGroup extends Component {
<Icon <Icon
containerClassName={styles.statusIcon} containerClassName={styles.statusIcon}
name={icons.WARNING} name={icons.WARNING}
title="Episode does not have an absolute episode number" title={translate('EpisodeMissingAbsoluteNumber')}
/> />
} }
@ -157,7 +158,7 @@ class CalendarEventGroup extends Component {
<Icon <Icon
containerClassName={styles.statusIcon} containerClassName={styles.statusIcon}
name={icons.DOWNLOADING} name={icons.DOWNLOADING}
title="An episode is downloading" title={translate('AnEpisodeIsDownloading')}
/> />
} }
@ -168,7 +169,7 @@ class CalendarEventGroup extends Component {
name={icons.INFO} name={icons.INFO}
kind={kinds.INFO} kind={kinds.INFO}
darken={fullColorEvents} darken={fullColorEvents}
title={seasonNumber === 1 ? 'Series Premiere' : 'Season Premiere'} title={seasonNumber === 1 ? translate('SeriesPremiere') : translate('SeasonPremiere')}
/> />
} }
@ -181,7 +182,7 @@ class CalendarEventGroup extends Component {
containerClassName={styles.statusIcon} containerClassName={styles.statusIcon}
name={icons.INFO} name={icons.INFO}
kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING} kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING}
title={series.status === 'ended' ? 'Series finale' : 'Season finale'} title={series.status === 'ended' ? translate('SeriesFinale') : translate('SeasonFinale')}
/> />
} }
</div> </div>

View File

@ -10,6 +10,7 @@ import MenuButton from 'Components/Menu/MenuButton';
import MenuContent from 'Components/Menu/MenuContent'; import MenuContent from 'Components/Menu/MenuContent';
import ViewMenuItem from 'Components/Menu/ViewMenuItem'; import ViewMenuItem from 'Components/Menu/ViewMenuItem';
import { align, icons } from 'Helpers/Props'; import { align, icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import CalendarHeaderViewButton from './CalendarHeaderViewButton'; import CalendarHeaderViewButton from './CalendarHeaderViewButton';
import styles from './CalendarHeader.css'; import styles from './CalendarHeader.css';
@ -23,7 +24,7 @@ function getTitle(time, start, end, view, longDateFormat) {
} else if (view === 'month') { } else if (view === 'month') {
return timeMoment.format('MMMM YYYY'); return timeMoment.format('MMMM YYYY');
} else if (view === 'agenda') { } else if (view === 'agenda') {
return 'Agenda'; return translate('Agenda');
} }
let startFormat = 'MMM D YYYY'; let startFormat = 'MMM D YYYY';
@ -125,7 +126,7 @@ class CalendarHeader extends Component {
isDisabled={view === calendarViews.AGENDA} isDisabled={view === calendarViews.AGENDA}
onPress={onTodayPress} onPress={onTodayPress}
> >
Today {translate('Today')}
</Button> </Button>
</div> </div>
@ -167,7 +168,7 @@ class CalendarHeader extends Component {
selectedView={view} selectedView={view}
onPress={this.onViewChange} onPress={this.onViewChange}
> >
Month {translate('Month')}
</ViewMenuItem> </ViewMenuItem>
} }
@ -176,7 +177,7 @@ class CalendarHeader extends Component {
selectedView={view} selectedView={view}
onPress={this.onViewChange} onPress={this.onViewChange}
> >
Week {translate('Week')}
</ViewMenuItem> </ViewMenuItem>
<ViewMenuItem <ViewMenuItem
@ -184,7 +185,7 @@ class CalendarHeader extends Component {
selectedView={view} selectedView={view}
onPress={this.onViewChange} onPress={this.onViewChange}
> >
Forecast {translate('Forecast')}
</ViewMenuItem> </ViewMenuItem>
<ViewMenuItem <ViewMenuItem
@ -192,7 +193,7 @@ class CalendarHeader extends Component {
selectedView={view} selectedView={view}
onPress={this.onViewChange} onPress={this.onViewChange}
> >
Day {translate('Day')}
</ViewMenuItem> </ViewMenuItem>
<ViewMenuItem <ViewMenuItem
@ -200,7 +201,7 @@ class CalendarHeader extends Component {
selectedView={view} selectedView={view}
onPress={this.onViewChange} onPress={this.onViewChange}
> >
Agenda {translate('Agenda')}
</ViewMenuItem> </ViewMenuItem>
</MenuContent> </MenuContent>
</Menu> : </Menu> :

View File

@ -1,6 +1,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { icons, kinds } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import LegendIconItem from './LegendIconItem'; import LegendIconItem from './LegendIconItem';
import LegendItem from './LegendItem'; import LegendItem from './LegendItem';
import styles from './Legend.css'; import styles from './Legend.css';
@ -24,7 +25,7 @@ function Legend(props) {
name="Finale" name="Finale"
icon={icons.INFO} icon={icons.INFO}
kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING} kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING}
tooltip="Series or season finale" tooltip={translate('CalendarLegendFinaleTooltip')}
/> />
); );
} }
@ -36,7 +37,7 @@ function Legend(props) {
icon={icons.INFO} icon={icons.INFO}
kind={kinds.PINK} kind={kinds.PINK}
darken={fullColorEvents} darken={fullColorEvents}
tooltip="Special episode" tooltip={translate('SpecialEpisode')}
/> />
); );
} }
@ -47,7 +48,7 @@ function Legend(props) {
name="Cutoff Not Met" name="Cutoff Not Met"
icon={icons.EPISODE_FILE} icon={icons.EPISODE_FILE}
kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING} kind={fullColorEvents ? kinds.DEFAULT : kinds.WARNING}
tooltip="Quality cutoff has not been met" tooltip={translate('QualityCutoffNotMet')}
/> />
); );
} }
@ -57,7 +58,7 @@ function Legend(props) {
<div> <div>
<LegendItem <LegendItem
status="unaired" status="unaired"
tooltip="Episode hasn't aired yet" tooltip={translate('CalendarLegendUnairedTooltip')}
isAgendaView={isAgendaView} isAgendaView={isAgendaView}
fullColorEvents={fullColorEvents} fullColorEvents={fullColorEvents}
colorImpairedMode={colorImpairedMode} colorImpairedMode={colorImpairedMode}
@ -65,7 +66,7 @@ function Legend(props) {
<LegendItem <LegendItem
status="unmonitored" status="unmonitored"
tooltip="Episode is unmonitored" tooltip={translate('CalendarLegendUnmonitoredTooltip')}
isAgendaView={isAgendaView} isAgendaView={isAgendaView}
fullColorEvents={fullColorEvents} fullColorEvents={fullColorEvents}
colorImpairedMode={colorImpairedMode} colorImpairedMode={colorImpairedMode}
@ -76,7 +77,7 @@ function Legend(props) {
<LegendItem <LegendItem
status="onAir" status="onAir"
name="On Air" name="On Air"
tooltip="Episode is currently airing" tooltip={translate('CalendarLegendOnAirTooltip')}
isAgendaView={isAgendaView} isAgendaView={isAgendaView}
fullColorEvents={fullColorEvents} fullColorEvents={fullColorEvents}
colorImpairedMode={colorImpairedMode} colorImpairedMode={colorImpairedMode}
@ -84,7 +85,7 @@ function Legend(props) {
<LegendItem <LegendItem
status="missing" status="missing"
tooltip="Episode has aired and is missing from disk" tooltip={translate('CalendarLegendMissingTooltip')}
isAgendaView={isAgendaView} isAgendaView={isAgendaView}
fullColorEvents={fullColorEvents} fullColorEvents={fullColorEvents}
colorImpairedMode={colorImpairedMode} colorImpairedMode={colorImpairedMode}
@ -94,7 +95,7 @@ function Legend(props) {
<div> <div>
<LegendItem <LegendItem
status="downloading" status="downloading"
tooltip="Episode is currently downloading" tooltip={translate('CalendarLegendDownloadingTooltip')}
isAgendaView={isAgendaView} isAgendaView={isAgendaView}
fullColorEvents={fullColorEvents} fullColorEvents={fullColorEvents}
colorImpairedMode={colorImpairedMode} colorImpairedMode={colorImpairedMode}
@ -102,7 +103,7 @@ function Legend(props) {
<LegendItem <LegendItem
status="downloaded" status="downloaded"
tooltip="Episode was downloaded and sorted" tooltip={translate('CalendarLegendDownloadedTooltip')}
isAgendaView={isAgendaView} isAgendaView={isAgendaView}
fullColorEvents={fullColorEvents} fullColorEvents={fullColorEvents}
colorImpairedMode={colorImpairedMode} colorImpairedMode={colorImpairedMode}
@ -115,7 +116,7 @@ function Legend(props) {
icon={icons.INFO} icon={icons.INFO}
kind={kinds.INFO} kind={kinds.INFO}
darken={true} darken={true}
tooltip="Series or season premiere" tooltip={translate('CalendarLegendPremiereTooltip')}
/> />
{iconsToShow[0]} {iconsToShow[0]}

View File

@ -12,6 +12,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader'; import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes } from 'Helpers/Props'; import { inputTypes } from 'Helpers/Props';
import { firstDayOfWeekOptions, timeFormatOptions, weekColumnOptions } from 'Settings/UI/UISettings'; import { firstDayOfWeekOptions, timeFormatOptions, weekColumnOptions } from 'Settings/UI/UISettings';
import translate from 'Utilities/String/translate';
class CalendarOptionsModalContent extends Component { class CalendarOptionsModalContent extends Component {
@ -112,90 +113,90 @@ class CalendarOptionsModalContent extends Component {
return ( return (
<ModalContent onModalClose={onModalClose}> <ModalContent onModalClose={onModalClose}>
<ModalHeader> <ModalHeader>
Calendar Options {translate('CalendarOptions')}
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
<FieldSet legend="Local"> <FieldSet legend={translate('Local')}>
<Form> <Form>
<FormGroup> <FormGroup>
<FormLabel>Collapse Multiple Episodes</FormLabel> <FormLabel>{translate('CollapseMultipleEpisodes')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="collapseMultipleEpisodes" name="collapseMultipleEpisodes"
value={collapseMultipleEpisodes} value={collapseMultipleEpisodes}
helpText="Collapse multiple episodes airing on the same day" helpText={translate('CollapseMultipleEpisodesHelpText')}
onChange={this.onOptionInputChange} onChange={this.onOptionInputChange}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Show Episode Information</FormLabel> <FormLabel>{translate('ShowEpisodeInformation')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="showEpisodeInformation" name="showEpisodeInformation"
value={showEpisodeInformation} value={showEpisodeInformation}
helpText="Show episode title and number" helpText={translate('ShowEpisodeInformationHelpText')}
onChange={this.onOptionInputChange} onChange={this.onOptionInputChange}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Icon for Finales</FormLabel> <FormLabel>{translate('IconForFinales')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="showFinaleIcon" name="showFinaleIcon"
value={showFinaleIcon} value={showFinaleIcon}
helpText="Show icon for series/season finales based on available episode information" helpText={translate('IconForFinalesHelpText')}
onChange={this.onOptionInputChange} onChange={this.onOptionInputChange}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Icon for Specials</FormLabel> <FormLabel>{translate('IconForSpecials')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="showSpecialIcon" name="showSpecialIcon"
value={showSpecialIcon} value={showSpecialIcon}
helpText="Show icon for special episodes (season 0)" helpText={translate('IconForSpecialsHelpText')}
onChange={this.onOptionInputChange} onChange={this.onOptionInputChange}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Icon for Cutoff Unmet</FormLabel> <FormLabel>{translate('IconForCutoffUnmet')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="showCutoffUnmetIcon" name="showCutoffUnmetIcon"
value={showCutoffUnmetIcon} value={showCutoffUnmetIcon}
helpText="Show icon for files when the cutoff hasn't been met" helpText={translate('IconForCutoffUnmetHelpText')}
onChange={this.onOptionInputChange} onChange={this.onOptionInputChange}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Full Color Events</FormLabel> <FormLabel>{translate('FullColorEvents')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="fullColorEvents" name="fullColorEvents"
value={fullColorEvents} value={fullColorEvents}
helpText="Altered style to color the entire event with the status color, instead of just the left edge. Does not apply to Agenda" helpText={translate('FullColorEventsHelpText')}
onChange={this.onOptionInputChange} onChange={this.onOptionInputChange}
/> />
</FormGroup> </FormGroup>
</Form> </Form>
</FieldSet> </FieldSet>
<FieldSet legend="Global"> <FieldSet legend={translate('Global')}>
<Form> <Form>
<FormGroup> <FormGroup>
<FormLabel>First Day of Week</FormLabel> <FormLabel>{translate('FirstDayOfWeek')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.SELECT} type={inputTypes.SELECT}
@ -207,7 +208,7 @@ class CalendarOptionsModalContent extends Component {
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Week Column Header</FormLabel> <FormLabel>{translate('WeekColumnHeader')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.SELECT} type={inputTypes.SELECT}
@ -215,12 +216,12 @@ class CalendarOptionsModalContent extends Component {
values={weekColumnOptions} values={weekColumnOptions}
value={calendarWeekColumnHeader} value={calendarWeekColumnHeader}
onChange={this.onGlobalInputChange} onChange={this.onGlobalInputChange}
helpText="Shown above each column when week is the active view" helpText={translate('WeekColumnHeaderHelpText')}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Time Format</FormLabel> <FormLabel>{translate('TimeFormat')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.SELECT} type={inputTypes.SELECT}
@ -232,13 +233,13 @@ class CalendarOptionsModalContent extends Component {
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Enable Color-Impaired Mode</FormLabel> <FormLabel>{translate('EnableColorImpairedMode')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="enableColorImpairedMode" name="enableColorImpairedMode"
value={enableColorImpairedMode} value={enableColorImpairedMode}
helpText="Altered style to allow color-impaired users to better distinguish color coded information" helpText={translate('EnableColorImpairedModeHelpText')}
onChange={this.onGlobalInputChange} onChange={this.onGlobalInputChange}
/> />
</FormGroup> </FormGroup>
@ -248,7 +249,7 @@ class CalendarOptionsModalContent extends Component {
<ModalFooter> <ModalFooter>
<Button onPress={onModalClose}> <Button onPress={onModalClose}>
Close {translate('Close')}
</Button> </Button>
</ModalFooter> </ModalFooter>
</ModalContent> </ModalContent>

View File

@ -13,6 +13,7 @@ import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter'; import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader'; import ModalHeader from 'Components/Modal/ModalHeader';
import { icons, inputTypes, kinds, sizes } from 'Helpers/Props'; import { icons, inputTypes, kinds, sizes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
function getUrls(state) { function getUrls(state) {
const { const {
@ -115,55 +116,55 @@ class CalendarLinkModalContent extends Component {
return ( return (
<ModalContent onModalClose={onModalClose}> <ModalContent onModalClose={onModalClose}>
<ModalHeader> <ModalHeader>
Sonarr Calendar Feed {translate('CalendarFeed', { appName: 'Sonarr' })}
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
<Form> <Form>
<FormGroup> <FormGroup>
<FormLabel>Include Unmonitored</FormLabel> <FormLabel>{translate('IncludeUnmonitored')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="unmonitored" name="unmonitored"
value={unmonitored} value={unmonitored}
helpText="Include unmonitored episodes in the iCal feed" helpText={translate('ICalIncludeUnmonitoredHelpText')}
onChange={this.onInputChange} onChange={this.onInputChange}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Season Premieres Only</FormLabel> <FormLabel>{translate('SeasonPremieresOnly')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="premieresOnly" name="premieresOnly"
value={premieresOnly} value={premieresOnly}
helpText="Only the first episode in a season will be in the feed" helpText={translate('ICalSeasonPremieresOnlyHelpText')}
onChange={this.onInputChange} onChange={this.onInputChange}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Show as All-Day Events</FormLabel> <FormLabel>{translate('ICalShowAsAllDayEvents')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="asAllDay" name="asAllDay"
value={asAllDay} value={asAllDay}
helpText="Events will appear as all-day events in your calendar" helpText={translate('ICalShowAsAllDayEventsHelpText')}
onChange={this.onInputChange} onChange={this.onInputChange}
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Tags</FormLabel> <FormLabel>{translate('Tags')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.TAG} type={inputTypes.TAG}
name="tags" name="tags"
value={tags} value={tags}
helpText="Feed will only contain series with at least one matching tag" helpText={translate('ICalTagsHelpText')}
onChange={this.onInputChange} onChange={this.onInputChange}
/> />
</FormGroup> </FormGroup>
@ -171,14 +172,14 @@ class CalendarLinkModalContent extends Component {
<FormGroup <FormGroup
size={sizes.LARGE} size={sizes.LARGE}
> >
<FormLabel>iCal Feed</FormLabel> <FormLabel>{translate('ICalFeed')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.TEXT} type={inputTypes.TEXT}
name="iCalHttpUrl" name="iCalHttpUrl"
value={iCalHttpUrl} value={iCalHttpUrl}
readOnly={true} readOnly={true}
helpText="Copy this URL to your client(s) or click to subscribe if your browser supports webcal" helpText={translate('ICalFeedHelpText')}
buttons={[ buttons={[
<ClipboardButton <ClipboardButton
key="copy" key="copy"
@ -205,7 +206,7 @@ class CalendarLinkModalContent extends Component {
<ModalFooter> <ModalFooter>
<Button onPress={onModalClose}> <Button onPress={onModalClose}>
Close {translate('Close')}
</Button> </Button>
</ModalFooter> </ModalFooter>
</ModalContent> </ModalContent>

View File

@ -46,6 +46,7 @@
"AfterManualRefresh": "After Manual Refresh", "AfterManualRefresh": "After Manual Refresh",
"Age": "Age", "Age": "Age",
"AgeWhenGrabbed": "Age (when grabbed)", "AgeWhenGrabbed": "Age (when grabbed)",
"Agenda": "Agenda",
"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",
@ -53,6 +54,7 @@
"AllTitles": "All Titles", "AllTitles": "All Titles",
"AlreadyInYourLibrary": "Already in your library", "AlreadyInYourLibrary": "Already in your library",
"Always": "Always", "Always": "Always",
"AnEpisodeIsDownloading": "An Episode is downloading",
"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",
@ -123,7 +125,17 @@
"BypassDelayIfHighestQualityHelpText": "Bypass delay when release has the highest enabled quality in the quality profile with the preferred protocol", "BypassDelayIfHighestQualityHelpText": "Bypass delay when release has the highest enabled quality in the quality profile with the preferred protocol",
"BypassProxyForLocalAddresses": "Bypass Proxy for Local Addresses", "BypassProxyForLocalAddresses": "Bypass Proxy for Local Addresses",
"Calendar": "Calendar", "Calendar": "Calendar",
"CalendarFeed": "{appName} Calendar Feed",
"CalendarLegendDownloadedTooltip": "Episode was downloaded and sorted",
"CalendarLegendDownloadingTooltip": "Episode is currently downloading",
"CalendarLegendFinaleTooltip": "Series or season finale",
"CalendarLegendMissingTooltip": "Episode has aired and is missing from disk",
"CalendarLegendOnAirTooltip": "Episode is currently airing",
"CalendarLegendPremiereTooltip": "Series or season premiere",
"CalendarLegendUnairedTooltip": "Episode hasn't aired yet",
"CalendarLegendUnmonitoredTooltip": "Episode is unmonitored",
"CalendarLoadError": "Unable to load the calendar", "CalendarLoadError": "Unable to load the calendar",
"CalendarOptions": "Calendar Options",
"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", "CancelProcessing": "Cancel Processing",
@ -149,6 +161,8 @@
"CloneIndexer": "Clone Indexer", "CloneIndexer": "Clone Indexer",
"CloneProfile": "Clone Profile", "CloneProfile": "Clone Profile",
"Close": "Close", "Close": "Close",
"CollapseMultipleEpisodes": "Collapse Multiple Episodes",
"CollapseMultipleEpisodesHelpText": "Collapse multiple episodes airing on the same day",
"CollectionsLoadError": "Unable to load collections", "CollectionsLoadError": "Unable to load collections",
"ColonReplacement": "Colon Replacement", "ColonReplacement": "Colon Replacement",
"ColonReplacementFormatHelpText": "Change how Sonarr handles colon replacement", "ColonReplacementFormatHelpText": "Change how Sonarr handles colon replacement",
@ -192,6 +206,7 @@
"Dash": "Dash", "Dash": "Dash",
"Date": "Date", "Date": "Date",
"Dates": "Dates", "Dates": "Dates",
"Day": "Day",
"Debug": "Debug", "Debug": "Debug",
"DefaultCase": "Default Case", "DefaultCase": "Default Case",
"DefaultDelayProfile": "This is the default profile. It applies to all series that don't have an explicit profile.", "DefaultDelayProfile": "This is the default profile. It applies to all series that don't have an explicit profile.",
@ -342,6 +357,8 @@
"EpisodeImported": "Episode Imported", "EpisodeImported": "Episode Imported",
"EpisodeImportedTooltip": "Episode downloaded successfully and picked up from download client", "EpisodeImportedTooltip": "Episode downloaded successfully and picked up from download client",
"EpisodeInfo": "Episode Info", "EpisodeInfo": "Episode Info",
"EpisodeIsDownloading": "Episode is downloading",
"EpisodeMissingAbsoluteNumber": "Episode does not have an absolute episode number",
"EpisodeNaming": "Episode Naming", "EpisodeNaming": "Episode Naming",
"EpisodeNumbers": "Episode Number(s)", "EpisodeNumbers": "Episode Number(s)",
"EpisodeProgress": "Episode Progress", "EpisodeProgress": "Episode Progress",
@ -372,20 +389,25 @@
"FileNameTokens": "File Name Tokens", "FileNameTokens": "File Name Tokens",
"FileNames": "File Names", "FileNames": "File Names",
"Filename": "Filename", "Filename": "Filename",
"FinaleTooltip": "Series or season finale",
"FirstDayOfWeek": "First Day of Week", "FirstDayOfWeek": "First Day of Week",
"Fixed": "Fixed", "Fixed": "Fixed",
"Folder": "Folder", "Folder": "Folder",
"Folders": "Folders", "Folders": "Folders",
"Forecast": "Forecast",
"Formats": "Formats", "Formats": "Formats",
"Forums": "Forums", "Forums": "Forums",
"FreeSpace": "Free Space", "FreeSpace": "Free Space",
"From": "From", "From": "From",
"FullColorEvents": "Full Color Events",
"FullColorEventsHelpText": "Altered style to color the entire event with the status color, instead of just the left edge. Does not apply to Agenda",
"FullSeason": "Full Season", "FullSeason": "Full Season",
"General": "General", "General": "General",
"GeneralSettings": "General Settings", "GeneralSettings": "General Settings",
"GeneralSettingsLoadError": "Unable to load General settings", "GeneralSettingsLoadError": "Unable to load General settings",
"GeneralSettingsSummary": "Port, SSL, username/password, proxy, analytics and updates", "GeneralSettingsSummary": "Port, SSL, username/password, proxy, analytics and updates",
"Genres": "Genres", "Genres": "Genres",
"Global": "Global",
"GrabId": "Grab ID", "GrabId": "Grab ID",
"GrabSelected": "Grab Selected", "GrabSelected": "Grab Selected",
"Grabbed": "Grabbed", "Grabbed": "Grabbed",
@ -403,8 +425,21 @@
"Hostname": "Hostname", "Hostname": "Hostname",
"HourShorthand": "h", "HourShorthand": "h",
"HttpHttps": "HTTP(S)", "HttpHttps": "HTTP(S)",
"ICalFeed": "iCal Feed",
"ICalFeedHelpText": "Copy this URL to your client(s) or click to subscribe if your browser supports webcal",
"ICalIncludeUnmonitoredHelpText": "Include unmonitored episodes in the iCal feed",
"ICalLink": "iCal Link",
"ICalSeasonPremieresOnlyHelpText": "Only the first episode in a season will be in the feed",
"ICalShowAsAllDayEventsHelpText": "Events will appear as all-day events in your calendar",
"ICalTagsHelpText": "Feed will only contain series with at least one matching tag",
"IRC": "IRC", "IRC": "IRC",
"IRCLinkText": "#sonarr on Libera", "IRCLinkText": "#sonarr on Libera",
"IconForCutoffUnmet": "Icon for Cutoff Unmet",
"IconForCutoffUnmetHelpText": "Show icon for files when the cutoff hasn't been met",
"IconForFinales": "Icon for Finales",
"IconForFinalesHelpText": "Show icon for series/season finales based on available episode information",
"IconForSpecials": "Icon for Specials",
"IconForSpecialsHelpText": "Show icon for special episodes (season 0)",
"Ignored": "Ignored", "Ignored": "Ignored",
"IgnoredAddresses": "Ignored Addresses", "IgnoredAddresses": "Ignored Addresses",
"Images": "Images", "Images": "Images",
@ -495,6 +530,7 @@
"ListTagsHelpText": "Tags that will be added on import from this list", "ListTagsHelpText": "Tags that will be added on import from this list",
"ListWillRefreshEveryInterval": "List will refresh every {refreshInterval}", "ListWillRefreshEveryInterval": "List will refresh every {refreshInterval}",
"ListsLoadError": "Unable to load Lists", "ListsLoadError": "Unable to load Lists",
"Local": "Local",
"LocalAirDate": "Local Air Date", "LocalAirDate": "Local Air Date",
"LocalPath": "Local Path", "LocalPath": "Local Path",
"Location": "Location", "Location": "Location",
@ -575,6 +611,7 @@
"Monitored": "Monitored", "Monitored": "Monitored",
"MonitoredOnly": "Monitored Only", "MonitoredOnly": "Monitored Only",
"MonitoringOptions": "Monitoring Options", "MonitoringOptions": "Monitoring Options",
"Month": "Month",
"MoreDetails": "More details", "MoreDetails": "More details",
"MoreInfo": "More Info", "MoreInfo": "More Info",
"MountHealthCheckMessage": "Mount containing a series path is mounted read-only: ", "MountHealthCheckMessage": "Mount containing a series path is mounted read-only: ",
@ -703,6 +740,7 @@
"QualitiesHelpText": "Qualities higher in the list are more preferred. Qualities within the same group are equal. Only checked qualities are wanted", "QualitiesHelpText": "Qualities higher in the list are more preferred. Qualities within the same group are equal. Only checked qualities are wanted",
"QualitiesLoadError": "Unable to load qualities", "QualitiesLoadError": "Unable to load qualities",
"Quality": "Quality", "Quality": "Quality",
"QualityCutoffNotMet": "Quality cutoff has not been met",
"QualityDefinitions": "Quality Definitions", "QualityDefinitions": "Quality Definitions",
"QualityDefinitionsLoadError": "Unable to load Quality Definitions", "QualityDefinitionsLoadError": "Unable to load Quality Definitions",
"QualityLimitsHelpText": "Limits are automatically adjusted for the series runtime and number of episodes in the file.", "QualityLimitsHelpText": "Limits are automatically adjusted for the series runtime and number of episodes in the file.",
@ -844,6 +882,7 @@
"RootFoldersLoadError": "Unable to load root folders", "RootFoldersLoadError": "Unable to load root folders",
"Rss": "RSS", "Rss": "RSS",
"RssIsNotSupportedWithThisIndexer": "RSS is not supported with this indexer", "RssIsNotSupportedWithThisIndexer": "RSS is not supported with this indexer",
"RssSync": "RSS Sync",
"RssSyncInterval": "RSS Sync Interval", "RssSyncInterval": "RSS Sync Interval",
"RssSyncIntervalHelpText": "Interval in minutes. Set to zero to disable (this will stop all automatic release grabbing)", "RssSyncIntervalHelpText": "Interval in minutes. Set to zero to disable (this will stop all automatic release grabbing)",
"RssSyncIntervalHelpTextWarning": "This will apply to all indexers, please follow the rules set forth by them", "RssSyncIntervalHelpTextWarning": "This will apply to all indexers, please follow the rules set forth by them",
@ -852,6 +891,7 @@
"SaveChanges": "Save Changes", "SaveChanges": "Save Changes",
"SaveSettings": "Save Settings", "SaveSettings": "Save Settings",
"Scene": "Scene", "Scene": "Scene",
"SceneNumberNotVerified": "Scene number hasn't been verified yet",
"SceneNumbering": "Scene Numbering", "SceneNumbering": "Scene Numbering",
"Scheduled": "Scheduled", "Scheduled": "Scheduled",
"Score": "Score", "Score": "Score",
@ -859,14 +899,18 @@
"ScriptPath": "Script Path", "ScriptPath": "Script Path",
"SearchByTvdbId": "You can also search using TVDB ID of a show. eg. tvdb:71663", "SearchByTvdbId": "You can also search using TVDB ID of a show. eg. tvdb:71663",
"SearchFailedError": "Search failed, please try again later.", "SearchFailedError": "Search failed, please try again later.",
"SearchForMissing": "Search for Missing",
"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",
"SeasonCount": "Season Count", "SeasonCount": "Season Count",
"SeasonFinale": "Season Finale",
"SeasonFolder": "Season Folder", "SeasonFolder": "Season Folder",
"SeasonFolderFormat": "Season Folder Format", "SeasonFolderFormat": "Season Folder Format",
"SeasonNumber": "Season Number", "SeasonNumber": "Season Number",
"SeasonPack": "Season Pack", "SeasonPack": "Season Pack",
"SeasonPremiere": "Season Premiere",
"SeasonPremieresOnly": "Season Premieres Only",
"Seasons": "Seasons", "Seasons": "Seasons",
"Security": "Security", "Security": "Security",
"Seeders": "Seeders", "Seeders": "Seeders",
@ -875,12 +919,14 @@
"Series": "Series", "Series": "Series",
"SeriesAndEpisodeInformationIsProvidedByTheTVDB": "Series and episode information is provided by TheTVDB.com. [Please consider supporting them](https://www.thetvdb.com/subscribe).", "SeriesAndEpisodeInformationIsProvidedByTheTVDB": "Series and episode information is provided by TheTVDB.com. [Please consider supporting them](https://www.thetvdb.com/subscribe).",
"SeriesEditor": "Series Editor", "SeriesEditor": "Series Editor",
"SeriesFinale": "Series Finale",
"SeriesFolderFormat": "Series Folder Format", "SeriesFolderFormat": "Series Folder Format",
"SeriesFolderFormatHelpText": "Used when adding a new series or moving series via the series editor", "SeriesFolderFormatHelpText": "Used when adding a new series or moving series via the series editor",
"SeriesFolderImportedTooltip": "Episode imported from series folder", "SeriesFolderImportedTooltip": "Episode imported from series folder",
"SeriesID": "Series ID", "SeriesID": "Series ID",
"SeriesLoadError": "Unable to load Series", "SeriesLoadError": "Unable to load Series",
"SeriesMatchType": "Series Match Type", "SeriesMatchType": "Series Match Type",
"SeriesPremiere": "Series Premiere",
"SeriesTitle": "Series Title", "SeriesTitle": "Series Title",
"SeriesTitleToExcludeHelpText": "The name of the series to exclude", "SeriesTitleToExcludeHelpText": "The name of the series to exclude",
"SeriesType": "Series Type", "SeriesType": "Series Type",
@ -893,6 +939,9 @@
"Settings": "Settings", "Settings": "Settings",
"ShortDateFormat": "Short Date Format", "ShortDateFormat": "Short Date Format",
"ShowAdvanced": "Show Advanced", "ShowAdvanced": "Show Advanced",
"ICalShowAsAllDayEvents": "Show as All-Day Events",
"ShowEpisodeInformation": "Show Episode Information",
"ShowEpisodeInformationHelpText": "Show episode title and number",
"ShowRelativeDates": "Show Relative Dates", "ShowRelativeDates": "Show Relative Dates",
"ShowRelativeDatesHelpText": "Show relative (Today/Yesterday/etc) or absolute dates", "ShowRelativeDatesHelpText": "Show relative (Today/Yesterday/etc) or absolute dates",
"ShownClickToHide": "Shown, click to hide", "ShownClickToHide": "Shown, click to hide",
@ -919,6 +968,7 @@
"SourceTitle": "Source Title", "SourceTitle": "Source Title",
"Space": "Space", "Space": "Space",
"Special": "Special", "Special": "Special",
"SpecialEpisode": "Special Episode",
"SpecialsFolderFormat": "Specials Folder Format", "SpecialsFolderFormat": "Specials Folder Format",
"SslCertPassword": "SSL Cert Password", "SslCertPassword": "SSL Cert Password",
"SslCertPasswordHelpText": "Password for pfx file", "SslCertPasswordHelpText": "Password for pfx file",
@ -968,6 +1018,7 @@
"TimeFormat": "Time Format", "TimeFormat": "Time Format",
"TimeLeft": "Time Left", "TimeLeft": "Time Left",
"Title": "Title", "Title": "Title",
"Today": "Today",
"TorrentDelay": "Torrent Delay", "TorrentDelay": "Torrent Delay",
"TorrentDelayHelpText": "Delay in minutes to wait before grabbing a torrent", "TorrentDelayHelpText": "Delay in minutes to wait before grabbing a torrent",
"TorrentDelayTime": "Torrent Delay: {torrentDelay}", "TorrentDelayTime": "Torrent Delay: {torrentDelay}",
@ -1045,6 +1096,7 @@
"WantMoreControlAddACustomFormat": "Want more control over which downloads are preferred? Add a [Custom Format](/settings/customformats)", "WantMoreControlAddACustomFormat": "Want more control over which downloads are preferred? Add a [Custom Format](/settings/customformats)",
"Wanted": "Wanted", "Wanted": "Wanted",
"Warn": "Warn", "Warn": "Warn",
"Week": "Week",
"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?", "WhyCantIFindMyShow": "Why can't I find my show?",