Convert Add Movie from collection to TypeScript

This commit is contained in:
Bogdan 2025-04-19 13:51:18 +03:00
parent 7e34d89069
commit 52a69b662d
45 changed files with 379 additions and 399 deletions

View file

@ -79,9 +79,9 @@ class AddNewMovieModalContent extends Component {
}
<div className={styles.info}>
<div className={styles.overview}>
{overview}
</div>
{overview ? (
<div className={styles.overview}>{overview}</div>
) : null}
<Form>
<FormGroup>
@ -98,7 +98,9 @@ class AddNewMovieModalContent extends Component {
movieFolder: folder,
isWindows
}}
helpText={translate('SubfolderWillBeCreatedAutomaticallyInterp', [folder])}
helpText={translate('AddNewMovieRootFolderHelpText', {
folder
})}
onChange={onInputChange}
{...rootFolderPath}
/>

View file

@ -1,6 +1,7 @@
import AppSectionState, {
AppSectionFilterState,
AppSectionSaveState,
Error,
} from 'App/State/AppSectionState';
import MovieCollection from 'typings/MovieCollection';
@ -10,6 +11,9 @@ interface MovieCollectionAppState
AppSectionSaveState {
itemMap: Record<number, number>;
isAdding: boolean;
addError: Error;
pendingChanges: Partial<MovieCollection>;
}

View file

@ -1,31 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import AddNewCollectionMovieModalContentConnector from './AddNewCollectionMovieModalContentConnector';
function AddNewCollectionMovieModal(props) {
const {
isOpen,
onModalClose,
...otherProps
} = props;
return (
<Modal
isOpen={isOpen}
onModalClose={onModalClose}
>
<AddNewCollectionMovieModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
</Modal>
);
}
AddNewCollectionMovieModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default AddNewCollectionMovieModal;

View file

@ -1,204 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import CheckInput from 'Components/Form/CheckInput';
import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import SpinnerButton from 'Components/Link/SpinnerButton';
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 { inputTypes, kinds } from 'Helpers/Props';
import MoviePoster from 'Movie/MoviePoster';
import translate from 'Utilities/String/translate';
import styles from './AddNewCollectionMovieModalContent.css';
class AddNewCollectionMovieModalContent extends Component {
//
// Listeners
onQualityProfileIdChange = ({ value }) => {
this.props.onInputChange({ name: 'qualityProfileId', value: parseInt(value) });
};
onAddMoviePress = () => {
this.props.onAddMoviePress();
};
//
// Render
render() {
const {
title,
year,
overview,
images,
isAdding,
folder,
tags,
isSmallScreen,
isWindows,
onModalClose,
onInputChange,
rootFolderPath,
monitor,
qualityProfileId,
minimumAvailability,
searchForMovie
} = this.props;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{title}
{
!title.contains(year) && !!year &&
<span className={styles.year}>({year})</span>
}
</ModalHeader>
<ModalBody>
<div className={styles.container}>
{
!isSmallScreen &&
<div className={styles.poster}>
<MoviePoster
className={styles.poster}
images={images}
size={250}
/>
</div>
}
<div className={styles.info}>
<div className={styles.overview}>
{overview}
</div>
<Form>
<FormGroup>
<FormLabel>{translate('RootFolder')}</FormLabel>
<FormInputGroup
type={inputTypes.ROOT_FOLDER_SELECT}
name="rootFolderPath"
valueOptions={{
movieFolder: folder,
isWindows
}}
selectedValueOptions={{
movieFolder: folder,
isWindows
}}
helpText={translate('SubfolderWillBeCreatedAutomaticallyInterp', [folder])}
onChange={onInputChange}
{...rootFolderPath}
/>
</FormGroup>
<FormGroup>
<FormLabel>
{translate('Monitor')}
</FormLabel>
<FormInputGroup
type={inputTypes.MONITOR_MOVIES_SELECT}
name="monitor"
onChange={onInputChange}
{...monitor}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('MinimumAvailability')}</FormLabel>
<FormInputGroup
type={inputTypes.AVAILABILITY_SELECT}
name="minimumAvailability"
onChange={onInputChange}
{...minimumAvailability}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('QualityProfile')}</FormLabel>
<FormInputGroup
type={inputTypes.QUALITY_PROFILE_SELECT}
name="qualityProfileId"
onChange={this.onQualityProfileIdChange}
{...qualityProfileId}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('Tags')}</FormLabel>
<FormInputGroup
type={inputTypes.TAG}
name="tags"
onChange={onInputChange}
{...tags}
/>
</FormGroup>
</Form>
</div>
</div>
</ModalBody>
<ModalFooter className={styles.modalFooter}>
<label className={styles.searchForMissingMovieLabelContainer}>
<span className={styles.searchForMissingMovieLabel}>
{translate('StartSearchForMissingMovie')}
</span>
<CheckInput
containerClassName={styles.searchForMissingMovieContainer}
className={styles.searchForMissingMovieInput}
name="searchForMovie"
onChange={onInputChange}
{...searchForMovie}
/>
</label>
<SpinnerButton
className={styles.addButton}
kind={kinds.SUCCESS}
isSpinning={isAdding}
onPress={this.onAddMoviePress}
>
{translate('AddMovie')}
</SpinnerButton>
</ModalFooter>
</ModalContent>
);
}
}
AddNewCollectionMovieModalContent.propTypes = {
title: PropTypes.string.isRequired,
year: PropTypes.number.isRequired,
overview: PropTypes.string,
images: PropTypes.arrayOf(PropTypes.object).isRequired,
isAdding: PropTypes.bool.isRequired,
addError: PropTypes.object,
rootFolderPath: PropTypes.object,
monitor: PropTypes.object.isRequired,
qualityProfileId: PropTypes.object,
minimumAvailability: PropTypes.object.isRequired,
searchForMovie: PropTypes.object.isRequired,
folder: PropTypes.string.isRequired,
tags: PropTypes.object.isRequired,
isSmallScreen: PropTypes.bool.isRequired,
isWindows: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired,
onInputChange: PropTypes.func.isRequired,
onAddMoviePress: PropTypes.func.isRequired
};
export default AddNewCollectionMovieModalContent;

View file

@ -1,121 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { addMovie, setMovieCollectionValue } from 'Store/Actions/movieCollectionActions';
import createCollectionSelector from 'Store/Selectors/createCollectionSelector';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector';
import selectSettings from 'Store/Selectors/selectSettings';
import AddNewMovieModalContent from './AddNewCollectionMovieModalContent';
function createMapStateToProps() {
return createSelector(
(state) => state.movieCollections,
createCollectionSelector(),
createDimensionsSelector(),
createSystemStatusSelector(),
(discoverMovieState, collection, dimensions, systemStatus) => {
const {
isAdding,
addError,
pendingChanges
} = discoverMovieState;
const collectionDefaults = {
rootFolderPath: collection.rootFolderPath,
monitor: 'movieOnly',
qualityProfileId: collection.qualityProfileId,
minimumAvailability: collection.minimumAvailability,
searchForMovie: collection.searchOnAdd,
tags: collection.tags || []
};
const {
settings,
validationErrors,
validationWarnings
} = selectSettings(collectionDefaults, pendingChanges, addError);
return {
isAdding,
addError,
isSmallScreen: dimensions.isSmallScreen,
validationErrors,
validationWarnings,
isWindows: systemStatus.isWindows,
...settings
};
}
);
}
const mapDispatchToProps = {
addMovie,
setMovieCollectionValue
};
class AddNewCollectionMovieModalContentConnector extends Component {
//
// Listeners
onInputChange = ({ name, value }) => {
this.props.setMovieCollectionValue({ name, value });
};
onAddMoviePress = () => {
const {
tmdbId,
title,
rootFolderPath,
monitor,
qualityProfileId,
minimumAvailability,
searchForMovie,
tags
} = this.props;
this.props.addMovie({
tmdbId,
title,
rootFolderPath: rootFolderPath.value,
monitor: monitor.value,
qualityProfileId: qualityProfileId.value,
minimumAvailability: minimumAvailability.value,
searchForMovie: searchForMovie.value,
tags: tags.value
});
this.props.onModalClose(true);
};
//
// Render
render() {
return (
<AddNewMovieModalContent
{...this.props}
onInputChange={this.onInputChange}
onAddMoviePress={this.onAddMoviePress}
/>
);
}
}
AddNewCollectionMovieModalContentConnector.propTypes = {
tmdbId: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
rootFolderPath: PropTypes.object,
monitor: PropTypes.object.isRequired,
qualityProfileId: PropTypes.object,
minimumAvailability: PropTypes.object.isRequired,
searchForMovie: PropTypes.object.isRequired,
tags: PropTypes.object.isRequired,
onModalClose: PropTypes.func.isRequired,
addMovie: PropTypes.func.isRequired,
setMovieCollectionValue: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(AddNewCollectionMovieModalContentConnector);

View file

@ -0,0 +1,36 @@
import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import Modal from 'Components/Modal/Modal';
import { clearPendingChanges } from 'Store/Actions/baseActions';
import AddNewMovieCollectionMovieModalContent, {
AddNewMovieCollectionMovieModalContentProps,
} from './AddNewMovieCollectionMovieModalContent';
interface AddNewCollectionMovieModalProps
extends AddNewMovieCollectionMovieModalContentProps {
isOpen: boolean;
}
function AddNewMovieCollectionMovieModal({
isOpen,
onModalClose,
...otherProps
}: AddNewCollectionMovieModalProps) {
const dispatch = useDispatch();
const handleModalClose = useCallback(() => {
dispatch(clearPendingChanges({ section: 'movieCollections' }));
onModalClose();
}, [dispatch, onModalClose]);
return (
<Modal isOpen={isOpen} onModalClose={handleModalClose}>
<AddNewMovieCollectionMovieModalContent
{...otherProps}
onModalClose={handleModalClose}
/>
</Modal>
);
}
export default AddNewMovieCollectionMovieModal;

View file

@ -0,0 +1,269 @@
import React, { useCallback, useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import MovieMinimumAvailabilityPopoverContent from 'AddMovie/MovieMinimumAvailabilityPopoverContent';
import AppState from 'App/State/AppState';
import useMovieCollection from 'Collection/useMovieCollection';
import CheckInput from 'Components/Form/CheckInput';
import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import Icon from 'Components/Icon';
import SpinnerButton from 'Components/Link/SpinnerButton';
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 Popover from 'Components/Tooltip/Popover';
import usePrevious from 'Helpers/Hooks/usePrevious';
import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props';
import { Image } from 'Movie/Movie';
import MoviePoster from 'Movie/MoviePoster';
import {
addMovie,
setMovieCollectionValue,
} from 'Store/Actions/movieCollectionActions';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import selectSettings from 'Store/Selectors/selectSettings';
import useIsWindows from 'System/useIsWindows';
import { InputChanged } from 'typings/inputs';
import translate from 'Utilities/String/translate';
import styles from './AddNewMovieCollectionMovieModalContent.css';
export interface AddNewMovieCollectionMovieModalContentProps {
tmdbId: number;
title: string;
year: number;
overview?: string;
images: Image[];
collectionId: number;
folder: string;
onModalClose: () => void;
}
function AddNewMovieCollectionMovieModalContent({
tmdbId,
title,
year,
overview,
images,
collectionId,
folder,
onModalClose,
}: AddNewMovieCollectionMovieModalContentProps) {
const dispatch = useDispatch();
const collection = useMovieCollection(collectionId)!;
const { isSmallScreen } = useSelector(createDimensionsSelector());
const isWindows = useIsWindows();
const { isAdding, addError, pendingChanges } = useSelector(
(state: AppState) => state.movieCollections
);
const wasAdding = usePrevious(isAdding);
const { settings, validationErrors, validationWarnings } = useMemo(() => {
const options = {
rootFolderPath: collection.rootFolderPath,
monitor: collection.monitored ? 'movieOnly' : 'none',
qualityProfileId: collection.qualityProfileId,
minimumAvailability: collection.minimumAvailability,
searchForMovie: collection.searchOnAdd,
tags: collection.tags || [],
};
return selectSettings(options, pendingChanges, addError);
}, [collection, pendingChanges, addError]);
const {
monitor,
qualityProfileId,
minimumAvailability,
rootFolderPath,
searchForMovie,
tags,
} = settings;
const handleInputChange = useCallback(
({ name, value }: InputChanged) => {
// @ts-expect-error actions aren't typed
dispatch(setMovieCollectionValue({ name, value }));
},
[dispatch]
);
const handleAddMoviePress = useCallback(() => {
dispatch(
addMovie({
tmdbId,
title,
rootFolderPath: rootFolderPath.value,
monitor: monitor.value,
qualityProfileId: qualityProfileId.value,
minimumAvailability: minimumAvailability.value,
searchForMovie: searchForMovie.value,
tags: tags.value,
})
);
}, [
tmdbId,
title,
rootFolderPath,
monitor,
qualityProfileId,
minimumAvailability,
searchForMovie,
tags,
dispatch,
]);
useEffect(() => {
if (!isAdding && wasAdding && !addError) {
onModalClose();
}
}, [isAdding, wasAdding, addError, onModalClose]);
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{title}
{!title.includes(String(year)) && year ? (
<span className={styles.year}>({year})</span>
) : null}
</ModalHeader>
<ModalBody>
<div className={styles.container}>
{isSmallScreen ? null : (
<div className={styles.poster}>
<MoviePoster
className={styles.poster}
images={images}
size={250}
/>
</div>
)}
<div className={styles.info}>
{overview ? (
<div className={styles.overview}>{overview}</div>
) : null}
<Form
validationErrors={validationErrors}
validationWarnings={validationWarnings}
>
<FormGroup>
<FormLabel>{translate('RootFolder')}</FormLabel>
<FormInputGroup
type={inputTypes.ROOT_FOLDER_SELECT}
name="rootFolderPath"
valueOptions={{
movieFolder: folder,
isWindows,
}}
selectedValueOptions={{
movieFolder: folder,
isWindows,
}}
helpText={translate('AddNewMovieRootFolderHelpText', {
folder,
})}
{...rootFolderPath}
onChange={handleInputChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('Monitor')}</FormLabel>
<FormInputGroup
type={inputTypes.MONITOR_MOVIES_SELECT}
name="monitor"
{...monitor}
onChange={handleInputChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>
{translate('MinimumAvailability')}
<Popover
anchor={
<Icon className={styles.labelIcon} name={icons.INFO} />
}
title={translate('MinimumAvailability')}
body={<MovieMinimumAvailabilityPopoverContent />}
position={tooltipPositions.RIGHT}
/>
</FormLabel>
<FormInputGroup
type={inputTypes.AVAILABILITY_SELECT}
name="minimumAvailability"
{...minimumAvailability}
helpLink="https://wiki.servarr.com/radarr/faq#what-is-minimum-availability"
onChange={handleInputChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('QualityProfile')}</FormLabel>
<FormInputGroup
type={inputTypes.QUALITY_PROFILE_SELECT}
name="qualityProfileId"
{...qualityProfileId}
onChange={handleInputChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('Tags')}</FormLabel>
<FormInputGroup
type={inputTypes.TAG}
name="tags"
{...tags}
onChange={handleInputChange}
/>
</FormGroup>
</Form>
</div>
</div>
</ModalBody>
<ModalFooter className={styles.modalFooter}>
<label className={styles.searchForMissingMovieLabelContainer}>
<span className={styles.searchForMissingMovieLabel}>
{translate('StartSearchForMissingMovie')}
</span>
<CheckInput
containerClassName={styles.searchForMissingMovieContainer}
className={styles.searchForMissingMovieInput}
name="searchForMovie"
{...searchForMovie}
onChange={handleInputChange}
/>
</label>
<SpinnerButton
className={styles.addButton}
kind={kinds.SUCCESS}
isSpinning={isAdding}
onPress={handleAddMoviePress}
>
{translate('AddMovie')}
</SpinnerButton>
</ModalFooter>
</ModalContent>
);
}
export default AddNewMovieCollectionMovieModalContent;

View file

@ -1,12 +1,12 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import AddNewMovieCollectionMovieModal from 'Collection/AddNewMovieCollectionMovieModal';
import Link from 'Components/Link/Link';
import MonitorToggleButton from 'Components/MonitorToggleButton';
import EditMovieModal from 'Movie/Edit/EditMovieModal';
import MovieIndexProgressBar from 'Movie/Index/ProgressBar/MovieIndexProgressBar';
import MoviePoster from 'Movie/MoviePoster';
import translate from 'Utilities/String/translate';
import AddNewCollectionMovieModal from './../AddNewCollectionMovieModal';
import styles from './CollectionMovie.css';
class CollectionMovie extends Component {
@ -160,7 +160,7 @@ class CollectionMovie extends Component {
</Link>
</div>
<AddNewCollectionMovieModal
<AddNewMovieCollectionMovieModal
isOpen={isNewAddMovieModalOpen && !isExistingMovie}
tmdbId={tmdbId}
title={title}
@ -188,7 +188,7 @@ CollectionMovie.propTypes = {
title: PropTypes.string.isRequired,
year: PropTypes.number.isRequired,
status: PropTypes.string.isRequired,
overview: PropTypes.string.isRequired,
overview: PropTypes.string,
monitored: PropTypes.bool,
collectionId: PropTypes.number.isRequired,
hasFile: PropTypes.bool,

View file

@ -2,6 +2,8 @@ import ModelBase from 'App/ModelBase';
import Language from 'Language/Language';
import { MovieFile } from 'MovieFile/MovieFile';
export type MovieMonitor = 'movieOnly' | 'movieAndCollection' | 'none';
export type MovieStatus =
| 'tba'
| 'announced'
@ -48,6 +50,11 @@ export interface AlternativeTitle extends ModelBase {
title: string;
}
export interface MovieAddOptions {
monitor: MovieMonitor;
searchForMovie: boolean;
}
interface Movie extends ModelBase {
tmdbId: number;
imdbId?: string;
@ -87,6 +94,7 @@ interface Movie extends ModelBase {
lastSearchTime?: string;
isAvailable: boolean;
isSaving?: boolean;
addOptions: MovieAddOptions;
}
export default Movie;

View file

@ -250,8 +250,7 @@ export const actionHandlers = handleThunks({
[ADD_MOVIE]: function(getState, payload, dispatch) {
dispatch(set({ section, isAdding: true }));
const tmdbId = payload.tmdbId;
const title = payload.title;
const { tmdbId, title } = payload;
const newMovie = getNewMovie({ tmdbId, title }, payload);
newMovie.id = 0;

View file

@ -0,0 +1,8 @@
import { useSelector } from 'react-redux';
import AppState from 'App/State/AppState';
function useIsWindows() {
return useSelector((state: AppState) => state.system.status.item.isWindows);
}
export default useIsWindows;

View file

@ -1,17 +1,27 @@
import Movie, { MovieAvailability, MovieMonitor } from 'Movie/Movie';
function getNewMovie(movie, payload) {
interface NewMoviePayload {
rootFolderPath: string;
monitor: MovieMonitor;
qualityProfileId: number;
minimumAvailability: MovieAvailability;
tags: number[];
searchForMovie?: boolean;
}
function getNewMovie(movie: Movie, payload: NewMoviePayload) {
const {
rootFolderPath,
monitor,
qualityProfileId,
minimumAvailability,
tags,
searchForMovie = false
searchForMovie = false,
} = payload;
const addOptions = {
monitor,
searchForMovie
searchForMovie,
};
movie.addOptions = addOptions;

View file

@ -494,7 +494,7 @@
"System": "النظام",
"Sunday": "الأحد",
"SuggestTranslationChange": "اقترح تغيير الترجمة",
"SubfolderWillBeCreatedAutomaticallyInterp": "سيتم إنشاء المجلد الفرعي \"{0}\" تلقائيًا",
"AddNewMovieRootFolderHelpText": "سيتم إنشاء المجلد الفرعي \"{0}\" تلقائيًا",
"Style": "أسلوب",
"Studio": "ستوديو",
"Status": "الحالة",

View file

@ -549,7 +549,7 @@
"Status": "Състояние",
"Studio": "Студио",
"Style": "Стил",
"SubfolderWillBeCreatedAutomaticallyInterp": "Подпапката „{0}“ ще бъде създадена автоматично",
"AddNewMovieRootFolderHelpText": "Подпапката „{0}“ ще бъде създадена автоматично",
"Sunday": "Неделя",
"Table": "Таблица",
"TableOptions": "Опции на таблицата",

View file

@ -840,7 +840,7 @@
"Status": "Estat",
"Studio": "Estudi",
"Style": "Estil",
"SubfolderWillBeCreatedAutomaticallyInterp": "La subcarpeta '{0}' es crearà automàticament",
"AddNewMovieRootFolderHelpText": "La subcarpeta '{0}' es crearà automàticament",
"SuggestTranslationChange": "Suggereix un canvi de traducció",
"Sunday": "Diumenge",
"System": "Sistema",

View file

@ -107,7 +107,7 @@
"StartImport": "Spusťte import",
"Status": "Postavení",
"Studio": "Studio",
"SubfolderWillBeCreatedAutomaticallyInterp": "Podsložka „{0}“ bude vytvořena automaticky",
"AddNewMovieRootFolderHelpText": "Podsložka „{0}“ bude vytvořena automaticky",
"ICalTagsMoviesHelpText": "Platí pro filmy s alespoň jednou shodnou značkou",
"TorrentDelayTime": "Torrent Delay: {0}",
"Trakt": "Trakt",

View file

@ -824,7 +824,7 @@
"Status": "Status",
"Studio": "Studio",
"Style": "Stil",
"SubfolderWillBeCreatedAutomaticallyInterp": "Undermappen '{0}' oprettes automatisk",
"AddNewMovieRootFolderHelpText": "Undermappen '{0}' oprettes automatisk",
"Sunday": "Søndag",
"Table": "Tabel",
"TableOptions": "Tabelindstillinger",

View file

@ -579,7 +579,7 @@
"WaitingToImport": "Warten auf Import",
"UpgradeUntilThisQualityIsMetOrExceeded": "Führe ein Upgrade durch, bis diese Qualität erreicht oder überschritten wird",
"TagCannotBeDeletedWhileInUse": "Kann während der Benutzung nicht gelöscht werden",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' Unterordner wird automatisch erstellt",
"AddNewMovieRootFolderHelpText": "'{0}' Unterordner wird automatisch erstellt",
"SslCertPathHelpText": "Pfad zur PFX Datei",
"SslCertPasswordHelpText": "Passwort für die PFX Datei",
"ShowYear": "Jahr anzeigen",

View file

@ -826,7 +826,7 @@
"Status": "Κατάσταση",
"Studio": "Στούντιο",
"Style": "Στυλ",
"SubfolderWillBeCreatedAutomaticallyInterp": "Ο υποφάκελος \"{0}\" θα δημιουργηθεί αυτόματα",
"AddNewMovieRootFolderHelpText": "Ο υποφάκελος \"{0}\" θα δημιουργηθεί αυτόματα",
"Sunday": "Κυριακή",
"Table": "Τραπέζι",
"TableOptions": "Επιλογές πίνακα",

View file

@ -35,6 +35,7 @@
"AddNew": "Add New",
"AddNewMessage": "It's easy to add a new movie, just start typing the name of the movie you want to add",
"AddNewMovie": "Add New Movie",
"AddNewMovieRootFolderHelpText": "'{folder}' subfolder will be created automatically",
"AddNewRestriction": "Add new restriction",
"AddNewTmdbIdMessage": "You can also search using TMDb Id of a movie. e.g. 'tmdb:71663'",
"AddNotificationError": "Unable to add a new notification, please try again.",
@ -1831,7 +1832,6 @@
"StopSelecting": "Stop Selecting",
"Studio": "Studio",
"Style": "Style",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' subfolder will be created automatically",
"SubtitleLanguages": "Subtitle Languages",
"SuggestTranslationChange": "Suggest translation change",
"Sunday": "Sunday",

View file

@ -581,7 +581,7 @@
"WaitingToImport": "Esperar para importar",
"UpgradeUntilThisQualityIsMetOrExceeded": "Actualizar hasta que esta calidad sea alcanzada o excedida",
"TagCannotBeDeletedWhileInUse": "No se puede eliminar estando en uso",
"SubfolderWillBeCreatedAutomaticallyInterp": "La subcarpeta '{0}' se creará automáticamente",
"AddNewMovieRootFolderHelpText": "La subcarpeta '{0}' se creará automáticamente",
"SslCertPathHelpText": "Ruta del archivo pfx",
"SslCertPasswordHelpText": "Contraseña para archivo pfx",
"ShowYear": "Mostrar Año",

View file

@ -828,7 +828,7 @@
"Status": "Tila",
"Studio": "Studio",
"Style": "Ulkoasu",
"SubfolderWillBeCreatedAutomaticallyInterp": "Alikansio '{0}' luodaan automaattisesti",
"AddNewMovieRootFolderHelpText": "Alikansio '{0}' luodaan automaattisesti",
"Sunday": "Sunnuntai",
"Table": "Taulukko",
"TableOptions": "Taulukkonäkymän asetukset",

View file

@ -596,7 +596,7 @@
"TestAllClients": "Tester tous les clients",
"TagCannotBeDeletedWhileInUse": "Ne peut pas être supprimé pendant l'utilisation",
"SuggestTranslationChange": "Suggérer un changement de traduction",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' le sous-dossier sera créé automatiquement",
"AddNewMovieRootFolderHelpText": "'{0}' le sous-dossier sera créé automatiquement",
"StartupDirectory": "Répertoire de démarrage",
"StandardMovieFormat": "Format de film standard",
"SslPort": "Port SSL",

View file

@ -828,7 +828,7 @@
"Status": "סטָטוּס",
"Studio": "סטוּדִיוֹ",
"Style": "סִגְנוֹן",
"SubfolderWillBeCreatedAutomaticallyInterp": "תיקיית המשנה '{0}' תיווצר באופן אוטומטי",
"AddNewMovieRootFolderHelpText": "תיקיית המשנה '{0}' תיווצר באופן אוטומטי",
"Sunday": "יוֹם רִאשׁוֹן",
"Table": "שולחן",
"TableOptions": "אפשרויות טבלה",

View file

@ -211,7 +211,7 @@
"SslCertPath": "एसएसएल सर्टिफिकेट पाथ",
"StandardMovieFormat": "मानक मूवी प्रारूप",
"StartSearchForMissingMovie": "लापता फिल्म की खोज शुरू करें",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' सबफ़ोल्डर स्वचालित रूप से बनाया जाएगा",
"AddNewMovieRootFolderHelpText": "'{0}' सबफ़ोल्डर स्वचालित रूप से बनाया जाएगा",
"TableColumnsHelpText": "चुनें कि कौन से कॉलम दिखाई दे रहे हैं और वे किस क्रम में दिखाई देते हैं",
"TagDetails": "टैग विवरण - {0}",
"TagIsNotUsedAndCanBeDeleted": "टैग का उपयोग नहीं किया जाता है और इसे हटाया जा सकता है",

View file

@ -238,7 +238,7 @@
"EnableColorImpairedMode": "Engedélyezze a színtévesztő módot",
"System": "Rendszer",
"SuggestTranslationChange": "Javasolj fordítási változtatást",
"SubfolderWillBeCreatedAutomaticallyInterp": "A(z) „{0}” almappa automatikusan létrehozásra kerül",
"AddNewMovieRootFolderHelpText": "A(z) „{0}” almappa automatikusan létrehozásra kerül",
"Style": "Stílus",
"Studio": "Stúdió",
"Status": "Állapot",

View file

@ -837,7 +837,7 @@
"StartSearchForMissingMovie": "Byrjaðu að leita að kvikmynd sem vantar",
"Studio": "Stúdíó",
"Style": "Stíll",
"SubfolderWillBeCreatedAutomaticallyInterp": "„{0}“ undirmöppan verður búin til sjálfkrafa",
"AddNewMovieRootFolderHelpText": "„{0}“ undirmöppan verður búin til sjálfkrafa",
"Sunday": "Sunnudag",
"Table": "Tafla",
"TableOptions": "Borðvalkostir",

View file

@ -664,7 +664,7 @@
"TagCannotBeDeletedWhileInUse": "Non può essere cancellato mentre è in uso",
"Table": "Tabella",
"SuggestTranslationChange": "Suggerisci un cambio nella traduzione",
"SubfolderWillBeCreatedAutomaticallyInterp": "La sottocartella '{0}' verrà creata automaticamente",
"AddNewMovieRootFolderHelpText": "La sottocartella '{0}' verrà creata automaticamente",
"StartupDirectory": "Cartella di Avvio",
"FileBrowserPlaceholderText": "Comincia a digitare o seleziona un percorso sotto",
"StandardMovieFormat": "Formato Film Standard",

View file

@ -824,7 +824,7 @@
"Status": "状態",
"Studio": "スタジオ",
"Style": "スタイル",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{0}'サブフォルダは自動的に作成されます",
"AddNewMovieRootFolderHelpText": "'{0}'サブフォルダは自動的に作成されます",
"Sunday": "日曜日",
"Table": "テーブル",
"TableOptions": "テーブルオプション",

View file

@ -832,7 +832,7 @@
"Status": "상태",
"Studio": "스튜디오",
"Style": "스타일",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' 하위 폴더가 자동으로 생성됩니다",
"AddNewMovieRootFolderHelpText": "'{0}' 하위 폴더가 자동으로 생성됩니다",
"Sunday": "일요일",
"Table": "테이블",
"TableColumnsHelpText": "표시되는 열과 표시되는 순서를 선택하세요",

View file

@ -587,7 +587,7 @@
"WaitingToImport": "Wachten tot Importeren",
"UpgradeUntilThisQualityIsMetOrExceeded": "Bijwerken totdat deze kwaliteit is behaald of overschreden",
"TagCannotBeDeletedWhileInUse": "Kan niet verwijderd worden terwijl in gebruik",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' submap zal automatisch worden aangemaakt",
"AddNewMovieRootFolderHelpText": "'{0}' submap zal automatisch worden aangemaakt",
"SslCertPathHelpText": "Pad naar pfx bestand",
"SslCertPasswordHelpText": "Wachtwoord voor pfx bestand",
"ShowYear": "Toon Jaar",

View file

@ -838,7 +838,7 @@
"Status": "Status",
"Studio": "Studio",
"Style": "Styl",
"SubfolderWillBeCreatedAutomaticallyInterp": "Podfolder „{0}” zostanie utworzony automatycznie",
"AddNewMovieRootFolderHelpText": "Podfolder „{0}” zostanie utworzony automatycznie",
"Sunday": "niedziela",
"Table": "Stół",
"TableOptions": "Opcje tabeli",

View file

@ -611,7 +611,7 @@
"TestAllClients": "Testar todos os clientes",
"ICalTagsMoviesHelpText": "Aplica-se a filmes com pelo menos uma etiqueta correspondente",
"TagIsNotUsedAndCanBeDeleted": "A etiqueta não é utilizada e pode ser eliminada",
"SubfolderWillBeCreatedAutomaticallyInterp": "A subpasta \"{0}\" será criada automaticamente",
"AddNewMovieRootFolderHelpText": "A subpasta \"{0}\" será criada automaticamente",
"FileBrowserPlaceholderText": "Começa a digitar ou seleciona um caminho abaixo",
"StandardMovieFormat": "Formato padrão de filme",
"SslCertPathHelpText": "Caminho para o ficheiro PFX",

View file

@ -602,7 +602,7 @@
"System": "Sistema",
"Sunday": "Domingo",
"SuggestTranslationChange": "Sugerir mudança de tradução",
"SubfolderWillBeCreatedAutomaticallyInterp": "A subpasta \"{0}\" será criada automaticamente",
"AddNewMovieRootFolderHelpText": "A subpasta \"{0}\" será criada automaticamente",
"Style": "Estilo",
"Studio": "Studio",
"Status": "Status",

View file

@ -866,7 +866,7 @@
"StartImport": "Porniți importul",
"StartProcessing": "Începeți procesarea",
"StartSearchForMissingMovie": "Începeți căutarea filmului lipsă",
"SubfolderWillBeCreatedAutomaticallyInterp": "Subfolderul „{0}” va fi creat automat",
"AddNewMovieRootFolderHelpText": "Subfolderul „{0}” va fi creat automat",
"Sunday": "duminică",
"Table": "Tabel",
"TagDetails": "Detalii etichetă - {0}",

View file

@ -853,7 +853,7 @@
"System": "Система",
"Sunday": "Воскресенье",
"SuggestTranslationChange": "Предложить изменение перевода",
"SubfolderWillBeCreatedAutomaticallyInterp": "Подпапка \"{0}\" будет создана автоматически",
"AddNewMovieRootFolderHelpText": "Подпапка \"{0}\" будет создана автоматически",
"Style": "Стиль",
"Studio": "Студия",
"Status": "Статус",

View file

@ -277,7 +277,7 @@
"DeleteQualityProfileMessageText": "Naozaj chcete zmazať tento profil oneskorenia?",
"DeleteReleaseProfileMessageText": "Naozaj chcete zmazať tento profil oneskorenia?",
"EditIndexerImplementation": "Pridať Indexer - {implementationName}",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{folder}' podpriečinok sa vytvorí automaticky",
"AddNewMovieRootFolderHelpText": "'{folder}' podpriečinok sa vytvorí automaticky",
"DeleteFormatMessageText": "Naozaj chcete zmazať značku formátu {0} ?",
"DownloadClientSettingsRecentPriority": "Priorita klienta",
"EditReleaseProfile": "Pridať profil vydania",

View file

@ -888,7 +888,7 @@
"SslCertPath": "SSL-certifierad sökväg",
"SslPort": "SSL-port",
"StandardMovieFormat": "Standardfilmformat",
"SubfolderWillBeCreatedAutomaticallyInterp": "Undermappen \"{0}\" skapas automatiskt",
"AddNewMovieRootFolderHelpText": "Undermappen \"{0}\" skapas automatiskt",
"TagDetails": "Taggdetaljer - {0}",
"TagIsNotUsedAndCanBeDeleted": "Taggen används inte och kan raderas",
"ICalTagsMoviesHelpText": "Gäller filmer med minst en matchande tagg",

View file

@ -855,7 +855,7 @@
"Status": "สถานะ",
"Studio": "สตูดิโอ",
"Style": "สไตล์",
"SubfolderWillBeCreatedAutomaticallyInterp": "โฟลเดอร์ย่อย \"{0}\" จะถูกสร้างขึ้นโดยอัตโนมัติ",
"AddNewMovieRootFolderHelpText": "โฟลเดอร์ย่อย \"{0}\" จะถูกสร้างขึ้นโดยอัตโนมัติ",
"Sunday": "วันอาทิตย์",
"TableOptions": "ตัวเลือกตาราง",
"TagDetails": "รายละเอียดแท็ก - {0}",

View file

@ -287,7 +287,7 @@
"StandardMovieFormat": "Standart Film Formatı",
"StartImport": "İçe Aktarmayı Başlat",
"StartSearchForMissingMovie": "Kayıp filmi aramaya başlayın",
"SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' alt klasörü otomatik olarak oluşturulacak",
"AddNewMovieRootFolderHelpText": "'{0}' alt klasörü otomatik olarak oluşturulacak",
"Sunday": "Pazar",
"Table": "Tablo",
"TableOptions": "Tablo Seçenekleri",

View file

@ -848,7 +848,7 @@
"Status": "Статус",
"Studio": "Студія",
"Style": "Стиль",
"SubfolderWillBeCreatedAutomaticallyInterp": "Вкладена папка \"{0}\" буде створена автоматично",
"AddNewMovieRootFolderHelpText": "Вкладена папка \"{0}\" буде створена автоматично",
"SuggestTranslationChange": "Запропонуйте зміну перекладу",
"SystemTimeHealthCheckMessage": "Системний час вимкнено більш ніж на 1 день. Заплановані завдання можуть не працювати належним чином, доки час не буде виправлено",
"Table": "Таблиця",

View file

@ -868,7 +868,7 @@
"StartImport": "Bắt đầu nhập",
"Status": "Trạng thái",
"Style": "Phong cách",
"SubfolderWillBeCreatedAutomaticallyInterp": "Thư mục con '{0}' sẽ được tạo tự động",
"AddNewMovieRootFolderHelpText": "Thư mục con '{0}' sẽ được tạo tự động",
"Sunday": "chủ nhật",
"Table": "Bàn",
"TableOptions": "Tùy chọn bảng",

View file

@ -726,7 +726,7 @@
"UpdateCheckUINotWritableMessage": "无法安装更新,因为用户 “{userName}” 对 UI 文件夹 “{uiFolder}” 无写入权限。",
"ShowMonitoredHelpText": "在海报下显示追踪状态",
"PosterSize": "海报大小",
"SubfolderWillBeCreatedAutomaticallyInterp": "“{0}” 子文件夹将自动创建",
"AddNewMovieRootFolderHelpText": "“{0}” 子文件夹将自动创建",
"Queued": "队列中",
"WhatsNew": "什么是新的?",
"ReleaseGroup": "发布组",