From 6747b742718a84fbb380d6eadef329229a6738d4 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 19 Jul 2024 20:42:59 -0700 Subject: [PATCH] Convert History to TypeScript (cherry picked from commit 824ed0a36931ce7aae9aa544a7baf0738dae568c) Closes #10230 Closes #10390 Closes #10247 --- .../History/Details/HistoryDetails.js | 354 ------------------ .../History/Details/HistoryDetails.tsx | 287 ++++++++++++++ .../Details/HistoryDetailsConnector.js | 18 - ...etailsModal.js => HistoryDetailsModal.tsx} | 78 ++-- frontend/src/Activity/History/History.js | 158 -------- frontend/src/Activity/History/History.tsx | 216 +++++++++++ .../src/Activity/History/HistoryConnector.js | 141 ------- ...ntTypeCell.js => HistoryEventTypeCell.tsx} | 56 +-- frontend/src/Activity/History/HistoryRow.js | 277 -------------- frontend/src/Activity/History/HistoryRow.tsx | 224 +++++++++++ .../Activity/History/HistoryRowConnector.js | 73 ---- frontend/src/App/AppRoutes.tsx | 4 +- frontend/src/App/State/HistoryAppState.ts | 6 +- .../src/Utilities/Object/selectUniqueIds.js | 15 - .../src/Utilities/Object/selectUniqueIds.ts | 13 + frontend/src/typings/Helpers/KeysMatching.ts | 2 +- frontend/src/typings/History.ts | 57 ++- src/NzbDrone.Core/Localization/Core/ar.json | 2 +- src/NzbDrone.Core/Localization/Core/bg.json | 2 +- src/NzbDrone.Core/Localization/Core/ca.json | 8 +- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 2 +- src/NzbDrone.Core/Localization/Core/el.json | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 8 +- src/NzbDrone.Core/Localization/Core/es.json | 8 +- src/NzbDrone.Core/Localization/Core/fi.json | 8 +- src/NzbDrone.Core/Localization/Core/fr.json | 8 +- src/NzbDrone.Core/Localization/Core/he.json | 2 +- src/NzbDrone.Core/Localization/Core/hi.json | 2 +- src/NzbDrone.Core/Localization/Core/hu.json | 4 +- src/NzbDrone.Core/Localization/Core/is.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 6 +- src/NzbDrone.Core/Localization/Core/ja.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt.json | 2 +- .../Localization/Core/pt_BR.json | 8 +- src/NzbDrone.Core/Localization/Core/ro.json | 8 +- src/NzbDrone.Core/Localization/Core/ru.json | 4 +- src/NzbDrone.Core/Localization/Core/sv.json | 2 +- src/NzbDrone.Core/Localization/Core/th.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 8 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- src/NzbDrone.Core/Localization/Core/vi.json | 2 +- .../Localization/Core/zh_CN.json | 8 +- 47 files changed, 923 insertions(+), 1178 deletions(-) delete mode 100644 frontend/src/Activity/History/Details/HistoryDetails.js create mode 100644 frontend/src/Activity/History/Details/HistoryDetails.tsx delete mode 100644 frontend/src/Activity/History/Details/HistoryDetailsConnector.js rename frontend/src/Activity/History/Details/{HistoryDetailsModal.js => HistoryDetailsModal.tsx} (52%) delete mode 100644 frontend/src/Activity/History/History.js create mode 100644 frontend/src/Activity/History/History.tsx delete mode 100644 frontend/src/Activity/History/HistoryConnector.js rename frontend/src/Activity/History/{HistoryEventTypeCell.js => HistoryEventTypeCell.tsx} (56%) delete mode 100644 frontend/src/Activity/History/HistoryRow.js create mode 100644 frontend/src/Activity/History/HistoryRow.tsx delete mode 100644 frontend/src/Activity/History/HistoryRowConnector.js delete mode 100644 frontend/src/Utilities/Object/selectUniqueIds.js create mode 100644 frontend/src/Utilities/Object/selectUniqueIds.ts diff --git a/frontend/src/Activity/History/Details/HistoryDetails.js b/frontend/src/Activity/History/Details/HistoryDetails.js deleted file mode 100644 index b3ae7cb2c..000000000 --- a/frontend/src/Activity/History/Details/HistoryDetails.js +++ /dev/null @@ -1,354 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import DescriptionList from 'Components/DescriptionList/DescriptionList'; -import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; -import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription'; -import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle'; -import Link from 'Components/Link/Link'; -import formatDateTime from 'Utilities/Date/formatDateTime'; -import formatAge from 'Utilities/Number/formatAge'; -import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; -import translate from 'Utilities/String/translate'; -import styles from './HistoryDetails.css'; - -function HistoryDetails(props) { - const { - eventType, - sourceTitle, - data, - downloadId, - shortDateFormat, - timeFormat - } = props; - - if (eventType === 'grabbed') { - const { - indexer, - releaseGroup, - movieMatchType, - customFormatScore, - nzbInfoUrl, - downloadClient, - downloadClientName, - age, - ageHours, - ageMinutes, - publishedDate - } = data; - - const downloadClientNameInfo = downloadClientName ?? downloadClient; - - return ( - - - - { - indexer ? - : - null - } - - { - releaseGroup ? - : - null - } - - { - customFormatScore && customFormatScore !== '0' ? - : - null - } - - { - movieMatchType ? - : - null - } - - { - nzbInfoUrl ? - - - {translate('InfoUrl')} - - - - {nzbInfoUrl} - - : - null - } - - { - downloadClientNameInfo ? - : - null - } - - { - downloadId ? - : - null - } - - { - indexer ? - : - null - } - - { - publishedDate ? - : - null - } - - ); - } - - if (eventType === 'downloadFailed') { - const { - message - } = data; - - return ( - - - - { - downloadId ? - : - null - } - - { - message ? - : - null - } - - ); - } - - if (eventType === 'downloadFolderImported') { - const { - customFormatScore, - droppedPath, - importedPath - } = data; - - return ( - - - - { - droppedPath ? - : - null - } - - { - importedPath ? - : - null - } - - { - customFormatScore && customFormatScore !== '0' ? - : - null - } - - ); - } - - if (eventType === 'movieFileDeleted') { - const { - reason, - customFormatScore - } = data; - - let reasonMessage = ''; - - switch (reason) { - case 'Manual': - reasonMessage = translate('DeletedReasonManual'); - break; - case 'MissingFromDisk': - reasonMessage = translate('DeletedReasonMissingFromDisk'); - break; - case 'Upgrade': - reasonMessage = translate('DeletedReasonUpgrade'); - break; - default: - reasonMessage = ''; - } - - return ( - - - - - - { - customFormatScore && customFormatScore !== '0' ? - : - null - } - - ); - } - - if (eventType === 'movieFileRenamed') { - const { - sourcePath, - sourceRelativePath, - path, - relativePath - } = data; - - return ( - - - - - - - - - - ); - } - - if (eventType === 'downloadIgnored') { - const { - message - } = data; - - return ( - - - - { - downloadId ? - : - null - } - - { - message ? - : - null - } - - ); - } - - return ( - - - - ); -} - -HistoryDetails.propTypes = { - eventType: PropTypes.string.isRequired, - sourceTitle: PropTypes.string.isRequired, - data: PropTypes.object.isRequired, - downloadId: PropTypes.string, - shortDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired -}; - -export default HistoryDetails; diff --git a/frontend/src/Activity/History/Details/HistoryDetails.tsx b/frontend/src/Activity/History/Details/HistoryDetails.tsx new file mode 100644 index 000000000..3f9bcbfe9 --- /dev/null +++ b/frontend/src/Activity/History/Details/HistoryDetails.tsx @@ -0,0 +1,287 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import DescriptionList from 'Components/DescriptionList/DescriptionList'; +import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; +import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription'; +import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle'; +import Link from 'Components/Link/Link'; +import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; +import { + DownloadFailedHistory, + DownloadFolderImportedHistory, + DownloadIgnoredHistory, + GrabbedHistoryData, + HistoryData, + HistoryEventType, + MovieFileDeletedHistory, + MovieFileRenamedHistory, +} from 'typings/History'; +import formatDateTime from 'Utilities/Date/formatDateTime'; +import formatAge from 'Utilities/Number/formatAge'; +import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; +import translate from 'Utilities/String/translate'; +import styles from './HistoryDetails.css'; + +interface HistoryDetailsProps { + eventType: HistoryEventType; + sourceTitle: string; + data: HistoryData; + downloadId?: string; +} + +function HistoryDetails(props: HistoryDetailsProps) { + const { eventType, sourceTitle, data, downloadId } = props; + + const { shortDateFormat, timeFormat } = useSelector( + createUISettingsSelector() + ); + + if (eventType === 'grabbed') { + const { + indexer, + releaseGroup, + movieMatchType, + customFormatScore, + nzbInfoUrl, + downloadClient, + downloadClientName, + age, + ageHours, + ageMinutes, + publishedDate, + } = data as GrabbedHistoryData; + + const downloadClientNameInfo = downloadClientName ?? downloadClient; + + return ( + + + + {indexer ? ( + + ) : null} + + {releaseGroup ? ( + + ) : null} + + {customFormatScore && customFormatScore !== '0' ? ( + + ) : null} + + {movieMatchType ? ( + + ) : null} + + {nzbInfoUrl ? ( + + + {translate('InfoUrl')} + + + + {nzbInfoUrl} + + + ) : null} + + {downloadClientNameInfo ? ( + + ) : null} + + {downloadId ? ( + + ) : null} + + {age || ageHours || ageMinutes ? ( + + ) : null} + + {publishedDate ? ( + + ) : null} + + ); + } + + if (eventType === 'downloadFailed') { + const { message } = data as DownloadFailedHistory; + + return ( + + + + {downloadId ? ( + + ) : null} + + {message ? ( + + ) : null} + + ); + } + + if (eventType === 'downloadFolderImported') { + const { customFormatScore, droppedPath, importedPath } = + data as DownloadFolderImportedHistory; + + return ( + + + + {droppedPath ? ( + + ) : null} + + {importedPath ? ( + + ) : null} + + {customFormatScore && customFormatScore !== '0' ? ( + + ) : null} + + ); + } + + if (eventType === 'movieFileDeleted') { + const { reason, customFormatScore } = data as MovieFileDeletedHistory; + + let reasonMessage = ''; + + switch (reason) { + case 'Manual': + reasonMessage = translate('DeletedReasonManual'); + break; + case 'MissingFromDisk': + reasonMessage = translate('DeletedReasonMovieMissingFromDisk'); + break; + case 'Upgrade': + reasonMessage = translate('DeletedReasonUpgrade'); + break; + default: + reasonMessage = ''; + } + + return ( + + + + + + {customFormatScore && customFormatScore !== '0' ? ( + + ) : null} + + ); + } + + if (eventType === 'movieFileRenamed') { + const { sourcePath, sourceRelativePath, path, relativePath } = + data as MovieFileRenamedHistory; + + return ( + + + + + + + + + + ); + } + + if (eventType === 'downloadIgnored') { + const { message } = data as DownloadIgnoredHistory; + + return ( + + + + {downloadId ? ( + + ) : null} + + {message ? ( + + ) : null} + + ); + } + + return ( + + + + ); +} + +export default HistoryDetails; diff --git a/frontend/src/Activity/History/Details/HistoryDetailsConnector.js b/frontend/src/Activity/History/Details/HistoryDetailsConnector.js deleted file mode 100644 index 65d95e557..000000000 --- a/frontend/src/Activity/History/Details/HistoryDetailsConnector.js +++ /dev/null @@ -1,18 +0,0 @@ -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; -import HistoryDetails from './HistoryDetails'; - -function createMapStateToProps() { - return createSelector( - createUISettingsSelector(), - (uiSettings) => { - return { - shortDateFormat: uiSettings.shortDateFormat, - timeFormat: uiSettings.timeFormat - }; - } - ); -} - -export default connect(createMapStateToProps)(HistoryDetails); diff --git a/frontend/src/Activity/History/Details/HistoryDetailsModal.js b/frontend/src/Activity/History/Details/HistoryDetailsModal.tsx similarity index 52% rename from frontend/src/Activity/History/Details/HistoryDetailsModal.js rename to frontend/src/Activity/History/Details/HistoryDetailsModal.tsx index 19fda4907..c54f2654f 100644 --- a/frontend/src/Activity/History/Details/HistoryDetailsModal.js +++ b/frontend/src/Activity/History/Details/HistoryDetailsModal.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React from 'react'; import Button from 'Components/Link/Button'; import SpinnerButton from 'Components/Link/SpinnerButton'; @@ -8,11 +7,12 @@ import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { kinds } from 'Helpers/Props'; +import { HistoryData, HistoryEventType } from 'typings/History'; import translate from 'Utilities/String/translate'; import HistoryDetails from './HistoryDetails'; import styles from './HistoryDetailsModal.css'; -function getHeaderTitle(eventType) { +function getHeaderTitle(eventType: HistoryEventType) { switch (eventType) { case 'grabbed': return translate('Grabbed'); @@ -31,29 +31,33 @@ function getHeaderTitle(eventType) { } } -function HistoryDetailsModal(props) { +interface HistoryDetailsModalProps { + isOpen: boolean; + eventType: HistoryEventType; + sourceTitle: string; + data: HistoryData; + downloadId?: string; + isMarkingAsFailed: boolean; + onMarkAsFailedPress: () => void; + onModalClose: () => void; +} + +function HistoryDetailsModal(props: HistoryDetailsModalProps) { const { isOpen, eventType, sourceTitle, data, downloadId, - isMarkingAsFailed, - shortDateFormat, - timeFormat, + isMarkingAsFailed = false, onMarkAsFailedPress, - onModalClose + onModalClose, } = props; return ( - + - - {getHeaderTitle(eventType)} - + {getHeaderTitle(eventType)} - { - eventType === 'grabbed' && - - {translate('MarkAsFailed')} - - } + {eventType === 'grabbed' && ( + + {translate('MarkAsFailed')} + + )} - + ); } -HistoryDetailsModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - eventType: PropTypes.string.isRequired, - sourceTitle: PropTypes.string.isRequired, - data: PropTypes.object.isRequired, - downloadId: PropTypes.string, - isMarkingAsFailed: PropTypes.bool.isRequired, - shortDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired, - onMarkAsFailedPress: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -HistoryDetailsModal.defaultProps = { - isMarkingAsFailed: false -}; - export default HistoryDetailsModal; diff --git a/frontend/src/Activity/History/History.js b/frontend/src/Activity/History/History.js deleted file mode 100644 index 21a06fb57..000000000 --- a/frontend/src/Activity/History/History.js +++ /dev/null @@ -1,158 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Alert from 'Components/Alert'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import FilterMenu from 'Components/Menu/FilterMenu'; -import PageContent from 'Components/Page/PageContent'; -import PageContentBody from 'Components/Page/PageContentBody'; -import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; -import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; -import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; -import Table from 'Components/Table/Table'; -import TableBody from 'Components/Table/TableBody'; -import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; -import TablePager from 'Components/Table/TablePager'; -import { align, icons, kinds } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import HistoryFilterModal from './HistoryFilterModal'; -import HistoryRowConnector from './HistoryRowConnector'; - -class History extends Component { - - // - // Render - - render() { - const { - isFetching, - isPopulated, - error, - isMoviesFetching, - isMoviesPopulated, - moviesError, - items, - columns, - selectedFilterKey, - filters, - customFilters, - totalRecords, - onFilterSelect, - onFirstPagePress, - ...otherProps - } = this.props; - - const isFetchingAny = isFetching || isMoviesFetching; - const isAllPopulated = isPopulated && (isMoviesPopulated || !items.length); - const hasError = error || moviesError; - - return ( - - - - - - - - - - - - - - - - - { - isFetchingAny && !isAllPopulated && - - } - - { - !isFetchingAny && hasError && - - {translate('HistoryLoadError')} - - } - - { - // If history isPopulated and it's empty show no history found and don't - // wait for the episodes to populate because they are never coming. - - isPopulated && !hasError && !items.length && - - {translate('NoHistoryFound')} - - } - - { - isAllPopulated && !hasError && !!items.length && -
- - - { - items.map((item) => { - return ( - - ); - }) - } - -
- - -
- } -
-
- ); - } -} - -History.propTypes = { - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - error: PropTypes.object, - isMoviesFetching: PropTypes.bool.isRequired, - isMoviesPopulated: PropTypes.bool.isRequired, - moviesError: PropTypes.object, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - columns: PropTypes.arrayOf(PropTypes.object).isRequired, - selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, - filters: PropTypes.arrayOf(PropTypes.object).isRequired, - customFilters: PropTypes.arrayOf(PropTypes.object).isRequired, - totalRecords: PropTypes.number, - onFilterSelect: PropTypes.func.isRequired, - onFirstPagePress: PropTypes.func.isRequired -}; - -export default History; diff --git a/frontend/src/Activity/History/History.tsx b/frontend/src/Activity/History/History.tsx new file mode 100644 index 000000000..f4652b5cc --- /dev/null +++ b/frontend/src/Activity/History/History.tsx @@ -0,0 +1,216 @@ +import React, { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import AppState from 'App/State/AppState'; +import Alert from 'Components/Alert'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import FilterMenu from 'Components/Menu/FilterMenu'; +import PageContent from 'Components/Page/PageContent'; +import PageContentBody from 'Components/Page/PageContentBody'; +import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; +import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; +import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; +import Table from 'Components/Table/Table'; +import TableBody from 'Components/Table/TableBody'; +import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; +import TablePager from 'Components/Table/TablePager'; +import usePaging from 'Components/Table/usePaging'; +import useCurrentPage from 'Helpers/Hooks/useCurrentPage'; +import { align, icons, kinds } from 'Helpers/Props'; +import createMoviesFetchingSelector from 'Movie/createMoviesFetchingSelector'; +import { + clearHistory, + fetchHistory, + gotoHistoryPage, + setHistoryFilter, + setHistorySort, + setHistoryTableOption, +} from 'Store/Actions/historyActions'; +import { createCustomFiltersSelector } from 'Store/Selectors/createClientSideCollectionSelector'; +import { TableOptionsChangePayload } from 'typings/Table'; +import { + registerPagePopulator, + unregisterPagePopulator, +} from 'Utilities/pagePopulator'; +import translate from 'Utilities/String/translate'; +import HistoryFilterModal from './HistoryFilterModal'; +import HistoryRow from './HistoryRow'; + +function History() { + const requestCurrentPage = useCurrentPage(); + + const { + isFetching, + isPopulated, + error, + items, + columns, + selectedFilterKey, + filters, + sortKey, + sortDirection, + page, + pageSize, + totalPages, + totalRecords, + } = useSelector((state: AppState) => state.history); + + const { isMoviesFetching, isMoviesPopulated, moviesError } = useSelector( + createMoviesFetchingSelector() + ); + const customFilters = useSelector(createCustomFiltersSelector('history')); + const dispatch = useDispatch(); + + const isFetchingAny = isFetching || isMoviesFetching; + const isAllPopulated = isPopulated && (isMoviesPopulated || !items.length); + const hasError = error || moviesError; + + const { + handleFirstPagePress, + handlePreviousPagePress, + handleNextPagePress, + handleLastPagePress, + handlePageSelect, + } = usePaging({ + page, + totalPages, + gotoPage: gotoHistoryPage, + }); + + const handleFilterSelect = useCallback( + (selectedFilterKey: string) => { + dispatch(setHistoryFilter({ selectedFilterKey })); + }, + [dispatch] + ); + + const handleSortPress = useCallback( + (sortKey: string) => { + dispatch(setHistorySort({ sortKey })); + }, + [dispatch] + ); + + const handleTableOptionChange = useCallback( + (payload: TableOptionsChangePayload) => { + dispatch(setHistoryTableOption(payload)); + + if (payload.pageSize) { + dispatch(gotoHistoryPage({ page: 1 })); + } + }, + [dispatch] + ); + + useEffect(() => { + if (requestCurrentPage) { + dispatch(fetchHistory()); + } else { + dispatch(gotoHistoryPage({ page: 1 })); + } + + return () => { + dispatch(clearHistory()); + }; + }, [requestCurrentPage, dispatch]); + + useEffect(() => { + const repopulate = () => { + dispatch(fetchHistory()); + }; + + registerPagePopulator(repopulate); + + return () => { + unregisterPagePopulator(repopulate); + }; + }, [dispatch]); + + return ( + + + + + + + + + + + + + + + + + {isFetchingAny && !isAllPopulated ? : null} + + {!isFetchingAny && hasError ? ( + {translate('HistoryLoadError')} + ) : null} + + { + // If history isPopulated and it's empty show no history found and don't + // wait for the movies to populate because they are never coming. + + isPopulated && !hasError && !items.length ? ( + {translate('NoHistoryFound')} + ) : null + } + + {isAllPopulated && !hasError && items.length ? ( +
+ + + {items.map((item) => { + return ( + + ); + })} + +
+ + +
+ ) : null} +
+
+ ); +} + +export default History; diff --git a/frontend/src/Activity/History/HistoryConnector.js b/frontend/src/Activity/History/HistoryConnector.js deleted file mode 100644 index 6cb5d5f7c..000000000 --- a/frontend/src/Activity/History/HistoryConnector.js +++ /dev/null @@ -1,141 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import withCurrentPage from 'Components/withCurrentPage'; -import * as historyActions from 'Store/Actions/historyActions'; -import { createCustomFiltersSelector } from 'Store/Selectors/createClientSideCollectionSelector'; -import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator'; -import History from './History'; - -function createMapStateToProps() { - return createSelector( - (state) => state.history, - (state) => state.movies, - createCustomFiltersSelector('history'), - (history, movies, customFilters) => { - return { - isMoviesFetching: movies.isFetching, - isMoviesPopulated: movies.isPopulated, - moviesError: movies.error, - customFilters, - ...history - }; - } - ); -} - -const mapDispatchToProps = { - ...historyActions -}; - -class HistoryConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - const { - useCurrentPage, - fetchHistory, - gotoHistoryFirstPage - } = this.props; - - registerPagePopulator(this.repopulate); - - if (useCurrentPage) { - fetchHistory(); - } else { - gotoHistoryFirstPage(); - } - } - - componentWillUnmount() { - unregisterPagePopulator(this.repopulate); - this.props.clearHistory(); - } - - // - // Control - - repopulate = () => { - this.props.fetchHistory(); - }; - - // - // Listeners - - onFirstPagePress = () => { - this.props.gotoHistoryFirstPage(); - }; - - onPreviousPagePress = () => { - this.props.gotoHistoryPreviousPage(); - }; - - onNextPagePress = () => { - this.props.gotoHistoryNextPage(); - }; - - onLastPagePress = () => { - this.props.gotoHistoryLastPage(); - }; - - onPageSelect = (page) => { - this.props.gotoHistoryPage({ page }); - }; - - onSortPress = (sortKey) => { - this.props.setHistorySort({ sortKey }); - }; - - onFilterSelect = (selectedFilterKey) => { - this.props.setHistoryFilter({ selectedFilterKey }); - }; - - onTableOptionChange = (payload) => { - this.props.setHistoryTableOption(payload); - - if (payload.pageSize) { - this.props.gotoHistoryFirstPage(); - } - }; - - // - // Render - - render() { - return ( - - ); - } -} - -HistoryConnector.propTypes = { - useCurrentPage: PropTypes.bool.isRequired, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - fetchHistory: PropTypes.func.isRequired, - gotoHistoryFirstPage: PropTypes.func.isRequired, - gotoHistoryPreviousPage: PropTypes.func.isRequired, - gotoHistoryNextPage: PropTypes.func.isRequired, - gotoHistoryLastPage: PropTypes.func.isRequired, - gotoHistoryPage: PropTypes.func.isRequired, - setHistorySort: PropTypes.func.isRequired, - setHistoryFilter: PropTypes.func.isRequired, - setHistoryTableOption: PropTypes.func.isRequired, - clearHistory: PropTypes.func.isRequired -}; - -export default withCurrentPage( - connect(createMapStateToProps, mapDispatchToProps)(HistoryConnector) -); diff --git a/frontend/src/Activity/History/HistoryEventTypeCell.js b/frontend/src/Activity/History/HistoryEventTypeCell.tsx similarity index 56% rename from frontend/src/Activity/History/HistoryEventTypeCell.js rename to frontend/src/Activity/History/HistoryEventTypeCell.tsx index b6e003ace..5069a8e05 100644 --- a/frontend/src/Activity/History/HistoryEventTypeCell.js +++ b/frontend/src/Activity/History/HistoryEventTypeCell.tsx @@ -1,12 +1,17 @@ -import PropTypes from 'prop-types'; import React from 'react'; import Icon from 'Components/Icon'; import TableRowCell from 'Components/Table/Cells/TableRowCell'; import { icons, kinds } from 'Helpers/Props'; +import { + GrabbedHistoryData, + HistoryData, + HistoryEventType, + MovieFileDeletedHistory, +} from 'typings/History'; import translate from 'Utilities/String/translate'; import styles from './HistoryEventTypeCell.css'; -function getIconName(eventType, data) { +function getIconName(eventType: HistoryEventType, data: HistoryData) { switch (eventType) { case 'grabbed': return icons.DOWNLOADING; @@ -17,7 +22,9 @@ function getIconName(eventType, data) { case 'downloadFailed': return icons.DOWNLOADING; case 'movieFileDeleted': - return data.reason === 'MissingFromDisk' ? icons.FILE_MISSING : icons.DELETE; + return (data as MovieFileDeletedHistory).reason === 'MissingFromDisk' + ? icons.FILE_MISSING + : icons.DELETE; case 'movieFileRenamed': return icons.ORGANIZE; case 'downloadIgnored': @@ -27,7 +34,7 @@ function getIconName(eventType, data) { } } -function getIconKind(eventType) { +function getIconKind(eventType: HistoryEventType) { switch (eventType) { case 'downloadFailed': return kinds.DANGER; @@ -36,52 +43,47 @@ function getIconKind(eventType) { } } -function getTooltip(eventType, data) { +function getTooltip(eventType: HistoryEventType, data: HistoryData) { switch (eventType) { case 'grabbed': - return translate('MovieGrabbedHistoryTooltip', { indexer: data.indexer, downloadClient: data.downloadClient }); + return translate('MovieGrabbedTooltip', { + indexer: (data as GrabbedHistoryData).indexer, + downloadClient: (data as GrabbedHistoryData).downloadClient, + }); case 'movieFolderImported': return translate('MovieFolderImportedTooltip'); case 'downloadFolderImported': return translate('MovieImportedTooltip'); case 'downloadFailed': - return translate('MovieDownloadFailedTooltip'); + return translate('DownloadFailedMovieTooltip'); case 'movieFileDeleted': - return data.reason === 'MissingFromDisk' ? translate('MovieFileMissingTooltip') : translate('MovieFileDeletedTooltip'); + return (data as MovieFileDeletedHistory).reason === 'MissingFromDisk' + ? translate('MovieFileMissingTooltip') + : translate('MovieFileDeletedTooltip'); case 'movieFileRenamed': return translate('MovieFileRenamedTooltip'); case 'downloadIgnored': - return translate('MovieDownloadIgnoredTooltip'); + return translate('DownloadIgnoredMovieTooltip'); default: return translate('UnknownEventTooltip'); } } -function HistoryEventTypeCell({ eventType, data }) { +interface HistoryEventTypeCellProps { + eventType: HistoryEventType; + data: HistoryData; +} + +function HistoryEventTypeCell({ eventType, data }: HistoryEventTypeCellProps) { const iconName = getIconName(eventType, data); const iconKind = getIconKind(eventType); const tooltip = getTooltip(eventType, data); return ( - - + + ); } -HistoryEventTypeCell.propTypes = { - eventType: PropTypes.string.isRequired, - data: PropTypes.object -}; - -HistoryEventTypeCell.defaultProps = { - data: {} -}; - export default HistoryEventTypeCell; diff --git a/frontend/src/Activity/History/HistoryRow.js b/frontend/src/Activity/History/HistoryRow.js deleted file mode 100644 index db87740ac..000000000 --- a/frontend/src/Activity/History/HistoryRow.js +++ /dev/null @@ -1,277 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import IconButton from 'Components/Link/IconButton'; -import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; -import TableRowCell from 'Components/Table/Cells/TableRowCell'; -import TableRow from 'Components/Table/TableRow'; -import Tooltip from 'Components/Tooltip/Tooltip'; -import { icons, tooltipPositions } from 'Helpers/Props'; -import MovieFormats from 'Movie/MovieFormats'; -import MovieLanguages from 'Movie/MovieLanguages'; -import MovieQuality from 'Movie/MovieQuality'; -import MovieTitleLink from 'Movie/MovieTitleLink'; -import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; -import HistoryDetailsModal from './Details/HistoryDetailsModal'; -import HistoryEventTypeCell from './HistoryEventTypeCell'; -import styles from './HistoryRow.css'; - -class HistoryRow extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - isDetailsModalOpen: false - }; - } - - componentDidUpdate(prevProps) { - if ( - prevProps.isMarkingAsFailed && - !this.props.isMarkingAsFailed && - !this.props.markAsFailedError - ) { - this.setState({ isDetailsModalOpen: false }); - } - } - - // - // Listeners - - onDetailsPress = () => { - this.setState({ isDetailsModalOpen: true }); - }; - - onDetailsModalClose = () => { - this.setState({ isDetailsModalOpen: false }); - }; - - // - // Render - - render() { - const { - movie, - quality, - customFormats, - customFormatScore, - languages, - qualityCutoffNotMet, - eventType, - sourceTitle, - date, - data, - downloadId, - isMarkingAsFailed, - columns, - shortDateFormat, - timeFormat, - onMarkAsFailedPress - } = this.props; - - if (!movie) { - return null; - } - - return ( - - { - columns.map((column) => { - const { - name, - isVisible - } = column; - - if (!isVisible) { - return null; - } - - if (name === 'eventType') { - return ( - - ); - } - - if (name === 'movieMetadata.sortTitle') { - return ( - - - - ); - } - - if (name === 'languages') { - return ( - - - - ); - } - - if (name === 'quality') { - return ( - - - - ); - } - - if (name === 'customFormats') { - return ( - - - - ); - } - - if (name === 'date') { - return ( - - ); - } - - if (name === 'downloadClient') { - return ( - - {data.downloadClient} - - ); - } - - if (name === 'indexer') { - return ( - - {data.indexer} - - ); - } - - if (name === 'customFormatScore') { - return ( - - } - position={tooltipPositions.BOTTOM} - /> - - ); - } - - if (name === 'releaseGroup') { - return ( - - {data.releaseGroup} - - ); - } - - if (name === 'sourceTitle') { - return ( - - {sourceTitle} - - ); - } - - if (name === 'details') { - return ( - -
- -
-
- ); - } - - return null; - }) - } - - -
- ); - } - -} - -HistoryRow.propTypes = { - movieId: PropTypes.number, - movie: PropTypes.object.isRequired, - languages: PropTypes.arrayOf(PropTypes.object).isRequired, - quality: PropTypes.object.isRequired, - customFormats: PropTypes.arrayOf(PropTypes.object), - customFormatScore: PropTypes.number.isRequired, - qualityCutoffNotMet: PropTypes.bool.isRequired, - eventType: PropTypes.string.isRequired, - sourceTitle: PropTypes.string.isRequired, - date: PropTypes.string.isRequired, - data: PropTypes.object.isRequired, - downloadId: PropTypes.string, - isMarkingAsFailed: PropTypes.bool, - markAsFailedError: PropTypes.object, - columns: PropTypes.arrayOf(PropTypes.object).isRequired, - shortDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired, - onMarkAsFailedPress: PropTypes.func.isRequired -}; - -HistoryRow.defaultProps = { - customFormats: [] -}; - -export default HistoryRow; diff --git a/frontend/src/Activity/History/HistoryRow.tsx b/frontend/src/Activity/History/HistoryRow.tsx new file mode 100644 index 000000000..45d0766b0 --- /dev/null +++ b/frontend/src/Activity/History/HistoryRow.tsx @@ -0,0 +1,224 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import IconButton from 'Components/Link/IconButton'; +import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; +import TableRowCell from 'Components/Table/Cells/TableRowCell'; +import Column from 'Components/Table/Column'; +import TableRow from 'Components/Table/TableRow'; +import Tooltip from 'Components/Tooltip/Tooltip'; +import usePrevious from 'Helpers/Hooks/usePrevious'; +import { icons, tooltipPositions } from 'Helpers/Props'; +import Language from 'Language/Language'; +import MovieFormats from 'Movie/MovieFormats'; +import MovieLanguages from 'Movie/MovieLanguages'; +import MovieQuality from 'Movie/MovieQuality'; +import MovieTitleLink from 'Movie/MovieTitleLink'; +import useMovie from 'Movie/useMovie'; +import { QualityModel } from 'Quality/Quality'; +import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions'; +import CustomFormat from 'typings/CustomFormat'; +import { HistoryData, HistoryEventType } from 'typings/History'; +import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; +import HistoryDetailsModal from './Details/HistoryDetailsModal'; +import HistoryEventTypeCell from './HistoryEventTypeCell'; +import styles from './HistoryRow.css'; + +interface HistoryRowProps { + id: number; + movieId: number; + languages: Language[]; + quality: QualityModel; + customFormats?: CustomFormat[]; + customFormatScore: number; + qualityCutoffNotMet: boolean; + eventType: HistoryEventType; + sourceTitle: string; + date: string; + data: HistoryData; + downloadId?: string; + isMarkingAsFailed?: boolean; + markAsFailedError?: object; + columns: Column[]; +} + +function HistoryRow(props: HistoryRowProps) { + const { + id, + movieId, + languages, + quality, + customFormats = [], + customFormatScore, + qualityCutoffNotMet, + eventType, + sourceTitle, + date, + data, + downloadId, + isMarkingAsFailed = false, + markAsFailedError, + columns, + } = props; + + const wasMarkingAsFailed = usePrevious(isMarkingAsFailed); + const dispatch = useDispatch(); + const movie = useMovie(movieId); + + const [isDetailsModalOpen, setIsDetailsModalOpen] = useState(false); + + const handleDetailsPress = useCallback(() => { + setIsDetailsModalOpen(true); + }, [setIsDetailsModalOpen]); + + const handleDetailsModalClose = useCallback(() => { + setIsDetailsModalOpen(false); + }, [setIsDetailsModalOpen]); + + const handleMarkAsFailedPress = useCallback(() => { + dispatch(markAsFailed({ id })); + }, [id, dispatch]); + + useEffect(() => { + if (wasMarkingAsFailed && !isMarkingAsFailed && !markAsFailedError) { + setIsDetailsModalOpen(false); + dispatch(fetchHistory()); + } + }, [ + wasMarkingAsFailed, + isMarkingAsFailed, + markAsFailedError, + setIsDetailsModalOpen, + dispatch, + ]); + + if (!movie) { + return null; + } + + return ( + + {columns.map((column) => { + const { name, isVisible } = column; + + if (!isVisible) { + return null; + } + + if (name === 'eventType') { + return ( + + ); + } + + if (name === 'movieMetadata.sortTitle') { + return ( + + + + ); + } + + if (name === 'languages') { + return ( + + + + ); + } + + if (name === 'quality') { + return ( + + + + ); + } + + if (name === 'customFormats') { + return ( + + + + ); + } + + if (name === 'date') { + return ; + } + + if (name === 'downloadClient') { + return ( + + {'downloadClient' in data ? data.downloadClient : ''} + + ); + } + + if (name === 'indexer') { + return ( + + {'indexer' in data ? data.indexer : ''} + + ); + } + + if (name === 'customFormatScore') { + return ( + + } + position={tooltipPositions.BOTTOM} + /> + + ); + } + + if (name === 'releaseGroup') { + return ( + + {'releaseGroup' in data ? data.releaseGroup : ''} + + ); + } + + if (name === 'sourceTitle') { + return {sourceTitle}; + } + + if (name === 'details') { + return ( + + + + ); + } + + return null; + })} + + + + ); +} + +export default HistoryRow; diff --git a/frontend/src/Activity/History/HistoryRowConnector.js b/frontend/src/Activity/History/HistoryRowConnector.js deleted file mode 100644 index f3bdb404b..000000000 --- a/frontend/src/Activity/History/HistoryRowConnector.js +++ /dev/null @@ -1,73 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions'; -import createMovieSelector from 'Store/Selectors/createMovieSelector'; -import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; -import HistoryRow from './HistoryRow'; - -function createMapStateToProps() { - return createSelector( - createMovieSelector(), - createUISettingsSelector(), - (movie, uiSettings) => { - return { - movie, - shortDateFormat: uiSettings.shortDateFormat, - timeFormat: uiSettings.timeFormat - }; - } - ); -} - -const mapDispatchToProps = { - fetchHistory, - markAsFailed -}; - -class HistoryRowConnector extends Component { - - // - // Lifecycle - - componentDidUpdate(prevProps) { - if ( - prevProps.isMarkingAsFailed && - !this.props.isMarkingAsFailed && - !this.props.markAsFailedError - ) { - this.props.fetchHistory(); - } - } - - // - // Listeners - - onMarkAsFailedPress = () => { - this.props.markAsFailed({ id: this.props.id }); - }; - - // - // Render - - render() { - return ( - - ); - } - -} - -HistoryRowConnector.propTypes = { - id: PropTypes.number.isRequired, - isMarkingAsFailed: PropTypes.bool, - markAsFailedError: PropTypes.object, - fetchHistory: PropTypes.func.isRequired, - markAsFailed: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(HistoryRowConnector); diff --git a/frontend/src/App/AppRoutes.tsx b/frontend/src/App/AppRoutes.tsx index f562083f3..e1b2d2e11 100644 --- a/frontend/src/App/AppRoutes.tsx +++ b/frontend/src/App/AppRoutes.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Redirect, Route } from 'react-router-dom'; import Blocklist from 'Activity/Blocklist/Blocklist'; -import HistoryConnector from 'Activity/History/HistoryConnector'; +import History from 'Activity/History/History'; import Queue from 'Activity/Queue/Queue'; import AddNewMovieConnector from 'AddMovie/AddNewMovie/AddNewMovieConnector'; import ImportMovies from 'AddMovie/ImportMovie/ImportMovies'; @@ -79,7 +79,7 @@ function AppRoutes() { Activity */} - + diff --git a/frontend/src/App/State/HistoryAppState.ts b/frontend/src/App/State/HistoryAppState.ts index e368ff86e..632b82179 100644 --- a/frontend/src/App/State/HistoryAppState.ts +++ b/frontend/src/App/State/HistoryAppState.ts @@ -1,10 +1,14 @@ import AppSectionState, { AppSectionFilterState, + PagedAppSectionState, + TableAppSectionState, } from 'App/State/AppSectionState'; import History from 'typings/History'; interface HistoryAppState extends AppSectionState, - AppSectionFilterState {} + AppSectionFilterState, + PagedAppSectionState, + TableAppSectionState {} export default HistoryAppState; diff --git a/frontend/src/Utilities/Object/selectUniqueIds.js b/frontend/src/Utilities/Object/selectUniqueIds.js deleted file mode 100644 index c2c0c17e3..000000000 --- a/frontend/src/Utilities/Object/selectUniqueIds.js +++ /dev/null @@ -1,15 +0,0 @@ -import _ from 'lodash'; - -function selectUniqueIds(items, idProp) { - const ids = _.reduce(items, (result, item) => { - if (item[idProp]) { - result.push(item[idProp]); - } - - return result; - }, []); - - return _.uniq(ids); -} - -export default selectUniqueIds; diff --git a/frontend/src/Utilities/Object/selectUniqueIds.ts b/frontend/src/Utilities/Object/selectUniqueIds.ts new file mode 100644 index 000000000..847613c83 --- /dev/null +++ b/frontend/src/Utilities/Object/selectUniqueIds.ts @@ -0,0 +1,13 @@ +import KeysMatching from 'typings/Helpers/KeysMatching'; + +function selectUniqueIds(items: T[], idProp: KeysMatching) { + return items.reduce((acc: K[], item) => { + if (item[idProp] && acc.indexOf(item[idProp] as K) === -1) { + acc.push(item[idProp] as K); + } + + return acc; + }, []); +} + +export default selectUniqueIds; diff --git a/frontend/src/typings/Helpers/KeysMatching.ts b/frontend/src/typings/Helpers/KeysMatching.ts index 0e20206ef..107e0904f 100644 --- a/frontend/src/typings/Helpers/KeysMatching.ts +++ b/frontend/src/typings/Helpers/KeysMatching.ts @@ -1,4 +1,4 @@ -type KeysMatching = { +export type KeysMatching = { [K in keyof T]-?: T[K] extends V ? K : never; }[keyof T]; diff --git a/frontend/src/typings/History.ts b/frontend/src/typings/History.ts index ee4c11842..0c43f3236 100644 --- a/frontend/src/typings/History.ts +++ b/frontend/src/typings/History.ts @@ -11,6 +11,61 @@ export type HistoryEventType = | 'movieFileRenamed' | 'downloadIgnored'; +export interface GrabbedHistoryData { + indexer: string; + nzbInfoUrl: string; + releaseGroup: string; + age: string; + ageHours: string; + ageMinutes: string; + publishedDate: string; + downloadClient: string; + downloadClientName: string; + size: string; + downloadUrl: string; + guid: string; + tmdbId: string; + protocol: string; + customFormatScore?: string; + movieMatchType: string; + releaseSource: string; + indexerFlags: string; +} + +export interface DownloadFailedHistory { + message: string; +} + +export interface DownloadFolderImportedHistory { + customFormatScore?: string; + droppedPath: string; + importedPath: string; +} + +export interface MovieFileDeletedHistory { + customFormatScore?: string; + reason: 'Manual' | 'MissingFromDisk' | 'Upgrade'; +} + +export interface MovieFileRenamedHistory { + sourcePath: string; + sourceRelativePath: string; + path: string; + relativePath: string; +} + +export interface DownloadIgnoredHistory { + message: string; +} + +export type HistoryData = + | GrabbedHistoryData + | DownloadFailedHistory + | DownloadFolderImportedHistory + | MovieFileDeletedHistory + | MovieFileRenamedHistory + | DownloadIgnoredHistory; + export default interface History { movieId: number; sourceTitle: string; @@ -22,6 +77,6 @@ export default interface History { date: string; downloadId: string; eventType: HistoryEventType; - data: unknown; + data: HistoryData; id: number; } diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 0785c95bb..6857dfb03 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -1048,7 +1048,7 @@ "DeleteConditionMessageText": "هل أنت متأكد من أنك تريد حذف ملف تعريف الجودة {0}", "AddAutoTagError": "غير قادر على إضافة قائمة جديدة ، يرجى المحاولة مرة أخرى.", "ConditionUsingRegularExpressions": "يتطابق هذا الشرط مع استخدام التعبيرات العادية. لاحظ أن الأحرف {0} لها معاني خاصة وتحتاج إلى الهروب بعلامة {1}", - "DeletedReasonMissingFromDisk": "لم يتمكن Whisparr من العثور على الملف على القرص لذا تمت إزالته", + "DeletedReasonMovieMissingFromDisk": "لم يتمكن {appName} من العثور على الملف على القرص لذا تمت إزالته", "MovieFileDeleted": "عند حذف ملف الفيلم", "DeleteCustomFormatMessageText": "هل أنت متأكد أنك تريد حذف العلامة \"{0}\"؟", "DeleteFormatMessageText": "هل أنت متأكد أنك تريد حذف العلامة \"{0}\"؟", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index b21ba80fe..d2f71c510 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -1046,7 +1046,7 @@ "RemoveSelectedItemsQueueMessageText": "Наистина ли искате да премахнете {0} елемент {1} от опашката?", "ApplyTagsHelpTextHowToApplyMovies": "Как да приложите тагове към избраните филми", "MovieSearchResultsLoadError": "Не могат да се заредят резултати за това търсене на филм. Опитайте отново по-късно", - "DeletedReasonMissingFromDisk": "Whisparr не можа да намери файла на диска, така че той беше премахнат", + "DeletedReasonMovieMissingFromDisk": "{appName} не можа да намери файла на диска, така че той беше премахнат", "IMDbId": "Идентификатор на TMDb", "NotificationsSimplepushSettingsEvent": "Събития", "MovieIsNotMonitored": "Филмът не се следи", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index c3b99c5ae..5e941dfdc 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -1112,7 +1112,7 @@ "ConnectionLostReconnect": "{appName} intentarà connectar-se automàticament, o podeu fer clic a recarregar.", "ConnectionLostToBackend": "{appName} ha perdut la connexió amb el backend i s'haurà de tornar a carregar per a restaurar la funcionalitat.", "DelayingDownloadUntil": "S'està retardant la baixada fins al {date} a les {time}", - "DeletedReasonMissingFromDisk": "{appName} no ha pogut trobar el fitxer al disc, de manera que el fitxer es desenllaçarà de la pel·lícula a la base de dades", + "DeletedReasonMovieMissingFromDisk": "{appName} no ha pogut trobar el fitxer al disc, de manera que el fitxer es desenllaçarà de la pel·lícula a la base de dades", "DeletedReasonUpgrade": "S'ha suprimit el fitxer per a importar una versió millorada", "HistoryLoadError": "No es pot carregar l'historial", "MovieFileDeleted": "S'ha suprimit el fitxer de pel·lícula", @@ -1200,7 +1200,7 @@ "InteractiveSearchResultsFailedErrorMessage": "La cerca ha fallat per {message}. Actualitza la informació de la pel·lícula i verifica que hi hagi la informació necessària abans de tornar a cercar.", "LogFilesLocation": "Els fitxers de registre es troben a: {location}", "ManageDownloadClients": "Gestiona els clients de descàrrega", - "MovieGrabbedHistoryTooltip": "Pel·lícula captura de {indexer} i enviada a {downloadClient}", + "MovieGrabbedTooltip": "Pel·lícula captura de {indexer} i enviada a {downloadClient}", "MovieFolderImportedTooltip": "Pel·lícula importada des de la carpeta de pel·lícules", "FullColorEvents": "Esdeveniments a tot color", "FullColorEventsHelpText": "Estil alterat per a pintar tot l'esdeveniment amb el color d'estat, en lloc de només la vora esquerra. No s'aplica a l'Agenda", @@ -1240,8 +1240,8 @@ "InfoUrl": "URL d'informació", "InvalidUILanguage": "La vostra IU està configurada en un idioma no vàlid, corregiu-lo i deseu la configuració", "ManageImportLists": "Gestiona les llistes d'importació", - "MovieDownloadFailedTooltip": "La baixada de la pel·lícula ha fallat", - "MovieDownloadIgnoredTooltip": "S'ha ignorat la pel·lícula baixada", + "DownloadFailedMovieTooltip": "La baixada de la pel·lícula ha fallat", + "DownloadIgnoredMovieTooltip": "S'ha ignorat la pel·lícula baixada", "MovieFileRenamed": "S'ha canviat el nom del fitxer de pel·lícula", "MovieImportedTooltip": "La pel·lícula s'ha baixat correctament i s'ha recollit del client de descàrrega", "EnableProfile": "Activa el perfil", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index dcf34809f..25d3f6a20 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1090,7 +1090,7 @@ "BlocklistReleaseHelpText": "Zabránit {appName} v opětovném sebrání tohoto vydání pomocí RSS nebo automatického vyhledávání", "CustomFormatJson": "Vlastní JSON formát", "DeleteQualityProfileMessageText": "Opravdu chcete smazat profil kvality '{name}'?", - "DeletedReasonMissingFromDisk": "{appName}u se nepodařilo najít soubor na disku, proto byl soubor odpojen od filmu v databázi", + "DeletedReasonMovieMissingFromDisk": "{appName}u se nepodařilo najít soubor na disku, proto byl soubor odpojen od filmu v databázi", "DeletedReasonUpgrade": "Soubor byl odstraněn pro import lepší verze", "DeleteSelectedMovieFilesHelpText": "Opravdu chcete smazat vybrané soubory filmů?", "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Klient stahování {downloadClientName} je nastaven na odstranění dokončených stahování. To může vést k tomu, že stahování budou z klienta odstraněna dříve, než je bude moci importovat {appName}.", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 50640851c..6b2b052f1 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -1067,7 +1067,7 @@ "MovieIsNotMonitored": "Film overvåges", "DeleteReleaseProfile": "Slet forsinkelsesprofil", "DeleteReleaseProfileMessageText": "Er du sikker på, at du vil slette kvalitetsprofilen {0}", - "DeletedReasonMissingFromDisk": "Whisparr kunne ikke finde filen på disken, så den blev fjernet", + "DeletedReasonMovieMissingFromDisk": "{appName} kunne ikke finde filen på disken, så den blev fjernet", "ReleaseProfilesLoadError": "Kunne ikke indlæse forsinkelsesprofiler", "SearchOnAddCollectionHelpText": "Søg efter film på denne liste, når du føjes til {appName}", "EditConnectionImplementation": "Tilføj forbindelse - {implementationName}", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 277d0098e..b95e08fee 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1443,7 +1443,7 @@ "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Optionaler Speicherort für Downloads. Lassen Sie das Feld leer, um den standardmäßigen rTorrent-Speicherort zu verwenden", "DownloadClientDelugeSettingsDirectoryHelpText": "Optionaler Speicherort für Downloads. Lassen Sie das Feld leer, um den standardmäßigen rTorrent-Speicherort zu verwenden", "ListQualityProfileHelpText": "Qualitätsprofil mit dem Listemelemente hinzugefügt werden sollen", - "DeletedReasonMissingFromDisk": "{appName} konnte die Datei auf der Festplatte nicht finden, daher wurde die Verknüpfung der Datei mit der Episode in der Datenbank aufgehoben", + "DeletedReasonMovieMissingFromDisk": "{appName} konnte die Datei auf der Festplatte nicht finden, daher wurde die Verknüpfung der Datei mit der Episode in der Datenbank aufgehoben", "ReleaseProfileTagMovieHelpText": "Veröffentlichungsprofile gelten für Künstler mit mindestens einem passenden Tag. Leer lassen, damit es für alle Künstler gilt", "SearchForAllMissingMoviesConfirmationCount": "Bist du dir sicher, dass du nach allen '{0}' fehlenden Alben suchen willst?", "SearchForCutoffUnmetMovies": "Suche nach allen abgeschnittenen unerfüllten Büchern", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 045412a6f..d94c7426c 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -1192,7 +1192,7 @@ "ConditionUsingRegularExpressions": "Αυτή η συνθήκη ταιριάζει με τη χρήση τυπικών εκφράσεων. Λάβετε υπόψη ότι οι χαρακτήρες {0} έχουν ειδικές έννοιες και χρειάζονται διαφυγή με {1}", "DeleteSpecificationHelpText": "Είστε σίγουροι πως θέλετε να διαγράψετε τη συνθήκη '{name}';", "ApplyTagsHelpTextHowToApplyMovies": "Πώς να εφαρμόσετε ετικέτες στις επιλεγμένες ταινίες", - "DeletedReasonMissingFromDisk": "Ο Whisparr δεν μπόρεσε να βρει το αρχείο στο δίσκο και έτσι καταργήθηκε", + "DeletedReasonMovieMissingFromDisk": "Ο {appName} δεν μπόρεσε να βρει το αρχείο στο δίσκο και έτσι καταργήθηκε", "ReleaseProfileTagMovieHelpText": "Τα προφίλ κυκλοφορίας θα ισχύουν για καλλιτέχνες με τουλάχιστον μία αντίστοιχη ετικέτα. Αφήστε το κενό για να εφαρμοστεί σε όλους τους καλλιτέχνες", "DownloadClientSettingsRecentPriority": "Προτεραιότητα πελάτη", "MovieIsNotMonitored": "Η ταινία παρακολουθείται", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 11b64845a..780d954e5 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -365,7 +365,7 @@ "Deleted": "Deleted", "DeletedMovieDescription": "Movie was deleted from TMDb", "DeletedReasonManual": "File was deleted using {appName}, either manually or by another tool through the API", - "DeletedReasonMissingFromDisk": "{appName} was unable to find the file on disk so the file was unlinked from the movie in the database", + "DeletedReasonMovieMissingFromDisk": "{appName} was unable to find the file on disk so the file was unlinked from the movie in the database", "DeletedReasonUpgrade": "File was deleted to import an upgrade", "Destination": "Destination", "DestinationPath": "Destination Path", @@ -541,7 +541,9 @@ "DownloadClientsLoadError": "Unable to load download clients", "DownloadClientsSettingsSummary": "Download clients, download handling and remote path mappings", "DownloadFailed": "Download failed", + "DownloadFailedMovieTooltip": "Movie download failed", "DownloadIgnored": "Download Ignored", + "DownloadIgnoredMovieTooltip": "Movie Download Ignored", "DownloadPropersAndRepacks": "Propers and Repacks", "DownloadPropersAndRepacksHelpText": "Whether or not to automatically upgrade to Propers/Repacks", "DownloadPropersAndRepacksHelpTextCustomFormat": "Use 'Do not Prefer' to sort by custom format score over Propers/Repacks", @@ -962,8 +964,6 @@ "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Missing root folder for movie collection: {rootFolderInfo}", "MovieDetailsNextMovie": "Movie Details: Next Movie", "MovieDetailsPreviousMovie": "Movie Details: Previous Movie", - "MovieDownloadFailedTooltip": "Movie download failed", - "MovieDownloadIgnoredTooltip": "Movie Download Ignored", "MovieDownloaded": "Movie Downloaded", "MovieEditor": "Movie Editor", "MovieExcludedFromAutomaticAdd": "Movie Excluded From Automatic Add", @@ -978,7 +978,7 @@ "MovieFolderFormatHelpText": "Used when adding a new movie or moving movies via the movie editor", "MovieFolderImportedTooltip": "Movie imported from movie folder", "MovieFootNote": "Optionally control truncation to a maximum number of bytes including ellipsis (`...`). Truncating from the end (e.g. `{Movie Title:30}`) or the beginning (e.g. `{Movie Title:-30}`) are both supported.", - "MovieGrabbedHistoryTooltip": "Movie grabbed from {indexer} and sent to {downloadClient}", + "MovieGrabbedTooltip": "Movie grabbed from {indexer} and sent to {downloadClient}", "MovieID": "Movie ID", "MovieImported": "Movie Imported", "MovieImportedTooltip": "Movie downloaded successfully and picked up from download client", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index dc93d5582..6ec6b0cc0 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1157,7 +1157,7 @@ "DeleteSelectedIndexersMessageText": "¿Estás seguro que quieres eliminar {count} indexador(es) seleccionado(s)?", "DisabledForLocalAddresses": "Deshabilitada para direcciones locales", "DeletedReasonManual": "El archivo fue eliminado usando {appName}, o bien manualmente o por otra herramienta a través de la API", - "DeletedReasonMissingFromDisk": "{appName} no ha podido encontrar el archivo en el disco, por lo que se ha desvinculado de la película en la base de datos", + "DeletedReasonMovieMissingFromDisk": "{appName} no ha podido encontrar el archivo en el disco, por lo que se ha desvinculado de la película en la base de datos", "DeletedReasonUpgrade": "Se ha borrado el archivo para importar una versión mejorada", "DeleteSelectedMovieFilesHelpText": "¿Está seguro de que desea eliminar los archivos de película seleccionados?", "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirma la nueva contraseña", @@ -1222,13 +1222,13 @@ "MovieFileRenamedTooltip": "Archivo de película renombrado", "MovieFolderImportedTooltip": "Película importada de la carpeta de películas", "InteractiveSearchModalHeader": "Búsqueda interactiva", - "MovieDownloadIgnoredTooltip": "Descarga de la película ignorada", - "MovieDownloadFailedTooltip": "No se ha podido descargar la película", + "DownloadIgnoredMovieTooltip": "Descarga de la película ignorada", + "DownloadFailedMovieTooltip": "No se ha podido descargar la película", "MovieFileDeletedTooltip": "Archivo de película eliminado", "MovieFileRenamed": "Archivo de película renombrado", "LanguagesLoadError": "No es posible cargar los idiomas", "DownloadClientQbittorrentSettingsContentLayout": "Diseño del contenido", - "MovieGrabbedHistoryTooltip": "Película capturada de {indexer} y enviada a {downloadClient}", + "MovieGrabbedTooltip": "Película capturada de {indexer} y enviada a {downloadClient}", "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Si usar el diseño de contenido configurado de qBittorrent, el diseño original del torrent o siempre crear una subcarpeta (qBittorrent 4.3.2+)", "MovieImported": "Película importada", "MovieImportedTooltip": "Película descargada correctamente y obtenida del cliente de descargas", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 28d917e9b..40af8f982 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -1216,7 +1216,7 @@ "DeletedReasonManual": "Tiedosto poistettiin käyttöliittymän kautta", "DeletedReasonUpgrade": "Tiedosto poistettiin päivitetyn version tuomiseksi", "InteractiveImportNoMovie": "Elokuva on valittava jokaiselle valitulle tiedostolle.", - "MovieGrabbedHistoryTooltip": "Elokuva kaapattiin lähteestä {indexer} ja välitettiin lataajalle {downloadClient}", + "MovieGrabbedTooltip": "Elokuva kaapattiin lähteestä {indexer} ja välitettiin lataajalle {downloadClient}", "CloneCondition": "Monista ehto", "AutomaticAdd": "Automaattinen lisäys", "AutoTagging": "Automaattinen tunnistemerkintä", @@ -1245,7 +1245,7 @@ "InteractiveImportNoFilesFound": "Valitusta kansiosta ei löytynyt videotiedostoja.", "ManualGrab": "Manuaalinen kaappaus", "Complete": "Kokonaiset", - "DeletedReasonMissingFromDisk": "{appName} ei löytänyt tiedostoa levyltä, joten sen kytkös kirjaston elokuvaan poistettiin.", + "DeletedReasonMovieMissingFromDisk": "{appName} ei löytänyt tiedostoa levyltä, joten sen kytkös kirjaston elokuvaan poistettiin.", "ShowImdbRatingHelpText": "Näytä IMDb-arvio julisteen alla.", "ShowRottenTomatoesRating": "Näytä Tomato-arvio", "ShowRottenTomatoesRatingHelpText": "Näytä Tomato-arvio julisteen alla.", @@ -1415,7 +1415,7 @@ "CustomFormatsSpecificationRegularExpression": "Säännöllinen lauseke", "False": "Epätosi", "CustomFormatsSpecificationRegularExpressionHelpText": "Mukautetun muodon säännöllisen lausekkeen kirjainkokoa ei huomioida.", - "MovieDownloadIgnoredTooltip": "Elokuvalataus ohitettiin", + "DownloadIgnoredMovieTooltip": "Elokuvalataus ohitettiin", "MovieFolderImportedTooltip": "Elokuva tuotiin elokuvakansiosta", "True": "Tosi", "SkipRedownloadHelpText": "Estää {appName}ia lataamasta kohteelle vaihtoehtoista julkaisua.", @@ -1460,7 +1460,7 @@ "NotificationsValidationUnableToConnectToService": "Palvelua {serviceName} ei tavoiteta.", "NotificationsValidationUnableToSendTestMessage": "Testiviestin lähetys ei onnistu: {exceptionMessage}", "NotificationsEmailSettingsUseEncryptionHelpText": "Määrittää suositaanko salausta, jos se on määritetty palvelimelle, käytetäänkö aina SSL- (vain portti 465) tai StartTLS-salausta (kaikki muut portit), voi käytetäänkö salausta lainkaan.", - "MovieDownloadFailedTooltip": "Elokuvan lataus epäonnistui", + "DownloadFailedMovieTooltip": "Elokuvan lataus epäonnistui", "MovieFileDeleted": "Elokuvatiedosto poistettiin", "MovieFileDeletedTooltip": "Elokuvatiedosto poistettiin", "ThereWasAnErrorLoadingThisItem": "Virhe ladattaessa kohdetta", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index f21348846..e2247da14 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1216,7 +1216,7 @@ "AutoTaggingLoadError": "Impossible de charger le marquage automatique", "DelayingDownloadUntil": "Retarder le téléchargement jusqu'au {date} à {time}", "DeleteSelectedMovieFilesHelpText": "Voulez-vous vraiment supprimer les fichiers vidéo sélectionnés ?", - "DeletedReasonMissingFromDisk": "{appName} n'a pas pu trouver le fichier sur le disque, il a donc été supprimé dans la base de données", + "DeletedReasonMovieMissingFromDisk": "{appName} n'a pas pu trouver le fichier sur le disque, il a donc été supprimé dans la base de données", "DeletedReasonUpgrade": "Le fichier a été supprimé pour importer une mise à niveau", "OrganizeLoadError": "Erreur lors du chargement des aperçus", "EditImportListImplementation": "Modifier la liste d'importation - {implementationName}", @@ -1285,7 +1285,7 @@ "MovieFileRenamed": "Fichier vidéo renommé", "MovieFileRenamedTooltip": "Fichier vidéo renommé", "MovieFolderImportedTooltip": "Film importé du dossier de film", - "MovieGrabbedHistoryTooltip": "Film récupéré de {indexer} et envoyé à {downloadClient}", + "MovieGrabbedTooltip": "Film récupéré de {indexer} et envoyé à {downloadClient}", "RemoveQueueItem": "Retirer - {sourceTitle}", "OverrideGrabModalTitle": "Remplacer et récupérer - {title}", "RemoveTagsAutomaticallyHelpText": "Supprimez automatiquement les étiquettes si les conditions ne sont pas remplies", @@ -1296,8 +1296,8 @@ "SetReleaseGroupModalTitle": "{modalTitle} – Définir le groupe de versions", "CountImportListsSelected": "{count} liste(s) d'importation sélectionnée(s)", "InteractiveSearchResultsFailedErrorMessage": "La recherche a échoué car il s'agit d'un {message}. Essayez d'actualiser les informations sur le film et vérifiez que les informations nécessaires sont présentes avant de lancer une nouvelle recherche.", - "MovieDownloadFailedTooltip": "Le téléchargement du film a échoué", - "MovieDownloadIgnoredTooltip": "Téléchargement de film ignoré", + "DownloadFailedMovieTooltip": "Le téléchargement du film a échoué", + "DownloadIgnoredMovieTooltip": "Téléchargement de film ignoré", "SkipRedownloadHelpText": "Empêche {appName} d'essayer de télécharger une version alternative pour cet élément", "QueueFilterHasNoItems": "Le filtre de file d'attente sélectionné ne contient aucun élément", "EnableProfile": "Activer profil", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index a4a7fadc6..cbafc4160 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -1100,7 +1100,7 @@ "NotificationsSimplepushSettingsEvent": "אירועים", "RemotePathMappingCheckFilesLocalWrongOSPath": "אתה משתמש בדוקר; קליינט ההורדות {downloadClientName} שם הורדות ב-{path} אבל הנתיב לא תקין {osName}. בחן מחדש את ניתוב התיקיות והגדרות קליינט ההורדות.", "RemotePathMappingCheckLocalWrongOSPath": "אתה משתמש בדוקר; קליינט ההורדות {downloadClientName} שם הורדות ב-{path} אבל הנתיב לא תקין {osName}. בחן מחדש את ניתוב התיקיות והגדרות קליינט ההורדות.", - "DeletedReasonMissingFromDisk": "Whisparr לא הצליח למצוא את הקובץ בדיסק ולכן הוא הוסר", + "DeletedReasonMovieMissingFromDisk": "{appName} לא הצליח למצוא את הקובץ בדיסק ולכן הוא הוסר", "AddDelayProfileError": "לא ניתן להוסיף פרופיל איכות חדש, נסה שוב.", "MovieFileDeletedTooltip": "במחיקת קובץ הסרט", "DeleteMovieFolders": "מחק את תיקיית הסרטים", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 59dbbb88e..7a23076ba 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -1047,7 +1047,7 @@ "MovieIsNotMonitored": "मूवी अनमनी है", "DownloadClientSettingsRecentPriority": "ग्राहक प्राथमिकता", "DeleteSelectedMovieFilesHelpText": "क्या आप वाकई चयनित मूवी फ़ाइलों को हटाना चाहते हैं?", - "DeletedReasonMissingFromDisk": "Whisparr डिस्क पर फ़ाइल खोजने में असमर्थ था इसलिए इसे हटा दिया गया था", + "DeletedReasonMovieMissingFromDisk": "{appName} डिस्क पर फ़ाइल खोजने में असमर्थ था इसलिए इसे हटा दिया गया था", "MovieFileDeleted": "मूवी फ़ाइल डिलीट पर", "DeleteCustomFormatMessageText": "क्या आप वाकई '{0}' टैग हटाना चाहते हैं?", "DeleteFormatMessageText": "क्या आप वाकई '{0}' टैग हटाना चाहते हैं?", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index c0205eddd..3ff81d550 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1151,7 +1151,7 @@ "DeleteAutoTag": "Automatikus címke törlése", "DeleteSelectedDownloadClients": "Letöltési kliens(ek) törlése", "DeleteSelectedIndexersMessageText": "Biztosan törölni szeretne {count} kiválasztott indexelőt?", - "DeletedReasonMissingFromDisk": "A(z) {appName} nem találta a fájlt a lemezen, ezért a fájlt leválasztották a filmről az adatbázisban", + "DeletedReasonMovieMissingFromDisk": "A(z) {appName} nem találta a fájlt a lemezen, ezért a fájlt leválasztották a filmről az adatbázisban", "EditIndexerImplementation": "Indexelő szerkesztése – {implementationName}", "FailedToFetchUpdates": "Nem sikerült lekérni a frissítéseket", "FormatAgeDay": "nap", @@ -1418,7 +1418,7 @@ "DownloadClientSettingsOlderPriorityMovieHelpText": "Elsőbbség a 14 nappal ezelőtt sugárzott epizódok megragadásánál", "MovieImportedTooltip": "Az epizód letöltése sikeresen megtörtént, és a letöltés kliensből lett letöltve", "SearchForCutoffUnmetMoviesConfirmationCount": "Biztosan megkeresi az összes {totalRecords} hiányzó epizódot?", - "MovieGrabbedHistoryTooltip": "Az epizódot letöltötte a(z) {indexer} és elküldte a(z) {downloadClient} számára", + "MovieGrabbedTooltip": "Az epizódot letöltötte a(z) {indexer} és elküldte a(z) {downloadClient} számára", "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Választható hely a letöltések elhelyezéséhez, hagyja üresen az alapértelmezett Aria2 hely használatához", "DownloadClientDelugeSettingsDirectoryHelpText": "Választható hely a letöltések elhelyezéséhez, hagyja üresen az alapértelmezett Aria2 hely használatához", "MovieFileDeletedTooltip": "A filmfájl törléséhez", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index 3612f442c..f8c008fbf 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -1055,7 +1055,7 @@ "NotificationsSimplepushSettingsEvent": "Viðburðir", "DeleteSelectedMovieFilesHelpText": "Ertu viss um að þú viljir eyða völdum kvikmyndaskrám?", "AutoRedownloadFailed": "Niðurhal mistókst", - "DeletedReasonMissingFromDisk": "Whisparr gat ekki fundið skrána á disknum svo hún var fjarlægð", + "DeletedReasonMovieMissingFromDisk": "{appName} gat ekki fundið skrána á disknum svo hún var fjarlægð", "DownloadClientSettingsRecentPriority": "Forgangur viðskiptavinar", "AddDelayProfileError": "Ekki er hægt að bæta við nýjum gæðaprófíl, reyndu aftur.", "MovieFileDeletedTooltip": "Á Eyða kvikmyndaskrá", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 351f801f3..f862ea1b0 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1162,7 +1162,7 @@ "ReleaseProfilesLoadError": "Non riesco a caricare i profili di ritardo", "ReleaseGroups": "Gruppo Release", "DeleteReleaseProfileMessageText": "Sicuro di voler cancellare il profilo di qualità {0}", - "DeletedReasonMissingFromDisk": "Whisparr non è riuscito a trovare il file sul disco, quindi è stato rimosso", + "DeletedReasonMovieMissingFromDisk": "{appName} non è riuscito a trovare il file sul disco, quindi è stato rimosso", "DeleteQualityProfileMessageText": "Sicuro di voler cancellare il profilo di qualità '{name}'?", "RemotePathMappingCheckFilesLocalWrongOSPath": "Stai utilizzando docker; Il client di download {downloadClientName} riporta files in {path} ma questo non è un percorso valido {osName}. Controlla la mappa dei percorsi remoti e le impostazioni del client di download.", "AutoTaggingNegateHelpText": "Se selezionato, il formato personalizzato non verrà applicato a questa {0} condizione.", @@ -1231,7 +1231,7 @@ "ManageIndexers": "Gestisci Indicizzatori", "ManageLists": "Gestisci Liste", "Menu": "Menu", - "MovieDownloadFailedTooltip": "Download del film fallito", + "DownloadFailedMovieTooltip": "Download del film fallito", "Never": "Mai", "NotificationsSettingsWebhookMethod": "Metodo", "NotificationsTraktSettingsAuthenticateWithTrakt": "Autentica con Trakt", @@ -1284,7 +1284,7 @@ "Letterboxd": "Letterboxd", "MissingLoadError": "Errore caricando elementi mancanti", "MonitorCollection": "Monitora Collezione", - "MovieDownloadIgnoredTooltip": "Download del Film Ignorato", + "DownloadIgnoredMovieTooltip": "Download del Film Ignorato", "MovieIsNotAvailable": "Film non disponibile", "MovieIsPopular": "Film Popolare su TMDb", "MovieIsTrending": "Film in Tendenza su TMDb", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 11a91f95b..a413424a4 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -1049,7 +1049,7 @@ "MovieFileDeleted": "ムービーファイルの削除について", "SearchOnAddCollectionHelpText": "{appName}に追加されたら、このリストで映画を検索します", "MovieIsNotMonitored": "映画は監視されていません", - "DeletedReasonMissingFromDisk": "Whisparrはディスク上でファイルを見つけることができなかったため、削除されました", + "DeletedReasonMovieMissingFromDisk": "{appName}はディスク上でファイルを見つけることができなかったため、削除されました", "IMDbId": "TMDbID", "DeleteSelectedMovieFilesHelpText": "選択したムービーファイルを削除してもよろしいですか?", "NotificationsSimplepushSettingsEvent": "イベント", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index a49428160..b59b275f5 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1039,7 +1039,7 @@ "RemoveSelectedBlocklistMessageText": "블랙리스트에서 선택한 항목을 제거 하시겠습니까?", "Yes": "예", "ApplyTagsHelpTextHowToApplyMovies": "선택한 동영상에 태그를 적용하는 방법", - "DeletedReasonMissingFromDisk": "Whisparr가 디스크에서 파일을 찾을 수 없어 제거되었습니다.", + "DeletedReasonMovieMissingFromDisk": "{appName}가 디스크에서 파일을 찾을 수 없어 제거되었습니다.", "ShowUnknownMovieItemsHelpText": "대기열에 영화가없는 항목을 표시합니다. 여기에는 제거 된 영화 또는 {appName} 카테고리의 다른 항목이 포함될 수 있습니다.", "DeleteSelectedMovieFilesHelpText": "선택한 동영상 파일을 삭제 하시겠습니까?", "DownloadClientSettingsRecentPriority": "클라이언트 우선 순위", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 8f8be5abc..8b9ed71a9 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -1185,7 +1185,7 @@ "FormatAgeMinute": "minuten", "EditConnectionImplementation": "Voeg connectie toe - {implementationName}", "FormatAgeHour": "Uren", - "DeletedReasonMissingFromDisk": "Whisparr kon het bestand niet vinden op de schijf dus werd het verwijderd", + "DeletedReasonMovieMissingFromDisk": "{appName} kon het bestand niet vinden op de schijf dus werd het verwijderd", "DeleteReleaseProfile": "Verwijder Vertragingsprofiel", "DeleteReleaseProfileMessageText": "Bent u zeker dat u het kwaliteitsprofiel {0} wilt verwijderen", "DownloadClientSettingsRecentPriority": "Client Prioriteit", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index db21bc245..0fb3b07c9 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -1151,7 +1151,7 @@ "MovieSearchResultsLoadError": "Nie można załadować wyników dla tego wyszukiwania filmów. Spróbuj ponownie później", "ShowUnknownMovieItemsHelpText": "Pokaż elementy bez filmu w kolejce. Może to obejmować usunięte filmy lub cokolwiek innego w kategorii Lidarr", "EditConnectionImplementation": "Dodaj Connection - {implementationName}", - "DeletedReasonMissingFromDisk": "Whisparr nie mógł znaleźć pliku na dysku, więc został usunięty", + "DeletedReasonMovieMissingFromDisk": "{appName} nie mógł znaleźć pliku na dysku, więc został usunięty", "DeleteSelectedMovieFilesHelpText": "Czy na pewno chcesz usunąć wybrane pliki filmowe?", "IMDbId": "Identyfikator TMDb", "AddDelayProfileError": "Nie można dodać nowego profilu opóźnienia, spróbuj później.", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index 45a6b3c6d..f3f5601c3 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -1135,7 +1135,7 @@ "DeleteSelectedImportListsMessageText": "Tem a certeza de que pretende eliminar a(s) lista(s) de {count} importação selecionada(s)?", "DeleteSelectedMovieFilesHelpText": "Tem a certeza de que pretende apagar os ficheiros de filmes seleccionados?", "DeletedReasonManual": "O ficheiro foi eliminado através da IU", - "DeletedReasonMissingFromDisk": "O {appName} não conseguiu encontrar o ficheiro no disco, pelo que o ficheiro foi desvinculado do filme na base de dados", + "DeletedReasonMovieMissingFromDisk": "O {appName} não conseguiu encontrar o ficheiro no disco, pelo que o ficheiro foi desvinculado do filme na base de dados", "DeletedReasonUpgrade": "O ficheiro foi eliminado para importar uma atualização", "DisabledForLocalAddresses": "Desativado para Endereços Locais", "DownloadClientsLoadError": "Não foi possível carregar os clientes de transferências", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 738e63e25..0cf261fb9 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1238,8 +1238,8 @@ "UnknownEventTooltip": "Evento desconhecido", "DeletedReasonManual": "O arquivo foi excluído usando {appName} manualmente ou por outra ferramenta por meio da API", "FormatAgeDay": "dia", - "MovieDownloadFailedTooltip": "Falha no download do filme", - "MovieDownloadIgnoredTooltip": "Download do Filme Ignorado", + "DownloadFailedMovieTooltip": "Falha no download do filme", + "DownloadIgnoredMovieTooltip": "Download do Filme Ignorado", "NoHistoryFound": "Nenhum histórico encontrado", "QueueLoadError": "Falha ao carregar a fila", "BlocklistLoadError": "Não foi possível carregar a lista de bloqueio", @@ -1252,7 +1252,7 @@ "HistoryLoadError": "Não foi possível carregar o histórico", "InfoUrl": "URL da info", "MovieImported": "Filme Importado", - "MovieGrabbedHistoryTooltip": "Filme obtido de {indexer} e enviado para {downloadClient}", + "MovieGrabbedTooltip": "Filme obtido de {indexer} e enviado para {downloadClient}", "MovieImportedTooltip": "Filme baixado com sucesso e obtido no cliente de download", "PendingDownloadClientUnavailable": "Pendente - O cliente de download não está disponível", "FormatAgeDays": "dias", @@ -1279,7 +1279,7 @@ "TablePageSize": "Tamanho da Página", "TablePageSizeHelpText": "Número de itens a serem exibidos em cada página", "TablePageSizeMinimum": "O tamanho da página precisa ser de pelo menos {minimumValue}", - "DeletedReasonMissingFromDisk": "O {appName} não conseguiu encontrar o arquivo no disco, então o arquivo foi desvinculado do filme no banco de dados", + "DeletedReasonMovieMissingFromDisk": "O {appName} não conseguiu encontrar o arquivo no disco, então o arquivo foi desvinculado do filme no banco de dados", "FormatDateTimeRelative": "{relativeDay}, {formattedDate} {formattedTime}", "RemoveSelectedBlocklistMessageText": "Tem certeza de que deseja remover os itens selecionados da lista de bloqueio?", "ShowUnknownMovieItemsHelpText": "Mostrar itens sem filme na fila. Isso pode incluir filmes removidos ou qualquer outra coisa na categoria do {appName}", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 7cf726c00..0ac903daa 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -1035,14 +1035,14 @@ "MovieFileRenamed": "Fișier de film redenumit", "MovieFileDeletedTooltip": "Fișier de film șters", "MovieFileDeleted": "Fișier de film șters", - "MovieDownloadIgnoredTooltip": "Descărcare film ignorată", + "DownloadIgnoredMovieTooltip": "Descărcare film ignorată", "MovieImported": "Film importat", - "MovieGrabbedHistoryTooltip": "Film preluat de la {indexer} și trimis către {downloadClient}", + "MovieGrabbedTooltip": "Film preluat de la {indexer} și trimis către {downloadClient}", "FormatAgeMinutes": "minute", "UnknownEventTooltip": "Eveniment necunoscut", "TablePageSize": "Mărimea Paginii", "MovieFileRenamedTooltip": "Fișier de film redenumit", - "MovieDownloadFailedTooltip": "Descărcarea filmului a eșuat", + "DownloadFailedMovieTooltip": "Descărcarea filmului a eșuat", "FullColorEvents": "Evenimente pline de culoare", "BlocklistReleaseHelpText": "Împiedică {appName} să apuce automat această versiune din nou", "BlocklistLoadError": "Imposibil de încărcat lista neagră", @@ -1070,7 +1070,7 @@ "ReleaseProfilesLoadError": "Nu se pot încărca profilurile", "PendingDownloadClientUnavailable": "În așteptare - Clientul de descărcare nu este disponibil", "MovieImportedTooltip": "Filmul a fost descărcat cu succes și preluat de la clientul de descărcare", - "DeletedReasonMissingFromDisk": "{appName} nu a putut găsi fișierul de pe disc, așa că a fost eliminat", + "DeletedReasonMovieMissingFromDisk": "{appName} nu a putut găsi fișierul de pe disc, așa că a fost eliminat", "AddConnection": "Adăugați conexiune", "AddConnectionImplementation": "Adăugați conexiune - {implementationName}", "AddDownloadClientImplementation": "Adăugați client de descărcare - {implementationName}", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index d99970ddc..36e08a323 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1263,7 +1263,7 @@ "Label": "Метка", "DelayProfileMovieTagsHelpText": "Применимо к фильмам с хотя бы одним подходящим тегом", "Release": "Релиз", - "DeletedReasonMissingFromDisk": "{appName} не смог найти файл на диске, поэтому файл был откреплён от фильма в базе данных", + "DeletedReasonMovieMissingFromDisk": "{appName} не смог найти файл на диске, поэтому файл был откреплён от фильма в базе данных", "MovieIsNotMonitored": "Фильм не отслеживается", "MovieFileDeleted": "При удалении файла фильма", "DeleteReleaseProfile": "Удалить профиль релиза", @@ -1641,7 +1641,7 @@ "EditionFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Series Title:30}`), так и с начала (например, `{Series Title:-30}`).", "NotificationsCustomScriptValidationFileDoesNotExist": "Файл не существует", "NotificationsGotifySettingsServerHelpText": "URL-адрес сервера Gotify, включая http(s):// и порт, если необходимо", - "MovieGrabbedHistoryTooltip": "Эпизод получен из {indexer} и отправлен в {downloadClient}", + "MovieGrabbedTooltip": "Эпизод получен из {indexer} и отправлен в {downloadClient}", "NotificationsPlexValidationNoMovieLibraryFound": "Требуется хотя бы одна библиотека c сериалами", "SearchForAllMissingMovies": "Искать все недостающие эпизоды", "SearchForAllMissingMoviesConfirmationCount": "Вы уверены, что хотите найти все ({totalRecords}) недостающие эпизоды ?", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 7eeee1d32..83dcf6ff3 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -1069,7 +1069,7 @@ "ConditionUsingRegularExpressions": "Detta villkor matchar användningen av reguljära uttryck. Observera att tecknen {0} har speciella betydelser och behöver fly med ett {1}", "MovieFileDeleted": "På filmfil Ta bort", "DeleteCustomFormatMessageText": "Är du säker på att du vill radera taggen '{0}'?", - "DeletedReasonMissingFromDisk": "Whisparr kunde inte hitta filen på disken så den togs bort", + "DeletedReasonMovieMissingFromDisk": "{appName} kunde inte hitta filen på disken så den togs bort", "DeleteSelectedMovieFilesHelpText": "Är du säker på att du vill radera de markerade filmfilerna?", "MovieIsNotMonitored": "FIlmen är bevakad", "SearchForAllMissingMovies": "Sök efter alla saknade böcker", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 9dc48eb81..5a5037e07 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -1052,7 +1052,7 @@ "IMDbId": "รหัส TMDb", "MovieFileDeleted": "บน Movie File Delete", "AddDelayProfileError": "ไม่สามารถเพิ่มโปรไฟล์คุณภาพใหม่ได้โปรดลองอีกครั้ง", - "DeletedReasonMissingFromDisk": "Whisparr ไม่พบไฟล์บนดิสก์ดังนั้นจึงถูกลบออก", + "DeletedReasonMovieMissingFromDisk": "{appName} ไม่พบไฟล์บนดิสก์ดังนั้นจึงถูกลบออก", "DownloadClientSettingsRecentPriority": "ลำดับความสำคัญของลูกค้า", "DeleteSelectedMovieFilesHelpText": "แน่ใจไหมว่าต้องการลบไฟล์ภาพยนตร์ที่เลือก", "ShowUnknownMovieItemsHelpText": "แสดงรายการที่ไม่มีภาพยนตร์อยู่ในคิว ซึ่งอาจรวมถึงภาพยนตร์ที่ถูกนำออกหรือสิ่งอื่นใดในหมวดหมู่ของ Lidarr", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 99214201a..7c570a365 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1114,7 +1114,7 @@ "DeleteRootFolderMessageText": "'{path}' kök klasörünü silmek istediğinizden emin misiniz?", "DeleteSelectedIndexersMessageText": "Seçilen {count} dizinleyiciyi silmek istediğinizden emin misiniz?", "Destination": "Hedef", - "DeletedReasonMissingFromDisk": "{appName} dosyayı diskte bulamadığından dosyanın veritabanındaki filmle bağlantısı kaldırıldı", + "DeletedReasonMovieMissingFromDisk": "{appName} dosyayı diskte bulamadığından dosyanın veritabanındaki filmle bağlantısı kaldırıldı", "DownloadClientDelugeTorrentStateError": "Deluge bir hata bildiriyor", "DownloadClientDelugeValidationLabelPluginInactive": "Etiket eklentisi etkinleştirilmedi", "DownloadClientDelugeValidationLabelPluginInactiveDetail": "Kategorileri kullanmak için {clientName} uygulamasında Etiket eklentisini etkinleştirmiş olmanız gerekir.", @@ -1287,8 +1287,8 @@ "ListRefreshInterval": "Liste Yenileme Aralığı", "InteractiveImportNoImportMode": "Bir içe aktarma modu seçilmelidir", "MonitorCollection": "Takip Etme Koleksiyonu", - "MovieDownloadFailedTooltip": "Film indirilemedi", - "MovieDownloadIgnoredTooltip": "Film İndirme Yoksayıldı", + "DownloadFailedMovieTooltip": "Film indirilemedi", + "DownloadIgnoredMovieTooltip": "Film İndirme Yoksayıldı", "NotificationsAppriseSettingsServerUrlHelpText": "Gerekiyorsa http(s):// ve bağlantı noktasını içeren Apprise sunucu URL'si", "NotificationsAppriseSettingsTags": "Apprise Etiketler", "NotificationsEmailSettingsUseEncryption": "Şifreleme Kullan", @@ -1341,7 +1341,7 @@ "IndexerDownloadClientHealthCheckMessage": "Geçersiz indirme istemcilerine sahip dizinleyiciler: {indexerNames}.", "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Film koleksiyonu için eksik kök klasör: {rootFolderInfo}", "NoImportListsFound": "İçe aktarma listesi bulunamadı", - "MovieGrabbedHistoryTooltip": "Film {indexer}'dan alındı ve {downloadClient}'a gönderildi", + "MovieGrabbedTooltip": "Film {indexer}'dan alındı ve {downloadClient}'a gönderildi", "NotificationStatusAllClientHealthCheckMessage": "Arızalar nedeniyle tüm bildirimler kullanılamıyor", "FormatAgeHour": "saat", "GrabId": "ID'den Yakala", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index d8d57eece..3882323ae 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -1103,7 +1103,7 @@ "AddConnection": "Додати Підключення", "TablePageSizeHelpText": "Кількість елементів для показу на кожній сторінці", "ConnectionLostToBackend": "{appName} втратив з’єднання з серверною частиною, і його потрібно перезавантажити, щоб відновити роботу.", - "DeletedReasonMissingFromDisk": "{appName} не зміг знайти файл на диску, тому файл було від’єднано від фільму в базі даних", + "DeletedReasonMovieMissingFromDisk": "{appName} не зміг знайти файл на диску, тому файл було від’єднано від фільму в базі даних", "FormatAgeHours": "Години", "FormatAgeMinute": "Хвилин", "FormatAgeMinutes": "Хвилин", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 418da4ad0..6b074ca78 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -1046,7 +1046,7 @@ "DeleteSelectedMovieFilesHelpText": "Bạn có chắc chắn muốn xóa các tệp phim đã chọn không?", "DeleteCustomFormatMessageText": "Bạn có chắc chắn muốn xóa thẻ '{0}' không?", "DeleteQualityProfileMessageText": "Bạn có chắc chắn muốn xóa cấu hình chất lượng không {0}", - "DeletedReasonMissingFromDisk": "Whisparr không thể tìm thấy tệp trên đĩa nên nó đã bị xóa", + "DeletedReasonMovieMissingFromDisk": "{appName} không thể tìm thấy tệp trên đĩa nên nó đã bị xóa", "MovieIsNotMonitored": "Phim không được giám sát", "SearchOnAddCollectionHelpText": "Tìm kiếm phim trong danh sách này khi được thêm vào {appName}", "DeleteFormatMessageText": "Bạn có chắc chắn muốn xóa thẻ '{0}' không?", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 362a0d29c..1424c60aa 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1205,8 +1205,8 @@ "InfoUrl": "信息 URL", "InvalidUILanguage": "您的UI设置为无效语言,请纠正并保存设置", "LanguagesLoadError": "无法加载语言", - "MovieDownloadFailedTooltip": "电影下载失败", - "MovieDownloadIgnoredTooltip": "电影下载被忽略", + "DownloadFailedMovieTooltip": "电影下载失败", + "DownloadIgnoredMovieTooltip": "电影下载被忽略", "MovieFileDeleted": "电影文件已删除", "MovieFileRenamed": "电影文件已重命名", "MovieFileRenamedTooltip": "电影文件已重命名", @@ -1217,7 +1217,7 @@ "AppUpdatedVersion": "{appName} 已经更新到版本 {version} ,重新加载 {appName} 使更新生效", "ConnectionLostReconnect": "{appName} 将会尝试自动连接,您也可以点击下方的重新加载。", "ConnectionLostToBackend": "{appName}失去了与后端的连接,需要重新加载以恢复功能。", - "DeletedReasonMissingFromDisk": "{appName} 无法在磁盘上找到该文件,因此该文件已与数据库中的电影解除链接", + "DeletedReasonMovieMissingFromDisk": "{appName} 无法在磁盘上找到该文件,因此该文件已与数据库中的电影解除链接", "EditDownloadClientImplementation": "编辑下载客户端- {implementationName}", "EditIndexerImplementation": "编辑索引器- {implementationName}", "GrabId": "抓取ID", @@ -1225,7 +1225,7 @@ "IMDbId": "IMDb Id", "InteractiveImportNoMovie": "每个选中的文件必须选择对应的电影", "MovieFileDeletedTooltip": "电影文件已删除", - "MovieGrabbedHistoryTooltip": "从 {indexer} 抓取电影并发送到 {downloadClient}", + "MovieGrabbedTooltip": "从 {indexer} 抓取电影并发送到 {downloadClient}", "IndexerDownloadClientHealthCheckMessage": "使用无效下载客户端的索引器:{indexerNames}。", "FullColorEvents": "全彩事件", "InteractiveImportNoFilesFound": "在所选文件夹中找不到视频文件",