1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-21 16:54:30 -04:00

Compare commits

..

35 Commits

Author SHA1 Message Date
Weblate
d4072cdfe2 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Jurriaan Den Toonder <jur.den.toonder@gmail.com>
Co-authored-by: RicardoVelaC <ricardovelac@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translation: Servarr/Radarr
2023-12-08 18:00:35 +02:00
Weblate
136a030c07 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Hajiroxx <luypanda@163.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2023-12-08 16:03:26 +02:00
Weblate
6d89ae89a4 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Augusto Poletti <augustpolet@gmail.com>
Co-authored-by: Dominika Matějková <dominika.matejkova@outlook.cz>
Co-authored-by: VisoTC <szlytlyt@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: 米大饭 <1246333567@qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2023-12-06 16:01:05 +02:00
Servarr
98e4273b7a Automated API Docs update 2023-12-06 16:00:42 +02:00
Bogdan
ecf9983ea6 Fix minimum availability label in movie table row 2023-12-06 14:35:55 +02:00
Bogdan
a059a700eb New: Minimum Availability in bulk manage import lists
Fixes #9461
2023-12-06 14:35:20 +02:00
Taloth Saldono
ced624c2ff Small helper in UI to access Radarr API more easily
(cherry picked from commit 090cdc364ef335fbfea8cf540696af813f6ecea4)
2023-12-06 13:16:02 +02:00
Bogdan
7c32061e17 Add existing flag for Discover Movie Posters 2023-12-06 13:12:49 +02:00
Bogdan
bc4847cdc7 New: Improve fields selection for Discord connection 2023-12-06 11:03:57 +02:00
Bogdan
65d79dd078 Fixed: Progress bar for collection movies in queue 2023-12-04 13:17:29 +02:00
Bogdan
238ddbbe1f Fixed: Improve Required Flags selection for indexers 2023-12-04 12:53:33 +02:00
Bogdan
3f444406da Fixed: (PassThePopcorn) Support for half leech releases 2023-12-04 12:34:22 +02:00
Bogdan
d7aaa1cdc2 Fixed: Cleanup orphaned movies 2023-12-03 22:02:56 +02:00
Mark McDowall
263534717d Always validate Custom Script path
(cherry picked from commit c922cc5dc617dd776d4523cbf62376821c5a4ad9)
2023-12-03 20:03:07 +02:00
Weblate
073d15160d Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: David Molero <contact@dolvem.com>
Co-authored-by: Patatra <patrice.chevreau@gmail.com>
Co-authored-by: Zalhera <tobias.bechen@gmail.com>
Co-authored-by: liimee <git.taaa@fedora.email>
Co-authored-by: resi23 <x-resistant-x@gmx.de>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/
Translation: Servarr/Radarr
2023-12-01 04:03:43 +02:00
Stevie Robinson
c5075e5d49 Fixed Custom Format Deletion confirmation message
(cherry picked from commit b76bf373717edff8e475fde31fbaec86c65903fe)

Closes #9410
2023-11-26 08:43:02 +02:00
Weblate
fc345047ee Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Appoxo <appoxo@appoxo.de>
Co-authored-by: Charlie <zola@zipmail.pw>
Co-authored-by: Dimitri <dimitridroeck@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: RicardoVelaC <ricardovelac@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translation: Servarr/Radarr
2023-11-26 08:28:12 +02:00
Weblate
bffab87da7 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translation: Servarr/Radarr
2023-11-26 08:26:37 +02:00
Bogdan
a8a9d3b833 Bump version to 5.2.4 2023-11-26 07:05:58 +02:00
Stevie Robinson
ff1987be84 New: Remove defunct Boxcar notifications
(cherry picked from commit c6ad2396bb98dc8eb1ad47bf5d066b227a47f8b5)

Closes #9451
2023-11-25 22:29:33 +02:00
Bogdan
cb08c0767d Switch assignment to operator 2023-11-22 21:50:29 +02:00
Bogdan
5f1d7ddc11 Improve discover movies sorting by release dates 2023-11-21 22:45:23 +02:00
Bogdan
0ba3c08ea6 Small UI fixes to discover movies 2023-11-21 22:37:36 +02:00
Bogdan
6b9a378eaf Fixed: Minimum refresh interval for import list presets 2023-11-21 19:52:58 +02:00
Bogdan
b4562e6236 Fixed: Movie grabbed history on interactive search 2023-11-21 03:45:19 +02:00
Bogdan
bbffff78ed Fixed: Disable swipe on movie details when a modal is open 2023-11-20 22:16:01 +02:00
Bogdan
740f0f1e5f Cleanup unused logic in Movie Details 2023-11-20 21:37:13 +02:00
Bogdan
45b38b44c1 Fixed: Interactive search modal on mobile 2023-11-20 07:52:48 +02:00
Mark McDowall
318d59bb99 Fixed force saving provider triggering testing
(cherry picked from commit 65cb1ccafd54479fa3fca1f1eaa4b96222b0176b)
2023-11-20 07:37:42 +02:00
Bogdan
ed54d071c4 Fixed: Wrap long lines in media info popup 2023-11-20 07:06:45 +02:00
Bogdan
cff15de4fc Translate custom format score for history actions 2023-11-20 05:48:02 +02:00
Bogdan
88c0e24c58 Fixed: Clear movie search results when navigating to another page
(cherry picked from commit 67dc8987970aa2a9eade48c02ae72be1851fa196)
2023-11-19 21:10:43 -06:00
Qstick
8e0645670b New: Rework Movie Details view 2023-11-19 21:10:43 -06:00
Qstick
40eeb31a21 New: Move Interactive search to toolbar 2023-11-19 21:10:43 -06:00
Qstick
3e534cf8bf Bump version to 5.2.3 2023-11-19 18:31:23 -06:00
118 changed files with 1421 additions and 1151 deletions

View File

@@ -9,7 +9,7 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '5.2.2'
majorVersion: '5.2.4'
minorVersion: $[counter('minorVersion', 2000)]
radarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(radarrVersion)'

View File

@@ -6,6 +6,7 @@ import * as commandNames from 'Commands/commandNames';
import withScrollPosition from 'Components/withScrollPosition';
import { executeCommand } from 'Store/Actions/commandActions';
import { saveMovieCollections, setMovieCollectionsFilter, setMovieCollectionsSort } from 'Store/Actions/movieCollectionActions';
import { clearQueueDetails, fetchQueueDetails } from 'Store/Actions/queueActions';
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
import scrollPositions from 'Store/scrollPositions';
import createCollectionClientSideCollectionItemsSelector from 'Store/Selectors/createCollectionClientSideCollectionItemsSelector';
@@ -38,6 +39,12 @@ function createMapDispatchToProps(dispatch, props) {
dispatchFetchRootFolders() {
dispatch(fetchRootFolders());
},
dispatchFetchQueueDetails() {
dispatch(fetchQueueDetails());
},
dispatchClearQueueDetails() {
dispatch(clearQueueDetails());
},
onUpdateSelectedPress(payload) {
dispatch(saveMovieCollections(payload));
},
@@ -63,10 +70,12 @@ class CollectionConnector extends Component {
componentDidMount() {
registerPagePopulator(this.repopulate);
this.props.dispatchFetchRootFolders();
this.props.dispatchFetchQueueDetails();
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.dispatchClearQueueDetails();
}
//
@@ -99,7 +108,9 @@ CollectionConnector.propTypes = {
isSmallScreen: PropTypes.bool.isRequired,
view: PropTypes.string.isRequired,
onUpdateSelectedPress: PropTypes.func.isRequired,
dispatchFetchRootFolders: PropTypes.func.isRequired
dispatchFetchRootFolders: PropTypes.func.isRequired,
dispatchFetchQueueDetails: PropTypes.func.isRequired,
dispatchClearQueueDetails: PropTypes.func.isRequired
};
export default withScrollPosition(

View File

@@ -70,6 +70,7 @@ class CollectionMovie extends Component {
hasFile,
folder,
isAvailable,
movieFile,
isExistingMovie,
posterWidth,
posterHeight,
@@ -131,6 +132,8 @@ class CollectionMovie extends Component {
id ?
<div className={styles.overlayStatus}>
<MovieIndexProgressBar
movieId={id}
movieFile={movieFile}
monitored={monitored}
hasFile={hasFile}
status={status}
@@ -180,6 +183,7 @@ CollectionMovie.propTypes = {
hasFile: PropTypes.bool,
folder: PropTypes.string,
isAvailable: PropTypes.bool,
movieFile: PropTypes.object,
images: PropTypes.arrayOf(PropTypes.object).isRequired,
posterWidth: PropTypes.number.isRequired,
posterHeight: PropTypes.number.isRequired,

View File

@@ -1,9 +1,7 @@
.description {
line-height: $lineHeight;
}
.description {
margin-left: 0;
line-height: $lineHeight;
overflow-wrap: break-word;
}
@media (min-width: 768px) {

View File

@@ -63,6 +63,12 @@
width: 1280px;
}
.extraExtraLarge {
composes: modal;
width: 1600px;
}
@media only screen and (max-width: $breakpointExtraLarge) {
.modal.extraLarge {
width: 90%;
@@ -90,7 +96,8 @@
.modal.small,
.modal.medium,
.modal.large,
.modal.extraLarge {
.modal.extraLarge,
.modal.extraExtraLarge {
max-height: 100%;
width: 100%;
height: 100% !important;

View File

@@ -1,6 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'extraExtraLarge': string;
'extraLarge': string;
'large': string;
'medium': string;

View File

@@ -0,0 +1,120 @@
import createAjaxRequest from 'Utilities/createAjaxRequest';
// This file contains some helpers for power users in a browser console
let hasWarned = false;
function checkActivationWarning() {
if (!hasWarned) {
console.log('Activated RadarrApi console helpers.');
console.warn('Be warned: There will be no further confirmation checks.');
hasWarned = true;
}
}
function attachAsyncActions(promise) {
promise.filter = function() {
const args = arguments;
const res = this.then((d) => d.filter(...args));
attachAsyncActions(res);
return res;
};
promise.map = function() {
const args = arguments;
const res = this.then((d) => d.map(...args));
attachAsyncActions(res);
return res;
};
promise.all = function() {
const res = this.then((d) => Promise.all(d));
attachAsyncActions(res);
return res;
};
promise.forEach = function(action) {
const res = this.then((d) => Promise.all(d.map(action)));
attachAsyncActions(res);
return res;
};
}
class ResourceApi {
constructor(api, url) {
this.api = api;
this.url = url;
}
single(id) {
return this.api.fetch(`${this.url}/${id}`);
}
all() {
return this.api.fetch(this.url);
}
filter(pred) {
return this.all().filter(pred);
}
update(resource) {
return this.api.fetch(`${this.url}/${resource.id}`, { method: 'PUT', data: resource });
}
delete(resource) {
if (typeof resource === 'object' && resource !== null && resource.id) {
resource = resource.id;
}
if (!resource || !Number.isInteger(resource)) {
throw Error('Invalid resource', resource);
}
return this.api.fetch(`${this.url}/${resource}`, { method: 'DELETE' });
}
fetch(url, options) {
return this.api.fetch(`${this.url}${url}`, options);
}
}
class ConsoleApi {
constructor() {
this.movie = new ResourceApi(this, '/movie');
}
resource(url) {
return new ResourceApi(this, url);
}
fetch(url, options) {
checkActivationWarning();
options = options || {};
const req = {
url,
method: options.method || 'GET'
};
if (options.data) {
req.dataType = 'json';
req.data = JSON.stringify(options.data);
}
const promise = createAjaxRequest(req).request;
promise.fail((xhr) => {
console.error(`Failed to fetch ${url}`, xhr);
});
attachAsyncActions(promise);
return promise;
}
}
window.RadarrApi = new ConsoleApi();
export default ConsoleApi;

View File

@@ -50,7 +50,7 @@ $hoverScale: 1.05;
.title {
@add-mixin truncate;
background-color: #fafbfc;
background-color: var(--movieBackgroundColor);
text-align: center;
font-size: $smallFontSize;
}
@@ -68,6 +68,19 @@ $hoverScale: 1.05;
color: var(--white);
}
.existing {
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: 0;
height: 0;
border-width: 25px 25px 0 0;
border-style: solid;
border-color: #37bc9b transparent transparent;
color: var(--white);
}
.controls {
position: absolute;
bottom: 10px;

View File

@@ -7,6 +7,7 @@ interface CssExports {
'controls': string;
'editorSelect': string;
'excluded': string;
'existing': string;
'externalLinks': string;
'link': string;
'overlayTitle': string;

View File

@@ -92,6 +92,7 @@ class DiscoverMoviePoster extends Component {
showRelativeDates,
shortDateFormat,
timeFormat,
movieRuntimeFormat,
...otherProps
} = this.props;
@@ -110,7 +111,7 @@ class DiscoverMoviePoster extends Component {
return (
<div className={styles.content}>
<div className={styles.posterContainer}>
<div className={styles.posterContainer} title={title}>
{
<div className={styles.editorSelect}>
<CheckInput
@@ -158,6 +159,14 @@ class DiscoverMoviePoster extends Component {
/>
}
{
isExisting &&
<div
className={styles.existing}
title={translate('Existing')}
/>
}
<Link
className={styles.link}
style={elementStyle}
@@ -185,7 +194,7 @@ class DiscoverMoviePoster extends Component {
{
showTitle &&
<div className={styles.title}>
<div className={styles.title} title={title}>
{title}
</div>
}
@@ -194,6 +203,7 @@ class DiscoverMoviePoster extends Component {
showRelativeDates={showRelativeDates}
shortDateFormat={shortDateFormat}
timeFormat={timeFormat}
movieRuntimeFormat={movieRuntimeFormat}
{...otherProps}
/>
@@ -236,6 +246,7 @@ DiscoverMoviePoster.propTypes = {
showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired,
movieRuntimeFormat: PropTypes.string.isRequired,
isExisting: PropTypes.bool.isRequired,
isExcluded: PropTypes.bool.isRequired,
isSelected: PropTypes.bool,

View File

@@ -5,9 +5,11 @@ import DiscoverMoviePoster from './DiscoverMoviePoster';
function createMapStateToProps() {
return createSelector(
(state) => state.settings.ui.item.movieRuntimeFormat,
createDimensionsSelector(),
( dimensions) => {
(movieRuntimeFormat, dimensions) => {
return {
movieRuntimeFormat,
isSmallScreen: dimensions.isSmallScreen
};
}

View File

@@ -1,5 +1,5 @@
.info {
background-color: #fafbfc;
background-color: var(--movieBackgroundColor);
text-align: center;
font-size: $smallFontSize;
}

View File

@@ -1,9 +1,12 @@
import PropTypes from 'prop-types';
import React from 'react';
import Icon from 'Components/Icon';
import TmdbRating from 'Components/TmdbRating';
import { icons } from 'Helpers/Props';
import { getMovieStatusDetails } from 'Movie/MovieStatus';
import formatRuntime from 'Utilities/Date/formatRuntime';
import getRelativeDate from 'Utilities/Date/getRelativeDate';
import translate from 'Utilities/String/translate';
import styles from './DiscoverMoviePosterInfo.css';
function DiscoverMoviePosterInfo(props) {
@@ -19,12 +22,13 @@ function DiscoverMoviePosterInfo(props) {
sortKey,
showRelativeDates,
shortDateFormat,
timeFormat
timeFormat,
movieRuntimeFormat
} = props;
if (sortKey === 'status' && status) {
return (
<div className={styles.info}>
<div className={styles.info} title={translate('Status')}>
{getMovieStatusDetails(status).title}
</div>
);
@@ -32,7 +36,7 @@ function DiscoverMoviePosterInfo(props) {
if (sortKey === 'studio' && studio) {
return (
<div className={styles.info}>
<div className={styles.info} title={translate('Studio')}>
{studio}
</div>
);
@@ -50,8 +54,8 @@ function DiscoverMoviePosterInfo(props) {
);
return (
<div className={styles.info}>
{`In Cinemas ${inCinemasDate}`}
<div className={styles.info} title={translate('InCinemas')}>
<Icon name={icons.IN_CINEMAS} /> {inCinemasDate}
</div>
);
}
@@ -68,8 +72,8 @@ function DiscoverMoviePosterInfo(props) {
);
return (
<div className={styles.info}>
{`Digital ${digitalReleaseDate}`}
<div className={styles.info} title={translate('DigitalRelease')}>
<Icon name={icons.MOVIE_FILE} /> {digitalReleaseDate}
</div>
);
}
@@ -86,15 +90,15 @@ function DiscoverMoviePosterInfo(props) {
);
return (
<div className={styles.info}>
{`Released ${physicalReleaseDate}`}
<div className={styles.info} title={translate('PhysicalRelease')}>
<Icon name={icons.DISC} /> {physicalReleaseDate}
</div>
);
}
if (sortKey === 'certification' && certification) {
return (
<div className={styles.info}>
<div className={styles.info} title={translate('Certification')}>
{certification}
</div>
);
@@ -102,8 +106,8 @@ function DiscoverMoviePosterInfo(props) {
if (sortKey === 'runtime' && runtime) {
return (
<div className={styles.info}>
{formatRuntime(runtime)}
<div className={styles.info} title={translate('Runtime')}>
{formatRuntime(runtime, movieRuntimeFormat)}
</div>
);
}
@@ -111,9 +115,7 @@ function DiscoverMoviePosterInfo(props) {
if (sortKey === 'ratings' && ratings) {
return (
<div className={styles.info}>
<TmdbRating
ratings={ratings}
/>
<TmdbRating ratings={ratings} />
</div>
);
}
@@ -133,7 +135,8 @@ DiscoverMoviePosterInfo.propTypes = {
sortKey: PropTypes.string.isRequired,
showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired
timeFormat: PropTypes.string.isRequired,
movieRuntimeFormat: PropTypes.string.isRequired
};
export default DiscoverMoviePosterInfo;

View File

@@ -76,6 +76,7 @@ class DiscoverMovieRow extends Component {
ratings,
popularity,
certification,
movieRuntimeFormat,
collection,
columns,
isExisting,
@@ -230,7 +231,7 @@ class DiscoverMovieRow extends Component {
key={name}
className={styles[name]}
>
{formatRuntime(runtime)}
{formatRuntime(runtime, movieRuntimeFormat)}
</VirtualTableRowCell>
);
}
@@ -397,6 +398,7 @@ DiscoverMovieRow.propTypes = {
popularity: PropTypes.number.isRequired,
certification: PropTypes.string,
collection: PropTypes.object,
movieRuntimeFormat: PropTypes.string.isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
isExisting: PropTypes.bool.isRequired,
isExcluded: PropTypes.bool.isRequired,

View File

@@ -5,9 +5,11 @@ import DiscoverMovieRow from './DiscoverMovieRow';
function createMapStateToProps() {
return createSelector(
(state) => state.settings.ui.item.movieRuntimeFormat,
createDimensionsSelector(),
(dimensions) => {
(movieRuntimeFormat, dimensions) => {
return {
movieRuntimeFormat,
isSmallScreen: dimensions.isSmallScreen
};
}

View File

@@ -3,5 +3,6 @@ export const SMALL = 'small';
export const MEDIUM = 'medium';
export const LARGE = 'large';
export const EXTRA_LARGE = 'extraLarge';
export const EXTRA_EXTRA_LARGE = 'extraExtraLarge';
export const all = [EXTRA_SMALL, SMALL, MEDIUM, LARGE, EXTRA_LARGE];
export const all = [EXTRA_SMALL, SMALL, MEDIUM, LARGE, EXTRA_LARGE, EXTRA_EXTRA_LARGE];

View File

@@ -3,13 +3,16 @@ import React, { Fragment } from 'react';
import Alert from 'Components/Alert';
import Icon from 'Components/Icon';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import FilterMenu from 'Components/Menu/FilterMenu';
import PageMenuButton from 'Components/Menu/PageMenuButton';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { icons, kinds, sortDirections } from 'Helpers/Props';
import { align, icons, kinds, sortDirections } from 'Helpers/Props';
import getErrorMessage from 'Utilities/Object/getErrorMessage';
import translate from 'Utilities/String/translate';
import InteractiveSearchFilterModalConnector from './InteractiveSearchFilterModalConnector';
import InteractiveSearchRowConnector from './InteractiveSearchRowConnector';
import styles from './InteractiveSearchContent.css';
import styles from './InteractiveSearch.css';
const columns = [
{
@@ -24,23 +27,6 @@ const columns = [
isSortable: true,
isVisible: true
},
{
name: 'releaseWeight',
label: React.createElement(Icon, { name: icons.DOWNLOAD }),
isSortable: true,
fixedSortDirection: sortDirections.ASCENDING,
isVisible: true
},
{
name: 'rejections',
label: React.createElement(Icon, {
name: icons.DANGER,
title: () => translate('Rejections')
}),
isSortable: true,
fixedSortDirection: sortDirections.ASCENDING,
isVisible: true
},
{
name: 'title',
label: () => translate('Title'),
@@ -84,12 +70,6 @@ const columns = [
isSortable: true,
isVisible: true
},
{
name: 'customFormat',
label: () => translate('Formats'),
isSortable: true,
isVisible: true
},
{
name: 'customFormatScore',
label: React.createElement(Icon, {
@@ -107,10 +87,27 @@ const columns = [
}),
isSortable: true,
isVisible: true
},
{
name: 'releaseWeight',
label: React.createElement(Icon, { name: icons.DOWNLOAD }),
isSortable: true,
fixedSortDirection: sortDirections.ASCENDING,
isVisible: true
},
{
name: 'rejections',
label: React.createElement(Icon, {
name: icons.DANGER,
title: () => translate('Rejections')
}),
isSortable: true,
fixedSortDirection: sortDirections.ASCENDING,
isVisible: true
}
];
function InteractiveSearchContent(props) {
function InteractiveSearch(props) {
const {
searchPayload,
isFetching,
@@ -118,18 +115,36 @@ function InteractiveSearchContent(props) {
error,
totalReleasesCount,
items,
selectedFilterKey,
filters,
customFilters,
sortKey,
sortDirection,
longDateFormat,
timeFormat,
onSortPress,
onFilterSelect,
onGrabPress
} = props;
const errorMessage = getErrorMessage(error);
const type = 'movies';
return (
<div>
<div className={styles.filterMenuContainer}>
<FilterMenu
alignMenu={align.RIGHT}
selectedFilterKey={selectedFilterKey}
filters={filters}
customFilters={customFilters}
buttonComponent={PageMenuButton}
filterModalConnectorComponent={InteractiveSearchFilterModalConnector}
filterModalConnectorComponentProps={{ type }}
onFilterSelect={onFilterSelect}
/>
</div>
{
isFetching ? <LoadingIndicator /> : null
}
@@ -203,19 +218,23 @@ function InteractiveSearchContent(props) {
);
}
InteractiveSearchContent.propTypes = {
InteractiveSearch.propTypes = {
searchPayload: PropTypes.object.isRequired,
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
totalReleasesCount: PropTypes.number.isRequired,
items: 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,
sortKey: PropTypes.string,
sortDirection: PropTypes.string,
longDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired,
onSortPress: PropTypes.func.isRequired,
onFilterSelect: PropTypes.func.isRequired,
onGrabPress: PropTypes.func.isRequired
};
export default InteractiveSearchContent;
export default InteractiveSearch;

View File

@@ -2,10 +2,11 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { clearMovieHistory, fetchMovieHistory } from 'Store/Actions/movieHistoryActions';
import * as releaseActions from 'Store/Actions/releaseActions';
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import InteractiveSearchContent from './InteractiveSearchContent';
import InteractiveSearch from './InteractiveSearch';
function createMapStateToProps(appState) {
return createSelector(
@@ -29,8 +30,12 @@ function createMapDispatchToProps(dispatch, props) {
dispatch(releaseActions.fetchReleases(payload));
},
dispatchClearReleases(payload) {
dispatch(releaseActions.clearReleases(payload));
dispatchFetchMovieHistory({ movieId }) {
dispatch(fetchMovieHistory({ movieId }));
},
dispatchClearMovieHistory() {
dispatch(clearMovieHistory());
},
onSortPress(sortKey, sortDirection) {
@@ -38,8 +43,7 @@ function createMapDispatchToProps(dispatch, props) {
},
onFilterSelect(selectedFilterKey) {
const action = releaseActions.setReleasesFilter;
dispatch(action({ selectedFilterKey }));
dispatch(releaseActions.setReleasesFilter({ selectedFilterKey }));
},
onGrabPress(payload) {
@@ -48,7 +52,7 @@ function createMapDispatchToProps(dispatch, props) {
};
}
class InteractiveSearchContentConnector extends Component {
class InteractiveSearchConnector extends Component {
//
// Lifecycle
@@ -57,7 +61,8 @@ class InteractiveSearchContentConnector extends Component {
const {
searchPayload,
isPopulated,
dispatchFetchReleases
dispatchFetchReleases,
dispatchFetchMovieHistory
} = this.props;
// If search results are not yet isPopulated fetch them,
@@ -65,6 +70,12 @@ class InteractiveSearchContentConnector extends Component {
if (!isPopulated) {
dispatchFetchReleases(searchPayload);
}
dispatchFetchMovieHistory(searchPayload);
}
componentWillUnmount() {
this.props.dispatchClearMovieHistory();
}
//
@@ -73,24 +84,26 @@ class InteractiveSearchContentConnector extends Component {
render() {
const {
dispatchFetchReleases,
dispatchClearReleases,
dispatchFetchMovieHistory,
dispatchClearMovieHistory,
...otherProps
} = this.props;
return (
<InteractiveSearchContent
<InteractiveSearch
{...otherProps}
/>
);
}
}
InteractiveSearchContentConnector.propTypes = {
InteractiveSearchConnector.propTypes = {
searchPayload: PropTypes.object.isRequired,
isPopulated: PropTypes.bool.isRequired,
dispatchFetchReleases: PropTypes.func.isRequired,
dispatchClearReleases: PropTypes.func.isRequired
dispatchFetchMovieHistory: PropTypes.func.isRequired,
dispatchClearMovieHistory: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, createMapDispatchToProps)(InteractiveSearchContentConnector);
export default connect(createMapStateToProps, createMapDispatchToProps)(InteractiveSearchConnector);

View File

@@ -4,7 +4,7 @@ import FilterMenu from 'Components/Menu/FilterMenu';
import PageMenuButton from 'Components/Menu/PageMenuButton';
import { align } from 'Helpers/Props';
import InteractiveSearchFilterModalConnector from './InteractiveSearchFilterModalConnector';
import styles from './InteractiveSearchContent.css';
import styles from './InteractiveSearch.css';
function InteractiveSearchFilterMenu(props) {
const {

View File

@@ -1,23 +1,25 @@
.cell {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
}
.protocol {
composes: cell;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 80px;
}
.titleContent {
display: flex;
align-items: center;
justify-content: space-between;
word-break: break-all;
}
.indexer {
composes: cell;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 85px;
}
.quality,
.customFormat,
.languages {
composes: cell;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
}
.languages {
@@ -25,7 +27,7 @@
}
.customFormatScore {
composes: cell;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 55px;
font-weight: bold;
@@ -33,31 +35,28 @@
}
.rejected,
.indexerFlags {
composes: cell;
.indexerFlags,
.download {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 50px;
}
.age,
.size {
composes: cell;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
white-space: nowrap;
}
.peers {
composes: cell;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 75px;
}
.titleContent {
overflow-wrap: break-word;
}
.history {
composes: cell;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 75px;
}
@@ -67,7 +66,7 @@
}
.download {
composes: cell;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 80px;
}

View File

@@ -3,8 +3,6 @@
interface CssExports {
'age': string;
'blocklist': string;
'cell': string;
'customFormat': string;
'customFormatScore': string;
'download': string;
'downloadIcon': string;

View File

@@ -133,9 +133,9 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
longDateFormat,
timeFormat,
grabError,
historyGrabbedData,
historyFailedData,
blocklistData,
historyGrabbedData = {} as MovieHistory,
historyFailedData = {} as MovieHistory,
blocklistData = {} as MovieBlocklist,
searchPayload,
onGrabPress,
} = props;
@@ -199,53 +199,6 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
{formatAge(age, ageHours, ageMinutes)}
</TableRowCell>
<TableRowCell className={styles.download}>
<SpinnerIconButton
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
kind={getDownloadKind(isGrabbed, grabError)}
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
isSpinning={isGrabbing}
onPress={onGrabPressWrapper}
/>
<Link
className={styles.manualDownloadContent}
title={translate('OverrideAndAddToDownloadQueue')}
onPress={onOverridePress}
>
<div className={styles.manualDownloadContent}>
<Icon
className={styles.interactiveIcon}
name={icons.INTERACTIVE}
size={12}
/>
<Icon
className={styles.downloadIcon}
name={icons.CIRCLE_DOWN}
size={10}
/>
</div>
</Link>
</TableRowCell>
<TableRowCell className={styles.rejected}>
{rejections.length ? (
<Popover
anchor={<Icon name={icons.DANGER} kind={kinds.DANGER} />}
title={translate('ReleaseRejected')}
body={
<ul>
{rejections.map((rejection, index) => {
return <li key={index}>{rejection}</li>;
})}
</ul>
}
position={tooltipPositions.RIGHT}
/>
) : null}
</TableRowCell>
<TableRowCell>
<div className={styles.titleContent}>
<Link to={infoUrl} title={title}>
@@ -316,10 +269,6 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
<MovieQuality quality={quality} />
</TableRowCell>
<TableRowCell className={styles.customFormat}>
<MovieFormats formats={customFormats} />
</TableRowCell>
<TableRowCell className={styles.customFormatScore}>
<Tooltip
anchor={formatCustomFormatScore(
@@ -348,6 +297,53 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
) : null}
</TableRowCell>
<TableRowCell className={styles.rejected}>
{rejections.length ? (
<Popover
anchor={<Icon name={icons.DANGER} kind={kinds.DANGER} />}
title={translate('ReleaseRejected')}
body={
<ul>
{rejections.map((rejection, index) => {
return <li key={index}>{rejection}</li>;
})}
</ul>
}
position={tooltipPositions.LEFT}
/>
) : null}
</TableRowCell>
<TableRowCell className={styles.download}>
<SpinnerIconButton
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
kind={getDownloadKind(isGrabbed, grabError)}
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
isSpinning={isGrabbing}
onPress={onGrabPressWrapper}
/>
<Link
className={styles.manualDownloadContent}
title={translate('OverrideAndAddToDownloadQueue')}
onPress={onOverridePress}
>
<div className={styles.manualDownloadContent}>
<Icon
className={styles.interactiveIcon}
name={icons.INTERACTIVE}
size={12}
/>
<Icon
className={styles.downloadIcon}
name={icons.CIRCLE_DOWN}
size={10}
/>
</div>
</Link>
</TableRowCell>
<ConfirmModal
isOpen={isConfirmGrabModalOpen}
kind={kinds.WARNING}

View File

@@ -1,16 +0,0 @@
import React from 'react';
import InteractiveSearchContentConnector from './InteractiveSearchContentConnector';
function InteractiveSearchTable(props) {
return (
<InteractiveSearchContentConnector
searchPayload={props}
/>
);
}
InteractiveSearchTable.propTypes = {
};
export default InteractiveSearchTable;

View File

@@ -1,11 +1,8 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Label from 'Components/Label';
import IconButton from 'Components/Link/IconButton';
import { icons } from 'Helpers/Props';
import MonitorToggleButton from 'Components/MonitorToggleButton';
import MovieHeadshot from 'Movie/MovieHeadshot';
import EditImportListModalConnector from 'Settings/ImportLists/ImportLists/EditImportListModalConnector';
import translate from 'Utilities/String/translate';
import styles from '../MovieCreditPoster.css';
class MovieCastPoster extends Component {
@@ -60,7 +57,7 @@ class MovieCastPoster extends Component {
images,
posterWidth,
posterHeight,
importListId
importList
} = this.props;
const {
@@ -69,36 +66,31 @@ class MovieCastPoster extends Component {
const elementStyle = {
width: `${posterWidth}px`,
height: `${posterHeight}px`
height: `${posterHeight}px`,
borderRadius: '5px'
};
const contentStyle = {
width: `${posterWidth}px`
};
const monitored = importList !== undefined && importList.enabled && importList.enableAuto;
const importListId = importList ? importList.id : 0;
return (
<div
className={styles.content}
style={contentStyle}
>
<div className={styles.posterContainer}>
<Label className={styles.controls}>
{
importListId > 0 ?
<IconButton
className={styles.action}
name={icons.EDIT}
title={translate('EditPerson')}
onPress={this.onEditImportListPress}
/> :
<IconButton
className={styles.action}
name={icons.ADD}
title={translate('FollowPerson')}
onPress={this.onAddImportListPress}
/>
}
</Label>
<div className={styles.controls}>
<MonitorToggleButton
className={styles.action}
monitored={monitored}
size={20}
onPress={importListId > 0 ? this.onEditImportListPress : this.onAddImportListPress}
/>
</div>
<div
style={elementStyle}
@@ -148,12 +140,8 @@ MovieCastPoster.propTypes = {
images: PropTypes.arrayOf(PropTypes.object).isRequired,
posterWidth: PropTypes.number.isRequired,
posterHeight: PropTypes.number.isRequired,
importListId: PropTypes.number.isRequired,
importList: PropTypes.object,
onImportListSelect: PropTypes.func.isRequired
};
MovieCastPoster.defaultProps = {
importListId: 0
};
export default MovieCastPoster;

View File

@@ -1,11 +1,8 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Label from 'Components/Label';
import IconButton from 'Components/Link/IconButton';
import { icons } from 'Helpers/Props';
import MonitorToggleButton from 'Components/MonitorToggleButton';
import MovieHeadshot from 'Movie/MovieHeadshot';
import EditImportListModalConnector from 'Settings/ImportLists/ImportLists/EditImportListModalConnector';
import translate from 'Utilities/String/translate';
import styles from '../MovieCreditPoster.css';
class MovieCrewPoster extends Component {
@@ -60,7 +57,7 @@ class MovieCrewPoster extends Component {
images,
posterWidth,
posterHeight,
importListId
importList
} = this.props;
const {
@@ -69,36 +66,31 @@ class MovieCrewPoster extends Component {
const elementStyle = {
width: `${posterWidth}px`,
height: `${posterHeight}px`
height: `${posterHeight}px`,
borderRadius: '5px'
};
const contentStyle = {
width: `${posterWidth}px`
};
const monitored = importList !== undefined && importList.enabled && importList.enableAuto;
const importListId = importList ? importList.id : 0;
return (
<div
className={styles.content}
style={contentStyle}
>
<div className={styles.posterContainer}>
<Label className={styles.controls}>
{
importListId > 0 ?
<IconButton
className={styles.action}
name={icons.EDIT}
title={translate('EditPerson')}
onPress={this.onEditImportListPress}
/> :
<IconButton
className={styles.action}
name={icons.ADD}
title={translate('FollowPerson')}
onPress={this.onAddImportListPress}
/>
}
</Label>
<div className={styles.controls}>
<MonitorToggleButton
className={styles.action}
monitored={monitored}
size={20}
onPress={importListId > 0 ? this.onEditImportListPress : this.onAddImportListPress}
/>
</div>
<div
style={elementStyle}
@@ -148,12 +140,8 @@ MovieCrewPoster.propTypes = {
images: PropTypes.arrayOf(PropTypes.object).isRequired,
posterWidth: PropTypes.number.isRequired,
posterHeight: PropTypes.number.isRequired,
importListId: PropTypes.number.isRequired,
importList: PropTypes.object,
onImportListSelect: PropTypes.func.isRequired
};
MovieCrewPoster.defaultProps = {
importListId: 0
};
export default MovieCrewPoster;

View File

@@ -18,7 +18,7 @@ function createMapStateToProps() {
}, []);
return {
items: crew
items: _.uniqBy(crew, 'personName')
};
}
);

View File

@@ -1,17 +1,13 @@
$hoverScale: 1.05;
.content {
border-radius: '5px';
transition: all 200ms ease-in;
&:hover {
z-index: 2;
box-shadow: 0 0 12px var(--black);
transition: all 200ms ease-in;
.controls {
opacity: 0.9;
transition: opacity 200ms linear 150ms;
}
}
}
@@ -50,22 +46,18 @@ $hoverScale: 1.05;
.controls {
position: absolute;
bottom: 10px;
left: 10px;
top: 10px;
z-index: 3;
border-radius: 4px;
background-color: #707070;
color: var(--white);
font-size: $smallFontSize;
opacity: 0;
transition: opacity 0;
}
.action {
composes: button from '~Components/Link/IconButton.css';
composes: toggleButton from '~Components/MonitorToggleButton.css';
width: 25px;
color: var(--white);
&:hover {
color: var(--radarrYellow);
color: var(--iconButtonHoverLightColor);
}
}

View File

@@ -1,11 +1,19 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { selectImportListSchema, setImportListFieldValue, setImportListValue } from 'Store/Actions/settingsActions';
import createMovieCreditListSelector from 'Store/Selectors/createMovieCreditListSelector';
function createMapStateToProps() {
return createMovieCreditListSelector();
return createSelector(
createMovieCreditListSelector(),
(importList) => {
return {
importList
};
}
);
}
const mapDispatchToProps = {
@@ -20,7 +28,7 @@ class MovieCreditPosterConnector extends Component {
// Listeners
onImportListSelect = () => {
this.props.selectImportListSchema({ implementation: 'TMDbPersonImport', presetName: undefined });
this.props.selectImportListSchema({ implementation: 'TMDbPersonImport', implementationName: 'TMDb Person', presetName: undefined });
this.props.setImportListFieldValue({ name: 'personId', value: this.props.tmdbId.toString() });
this.props.setImportListValue({ name: 'name', value: `${this.props.personName} - ${this.props.tmdbId}` });
};

View File

@@ -2,6 +2,10 @@
flex: 1 0 auto;
}
.movie {
padding: 10px;
}
.container {
padding: 10px;
}

View File

@@ -3,6 +3,7 @@
interface CssExports {
'container': string;
'grid': string;
'movie': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,12 +1,15 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Grid, WindowScroller } from 'react-virtualized';
import Measure from 'Components/Measure';
import { Navigation } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/react';
import dimensions from 'Styles/Variables/dimensions';
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
import MovieCreditPosterConnector from './MovieCreditPosterConnector';
import styles from './MovieCreditPosters.css';
// Import Swiper styles
import 'swiper/css';
import 'swiper/css/navigation';
// Poster container dimensions
const columnPadding = parseInt(dimensions.movieIndexColumnPadding);
const columnPaddingSmallScreen = parseInt(dimensions.movieIndexColumnPaddingSmallScreen);
@@ -65,39 +68,11 @@ class MovieCreditPosters extends Component {
};
this._isInitialized = false;
this._grid = null;
}
componentDidUpdate(prevProps, prevState) {
const {
items
} = this.props;
const {
width,
columnWidth,
columnCount,
rowHeight
} = this.state;
if (this._grid &&
(prevState.width !== width ||
prevState.columnWidth !== columnWidth ||
prevState.columnCount !== columnCount ||
prevState.rowHeight !== rowHeight ||
hasDifferentItemsOrOrder(prevProps.items, items))) {
// recomputeGridSize also forces Grid to discard its cache of rendered cells
this._grid.recomputeGridSize();
}
}
//
// Control
setGridRef = (ref) => {
this._grid = ref;
};
calculateGrid = (width = this.state.width, isSmallScreen) => {
const padding = isSmallScreen ? columnPaddingSmallScreen : columnPadding;
@@ -117,7 +92,10 @@ class MovieCreditPosters extends Component {
});
};
cellRenderer = ({ key, rowIndex, columnIndex, style }) => {
//
// Render
render() {
const {
items,
itemComponent
@@ -126,99 +104,44 @@ class MovieCreditPosters extends Component {
const {
posterWidth,
posterHeight,
columnCount
} = this.state;
const movieIdx = rowIndex * columnCount + columnIndex;
const movie = items[movieIdx];
if (!movie) {
return null;
}
return (
<div
className={styles.container}
key={key}
style={style}
>
<MovieCreditPosterConnector
key={movie.order}
component={itemComponent}
posterWidth={posterWidth}
posterHeight={posterHeight}
tmdbId={movie.personTmdbId}
personName={movie.personName}
job={movie.job}
character={movie.character}
images={movie.images}
/>
</div>
);
};
//
// Listeners
onMeasure = ({ width }) => {
this.calculateGrid(width, this.props.isSmallScreen);
};
//
// Render
render() {
const {
items
} = this.props;
const {
width,
columnWidth,
columnCount,
rowHeight
} = this.state;
const rowCount = Math.ceil(items.length / columnCount);
return (
<Measure
whitelist={['width']}
onMeasure={this.onMeasure}
>
<WindowScroller
scrollElement={undefined}
>
{({ height, registerChild, onChildScroll, scrollTop }) => {
if (!height) {
return <div />;
}
return (
<div ref={registerChild}>
<Grid
ref={this.setGridRef}
className={styles.grid}
autoHeight={true}
height={height}
columnCount={columnCount}
columnWidth={columnWidth}
rowCount={rowCount}
rowHeight={rowHeight}
width={width}
onScroll={onChildScroll}
scrollTop={scrollTop}
overscanRowCount={2}
cellRenderer={this.cellRenderer}
scrollToAlignment={'start'}
isScrollingOptOut={true}
/>
</div>
);
}
}
</WindowScroller>
</Measure>
<div className={styles.sliderContainer}>
<Swiper
slidesPerView='auto'
spaceBetween={10}
slidesPerGroup={3}
loop={false}
loopFillGroupWithBlank={true}
className="mySwiper"
modules={[Navigation]}
onInit={(swiper) => {
swiper.params.navigation.prevEl = this._swiperPrevRef;
swiper.params.navigation.nextEl = this._swiperNextRef;
swiper.navigation.init();
swiper.navigation.update();
}}
>
{items.map((credit) => (
<SwiperSlide key={credit.id} style={{ width: posterWidth, height: rowHeight }}>
<MovieCreditPosterConnector
key={credit.id}
component={itemComponent}
posterWidth={posterWidth}
posterHeight={posterHeight}
tmdbId={credit.personTmdbId}
personName={credit.personName}
job={credit.job}
character={credit.character}
images={credit.images}
/>
</SwiperSlide>
))}
</Swiper>
</div>
);
}
}

View File

@@ -1,3 +0,0 @@
.alternateTitle {
white-space: nowrap;
}

View File

@@ -1,28 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import styles from './MovieAlternateTitles.css';
function MovieAlternateTitles({ alternateTitles }) {
return (
<ul>
{
alternateTitles.filter((x, i, a) => a.indexOf(x) === i).map((alternateTitle) => {
return (
<li
key={alternateTitle}
className={styles.alternateTitle}
>
{alternateTitle}
</li>
);
})
}
</ul>
);
}
MovieAlternateTitles.propTypes = {
alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired
};
export default MovieAlternateTitles;

View File

@@ -5,7 +5,7 @@
.header {
position: relative;
width: 100%;
height: 375px;
height: 425px;
}
.errorMessage {
@@ -39,10 +39,11 @@
}
.poster {
z-index: 2;
flex-shrink: 0;
margin-right: 35px;
width: 217px;
height: 319px;
width: 250px;
height: 368px;
}
.info {

View File

@@ -1,9 +1,9 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
import TextTruncate from 'react-text-truncate';
import Alert from 'Components/Alert';
import FieldSet from 'Components/FieldSet';
import Icon from 'Components/Icon';
import ImdbRating from 'Components/ImdbRating';
import InfoLabel from 'Components/InfoLabel';
@@ -23,12 +23,11 @@ import Popover from 'Components/Tooltip/Popover';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props';
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector';
import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable';
import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal';
import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector';
import MovieHistoryTable from 'Movie/History/MovieHistoryTable';
import MovieHistoryModal from 'Movie/History/MovieHistoryModal';
import MoviePoster from 'Movie/MoviePoster';
import MovieInteractiveSearchModalConnector from 'Movie/Search/MovieInteractiveSearchModalConnector';
import MovieFileEditorTable from 'MovieFile/Editor/MovieFileEditorTable';
import ExtraFileTable from 'MovieFile/Extras/ExtraFileTable';
import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector';
@@ -38,8 +37,6 @@ import * as keyCodes from 'Utilities/Constants/keyCodes';
import formatRuntime from 'Utilities/Date/formatRuntime';
import formatBytes from 'Utilities/Number/formatBytes';
import translate from 'Utilities/String/translate';
import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected';
import MovieCollectionLabelConnector from './../MovieCollectionLabelConnector';
import MovieCastPostersConnector from './Credits/Cast/MovieCastPostersConnector';
import MovieCrewPostersConnector from './Credits/Crew/MovieCrewPostersConnector';
@@ -57,14 +54,6 @@ function getFanartUrl(images) {
return _.find(images, { coverType: 'fanart' })?.url;
}
function getExpandedState(newState) {
return {
allExpanded: newState.allSelected,
allCollapsed: newState.allUnselected,
expandedState: newState.selectedState
};
}
class MovieDetails extends Component {
//
@@ -78,10 +67,8 @@ class MovieDetails extends Component {
isEditMovieModalOpen: false,
isDeleteMovieModalOpen: false,
isInteractiveImportModalOpen: false,
allExpanded: false,
allCollapsed: false,
expandedState: {},
selectedTabIndex: 0,
isInteractiveSearchModalOpen: false,
isMovieHistoryModalOpen: false,
overviewHeight: 0,
titleWidth: 0
};
@@ -114,10 +101,6 @@ class MovieDetails extends Component {
this.setState({ isOrganizeModalOpen: false });
};
onManageEpisodesPress = () => {
this.setState({ isManageEpisodesOpen: true });
};
onInteractiveImportPress = () => {
this.setState({ isInteractiveImportModalOpen: true });
};
@@ -134,6 +117,14 @@ class MovieDetails extends Component {
this.setState({ isEditMovieModalOpen: false });
};
onInteractiveSearchPress = () => {
this.setState({ isInteractiveSearchModalOpen: true });
};
onInteractiveSearchModalClose = () => {
this.setState({ isInteractiveSearchModalOpen: false });
};
onDeleteMoviePress = () => {
this.setState({
isEditMovieModalOpen: false,
@@ -145,27 +136,12 @@ class MovieDetails extends Component {
this.setState({ isDeleteMovieModalOpen: false });
};
onExpandAllPress = () => {
const {
allExpanded,
expandedState
} = this.state;
this.setState(getExpandedState(selectAll(expandedState, !allExpanded)));
onMovieHistoryPress = () => {
this.setState({ isMovieHistoryModalOpen: true });
};
onExpandPress = (seasonNumber, isExpanded) => {
this.setState((state) => {
const convertedState = {
allSelected: state.allExpanded,
allUnselected: state.allCollapsed,
selectedState: state.expandedState
};
const newState = toggleSelected(convertedState, [], seasonNumber, isExpanded, false);
return getExpandedState(newState);
});
onMovieHistoryModalClose = () => {
this.setState({ isMovieHistoryModalOpen: false });
};
onMeasure = ({ height }) => {
@@ -204,7 +180,12 @@ class MovieDetails extends Component {
if (
touchStart < 50 ||
this.props.isSidebarVisible ||
this.state.isEventModalOpen
this.state.isOrganizeModalOpen ||
this.state.isEditMovieModalOpen ||
this.state.isDeleteMovieModalOpen ||
this.state.isInteractiveImportModalOpen ||
this.state.isInteractiveSearchModalOpen ||
this.state.isMovieHistoryModalOpen
) {
return;
}
@@ -239,10 +220,6 @@ class MovieDetails extends Component {
}
};
onTabSelect = (index, lastIndex) => {
this.setState({ selectedTabIndex: index });
};
//
// Render
@@ -295,9 +272,10 @@ class MovieDetails extends Component {
isEditMovieModalOpen,
isDeleteMovieModalOpen,
isInteractiveImportModalOpen,
isInteractiveSearchModalOpen,
isMovieHistoryModalOpen,
overviewHeight,
titleWidth,
selectedTabIndex
titleWidth
} = this.state;
const fanartUrl = getFanartUrl(images);
@@ -324,6 +302,14 @@ class MovieDetails extends Component {
onPress={onSearchPress}
/>
<PageToolbarButton
label={translate('InteractiveSearch')}
iconName={icons.INTERACTIVE}
isSpinning={isSearching}
title={undefined}
onPress={this.onInteractiveSearchPress}
/>
<PageToolbarSeparator />
<PageToolbarButton
@@ -339,6 +325,12 @@ class MovieDetails extends Component {
onPress={this.onInteractiveImportPress}
/>
<PageToolbarButton
label={translate('History')}
iconName={icons.HISTORY}
onPress={this.onMovieHistoryPress}
/>
<PageToolbarSeparator />
<PageToolbarButton
@@ -654,101 +646,33 @@ class MovieDetails extends Component {
null
}
<Tabs selectedIndex={selectedTabIndex} onSelect={this.onTabSelect}>
<TabList
className={styles.tabList}
>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('History')}
</Tab>
<FieldSet legend={translate('Files')}>
<MovieFileEditorTable
movieId={id}
/>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Search')}
</Tab>
<ExtraFileTable
movieId={id}
/>
</FieldSet>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Files')}
</Tab>
<FieldSet legend={translate('Cast')}>
<MovieCastPostersConnector
isSmallScreen={isSmallScreen}
/>
</FieldSet>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Titles')}
</Tab>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Cast')}
</Tab>
<Tab
className={styles.tab}
selectedClassName={styles.selectedTab}
>
{translate('Crew')}
</Tab>
{
selectedTabIndex === 1 &&
<div className={styles.filterIcon}>
<InteractiveSearchFilterMenuConnector />
</div>
}
</TabList>
<TabPanel>
<MovieHistoryTable
movieId={id}
/>
</TabPanel>
<TabPanel>
<InteractiveSearchTable
movieId={id}
/>
</TabPanel>
<TabPanel>
<MovieFileEditorTable
movieId={id}
/>
<ExtraFileTable
movieId={id}
/>
</TabPanel>
<TabPanel>
<MovieTitlesTable
movieId={id}
/>
</TabPanel>
<TabPanel>
<MovieCastPostersConnector
isSmallScreen={isSmallScreen}
/>
</TabPanel>
<TabPanel>
<MovieCrewPostersConnector
isSmallScreen={isSmallScreen}
/>
</TabPanel>
</Tabs>
<FieldSet legend={translate('Crew')}>
<MovieCrewPostersConnector
isSmallScreen={isSmallScreen}
/>
</FieldSet>
<FieldSet legend={translate('Titles')}>
<MovieTitlesTable
movieId={id}
/>
</FieldSet>
</div>
<OrganizePreviewModalConnector
@@ -764,6 +688,12 @@ class MovieDetails extends Component {
onDeleteMoviePress={this.onDeleteMoviePress}
/>
<MovieHistoryModal
isOpen={isMovieHistoryModalOpen}
movieId={id}
onModalClose={this.onMovieHistoryModalClose}
/>
<DeleteMovieModal
isOpen={isDeleteMovieModalOpen}
movieId={id}
@@ -780,6 +710,12 @@ class MovieDetails extends Component {
showImportMode={false}
onModalClose={this.onInteractiveImportModalClose}
/>
<MovieInteractiveSearchModalConnector
isOpen={isInteractiveSearchModalOpen}
movieId={id}
onModalClose={this.onInteractiveSearchModalClose}
/>
</PageContentBody>
</PageContent>
);

View File

@@ -11,7 +11,6 @@ import { toggleMovieMonitored } from 'Store/Actions/movieActions';
import { clearMovieBlocklist, fetchMovieBlocklist } from 'Store/Actions/movieBlocklistActions';
import { clearMovieCredits, fetchMovieCredits } from 'Store/Actions/movieCreditsActions';
import { clearMovieFiles, fetchMovieFiles } from 'Store/Actions/movieFileActions';
import { clearMovieHistory, fetchMovieHistory } from 'Store/Actions/movieHistoryActions';
import { clearQueueDetails, fetchQueueDetails } from 'Store/Actions/queueActions';
import { cancelFetchReleases, clearReleases } from 'Store/Actions/releaseActions';
import { fetchImportListSchema } from 'Store/Actions/settingsActions';
@@ -182,12 +181,6 @@ function createMapDispatchToProps(dispatch, props) {
dispatchClearMovieFiles() {
dispatch(clearMovieFiles());
},
dispatchFetchMovieHistory({ movieId }) {
dispatch(fetchMovieHistory({ movieId }));
},
dispatchClearMovieHistory() {
dispatch(clearMovieHistory());
},
dispatchFetchMovieCredits({ movieId }) {
dispatch(fetchMovieCredits({ movieId }));
},
@@ -283,7 +276,6 @@ class MovieDetailsConnector extends Component {
this.props.dispatchFetchMovieFiles({ movieId });
this.props.dispatchFetchMovieBlocklist({ movieId });
this.props.dispatchFetchMovieHistory({ movieId });
this.props.dispatchFetchExtraFiles({ movieId });
this.props.dispatchFetchMovieCredits({ movieId });
this.props.dispatchFetchQueueDetails({ movieId });
@@ -294,7 +286,6 @@ class MovieDetailsConnector extends Component {
this.props.dispatchCancelFetchReleases();
this.props.dispatchClearMovieBlocklist();
this.props.dispatchClearMovieFiles();
this.props.dispatchClearMovieHistory();
this.props.dispatchClearExtraFiles();
this.props.dispatchClearMovieCredits();
this.props.dispatchClearQueueDetails();
@@ -351,8 +342,6 @@ MovieDetailsConnector.propTypes = {
isSmallScreen: PropTypes.bool.isRequired,
dispatchFetchMovieFiles: PropTypes.func.isRequired,
dispatchClearMovieFiles: PropTypes.func.isRequired,
dispatchFetchMovieHistory: PropTypes.func.isRequired,
dispatchClearMovieHistory: PropTypes.func.isRequired,
dispatchFetchExtraFiles: PropTypes.func.isRequired,
dispatchClearExtraFiles: PropTypes.func.isRequired,
dispatchFetchMovieCredits: PropTypes.func.isRequired,

View File

@@ -1,5 +1,4 @@
.container {
margin-top: 20px;
border: 1px solid var(--borderColor);
border-radius: 4px;
background-color: var(--inputBackgroundColor);

View File

@@ -1,5 +1,6 @@
import React from 'react';
import MovieTitlesTableContentConnector from './MovieTitlesTableContentConnector';
import styles from './MovieTitlesTable.css';
function MovieTitlesTable(props) {
const {
@@ -7,9 +8,11 @@ function MovieTitlesTable(props) {
} = props;
return (
<MovieTitlesTableContentConnector
{...otherProps}
/>
<div className={styles.container}>
<MovieTitlesTableContentConnector
{...otherProps}
/>
</div>
);
}

View File

@@ -0,0 +1,33 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import MovieHistoryModalContentConnector from './MovieHistoryModalContentConnector';
function MovieHistoryModal(props) {
const {
isOpen,
onModalClose,
...otherProps
} = props;
return (
<Modal
isOpen={isOpen}
onModalClose={onModalClose}
size={sizes.EXTRA_LARGE}
>
<MovieHistoryModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
</Modal>
);
}
MovieHistoryModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default MovieHistoryModal;

View File

@@ -0,0 +1,142 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Alert from 'Components/Alert';
import Icon from 'Components/Icon';
import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
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 Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { icons, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import MovieHistoryRowConnector from './MovieHistoryRowConnector';
const columns = [
{
name: 'eventType',
isVisible: true
},
{
name: 'sourceTitle',
label: () => translate('SourceTitle'),
isVisible: true
},
{
name: 'languages',
label: () => translate('Languages'),
isVisible: true
},
{
name: 'quality',
label: () => translate('Quality'),
isVisible: true
},
{
name: 'customFormats',
label: () => translate('CustomFormats'),
isSortable: false,
isVisible: true
},
{
name: 'customFormatScore',
label: React.createElement(Icon, {
name: icons.SCORE,
title: () => translate('CustomFormatScore')
}),
isSortable: true,
isVisible: true
},
{
name: 'date',
label: () => translate('Date'),
isVisible: true
},
{
name: 'actions',
label: () => translate('Actions'),
isVisible: true
}
];
class MovieHistoryModalContent extends Component {
//
// Render
render() {
const {
isFetching,
isPopulated,
error,
items,
onMarkAsFailedPress,
onModalClose
} = this.props;
const hasItems = !!items.length;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{translate('History')}
</ModalHeader>
<ModalBody>
{
isFetching &&
<LoadingIndicator />
}
{
!isFetching && !!error &&
<Alert kind={kinds.DANGER}>{translate('HistoryLoadError')}</Alert>
}
{
isPopulated && !hasItems && !error &&
<div>{translate('NoHistory')}</div>
}
{
isPopulated && hasItems && !error &&
<Table columns={columns}>
<TableBody>
{
items.map((item) => {
return (
<MovieHistoryRowConnector
key={item.id}
{...item}
onMarkAsFailedPress={onMarkAsFailedPress}
/>
);
})
}
</TableBody>
</Table>
}
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
{translate('Close')}
</Button>
</ModalFooter>
</ModalContent>
);
}
}
MovieHistoryModalContent.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
onMarkAsFailedPress: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default MovieHistoryModalContent;

View File

@@ -2,8 +2,8 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { movieHistoryMarkAsFailed } from 'Store/Actions/movieHistoryActions';
import MovieHistoryTableContent from './MovieHistoryTableContent';
import { clearMovieHistory, fetchMovieHistory, movieHistoryMarkAsFailed } from 'Store/Actions/movieHistoryActions';
import MovieHistoryModalContent from './MovieHistoryModalContent';
function createMapStateToProps() {
return createSelector(
@@ -15,10 +15,29 @@ function createMapStateToProps() {
}
const mapDispatchToProps = {
fetchMovieHistory,
clearMovieHistory,
movieHistoryMarkAsFailed
};
class MovieHistoryTableContentConnector extends Component {
class MovieHistoryModalContentConnector extends Component {
//
// Lifecycle
componentDidMount() {
const {
movieId
} = this.props;
this.props.fetchMovieHistory({
movieId
});
}
componentWillUnmount() {
this.props.clearMovieHistory();
}
//
// Listeners
@@ -39,7 +58,7 @@ class MovieHistoryTableContentConnector extends Component {
render() {
return (
<MovieHistoryTableContent
<MovieHistoryModalContent
{...this.props}
onMarkAsFailedPress={this.onMarkAsFailedPress}
/>
@@ -47,9 +66,11 @@ class MovieHistoryTableContentConnector extends Component {
}
}
MovieHistoryTableContentConnector.propTypes = {
MovieHistoryModalContentConnector.propTypes = {
movieId: PropTypes.number.isRequired,
fetchMovieHistory: PropTypes.func.isRequired,
clearMovieHistory: PropTypes.func.isRequired,
movieHistoryMarkAsFailed: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(MovieHistoryTableContentConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(MovieHistoryModalContentConnector);

View File

@@ -1,22 +0,0 @@
import React from 'react';
import MovieHistoryTableContentConnector from './MovieHistoryTableContentConnector';
import styles from './MovieHistoryTable.css';
function MovieHistoryTable(props) {
const {
...otherProps
} = props;
return (
<div className={styles.container}>
<MovieHistoryTableContentConnector
{...otherProps}
/>
</div>
);
}
MovieHistoryTable.propTypes = {
};
export default MovieHistoryTable;

View File

@@ -1,128 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Icon from 'Components/Icon';
import IconButton from 'Components/Link/IconButton';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import MovieHistoryRowConnector from './MovieHistoryRowConnector';
import styles from './MovieHistoryTableContent.css';
const columns = [
{
name: 'eventType',
isVisible: true
},
{
name: 'sourceTitle',
label: () => translate('SourceTitle'),
isVisible: true
},
{
name: 'languages',
label: () => translate('Languages'),
isVisible: true
},
{
name: 'quality',
label: () => translate('Quality'),
isVisible: true
},
{
name: 'customFormats',
label: () => translate('CustomFormats'),
isSortable: false,
isVisible: true
},
{
name: 'customFormatScore',
label: React.createElement(Icon, {
name: icons.SCORE,
title: 'Custom format score'
}),
isSortable: true,
isVisible: true
},
{
name: 'date',
label: () => translate('Date'),
isVisible: true
},
{
name: 'actions',
label: React.createElement(IconButton, { name: icons.ADVANCED_SETTINGS }),
isVisible: true
}
];
class MovieHistoryTableContent extends Component {
//
// Render
render() {
const {
isFetching,
isPopulated,
error,
items,
onMarkAsFailedPress
} = this.props;
const hasItems = !!items.length;
return (
<div>
{
isFetching &&
<LoadingIndicator />
}
{
!isFetching && !!error &&
<div className={styles.blankpad}>
{translate('UnableToLoadHistory')}
</div>
}
{
isPopulated && !hasItems && !error &&
<div className={styles.blankpad}>
{translate('NoHistory')}
</div>
}
{
isPopulated && hasItems && !error &&
<Table columns={columns}>
<TableBody>
{
items.map((item) => {
return (
<MovieHistoryRowConnector
key={item.id}
{...item}
onMarkAsFailedPress={onMarkAsFailedPress}
/>
);
})
}
</TableBody>
</Table>
}
</div>
);
}
}
MovieHistoryTableContent.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
onMarkAsFailedPress: PropTypes.func.isRequired
};
export default MovieHistoryTableContent;

View File

@@ -26,7 +26,7 @@ import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import { SelectStateInputProps } from 'typings/props';
import formatRuntime from 'Utilities/Date/formatRuntime';
import formatBytes from 'Utilities/Number/formatBytes';
import titleCase from 'Utilities/String/titleCase';
import firstCharToUpper from 'Utilities/String/firstCharToUpper';
import translate from 'Utilities/String/translate';
import MovieIndexProgressBar from '../ProgressBar/MovieIndexProgressBar';
import MovieStatusCell from './MovieStatusCell';
@@ -286,7 +286,7 @@ function MovieIndexRow(props: MovieIndexRowProps) {
if (name === 'minimumAvailability') {
return (
<VirtualTableRowCell key={name} className={styles[name]}>
{titleCase(minimumAvailability)}
{translate(firstCharToUpper(minimumAvailability))}
</VirtualTableRowCell>
);
}

View File

@@ -0,0 +1,35 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import MovieInteractiveSearchModalContent from './MovieInteractiveSearchModalContent';
function MovieInteractiveSearchModal(props) {
const {
isOpen,
movieId,
onModalClose
} = props;
return (
<Modal
isOpen={isOpen}
closeOnBackgroundClick={false}
onModalClose={onModalClose}
size={sizes.EXTRA_EXTRA_LARGE}
>
<MovieInteractiveSearchModalContent
movieId={movieId}
onModalClose={onModalClose}
/>
</Modal>
);
}
MovieInteractiveSearchModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
movieId: PropTypes.number.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default MovieInteractiveSearchModal;

View File

@@ -0,0 +1,59 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { cancelFetchReleases, clearReleases } from 'Store/Actions/releaseActions';
import MovieInteractiveSearchModal from './MovieInteractiveSearchModal';
function createMapDispatchToProps(dispatch, props) {
return {
dispatchCancelFetchReleases() {
dispatch(cancelFetchReleases());
},
dispatchClearReleases() {
dispatch(clearReleases());
},
onModalClose() {
dispatch(cancelFetchReleases());
dispatch(clearReleases());
props.onModalClose();
}
};
}
class MovieInteractiveSearchModalConnector extends Component {
//
// Lifecycle
componentWillUnmount() {
this.props.dispatchCancelFetchReleases();
this.props.dispatchClearReleases();
}
//
// Render
render() {
const {
dispatchCancelFetchReleases,
dispatchClearReleases,
...otherProps
} = this.props;
return (
<MovieInteractiveSearchModal
{...otherProps}
/>
);
}
}
MovieInteractiveSearchModalConnector.propTypes = {
...MovieInteractiveSearchModal.propTypes,
dispatchCancelFetchReleases: PropTypes.func.isRequired,
dispatchClearReleases: PropTypes.func.isRequired
};
export default connect(null, createMapDispatchToProps)(MovieInteractiveSearchModalConnector);

View File

@@ -0,0 +1,44 @@
import PropTypes from 'prop-types';
import React from 'react';
import Button from 'Components/Link/Button';
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 { scrollDirections } from 'Helpers/Props';
import InteractiveSearchConnector from 'InteractiveSearch/InteractiveSearchConnector';
import translate from 'Utilities/String/translate';
function MovieInteractiveSearchModalContent(props) {
const {
movieId,
onModalClose
} = props;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{translate('InteractiveSearchModalHeader')}
</ModalHeader>
<ModalBody scrollDirection={scrollDirections.BOTH}>
<InteractiveSearchConnector
searchPayload={{ movieId }}
/>
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
{translate('Close')}
</Button>
</ModalFooter>
</ModalContent>
);
}
MovieInteractiveSearchModalContent.propTypes = {
movieId: PropTypes.number.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default MovieInteractiveSearchModalContent;

View File

@@ -1,5 +1,4 @@
.container {
margin-top: 20px;
border: 1px solid var(--borderColor);
border-radius: 4px;
background-color: var(--inputBackgroundColor);

View File

@@ -152,7 +152,7 @@ class CustomFormat extends Component {
isOpen={this.state.isDeleteCustomFormatModalOpen}
kind={kinds.DANGER}
title={translate('DeleteCustomFormat')}
message={translate('DeleteCustomFormatMessageText', { name })}
message={translate('DeleteCustomFormatMessageText', { customFormatName: name })}
confirmLabel={translate('Delete')}
isSpinning={isDeleting}
onConfirm={this.onConfirmDeleteCustomFormat}

View File

@@ -15,6 +15,7 @@ interface SavePayload {
enabled?: boolean;
enableAuto?: boolean;
qualityProfileId?: number;
minimumAvailability?: string;
rootFolderPath?: string;
}
@@ -58,6 +59,7 @@ function ManageImportListsEditModalContent(
const [qualityProfileId, setQualityProfileId] = useState<string | number>(
NO_CHANGE
);
const [minimumAvailability, setMinimumAvailability] = useState(NO_CHANGE);
const [rootFolderPath, setRootFolderPath] = useState(NO_CHANGE);
const save = useCallback(() => {
@@ -79,6 +81,11 @@ function ManageImportListsEditModalContent(
payload.qualityProfileId = qualityProfileId as number;
}
if (minimumAvailability !== NO_CHANGE) {
hasChanges = true;
payload.minimumAvailability = minimumAvailability as string;
}
if (rootFolderPath !== NO_CHANGE) {
hasChanges = true;
payload.rootFolderPath = rootFolderPath;
@@ -93,6 +100,7 @@ function ManageImportListsEditModalContent(
enabled,
enableAuto,
qualityProfileId,
minimumAvailability,
rootFolderPath,
onSavePress,
onModalClose,
@@ -110,6 +118,9 @@ function ManageImportListsEditModalContent(
case 'qualityProfileId':
setQualityProfileId(value);
break;
case 'minimumAvailability':
setMinimumAvailability(value);
break;
case 'rootFolderPath':
setRootFolderPath(value);
break;
@@ -164,6 +175,19 @@ function ManageImportListsEditModalContent(
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('MinimumAvailability')}</FormLabel>
<FormInputGroup
type={inputTypes.AVAILABILITY_SELECT}
name="minimumAvailability"
value={minimumAvailability}
includeNoChange={true}
includeNoChangeDisabled={false}
onChange={onInputChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('RootFolder')}</FormLabel>

View File

@@ -1,5 +1,6 @@
import React from 'react';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import ManageImportListsModalContent from './ManageImportListsModalContent';
interface ManageImportListsModalProps {
@@ -11,7 +12,7 @@ function ManageImportListsModal(props: ManageImportListsModalProps) {
const { isOpen, onModalClose } = props;
return (
<Modal isOpen={isOpen} onModalClose={onModalClose}>
<Modal isOpen={isOpen} size={sizes.EXTRA_LARGE} onModalClose={onModalClose}>
<ManageImportListsModalContent onModalClose={onModalClose} />
</Modal>
);

View File

@@ -52,6 +52,12 @@ const COLUMNS = [
isSortable: true,
isVisible: true,
},
{
name: 'minimumAvailability',
label: () => translate('MinimumAvailability'),
isSortable: true,
isVisible: true,
},
{
name: 'rootFolderPath',
label: () => translate('RootFolder'),

View File

@@ -2,6 +2,7 @@
.tags,
.enabled,
.enableAuto,
.minimumAvailability,
.qualityProfileId,
.rootFolderPath,
.implementation {

View File

@@ -4,6 +4,7 @@ interface CssExports {
'enableAuto': string;
'enabled': string;
'implementation': string;
'minimumAvailability': string;
'name': string;
'qualityProfileId': string;
'rootFolderPath': string;

View File

@@ -7,6 +7,7 @@ import TableRow from 'Components/Table/TableRow';
import TagListConnector from 'Components/TagListConnector';
import { createQualityProfileSelectorForHook } from 'Store/Selectors/createQualityProfileSelector';
import { SelectStateInputProps } from 'typings/props';
import firstCharToUpper from 'Utilities/String/firstCharToUpper';
import translate from 'Utilities/String/translate';
import styles from './ManageImportListsModalRow.css';
@@ -15,6 +16,7 @@ interface ManageImportListsModalRowProps {
name: string;
rootFolderPath: string;
qualityProfileId: number;
minimumAvailability: string;
implementation: string;
tags: number[];
enabled: boolean;
@@ -30,6 +32,7 @@ function ManageImportListsModalRow(props: ManageImportListsModalRowProps) {
isSelected,
name,
rootFolderPath,
minimumAvailability,
qualityProfileId,
implementation,
enabled,
@@ -69,6 +72,10 @@ function ManageImportListsModalRow(props: ManageImportListsModalRowProps) {
{qualityProfile?.name ?? translate('None')}
</TableRowCell>
<TableRowCell className={styles.minimumAvailability}>
{translate(firstCharToUpper(minimumAvailability))}
</TableRowCell>
<TableRowCell className={styles.rootFolderPath}>
{rootFolderPath}
</TableRowCell>

View File

@@ -122,7 +122,7 @@ export default {
return selectProviderSchema(state, section, payload, (selectedSchema) => {
selectedSchema.name = payload.presetName ?? payload.implementationName;
selectedSchema.implementationName = payload.implementationName;
selectedSchema.minRefreshInterval = payload.minRefreshInterval;
selectedSchema.minRefreshInterval = selectedSchema.minRefreshInterval ?? payload.minRefreshInterval;
selectedSchema.minimumAvailability = 'released';
selectedSchema.rootFolderPath = '';

View File

@@ -1,4 +1,5 @@
import _ from 'lodash';
import moment from 'moment/moment';
import { createAction } from 'redux-actions';
import { batchActions } from 'redux-batched-actions';
import { filterBuilderTypes, filterBuilderValueTypes, filterTypes, sortDirections } from 'Helpers/Props';
@@ -219,6 +220,42 @@ export const defaultState = {
const { ratings = {} } = item;
return ratings.tmdb? ratings.tmdb.value : 0;
},
inCinemas: function(item, direction) {
if (item.inCinemas) {
return moment(item.inCinemas).unix();
}
if (direction === sortDirections.DESCENDING) {
return -1 * Number.MAX_VALUE;
}
return Number.MAX_VALUE;
},
physicalRelease: function(item, direction) {
if (item.physicalRelease) {
return moment(item.physicalRelease).unix();
}
if (direction === sortDirections.DESCENDING) {
return -1 * Number.MAX_VALUE;
}
return Number.MAX_VALUE;
},
digitalRelease: function(item, direction) {
if (item.digitalRelease) {
return moment(item.digitalRelease).unix();
}
if (direction === sortDirections.DESCENDING) {
return -1 * Number.MAX_VALUE;
}
return Number.MAX_VALUE;
}
},

View File

@@ -91,7 +91,7 @@ export const defaultState = {
columnLabel: () => translate('CustomFormatScore'),
label: React.createElement(Icon, {
name: icons.SCORE,
title: 'Custom format score'
title: () => translate('CustomFormatScore')
}),
isVisible: false
},

View File

@@ -1,33 +0,0 @@
import _ from 'lodash';
import { createSelector } from 'reselect';
function createMovieCollectionListSelector() {
return createSelector(
(state, { tmdbId }) => tmdbId,
(state) => state.settings.importLists.items,
(tmdbId, importLists) => {
const importListIds = _.reduce(importLists, (acc, list) => {
if (list.implementation === 'TMDbCollectionImport') {
const collectionIdField = list.fields.find((field) => {
return field.name === 'collectionId';
});
if (collectionIdField && parseInt(collectionIdField.value) === tmdbId) {
acc.push(list);
return acc;
}
}
return acc;
}, []);
if (importListIds.length === 0) {
return undefined;
}
return importListIds[0];
}
);
}
export default createMovieCollectionListSelector;

View File

@@ -21,15 +21,11 @@ function createMovieCreditListSelector() {
return acc;
}, []);
let importListId = 0;
if (importListIds.length > 0) {
importListId = importListIds[0].id;
if (importListIds.length === 0) {
return undefined;
}
return {
importListId
};
return importListIds[0];
}
);
}

View File

@@ -4,6 +4,8 @@ import { render } from 'react-dom';
import createAppStore from 'Store/createAppStore';
import App from './App/App';
import 'Diag/ConsoleApi';
export async function bootstrap() {
const history = createBrowserHistory();
const store = createAppStore(history);

View File

@@ -15,6 +15,7 @@ interface ImportList extends ModelBase {
enabled: boolean;
enableAuto: boolean;
qualityProfileId: number;
minimumAvailability: string;
rootFolderPath: string;
name: string;
fields: Field[];

View File

@@ -0,0 +1,25 @@
using Dapper;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Housekeeping.Housekeepers
{
public class CleanupOrphanedMovies : IHousekeepingTask
{
private readonly IMainDatabase _database;
public CleanupOrphanedMovies(IMainDatabase database)
{
_database = database;
}
public void Clean()
{
using var mapper = _database.OpenConnection();
mapper.Execute(@"DELETE FROM ""Movies""
WHERE ""Id"" IN (
SELECT ""Movies"".""Id"" FROM ""Movies""
LEFT OUTER JOIN ""MovieMetadata"" ON ""Movies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
WHERE ""MovieMetadata"".""Id"" IS NULL)");
}
}
}

View File

@@ -38,6 +38,7 @@ namespace NzbDrone.Core.ImportLists.RSSImport
EnableAuto = true,
QualityProfileId = 1,
Implementation = GetType().Name,
MinRefreshInterval = MinRefreshInterval,
Settings = new RSSImportSettings { Link = "https://rss.imdb.com/list/YOURLISTID" },
};
yield return new ImportListDefinition
@@ -47,6 +48,7 @@ namespace NzbDrone.Core.ImportLists.RSSImport
EnableAuto = true,
QualityProfileId = 1,
Implementation = GetType().Name,
MinRefreshInterval = MinRefreshInterval,
Settings = new RSSImportSettings { Link = "https://rss.imdb.com/user/IMDBUSERID/watchlist" },
};
}

View File

@@ -47,6 +47,7 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList
EnableAuto = true,
QualityProfileId = 1,
Implementation = GetType().Name,
MinRefreshInterval = MinRefreshInterval,
Settings = new IMDbListSettings { ListId = "top250" },
};
yield return new ImportListDefinition
@@ -56,6 +57,7 @@ namespace NzbDrone.Core.ImportLists.RadarrList2.IMDbList
EnableAuto = true,
QualityProfileId = 1,
Implementation = GetType().Name,
MinRefreshInterval = MinRefreshInterval,
Settings = new IMDbListSettings { ListId = "popular" },
};
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
@@ -28,15 +29,15 @@ namespace NzbDrone.Core.Indexers.FileList
BaseUrl = "https://filelist.io";
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
Categories = new int[]
Categories = new[]
{
(int)FileListCategories.Movie_HD,
(int)FileListCategories.Movie_SD,
(int)FileListCategories.Movie_4K
};
MultiLanguages = new List<int>();
RequiredFlags = new List<int>();
MultiLanguages = Array.Empty<int>();
RequiredFlags = Array.Empty<int>();
}
[FieldDefinition(0, Label = "Username", Privacy = PrivacyLevel.UserName)]
@@ -57,7 +58,7 @@ namespace NzbDrone.Core.Indexers.FileList
[FieldDefinition(5, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(6, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(7)]

View File

@@ -31,8 +31,8 @@ namespace NzbDrone.Core.Indexers.HDBits
Categories = new[] { (int)HdBitsCategory.Movie };
Codecs = Array.Empty<int>();
Mediums = Array.Empty<int>();
MultiLanguages = new List<int>();
RequiredFlags = new List<int>();
MultiLanguages = Array.Empty<int>();
RequiredFlags = Array.Empty<int>();
}
[FieldDefinition(0, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
@@ -59,7 +59,7 @@ namespace NzbDrone.Core.Indexers.HDBits
[FieldDefinition(7, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(8, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
[FieldDefinition(8, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(9)]

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using FluentValidation;
@@ -33,8 +34,8 @@ namespace NzbDrone.Core.Indexers.IPTorrents
{
BaseUrl = string.Empty;
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
MultiLanguages = new List<int>();
RequiredFlags = new List<int>();
MultiLanguages = Array.Empty<int>();
RequiredFlags = Array.Empty<int>();
}
[FieldDefinition(0, Label = "Feed URL", HelpText = "The full RSS feed url generated by IPTorrents, using only the categories you selected (HD, SD, x264, etc ...)")]
@@ -46,7 +47,7 @@ namespace NzbDrone.Core.Indexers.IPTorrents
[FieldDefinition(2, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(3, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
[FieldDefinition(3, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(4)]

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
@@ -55,7 +56,7 @@ namespace NzbDrone.Core.Indexers.Newznab
{
ApiPath = "/api";
Categories = new[] { 2000, 2010, 2020, 2030, 2040, 2045, 2050, 2060 };
MultiLanguages = new List<int>();
MultiLanguages = Array.Empty<int>();
}
[FieldDefinition(0, Label = "URL")]

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using FluentValidation;
@@ -28,8 +29,8 @@ namespace NzbDrone.Core.Indexers.Nyaa
BaseUrl = "";
AdditionalParameters = "&cats=1_0&filter=1";
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
MultiLanguages = new List<int>();
RequiredFlags = new List<int>();
MultiLanguages = Array.Empty<int>();
RequiredFlags = Array.Empty<int>();
}
[FieldDefinition(0, Label = "Website URL")]
@@ -44,7 +45,7 @@ namespace NzbDrone.Core.Indexers.Nyaa
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(4, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
[FieldDefinition(4, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(5)]

View File

@@ -59,9 +59,14 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
flags |= IndexerFlags.PTP_Approved;
}
if (torrent.FreeleechType == "Freeleech")
switch (torrent.FreeleechType?.ToUpperInvariant())
{
flags |= IndexerFlags.G_Freeleech;
case "FREELEECH":
flags |= IndexerFlags.G_Freeleech;
break;
case "HALF LEECH":
flags |= IndexerFlags.G_Halfleech;
break;
}
if (torrent.Scene)

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
@@ -26,9 +27,9 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
public PassThePopcornSettings()
{
BaseUrl = "https://passthepopcorn.me";
MinimumSeeders = 0;
MultiLanguages = new List<int>();
RequiredFlags = new List<int>();
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
MultiLanguages = Array.Empty<int>();
RequiredFlags = Array.Empty<int>();
}
[FieldDefinition(0, Label = "URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your cookie will be sent to that host.")]
@@ -49,7 +50,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
[FieldDefinition(5)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(6, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
@@ -25,8 +26,8 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
{
BaseUrl = "http://127.0.0.1";
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
MultiLanguages = new List<int>();
RequiredFlags = new List<int>();
MultiLanguages = Array.Empty<int>();
RequiredFlags = Array.Empty<int>();
}
[FieldDefinition(0, Label = "API URL", HelpText = "URL to TorrentPotato api.")]
@@ -47,7 +48,7 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
[FieldDefinition(5)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(6, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
@@ -26,8 +27,8 @@ namespace NzbDrone.Core.Indexers.TorrentRss
BaseUrl = string.Empty;
AllowZeroSize = false;
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
MultiLanguages = new List<int>();
RequiredFlags = new List<int>();
MultiLanguages = Array.Empty<int>();
RequiredFlags = Array.Empty<int>();
}
[FieldDefinition(0, Label = "Full RSS Feed URL")]
@@ -48,7 +49,7 @@ namespace NzbDrone.Core.Indexers.TorrentRss
[FieldDefinition(5)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(6, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()

View File

@@ -58,7 +58,7 @@ namespace NzbDrone.Core.Indexers.Torznab
[FieldDefinition(9)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(10, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
[FieldDefinition(10, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public override NzbDroneValidationResult Validate()

View File

@@ -1096,7 +1096,7 @@
"DeleteRemotePathMappingMessageText": "Esteu segur que voleu suprimir aquesta assignació remota de camins?",
"DeleteImportListExclusionMessageText": "Esteu segur que voleu suprimir aquesta exclusió de la llista d'importació?",
"DeleteConditionMessageText": "Esteu segur que voleu suprimir la notificació '{0}'?",
"DeleteCustomFormatMessageText": "Esteu segur que voleu suprimir l'indexador '{0}'?",
"DeleteCustomFormatMessageText": "Esteu segur que voleu suprimir l'indexador '{customFormatName}'?",
"DeleteDelayProfileMessageText": "Esteu segur que voleu suprimir aquest perfil de retard?",
"DeleteFormatMessageText": "Esteu segur que voleu suprimir l'etiqueta de format {0} ?",
"RemoveSelectedItemQueueMessageText": "Esteu segur que voleu eliminar {0} de la cua?",
@@ -1159,5 +1159,7 @@
"FormatAgeMinute": "Minuts",
"FormatAgeMinutes": "Minuts",
"FormatAgeHour": "Hores",
"BlocklistLoadError": "No es pot carregar la llista de bloqueig"
"BlocklistLoadError": "No es pot carregar la llista de bloqueig",
"AutoRedownloadFailed": "La baixada ha fallat",
"InteractiveSearchModalHeader": "Cerca interactiva"
}

View File

@@ -10,7 +10,7 @@
"AddRemotePathMapping": "Přidat mapování vzdálených cest",
"Date": "datum",
"About": "O aplikaci",
"AddIndexer": "Přidat indexátor",
"AddIndexer": "Přidat indexer",
"AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Filmy odstraněné z disku jsou automaticky sledovány v {appName}u",
"AvailabilityDelay": "Zpoždění dostupnosti",
"Certification": "Osvědčení",
@@ -37,13 +37,13 @@
"Real": "Nemovitý",
"ClickToChangeMovie": "Kliknutím změníte film",
"ConnectSettings": "Nastavení připojení",
"CopyUsingHardlinksHelpText": "Hardlinks použijte, když se pokoušíte kopírovat soubory z torrentů, které se stále používají",
"CopyUsingHardlinksHelpText": "Pevné odkazy umožňují {appName} importovat odesílané torrenty do složky s filmem, aniž by zabíraly další místo na disku nebo kopírovaly celý obsah souboru. Pevné odkazy budou fungovat pouze v případě, že zdroj a cíl jsou na stejném svazku",
"CustomFormatsSettings": "Nastavení vlastních formátů",
"CutoffFormatScoreHelpText": "Jakmile je dosaženo tohoto skóre vlastního formátu, {appName} již nebude stahovat filmy",
"DeleteEmptyFolders": "Odstraňte prázdné složky",
"DeleteEmptyFoldersHelpText": "Během skenování disku a při mazání filmových souborů odstraňte prázdné složky s filmy",
"DeleteFilesLabel": "Smažte {0} filmové soubory",
"DeleteNotificationMessageText": "Opravdu chcete smazat oznámení „{0}“?",
"DeleteNotificationMessageText": "Opravdu chcete smazat oznámení '{name}'?",
"DeleteRestrictionHelpText": "Opravdu chcete toto omezení smazat?",
"DeleteTagMessageText": "Opravdu chcete smazat značku „{0}“?",
"DetailedProgressBar": "Podrobný ukazatel průběhu",
@@ -493,7 +493,7 @@
"ConsideredAvailable": "Považováno za dostupné",
"CopyToClipboard": "Zkopírovat do schránky",
"CopyUsingHardlinksHelpTextWarning": "Zámky souborů mohou občas zabránit přejmenování souborů, které se právě vysazují. Výsev můžete dočasně deaktivovat a použít funkci {appName} pro přejmenování.",
"CouldNotFindResults": "Nelze najít žádné výsledky pro dotaz „{0}“",
"CouldNotFindResults": "Nepodařilo se najít žádné výsledky pro '{term}'",
"CreateGroup": "Vytvořit skupinu",
"Crew": "Osádka",
"CurrentlyInstalled": "Aktuálně nainstalováno",
@@ -515,16 +515,16 @@
"DelayProfile": "Zpožděný profil",
"DelayProfiles": "Profily zpoždění",
"Delete": "Vymazat",
"DeleteBackupMessageText": "Opravdu chcete smazat zálohu „{0}“?",
"DeleteBackupMessageText": "Opravdu chcete odstranit zálohu '{name}'?",
"Deleted": "Smazáno",
"DeleteDelayProfile": "Smazat profil zpoždění",
"DeleteDownloadClientMessageText": "Opravdu chcete odstranit klienta pro stahování „{0}“?",
"DeleteDownloadClientMessageText": "Opravdu chcete odstranit klienta pro stahování '{name}'?",
"DeleteFile": "Smazat soubor",
"DeleteFilesHelpText": "Odstraňte soubory filmu a složku filmu",
"DeleteHeader": "Smazat - {0}",
"DeleteImportListExclusion": "Odstranit vyloučení seznamu importů",
"DeleteIndexer": "Odstranit indexer",
"DeleteIndexerMessageText": "Opravdu chcete odstranit indexer „{0}“?",
"DeleteIndexerMessageText": "Opravdu chcete odstranit indexer '{name}'?",
"DeleteMovieFolderHelpText": "Odstraňte složku filmu a její obsah",
"DeleteNotification": "Smazat oznámení",
"EditMovie": "Upravit film",
@@ -1004,18 +1004,18 @@
"ShowCinemaReleaseHelpText": "Zobrazit datum vydání pod plakátem",
"DeleteRemotePathMapping": "Upravit vzdálené mapování cesty",
"DeleteRemotePathMappingMessageText": "Opravdu chcete toto vzdálené mapování cesty odstranit?",
"ApplyTagsHelpTextReplace": "Nahradit: Nahradit značky zadanými značkami (zadáním žádné značky vymažete všechny značky)",
"DeleteConditionMessageText": "Opravdu chcete smazat značku „{0}“?",
"DeleteCustomFormatMessageText": "Opravdu chcete odstranit indexer „{0}“?",
"ApplyTagsHelpTextReplace": "Nahradit: Nahradit značky zadanými značkami (prázdné pole vymaže všechny značky)",
"DeleteConditionMessageText": "Opravdu chcete odstranit podmínku '{name}'?",
"DeleteCustomFormatMessageText": "Opravdu chcete odstranit indexer „{customFormatName}“?",
"DeleteDelayProfileMessageText": "Opravdu chcete smazat tento profil zpoždění?",
"DeleteFormatMessageText": "Opravdu chcete smazat značku formátu {0}?",
"RemoveSelectedItemQueueMessageText": "Opravdu chcete odebrat {0} položku {1} z fronty?",
"RemoveSelectedItemsQueueMessageText": "Opravdu chcete odebrat {0} položku {1} z fronty?",
"ApplyTagsHelpTextAdd": "Přidat: Přidá značky k již existujícímu seznamu",
"ApplyTagsHelpTextHowToApplyIndexers": "Jak použít značky na vybrané indexátory",
"ApplyTagsHelpTextHowToApplyIndexers": "Jak použít značky na vybrané indexery",
"ApplyTagsHelpTextRemove": "Odebrat: Odebrat zadané značky",
"DeleteImportListExclusionMessageText": "Opravdu chcete toto vyloučení importního seznamu smazat?",
"DeleteSelectedDownloadClients": "Odstranit staženého klienta",
"DeleteSelectedDownloadClients": "Odstranit klienta pro stahování",
"DeleteSelectedIndexers": "Odstranit indexer",
"ResetAPIKeyMessageText": "Opravdu chcete resetovat klíč API?",
"AddConditionImplementation": "Přidat podmínku - {implementationName}",
@@ -1023,11 +1023,11 @@
"AddConnectionImplementation": "Přidat spojení - {implementationName}",
"AddDownloadClientImplementation": "Přidat klienta pro stahování - {implementationName}",
"AddImportList": "Přidat importované položky",
"AddIndexerImplementation": "Přidat indexátor - {implementationName}",
"AddAutoTag": "Přidat automatické tagy",
"AddIndexerImplementation": "Přidat indexer - {implementationName}",
"AddAutoTag": "Přidat automatickou značku",
"AddCondition": "Přidat podmínku",
"AllTitles": "Všechny názvy",
"AddImportListImplementation": "Přidat importované položky - {implementationName}",
"AddImportListImplementation": "Přidat seznam k importu - {implementationName}",
"ApplicationURL": "URL aplikace",
"ApiKeyValidationHealthCheckMessage": "Aktualizujte svůj klíč API tak, aby měl alespoň {length} znaků. Můžete to provést prostřednictvím nastavení nebo konfiguračního souboru",
"BypassDelayIfHighestQuality": "Obejít v případě nejvyšší kvality",
@@ -1037,7 +1037,7 @@
"AutoTagging": "Automatické označování",
"AutomaticAdd": "Přidat automaticky",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Jak použít značky na vybrané klienty pro stahování",
"ApplyTagsHelpTextHowToApplyImportLists": "Jak použít značky na vybrané importní seznamy",
"ApplyTagsHelpTextHowToApplyImportLists": "Jak použít značky na vybrané seznamy k importu",
"AutomaticUpdatesDisabledDocker": "Automatické aktualizace nejsou při použití aktualizačního mechanismu Docker přímo podporovány. Obraz kontejneru je nutné aktualizovat mimo {appName} nebo použít skript",
"BypassDelayIfAboveCustomFormatScore": "Obejít, pokud je vyšší než skóre vlastního formátu",
"AuthenticationRequired": "Vyžadované ověření",
@@ -1055,5 +1055,85 @@
"DiscordUrlInSlackNotification": "Máte nastaveny Discord notifikace v režimu Slack. Nastavte je do režimu Discord pro lepší funkcionalitu. Postižené notifikace: {0}",
"AnnouncedMsg": "Film je oznámen",
"IndexerDownloadClientHelpText": "Zvolte, který klient pro stahování bude použit pro zachytávání z toho indexeru",
"ImportListMissingRoot": "Chybí kořenový adresář pro import seznamu: {rootFolderInfo}"
"ImportListMissingRoot": "Chybí kořenový adresář pro import seznamu: {rootFolderInfo}",
"EditCollection": "Upravit sbírku",
"ApplyTagsHelpTextHowToApplyMovies": "Jak přidat tagy vybraným filmům",
"Default": "Výchozí",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Potvrďte nové heslo",
"AutoRedownloadFailed": "Opětovné stažení se nezdařilo",
"AutoRedownloadFailedFromInteractiveSearch": "Opětovné stažení z interaktivního vyhledávání selhalo",
"AutoTaggingRequiredHelpText": "Tato podmínka {0} musí odpovídat, aby se pravidlo automatického označování použilo. V opačném případě postačí jediná shoda s {0}.",
"ClearBlocklist": "Vyčistit blocklist",
"ClearBlocklistMessageText": "Určitě chcete smazat všechny položky z blocklistu?",
"CollectionShowPostersHelpText": "Zobrazit plakáty položek v kolekci",
"ConnectionLostReconnect": "{appName} se pokusí připojit automaticky, nebo můžete kliknout na tlačítko znovunačtení níže.",
"ConnectionLostToBackend": "{appName} ztratil spojení s backendem a pro obnovení funkčnosti bude třebaho znovu načíst.",
"CountDownloadClientsSelected": "{count} vybraných klientů ke stahování",
"DefaultNameCopiedProfile": "{name} - Kopírovat",
"DefaultNameCopiedSpecification": "{name} - Kopírovat",
"DelayingDownloadUntil": "Odložení stahování do {date} v {time}",
"DeleteAutoTag": "Odstranění automatické značky",
"DeleteAutoTagHelpText": "Opravdu chcete odstranit automatickou značku '{name}'?",
"DeleteImportList": "Smazat seznam importovaných položek",
"DeleteImportListMessageText": "Opravdu chcete smazat seznam '{name}'?",
"DeleteSelectedDownloadClientsMessageText": "Opravdu chcete smazat {count} vybraných klientů pro stahování?",
"DeleteSelectedIndexersMessageText": "Opravdu chcete smazat {count} vybraný(ch) indexer(ů)?",
"DeletedReasonManual": "Soubor byl smazán pomocí UI",
"DownloadClientTagHelpText": "Tohoto klienta pro stahování používat pouze pro filmy s alespoň jednou odpovídající značkou. Pro použití se všemi filmy ponechte prázdné pole.",
"DownloadIgnored": "Stahování ignorováno",
"EditAutoTag": "Upravit automatickou značku",
"EditConditionImplementation": "Upravit sbírku - {implementationName}",
"EditConnectionImplementation": "Upravit upozornění - {implementationName}",
"EditDownloadClientImplementation": "Upravit klienta pro stahování - {implementationName}",
"EditImportListImplementation": "Upravit seznam k importu - {implementationName}",
"EditIndexerImplementation": "Upravit indexer - {implementationName}",
"FailedToFetchUpdates": "Nepodařilo se načíst aktualizace",
"FailedToUpdateSettings": "Nepodařilo se aktualizovat nastavení",
"FormatAgeDay": "den",
"FormatAgeDays": "dnů",
"FormatAgeHour": "hodina",
"FormatAgeHours": "hodin",
"FormatAgeMinute": "minuta",
"FormatAgeMinutes": "minut",
"FormatDateTime": "{formattedDate} {formattedTime}",
"Complete": "Dokončit",
"CollectionOptions": "Možnosti kolekce",
"Auto": "Auto",
"AppUpdated": "{appName} aktualizován",
"AppUpdatedVersion": "{appName} byl aktualizován na verzi `{version}`, abyste získali nejnovější změny, musíte znovu načíst {appName}",
"CountIndexersSelected": "{count} vybraných indexerů",
"CollectionShowOverviewsHelpText": "Zobrazit přehledy kolekcí",
"Database": "Databáze",
"Duration": "Trvání",
"CollectionsSelectedInterp": "Vybráno {0} kolekcí",
"CountImportListsSelected": "{count} vybraných seznamů pro import",
"CollectionShowDetailsHelpText": "Zobrazit stav a vlastnosti kolekce",
"AutoTaggingNegateHelpText": "Pokud je zaškrtnuto, pravidlo automatického označování se nepoužije, pokud odpovídá této podmínce {0}.",
"DownloadClientSortingCheckMessage": "Klient pro stahování {downloadClientName} má nastaveno třídění {sortingMode} pro kategorii {appName}. Ve svém klientovi pro stahování byste měli třídění zakázat, abyste se vyhnuli problémům s importem.",
"EditSelectedImportLists": "Upravit vybrané seznamy k importu",
"DeleteRootFolder": "Smazat kořenový adresář",
"DeleteRootFolderMessageText": "Opravdu chcete smazat kořenový adresář s cestou '{path}'?",
"EditSelectedIndexers": "Upravit vybrané indexery",
"DisabledForLocalAddresses": "Zakázáno pro místní adresy",
"BlocklistLoadError": "Nelze načíst černou listinu",
"BlocklistReleaseHelpText": "Zabránit {appName}u v opětovném sebrání tohoto vydá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",
"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 {1}.",
"DownloadClientsLoadError": "Nelze načíst klienty pro stahování",
"EditSelectedMovies": "Upravit vybrané filmy",
"EditSelectedDownloadClients": "Upravit vybrané klienty pro stahování",
"AuthenticationMethod": "Metoda ověřování",
"AuthenticationMethodHelpTextWarning": "Prosím vyberte platnou metodu ověřování",
"AuthenticationRequiredPasswordHelpTextWarning": "Vložte nové heslo",
"AuthenticationRequiredUsernameHelpTextWarning": "Vložte nové uživatelské jméno",
"AuthenticationRequiredWarning": "Aby se zabránilo vzdálenému přístupu bez ověření, vyžaduje nyní {appName} povolení ověření. Ověřování z místních adres můžete volitelně zakázat.",
"DeleteCondition": "Odstranit podmínku",
"EnableProfile": "Povolit profil",
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Automaticky vyhledat a pokusit se o stažení jiného vydání, pokud bylo neúspěšné vydání zachyceno z interaktivního vyhledávání",
"DeleteSelectedImportLists": "Smazat seznam k importu",
"DeleteSelectedImportListsMessageText": "Opravdu chcete smazat {count} vybraných seznamů k importu?"
}

View File

@@ -1010,7 +1010,7 @@
"DeleteImportListExclusionMessageText": "Er du sikker på, at du vil slette denne undtagelse fra importlisten?",
"DeleteFormatMessageText": "Er du sikker på, at du vil slette formattag {0}?",
"DeleteConditionMessageText": "Er du sikker på, at du vil slette listen '{0}'?",
"DeleteCustomFormatMessageText": "Er du sikker på, at du vil slette indeksøren '{0}'?",
"DeleteCustomFormatMessageText": "Er du sikker på, at du vil slette indeksøren '{customFormatName}'?",
"RemoveSelectedItemQueueMessageText": "Er du sikker på, at du vil fjerne {0} element {1} fra køen?",
"RemoveSelectedItemsQueueMessageText": "Er du sikker på, at du vil fjerne {0} element {1} fra køen?",
"ResetAPIKeyMessageText": "Er du sikker på, at du vil nulstille din API-nøgle?",

View File

@@ -3,7 +3,7 @@
"Activity": "Aktivität",
"AddExclusion": "Ausschluss hinzufügen",
"AddMovies": "Filme hinzufügen",
"AddNew": "Hinzufügen",
"AddNew": "Neue hinzufügen",
"AddNewMessage": "Es ist einfach einen neuen Film hinzuzufügen. Gib einfach den Namen des Filmes ein, den du hinzufügen möchtest",
"AddNewTmdbIdMessage": "Du kannst auch mit der TMDb-ID eines Films suchen. Z.B. 'tmdb:71663'",
"Agenda": "Agenda",
@@ -103,7 +103,7 @@
"Queue": "Warteschlange",
"RSSSync": "RSS-Sync",
"Refresh": "Aktualisieren",
"RefreshAndScan": "Aktualisieren",
"RefreshAndScan": "Aktualisieren und scannen",
"ReleaseBranchCheckOfficialBranchMessage": "Zweig {0} ist kein gültiger {appName}-Release-Zweig. Sie erhalten keine Updates",
"RemotePathMappings": "Remote-Pfadzuordnungen",
"RemoveSelected": "Auswahl entfernen",
@@ -165,7 +165,7 @@
"ReleaseStatus": "Releasestatus",
"ReleaseGroup": "Release-Gruppe",
"Ratings": "Bewertung",
"QualitySettingsSummary": "Qualitätgrößen und Bennenung",
"QualitySettingsSummary": "Qualitätsgrößen und Namensgebung",
"Protocol": "Protokoll",
"Progress": "Fortschritt",
"ProfilesSettingsSummary": "Profile für Qualität, Sprache und Verzögerung",
@@ -446,21 +446,21 @@
"PortNumber": "Port Nummer",
"PreferIndexerFlagsHelpText": "Priorisiere Releases mit speziellen Flags",
"PreferredSize": "Bevorzugte Größe",
"Proper": "Proper",
"ProtocolHelpText": "Wählen Sie, welche(s) Protokoll(e) verwendet werden soll(en) und welches Protokoll bei der Wahl zwischen ansonsten gleichwertigen Releases bevorzugt wird",
"ProxyBypassFilterHelpText": "Verwende ',' als Trennzeichen und '*.' als Platzhalter für Subdomains",
"ProxyType": "Proxy Typ",
"ProxyUsernameHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.",
"PublishedDate": "Veröffentlichungs Datum",
"Proper": "Korrekt",
"ProtocolHelpText": "Wählen Sie aus, welche(s) Protokoll(e) Sie verwenden möchten und welches Protokoll Sie bevorzugen, wenn Sie zwischen ansonsten gleichen Versionen wählen",
"ProxyBypassFilterHelpText": "Verwenden Sie ',' als Trennzeichen und '*.' als Wildcard für Subdomains",
"ProxyType": "Proxy-Typ",
"ProxyUsernameHelpText": "Sie müssen nur einen Benutzernamen und ein Passwort eingeben, wenn dies erforderlich ist. Andernfalls lassen Sie sie leer.",
"PublishedDate": "Veröffentlichungsdatum",
"QualityCutoffHasNotBeenMet": "Qualitätsschwelle wurde noch nicht erreicht",
"QualitySettings": "Qualitäts Einstellungen",
"QualitySettings": "Qualitätseinstellungen",
"RadarrTags": "{appName} Tags",
"Real": "Echt",
"Reason": "Grund",
"Real": "Real",
"Reason": "Begründung",
"RecycleBinCleanupDaysHelpText": "Auf 0 setzen um das automatische leeren des Papierkorbs zu deaktivieren",
"RecycleBinHelpText": "Gelöschte Filmdateien werden hierher verschoben anstatt sie direkt endgültig zu löschen",
"RecyclingBin": "Papierkorb",
"RecyclingBinCleanup": "Papierkorb aufräumen",
"RecyclingBinCleanup": "Papierkorb leeren",
"RefreshInformationAndScanDisk": "Metadaten aktualisieren und Festplatte scannen",
"RefreshMovie": "Film aktualisieren",
"ReleaseRejected": "Release abgelehnt",
@@ -571,12 +571,12 @@
"AuthenticationMethodHelpText": "Für den Zugriff auf {appName} sind Benutzername und Passwort erforderlich",
"CopyUsingHardlinksHelpTextWarning": "Dateisperren Gelegentlich kann es vorkommen, dass Dateisperren das Umbenennen von Dateien verhindern, die gerade geseeded werden. Sie können das Seeding vorübergehend deaktivieren und die Umbenennungsfunktion von {appName} als Workaround verwenden.",
"IndexerSettings": "Indexer Einstellungen",
"ProxyPasswordHelpText": "Nur wenn ein Benutzername und Passwort erforderlich ist, muss es eingegeben werden. Ansonsten leer lassen.",
"ProxyPasswordHelpText": "Sie müssen nur einen Benutzernamen und ein Passwort eingeben, wenn dies erforderlich ist. Andernfalls lassen Sie sie leer.",
"SendAnonymousUsageData": "Anonyme Nutzungsdaten übertragen",
"AutoRedownloadFailedHelpText": "Automatisch nach einem anderen Release suchen",
"DBMigration": "DB Migration",
"LaunchBrowserHelpText": " Öffne die Startseite von {appName} im Webbrowser nach dem Start.",
"ReadTheWikiForMoreInformation": "Lese das Wiki für mehr Informationen",
"ReadTheWikiForMoreInformation": "Lesen Sie das Wiki für weitere Informationen",
"SetPermissionsLinuxHelpText": "Soll CHMOD ausgeführt werden wenn Datien importiert/umbenannt werden?",
"BackupFolderHelpText": "Relative Pfade befinden sich unter {appName}s AppData Ordner",
"DelayProfile": "Verzögerungsprofil",
@@ -613,7 +613,7 @@
"RSSSyncIntervalHelpTextWarning": "Dies wird alle Indexer betreffen. Bitte folge deren Regeln",
"RSSIsNotSupportedWithThisIndexer": "RSS wird von diesem Indexer nicht unterstützt",
"RemovingTag": "Tag entfernen",
"Queued": "In der Warteschlange",
"Queued": "In Warteschlange",
"Pending": "Ausstehend",
"Paused": "Pausiert",
"NegateHelpText": "Wenn aktiviert wird das eigene Format nicht angewendet solange diese {0} Bedingung zutrifft.",
@@ -838,14 +838,14 @@
"RemoveMovieAndDeleteFiles": "Film entfernen und Dateien löschen",
"ReleasedMsg": "Film wurde veröffentlicht",
"RefreshLists": "Listen aktualisieren",
"RecentChanges": "Neuste Änderungen",
"RecentChanges": "Kürzliche Änderungen",
"RadarrCalendarFeed": "{appName} Kalender Feed",
"QueueIsEmpty": "Warteschlange ist leer",
"QueueIsEmpty": "Die Warteschlange ist leer",
"QualityProfileInUse": "Ein Qualitätsprofil mit zugeordneten Filmen, Listen oder Sammlungen kann nicht gelöscht werden",
"QualityOrLangCutoffHasNotBeenMet": "Qualität oder Sprache haben die Schwelle noch nicht erreicht",
"QualityLimitsHelpText": "Limitierungen werden automatisch an die Filmlänge angepasst.",
"QualitiesHelpText": "Qualitätsprofile oben sind mehr bevorzugt, auch wenn diese nicht angehakt sind. Profile in einer Gruppe sind gleichgestellt. Nur ausgewählte werden gesucht",
"Qualities": "Qualitätsprofile",
"Qualities": "Qualitäten",
"PrioritySettings": "Priorität: {0}",
"PreviewRenameHelpText": "Tipp: Um eine Vorschau der Umbenennung zu bekommen, wähle Abbrechen und klicke auf einen Filmtitel und benutze den",
"Presets": "Voreinstellungen",
@@ -1118,7 +1118,7 @@
"RemoveSelectedItemsQueueMessageText": "Bist du sicher, dass du {0} Einträge aus der Warteschlange entfernen willst?",
"ResetDefinitionTitlesHelpText": "Definitionstitel und Werte zurücksetzen",
"DeleteConditionMessageText": "Bist du sicher, dass du die Bedingung '{0}' löschen willst?",
"DeleteCustomFormatMessageText": "Bist du sicher, dass du das eigene Format '{0}' löschen willst?",
"DeleteCustomFormatMessageText": "Bist du sicher, dass du das eigene Format '{customFormatName}' löschen willst?",
"DeleteDelayProfileMessageText": "Bist du sicher, dass du dieses Verzögerung-Profil löschen willst?",
"DeleteFormatMessageText": "Bist du sicher, dass du das Formatierungstag {0} löschen willst?",
"DeleteImportListExclusionMessageText": "Bist du sicher, dass du diesen Importlisten Ausschluss löschen willst?",
@@ -1178,5 +1178,16 @@
"IMDbId": "TMDb ID",
"DisabledForLocalAddresses": "Für Lokale Adressen deaktivieren",
"AddCondition": "Bedingung hinzufügen",
"AddAutoTag": "Automatisches Tag hinzufügen"
"AddAutoTag": "Automatisches Tag hinzufügen",
"AppUpdated": "{appName} aktualisiert",
"AddConditionImplementation": "Bedingung hinzufügen - {implementationName}",
"AddImportList": "Importliste hinzufügen",
"AddImportListImplementation": "Importliste hinzufügen - {implementationName}",
"QualitiesLoadError": "Qualitäten können nicht geladen werden",
"QueueLoadError": "Die Warteschlange konnte nicht geladen werden",
"QueueFilterHasNoItems": "Der ausgewählte Warteschlangenfilter enthält keine Elemente",
"AddConnectionImplementation": "Verbindung hinzufügen - {implementationName}",
"AddDownloadClientImplementation": "Download-Client hinzufügen - {implementationName}",
"AddIndexerImplementation": "Indexer hinzufügen - {implementationName}",
"AppUpdatedVersion": "{appName} wurde auf die Version `{version}` aktualisiert. Um die neusten Funktionen zu bekommen lade {appName} neu"
}

View File

@@ -1119,7 +1119,7 @@
"DeleteCondition": "Διαγραφή συνθήκης",
"DeleteFormatMessageText": "Είστε βέβαιοι ότι θέλετε να διαγράψετε την ετικέτα μορφής {0};",
"DeleteConditionMessageText": "Είστε σίγουροι πως θέλετε να διαγράψετε τη συνθήκη '{0}';",
"DeleteCustomFormatMessageText": "Είστε σίγουροι πως θέλετε να διαγράψετε τη προσαρμοσμένη μορφή '{0}';",
"DeleteCustomFormatMessageText": "Είστε σίγουροι πως θέλετε να διαγράψετε τη προσαρμοσμένη μορφή '{customFormatName}';",
"DeleteDelayProfileMessageText": "Είστε σίγουροι πως θέλετε να διαγράψετε αυτό το Προφίλ χρονοκαθυστέρησης;",
"DeleteImportListExclusionMessageText": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν την εξαίρεση λίστας εισαγωγής;",
"NoHistoryBlocklist": "Δεν υπάρχει λίστα αποκλεισμού ιστορικού",

View File

@@ -246,7 +246,7 @@
"DeleteCondition": "Delete Condition",
"DeleteConditionMessageText": "Are you sure you want to delete the condition '{name}'?",
"DeleteCustomFormat": "Delete Custom Format",
"DeleteCustomFormatMessageText": "Are you sure you want to delete the custom format '{name}'?",
"DeleteCustomFormatMessageText": "Are you sure you want to delete the custom format '{customFormatName}'?",
"DeleteDelayProfile": "Delete Delay Profile",
"DeleteDelayProfileMessageText": "Are you sure you want to delete this delay profile?",
"DeleteDownloadClient": "Delete Download Client",
@@ -556,6 +556,7 @@
"InteractiveImportNoMovie": "Movie must be chosen for each selected file",
"InteractiveImportNoQuality": "Quality must be chosen for each selected file",
"InteractiveSearch": "Interactive Search",
"InteractiveSearchModalHeader": "Interactive Search",
"InteractiveSearchResultsFailedErrorMessage": "Search failed because its {message}. Try refreshing the movie info and verify the necessary information is present before searching again.",
"Interval": "Interval",
"InvalidFormat": "Invalid Format",

View File

@@ -9,7 +9,7 @@
"Import": "Importar",
"iCalLink": "enlace iCal",
"Host": "Host",
"History": "Historia",
"History": "Historial",
"HideAdvanced": "Ocultar Avanzado",
"Health": "Salud",
"GrabSelected": "Capturar Seleccionados",
@@ -42,7 +42,6 @@
"Crew": "Equipo",
"Connections": "Conexiones",
"Connect": "Conectar",
"CompletedDownloadHandling": "Manipulación de descargas completas",
"Clear": "Borrar",
"ChooseAnotherFolder": "Elige otra Carpeta",
"Cast": "Reparto",
@@ -226,7 +225,7 @@
"OAuthPopupMessage": "Pop-ups bloqueados por su navegador",
"Name": "Nombre",
"MoveFiles": "Mover Archivos",
"Monitored": "Monitoreada",
"Monitored": "Monitorizado",
"Message": "Mensaje",
"Location": "Ubicación",
"Level": "Nivel",
@@ -241,7 +240,6 @@
"ConnectionLost": "Conexión perdida",
"Component": "Componente",
"Columns": "Columnas",
"Close": "Cerrar",
"Cancel": "Cancelar",
"AudioInfo": "Audio Info",
"Apply": "Aplicar",
@@ -340,19 +338,15 @@
"CreateEmptyMovieFolders": "Crear carpetas de películas vacías",
"Conditions": "Condiciones",
"ColonReplacementFormatHelpText": "Cambia la forma en que {appName} reemplaza los dos puntos",
"ColonReplacement": "Reemplazo dos puntos",
"CloneProfile": "Clonar Perfil",
"CloneIndexer": "Clonar Indexer",
"ClientPriority": "Prioridad de Cliente",
"ClickToChangeQuality": "Clic para cambiar la calidad",
"ClickToChangeLanguage": "Clic para cambiar el idioma",
"CheckForFinishedDownloadsInterval": "Intervalo para verificar descargas terminadas",
"ChangeHasNotBeenSavedYet": "El cambio aún no se ha guardado",
"ChangeFileDate": "Cambiar Fecha de Archivo",
"ChangeFileDate": "Cambiar fecha de archivo",
"CertificationCountryHelpText": "Seleccionar país para certificaciones de películas",
"CertificationCountry": "País de certificación",
"CertificateValidationHelpText": "Cambiar como de estricta será la validación del certificado HTTPS. No cambiar a menos que entiendas los riesgos.",
"CertificateValidation": "Validación del certificado",
"CertificateValidationHelpText": "Cambiar como es la validacion de la certificacion estricta de HTTPS. No cambiar a menos que entiendas las consecuencias.",
"CertificateValidation": "Validacion de certificado",
"BypassProxyForLocalAddresses": "Omitir Proxy para Direcciones Locales",
"Branch": "Rama",
"BindAddressHelpText": "Dirección IP4 válida, localhost o '*' para todas las interfaces",
@@ -378,7 +372,7 @@
"AllowHardcodedSubs": "Permitir Hardcoded Subs",
"AgeWhenGrabbed": "Antigüedad (cuando se añadió)",
"AddImportExclusionHelpText": "Prevenir que la película sea añadida a {appName} mediante listas",
"AddListExclusion": "Añadir Exclusión De Lista",
"AddListExclusion": "Agregar Lista de Exclusión",
"YesCancel": "Sí, Cancelar",
"WhitelistedSubtitleTags": "Etiquetas de Subtítulos Permitidas",
"WhitelistedHardcodedSubsHelpText": "Las etiquetas de los subtítulos aquí, no se considerarán incrustados",
@@ -395,7 +389,7 @@
"Uptime": "Tiempo de actividad",
"UpgradeAllowedHelpText": "Si está desactivado las calidades no serán actualizadas",
"UpdateScriptPathHelpText": "Ruta del script propio que toma el paquete de actualización y se encarga del proceso de actualización restante",
"UpdateMechanismHelpText": "Usar el actualizador de {appName} o un script",
"UpdateMechanismHelpText": "Usar el actualizador incorporado de {appName} o un script",
"UpdateAutomaticallyHelpText": "Descargar e instalar actualizaciones automáticamente. Se podrán instalar desde Sistema: Actualizaciones también",
"UnmonitoredHelpText": "Incluir las peliculas no monitoreadas en el feed de iCal",
"Ungroup": "Desagrupar",
@@ -459,7 +453,7 @@
"ResetAPIKey": "Reajustar API",
"Reset": "Reiniciar",
"RescanMovieFolderAfterRefresh": "Reescanear la Carpeta de Películas después de Actualizar",
"RescanAfterRefreshHelpTextWarning": "{appName} no detectará los cambios automáticamente en los ficheros si no se ajusta a 'Siempre'",
"RescanAfterRefreshHelpTextWarning": "{appName} no detectará automáticamente cambios en los archivos si no se elige 'Siempre'",
"RescanAfterRefreshHelpText": "Reescanear la carpeta de películas después de actualizar la película",
"RequiredHelpText": "Esta condición {0} ha de igualar al formato propio para aplicarse. Si no, una sóla {1} es suficiente.",
"ReplaceIllegalCharactersHelpText": "Reemplazar caracteres ilegales. Si está desactivado, {appName} los eliminará si no",
@@ -585,7 +579,7 @@
"EnableAutoHelpText": "Si se habilita, las Películas en esta lista se añadirán automáticamente a {appName}",
"CutoffFormatScoreHelpText": "Una la vez que la calidad objetivo es cumplida o excedida y esta puntuación de formato propio es alcanzada {appName} dejará de descargar o importar mejoras para estas películas",
"CustomFormatsSettings": "Ajustes de Formatos Propios",
"CopyUsingHardlinksHelpTextWarning": "Ocasionalmente, los archivos blqoueados impiden renombrar los archivos que siguen seedeando. Puedes desactivar el seedeo temporalmete y usar la función de renombrado de {appName} como alternativa.",
"CopyUsingHardlinksHelpTextWarning": "Ocasionalmente, los archivos bloqueados impiden renombrar los archivos que siguen seedeando. Puedes desactivar el seedeo temporalmete y usar la función de renombrado de Radarr como alternativa.",
"CopyUsingHardlinksHelpText": "Los Hardlinks permiten a {appName} importar torrents que siguen seedeando a la carpeta de películas sin ocupar espacio extra en el disco o copiando los contenidos al completo del archivo. Los Hardlinks solo funcionarán si el orígen y destino se encuentran en el mismo volumen",
"ConnectSettings": "Conectar Ajustes",
"CleanLibraryLevel": "Limpiar el Nivel de la Librería",
@@ -650,10 +644,10 @@
"DeleteIndexerMessageText": "Seguro que quieres eliminar el indexer '{name}'?",
"Cutoff": "Requisito",
"ClickToChangeMovie": "Clic para cambiar película",
"CheckDownloadClientForDetails": "comprobar el gestor de descargas para más detalles",
"CancelPendingTask": "Seguro que quieres cancelar esta tarea pendiente?",
"BranchUpdateMechanism": "Rama usada por el mecanismo de actualización externo",
"BranchUpdate": "Qué rama usar para actualizar {appName}",
"CheckDownloadClientForDetails": "Revisar cliente de descarpa para mas detalles",
"CancelPendingTask": "Estas seguro de que deseas cancelar esta tarea pendiente?",
"BranchUpdateMechanism": "La rama se uso por un mecanisco de actualizacion externo",
"BranchUpdate": "Rama a usar para actualizar {appName}",
"BeforeUpdate": "Antes de actualizar",
"AddingTag": "Añadir etiqueta",
"RadarrSupportsCustomConditionsAgainstTheReleasePropertiesBelow": "{appName} soporta condiciones personalizadas contra las propiedades de estrenos abajo.",
@@ -691,7 +685,7 @@
"NoUpdatesAreAvailable": "No hay actualizaciones disponibles",
"NoTagsHaveBeenAddedYet": "No se han añadido etiquetas todavía",
"NoLogFiles": "Sin archivos de registro",
"NoHistory": "Sin historia",
"NoHistory": "Sin historial",
"NoBackupsAreAvailable": "No hay copias de seguridad disponibles",
"MoreDetails": "Más detalles",
"MissingNotMonitored": "No encontrada (No Monitoreada)",
@@ -734,8 +728,6 @@
"DownloadPropersAndRepacks": "Propers y Repacks",
"CustomFormatUnknownConditionOption": "Opción Desconocida '{0}' para condición '{1}'",
"CustomFormatUnknownCondition": "Condición de Formato Personalizado Desconocida '{0}'",
"CopyToClipboard": "Copiar al portapapeles",
"CloneCustomFormat": "Clonar Formato Personalizado",
"Priority": "Prioridad",
"InteractiveSearch": "Búsqueda Interactiva",
"IndexerPriorityHelpText": "Prioridad del Indexer de 1 (La más alta) a 50 (La más baja). Por defecto: 25. Se utiliza cuando se toman las versiones como un criterio para las versiones que de otro modo serían iguales, {appName} seguirá utilizando todos los indexadores habilitados para la sincronización y la búsqueda de RSS",
@@ -765,23 +757,23 @@
"ImportErrors": "Errores al importar",
"Existing": "Existente",
"EditRestriction": "Editar Restricción",
"CancelProcessing": "Cancelar Procesamiento",
"CancelProcessing": "Procesando cancelacion",
"AddRestriction": "Añadir Restricción",
"AddMovie": "Añadir Película",
"IndexerLongTermStatusCheckSingleClientMessage": "Indexers no disponible por errores durando más de 6 horas: {indexerNames}",
"IndexerLongTermStatusCheckAllClientMessage": "Ningún indexer está disponible por errores durando más de 6 horas",
"EditMovieFile": "Editar Archivo de Película",
"ListTagsHelpText": "Etiquetas con las que se añadirán los elementos",
"AddToDownloadQueue": "Añadida a cola de descarga",
"AddToDownloadQueue": "Agregar a la cola de descarga",
"Add": "Añadir",
"AddCustomFormat": "Añadir Formato Personalizado",
"AddDelayProfile": "Añadir Perfil de Retraso",
"AddDownloadClient": "Añadir Cliente de Descarga",
"AddedToDownloadQueue": "Añadida a la cola de descargas",
"AddedToDownloadQueue": "Agregado a la cola de descarga",
"AddQualityProfile": "Añadir Perfil de Calidad",
"AddRootFolder": "Añadir Carpeta Raíz",
"AfterManualRefresh": "Tras Refrescar Manualmente",
"AllFiles": "Todos los Archivos",
"AllFiles": "Todos los archivos",
"ImportLibrary": "Importar biblioteca",
"ExcludeTitle": "¿Excluir {0}? Esto evitará que {appName} agregue automáticamente mediante la sincronización de listas.",
"None": "Ninguna",
@@ -963,7 +955,7 @@
"UsenetDisabled": "Usenet deshabilitado",
"Weeks": "Semanas",
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "¿Le gustaría restaurar la copia de seguridad {0}?",
"WouldYouLikeToRestoreBackup": "Te gustaria restaurar la copia de seguridad '{name}'?",
"YesMoveFiles": "Sí, mover los archivos",
"Yesterday": "Ayer",
"MoveFolders2": "¿Le gustaría mover los archivos de película de '{0}' a '{1}'?",
@@ -989,10 +981,10 @@
"BypassDelayIfHighestQuality": "Pasar sí es la calidad más alta",
"UnableToAddRootFolder": "No se han podido cargar las carpetas raiz",
"Blocklist": "Bloqueadas",
"BlocklistRelease": "Bloquear este Estreno",
"BlocklistRelease": "Lista de lanzamientos bloqueados",
"RemoveFromBlocklist": "Eliminar de lista de bloqueados",
"Blocklisted": "Bloqueados",
"BlocklistReleases": "Bloquear este Estreno",
"BlocklistReleases": "Lista de lanzamientos bloqueados",
"RemotePathMappingCheckDownloadPermissions": "{appName} puede ver pero no acceder a la película descargada {path}. Probablemente sea un error de permisos.",
"RemotePathMappingCheckFilesGenericPermissions": "El cliente de descarga {downloadClientName} informó de la existencia de archivos en {path} pero {appName} no puede ver este directorio. Es posible que tenga que ajustar los permisos de la carpeta.",
"Waiting": "Esperando",
@@ -1094,7 +1086,7 @@
"ShowCinemaReleaseHelpText": "Mostrar la fecha de lanzamiento debajo del cartel",
"DeleteRemotePathMapping": "Editar Mapeo de Ruta Remota",
"DownloadClientTagHelpText": "Solo utilizar este indexador para películas que coincidan con al menos una etiqueta. Déjelo en blanco para utilizarlo con todas las películas.",
"DeleteCustomFormatMessageText": "Seguro que quieres eliminar el indexer '{name}'?",
"DeleteCustomFormatMessageText": "Seguro que quieres eliminar el indexer '{customFormatName}'?",
"DeleteDelayProfileMessageText": "Está seguro que quieres borrar este perfil de retraso?",
"DeleteConditionMessageText": "Seguro que quieres eliminar la etiqueta '{name}'?",
"DeleteFormatMessageText": "¿Está seguro de que desea eliminar la etiqueta de formato {0}?",
@@ -1198,5 +1190,19 @@
"DeletedReasonManual": "El archivo fue borrado por vía UI",
"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",
"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?"
"DeleteSelectedMovieFilesHelpText": "¿Está seguro de que desea eliminar los archivos de película seleccionados?",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirma la nueva contraseña",
"ClearBlocklist": "Limpiar lista de bloqueadas",
"HistoryLoadError": "No se pudo cargar el historial",
"NoHistoryFound": "No se encontró historial",
"NoHistoryBlocklist": "Sin lista de bloqueo de historial",
"ClearBlocklistMessageText": "¿Estás seguro de que quieres borrar todos los elementos de la lista de bloqueo?",
"ClientPriority": "Prioridad del Cliente",
"ColonReplacement": "Reemplazar dos puntos",
"CloneIndexer": "Clonar Indexer",
"CompletedDownloadHandling": "Manipulación de descargas completas",
"CopyToClipboard": "Copiar al portapapeles",
"CloneCustomFormat": "Clonar formato personalizado",
"CloneProfile": "Clonar Perfil",
"Close": "Cerrar"
}

View File

@@ -1101,7 +1101,7 @@
"DeleteImportListExclusionMessageText": "Haluatko varmasti poistaa poikkeussäännön?",
"CountIndexersSelected": "{0} valittua tietolähdettä",
"DeleteConditionMessageText": "Haluatko varmasti poistaa tunnisteen '{0}'?",
"DeleteCustomFormatMessageText": "Haluatko varmasti poistaa pääkansion '{0}'?",
"DeleteCustomFormatMessageText": "Haluatko varmasti poistaa pääkansion '{customFormatName}'?",
"DeleteDelayProfileMessageText": "Haluatko varmasti poistaa viiveprofiilin?",
"DeleteSelectedImportLists": "Poista tuontilista",
"DeleteSelectedIndexers": "Poista tietolähde",

View File

@@ -26,7 +26,7 @@
"Edit": "Modifier",
"Downloaded": "Téléchargé",
"DownloadClientStatusCheckAllClientMessage": "Aucun client de téléchargement n'est disponible en raison d'échecs",
"DownloadClients": "Clients de téléchargements",
"DownloadClients": "Clients de téléchargement",
"DownloadClientCheckNoneAvailableMessage": "Aucun client de téléchargement n'est disponible",
"Dates": "Dates",
"Date": "Date",
@@ -36,7 +36,7 @@
"Delete": "Supprimer",
"DelayProfiles": "Profils de retard",
"Day": "Jour",
"CustomFormats": "Formats perso.",
"CustomFormats": "Formats personnalisés",
"CustomFilters": "Filtres personnalisés",
"Crew": "Équipe",
"Connections": "Connexions",
@@ -122,7 +122,7 @@
"Protocol": "Protocole",
"Progress": "Progression",
"ProfilesSettingsSummary": "Profils de qualité, de langue, de délai et de release",
"Profiles": "Profiles",
"Profiles": "Profils",
"PreviewRename": "Aperçu Renommer",
"PhysicalRelease": "Sortie physique",
"Path": "Chemin",
@@ -148,7 +148,7 @@
"Genres": "Genres",
"Forecast": "Prévision",
"DownloadClientsSettingsSummary": "Clients de téléchargement, gestion des téléchargements et mappages de chemins distants",
"DownloadClientCheckUnableToCommunicateMessage": "Impossible de communiquer avec {downloadClientName}.",
"DownloadClientCheckUnableToCommunicateMessage": "Impossible de communiquer avec {downloadClientName}. {errorMessage}",
"DownloadClient": "Client de téléchargement",
"CutoffUnmet": "Limite non satisfaite",
"MonitoredOnly": "Surveillé uniquement",
@@ -157,7 +157,7 @@
"MinimumAvailability": "Disponibilité minimale",
"MinAvailability": "Disponibilité minimale",
"MetadataSettingsSummary": "Créer des fichiers de métadonnées lorsque des films sont importés ou actualisés",
"Metadata": "Metadonnées",
"Metadata": "Métadonnées",
"MediaManagementSettingsSummary": "Paramètres de dénomination et de gestion des fichiers",
"MediaManagement": "Gestion des médias",
"MassMovieSearch": "Recherche de films en masse",
@@ -283,7 +283,7 @@
"RecentFolders": "Dossiers récents",
"QuickImport": "Déplacer automatiquement",
"PosterSize": "Poster taille",
"Posters": "Posters",
"Posters": "Affiches",
"PosterOptions": "Poster options",
"PendingChangesStayReview": "Rester et vérifier les modifications",
"PendingChangesMessage": "Vous avez des modifications non sauvegardées, voulez-vous vraiment quitter cette page ?",
@@ -339,7 +339,7 @@
"IconForCutoffUnmet": "Icône pour la date limite non respectée",
"ICalHttpUrlHelpText": "Copiez cette URL dans votre/vos client(s) ou cliquez pour abonner si votre navigateur est compatible avec webcal",
"ICalFeed": "Flux iCal",
"Hostname": "Hostname",
"Hostname": "Nom d'hôte",
"Group": "Groupe",
"GrabRelease": "Saisir Release",
"Grab": "Saisir",
@@ -347,7 +347,7 @@
"GeneralSettings": "Réglages généraux",
"FollowPerson": "Suivre la personne",
"Folders": "Dossiers",
"Fixed": "Fixé",
"Fixed": "Corrigés",
"FirstDayOfWeek": "Premier jour de la semaine",
"FileNames": "Noms de fichier",
"FileDateHelpText": "Changer la date du fichier lors de l'import/re-scan",
@@ -776,7 +776,7 @@
"Today": "Aujourd'hui",
"ConsideredAvailable": "Considéré comme disponible",
"CouldNotConnectSignalR": "Impossible de se connecter à SignalR, l'interface utilisateur ne sera pas mise à jour",
"ChmodFolderHelpTextWarning": "Fonctionne uniquement si l'utilisateur exécutant {appName} est le propriétaire du fichier. Il est recommandé de vérifier les permissions du client de téléchargement.",
"ChmodFolderHelpTextWarning": "Cela ne fonctionne que si l'utilisateur qui exécute {appName} est le propriétaire du fichier. Il est préférable de s'assurer que le client de téléchargement définit correctement les permissions.",
"ChmodGroupHelpTextWarning": "Fonctionne uniquement si l'utilisateur exécutant {appName} est le propriétaire du fichier. Il est recommandé de vérifier que le client de téléchargement utilise le meme Groupe que {appName}.",
"DefaultDelayProfile": "Ceci est le profil par défaut. Il est appliqué à tous les films qui n'ont pas de profils spécifiques.",
"DeleteTheMovieFolder": "Le dossier '{0}' et son contenu vont être supprimés.",
@@ -812,7 +812,7 @@
"CurrentlyInstalled": "Actuellement installé",
"Custom": "Customisé",
"CustomFormat": "Format personnalisé",
"CustomFormatHelpText": "Raddar met un score pour chaque release en additionnant les scores des formats personnalisés correspondants. Si une nouvelle release permet d'améliorer le score, pour une qualité identique ou supérieure, alors Raddar la téléchargera.",
"CustomFormatHelpText": "{appName} attribue un score pour chaque release en additionnant les scores des formats personnalisés correspondants. Si une nouvelle release permet d'améliorer le score, pour une qualité identique ou supérieure, alors {appName} la téléchargera.",
"Days": "Jours",
"Debug": "Déboguer",
"DefaultCase": "Casse par défaut",
@@ -833,7 +833,7 @@
"EditGroups": "Modifier les groupes",
"EditListExclusion": "Modifier l'exclusion de liste",
"Enabled": "Activé",
"ExcludeTitle": "Exclure {0} ? Raddar n'importeras plus automatiquement ce film des listes de synchronisation.",
"ExcludeTitle": "Exclure {0} ? {appName} n'importera plus automatiquement ce film des listes de synchronisation.",
"FailedToLoadMovieFromAPI": "Erreur lors du chargement du film via l'API",
"FeatureRequests": "Requêtes de nouvelles fonctionnalités",
"FileNameTokens": "Tokens des noms de fichier",
@@ -945,7 +945,7 @@
"SomeResultsHiddenFilter": "Tous les résultats ont été dissimulés par le filtre actuellement appliqué",
"Sunday": "Dimanche",
"TagDetails": "Détails de la balise - {label}",
"TheLogLevelDefault": "Le niveau de journalisation est par défaut «Info» et peut être modifié dans",
"TheLogLevelDefault": "Le niveau de journalisation est par défaut à « Information » et peut être modifié dans les [paramètres généraux](/settings/general)",
"ThisCannotBeCancelled": "Cela ne peut pas être annulé une fois démarré sans désactiver tous vos indexeurs.",
"TorrentDelayTime": "Retard du torrent : {0}",
"TorrentsDisabled": "Torrents désactivés",
@@ -1021,7 +1021,7 @@
"DiscordUrlInSlackNotification": "Vous avez une configuration de notification Discord en tant que notification Slack. Configurez cela comme une notification Discord pour un meilleur fonctionnement. Les notifications affectées sont : {0}",
"RemotePathMappingCheckDockerFolderMissing": "Vous utilisez docker; {downloadClientName} enregistre les téléchargements dans {path} mais ce dossier n'est pas présent dans ce conteneur. Vérifiez vos paramètres de dossier distant et les paramètres de votre conteneur docker.",
"RemotePathMappingCheckRemoteDownloadClient": "Le client de téléchargement distant {downloadClientName} met les téléchargements dans {path} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
"RemotePathMappingCheckBadDockerPath": "Vous utilisez docker ; le client de téléchargement {0} enregistre les téléchargements dans {1} mais ce n'est pas un chemin valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckBadDockerPath": "Vous utilisez docker ; le client de téléchargement {downloadClientName} enregistre les téléchargements dans {path} mais ce n'est pas un chemin {osName} valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckFilesWrongOSPath": "Le client de téléchargement distant {downloadClientName} met les téléchargements dans {path} mais il ne s'agit pas d'un chemin {osName} valide. Vérifiez les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckLocalFolderMissing": "Le client de téléchargement distant {downloadClientName} met les téléchargements dans {path} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
"OnApplicationUpdate": "Sur la mise à jour de l'application",
@@ -1112,7 +1112,7 @@
"RemoveSelectedItemQueueMessageText": "Êtes-vous sûr de vouloir supprimer 1 élément de la file d'attente ?",
"CountIndexersSelected": "{count} indexeur(s) sélectionné(s)",
"DeleteConditionMessageText": "Voulez-vous vraiment supprimer la condition « {name} » ?",
"DeleteCustomFormatMessageText": "Voulez-vous vraiment supprimer le format personnalisé « {name} » ?",
"DeleteCustomFormatMessageText": "Voulez-vous vraiment supprimer le format personnalisé « {customFormatName} » ?",
"DeleteDelayProfileMessageText": "Êtes-vous sûr de vouloir supprimer ce profil de retard ?",
"ResetAPIKeyMessageText": "Êtes-vous sûr de vouloir réinitialiser votre clé API ?",
"ResetDefinitionTitlesHelpText": "Réinitialiser les titres de définition ainsi que les valeurs",
@@ -1187,7 +1187,7 @@
"ListWillRefreshEveryInterp": "La liste se rafraîchira tous/toutes la/les {0}",
"OverrideGrabNoMovie": "Un film doit être sélectionné",
"OverrideGrabNoLanguage": "Au moins une langue doit être sélectionnée",
"ParseModalHelpTextDetails": "{appName} va tenter de parser le titre et de vous afficher les détails à son sujet",
"ParseModalHelpTextDetails": "{appName} va tenter d'analyser le titre et de vous afficher les détails à son sujet",
"QualitiesLoadError": "Impossible de charger les qualités",
"SelectFolderModalTitle": "{modalTitle} Sélectionner un dossier",
"ShowImdbRatingHelpText": "Affiche la note IMDb sous l'affiche",
@@ -1249,7 +1249,7 @@
"UnableToLoadAutoTagging": "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": "Readarr n'a pas pu trouver le fichier sur le disque, il a donc été supprimé dans la base de données",
"DeletedReasonMissingFromDisk": "{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}",
@@ -1334,5 +1334,17 @@
"MovieDownloadIgnoredTooltip": "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"
"EnableProfile": "Activer profil",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirmer le nouveau mot de passe",
"ClearBlocklist": "Effacer la liste de blocage",
"ClearBlocklistMessageText": "Êtes-vous sûr de vouloir supprimer tous les éléments de la liste de blocage ?",
"FailedToFetchUpdates": "Échec de la récupération des mises à jour",
"FailedToUpdateSettings": "Échec de la mise à jour des paramètres",
"LogFilesLocation": "Les fichiers journaux sont situés dans : {location}",
"PackageVersionInfo": "{packageVersion} par {packageAuthor}",
"InteractiveSearchModalHeader": "Recherche interactive",
"PreviouslyInstalled": "Installé précédemment",
"WhySearchesCouldBeFailing": "Cliquez ici pour savoir pourquoi les recherches pourraient échouer",
"PasswordConfirmation": "Confirmation du mot de passe",
"UpdaterLogFiles": "Journaux du programme de mise à jour"
}

View File

@@ -1042,7 +1042,7 @@
"DownloadClientTagHelpText": "השתמש באינדקסר זה רק לסרטים שתואמים לתויות. השאר ריק כדי לחפש את כל הסרטים.",
"RemoveSelectedItemsQueueMessageText": "האם אתה בטוח שברצונך להסיר את {0} פריט {1} מהתור?",
"DeleteConditionMessageText": "האם אתה בטוח שברצונך למחוק את התג '{0}'?",
"DeleteCustomFormatMessageText": "האם אתה בטוח שברצונך למחוק את האינדקס '{0}'?",
"DeleteCustomFormatMessageText": "האם אתה בטוח שברצונך למחוק את האינדקס '{customFormatName}'?",
"DeleteDelayProfileMessageText": "האם אתה בטוח שברצונך למחוק פרופיל עיכוב זה?",
"ResetAPIKeyMessageText": "האם אתה בטוח שברצונך לאפס את מפתח ה- API שלך?",
"DeleteSelectedIndexers": "מחק את אינדקס",

View File

@@ -242,7 +242,7 @@
"DeleteDelayProfileMessageText": "Jeste li sigurni da želite obrisati ovaj profil odgode?",
"DeleteFormatMessageText": "Jeste li sigurni da želite obrisati oznaku formata {0}?",
"DeleteImportListExclusionMessageText": "Jeste li sigurni da želite izbrisati ovu uvoznu listu isključenja?",
"DeleteCustomFormatMessageText": "Jeste li sigurni da želite obrisati oznaku formata {0}?",
"DeleteCustomFormatMessageText": "Jeste li sigurni da želite obrisati oznaku formata {customFormatName}?",
"DeleteConditionMessageText": "Jeste li sigurni da želite obrisati oznaku formata {0}?",
"RemoveSelectedItemQueueMessageText": "Jeste li sigurni da želite izbrisati stavku {0} iz reda?",
"RemoveSelectedItemsQueueMessageText": "Jeste li sigurni da želite izbrisati stavku {0} iz reda?",

View File

@@ -1098,7 +1098,7 @@
"CloneCondition": "Feltétel klónozása",
"DeleteCondition": "Feltétel törlése",
"DeleteConditionMessageText": "Biztosan törölni akarod a '{0}' feltételt?",
"DeleteCustomFormatMessageText": "Biztosan törölni akarod a/az '{0}' egyéni formátumot?",
"DeleteCustomFormatMessageText": "Biztosan törölni akarod a/az '{customFormatName}' egyéni formátumot?",
"RemoveSelectedItemsQueueMessageText": "Biztosan el akar távolítani {0} elemet a várólistáról?",
"RemoveSelectedItemQueueMessageText": "Biztosan el akar távolítani 1 elemet a várólistáról?",
"ApiKeyValidationHealthCheckMessage": "Kérlek frissítsd az API kulcsot, ami legalább {length} karakter hosszú. Ezt megteheted a Beállításokban, vagy a config file-ban",

View File

@@ -1,6 +1,6 @@
{
"AuthBasic": "Dasar (Popup Browser)",
"AuthForm": "Formulir (Halaman Login)",
"AuthForm": "Formulir (Halaman Masuk)",
"Authentication": "Autentikasi",
"AuthenticationMethodHelpText": "Perlukan Nama Pengguna dan Sandi untuk mengakses {appName}",
"About": "Tentang",
@@ -15,7 +15,7 @@
"AllMoviesHiddenDueToFilter": "Semua film disembunyikan karena penyaringan yang diterapkan.",
"Apply": "Terapkan",
"AllMoviesInPathHaveBeenImported": "Semua film di {0} telah diimpor",
"AlreadyInYourLibrary": "Sudah ada di pustaka kamu",
"AlreadyInYourLibrary": "Sudah di pustakamu",
"Always": "Selalu",
"AnalyseVideoFiles": "Analisis berkas video",
"Analytics": "Analitik",
@@ -60,7 +60,7 @@
"Info": "Informasi",
"Movie": "Film",
"Blocklisted": "Daftar Blokir",
"Connections": "Koleksi",
"Connections": "Koneksi",
"Indexer": "Pengindeks",
"Actions": "Tindakan",
"Backup": "Cadangan",
@@ -75,7 +75,7 @@
"Hostname": "Hostname",
"IMDb": "IMDb",
"NetCore": ".NET",
"Connection": "Koleksi",
"Connection": "Koneksi",
"ImportCustomFormat": "Tambahkan Format Khusus",
"ConnectionLost": "Koneksi Terputus",
"CopyToClipboard": "Salin ke Papan Klip",
@@ -99,7 +99,7 @@
"ProxyCheckBadRequestMessage": "Gagal menguji proxy. Kode Status: {statusCode}",
"ProxyCheckFailedToTestMessage": "Gagal menguji proxy: {url}",
"Queue": "Antrean",
"LogFiles": "Berkas Log",
"LogFiles": "File Log",
"Metadata": "Metadata",
"Monitored": "Dimonitor",
"NoChange": "Tidak Ada Perubahan",
@@ -116,5 +116,47 @@
"Profiles": "Profil",
"Disabled": "Nonaktif",
"BlocklistReleaseHelpText": "Mencegah {appName} memperoleh rilis ini secara otomatis",
"ConnectionLostReconnect": "{appName} akan mencoba untuk menghubungi secara otomatis, atau klik muat ulang di bawah."
"ConnectionLostReconnect": "{appName} akan mencoba untuk menghubungkan secara otomatis, atau silakan klik muat ulang di bawah.",
"Sunday": "Minggu",
"ConnectSettings": "Pengaturan Koneksi",
"FormatAgeDays": "hari",
"FormatAgeDay": "hari",
"FormatDateTimeRelative": "{relativeDay}, {formattedDate} {formattedTime}",
"FormatRuntimeMinutes": "{minutes}mnt",
"Week": "Minggu",
"Monday": "Senin",
"Refresh": "Muat Ulang",
"ApplyChanges": "Terapkan Perubahan",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Konfirmasi sandi baru",
"ConnectSettingsSummary": "Notifikasi, koneksi ke server/pemutar media, dan script khusus",
"CouldNotFindResults": "Tidak ditemukan hasil untuk '{term}'",
"Edit": "Edit",
"Files": "File",
"FormatAgeMinutes": "menit",
"FormatTimeSpanDays": "{days}h {time}",
"FormatShortTimeSpanMinutes": "{minutes} menit",
"History": "Riwayat",
"Unmonitored": "Tidak Dimonitor",
"Yesterday": "Kemarin",
"Connect": "Koneksi",
"AllTitles": "Semua Judul",
"Day": "Hari",
"Month": "Bulan",
"AllFiles": "Semua File",
"AddNew": "Tambah",
"Agenda": "Agenda",
"Search": "Cari",
"AuthenticationRequired": "Autentikasi Diperlukan",
"ClickToChangeReleaseGroup": "Klik untuk mengubah rilis grup",
"AuthenticationRequiredWarning": "Untuk mencegah akses jarak jauh tanpa autentikasi, {appName} kini mewajibkan pengaktifkan autentikasi. Kamu dapat menonaktifkan autentikasi dari jaringan lokal.",
"AudioLanguages": "Bahasa Audio",
"Today": "Hari Ini",
"TotalFileSize": "Jumlah Ukuran File",
"AuthenticationMethod": "Metode Autentikasi",
"AuthenticationMethodHelpTextWarning": "Silakan pilih metode autentikasi yang sah",
"AuthenticationRequiredPasswordHelpTextWarning": "Masukkan sandi baru",
"AuthenticationRequiredUsernameHelpTextWarning": "Masukkan nama pengguna baru",
"AutoRedownloadFailed": "Pengunduhan Ulang Gagal",
"ConnectionLostToBackend": "Koneksi {appName} telah terputus dari backend dan perlu dimuat ulang untuk dipulihkan.",
"Links": "Tautan"
}

View File

@@ -1059,7 +1059,7 @@
"ApplyTagsHelpTextReplace": "Sostituire: Sostituisce le etichette con quelle inserite (non inserire nessuna etichette per eliminarle tutte)",
"DownloadClientTagHelpText": "Usa questo indicizzatore per i film con almeno un tag corrispondente. Lascia in bianco per usarlo con tutti i film.",
"DeleteConditionMessageText": "Sei sicuro di voler eliminare la condizione '{0}'?",
"DeleteCustomFormatMessageText": "Sei sicuro di voler eliminare il formato personalizzato '{0}'?",
"DeleteCustomFormatMessageText": "Sei sicuro di voler eliminare il formato personalizzato '{customFormatName}'?",
"DeleteDelayProfileMessageText": "Sei sicuro di voler cancellare questo profilo di ritardo?",
"DeleteFormatMessageText": "Sei sicuro di voler cancellare il formato etichetta {0} ?",
"DeleteImportListExclusionMessageText": "Sei sicuro di voler cancellare questa lista di esclusioni delle importazioni?",

View File

@@ -1001,7 +1001,7 @@
"RssSyncHelpText": "간격 (분)입니다. 사용하지 않으려면 0으로 설정합니다 (모든 자동 릴리스 잡기가 중지됨).",
"File": "파일",
"DeleteRemotePathMapping": "원격 경로 매핑 편집",
"DeleteCustomFormatMessageText": "인덱서 '{0}'을 (를) 삭제 하시겠습니까?",
"DeleteCustomFormatMessageText": "인덱서 '{customFormatName}'을 (를) 삭제 하시겠습니까?",
"DeleteDelayProfileMessageText": "이 지연 프로필을 삭제하시겠습니까?",
"ResetAPIKeyMessageText": "API 키를 재설정하시겠습니까?",
"DeleteConditionMessageText": "'{0}' 태그를 삭제하시겠습니까?",

View File

@@ -244,7 +244,7 @@
"PreferredProtocol": "Foretrukket Protokoll",
"Reset": "Tilbakestill",
"DeleteConditionMessageText": "Er du sikker på at du vil slette formattaggen {0}?",
"DeleteCustomFormatMessageText": "Er du sikker på at du vil slette formattaggen {0}?",
"DeleteCustomFormatMessageText": "Er du sikker på at du vil slette formattaggen {customFormatName}?",
"DeleteDelayProfileMessageText": "Er du sikker på at du vil slette denne forsinkelsesprofilen?",
"DeleteFormatMessageText": "Er du sikker på at du vil slette formattaggen {0}?",
"DeleteImportListExclusionMessageText": "Er du sikker på at du vil slette denne ekskluderingen av importlister?",

View File

@@ -58,7 +58,7 @@
"AddNewTmdbIdMessage": "Je kunt ook zoeken met het TMDb id van een film. Bijv. tmdb:71663",
"AddNewMessage": "Het is gemakkelijk om een nieuwe film toe te voegen, begin gewoon met de naam te typen van de film die je wilt toevoegen",
"AddNew": "Nieuwe toevoegen",
"AddExclusion": "Uitzondering(en) Toevoegen",
"AddExclusion": "Uitzondering toevoegen",
"AddMovies": "Film(s) Toevoegen",
"Activity": "Activiteit",
"About": "Over",
@@ -303,7 +303,7 @@
"AuthenticationMethodHelpText": "Gebruikersnaam en wachtwoord nodig voor toegang tot {appName}",
"Authentication": "Authenticatie",
"AppDataDirectory": "AppData folder",
"AddImportExclusionHelpText": "Voorkom dat een film wordt toegevoegd door een lijst",
"AddImportExclusionHelpText": "Voorkom dat film wordt toegevoegd aan {appName} door een lijst",
"AgeWhenGrabbed": "Leeftijd (op moment van ophalen)",
"AnalyticsEnabledHelpText": "Stuur anonieme gebruiks- en foutinformatie naar de servers van {appName}. Dit omvat informatie over uw browser, welke {appName} WebUI pagina's u gebruikt, foutrapportage en OS en runtime versie. We zullen deze informatie gebruiken om prioriteiten te stellen voor functies en het verhelpen van fouten.",
"AllowHardcodedSubsHelpText": "Gedetecteerde ingebrande ondertiteling zal automatisch worden gedownload",
@@ -311,7 +311,7 @@
"AlreadyInYourLibrary": "Reeds in uw bibliotheek",
"AllowHardcodedSubs": "Sta Ingebrande Ondertiteling Toe",
"YesCancel": "Ja, Annuleren",
"AddListExclusion": "Toevoegen aan Uitzonderingenlijst",
"AddListExclusion": "Lijst uitzondering toevoegen",
"CleanLibraryLevel": "Bibliotheek Opschonen Niveau",
"DeleteTag": "Verwijder Tag",
"DeleteSelectedMovieFiles": "Verwijder Geselecteerde Filmbestanden",
@@ -760,7 +760,7 @@
"Announced": "Aangekondigd",
"Always": "Altijd",
"AllResultsHiddenFilter": "Alle resultaten zijn verborgen door de toegepaste filter",
"AllMoviesInPathHaveBeenImported": "Alle films in {0} zijn geïmporteerd",
"AllMoviesInPathHaveBeenImported": "Alle films in {path} zijn geïmporteerd",
"AllFiles": "Alle bestanden",
"AfterManualRefresh": "Na handmatig verversen",
"AddToDownloadQueue": "Toegevoegd aan downloadwachtrij",
@@ -1106,7 +1106,7 @@
"DeleteSelectedIndexers": "Verwijder Indexeerder",
"ResetAPIKeyMessageText": "Bent u zeker dat u uw API-sleutel wilt resetten?",
"DeleteConditionMessageText": "Bent u zeker dat u de lijst '{0}' wilt verwijderen?",
"DeleteCustomFormatMessageText": "Bent u zeker dat u de indexeerder '{0}' wilt verwijderen?",
"DeleteCustomFormatMessageText": "Bent u zeker dat u de indexeerder '{customFormatName}' wilt verwijderen?",
"DeleteFormatMessageText": "Weet je zeker dat je formaat tag {0} wilt verwijderen?",
"DeleteImportListExclusionMessageText": "Bent u zeker dat u dit van de uitzonderingenlijst wilt verwijderen?",
"RemoveSelectedItemsQueueMessageText": "Weet je zeker dat je {0} van de wachtrij wilt verwijderen?",
@@ -1132,5 +1132,11 @@
"AddIndexerImplementation": "Indexeerder toevoegen - {implementationName}",
"DeleteQualityProfileMessageText": "Bent u zeker dat u het kwaliteitsprofiel {name} wilt verwijderen?",
"AppUpdated": "{appName} is geüpdatet",
"AppUpdatedVersion": "{appName} is geüpdatet naar versie '{version}', om de laatste wijzigingen door te voeren moet je mogelijk {appName} herstarten"
"AppUpdatedVersion": "{appName} is geüpdatet naar versie '{version}', om de laatste wijzigingen door te voeren moet je mogelijk {appName} herstarten",
"AuthenticationRequired": "Verificatie vereist",
"AddImportList": "Importlijst toevoegen",
"AddImportListImplementation": "Importlijst toevoegen - {implementationName}",
"AudioLanguages": "Audiotalen",
"AuthenticationMethodHelpTextWarning": "Selecteer een geldige verificatie methode",
"AuthenticationMethod": "Authenticatiemethode"
}

View File

@@ -1092,7 +1092,7 @@
"DeleteSelectedDownloadClients": "Usuń klienta pobierania",
"DeleteSelectedIndexers": "Usuń indeksator",
"DeleteConditionMessageText": "Czy na pewno chcesz usunąć tag „{0}”?",
"DeleteCustomFormatMessageText": "Czy na pewno chcesz usunąć indeksator „{0}”?",
"DeleteCustomFormatMessageText": "Czy na pewno chcesz usunąć indeksator „{customFormatName}”?",
"DeleteDelayProfileMessageText": "Czy na pewno chcesz usunąć ten profil opóźnienia?",
"DeleteFormatMessageText": "Czy na pewno chcesz usunąć tag formatu {0}?",
"DeleteImportListExclusionMessageText": "Czy na pewno chcesz usunąć to wykluczenie listy importu?",

View File

@@ -1112,7 +1112,7 @@
"ApplyTagsHelpTextRemove": "Remover: eliminar as etiquetas adicionadas",
"ApplyTagsHelpTextReplace": "Substituir: mudar as etiquetas pelas adicionadas (deixe em branco para limpar todas as etiquetas)",
"DeleteConditionMessageText": "Tem a certeza de que pretende eliminar a condição '{name}'?",
"DeleteCustomFormatMessageText": "Tem a certeza de que pretende eliminar o formato personalizado '{name}'?",
"DeleteCustomFormatMessageText": "Tem a certeza de que pretende eliminar o formato personalizado '{customFormatName}'?",
"DeleteSelectedDownloadClients": "Eliminar cliente de transferências",
"DeleteSelectedImportLists": "Eliminar lista de importação",
"AddAutoTag": "Adicionar Etiqueta Automática",

View File

@@ -182,7 +182,7 @@
"DownloadClientsSettingsSummary": "Clientes de download, gerenciamento de download e mapeamentos de caminhos remotos",
"DownloadClientSettings": "Configurações do cliente de download",
"DownloadClients": "Clientes de download",
"DownloadClientCheckUnableToCommunicateMessage": "Não é possível se comunicar com {downloadClientName}.",
"DownloadClientCheckUnableToCommunicateMessage": "Não foi possível comunicar com {downloadClientName}. {errorMessage}",
"DownloadClientCheckNoneAvailableMessage": "Nenhum cliente de download está disponível",
"DownloadClient": "Cliente de download",
"DoNotUpgradeAutomatically": "Não atualizar automaticamente",
@@ -292,7 +292,7 @@
"ChmodGroupHelpTextWarning": "Isso só funciona se o usuário que está executando o {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download use o mesmo grupo que o {appName}.",
"ChmodGroupHelpText": "Nome ou ID do grupo. Use a ID para sistemas de arquivos remotos.",
"ChmodGroup": "Grupo chmod",
"ChmodFolderHelpTextWarning": "Isso só funciona se o usuário que está executando o {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download defina as permissões corretamente.",
"ChmodFolderHelpTextWarning": "Isso só funciona se o usuário que executa {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download defina as permissões corretamente.",
"ChmodFolderHelpText": "Octal, aplicado durante a importação/renomeação de pastas e arquivos de mídia (sem bits de execução)",
"ChmodFolder": "Fazer chmod de pasta",
"CheckForFinishedDownloadsInterval": "Verifique o intervalo de downloads concluídos",
@@ -588,7 +588,7 @@
"TimeFormat": "Formato da Hora",
"Time": "Tempo",
"ThisCannotBeCancelled": "Isso não pode ser cancelado uma vez iniciado sem desabilitar todos os seus indexadores.",
"TheLogLevelDefault": "O nível de registro é padronizado como \"Informações\" e pode ser alterado em",
"TheLogLevelDefault": "O nível de registro é padronizado como 'Info' e pode ser alterado em [Configurações Gerais](/settings/general)",
"TestAllLists": "Testar todas as listas",
"TestAllIndexers": "Testar todos os indexadores",
"TestAllClients": "Testar todos os clientes",
@@ -908,7 +908,7 @@
"UpdateSelected": "Atualizar Selecionada",
"UpdateScriptPathHelpText": "Caminho para um script personalizado que usa um pacote de atualização extraído e lida com o restante do processo de atualização",
"Updates": "Atualizações",
"UpdateMechanismHelpText": "Usar o atualizador integrado do {appName} ou um script",
"UpdateMechanismHelpText": "Use o atualizador integrado do {appName} ou um script",
"UpdateCheckUINotWritableMessage": "Não é possível instalar a atualização porque a pasta de IU '{startupFolder}' não pode ser gravada pelo usuário '{userName}'.",
"UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{startupFolder}' está em uma pasta de translocação de aplicativo.",
"UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{startupFolder}' não pode ser gravada pelo usuário '{userName}'.",
@@ -1014,7 +1014,7 @@
"RemoveFromBlocklist": "Remover da lista de bloqueio",
"BlocklistReleases": "Lançamentos na lista de bloqueio",
"RemoveSelectedItems": "Remover itens selecionados",
"IndexerTagHelpText": "Usar este indexador apenas para filmes com pelo menos uma tag correspondente. Deixe em branco para usar com todos os filmes.",
"IndexerTagHelpText": "Use este indexador apenas para filmes com pelo menos uma etiqueta correspondente. Deixe em branco para usar com todos os filmes.",
"RemoveSelectedItem": "Remover item selecionado",
"RemoveFailed": "Falha na remoção",
"RemoveCompleted": "Remoção Concluída",
@@ -1119,7 +1119,7 @@
"DeleteRemotePathMappingMessageText": "Tem certeza de que deseja excluir este mapeamento de caminho remoto?",
"DeleteCondition": "Excluir condição",
"CloneCondition": "Clonar Condição",
"DeleteCustomFormatMessageText": "Tem certeza de que deseja excluir o formato personalizado '{name}'?",
"DeleteCustomFormatMessageText": "Tem certeza de que deseja excluir o formato personalizado '{customFormatName}'?",
"DeleteDelayProfileMessageText": "Tem certeza de que deseja excluir este perfil de atraso?",
"DeleteFormatMessageText": "Tem certeza de que deseja excluir a etiqueta de formato {0} ?",
"RemoveSelectedItemQueueMessageText": "Tem certeza de que deseja remover 1 item da fila?",
@@ -1251,7 +1251,7 @@
"Parse": "Analisar",
"ParseModalErrorParsing": "Erro ao analisar, tente novamente.",
"ParseModalHelpText": "Insira um título de lançamento na entrada acima",
"ParseModalHelpTextDetails": "O {appName} tentará analisar o título e mostrar detalhes sobre ele",
"ParseModalHelpTextDetails": "{appName} tentará analisar o título e mostrar detalhes sobre ele",
"QualitiesLoadError": "Não foi possível carregar qualidades",
"SelectDropdown": "Selecionar...",
"SelectFolderModalTitle": "{modalTitle} - Selecione a Pasta",
@@ -1260,7 +1260,7 @@
"True": "Verdadeiro",
"HealthMessagesInfoBox": "Para saber mais sobre a causa dessas mensagens de verificação de integridade, clique no link da wiki (ícone de livro) no final da linha ou verifique os [logs]({link}). Se tiver dificuldade em interpretar essas mensagens, entre em contato com nosso suporte nos links abaixo.",
"DefaultNameCopiedProfile": "{name} - Cópia",
"InvalidUILanguage": "A interface está configurada com um idioma inválido, corrija-o e salve as configurações",
"InvalidUILanguage": "Sua UI está definida com um idioma inválido, corrija-a e salve suas configurações",
"AuthenticationMethod": "Método de autenticação",
"AuthenticationMethodHelpTextWarning": "Selecione um método de autenticação válido",
"AuthenticationRequiredPasswordHelpTextWarning": "Digite uma nova senha",
@@ -1334,5 +1334,17 @@
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Procure e tente baixar automaticamente uma versão diferente quando a versão com falha for obtida pela pesquisa interativa",
"AutoRedownloadFailed": "Falha no Novo Download",
"QueueFilterHasNoItems": "O filtro de fila selecionado não possui itens",
"EnableProfile": "Habilitar Perfil"
"EnableProfile": "Habilitar Perfil",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirme a nova senha",
"ClearBlocklist": "Limpar lista de bloqueio",
"ClearBlocklistMessageText": "Tem certeza de que deseja limpar todos os itens da lista de bloqueio?",
"FailedToFetchUpdates": "Falha ao buscar atualizações",
"FailedToUpdateSettings": "Falha ao atualizar as configurações",
"LogFilesLocation": "Os arquivos de log estão localizados em: {location}",
"PasswordConfirmation": "Confirmação Da Senha",
"PackageVersionInfo": "{packageVersion} por {packageAuthor}",
"PreviouslyInstalled": "Instalado anteriormente",
"UpdaterLogFiles": "Arquivos de log do atualizador",
"InteractiveSearchModalHeader": "Pesquisa Interativa",
"WhySearchesCouldBeFailing": "Clique aqui para descobrir por que as pesquisas podem estar falhando"
}

Some files were not shown because too many files have changed in this diff Show More