Compare commits

..

1 Commits

Author SHA1 Message Date
Qstick
edc522e412 Remove Non-Failing Rules
(cherry picked from commit e8b862a38059da4fcb5ab1ab51cf838fe5424f47)
2023-03-16 00:33:19 +00:00
1141 changed files with 9261 additions and 21269 deletions

View File

@@ -36,18 +36,9 @@ dotnet_naming_style.instance_field_style.capitalization = camel_case
dotnet_naming_style.instance_field_style.required_prefix = _
# Prefer "var" everywhere
csharp_style_var_for_built_in_types = true
csharp_style_var_when_type_is_apparent = true
csharp_style_var_elsewhere = true
# Prefer "out" variables to be declared inline
csharp_style_inlined_variable_declaration = true
# Using directive is unnecessary.
dotnet_diagnostic.IDE0005.severity = error
# Use var instead of explicit type
dotnet_diagnostic.IDE0007.severity = error
# Inline variable declaration
dotnet_diagnostic.IDE0018.severity = error
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = true:suggestion
# Stylecop Rules
dotnet_diagnostic.SA0001.severity = none
@@ -213,9 +204,6 @@ dotnet_diagnostic.CA2000.severity = suggestion
dotnet_diagnostic.CA2002.severity = suggestion
dotnet_diagnostic.CA2007.severity = suggestion
dotnet_diagnostic.CA2008.severity = suggestion
dotnet_diagnostic.CA2009.severity = suggestion
dotnet_diagnostic.CA2010.severity = suggestion
dotnet_diagnostic.CA2011.severity = suggestion
dotnet_diagnostic.CA2012.severity = suggestion
dotnet_diagnostic.CA2013.severity = suggestion
dotnet_diagnostic.CA2100.severity = suggestion
@@ -275,7 +263,7 @@ dotnet_diagnostic.CA5397.severity = suggestion
[*.{js,html,hbs,less,css,ts,tsx}]
[*.{js,html,js,hbs,less,css}]
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

9
.esprintrc Normal file
View File

@@ -0,0 +1,9 @@
{
"paths": [
"frontend/src/**/*.js"
],
"ignored": [
"**/node_modules/**/*"
],
"port": 5004
}

View File

@@ -73,10 +73,3 @@ body:
Additionally, any additional info? Screenshots? References? Anything that will give us more context about the issue you are encountering!
validations:
required: true
- type: checkboxes
attributes:
label: Trace Logs have been provided as applicable. Reports may be closed if the required logs are not provided.
description: Trace logs are generally required for all bug reports and contain `trace`. Info logs are invalid for bug reports and do not contain `debug` nor `trace`
options:
- label: I have read and followed the steps in the wiki link above and provided the required trace logs - the logs contain `trace` - that are relevant and show this issue.
required: true

28
.github/labeler.yml vendored
View File

@@ -1,28 +0,0 @@
'Area: API':
- src/Readarr.Api.V1/**/*
'Area: Db-migration':
- src/NzbDrone.Core/Datastore/Migration/*
'Area: Download Clients':
- src/NzbDrone.Core/Download/Clients/**/*
'Area: Import Lists':
- src/NzbDrone.Core/ImportLists/**/*
'Area: Indexer':
- src/NzbDrone.Core/Indexers/**/*
'Area: Notifications':
- src/NzbDrone.Core/Notifications/**/*
'Area: Organizer':
- src/NzbDrone.Core/Organizer/**/*
'Area: Parser':
- src/NzbDrone.Core/Parser/**/*
'Area: UI':
- frontend/**/*
- package.json
- yarn.lock

View File

@@ -1,12 +0,0 @@
name: "Pull Request Labeler"
on:
- pull_request_target
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4

View File

@@ -9,13 +9,13 @@ jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v4
- uses: dessant/lock-threads@v2
with:
github-token: ${{ github.token }}
issue-inactive-days: '90'
exclude-issue-created-before: ''
exclude-any-issue-labels: ''
add-issue-labels: ''
issue-comment: ''
issue-lock-inactive-days: '90'
issue-exclude-created-before: ''
issue-exclude-labels: ''
issue-lock-labels: ''
issue-lock-comment: ''
issue-lock-reason: 'resolved'
process-only: ''

View File

@@ -8,7 +8,7 @@ jobs:
support:
runs-on: ubuntu-latest
steps:
- uses: dessant/support-requests@v3
- uses: dessant/support-requests@v2
with:
github-token: ${{ github.token }}
support-label: 'Type: Support'
@@ -18,15 +18,4 @@ jobs:
to be a support request. Please hop over onto our [Discord](https://readarr.com/discord)
or [Subreddit](https://reddit.com/r/readarr)
close-issue: true
lock-issue: false
- uses: dessant/support-requests@v3
with:
github-token: ${{ github.token }}
support-label: 'Status: Logs Needed'
issue-comment: >
:wave: @{issue-author}, In order to help you further we'll need to see logs.
You'll need to enable trace logging and replicate the problem that you encountered.
Guidance on how to enable trace logging can be found in
our [troubleshooting guide](https://wiki.servarr.com/readarr/troubleshooting#logging-and-log-files).
close-issue: false
lock-issue: false
lock-issue: false

3
.gitignore vendored
View File

@@ -148,6 +148,3 @@ _temp_*/**/*
## Merge any idea folder
*/**/.idea
*.iml
# API doc generation
.config/

View File

@@ -9,14 +9,13 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '0.3.1'
majorVersion: '0.1.5'
minorVersion: $[counter('minorVersion', 1)]
readarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(readarrVersion)'
sentryOrg: 'servarr'
sentryUrl: 'https://sentry.servarr.com'
dotnetVersion: '6.0.408'
nodeVersion: '16.X'
dotnetVersion: '6.0.302'
innoVersion: '6.2.0'
windowsImage: 'windows-2022'
linuxImage: 'ubuntu-20.04'
@@ -183,7 +182,7 @@ stages:
- task: NodeTool@0
displayName: Set Node.js version
inputs:
versionSpec: $(nodeVersion)
versionSpec: '12.x'
- checkout: self
submodules: true
fetchDepth: 1
@@ -382,7 +381,7 @@ stages:
- bash: |
echo "Uploading source maps to sentry"
curl -sL https://sentry.io/get-cli/ | bash
RELEASENAME="Readarr@${READARRVERSION}-${BUILD_SOURCEBRANCHNAME}"
RELEASENAME="${READARRVERSION}-${BUILD_SOURCEBRANCHNAME}"
sentry-cli releases new --finalize -p readarr -p readarr-ui -p readarr-update "${RELEASENAME}"
sentry-cli releases -p readarr-ui files "${RELEASENAME}" upload-sourcemaps _output/UI/ --rewrite
sentry-cli releases set-commits --auto "${RELEASENAME}"
@@ -918,7 +917,7 @@ stages:
- task: NodeTool@0
displayName: Set Node.js version
inputs:
versionSpec: $(nodeVersion)
versionSpec: '12.x'
- checkout: self
submodules: true
fetchDepth: 1
@@ -956,55 +955,6 @@ stages:
cliProjectVersion: '$(readarrVersion)'
cliSources: './frontend'
- task: SonarCloudAnalyze@1
- job: Api_Docs
displayName: API Docs
condition: |
and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop'))
pool:
vmImage: ${{ variables.windowsImage }}
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
inputs:
version: $(dotnetVersion)
- checkout: self
submodules: true
persistCredentials: true
fetchDepth: 1
- bash: ./docs.sh Windows
displayName: Create openapi.json
- bash: |
git config --global user.email "development@lidarr.audio"
git config --global user.name "Servarr"
git checkout -b api-docs
git add .
git status
if git status | grep modified
then
git commit -am 'Automated API Docs update [skip ci]'
git push -f --set-upstream origin api-docs
curl -X POST -H "Authorization: token ${GITHUBTOKEN}" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/readarr/readarr/pulls -d '{"head":"api-docs","base":"develop","title":"Update API docs"}'
else
echo "No changes since last run"
fi
displayName: Commit API Doc Change
continueOnError: true
env:
GITHUBTOKEN: $(githubToken)
- task: CopyFiles@2
displayName: 'Copy openapi.json to: $(Build.ArtifactStagingDirectory)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: |
**/*openapi.json
TargetFolder: '$(Build.ArtifactStagingDirectory)/api_docs'
- publish: $(Build.ArtifactStagingDirectory)/api_docs
artifact: 'APIDocs'
displayName: Publish API Docs Bundle
condition: and(succeeded(), eq(variables['System.JobAttempt'], '1'))
- job: Analyze_Backend
displayName: Backend

38
docs.sh
View File

@@ -1,38 +0,0 @@
PLATFORM=$1
if [ "$PLATFORM" = "Windows" ]; then
RUNTIME="win-x64"
elif [ "$PLATFORM" = "Linux" ]; then
RUNTIME="linux-x64"
elif [ "$PLATFORM" = "Mac" ]; then
RUNTIME="osx-x64"
else
echo "Platform must be provided as first arguement: Windows, Linux or Mac"
exit 1
fi
outputFolder='_output'
testPackageFolder='_tests'
rm -rf $outputFolder
rm -rf $testPackageFolder
slnFile=src/Readarr.sln
platform=Posix
dotnet clean $slnFile -c Debug
dotnet clean $slnFile -c Release
dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids
dotnet new tool-manifest
dotnet tool install --version 6.5.0 Swashbuckle.AspNetCore.Cli
dotnet tool run swagger tofile --output ./src/Readarr.Api.V1/openapi.json "$outputFolder/net6.0/$RUNTIME/Readarr.console.dll" v1 &
sleep 45
kill %1
exit 0

25
frontend/.csscomb.json Normal file
View File

@@ -0,0 +1,25 @@
{
"remove-empty-rulesets": true,
"always-semicolon": true,
"color-case": "lower",
"block-indent": " ",
"color-shorthand": false,
"element-case": "lower",
"eof-newline": true,
"leading-zero": true,
"quotes": "double",
"sort-order-fallback": "abc",
"space-before-colon": "",
"space-after-colon": " ",
"space-before-combinator": " ",
"space-after-combinator": " ",
"space-between-declarations": "\n",
"space-before-opening-brace": " ",
"space-after-opening-brace": "\n",
"space-after-selector-delimiter": " ",
"space-before-selector-delimiter": "",
"space-before-closing-brace": "\n",
"strip-spaces": true,
"tab-size": true,
"unitless-zero": false
}

335
frontend/.esformatter Normal file
View File

@@ -0,0 +1,335 @@
{
"indent": {
"value": " ",
"FunctionExpression": 1,
"ArrayExpression": 1,
"ObjectExpression": 1
},
"lineBreak": {
"value": "\n",
"before": {
"ArrayPatternClosing": 0,
"ArrayPatternComma": 0,
"ArrayPatternOpening": 0,
"ArrowFunctionExpressionArrow": 0,
"ArrowFunctionExpressionClosingBrace": ">=1",
"ArrowFunctionExpressionOpeningBrace": 0,
"AssignmentExpression": ">=1",
"AssignmentOperator": 0,
"BlockStatement": 0,
"BreakKeyword": ">=1",
"CallExpression": -1,
"CallExpressionClosingParentheses": -1,
"CallExpressionOpeningParentheses": 0,
"CatchClosingBrace": ">=1",
"CatchKeyword": 0,
"CatchOpeningBrace": 0,
"ClassDeclaration": ">=1",
"ClassDeclarationClosingBrace": ">=1",
"ClassDeclarationOpeningBrace": 0,
"ConditionalExpression": ">=1",
"DeleteOperator": ">=1",
"DoWhileStatement": ">=1",
"DoWhileStatementClosingBrace": ">=1",
"DoWhileStatementOpeningBrace": 0,
"ElseIfStatement": 0,
"ElseIfStatementClosingBrace": ">=1",
"ElseIfStatementOpeningBrace": 0,
"ElseStatement": 0,
"ElseStatementClosingBrace": ">=1",
"ElseStatementOpeningBrace": 0,
"EmptyStatement": -1,
"EndOfFile": -1,
"FinallyClosingBrace": ">=1",
"FinallyKeyword": -1,
"FinallyOpeningBrace": 0,
"ForInStatement": ">=1",
"ForInStatementClosingBrace": ">=1",
"ForInStatementExpressionClosing": 0,
"ForInStatementExpressionOpening": 0,
"ForInStatementOpeningBrace": 0,
"ForStatement": ">=1",
"ForStatementClosingBrace": ">=1",
"ForStatementExpressionClosing": "<2",
"ForStatementExpressionOpening": 0,
"ForStatementOpeningBrace": 0,
"FunctionDeclaration": ">=1",
"FunctionDeclarationClosingBrace": ">=1",
"FunctionDeclarationOpeningBrace": 0,
"FunctionExpression": 0,
"FunctionExpressionClosingBrace": 1,
"FunctionExpressionOpeningBrace":0,
"IIFEClosingParentheses": 0,
"IfStatement": ">=1",
"IfStatementClosingBrace": ">=1",
"IfStatementOpeningBrace": 0,
"LogicalExpression": -1,
"MemberExpressionClosing": 0,
"MemberExpressionOpening": 0,
"MemberExpressionPeriod": -1,
"MethodDefinition": ">=1",
"ObjectExpressionClosingBrace": "<=1",
"ObjectPatternClosingBrace": 0,
"ObjectPatternComma": 0,
"ObjectPatternOpeningBrace": 0,
"ParameterDefault": 0,
"Property": "<=2",
"PropertyValue": 0,
"ReturnStatement": -1,
"SwitchClosingBrace": ">=1",
"SwitchOpeningBrace": 0,
"ThisExpression": -1,
"ThrowStatement": ">=1",
"TryClosingBrace": ">=1",
"TryKeyword": -1,
"TryOpeningBrace": 0,
"VariableDeclaration": ">=1",
"VariableDeclarationSemiColon": 0,
"VariableDeclarationWithoutInit": ">=1",
"VariableName": ">=1",
"VariableValue": 0,
"WhileStatement": ">=1",
"WhileStatementClosingBrace": ">=1",
"WhileStatementOpeningBrace": 0
},
"after": {
"ArrayPatternClosing": 0,
"ArrayPatternComma": 0,
"ArrayPatternOpening": 0,
"ArrowFunctionExpressionArrow": 0,
"ArrowFunctionExpressionClosingBrace": -1,
"ArrowFunctionExpressionOpeningBrace": ">=1",
"AssignmentExpression": ">=1",
"AssignmentOperator": 0,
"BlockStatement": 0,
"BreakKeyword": -1,
"CallExpression": -1,
"CallExpressionClosingParentheses": -1,
"CallExpressionOpeningParentheses": -1,
"CatchClosingBrace": ">=0",
"CatchKeyword": 0,
"CatchOpeningBrace": ">=1",
"ClassDeclaration": ">=1",
"ClassDeclarationClosingBrace": ">=1",
"ClassDeclarationOpeningBrace": ">=1",
"ConditionalExpression": ">=1",
"DeleteOperator": ">=1",
"DoWhileStatement": ">=1",
"DoWhileStatementClosingBrace": 0,
"DoWhileStatementOpeningBrace": ">=1",
"ElseIfStatement": ">=1",
"ElseIfStatementClosingBrace": ">=1",
"ElseIfStatementOpeningBrace": ">=1",
"ElseStatement": ">=1",
"ElseStatementClosingBrace": ">=1",
"ElseStatementOpeningBrace": ">=1",
"EmptyStatement": -1,
"FinallyClosingBrace": ">=1",
"FinallyKeyword": -1,
"FinallyOpeningBrace": ">=1",
"ForInStatement": ">=1",
"ForInStatementClosingBrace": ">=1",
"ForInStatementExpressionClosing": -1,
"ForInStatementExpressionOpening": "<2",
"ForInStatementOpeningBrace": ">=1",
"ForStatement": ">=1",
"ForStatementClosingBrace": ">=1",
"ForStatementExpressionClosing": -1,
"ForStatementExpressionOpening": "<2",
"ForStatementOpeningBrace": ">=1",
"FunctionDeclaration": ">=1",
"FunctionDeclarationClosingBrace": ">=1",
"FunctionDeclarationOpeningBrace": ">=1",
"FunctionExpression": 0,
"FunctionExpressionClosingBrace": -1,
"FunctionExpressionOpeningBrace": 1,
"IIFEOpeningParentheses": 0,
"IfStatement": ">=1",
"IfStatementClosingBrace": ">=1",
"IfStatementOpeningBrace": ">=1",
"LogicalExpression": -1,
"MemberExpressionClosing": 0,
"MemberExpressionOpening": 0,
"MemberExpressionPeriod": 0,
"MethodDefinition": ">=1",
"ObjectExpressionOpeningBrace": "<=1",
"ObjectPatternClosingBrace": 0,
"ObjectPatternComma": 0,
"ObjectPatternOpeningBrace": 0,
"ParameterDefault": 0,
"Property": -1,
"PropertyName": 0,
"ReturnStatement": -1,
"SwitchCaseColon": ">=1",
"SwitchClosingBrace": ">=1",
"SwitchOpeningBrace": ">=1",
"ThisExpression": 0,
"ThrowStatement": ">=1",
"TryClosingBrace": 0,
"TryKeyword": -1,
"TryOpeningBrace": ">=1",
"VariableDeclaration": ">=1",
"VariableDeclarationSemiColon": ">=1",
"VariableValue": -1,
"WhileStatement": ">=1",
"WhileStatementClosingBrace": ">=1",
"WhileStatementOpeningBrace": ">=1"
}
},
"whiteSpace": {
"value": " ",
"removeTrailing": 1,
"before": {
"ArgumentComma": 0,
"ArgumentList": 0,
"ArgumentListArrayExpression": 0,
"ArgumentListFunctionExpression": 1,
"ArgumentListObjectExpression": 0,
"ArrayExpressionClosing": 0,
"ArrayExpressionComma": 0,
"ArrayExpressionOpening": 1,
"AssignmentOperator": 1,
"BinaryExpression": 0,
"BinaryExpressionOperator": 1,
"BlockComment": 1,
"CallExpression": 1,
"CatchClosingBrace": 1,
"CatchKeyword": 1,
"CatchOpeningBrace": 1,
"CatchParameterList": 0,
"CommaOperator": 0,
"ConditionalExpressionAlternate": 1,
"ConditionalExpressionConsequent": 1,
"DoWhileStatementClosingBrace": 1,
"DoWhileStatementConditional": 1,
"DoWhileStatementOpeningBrace": 1,
"ElseIfStatementClosingBrace": 1,
"ElseIfStatementOpeningBrace": 1,
"ElseStatementClosingBrace": 1,
"ElseStatementOpeningBrace": 1,
"EmptyStatement": 0,
"ExpressionClosingParentheses": 0,
"FinallyClosingBrace": 1,
"FinallyKeyword": -1,
"FinallyOpeningBrace": 1,
"ForInStatement": 1,
"ForInStatementClosingBrace": 1,
"ForInStatementExpressionClosing": 0,
"ForInStatementExpressionOpening": 1,
"ForInStatementOpeningBrace": 1,
"ForStatement": 1,
"ForStatementClosingBrace": 1,
"ForStatementExpressionClosing": 0,
"ForStatementExpressionOpening": 1,
"ForStatementOpeningBrace": 1,
"ForStatementSemicolon": 0,
"FunctionDeclarationClosingBrace": 1,
"FunctionDeclarationOpeningBrace": 1,
"FunctionExpressionClosingBrace": 1,
"FunctionExpressionOpeningBrace": 1,
"IfStatementClosingBrace": 1,
"IfStatementConditionalClosing": 0,
"IfStatementConditionalOpening": 1,
"IfStatementOpeningBrace": 1,
"LineComment": 1,
"LogicalExpressionOperator": 1,
"MemberExpressionClosing": 0,
"ObjectExpressionClosingBrace": 1,
"ParameterComma": 0,
"ParameterList": 0,
"Property": 1,
"PropertyName": 1,
"PropertyValue": 1,
"SwitchDiscriminantClosing": 0,
"SwitchDiscriminantOpening": 1,
"ThrowKeyword": 1,
"TryClosingBrace": 1,
"TryKeyword": -1,
"TryOpeningBrace": 1,
"UnaryExpressionOperator": 0,
"VariableName": 1,
"VariableValue": 1,
"WhileStatementClosingBrace": 1,
"WhileStatementConditionalClosing": 0,
"WhileStatementConditionalOpening": 1,
"WhileStatementOpeningBrace": 1
},
"after": {
"ArgumentComma": 1,
"ArgumentList": 0,
"ArgumentListArrayExpression": 1,
"ArgumentListFunctionExpression": 1,
"ArgumentListObjectExpression": 0,
"ArrayExpressionClosing": 0,
"ArrayExpressionComma": 1,
"ArrayExpressionOpening": 0,
"AssignmentOperator": 1,
"BinaryExpression": 0,
"BinaryExpressionOperator": 1,
"BlockComment": 1,
"CallExpression": 0,
"CatchClosingBrace": 1,
"CatchKeyword": 1,
"CatchOpeningBrace": 1,
"CatchParameterList": 0,
"CommaOperator": 1,
"ConditionalExpressionConsequent": 1,
"ConditionalExpressionTest": 1,
"DoWhileStatementBody": 1,
"DoWhileStatementClosingBrace": 1,
"DoWhileStatementOpeningBrace": 1,
"ElseIfStatementClosingBrace": 1,
"ElseIfStatementOpeningBrace": 1,
"ElseStatementClosingBrace": 1,
"ElseStatementOpeningBrace": 1,
"EmptyStatement": 0,
"ExpressionOpeningParentheses": 0,
"FinallyClosingBrace": 1,
"FinallyKeyword": -1,
"FinallyOpeningBrace": 1,
"ForInStatement": 1,
"ForInStatementClosingBrace": 1,
"ForInStatementExpressionClosing": 1,
"ForInStatementExpressionOpening": 0,
"ForInStatementOpeningBrace": 1,
"ForStatement": 1,
"ForStatementClosingBrace": 1,
"ForStatementExpressionClosing": 1,
"ForStatementExpressionOpening": 0,
"ForStatementOpeningBrace": 1,
"ForStatementSemicolon": 1,
"FunctionDeclarationClosingBrace": 0,
"FunctionDeclarationOpeningBrace": 0,
"FunctionExpressionClosingBrace": 0,
"FunctionExpressionOpeningBrace": 0,
"FunctionName": 0,
"FunctionReservedWord": 0,
"IfStatementClosingBrace": 1,
"IfStatementConditionalClosing": 0,
"IfStatementConditionalOpening": 0,
"IfStatementOpeningBrace": 1,
"LogicalExpressionOperator": 1,
"MemberExpressionOpening": 0,
"ObjectExpressionClosingBrace": 0,
"ObjectExpressionOpeningBrace": 1,
"ParameterComma": 1,
"ParameterList": 0,
"PropertyName": 0,
"PropertyValue": 0,
"SwitchDiscriminantClosing": 1,
"SwitchDiscriminantOpening": 0,
"ThrowKeyword": 1,
"TryClosingBrace": 1,
"TryKeyword": -1,
"TryOpeningBrace": 1,
"UnaryExpressionOperator": 0,
"VariableName": 1,
"WhileStatementClosingBrace": 1,
"WhileStatementConditionalClosing": 1,
"WhileStatementConditionalOpening": 0,
"WhileStatementOpeningBrace": 1
}
}
}

View File

@@ -1,2 +1 @@
**/JsLibraries/**
**/*.css.d.ts

View File

@@ -1,21 +1,14 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require('fs');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const typescriptEslintRecommended = require('@typescript-eslint/eslint-plugin').configs.recommended;
const frontendFolder = __dirname;
const dirs = fs
.readdirSync(path.join(frontendFolder, 'src'), { withFileTypes: true })
.readdirSync('frontend/src', { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name)
.join('|');
module.exports = {
root: true,
const frontendFolder = __dirname;
module.exports = {
parser: '@babel/eslint-parser',
env: {
@@ -35,7 +28,7 @@ module.exports = {
ecmaVersion: 6,
sourceType: 'module',
babelOptions: {
configFile: `${frontendFolder}/babel.config.js`
configFile: `${frontendFolder}/babel.config.js`,
},
ecmaFeatures: {
modules: true,
@@ -48,9 +41,7 @@ module.exports = {
'react',
'react-hooks',
'simple-import-sort',
'import',
'@typescript-eslint',
'prettier'
'import'
],
settings: {
@@ -233,7 +224,7 @@ module.exports = {
'consistent-this': ['error', 'self'],
'eol-last': 'error',
'func-names': 'off',
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'func-style': ['error', 'declaration'],
indent: ['error', 2, { SwitchCase: 1 }],
'key-spacing': ['error', { beforeColon: false, afterColon: true }],
'keyword-spacing': ['error', { before: true, after: true }],
@@ -324,9 +315,7 @@ module.exports = {
},
overrides: [
{
files: [
'*.js'
],
files: ['*.js'],
rules: {
'simple-import-sort/imports': [
'error',
@@ -341,52 +330,6 @@ module.exports = {
}
]
}
},
{
files: [
'*.ts',
'*.tsx'
],
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json'
},
extends: [
'prettier'
],
rules: Object.assign(typescriptEslintRecommended.rules, {
'no-shadow': 'off',
// These should be enabled after cleaning things up
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/explicit-function-return-type': 'off',
'react/prop-types': 'off',
'prettier/prettier': 'error',
'simple-import-sort/imports': [
'error',
{
groups: [
// Packages
// Absolute Paths
// Relative Paths
// Css
['^@?\\w', `^(${dirs})(/.*|$)`, '^\\.', '^\\..*css$']
]
}
]
})
},
{
files: [
'*.css.d.ts'
],
rules: {
'filenames/match-exported': 'off',
'init-declarations': 'off',
'prettier/prettier': 'off'
}
}
]
};

12
frontend/.jsbeautifyrc Normal file
View File

@@ -0,0 +1,12 @@
{
"js": {
"indent_size": 2,
"indent_char": " ",
"indent_level": 2,
"indent_with_tabs": false,
"preserve_newlines": true,
"brace_style": "collapse",
"max_preserve_newlines": 2,
"jslint_happy": true
}
}

View File

@@ -1,10 +0,0 @@
# Ignore everything recursively
*
# But not the .ts files
!*.ts*
*css.d.ts
# Check subdirectories too
!*/

View File

@@ -1,6 +0,0 @@
{
"arrowParens": "always",
"endOfLine": "auto",
"singleQuote": true,
"trailingComma": "es5"
}

View File

@@ -1,12 +1,12 @@
{
"plugins": [
"stylelint-order"
],
"ignoreFiles": [
"frontend/src/Styles/scaffolding.css",
"**/*.js"
],
"rules": {
"plugins": [
"stylelint-order"
],
"ignoreFiles": [
"frontend/src/Styles/scaffolding.css",
"**/*.js"
],
"rules": {
"at-rule-empty-line-before": [
"always",
{
@@ -15,6 +15,9 @@
]
}
],
"at-rule-name-case": "lower",
"at-rule-name-newline-after": "always-multi-line",
"at-rule-name-space-after": "always",
"at-rule-no-unknown": [
true,
{
@@ -25,36 +28,83 @@
}
],
"at-rule-no-vendor-prefix": true,
"at-rule-semicolon-newline-after": "always",
"at-rule-semicolon-space-before": "never",
"block-closing-brace-empty-line-before": "never",
"block-closing-brace-newline-after": "always",
"block-closing-brace-newline-before": "always",
"block-closing-brace-space-after": "always-single-line",
"block-closing-brace-space-before": "always-single-line",
"block-no-empty": true,
"block-opening-brace-newline-after": "always",
"block-opening-brace-newline-before": "never-single-line",
"block-opening-brace-space-after": "always-single-line",
"block-opening-brace-space-before": "always",
"color-hex-case": "lower",
"color-hex-length": "short",
"color-named": "never",
"color-no-invalid-hex": true,
"comment-whitespace-inside": "always",
"declaration-bang-space-after": "never",
"declaration-bang-space-before": "always",
"declaration-block-no-duplicate-properties": [
true,
{
"ignoreProperties": [
"composes"
"composes"
]
}
],
"declaration-block-no-redundant-longhand-properties": true,
"declaration-block-no-shorthand-property-overrides": true,
"declaration-block-semicolon-newline-after": "always",
"declaration-block-semicolon-newline-before": "never-multi-line",
"declaration-block-semicolon-space-before": "never",
"declaration-block-single-line-max-declarations": 1,
"declaration-block-trailing-semicolon": "always",
"declaration-colon-space-after": "always",
"declaration-colon-space-before": "never",
"font-family-name-quotes": "always-unless-keyword",
"function-calc-no-unspaced-operator": true,
"function-comma-newline-after": "never-multi-line",
"function-comma-newline-before": "never-multi-line",
"function-comma-space-after": "always",
"function-comma-space-before": "never",
"function-linear-gradient-no-nonstandard-direction": true,
"function-name-case": "lower",
"function-parentheses-newline-inside": "never-multi-line",
"function-parentheses-space-inside": "never",
"function-url-quotes": "always",
"function-url-scheme-disallowed-list": [
"data"
],
"function-whitespace-after": "always",
"indentation": 2,
"keyframe-declaration-no-important": true,
"length-zero-no-unit": true,
"max-empty-lines": 1,
"max-line-length": [
100,
{
"ignore": [
"non-comments"
]
}
],
"max-nesting-depth": 2,
"media-feature-colon-space-after": "always",
"media-feature-colon-space-before": "never",
"media-feature-name-case": "lower",
"media-feature-name-no-vendor-prefix": true,
"media-feature-range-operator-space-after": "always",
"media-feature-range-operator-space-before": "always",
"no-empty-source": true,
"no-eol-whitespace": true,
"no-extra-semicolons": true,
"no-invalid-double-slash-comments": true,
"no-missing-end-of-source-newline": true,
"number-leading-zero": "always",
"number-no-trailing-zeros": true,
"order/order": [
"custom-properties",
"dollar-variables",
@@ -82,7 +132,6 @@
"right",
"bottom",
"left",
"inset",
"z-index",
"display",
"visibility",
@@ -294,33 +343,54 @@
]
}
],
"property-case": "lower",
"property-no-vendor-prefix": true,
"rule-empty-line-before": [
"always",
{
"except": [
"first-nested"
"first-nested"
],
"ignore": [
"after-comment"
"after-comment"
]
}
],
"selector-attribute-brackets-space-inside": "never",
"selector-attribute-operator-space-after": "never",
"selector-attribute-operator-space-before": "never",
"selector-attribute-quotes": "never",
"selector-class-pattern": "^[A-Za-z0-9]+$",
"selector-combinator-space-after": "always",
"selector-combinator-space-before": "always",
"selector-descendant-combinator-no-non-space": true,
"selector-list-comma-newline-after": "always",
"selector-list-comma-newline-before": "never-multi-line",
"selector-list-comma-space-before": "never",
"selector-max-attribute": 0,
"selector-max-class": 3,
"selector-max-compound-selectors": 3,
"selector-max-empty-lines": 0,
"selector-max-id": 0,
"selector-max-universal": 0,
"selector-pseudo-class-case": "lower",
"selector-pseudo-class-parentheses-space-inside": "never",
"selector-pseudo-element-case": "lower",
"selector-pseudo-element-colon-notation": "double",
"selector-pseudo-element-no-unknown": true,
"selector-type-case": "lower",
"selector-type-no-unknown": true,
"shorthand-property-no-redundant-values": true,
"string-no-newline": true,
"string-quotes": "single",
"time-min-milliseconds": 100,
"unit-case": "lower",
"unit-no-unknown": true,
"value-list-comma-newline-after": "never-multi-line",
"value-list-comma-newline-before": "never-multi-line",
"value-list-comma-space-after": "always",
"value-list-comma-space-before": "never",
"value-list-max-empty-lines": 0,
"value-no-vendor-prefix": true
}
}
}

View File

@@ -1,7 +0,0 @@
{
"recommendations": [
"stylelint.vscode-stylelint",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}

View File

@@ -1,23 +0,0 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.insertFinalNewline": true,
"files.exclude": {
"**/node_modules": true,
"**/*.d.css": true
},
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"typescript.preferences.quoteStyle": "single",
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
}

View File

@@ -17,8 +17,7 @@ module.exports = {
env: {
development: {
presets: [
['@babel/preset-react', { development: true }],
'@babel/preset-typescript'
['@babel/preset-react', { development: true }]
],
plugins: [
'babel-plugin-inline-classnames'
@@ -26,8 +25,7 @@ module.exports = {
},
production: {
presets: [
'@babel/preset-react',
'@babel/preset-typescript'
'@babel/preset-react'
],
plugins: [
'babel-plugin-transform-react-remove-prop-types'

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const webpack = require('webpack');
const FileManagerPlugin = require('filemanager-webpack-plugin');
@@ -6,7 +5,6 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
const LiveReloadPlugin = require('webpack-livereload-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = (env) => {
const uiFolder = 'UI';
@@ -40,18 +38,13 @@ module.exports = (env) => {
},
resolve: {
extensions: [
'.ts',
'.tsx',
'.js'
],
modules: [
srcFolder,
path.join(srcFolder, 'Shims'),
'node_modules'
],
alias: {
jquery: 'jquery/dist/jquery.min',
jquery: 'jquery/src/jquery',
'react-middle-truncate': 'react-middle-truncate/lib/react-middle-truncate'
},
fallback: {
@@ -67,23 +60,23 @@ module.exports = (env) => {
output: {
path: distFolder,
publicPath: '/',
filename: '[name]-[contenthash].js',
filename: '[name].js',
sourceMapFilename: '[file].map'
},
optimization: {
moduleIds: 'deterministic',
chunkIds: isProduction ? 'deterministic' : 'named'
chunkIds: 'named',
splitChunks: {
chunks: 'initial',
name: 'vendors'
}
},
performance: {
hints: false
},
experiments: {
topLevelAwait: true
},
plugins: [
new webpack.DefinePlugin({
__DEV__: !isProduction,
@@ -91,8 +84,7 @@ module.exports = (env) => {
}),
new MiniCssExtractPlugin({
filename: 'Content/styles.css',
chunkFilename: 'Content/[id]-[chunkhash].css'
filename: 'Content/styles.css'
}),
new HtmlWebpackPlugin({
@@ -139,8 +131,6 @@ module.exports = (env) => {
}
}),
new ForkTsCheckerWebpackPlugin(),
new LiveReloadPlugin()
],
@@ -164,7 +154,7 @@ module.exports = (env) => {
}
},
{
test: [/\.jsx?$/, /\.tsx?$/],
test: /\.js?$/,
exclude: /(node_modules|JsLibraries)/,
use: [
{
@@ -195,7 +185,6 @@ module.exports = (env) => {
exclude: /(node_modules|globals.css)/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{ loader: 'css-modules-typescript-loader' },
{
loader: 'css-loader',
options: {
@@ -264,19 +253,18 @@ module.exports = (env) => {
config.resolve.alias['react-dom$'] = 'react-dom/profiling';
config.resolve.alias['scheduler/tracing'] = 'scheduler/tracing-profiling';
config.optimization = {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
sourceMap: true, // Must be set to true if using source-maps in production
mangle: false,
keep_classnames: true,
keep_fnames: true
}
})
]
};
config.optimization.minimizer = [
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true, // Must be set to true if using source-maps in production
terserOptions: {
mangle: false,
keep_classnames: true,
keep_fnames: true
}
})
];
}
return config;

View File

@@ -1,4 +1,3 @@
// eslint-disable-next-line filenames/match-exported
const loaderUtils = require('loader-utils');
module.exports = function cssVariablesLoader(source) {

4
frontend/src/.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.insertFinalNewline": true
}

View File

@@ -1,6 +1,5 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import PageContent from 'Components/Page/PageContent';
@@ -162,16 +161,16 @@ class Blocklist extends Component {
{
!isAnyFetching && !!error &&
<Alert kind={kinds.DANGER}>
<div>
{translate('UnableToLoadBlocklist')}
</Alert>
</div>
}
{
isAllPopulated && !error && !items.length &&
<Alert kind={kinds.INFO}>
<div>
{translate('NoHistoryBlocklist')}
</Alert>
</div>
}
{
@@ -215,7 +214,7 @@ class Blocklist extends Component {
isOpen={isConfirmRemoveModalOpen}
kind={kinds.DANGER}
title={translate('RemoveSelected')}
message={translate('RemoveSelectedItemBlocklistMessageText')}
message={translate('RemoveSelectedMessageText')}
confirmLabel={translate('RemoveSelected')}
onConfirm={this.onRemoveSelectedConfirmed}
onCancel={this.onConfirmRemoveModalClose}

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actions': string;
'indexer': string;
'quality': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'description': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -9,7 +9,7 @@ import Link from 'Components/Link/Link';
import { icons } from 'Helpers/Props';
import formatDateTime from 'Utilities/Date/formatDateTime';
import formatAge from 'Utilities/Number/formatAge';
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
import formatPreferredWordScore from 'Utilities/Number/formatPreferredWordScore';
import translate from 'Utilities/String/translate';
import styles from './HistoryDetails.css';
@@ -107,8 +107,8 @@ function HistoryDetails(props) {
{
customFormatScore && customFormatScore !== '0' ?
<DescriptionListItem
title={translate('CustomFormatScore')}
data={formatCustomFormatScore(customFormatScore)}
title="Custom Format Score"
data={formatPreferredWordScore(customFormatScore)}
/> :
null
}
@@ -224,8 +224,8 @@ function HistoryDetails(props) {
{
customFormatScore && customFormatScore !== '0' ?
<DescriptionListItem
title={translate('CustomFormatScore')}
data={formatCustomFormatScore(customFormatScore)}
title="Custom Format Score"
data={formatPreferredWordScore(customFormatScore)}
/> :
null
}
@@ -270,8 +270,8 @@ function HistoryDetails(props) {
{
customFormatScore && customFormatScore !== '0' ?
<DescriptionListItem
title={translate('CustomFormatScore')}
data={formatCustomFormatScore(customFormatScore)}
title="Custom Format Score"
data={formatPreferredWordScore(customFormatScore)}
/> :
null
}

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'markAsFailedButton': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,6 +1,5 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import FilterMenu from 'Components/Menu/FilterMenu';
import PageContent from 'Components/Page/PageContent';
@@ -12,7 +11,7 @@ import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
import TablePager from 'Components/Table/TablePager';
import { align, icons, kinds } from 'Helpers/Props';
import { align, icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import HistoryRowConnector from './HistoryRowConnector';
@@ -86,9 +85,9 @@ class History extends Component {
{
!isFetchingAny && hasError &&
<Alert kind={kinds.DANGER}>
<div>
{translate('UnableToLoadHistory')}
</Alert>
</div>
}
{
@@ -96,9 +95,9 @@ class History extends Component {
// wait for the books to populate because they are never coming.
isPopulated && !hasError && !items.length &&
<Alert kind={kinds.INFO}>
{translate('NoHistory')}
</Alert>
<div>
No history found
</div>
}
{

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'cell': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,11 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'customFormatScore': string;
'details': string;
'downloadClient': string;
'indexer': string;
'releaseGroup': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -8,9 +8,8 @@ import IconButton from 'Components/Link/IconButton';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableRow from 'Components/Table/TableRow';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, tooltipPositions } from 'Helpers/Props';
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
import { icons } from 'Helpers/Props';
import formatPreferredWordScore from 'Utilities/Number/formatPreferredWordScore';
import HistoryDetailsModal from './Details/HistoryDetailsModal';
import HistoryEventTypeCell from './HistoryEventTypeCell';
import styles from './HistoryRow.css';
@@ -58,7 +57,6 @@ class HistoryRow extends Component {
book,
quality,
customFormats,
customFormatScore,
qualityCutoffNotMet,
eventType,
sourceTitle,
@@ -179,14 +177,7 @@ class HistoryRow extends Component {
key={name}
className={styles.customFormatScore}
>
<Tooltip
anchor={formatCustomFormatScore(
customFormatScore,
customFormats.length
)}
tooltip={<BookFormats formats={customFormats} />}
position={tooltipPositions.BOTTOM}
/>
{formatPreferredWordScore(data.customFormatScore)}
</TableRowCell>
);
}
@@ -253,7 +244,6 @@ HistoryRow.propTypes = {
book: PropTypes.object,
quality: PropTypes.object.isRequired,
customFormats: PropTypes.arrayOf(PropTypes.object),
customFormatScore: PropTypes.number.isRequired,
qualityCutoffNotMet: PropTypes.bool.isRequired,
eventType: PropTypes.string.isRequired,
sourceTitle: PropTypes.string.isRequired,
@@ -267,8 +257,4 @@ HistoryRow.propTypes = {
onMarkAsFailedPress: PropTypes.func.isRequired
};
HistoryRow.defaultProps = {
customFormats: []
};
export default HistoryRow;

View File

@@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'torrent': string;
'usenet': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +1,6 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody';
@@ -13,7 +12,7 @@ import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
import TablePager from 'Components/Table/TablePager';
import { align, icons, kinds } from 'Helpers/Props';
import { align, icons } from 'Helpers/Props';
import getRemovedItems from 'Utilities/Object/getRemovedItems';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import translate from 'Utilities/String/translate';
@@ -234,17 +233,17 @@ class Queue extends Component {
{
!isRefreshing && hasError ?
<Alert kind={kinds.DANGER}>
<div>
{translate('FailedToLoadQueue')}
</Alert> :
</div> :
null
}
{
isAllPopulated && !hasError && !items.length ?
<Alert kind={kinds.INFO}>
<div>
{translate('QueueIsEmpty')}
</Alert> :
</div> :
null
}

View File

@@ -16,12 +16,6 @@
width: 150px;
}
.customFormatScore {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 55px;
}
.actions {
composes: cell from '~Components/Table/Cells/TableRowCell.css';

View File

@@ -1,11 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actions': string;
'customFormatScore': string;
'progress': string;
'protocol': string;
'quality': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -14,11 +14,9 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
import TableRow from 'Components/Table/TableRow';
import Popover from 'Components/Tooltip/Popover';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
import formatBytes from 'Utilities/Number/formatBytes';
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
import translate from 'Utilities/String/translate';
import QueueStatusCell from './QueueStatusCell';
import RemoveQueueItemModal from './RemoveQueueItemModal';
@@ -46,14 +44,14 @@ class QueueRow extends Component {
this.setState({ isRemoveQueueItemModalOpen: true });
};
onRemoveQueueItemModalConfirmed = (blocklist, skipRedownload) => {
onRemoveQueueItemModalConfirmed = (blocklist, skipredownload) => {
const {
onRemoveQueueItemPress,
onQueueRowModalOpenOrClose
} = this.props;
onQueueRowModalOpenOrClose(false);
onRemoveQueueItemPress(blocklist, skipRedownload);
onRemoveQueueItemPress(blocklist, skipredownload);
this.setState({ isRemoveQueueItemModalOpen: false });
};
@@ -93,7 +91,6 @@ class QueueRow extends Component {
book,
quality,
customFormats,
customFormatScore,
protocol,
indexer,
outputPath,
@@ -225,24 +222,6 @@ class QueueRow extends Component {
);
}
if (name === 'customFormatScore') {
return (
<TableRowCell
key={name}
className={styles.customFormatScore}
>
<Tooltip
anchor={formatCustomFormatScore(
customFormatScore,
customFormats.length
)}
tooltip={<BookFormats formats={customFormats} />}
position={tooltipPositions.BOTTOM}
/>
</TableRowCell>
);
}
if (name === 'protocol') {
return (
<TableRowCell key={name}>
@@ -413,7 +392,6 @@ QueueRow.propTypes = {
book: PropTypes.object,
quality: PropTypes.object.isRequired,
customFormats: PropTypes.arrayOf(PropTypes.object),
customFormatScore: PropTypes.number.isRequired,
protocol: PropTypes.string.isRequired,
indexer: PropTypes.string,
outputPath: PropTypes.string,
@@ -438,7 +416,6 @@ QueueRow.propTypes = {
};
QueueRow.defaultProps = {
customFormats: [],
isGrabbing: false,
isRemoving: false
};

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'status': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -23,7 +23,7 @@ class RemoveQueueItemModal extends Component {
this.state = {
remove: true,
blocklist: false,
skipRedownload: false
skipredownload: false
};
}
@@ -34,7 +34,7 @@ class RemoveQueueItemModal extends Component {
this.setState({
remove: true,
blocklist: false,
skipRedownload: false
skipredownload: false
});
};
@@ -49,8 +49,8 @@ class RemoveQueueItemModal extends Component {
this.setState({ blocklist: value });
};
onSkipRedownloadChange = ({ value }) => {
this.setState({ skipRedownload: value });
onSkipReDownloadChange = ({ value }) => {
this.setState({ skipredownload: value });
};
onRemoveConfirmed = () => {
@@ -76,7 +76,7 @@ class RemoveQueueItemModal extends Component {
isPending
} = this.props;
const { remove, blocklist, skipRedownload } = this.state;
const { remove, blocklist, skipredownload } = this.state;
return (
<Modal
@@ -124,7 +124,7 @@ class RemoveQueueItemModal extends Component {
type={inputTypes.CHECK}
name="blocklist"
value={blocklist}
helpText={translate('BlocklistReleaseHelpText')}
helpText={translate('BlocklistHelpText')}
onChange={this.onBlocklistChange}
/>
</FormGroup>
@@ -137,10 +137,10 @@ class RemoveQueueItemModal extends Component {
</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="skipRedownload"
value={skipRedownload}
helpText={translate('SkipRedownloadHelpText')}
onChange={this.onSkipRedownloadChange}
name="skipredownload"
value={skipredownload}
helpText={translate('SkipredownloadHelpText')}
onChange={this.onSkipReDownloadChange}
/>
</FormGroup>
}

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'message': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -24,7 +24,7 @@ class RemoveQueueItemsModal extends Component {
this.state = {
remove: true,
blocklist: false,
skipRedownload: false
skipredownload: false
};
}
@@ -35,7 +35,7 @@ class RemoveQueueItemsModal extends Component {
this.setState({
remove: true,
blocklist: false,
skipRedownload: false
skipredownload: false
});
};
@@ -50,8 +50,8 @@ class RemoveQueueItemsModal extends Component {
this.setState({ blocklist: value });
};
onSkipRedownloadChange = ({ value }) => {
this.setState({ skipRedownload: value });
onSkipReDownloadChange = ({ value }) => {
this.setState({ skipredownload: value });
};
onRemoveConfirmed = () => {
@@ -77,7 +77,7 @@ class RemoveQueueItemsModal extends Component {
allPending
} = this.props;
const { remove, blocklist, skipRedownload } = this.state;
const { remove, blocklist, skipredownload } = this.state;
return (
<Modal
@@ -89,12 +89,12 @@ class RemoveQueueItemsModal extends Component {
onModalClose={this.onModalClose}
>
<ModalHeader>
{selectedCount > 1 ? translate('RemoveSelectedItems') : translate('RemoveSelectedItem')}
Remove Selected Item{selectedCount > 1 ? 's' : ''}
</ModalHeader>
<ModalBody>
<div className={styles.message}>
{selectedCount > 1 ? translate('RemoveSelectedItemsQueueMessageText', selectedCount) : translate('RemoveSelectedItemQueueMessageText')}
Are you sure you want to remove {selectedCount} item{selectedCount > 1 ? 's' : ''} from the queue?
</div>
{
@@ -118,14 +118,14 @@ class RemoveQueueItemsModal extends Component {
<FormGroup>
<FormLabel>
{selectedCount > 1 ? translate('BlocklistReleases') : translate('BlocklistRelease')}
Add Release{selectedCount > 1 ? 's' : ''} To Blocklist
</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="blocklist"
value={blocklist}
helpText={translate('BlocklistReleaseHelpText')}
helpText={translate('BlocklistHelpText')}
onChange={this.onBlocklistChange}
/>
</FormGroup>
@@ -138,10 +138,10 @@ class RemoveQueueItemsModal extends Component {
</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="skipRedownload"
value={skipRedownload}
helpText={translate('SkipRedownloadHelpText')}
onChange={this.onSkipRedownloadChange}
name="skipredownload"
value={skipredownload}
helpText={translate('SkipredownloadHelpText')}
onChange={this.onSkipReDownloadChange}
/>
</FormGroup>
}
@@ -150,14 +150,14 @@ class RemoveQueueItemsModal extends Component {
<ModalFooter>
<Button onPress={this.onModalClose}>
{translate('Close')}
Close
</Button>
<Button
kind={kinds.DANGER}
onPress={this.onRemoveConfirmed}
>
{translate('Remove')}
Remove
</Button>
</ModalFooter>
</ModalContent>

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'timeleft': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -7,13 +7,13 @@ import PageConnector from 'Components/Page/PageConnector';
import ApplyTheme from './ApplyTheme';
import AppRoutes from './AppRoutes';
function App({ store, history, hasTranslationsError }) {
function App({ store, history }) {
return (
<DocumentTitle title={window.Readarr.instanceName}>
<Provider store={store}>
<ConnectedRouter history={history}>
<ApplyTheme>
<PageConnector hasTranslationsError={hasTranslationsError}>
<PageConnector>
<AppRoutes app={App} />
</PageConnector>
</ApplyTheme>
@@ -25,8 +25,7 @@ function App({ store, history, hasTranslationsError }) {
App.propTypes = {
store: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
hasTranslationsError: PropTypes.bool.isRequired
history: PropTypes.object.isRequired
};
export default App;

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'changes': string;
'maintenance': string;
'version': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'automatic': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,5 +0,0 @@
interface ModelBase {
id: number;
}
export default ModelBase;

View File

@@ -1,48 +0,0 @@
import SortDirection from 'Helpers/Props/SortDirection';
export interface Error {
responseJSON: {
message: string;
};
}
export interface AppSectionDeleteState {
isDeleting: boolean;
deleteError: Error;
}
export interface AppSectionSaveState {
isSaving: boolean;
saveError: Error;
}
export interface PagedAppSectionState {
pageSize: number;
}
export interface AppSectionSchemaState<T> {
isSchemaFetching: boolean;
isSchemaPopulated: boolean;
schemaError: Error;
schema: {
items: T[];
};
}
export interface AppSectionItemState<T> {
isFetching: boolean;
isPopulated: boolean;
error: Error;
item: T;
}
interface AppSectionState<T> {
isFetching: boolean;
isPopulated: boolean;
error: Error;
items: T[];
sortKey: string;
sortDirection: SortDirection;
}
export default AppSectionState;

View File

@@ -1,41 +0,0 @@
import SettingsAppState from './SettingsAppState';
import TagsAppState from './TagsAppState';
interface FilterBuilderPropOption {
id: string;
name: string;
}
export interface FilterBuilderProp<T> {
name: string;
label: string;
type: string;
valueType?: string;
optionsSelector?: (items: T[]) => FilterBuilderPropOption[];
}
export interface PropertyFilter {
key: string;
value: boolean | string | number | string[] | number[];
type: string;
}
export interface Filter {
key: string;
label: string;
filers: PropertyFilter[];
}
export interface CustomFilter {
id: number;
type: string;
label: string;
filers: PropertyFilter[];
}
interface AppState {
settings: SettingsAppState;
tags: TagsAppState;
}
export default AppState;

View File

@@ -1,40 +0,0 @@
import AppSectionState, {
AppSectionDeleteState,
AppSectionSaveState,
} from 'App/State/AppSectionState';
import DownloadClient from 'typings/DownloadClient';
import ImportList from 'typings/ImportList';
import Indexer from 'typings/Indexer';
import Notification from 'typings/Notification';
import { UiSettings } from 'typings/UiSettings';
export interface DownloadClientAppState
extends AppSectionState<DownloadClient>,
AppSectionDeleteState,
AppSectionSaveState {}
export interface ImportListAppState
extends AppSectionState<ImportList>,
AppSectionDeleteState,
AppSectionSaveState {}
export interface IndexerAppState
extends AppSectionState<Indexer>,
AppSectionDeleteState,
AppSectionSaveState {}
export interface NotificationAppState
extends AppSectionState<Notification>,
AppSectionDeleteState {}
export type UiSettingsAppState = AppSectionState<UiSettings>;
interface SettingsAppState {
downloadClients: DownloadClientAppState;
importLists: ImportListAppState;
indexers: IndexerAppState;
notifications: NotificationAppState;
uiSettings: UiSettingsAppState;
}
export default SettingsAppState;

View File

@@ -1,12 +0,0 @@
import ModelBase from 'App/ModelBase';
import AppSectionState, {
AppSectionDeleteState,
} from 'App/State/AppSectionState';
export interface Tag extends ModelBase {
label: string;
}
interface TagsAppState extends AppSectionState<Tag>, AppSectionDeleteState {}
export default TagsAppState;

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'deleteFilesMessage': string;
'pathContainer': string;
'pathIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'alternateTitle': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,17 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'authorNavigationButton': string;
'authorNavigationButtons': string;
'authorUpButton': string;
'contentContainer': string;
'errorMessage': string;
'innerContentBody': string;
'metadataMessage': string;
'selectedTab': string;
'tab': string;
'tabContent': string;
'tabList': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -392,7 +392,10 @@ class AuthorDetails extends Component {
name={icons.ARROW_UP}
size={30}
title={translate('GoToAuthorListing')}
to={'/'}
to={{
pathname: '/',
state: { restoreScrollPosition: true }
}}
/>
<IconButton

View File

@@ -1,29 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'alternateTitlesIconContainer': string;
'authorNavigationButton': string;
'authorNavigationButtons': string;
'authorUpButton': string;
'backdrop': string;
'backdropOverlay': string;
'details': string;
'detailsLabel': string;
'header': string;
'headerContent': string;
'info': string;
'links': string;
'monitorToggleButton': string;
'overview': string;
'path': string;
'poster': string;
'qualityProfileName': string;
'sizeOnDisk': string;
'tags': string;
'title': string;
'titleContainer': string;
'titleRow': string;
'toggleMonitoredContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -92,7 +92,6 @@ class AuthorDetailsHeader extends Component {
titleWidth
} = this.state;
const fanartUrl = getFanartUrl(images);
const marqueeWidth = titleWidth - (isSmallScreen ? 85 : 160);
const continuing = status === 'continuing';
@@ -109,11 +108,9 @@ class AuthorDetailsHeader extends Component {
<div className={styles.header} style={{ width }} >
<div
className={styles.backdrop}
style={
fanartUrl ?
{ backgroundImage: `url(${fanartUrl})` } :
null
}
style={{
backgroundImage: `url(${getFanartUrl(images)})`
}}
>
<div className={styles.backdropOverlay} />
</div>

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'link': string;
'linkLabel': string;
'links': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -74,7 +74,7 @@ class AuthorDetailsPageConnector extends Component {
if (isFetching && !isPopulated) {
return (
<PageContent title={translate('Loading')}>
<PageContent title='loading'>
<PageContentBody>
<LoadingIndicator />
</PageContentBody>

View File

@@ -1,23 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actionButton': string;
'actionMenuIcon': string;
'actions': string;
'actionsMenu': string;
'actionsMenuContent': string;
'bookCount': string;
'bookType': string;
'bookTypeLabel': string;
'books': string;
'collapseButtonContainer': string;
'collapseButtonIcon': string;
'episodeCountTooltip': string;
'expandButton': string;
'expandButtonIcon': string;
'header': string;
'left': string;
'noBooks': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,24 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actionButton': string;
'actionMenuIcon': string;
'actions': string;
'actionsMenu': string;
'actionsMenuContent': string;
'bookCount': string;
'bookType': string;
'bookTypeLabel': string;
'books': string;
'collapseButtonContainer': string;
'collapseButtonIcon': string;
'episodeCountTooltip': string;
'expandButton': string;
'expandButtonIcon': string;
'header': string;
'left': string;
'noBooks': string;
'seriesTitle': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,3 +1,4 @@
import _ from 'lodash';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createAuthorSelector from 'Store/Selectors/createAuthorSelector';
@@ -9,11 +10,15 @@ function createMapStateToProps() {
createAuthorSelector(),
createTagsSelector(),
(author, tagList) => {
const tags = author.tags
.map((tagId) => tagList.find((tag) => tag.id === tagId))
.filter((tag) => !!tag)
.map((tag) => tag.label)
.sort((a, b) => a.localeCompare(b));
const tags = _.reduce(author.tags, (acc, tag) => {
const matchingTag = _.find(tagList, { id: tag });
if (matchingTag) {
acc.push(matchingTag.label);
}
return acc;
}, []);
return {
tags

View File

@@ -1,13 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'monitored': string;
'pageCount': string;
'position': string;
'rating': string;
'releaseDate': string;
'status': string;
'title': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'center': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'deleteButton': string;
'labelIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,12 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'message': string;
'retagIcon': string;
'searchForNewBookContainer': string;
'searchForNewBookInput': string;
'searchForNewBookLabel': string;
'searchForNewBookLabelContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,16 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'buttonContainer': string;
'buttonContainerContent': string;
'buttons': string;
'deleteSelectedButton': string;
'dropdownContainer': string;
'footer': string;
'inputContainer': string;
'organizeSelectedButton': string;
'selectedAuthorLabel': string;
'tagsButton': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,6 +1,5 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import MoveAuthorModal from 'Author/MoveAuthor/MoveAuthorModal';
import MetadataProfileSelectInputConnector from 'Components/Form/MetadataProfileSelectInputConnector';
import MonitorNewItemsSelectInput from 'Components/Form/MonitorNewItemsSelectInput';
@@ -10,7 +9,6 @@ import SelectInput from 'Components/Form/SelectInput';
import SpinnerButton from 'Components/Link/SpinnerButton';
import PageContentFooter from 'Components/Page/PageContentFooter';
import { kinds } from 'Helpers/Props';
import { fetchRootFolders } from 'Store/Actions/Settings/rootFolders';
import translate from 'Utilities/String/translate';
import AuthorEditorFooterLabel from './AuthorEditorFooterLabel';
import DeleteAuthorModal from './Delete/DeleteAuthorModal';
@@ -19,10 +17,6 @@ import styles from './AuthorEditorFooter.css';
const NO_CHANGE = 'noChange';
const mapDispatchToProps = {
dispatchFetchRootFolders: fetchRootFolders
};
class AuthorEditorFooter extends Component {
//
@@ -45,13 +39,6 @@ class AuthorEditorFooter extends Component {
};
}
//
// Lifecycle
componentDidMount() {
this.props.dispatchFetchRootFolders();
}
componentDidUpdate(prevProps) {
const {
isSaving,
@@ -173,9 +160,9 @@ class AuthorEditorFooter extends Component {
} = this.state;
const monitoredOptions = [
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
{ key: 'monitored', value: translate('Monitored') },
{ key: 'unmonitored', value: translate('Unmonitored') }
{ key: NO_CHANGE, value: 'No Change', disabled: true },
{ key: 'monitored', value: 'Monitored' },
{ key: 'unmonitored', value: 'Unmonitored' }
];
return (
@@ -354,8 +341,7 @@ AuthorEditorFooter.propTypes = {
showMetadataProfile: PropTypes.bool.isRequired,
onSaveSelected: PropTypes.func.isRequired,
onOrganizeAuthorPress: PropTypes.func.isRequired,
onRetagAuthorPress: PropTypes.func.isRequired,
dispatchFetchRootFolders: PropTypes.func.isRequired
onRetagAuthorPress: PropTypes.func.isRequired
};
export default connect(undefined, mapDispatchToProps)(AuthorEditorFooter);
export default AuthorEditorFooter;

View File

@@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'label': string;
'savingIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'message': string;
'path': string;
'pathContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'message': string;
'renameIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'message': string;
'renameIcon': string;
'result': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -98,10 +98,10 @@ class TagsModalContent extends Component {
value={applyTags}
values={applyTagsOptions}
helpTexts={[
translate('ApplyTagsHelpTextHowToApplyAuthors'),
translate('ApplyTagsHelpTextAdd'),
translate('ApplyTagsHelpTextRemove'),
translate('ApplyTagsHelpTextReplace')
translate('ApplyTagsHelpTexts1'),
translate('ApplyTagsHelpTexts2'),
translate('ApplyTagsHelpTexts3'),
translate('ApplyTagsHelpTexts4')
]}
onChange={this.onInputChange}
/>

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actions': string;
'details': string;
'sourceTitle': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,10 +1,8 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import AuthorHistoryRowConnector from './AuthorHistoryRowConnector';
@@ -72,9 +70,9 @@ class AuthorHistoryTableContent extends Component {
{
!isFetching && !!error &&
<Alert kind={kinds.DANGER}>
<div>
{translate('UnableToLoadHistory')}
</Alert>
</div>
}
{

View File

@@ -1,13 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'bannersInnerContentBody': string;
'contentBody': string;
'contentBodyContainer': string;
'errorMessage': string;
'pageContentBodyWrapper': string;
'postersInnerContentBody': string;
'tableInnerContentBody': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,14 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'continuing': string;
'ended': string;
'footer': string;
'legendItem': string;
'legendItemColor': string;
'missingMonitored': string;
'missingUnmonitored': string;
'statistics': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,19 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actions': string;
'container': string;
'content': string;
'details': string;
'editorSelect': string;
'ended': string;
'info': string;
'link': string;
'overview': string;
'poster': string;
'posterContainer': string;
'title': string;
'titleRow': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'infos': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'icon': string;
'infoRow': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'grid': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,18 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'action': string;
'container': string;
'content': string;
'controls': string;
'editorSelect': string;
'ended': string;
'link': string;
'nextAiring': string;
'overlayTitle': string;
'poster': string;
'posterContainer': string;
'title': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'info': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'grid': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'progress': string;
'progressBar': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -17,8 +17,8 @@ function AuthorIndexProgressBar(props) {
detailedProgressBar
} = props;
const progress = bookCount ? bookCount / totalBookCount * 100 : 100;
const text = `${bookCount} / ${totalBookCount}`;
const progress = bookCount ? bookFileCount / bookCount * 100 : 100;
const text = `${bookFileCount} / ${bookCount}`;
return (
<ProgressBar

View File

@@ -1,25 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actions': string;
'added': string;
'banner': string;
'bannerGrow': string;
'bookCount': string;
'bookProgress': string;
'genres': string;
'lastBook': string;
'latestBook': string;
'metadataProfileId': string;
'nextBook': string;
'path': string;
'qualityProfileId': string;
'ratings': string;
'sizeOnDisk': string;
'sortName': string;
'status': string;
'tags': string;
'useSceneNumbering': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,28 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actions': string;
'added': string;
'banner': string;
'bannerGrow': string;
'bannerImage': string;
'bookProgress': string;
'cell': string;
'checkInput': string;
'genres': string;
'lastBook': string;
'link': string;
'metadataProfileId': string;
'nextBook': string;
'overlayTitle': string;
'path': string;
'qualityProfileId': string;
'ratings': string;
'sizeOnDisk': string;
'sortName': string;
'status': string;
'tags': string;
'useSceneNumbering': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -297,7 +297,7 @@ class AuthorIndexRow extends Component {
progress={progress}
kind={getProgressBarKind(status, monitored, progress)}
showText={true}
text={`${bookCount} / ${totalBookCount}`}
text={`${bookFileCount} / ${bookCount}`}
title={translate('BookFileCountBookCountTotalTotalBookCountInterp', [bookFileCount, bookCount, totalBookCount])}
width={125}
/>

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'tableContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'status': string;
'statusIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -33,7 +33,7 @@ class MonitoringOptionsModalContent extends Component {
const {
isSaving,
saveError
} = this.props;
} = prevProps;
if (prevProps.isSaving && !isSaving && !saveError) {
this.setState({

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'doNotMoveButton': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'buttonContainer': string;
'message': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,7 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'BookSearchCell': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'deleteFilesMessage': string;
'pathContainer': string;
'pathIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,16 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'bookNavigationButton': string;
'bookNavigationButtons': string;
'bookUpButton': string;
'contentContainer': string;
'filterIcon': string;
'innerContentBody': string;
'selectedTab': string;
'tab': string;
'tabContent': string;
'tabList': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,26 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'alternateTitlesIconContainer': string;
'backdrop': string;
'backdropOverlay': string;
'cover': string;
'details': string;
'detailsLabel': string;
'duration': string;
'header': string;
'headerContent': string;
'info': string;
'links': string;
'monitorToggleButton': string;
'overview': string;
'qualityProfileName': string;
'sizeOnDisk': string;
'tags': string;
'title': string;
'titleContainer': string;
'titleRow': string;
'toggleMonitoredContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -83,18 +83,15 @@ class BookDetailsHeader extends Component {
titleWidth
} = this.state;
const fanartUrl = getFanartUrl(author.images);
const marqueeWidth = titleWidth - (isSmallScreen ? 85 : 160);
return (
<div className={styles.header} style={{ width }}>
<div
className={styles.backdrop}
style={
fanartUrl ?
{ backgroundImage: `url(${fanartUrl})` } :
null
}
style={{
backgroundImage: `url(${getFanartUrl(author.images)})`
}}
>
<div className={styles.backdropOverlay} />
</div>

View File

@@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'link': string;
'linkLabel': string;
'links': string;
}
export const cssExports: CssExports;
export default cssExports;

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