Your ROOT_URL in app.ini is https://git.cloudchain.link/ but you are visiting https://dash.bss.nz/open-source-mirrors/Radarr/commit/43a0e75acfa2db113d8e0c4cad760fcdce86aca0
You should set ROOT_URL correctly, otherwise the web may not work correctly.
38 changed files with
267 additions and
163 deletions
@ -1,9 +1,12 @@
import InteractiveImportAppState from 'App/State/InteractiveImportAppState' ;
import CommandAppState from './CommandAppState' ;
import MovieCollectionAppState from './MovieCollectionAppState' ;
import MovieFilesAppState from './MovieFilesAppState' ;
import MoviesAppState , { MovieIndexAppState } from './MoviesAppState' ;
import ParseAppState from './ParseAppState' ;
import QueueAppState from './QueueAppState' ;
import SettingsAppState from './SettingsAppState' ;
import SystemAppState from './SystemAppState' ;
import TagsAppState from './TagsAppState' ;
interface FilterBuilderPropOption {
@ -39,14 +42,17 @@ export interface CustomFilter {
}
interface AppState {
movieFiles: MovieFiles AppState;
commands: Command AppState;
interactiveImport : InteractiveImportAppState ;
movieCollections : MovieCollectionAppState ;
movieFiles : MovieFilesAppState ;
movieIndex : MovieIndexAppState ;
movies : MoviesAppState ;
parse : ParseAppState ;
queue : QueueAppState ;
settings : SettingsAppState ;
movies: Movies AppState;
system: System AppState;
tags : TagsAppState ;
queue : QueueAppState ;
}
export default AppState ;
@ -0,0 +1,6 @@
import AppSectionState from 'App/State/AppSectionState' ;
import Command from 'Commands/Command' ;
export type CommandAppState = AppSectionState < Command > ;
export default CommandAppState ;
@ -0,0 +1,6 @@
import AppSectionState from 'App/State/AppSectionState' ;
import MovieCollection from 'typings/MovieCollection' ;
type MovieCollectionAppState = AppSectionState < MovieCollection > ;
export default MovieCollectionAppState ;
@ -1,5 +1,6 @@
import AppSectionState , {
AppSectionDeleteState ,
AppSectionItemState ,
AppSectionSaveState ,
AppSectionSchemaState ,
} from 'App/State/AppSectionState' ;
@ -41,17 +42,17 @@ export interface RootFolderAppState
AppSectionSaveState { }
export type LanguageSettingsAppState = AppSectionState < Language > ;
export type UiSettingsAppState = AppSection State< UiSettings > ;
export type UiSettingsAppState = AppSection Item State< UiSettings > ;
interface SettingsAppState {
downloadClients : DownloadClientAppState ;
importLists : ImportListAppState ;
indexers : IndexerAppState ;
language : LanguageSettingsAppState ;
language s : LanguageSettingsAppState ;
notifications : NotificationAppState ;
qualityProfiles : QualityProfilesAppState ;
rootFolders : RootFolderAppState ;
ui Settings : UiSettingsAppState ;
ui : UiSettingsAppState ;
}
export default SettingsAppState ;
@ -0,0 +1,10 @@
import SystemStatus from 'typings/SystemStatus' ;
import { AppSectionItemState } from './AppSectionState' ;
export type SystemStatusAppState = AppSectionItemState < SystemStatus > ;
interface SystemAppState {
status : SystemStatusAppState ;
}
export default SystemAppState ;
@ -1,12 +1,32 @@
import ModelBase from 'App/ModelBase' ;
import AppSectionState , {
AppSectionDeleteState ,
AppSectionSaveState ,
} from 'App/State/AppSectionState' ;
export interface Tag extends ModelBase {
label : string ;
}
interface TagsAppState extends AppSectionState < Tag > , AppSectionDeleteState { }
export interface TagDetail extends ModelBase {
label : string ;
autoTagIds : number [ ] ;
delayProfileIds : number [ ] ;
downloadClientIds : number [ ] ;
importListIds : number [ ] ;
indexerIds : number [ ] ;
movieIds : number [ ] ;
notificationIds : number [ ] ;
restrictionIds : number [ ] ;
}
export interface TagDetailAppState
extends AppSectionState < TagDetail > ,
AppSectionDeleteState ,
AppSectionSaveState { }
interface TagsAppState extends AppSectionState < Tag > , AppSectionDeleteState {
details : TagDetailAppState ;
}
export default TagsAppState ;
@ -4,6 +4,7 @@ import { useSelector } from 'react-redux';
import { icons } from 'Helpers/Props' ;
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector' ;
import dimensions from 'Styles/Variables/dimensions' ;
import QualityProfile from 'typings/QualityProfile' ;
import { UiSettings } from 'typings/UiSettings' ;
import formatDateTime from 'Utilities/Date/formatDateTime' ;
import getRelativeDate from 'Utilities/Date/getRelativeDate' ;
@ -33,7 +34,7 @@ interface MovieIndexOverviewInfoProps {
showSizeOnDisk : boolean ;
monitored : boolean ;
studio? : string ;
qualityProfile : object ;
qualityProfile ?: QualityProfile ;
added? : string ;
path : string ;
sizeOnDisk? : number ;
@ -100,13 +101,10 @@ function getInfoRowProps(
} ;
}
if ( name === 'qualityProfileId' ) {
if ( name === 'qualityProfileId' && ! ! props . qualityProfile ? . name ) {
return {
title : 'Quality Profile' ,
iconName : icons.PROFILE ,
// TODO: Type QualityProfile
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore ts(2339)
label : props.qualityProfile.name ,
} ;
}
@ -229,7 +229,7 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
< / div >
) : null }
{ showQualityProfile ? (
{ showQualityProfile && ! ! qualityProfile ? . name ? (
< div className = { styles . title } title = { translate ( 'QualityProfile' ) } >
{ qualityProfile . name }
< / div >
@ -14,7 +14,7 @@ import styles from './MovieIndexPosterInfo.css';
interface MovieIndexPosterInfoProps {
studio? : string ;
showQualityProfile : boolean ;
qualityProfile : QualityProfile ;
qualityProfile ? : QualityProfile ;
added? : string ;
year : number ;
inCinemas? : string ;
@ -68,7 +68,11 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) {
) ;
}
if ( sortKey === 'qualityProfileId' && ! showQualityProfile ) {
if (
sortKey === 'qualityProfileId' &&
! showQualityProfile &&
! ! qualityProfile ? . name
) {
return (
< div className = { styles . info } title = { translate ( 'QualityProfile' ) } >
{ qualityProfile . name }
@ -210,7 +210,7 @@ function MovieIndexRow(props: MovieIndexRowProps) {
if ( name === 'qualityProfileId' ) {
return (
< VirtualTableRowCell key = { name } className = { styles [ name ] } >
{ qualityProfile . name }
{ qualityProfile ? . name ? ? '' }
< / VirtualTableRowCell >
) ;
}
@ -35,7 +35,7 @@ interface Movie extends ModelBase {
titleSlug : string ;
collection : Collection ;
studio : string ;
qualityProfile : object ;
qualityProfile Id: number ;
added : string ;
year : number ;
inCinemas : string ;
@ -1,8 +1,9 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createAllMoviesSelector() {
return createSelector (
( state ) = > state . movies ,
( state : AppState ) = > state . movies ,
( movies ) = > {
return movies . items ;
}
@ -2,13 +2,10 @@ import { createSelector } from 'reselect';
import { isCommandExecuting } from 'Utilities/Command' ;
import createCommandSelector from './createCommandSelector' ;
function createCommandExecutingSelector ( name , contraints = { } ) {
return createSelector (
createCommandSelector ( name , contraints ) ,
( command ) = > {
return isCommandExecuting ( command ) ;
}
) ;
function createCommandExecutingSelector ( name : string , contraints = { } ) {
return createSelector ( createCommandSelector ( name , contraints ) , ( command ) = > {
return isCommandExecuting ( command ) ;
} ) ;
}
export default createCommandExecutingSelector ;
@ -1,14 +0,0 @@
import { createSelector } from 'reselect' ;
import { findCommand } from 'Utilities/Command' ;
import createCommandsSelector from './createCommandsSelector' ;
function createCommandSelector ( name , contraints = { } ) {
return createSelector (
createCommandsSelector ( ) ,
( commands ) => {
return findCommand ( commands , { name , ... contraints } ) ;
}
) ;
}
export default createCommandSelector ;
@ -0,0 +1,11 @@
import { createSelector } from 'reselect' ;
import { findCommand } from 'Utilities/Command' ;
import createCommandsSelector from './createCommandsSelector' ;
function createCommandSelector ( name : string , contraints = { } ) {
return createSelector ( createCommandsSelector ( ) , ( commands ) = > {
return findCommand ( commands , { name , . . . contraints } ) ;
} ) ;
}
export default createCommandSelector ;
@ -1,8 +1,9 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createCommandsSelector() {
return createSelector (
( state ) = > state . commands ,
( state : AppState ) = > state . commands ,
( commands ) = > {
return commands . items ;
}
@ -1,9 +0,0 @@
import _ from 'lodash' ;
import { createSelectorCreator , defaultMemoize } from 'reselect' ;
const createDeepEqualSelector = createSelectorCreator (
defaultMemoize ,
_ . isEqual
) ;
export default createDeepEqualSelector ;
@ -0,0 +1,6 @@
import { isEqual } from 'lodash' ;
import { createSelectorCreator , defaultMemoize } from 'reselect' ;
const createDeepEqualSelector = createSelectorCreator ( defaultMemoize , isEqual ) ;
export default createDeepEqualSelector ;
@ -1,9 +1,10 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
import { isCommandExecuting } from 'Utilities/Command' ;
function createExecutingCommandsSelector() {
return createSelector (
( state ) = > state . commands . items ,
( state : AppState ) = > state . commands . items ,
( commands ) = > {
return commands . filter ( ( command ) = > isCommandExecuting ( command ) ) ;
}
@ -1,13 +1,14 @@
import _ from 'lodash' ;
import { some } from 'lodash' ;
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
import createAllMoviesSelector from './createAllMoviesSelector' ;
function createExistingMovieSelector() {
return createSelector (
( state, { tmdbId } ) = > tmdbId ,
( _: AppState , { tmdbId } : { tmdbId : number } ) = > tmdbId ,
createAllMoviesSelector ( ) ,
( tmdbId , movies ) = > {
return _. some( movies , { tmdbId } ) ;
return some( movies , { tmdbId } ) ;
}
) ;
}
@ -1,27 +0,0 @@
import { createSelector } from 'reselect' ;
function createLanguagesSelector ( ) {
return createSelector (
( state ) => state . settings . languages ,
( languages ) => {
const {
isFetching ,
isPopulated ,
error ,
items
} = languages ;
const filterItems = [ 'Any' ] ;
const filteredLanguages = items . filter ( ( lang ) => ! filterItems . includes ( lang . name ) ) ;
return {
isFetching ,
isPopulated ,
error ,
items : filteredLanguages
} ;
}
) ;
}
export default createLanguagesSelector ;
@ -0,0 +1,25 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createLanguagesSelector() {
return createSelector (
( state : AppState ) = > state . settings . languages ,
( languages ) = > {
const { isFetching , isPopulated , error , items } = languages ;
const filterItems = [ 'Any' ] ;
const filteredLanguages = items . filter (
( lang ) = > ! filterItems . includes ( lang . name )
) ;
return {
isFetching ,
isPopulated ,
error ,
items : filteredLanguages ,
} ;
}
) ;
}
export default createLanguagesSelector ;
@ -1,18 +1,19 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
import createAllMoviesSelector from './createAllMoviesSelector' ;
function createMovieCountSelector() {
return createSelector (
createAllMoviesSelector ( ) ,
( state ) = > state . movies . error ,
( state ) = > state . movies . isFetching ,
( state ) = > state . movies . isPopulated ,
( state : AppState ) = > state . movies . error ,
( state : AppState ) = > state . movies . isFetching ,
( state : AppState ) = > state . movies . isPopulated ,
( movies , error , isFetching , isPopulated ) = > {
return {
count : movies.length ,
error ,
isFetching ,
isPopulated
isPopulated ,
} ;
}
) ;
@ -1,9 +1,10 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createMovieFileSelector() {
return createSelector (
( state, { movieFileId } ) = > movieFileId ,
( state ) = > state . movieFiles ,
( _: AppState , { movieFileId } : { movieFileId : number } ) = > movieFileId ,
( state : AppState ) = > state . movieFiles ,
( movieFileId , movieFiles ) = > {
if ( ! movieFileId ) {
return ;
@ -1,16 +0,0 @@
import { createSelector } from 'reselect' ;
import { createMovieSelectorForHook } from './createMovieSelector' ;
function createMovieQualityProfileSelector ( movieId ) {
return createSelector (
( state ) => state . settings . qualityProfiles . items ,
createMovieSelectorForHook ( movieId ) ,
( qualityProfiles , movie = { } ) => {
return qualityProfiles . find ( ( profile ) => {
return profile . id === movie . qualityProfileId ;
} ) ;
}
) ;
}
export default createMovieQualityProfileSelector ;
@ -0,0 +1,18 @@
import { createSelector } from 'reselect' ;
import appState from 'App/State/AppState' ;
import Movie from 'Movie/Movie' ;
import { createMovieSelectorForHook } from './createMovieSelector' ;
function createMovieQualityProfileSelector ( movieId : number ) {
return createSelector (
( state : appState ) = > state . settings . qualityProfiles . items ,
createMovieSelectorForHook ( movieId ) ,
( qualityProfiles , movie = { } as Movie ) = > {
return qualityProfiles . find (
( profile ) = > profile . id === movie . qualityProfileId
) ;
}
) ;
}
export default createMovieQualityProfileSelector ;
@ -1,25 +0,0 @@
import _ from 'lodash' ;
import { createSelector } from 'reselect' ;
import createAllMoviesSelector from './createAllMoviesSelector' ;
function createProfileInUseSelector ( profileProp ) {
return createSelector (
( state , { id } ) => id ,
createAllMoviesSelector ( ) ,
( state ) => state . settings . importLists . items ,
( state ) => state . movieCollections . items ,
( id , movies , lists , collections ) => {
if ( ! id ) {
return false ;
}
if ( _ . some ( movies , { [ profileProp ] : id } ) || _ . some ( lists , { [ profileProp ] : id } ) || _ . some ( collections , { [ profileProp ] : id } ) ) {
return true ;
}
return false ;
}
) ;
}
export default createProfileInUseSelector ;
@ -0,0 +1,31 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
import Movie from 'Movie/Movie' ;
import ImportList from 'typings/ImportList' ;
import MovieCollection from 'typings/MovieCollection' ;
import createAllMoviesSelector from './createAllMoviesSelector' ;
function createProfileInUseSelector ( profileProp : string ) {
return createSelector (
( _ : AppState , { id } : { id : number } ) = > id ,
createAllMoviesSelector ( ) ,
( state : AppState ) = > state . settings . importLists . items ,
( state : AppState ) = > state . movieCollections . items ,
( id , movies , lists , collections ) = > {
if ( ! id ) {
return false ;
}
return (
movies . some ( ( m ) = > m [ profileProp as keyof Movie ] === id ) ||
lists . some ( ( list ) = > list [ profileProp as keyof ImportList ] === id ) ||
collections . some (
( collection ) = >
collection [ profileProp as keyof MovieCollection ] === id
)
) ;
}
) ;
}
export default createProfileInUseSelector ;
@ -1,26 +0,0 @@
import { createSelector } from 'reselect' ;
export function createQualityProfileSelectorForHook ( qualityProfileId ) {
return createSelector (
( state ) => state . settings . qualityProfiles . items ,
( qualityProfiles ) => {
return qualityProfiles . find ( ( profile ) => {
return profile . id === qualityProfileId ;
} ) ;
}
) ;
}
function createQualityProfileSelector ( ) {
return createSelector (
( state , { qualityProfileId } ) => qualityProfileId ,
( state ) => state . settings . qualityProfiles . items ,
( qualityProfileId , qualityProfiles ) => {
return qualityProfiles . find ( ( profile ) => {
return profile . id === qualityProfileId ;
} ) ;
}
) ;
}
export default createQualityProfileSelector ;
@ -0,0 +1,24 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
export function createQualityProfileSelectorForHook ( qualityProfileId : number ) {
return createSelector (
( state : AppState ) = > state . settings . qualityProfiles . items ,
( qualityProfiles ) = > {
return qualityProfiles . find ( ( profile ) = > profile . id === qualityProfileId ) ;
}
) ;
}
function createQualityProfileSelector() {
return createSelector (
( _ : AppState , { qualityProfileId } : { qualityProfileId : number } ) = >
qualityProfileId ,
( state : AppState ) = > state . settings . qualityProfiles . items ,
( qualityProfileId , qualityProfiles ) = > {
return qualityProfiles . find ( ( profile ) = > profile . id === qualityProfileId ) ;
}
) ;
}
export default createQualityProfileSelector ;
@ -1,17 +1,16 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createQueueItemSelector() {
return createSelector (
( state, { movieId } ) = > movieId ,
( state ) = > state . queue . details . items ,
( _: AppState , { movieId } : { movieId : number } ) = > movieId ,
( state : AppState ) = > state . queue . details . items ,
( movieId , details ) = > {
if ( ! movieId || ! details ) {
return null ;
}
return details . find ( ( item ) = > {
return item . movieId === movieId ;
} ) ;
return details . find ( ( item ) = > item . movieId === movieId ) ;
}
) ;
}
@ -1,8 +1,9 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createSystemStatusSelector() {
return createSelector (
( state ) = > state . system . status ,
( state : AppState ) = > state . system . status ,
( status ) = > {
return status . item ;
}
@ -1,9 +1,10 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createTagDetailsSelector() {
return createSelector (
( state, { id } ) = > id ,
( state ) = > state . tags . details . items ,
( _: AppState , { id } : { id : number } ) = > id ,
( state : AppState ) = > state . tags . details . items ,
( id , tagDetails ) = > {
return tagDetails . find ( ( t ) = > t . id === id ) ;
}
@ -1,8 +1,9 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createTagsSelector() {
return createSelector (
( state ) = > state . tags . items ,
( state : AppState ) = > state . tags . items ,
( tags ) = > {
return tags ;
}
@ -1,8 +1,9 @@
import { createSelector } from 'reselect' ;
import AppState from 'App/State/AppState' ;
function createUISettingsSelector() {
return createSelector (
( state ) = > state . settings . ui ,
( state : AppState ) = > state . settings . ui ,
( ui ) = > {
return ui . item ;
}
@ -0,0 +1,17 @@
import ModelBase from 'App/ModelBase' ;
import Movie from 'Movie/Movie' ;
interface MovieCollection extends ModelBase {
title : string ;
sortTitle : string ;
tmdbId : number ;
overview : string ;
monitored : boolean ;
rootFolderPath : string ;
qualityProfileId : number ;
movies : Movie [ ] ;
missingMovies : number ;
tags : number [ ] ;
}
export default MovieCollection ;
@ -0,0 +1,31 @@
interface SystemStatus {
appData : string ;
appName : string ;
authentication : string ;
branch : string ;
buildTime : string ;
instanceName : string ;
isAdmin : boolean ;
isDebug : boolean ;
isDocker : boolean ;
isLinux : boolean ;
isNetCore : boolean ;
isOsx : boolean ;
isProduction : boolean ;
isUserInteractive : boolean ;
isWindows : boolean ;
migrationVersion : number ;
mode : string ;
osName : string ;
osVersion : string ;
packageUpdateMechanism : string ;
runtimeName : string ;
runtimeVersion : string ;
sqliteVersion : string ;
startTime : string ;
startupPath : string ;
urlBase : string ;
version : string ;
}
export default SystemStatus ;
@ -3,4 +3,5 @@ export interface UiSettings {
shortDateFormat : string ;
longDateFormat : string ;
timeFormat : string ;
movieRuntimeFormat : string ;
}