From d87bf5ae63e5e536560c231612e613404376986d Mon Sep 17 00:00:00 2001 From: nitsua Date: Fri, 16 Apr 2021 22:01:47 -0400 Subject: [PATCH] Localization framework --- frontend/src/Activity/Blacklist/Blacklist.js | 19 +- .../Blacklist/BlacklistDetailsModal.js | 9 +- .../src/Activity/Blacklist/BlacklistRow.js | 3 +- .../History/Details/HistoryDetails.js | 61 +- frontend/src/Activity/History/History.js | 11 +- frontend/src/Activity/Queue/Queue.js | 11 +- frontend/src/Activity/Queue/QueueDetails.js | 13 +- frontend/src/Activity/Queue/QueueOptions.js | 7 +- frontend/src/Activity/Queue/QueueRow.js | 5 +- .../src/Activity/Queue/QueueStatusCell.js | 3 +- .../Activity/Queue/RemoveQueueItemModal.js | 19 +- .../Activity/Queue/RemoveQueueItemsModal.js | 15 +- frontend/src/Activity/Queue/TimeleftCell.js | 5 +- .../AuthorMonitoringOptionsPopoverContent.js | 15 +- frontend/src/App/AppUpdatedModalContent.js | 5 +- .../Author/Delete/DeleteAuthorModalContent.js | 13 +- frontend/src/Author/Details/AuthorDetails.js | 35 +- .../src/Author/Details/AuthorDetailsHeader.js | 9 +- .../Details/AuthorDetailsPageConnector.js | 3 +- .../src/Author/Details/AuthorDetailsSeries.js | 5 +- frontend/src/Author/Details/BookRow.js | 3 +- .../src/Author/Edit/EditAuthorModalContent.js | 23 +- frontend/src/Author/Editor/AuthorEditor.js | 5 +- .../src/Author/Editor/AuthorEditorFooter.js | 11 +- .../Author/Editor/Tags/TagsModalContent.js | 25 +- .../src/Author/History/AuthorHistoryRow.js | 9 +- .../History/AuthorHistoryTableContent.js | 9 +- frontend/src/Author/Index/AuthorIndex.js | 13 +- .../src/Author/Index/AuthorIndexFooter.js | 33 +- .../Author/Index/Banners/AuthorIndexBanner.js | 9 +- .../AuthorIndexBannerOptionsModalContent.js | 35 +- .../Index/Overview/AuthorIndexOverview.js | 9 +- .../AuthorIndexOverviewOptionsModalContent.js | 45 +- .../Author/Index/Posters/AuthorIndexPoster.js | 9 +- .../AuthorIndexPosterOptionsModalContent.js | 35 +- .../ProgressBar/AuthorIndexProgressBar.js | 3 +- .../Index/Table/AuthorIndexActionsCell.js | 5 +- .../src/Author/Index/Table/AuthorIndexRow.js | 9 +- .../Index/Table/AuthorIndexTableOptions.js | 13 +- .../Author/Index/Table/AuthorStatusCell.js | 5 +- .../src/Book/Delete/DeleteBookModalContent.js | 15 +- frontend/src/Book/Details/BookDetails.js | 25 +- .../Book/Details/BookDetailsPageConnector.js | 3 +- .../src/Book/Edit/EditBookModalContent.js | 19 +- frontend/src/Book/EpisodeNumber.js | 7 +- frontend/src/Book/EpisodeStatus.js | 15 +- frontend/src/Book/SceneInfo.js | 9 +- .../BookFile/Editor/BookFileActionsCell.js | 7 +- .../Editor/BookFileEditorTableContent.js | 7 +- frontend/src/BookFile/ExpandingFileDetails.js | 3 +- frontend/src/BookFile/FileDetails.js | 47 +- frontend/src/Bookshelf/Bookshelf.js | 3 +- frontend/src/Bookshelf/BookshelfBook.js | 3 +- frontend/src/Bookshelf/BookshelfRow.js | 3 +- frontend/src/Calendar/Agenda/AgendaEvent.js | 3 +- frontend/src/Calendar/Calendar.js | 5 +- frontend/src/Calendar/CalendarPage.js | 9 +- frontend/src/Calendar/Events/CalendarEvent.js | 3 +- .../Events/CalendarEventQueueDetails.js | 3 +- .../Options/CalendarOptionsModalContent.js | 37 +- .../Calendar/iCal/CalendarLinkModalContent.js | 31 +- .../FileBrowser/FileBrowserModalContent.js | 7 +- .../Filter/CustomFilters/CustomFilter.js | 3 +- .../src/Components/Form/FormInputGroup.js | 3 +- frontend/src/Components/NotFound.js | 3 +- frontend/src/Components/Page/PageConnector.js | 15 +- .../Table/TableOptions/TableOptionsModal.js | 11 +- .../Author/SelectAuthorModalContent.js | 3 +- .../Book/SelectBookModalContent.js | 3 +- .../InteractiveImport/Book/SelectBookRow.js | 3 +- .../Folder/RecentFolderRow.js | 3 +- .../Interactive/InteractiveImportRow.js | 13 +- .../Quality/SelectQualityModalContent.js | 17 +- .../InteractiveSearch/InteractiveSearchRow.js | 9 +- .../Organize/OrganizePreviewModalContent.js | 9 +- .../src/Retag/RetagPreviewModalContent.js | 9 +- frontend/src/Search/AddNewItem.js | 5 +- .../Search/Author/AddNewAuthorSearchResult.js | 3 +- .../src/Search/Book/AddNewBookSearchResult.js | 3 +- .../src/Search/Common/AddAuthorOptionsForm.js | 17 +- .../src/Settings/AdvancedSettingsButton.js | 3 +- .../Development/DevelopmentSettings.js | 37 +- .../DownloadClients/DownloadClientSettings.js | 5 +- .../AddDownloadClientModalContent.js | 17 +- .../DownloadClients/DownloadClient.js | 7 +- .../DownloadClients/DownloadClients.js | 5 +- .../EditDownloadClientModalContent.js | 19 +- .../Options/DownloadClientOptions.js | 33 +- .../EditRemotePathMappingModalContent.js | 23 +- .../RemotePathMappings/RemotePathMapping.js | 7 +- .../RemotePathMappings/RemotePathMappings.js | 5 +- .../src/Settings/General/AnalyticSettings.js | 11 +- .../src/Settings/General/BackupSettings.js | 21 +- .../src/Settings/General/GeneralSettings.js | 13 +- frontend/src/Settings/General/HostSettings.js | 59 +- .../src/Settings/General/LoggingSettings.js | 9 +- .../src/Settings/General/ProxySettings.js | 41 +- .../src/Settings/General/SecuritySettings.js | 35 +- .../src/Settings/General/UpdateSettings.js | 33 +- .../EditImportListExclusionModalContent.js | 17 +- .../ImportListExclusion.js | 7 +- .../ImportListExclusions.js | 5 +- .../ImportLists/ImportListSettings.js | 5 +- .../ImportLists/AddImportListModalContent.js | 13 +- .../ImportLists/EditImportListModalContent.js | 55 +- .../ImportLists/ImportLists/ImportList.js | 7 +- .../ImportLists/ImportLists/ImportLists.js | 5 +- .../src/Settings/Indexers/IndexerSettings.js | 5 +- .../Indexers/AddIndexerModalContent.js | 17 +- .../Indexers/EditIndexerModalContent.js | 37 +- .../src/Settings/Indexers/Indexers/Indexer.js | 9 +- .../Settings/Indexers/Indexers/Indexers.js | 5 +- .../Indexers/Options/IndexerOptions.js | 33 +- .../MediaManagement/MediaManagement.js | 145 ++-- .../Settings/MediaManagement/Naming/Naming.js | 27 +- .../MediaManagement/Naming/NamingModal.js | 21 +- .../RootFolder/EditRootFolderModalContent.js | 89 ++- .../MediaManagement/RootFolder/RootFolder.js | 7 +- .../MediaManagement/RootFolder/RootFolders.js | 5 +- .../Metadata/EditMetadataModalContent.js | 7 +- .../Settings/Metadata/Metadata/Metadatas.js | 5 +- .../MetadataProvider/MetadataProvider.js | 25 +- .../src/Settings/Metadata/MetadataSettings.js | 3 +- .../Notifications/NotificationSettings.js | 3 +- .../AddNotificationModalContent.js | 5 +- .../EditNotificationModalContent.js | 15 +- .../Notifications/Notification.js | 7 +- .../Notifications/NotificationEventItems.js | 23 +- .../Notifications/Notifications.js | 5 +- .../Settings/Profiles/Delay/DelayProfile.js | 7 +- .../Settings/Profiles/Delay/DelayProfiles.js | 5 +- .../Delay/EditDelayProfileModalContent.js | 29 +- .../EditMetadataProfileModalContent.js | 37 +- .../Profiles/Metadata/MetadataProfile.js | 9 +- .../Profiles/Metadata/MetadataProfiles.js | 5 +- frontend/src/Settings/Profiles/Profiles.js | 3 +- .../Quality/EditQualityProfileModalContent.js | 11 +- .../Profiles/Quality/QualityProfile.js | 15 +- .../Profiles/Quality/QualityProfileItem.js | 5 +- .../Quality/QualityProfileItemGroup.js | 5 +- .../Profiles/Quality/QualityProfiles.js | 5 +- .../Release/EditReleaseProfileModalContent.js | 55 +- .../Profiles/Release/ReleaseProfile.js | 7 +- .../Profiles/Release/ReleaseProfiles.js | 5 +- .../Quality/Definition/QualityDefinition.js | 9 +- .../Definition/QualityDefinitionLimits.js | 13 +- .../Quality/Definition/QualityDefinitions.js | 5 +- frontend/src/Settings/Quality/Quality.js | 3 +- frontend/src/Settings/Settings.js | 3 +- frontend/src/Settings/SettingsToolbar.js | 3 +- .../Tags/Details/TagDetailsModalContent.js | 17 +- frontend/src/Settings/Tags/Tag.js | 7 +- frontend/src/Settings/Tags/TagSettings.js | 3 +- frontend/src/Settings/Tags/Tags.js | 10 +- frontend/src/Settings/UI/UISettings.js | 66 +- .../src/Settings/UI/UISettingsConnector.js | 27 +- .../src/Store/Actions/Settings/languages.js | 48 ++ frontend/src/Store/Actions/settingsActions.js | 5 + frontend/src/System/Backup/BackupRow.js | 11 +- frontend/src/System/Backup/Backups.js | 15 +- .../Backup/RestoreBackupModalContent.js | 13 +- frontend/src/System/Events/LogsTable.js | 9 +- .../System/Events/LogsTableDetailsModal.js | 9 +- frontend/src/System/Logs/Files/LogFiles.js | 11 +- frontend/src/System/Status/About/About.js | 23 +- .../src/System/Status/DiskSpace/DiskSpace.js | 3 +- frontend/src/System/Status/Health/Health.js | 15 +- .../src/System/Status/MoreInfo/MoreInfo.js | 3 +- frontend/src/System/Status/Status.js | 3 +- .../src/System/Tasks/Queued/QueuedTaskRow.js | 11 +- .../src/System/Tasks/Queued/QueuedTasks.js | 3 +- .../System/Tasks/Scheduled/ScheduledTasks.js | 3 +- frontend/src/System/Tasks/Tasks.js | 3 +- frontend/src/System/Updates/Updates.js | 15 +- .../src/UnmappedFiles/UnmappedFilesTable.js | 7 +- .../UnmappedFiles/UnmappedFilesTableRow.js | 7 +- frontend/src/Utilities/String/translate.js | 34 + .../src/Wanted/CutoffUnmet/CutoffUnmet.js | 13 +- frontend/src/Wanted/Missing/Missing.js | 15 +- .../Configuration/ConfigService.cs | 8 + .../Configuration/IConfigService.cs | 1 + src/NzbDrone.Core/Languages/Language.cs | 191 +++++ .../Languages/LanguageExtensions.cs | 13 + .../Languages/LanguageFieldConverter.cs | 13 + .../Languages/LanguagesComparer.cs | 53 ++ .../Languages/RealLanguageFieldConverter.cs | 17 + src/NzbDrone.Core/Localization/Core/en.json | 694 ++++++++++++++++++ .../Localization/LocalizationService.cs | 188 +++++ src/NzbDrone.Core/Parser/IsoLanguage.cs | 10 +- src/NzbDrone.Core/Parser/IsoLanguages.cs | 86 ++- src/NzbDrone.Core/Readarr.Core.csproj | 5 + src/Readarr.Api.V1/Config/UiConfigResource.cs | 2 + .../Languages/LanguageController.cs | 36 + .../Languages/LanguageResource.cs | 13 + .../Localization/LocalizationController.cs | 29 + .../Localization/LocalizationResource.cs | 26 + 196 files changed, 3074 insertions(+), 924 deletions(-) create mode 100644 frontend/src/Store/Actions/Settings/languages.js create mode 100644 frontend/src/Utilities/String/translate.js create mode 100644 src/NzbDrone.Core/Languages/Language.cs create mode 100644 src/NzbDrone.Core/Languages/LanguageExtensions.cs create mode 100644 src/NzbDrone.Core/Languages/LanguageFieldConverter.cs create mode 100644 src/NzbDrone.Core/Languages/LanguagesComparer.cs create mode 100644 src/NzbDrone.Core/Languages/RealLanguageFieldConverter.cs create mode 100644 src/NzbDrone.Core/Localization/Core/en.json create mode 100644 src/NzbDrone.Core/Localization/LocalizationService.cs create mode 100644 src/Readarr.Api.V1/Languages/LanguageController.cs create mode 100644 src/Readarr.Api.V1/Languages/LanguageResource.cs create mode 100644 src/Readarr.Api.V1/Localization/LocalizationController.cs create mode 100644 src/Readarr.Api.V1/Localization/LocalizationResource.cs diff --git a/frontend/src/Activity/Blacklist/Blacklist.js b/frontend/src/Activity/Blacklist/Blacklist.js index 587d1bb4a..5e1bfbc5b 100644 --- a/frontend/src/Activity/Blacklist/Blacklist.js +++ b/frontend/src/Activity/Blacklist/Blacklist.js @@ -14,6 +14,7 @@ import TablePager from 'Components/Table/TablePager'; import { align, icons, kinds } from 'Helpers/Props'; import getRemovedItems from 'Utilities/Object/getRemovedItems'; import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; +import translate from 'Utilities/String/translate'; import getSelectedIds from 'Utilities/Table/getSelectedIds'; import removeOldSelectedState from 'Utilities/Table/removeOldSelectedState'; import selectAll from 'Utilities/Table/selectAll'; @@ -120,11 +121,11 @@ class Blacklist extends Component { const selectedIds = this.getSelectedIds(); return ( - + @@ -160,7 +161,9 @@ class Blacklist extends Component { { !isAnyFetching && !!error && -
Unable to load blacklist
+
+ {translate('UnableToLoadBlacklist')} +
} { @@ -210,9 +213,9 @@ class Blacklist extends Component { diff --git a/frontend/src/Activity/Blacklist/BlacklistDetailsModal.js b/frontend/src/Activity/Blacklist/BlacklistDetailsModal.js index 75b963955..6ef3a2dd3 100644 --- a/frontend/src/Activity/Blacklist/BlacklistDetailsModal.js +++ b/frontend/src/Activity/Blacklist/BlacklistDetailsModal.js @@ -8,6 +8,7 @@ import ModalBody from 'Components/Modal/ModalBody'; import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; +import translate from 'Utilities/String/translate'; class BlacklistDetailsModal extends Component { @@ -39,19 +40,19 @@ class BlacklistDetailsModal extends Component { { !!message && } @@ -59,7 +60,7 @@ class BlacklistDetailsModal extends Component { { !!message && } diff --git a/frontend/src/Activity/Blacklist/BlacklistRow.js b/frontend/src/Activity/Blacklist/BlacklistRow.js index 76b48e7f1..2ee3191c0 100644 --- a/frontend/src/Activity/Blacklist/BlacklistRow.js +++ b/frontend/src/Activity/Blacklist/BlacklistRow.js @@ -8,6 +8,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell'; import TableSelectCell from 'Components/Table/Cells/TableSelectCell'; import TableRow from 'Components/Table/TableRow'; import { icons, kinds } from 'Helpers/Props'; +import translate from 'Utilities/String/translate'; import BlacklistDetailsModal from './BlacklistDetailsModal'; import styles from './BlacklistRow.css'; @@ -141,7 +142,7 @@ class BlacklistRow extends Component { /> { !!indexer && } @@ -93,7 +94,7 @@ function HistoryDetails(props) { !!releaseGroup && } @@ -114,7 +115,7 @@ function HistoryDetails(props) { { !!downloadClient && } @@ -122,7 +123,7 @@ function HistoryDetails(props) { { !!downloadId && } @@ -130,7 +131,7 @@ function HistoryDetails(props) { { !!indexer && } @@ -138,7 +139,7 @@ function HistoryDetails(props) { { !!publishedDate && } @@ -155,14 +156,14 @@ function HistoryDetails(props) { { !!message && } @@ -180,7 +181,7 @@ function HistoryDetails(props) { @@ -188,7 +189,7 @@ function HistoryDetails(props) { !!droppedPath && } @@ -197,7 +198,7 @@ function HistoryDetails(props) { !!importedPath && } @@ -229,12 +230,12 @@ function HistoryDetails(props) { return ( @@ -250,12 +251,12 @@ function HistoryDetails(props) { return ( @@ -271,7 +272,7 @@ function HistoryDetails(props) { return ( { @@ -286,7 +287,7 @@ function HistoryDetails(props) { }) } : } /> @@ -301,14 +302,14 @@ function HistoryDetails(props) { return ( { !!statusMessages && } @@ -332,14 +333,14 @@ function HistoryDetails(props) { return ( { !!indexer && } @@ -347,7 +348,7 @@ function HistoryDetails(props) { { !!releaseGroup && } @@ -368,7 +369,7 @@ function HistoryDetails(props) { { !!downloadClient && } @@ -376,7 +377,7 @@ function HistoryDetails(props) { { !!downloadId && } @@ -384,7 +385,7 @@ function HistoryDetails(props) { { !!indexer && } @@ -392,7 +393,7 @@ function HistoryDetails(props) { { !!publishedDate && } @@ -409,14 +410,14 @@ function HistoryDetails(props) { { !!message && } @@ -428,7 +429,7 @@ function HistoryDetails(props) { diff --git a/frontend/src/Activity/History/History.js b/frontend/src/Activity/History/History.js index 624637ec2..baeab9cd1 100644 --- a/frontend/src/Activity/History/History.js +++ b/frontend/src/Activity/History/History.js @@ -13,6 +13,7 @@ import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptions import TablePager from 'Components/Table/TablePager'; import { align, icons } from 'Helpers/Props'; import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; +import translate from 'Utilities/String/translate'; import HistoryRowConnector from './HistoryRowConnector'; class History extends Component { @@ -66,11 +67,11 @@ class History extends Component { const hasError = error || booksError; return ( - + @@ -106,7 +107,9 @@ class History extends Component { { !isFetchingAny && hasError && -
Unable to load history
+
+ {translate('UnableToLoadHistory')} +
} { diff --git a/frontend/src/Activity/Queue/Queue.js b/frontend/src/Activity/Queue/Queue.js index 4e25b9ed1..a5106f642 100644 --- a/frontend/src/Activity/Queue/Queue.js +++ b/frontend/src/Activity/Queue/Queue.js @@ -15,6 +15,7 @@ import TablePager from 'Components/Table/TablePager'; import { align, icons } from 'Helpers/Props'; import getRemovedItems from 'Utilities/Object/getRemovedItems'; import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; +import translate from 'Utilities/String/translate'; import getSelectedIds from 'Utilities/Table/getSelectedIds'; import removeOldSelectedState from 'Utilities/Table/removeOldSelectedState'; import selectAll from 'Utilities/Table/selectAll'; @@ -150,11 +151,11 @@ class Queue extends Component { const disableSelectedActions = selectedCount === 0; return ( - + diff --git a/frontend/src/Activity/Queue/QueueDetails.js b/frontend/src/Activity/Queue/QueueDetails.js index d13dee63f..540e602ce 100644 --- a/frontend/src/Activity/Queue/QueueDetails.js +++ b/frontend/src/Activity/Queue/QueueDetails.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import Icon from 'Components/Icon'; import { icons, kinds } from 'Helpers/Props'; +import translate from 'Utilities/String/translate'; function QueueDetails(props) { const { @@ -23,7 +24,7 @@ function QueueDetails(props) { return ( ); } @@ -34,7 +35,7 @@ function QueueDetails(props) { ); } @@ -47,7 +48,7 @@ function QueueDetails(props) { ); } @@ -57,7 +58,7 @@ function QueueDetails(props) { ); } @@ -67,7 +68,7 @@ function QueueDetails(props) { ); } @@ -76,7 +77,7 @@ function QueueDetails(props) { return ( ); } diff --git a/frontend/src/Activity/Queue/QueueOptions.js b/frontend/src/Activity/Queue/QueueOptions.js index 75ac5d226..b2486579e 100644 --- a/frontend/src/Activity/Queue/QueueOptions.js +++ b/frontend/src/Activity/Queue/QueueOptions.js @@ -4,6 +4,7 @@ import FormGroup from 'Components/Form/FormGroup'; import FormInputGroup from 'Components/Form/FormInputGroup'; import FormLabel from 'Components/Form/FormLabel'; import { inputTypes } from 'Helpers/Props'; +import translate from 'Utilities/String/translate'; class QueueOptions extends Component { @@ -54,13 +55,15 @@ class QueueOptions extends Component { return ( - Show Unknown Author Items + + {translate('ShowUnknownAuthorItems')} + diff --git a/frontend/src/Activity/Queue/QueueRow.js b/frontend/src/Activity/Queue/QueueRow.js index 6b46ea9ab..3bd52f999 100644 --- a/frontend/src/Activity/Queue/QueueRow.js +++ b/frontend/src/Activity/Queue/QueueRow.js @@ -15,6 +15,7 @@ import TableRow from 'Components/Table/TableRow'; import Popover from 'Components/Tooltip/Popover'; import { icons, kinds, tooltipPositions } from 'Helpers/Props'; import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; +import translate from 'Utilities/String/translate'; import QueueStatusCell from './QueueStatusCell'; import RemoveQueueItemModal from './RemoveQueueItemModal'; import TimeleftCell from './TimeleftCell'; @@ -285,7 +286,7 @@ class QueueRow extends Component { kind={kinds.DANGER} /> } - title="Manual Download" + title={translate('ManualDownload')} body="This release failed parsing checks and was manually downloaded from an interactive search. Import is likely to fail." position={tooltipPositions.LEFT} /> @@ -310,7 +311,7 @@ class QueueRow extends Component { } - Remove From Download Client + + {translate('RemoveFromDownloadClient')} + - Blacklist Release + + {translate('BlacklistRelease')} + @@ -122,12 +127,14 @@ class RemoveQueueItemModal extends Component { { blacklist && - Skip Redownload + + {translate('SkipRedownload')} + diff --git a/frontend/src/Activity/Queue/RemoveQueueItemsModal.js b/frontend/src/Activity/Queue/RemoveQueueItemsModal.js index 91c7a2d13..a672de728 100644 --- a/frontend/src/Activity/Queue/RemoveQueueItemsModal.js +++ b/frontend/src/Activity/Queue/RemoveQueueItemsModal.js @@ -10,6 +10,7 @@ import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { inputTypes, kinds, sizes } from 'Helpers/Props'; +import translate from 'Utilities/String/translate'; import styles from './RemoveQueueItemsModal.css'; class RemoveQueueItemsModal extends Component { @@ -96,13 +97,15 @@ class RemoveQueueItemsModal extends Component { - Remove From Download Client + + {translate('RemoveFromDownloadClient')} + @@ -117,7 +120,7 @@ class RemoveQueueItemsModal extends Component { type={inputTypes.CHECK} name="blacklist" value={blacklist} - helpText="Prevents Readarr from automatically grabbing these files again" + helpText={translate('BlacklistHelpText')} onChange={this.onBlacklistChange} /> @@ -125,12 +128,14 @@ class RemoveQueueItemsModal extends Component { { blacklist && - Skip Redownload + + {translate('SkipRedownload')} + diff --git a/frontend/src/Activity/Queue/TimeleftCell.js b/frontend/src/Activity/Queue/TimeleftCell.js index a8d9d52e8..56132671c 100644 --- a/frontend/src/Activity/Queue/TimeleftCell.js +++ b/frontend/src/Activity/Queue/TimeleftCell.js @@ -5,6 +5,7 @@ import formatTime from 'Utilities/Date/formatTime'; import formatTimeSpan from 'Utilities/Date/formatTimeSpan'; import getRelativeDate from 'Utilities/Date/getRelativeDate'; import formatBytes from 'Utilities/Number/formatBytes'; +import translate from 'Utilities/String/translate'; import styles from './TimeleftCell.css'; function TimeleftCell(props) { @@ -26,7 +27,7 @@ function TimeleftCell(props) { return ( - @@ -40,7 +41,7 @@ function TimeleftCell(props) { return ( - diff --git a/frontend/src/AddAuthor/AuthorMonitoringOptionsPopoverContent.js b/frontend/src/AddAuthor/AuthorMonitoringOptionsPopoverContent.js index 7f40f30cd..4f27c7fc4 100644 --- a/frontend/src/AddAuthor/AuthorMonitoringOptionsPopoverContent.js +++ b/frontend/src/AddAuthor/AuthorMonitoringOptionsPopoverContent.js @@ -1,42 +1,43 @@ import React from 'react'; import DescriptionList from 'Components/DescriptionList/DescriptionList'; import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; +import translate from 'Utilities/String/translate'; function AuthorMonitoringOptionsPopoverContent() { return ( diff --git a/frontend/src/App/AppUpdatedModalContent.js b/frontend/src/App/AppUpdatedModalContent.js index a7c9b8903..7594aa7fa 100644 --- a/frontend/src/App/AppUpdatedModalContent.js +++ b/frontend/src/App/AppUpdatedModalContent.js @@ -8,6 +8,7 @@ import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { kinds } from 'Helpers/Props'; import UpdateChanges from 'System/Updates/UpdateChanges'; +import translate from 'Utilities/String/translate'; import styles from './AppUpdatedModalContent.css'; function AppUpdatedModalContent(props) { @@ -49,12 +50,12 @@ function AppUpdatedModalContent(props) { diff --git a/frontend/src/Author/Delete/DeleteAuthorModalContent.js b/frontend/src/Author/Delete/DeleteAuthorModalContent.js index 61b5c9a50..43018e67c 100644 --- a/frontend/src/Author/Delete/DeleteAuthorModalContent.js +++ b/frontend/src/Author/Delete/DeleteAuthorModalContent.js @@ -11,6 +11,7 @@ import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { icons, inputTypes, kinds } from 'Helpers/Props'; import formatBytes from 'Utilities/Number/formatBytes'; +import translate from 'Utilities/String/translate'; import styles from './DeleteAuthorModalContent.css'; class DeleteAuthorModalContent extends Component { @@ -67,7 +68,7 @@ class DeleteAuthorModalContent extends Component { const addImportListExclusion = this.state.addImportListExclusion; let deleteFilesLabel = `Delete ${bookFileCount} Book Files`; - let deleteFilesHelpText = 'Delete the book files and author folder'; + let deleteFilesHelpText = translate('DeleteFilesHelpText'); if (bookFileCount === 0) { deleteFilesLabel = 'Delete Author Folder'; @@ -106,13 +107,15 @@ class DeleteAuthorModalContent extends Component { - Add List Exclusion + + {translate('AddListExclusion')} + @@ -121,7 +124,9 @@ class DeleteAuthorModalContent extends Component { { deleteFiles &&
-
The author folder {path} and all of its content will be deleted.
+
+ {translate('TheAuthorFolderStrongpathstrongAndAllOfItsContentWillBeDeleted')} +
{ !!bookFileCount && diff --git a/frontend/src/Author/Details/AuthorDetails.js b/frontend/src/Author/Details/AuthorDetails.js index df665b41a..2a6e743fc 100644 --- a/frontend/src/Author/Details/AuthorDetails.js +++ b/frontend/src/Author/Details/AuthorDetails.js @@ -20,6 +20,7 @@ import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveS import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable'; import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector'; import RetagPreviewModalConnector from 'Retag/RetagPreviewModalConnector'; +import translate from 'Utilities/String/translate'; import selectAll from 'Utilities/Table/selectAll'; import toggleSelected from 'Utilities/Table/toggleSelected'; import InteractiveImportModal from '../../InteractiveImport/InteractiveImportModal'; @@ -181,41 +182,41 @@ class AuthorDetails extends Component { @@ -223,13 +224,13 @@ class AuthorDetails extends Component { @@ -237,7 +238,7 @@ class AuthorDetails extends Component { @@ -258,7 +259,7 @@ class AuthorDetails extends Component { className={styles.authorNavigationButton} name={icons.ARROW_LEFT} size={30} - title={`Go to ${previousAuthor.authorName}`} + title={translate('GoToInterp', [previousAuthor.authorName])} to={`/author/${previousAuthor.titleSlug}`} /> @@ -266,7 +267,7 @@ class AuthorDetails extends Component { className={styles.authorUpButton} name={icons.ARROW_UP} size={30} - title={'Go to author listing'} + title={translate('GoToAuthorListing')} to={'/'} /> @@ -274,7 +275,7 @@ class AuthorDetails extends Component { className={styles.authorNavigationButton} name={icons.ARROW_RIGHT} size={30} - title={`Go to ${nextAuthor.authorName}`} + title={translate('GoToInterp', [nextAuthor.authorName])} to={`/author/${nextAuthor.titleSlug}`} />
@@ -288,12 +289,16 @@ class AuthorDetails extends Component { { !isFetching && booksError && -
Loading books failed
+
+ {translate('LoadingBooksFailed')} +
} { !isFetching && bookFilesError && -
Loading book files failed
+
+ {translate('LoadingBookFilesFailed')} +
} { diff --git a/frontend/src/Author/Details/AuthorDetailsHeader.js b/frontend/src/Author/Details/AuthorDetailsHeader.js index cc5d1d42e..afb554bac 100644 --- a/frontend/src/Author/Details/AuthorDetailsHeader.js +++ b/frontend/src/Author/Details/AuthorDetailsHeader.js @@ -15,6 +15,7 @@ import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfil import fonts from 'Styles/Variables/fonts'; import formatBytes from 'Utilities/Number/formatBytes'; import stripHtml from 'Utilities/String/stripHtml'; +import translate from 'Utilities/String/translate'; import AuthorAlternateTitles from './AuthorAlternateTitles'; import AuthorDetailsLinks from './AuthorDetailsLinks'; import AuthorTagsConnector from './AuthorTagsConnector'; @@ -95,7 +96,7 @@ class AuthorDetailsHeader extends Component { const continuing = status === 'continuing'; - let bookFilesCountMessage = 'No book files'; + let bookFilesCountMessage = translate('BookFilesCountMessage'); if (bookFileCount === 1) { bookFilesCountMessage = '1 book file'; @@ -152,7 +153,7 @@ class AuthorDetailsHeader extends Component { size={20} /> } - title="Alternate Titles" + title={translate('AlternateTitles')} body={} position={tooltipPositions.BOTTOM} /> @@ -204,7 +205,7 @@ class AuthorDetailsHeader extends Component {