mirror of
https://github.com/Radarr/Radarr.git
synced 2026-03-28 18:05:41 -04:00
Compare commits
112 Commits
v3.2.2.508
...
ending-col
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da5feda71b | ||
|
|
750b0331ab | ||
|
|
4bf311d820 | ||
|
|
67b1fd9bc5 | ||
|
|
ea8a5dc25e | ||
|
|
ae5c7a3ace | ||
|
|
4b06f6b506 | ||
|
|
147cfe538a | ||
|
|
5fb6b44950 | ||
|
|
bb4c1d6181 | ||
|
|
a774ccf426 | ||
|
|
3654340e0f | ||
|
|
ee84321d4b | ||
|
|
aa49358b97 | ||
|
|
aca669defe | ||
|
|
8cad9600cc | ||
|
|
d6967a786f | ||
|
|
06e2d5b3c3 | ||
|
|
2d53ec24f8 | ||
|
|
c14ef7bee7 | ||
|
|
4299799967 | ||
|
|
c93c87de30 | ||
|
|
64045b0810 | ||
|
|
4e1aa5b946 | ||
|
|
3ce83d0cb4 | ||
|
|
f5b0e78c2f | ||
|
|
af872e4bc5 | ||
|
|
f8a82dbb90 | ||
|
|
27c5a30cc1 | ||
|
|
0541041b2b | ||
|
|
90cff01fe5 | ||
|
|
b627c6badd | ||
|
|
4f8b0dd5cc | ||
|
|
672b37c319 | ||
|
|
d0fbcffa42 | ||
|
|
8f4b028abe | ||
|
|
db7babc6ed | ||
|
|
88d516a6d4 | ||
|
|
d091458a8d | ||
|
|
c8c9db1452 | ||
|
|
10f37e0774 | ||
|
|
49583f8507 | ||
|
|
6da18c8a4f | ||
|
|
d666366deb | ||
|
|
31ac40d2cc | ||
|
|
2d0271978d | ||
|
|
13224f03cc | ||
|
|
8024f4658c | ||
|
|
beca2c99ca | ||
|
|
94b481a66f | ||
|
|
425772da1c | ||
|
|
6808d5388c | ||
|
|
e912e14cbb | ||
|
|
6e60e3dfa4 | ||
|
|
ac9dfc4f25 | ||
|
|
0369ad86a3 | ||
|
|
8d1a9f98af | ||
|
|
34c545d932 | ||
|
|
5a51225286 | ||
|
|
d2d81db8b3 | ||
|
|
90cc79b6bc | ||
|
|
ebf4425beb | ||
|
|
0daa978fba | ||
|
|
31ba45cb7a | ||
|
|
8dad6cc8db | ||
|
|
e632dea99a | ||
|
|
560f12122f | ||
|
|
3ec5d1ef3d | ||
|
|
203d735a85 | ||
|
|
35e6d54409 | ||
|
|
2c5b4c6217 | ||
|
|
94c685a5ca | ||
|
|
28e9d112c8 | ||
|
|
4698dca813 | ||
|
|
8dbf9471a6 | ||
|
|
0ef7f0155a | ||
|
|
6f0a2de505 | ||
|
|
c23eea21fc | ||
|
|
b955a37a1c | ||
|
|
df08385603 | ||
|
|
64cf11bc54 | ||
|
|
92c4c50e1c | ||
|
|
cc572729ff | ||
|
|
79a10fa18f | ||
|
|
e3b5efc9e5 | ||
|
|
ad77a438f8 | ||
|
|
a7088ce387 | ||
|
|
b06ec1f291 | ||
|
|
8eedae1af0 | ||
|
|
a3242b4823 | ||
|
|
a037a8dbe2 | ||
|
|
eb76dd5248 | ||
|
|
143067621c | ||
|
|
84d1a8983b | ||
|
|
61b71a206d | ||
|
|
ee9ff25afc | ||
|
|
5e3e8feb0a | ||
|
|
1b63a9ad80 | ||
|
|
15a99ab650 | ||
|
|
c228361654 | ||
|
|
7d644aa544 | ||
|
|
9ef0906da1 | ||
|
|
8fd6c72037 | ||
|
|
45c08db1ce | ||
|
|
7d7b2c9e2b | ||
|
|
13ce3fc6da | ||
|
|
f55f6e198a | ||
|
|
4f68cb85e1 | ||
|
|
b7f3791966 | ||
|
|
ee8dfe1ea9 | ||
|
|
6f0d5a0583 | ||
|
|
ba1637087e |
37
.github/ISSUE_TEMPLATE/bug_report.md
vendored
37
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,37 +0,0 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Support Requests will be closed immediately, if you are not 100% certain this is a bug please go to our Reddit or Discord first. Exceptions do not mean you found a bug!
|
||||
title: ''
|
||||
labels: 'Type: Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
<!-- Support Requests will be closed immediately, if you are unsure go to our Reddit or Discord first. Exceptions do not mean you found a bug! -->
|
||||
**Describe the bug**
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**To Reproduce**
|
||||
<!-- Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error -->
|
||||
|
||||
**Expected behavior**
|
||||
<!-- A clear and concise description of what you expected to happen.-->
|
||||
|
||||
**Screenshots**
|
||||
<!-- If applicable, add screenshots to help explain your problem.-->
|
||||
|
||||
**Platform Information (please complete the following information):**
|
||||
- OS: <!-- [e.g. Windows 10 2004 / Ubuntu 20.04] -->
|
||||
- Docker: <!-- [Yes/No] -->
|
||||
- Mono or .NET Version (System -> Status): <!--[e.g. Mono 5.8 or .Net Core 3.1.10 or .NET 5.0.1] -->
|
||||
- Browser and Version (Only needed for UI issues): <!--[e.g. chrome 86.0.4240.198] -->
|
||||
- Radarr Version: <!--[e.g. 3.0.1.4259, 3.0.2.4369]-->
|
||||
- Radarr Branch: <!--[e.g. master, develop]-->
|
||||
|
||||
**Trace Logs**
|
||||
Turn on Trace logs under Settings -> General and wait for the bug to occur again.
|
||||
**Upload the full log file here (or another site (e.g. pastebin) and link it). Issues will be closed, if they do not include this!**
|
||||
<!-- Trace logs are named Radarr.trace.txt or Radarr.trace.#.txt and will contain "trace" in them-->
|
||||
75
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
75
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
name: Bug Report
|
||||
title: "[BUG]: "
|
||||
description: 'Report a new bug, if you are not 100% certain this is a bug please go to our Reddit or Discord first'
|
||||
labels: ['Type: Bug', 'Status: Needs Triage']
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
description: A concise description of what you're experiencing.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps To Reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. In this environment...
|
||||
2. With this config...
|
||||
3. Run '...'
|
||||
4. See error...
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Environment
|
||||
description: |
|
||||
examples:
|
||||
- **OS**: Ubuntu 20.04
|
||||
- **Radarr**: Radarr 3.0.1.4259
|
||||
- **Docker Install**: Yes
|
||||
- **Using Reverse Proxy**: No
|
||||
- **Browser**: Firefox 90 (If UI related)
|
||||
value: |
|
||||
- OS:
|
||||
- Radarr:
|
||||
- Docker Install:
|
||||
- Using Reverse Proxy:
|
||||
- Browser:
|
||||
render: markdown
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: What branch are you running?
|
||||
options:
|
||||
- Master
|
||||
- Develop
|
||||
- Nightly
|
||||
- Other (This issue will be closed)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: |
|
||||
Trace Logs (https://wiki.servarr.com/radarr/troubleshooting#logging-and-log-files)
|
||||
Links? References? Anything that will give us more context about the issue you are encountering!
|
||||
***Generally speaking, all bug reports must have trace logs provided.***
|
||||
|
||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||
validations:
|
||||
required: true
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: feature request
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
|
||||
|
||||
**Describe the solution you'd like**
|
||||
<!-- A clear and concise description of what you want to happen. -->
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
**Additional context**
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
39
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
39
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Feature Request
|
||||
title: "[FEAT]: "
|
||||
description: 'Suggest an idea for Radarr'
|
||||
labels: ['Type: Feature Request', 'Status: Needs Triage']
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the feature you are requesting.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe
|
||||
description: A clear and concise description of what the problem is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: |
|
||||
Links? References? Mockups? Anything that will give us more context about the feature you are encountering!
|
||||
|
||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||
validations:
|
||||
required: true
|
||||
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,15 +1,16 @@
|
||||
#### Database Migration
|
||||
YES | NO
|
||||
YES - XXXX | NO
|
||||
|
||||
#### Description
|
||||
A few sentences describing the overall goals of the pull request's commits.
|
||||
|
||||
#### Screenshot (if UI related)
|
||||
|
||||
#### Todos
|
||||
- [ ] Tests
|
||||
- [ ] Translation Keys
|
||||
- [ ] Wiki Updates
|
||||
- [ ] Translation Keys (./src/NzbDrone.Core/Localization/Core/en.json)
|
||||
- [ ] [Wiki Updates](https://wiki.servarr.com)
|
||||
|
||||
#### Issues Fixed or Closed by this PR
|
||||
|
||||
* Fixes #XXXX
|
||||
* Fixes #XXXX
|
||||
3
.github/stale.yml
vendored
3
.github/stale.yml
vendored
@@ -4,7 +4,8 @@ daysUntilStale: 60
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- feature request
|
||||
- feature request #legacy
|
||||
- 'Type: Feature Request'
|
||||
- 'Status: Confirmed'
|
||||
- sonarr-pull
|
||||
- lidarr-pull
|
||||
|
||||
41
.github/workflows/azuresync.yml
vendored
Normal file
41
.github/workflows/azuresync.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: Sync issue to Azure DevOps work item
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
[opened, edited, deleted, closed, reopened, labeled, unlabeled, assigned]
|
||||
|
||||
concurrency: azuresync-${{ github.event.issue.number }}
|
||||
|
||||
jobs:
|
||||
alert:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: danhellem/github-actions-issue-to-work-item@master
|
||||
if: "${{ contains(github.event.issue.labels.*.name, 'Type: Bug') == true }}"
|
||||
env:
|
||||
ado_token: "${{ secrets.ADO_PERSONAL_ACCESS_TOKEN }}"
|
||||
github_token: "${{ github.token }}"
|
||||
ado_organization: "Servarr"
|
||||
ado_project: "Servarr"
|
||||
ado_area_path: "Servarr\\Radarr"
|
||||
ado_wit: "Bug"
|
||||
ado_new_state: "New"
|
||||
ado_active_state: "Active"
|
||||
ado_close_state: "Closed"
|
||||
ado_bypassrules: true
|
||||
log_level: 100
|
||||
- uses: danhellem/github-actions-issue-to-work-item@master
|
||||
if: "${{ contains(github.event.issue.labels.*.name, 'Type: Bug') == false }}"
|
||||
env:
|
||||
ado_token: "${{ secrets.ADO_PERSONAL_ACCESS_TOKEN }}"
|
||||
github_token: "${{ github.token }}"
|
||||
ado_organization: "Servarr"
|
||||
ado_project: "Servarr"
|
||||
ado_area_path: "Servarr\\Radarr"
|
||||
ado_wit: "User Story"
|
||||
ado_new_state: "New"
|
||||
ado_active_state: "Active"
|
||||
ado_close_state: "Closed"
|
||||
ado_bypassrules: true
|
||||
log_level: 100
|
||||
@@ -1,49 +1,13 @@
|
||||
# How to Contribute #
|
||||
# How to Contribute
|
||||
|
||||
We're always looking for people to help make Radarr even better, there are a number of ways to contribute.
|
||||
|
||||
## Documentation ##
|
||||
Setup guides, FAQ, the more information we have on the [wiki](https://wiki.servarr.com/Radarr) the better.
|
||||
This file has been moved to the wiki for the latest details please see the [contributing wiki page](https://wiki.servarr.com/radarr/contributing).
|
||||
|
||||
## Development ##
|
||||
## Documentation
|
||||
|
||||
### Tools required ###
|
||||
- Visual Studio 2019 or higher (https://www.visualstudio.com/vs/). The community version is free and works (https://www.visualstudio.com/downloads/).
|
||||
- HTML/Javascript editor of choice (VS Code/Sublime Text/Webstorm/Atom/etc)
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
- [NodeJS](https://nodejs.org/en/download/) (Node 12.X.X or higher)
|
||||
- [Yarn](https://yarnpkg.com/)
|
||||
- .NET Core 5.0.
|
||||
Setup guides, [FAQ](https://wiki.servarr.com/radarr/faq), the more information we have on the [wiki](https://wiki.servarr.com/radarr) the better.
|
||||
|
||||
### Getting started ###
|
||||
## Development
|
||||
|
||||
1. Fork Radarr
|
||||
2. Clone the repository into your development machine. [*info*](https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository-from-github)
|
||||
3. Install the required Node Packages `yarn install`
|
||||
4. Start gulp to monitor your dev environment for any changes that need post processing using `yarn start` command.
|
||||
5. Build the project in Visual Studio, Setting startup project to `Radarr.Console` and framework to `net5.0`
|
||||
6. Debug the project in Visual Studio
|
||||
7. Open http://localhost:7878
|
||||
|
||||
### Contributing Code ###
|
||||
- If you're adding a new, already requested feature, please comment on [Github Issues](https://github.com/Radarr/Radarr/issues "Github Issues") so work is not duplicated (If you want to add something not already on there, please talk to us first)
|
||||
- Rebase from Radarr's develop branch, don't merge
|
||||
- Make meaningful commits, or squash them
|
||||
- Feel free to make a pull request before work is complete, this will let us see where its at and make comments/suggest improvements
|
||||
- Reach out to us on the discord if you have any questions
|
||||
- Add tests (unit/integration)
|
||||
- Commit with *nix line endings for consistency (We checkout Windows and commit *nix)
|
||||
- One feature/bug fix per pull request to keep things clean and easy to understand
|
||||
- Use 4 spaces instead of tabs, this is the default for VS 2019 and WebStorm (to my knowledge)
|
||||
|
||||
### Pull Requesting ###
|
||||
- Only make pull requests to develop, never master, if you make a PR to master we'll comment on it and close it
|
||||
- You're probably going to get some comments or questions from us, they will be to ensure consistency and maintainability
|
||||
- We'll try to respond to pull requests as soon as possible, if its been a day or two, please reach out to us, we may have missed it
|
||||
- Each PR should come from its own [feature branch](http://martinfowler.com/bliki/FeatureBranch.html) not develop in your fork, it should have a meaningful branch name (what is being added/fixed)
|
||||
- new-feature (Good)
|
||||
- fix-bug (Good)
|
||||
- patch (Bad)
|
||||
- develop (Bad)
|
||||
|
||||
If you have any questions about any of this, please let us know.
|
||||
See the [Wiki Page](https://wiki.servarr.com/radarr/contributing)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://dev.azure.com/Radarr/Radarr/_build/latest?definitionId=1&branchName=develop)
|
||||
[](https://translate.servarr.com/engage/radarr/?utm_source=widget)
|
||||
[](https://wiki.servarr.com/Radarr_Installation#Docker)
|
||||
[](https://wiki.servarr.com/radarr/installation#docker)
|
||||

|
||||
[](#backers)
|
||||
[](#sponsors)
|
||||
@@ -34,11 +34,7 @@ Note: GitHub Issues are for Bugs and Feature Requests Only
|
||||
[](https://radarr.video/discord)
|
||||
[](https://www.reddit.com/r/Radarr)
|
||||
[](https://github.com/Radarr/Radarr/issues)
|
||||
[](https://wiki.servarr.com/Radarr)
|
||||
|
||||
## Feature Requests
|
||||
|
||||
[Feature Requests](https://github.com/Radarr/Radarr/issues/new?assignees=&labels=Type%3A+Enhancement&template=feature_request.md&title=)
|
||||
[](https://wiki.servarr.com/radarr)
|
||||
|
||||
## Contributors & Developers
|
||||
[API Documentation](https://radarr.video/docs/api/)
|
||||
|
||||
@@ -7,13 +7,13 @@ variables:
|
||||
outputFolder: './_output'
|
||||
artifactsFolder: './_artifacts'
|
||||
testsFolder: './_tests'
|
||||
majorVersion: '3.2.1'
|
||||
majorVersion: '4.0.0'
|
||||
minorVersion: $[counter('minorVersion', 2000)]
|
||||
radarrVersion: '$(majorVersion).$(minorVersion)'
|
||||
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
|
||||
sentryOrg: 'servarr'
|
||||
sentryUrl: 'https://sentry.servarr.com'
|
||||
dotnetVersion: '5.0.202'
|
||||
dotnetVersion: '5.0.401'
|
||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||
|
||||
trigger:
|
||||
@@ -115,10 +115,6 @@ stages:
|
||||
artifact: WindowsCoreTests
|
||||
displayName: Publish Windows Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net472/linux-x64/publish'
|
||||
artifact: LinuxTests
|
||||
displayName: Publish Linux Mono Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net5.0/linux-x64/publish'
|
||||
artifact: LinuxCoreTests
|
||||
displayName: Publish Linux Test Package
|
||||
@@ -277,14 +273,6 @@ stages:
|
||||
tarCompression: 'gz'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/macos/net5.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Linux Mono tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux.tar.gz'
|
||||
archiveType: 'tar'
|
||||
tarCompression: 'gz'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-x64/net472
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Linux Core tar
|
||||
inputs:
|
||||
@@ -439,14 +427,6 @@ stages:
|
||||
- powershell: Set-Service SCardSvr -StartupType Manual
|
||||
displayName: Enable Windows Test Service
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- bash: |
|
||||
SYMLINK=6_6_0
|
||||
MONOPREFIX=/Library/Frameworks/Mono.framework/Versions/$SYMLINK
|
||||
echo "##vso[task.setvariable variable=MONOPREFIX;]$MONOPREFIX"
|
||||
echo "##vso[task.setvariable variable=PKG_CONFIG_PATH;]$MONOPREFIX/lib/pkgconfig:$MONOPREFIX/share/pkgconfig:$PKG_CONFIG_PATH"
|
||||
echo "##vso[task.setvariable variable=PATH;]$MONOPREFIX/bin:$PATH"
|
||||
displayName: Set Mono Version
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Mac'))
|
||||
- bash: find ${TESTSFOLDER} -name "Radarr.Test.Dummy" -exec chmod a+x {} \;
|
||||
displayName: Make Test Dummy Executable
|
||||
condition: and(succeeded(), ne(variables['osName'], 'Windows'))
|
||||
@@ -470,18 +450,6 @@ stages:
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
strategy:
|
||||
matrix:
|
||||
mono520:
|
||||
testName: 'Mono 5.20'
|
||||
artifactName: LinuxTests
|
||||
containerImage: ghcr.io/servarr/testimages:mono-5.20
|
||||
mono610:
|
||||
testName: 'Mono 6.10'
|
||||
artifactName: LinuxTests
|
||||
containerImage: ghcr.io/servarr/testimages:mono-6.10
|
||||
mono612:
|
||||
testName: 'Mono 6.12'
|
||||
artifactName: LinuxTests
|
||||
containerImage: ghcr.io/servarr/testimages:mono-6.12
|
||||
alpine:
|
||||
testName: 'Musl Net Core'
|
||||
artifactName: LinuxMuslCoreTests
|
||||
@@ -566,14 +534,6 @@ stages:
|
||||
vmImage: $(imageName)
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
SYMLINK=6_6_0
|
||||
MONOPREFIX=/Library/Frameworks/Mono.framework/Versions/$SYMLINK
|
||||
echo "##vso[task.setvariable variable=MONOPREFIX;]$MONOPREFIX"
|
||||
echo "##vso[task.setvariable variable=PKG_CONFIG_PATH;]$MONOPREFIX/lib/pkgconfig:$MONOPREFIX/share/pkgconfig:$PKG_CONFIG_PATH"
|
||||
echo "##vso[task.setvariable variable=PATH;]$MONOPREFIX/bin:$PATH"
|
||||
displayName: Set Mono Version
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Mac'))
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
inputs:
|
||||
@@ -665,21 +625,6 @@ stages:
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
strategy:
|
||||
matrix:
|
||||
mono520:
|
||||
testName: 'Mono 5.20'
|
||||
artifactName: LinuxTests
|
||||
containerImage: ghcr.io/servarr/testimages:mono-5.20
|
||||
pattern: 'Radarr.*.linux.tar.gz'
|
||||
mono610:
|
||||
testName: 'Mono 6.10'
|
||||
artifactName: LinuxTests
|
||||
containerImage: ghcr.io/servarr/testimages:mono-6.10
|
||||
pattern: 'Radarr.*.linux.tar.gz'
|
||||
mono612:
|
||||
testName: 'Mono 6.12'
|
||||
artifactName: LinuxTests
|
||||
containerImage: ghcr.io/servarr/testimages:mono-6.12
|
||||
pattern: 'Radarr.*.linux.tar.gz'
|
||||
alpine:
|
||||
testName: 'Musl Net Core'
|
||||
artifactName: LinuxMuslCoreTests
|
||||
@@ -916,7 +861,7 @@ stages:
|
||||
projectVersion: '$(radarrVersion)'
|
||||
extraProperties: |
|
||||
sonar.exclusions=**/obj/**,**/*.dll,**/NzbDrone.Core.Test/Files/**/*,./frontend/**,**/ExternalModules/**,./src/Libraries/**
|
||||
sonar.coverage.exclusions=**/Radarr.Api.V3/**/*,**/NzbDrone.Api/**/*,**/MonoTorrent/**/*,**/Marr.Data/**/*
|
||||
sonar.coverage.exclusions=**/Radarr.Api.V3/**/*
|
||||
sonar.cs.opencover.reportsPaths=$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml
|
||||
sonar.cs.nunit.reportsPaths=$(Build.SourcesDirectory)/TestResult.xml
|
||||
- bash: |
|
||||
@@ -951,7 +896,7 @@ stages:
|
||||
- job:
|
||||
displayName: Discord Notification
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
vmImage: 'ubuntu-18.04'
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
continueOnError: true
|
||||
@@ -961,7 +906,7 @@ stages:
|
||||
artifactName: 'WindowsAutomationScreenshots'
|
||||
targetPath: $(Build.SourcesDirectory)
|
||||
- checkout: none
|
||||
- powershell: |
|
||||
- pwsh: |
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/Servarr/AzureDiscordNotify/master/DiscordNotify.ps1'))
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
|
||||
8
build.sh
8
build.sh
@@ -33,7 +33,6 @@ EnableBsdSupport()
|
||||
|
||||
if grep -qv freebsd-x64 src/Directory.Build.props; then
|
||||
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64</RuntimeIdentifiers>^g" src/Directory.Build.props
|
||||
sed -i'' -e "s^<ExcludedRuntimeFrameworkPairs>\(.*\)</ExcludedRuntimeFrameworkPairs>^<ExcludedRuntimeFrameworkPairs>\1;freebsd-x64:net472</ExcludedRuntimeFrameworkPairs>^g" src/Directory.Build.props
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -148,11 +147,6 @@ PackageMacOS()
|
||||
|
||||
PackageFiles "$folder" "$framework" "osx-x64"
|
||||
|
||||
if [ "$framework" = "net472" ]; then
|
||||
echo "Adding Startup script"
|
||||
cp macOS/Radarr $folder
|
||||
fi
|
||||
|
||||
echo "Removing Service helpers"
|
||||
rm -f $folder/ServiceUninstall.*
|
||||
rm -f $folder/ServiceInstall.*
|
||||
@@ -337,7 +331,6 @@ then
|
||||
PackageTests "net5.0" "linux-x64"
|
||||
PackageTests "net5.0" "linux-musl-x64"
|
||||
PackageTests "net5.0" "osx-x64"
|
||||
PackageTests "net472" "linux-x64"
|
||||
if [ "$ENABLE_BSD" = "YES" ];
|
||||
then
|
||||
PackageTests "net5.0" "freebsd-x64"
|
||||
@@ -377,7 +370,6 @@ then
|
||||
Package "net5.0" "linux-musl-arm64"
|
||||
Package "net5.0" "linux-arm"
|
||||
Package "net5.0" "osx-x64"
|
||||
Package "net472" "linux-x64"
|
||||
if [ "$ENABLE_BSD" = "YES" ];
|
||||
then
|
||||
Package "net5.0" "freebsd-x64"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const FileManagerPlugin = require('filemanager-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const LiveReloadPlugin = require('webpack-livereload-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
@@ -23,7 +23,7 @@ module.exports = (env) => {
|
||||
|
||||
const config = {
|
||||
mode: isProduction ? 'production' : 'development',
|
||||
devtool: 'source-map',
|
||||
devtool: isProduction ? 'source-map' : 'eval-source-map',
|
||||
|
||||
stats: {
|
||||
children: false
|
||||
@@ -87,46 +87,47 @@ module.exports = (env) => {
|
||||
}),
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'frontend/src/index.html',
|
||||
template: 'frontend/src/index.ejs',
|
||||
filename: 'index.html',
|
||||
publicPath: '/'
|
||||
}),
|
||||
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
// HTML
|
||||
{
|
||||
from: 'frontend/src/*.html',
|
||||
to: path.join(distFolder, '[name][ext]'),
|
||||
globOptions: {
|
||||
ignore: ['**/index.html']
|
||||
}
|
||||
},
|
||||
new FileManagerPlugin({
|
||||
events: {
|
||||
onEnd: {
|
||||
copy: [
|
||||
// HTML
|
||||
{
|
||||
source: 'frontend/src/*.html',
|
||||
destination: distFolder
|
||||
},
|
||||
|
||||
// Fonts
|
||||
{
|
||||
from: 'frontend/src/Content/Fonts/*.*',
|
||||
to: path.join(distFolder, 'Content/Fonts', '[name][ext]')
|
||||
},
|
||||
// Fonts
|
||||
{
|
||||
source: 'frontend/src/Content/Fonts/*.*',
|
||||
destination: path.join(distFolder, 'Content/Fonts')
|
||||
},
|
||||
|
||||
// Icon Images
|
||||
{
|
||||
from: 'frontend/src/Content/Images/Icons/*.*',
|
||||
to: path.join(distFolder, 'Content/Images/Icons', '[name][ext]')
|
||||
},
|
||||
// Icon Images
|
||||
{
|
||||
source: 'frontend/src/Content/Images/Icons/*.*',
|
||||
destination: path.join(distFolder, 'Content/Images/Icons')
|
||||
},
|
||||
|
||||
// Images
|
||||
{
|
||||
from: 'frontend/src/Content/Images/*.*',
|
||||
to: path.join(distFolder, 'Content/Images', '[name][ext]')
|
||||
},
|
||||
// Images
|
||||
{
|
||||
source: 'frontend/src/Content/Images/*.*',
|
||||
destination: path.join(distFolder, 'Content/Images')
|
||||
},
|
||||
|
||||
// Robots
|
||||
{
|
||||
from: 'frontend/src/Content/robots.txt',
|
||||
to: path.join(distFolder, 'Content', '[name][ext]')
|
||||
// Robots
|
||||
{
|
||||
source: 'frontend/src/Content/robots.txt',
|
||||
destination: path.join(distFolder, 'Content/robots.txt')
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}),
|
||||
|
||||
new LiveReloadPlugin()
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import withCurrentPage from 'Components/withCurrentPage';
|
||||
import * as blacklistActions from 'Store/Actions/blacklistActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
|
||||
import Blacklist from './Blacklist';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.blacklist,
|
||||
createCommandExecutingSelector(commandNames.CLEAR_BLACKLIST),
|
||||
(blacklist, isClearingBlacklistExecuting) => {
|
||||
return {
|
||||
isClearingBlacklistExecuting,
|
||||
...blacklist
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
...blacklistActions,
|
||||
executeCommand
|
||||
};
|
||||
|
||||
class BlacklistConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
const {
|
||||
useCurrentPage,
|
||||
fetchBlacklist,
|
||||
gotoBlacklistFirstPage
|
||||
} = this.props;
|
||||
|
||||
registerPagePopulator(this.repopulate);
|
||||
|
||||
if (useCurrentPage) {
|
||||
fetchBlacklist();
|
||||
} else {
|
||||
gotoBlacklistFirstPage();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.isClearingBlacklistExecuting && !this.props.isClearingBlacklistExecuting) {
|
||||
this.props.gotoBlacklistFirstPage();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.clearBlacklist();
|
||||
unregisterPagePopulator(this.repopulate);
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
repopulate = () => {
|
||||
this.props.fetchBlacklist();
|
||||
}
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onFirstPagePress = () => {
|
||||
this.props.gotoBlacklistFirstPage();
|
||||
}
|
||||
|
||||
onPreviousPagePress = () => {
|
||||
this.props.gotoBlacklistPreviousPage();
|
||||
}
|
||||
|
||||
onNextPagePress = () => {
|
||||
this.props.gotoBlacklistNextPage();
|
||||
}
|
||||
|
||||
onLastPagePress = () => {
|
||||
this.props.gotoBlacklistLastPage();
|
||||
}
|
||||
|
||||
onPageSelect = (page) => {
|
||||
this.props.gotoBlacklistPage({ page });
|
||||
}
|
||||
|
||||
onRemoveSelected = (ids) => {
|
||||
this.props.removeBlacklistItems({ ids });
|
||||
}
|
||||
|
||||
onSortPress = (sortKey) => {
|
||||
this.props.setBlacklistSort({ sortKey });
|
||||
}
|
||||
|
||||
onTableOptionChange = (payload) => {
|
||||
this.props.setBlacklistTableOption(payload);
|
||||
|
||||
if (payload.pageSize) {
|
||||
this.props.gotoBlacklistFirstPage();
|
||||
}
|
||||
}
|
||||
|
||||
onClearBlacklistPress = () => {
|
||||
this.props.executeCommand({ name: commandNames.CLEAR_BLACKLIST });
|
||||
}
|
||||
|
||||
onTableOptionChange = (payload) => {
|
||||
this.props.setBlacklistTableOption(payload);
|
||||
|
||||
if (payload.pageSize) {
|
||||
this.props.gotoBlacklistFirstPage();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Blacklist
|
||||
onFirstPagePress={this.onFirstPagePress}
|
||||
onPreviousPagePress={this.onPreviousPagePress}
|
||||
onNextPagePress={this.onNextPagePress}
|
||||
onLastPagePress={this.onLastPagePress}
|
||||
onPageSelect={this.onPageSelect}
|
||||
onRemoveSelected={this.onRemoveSelected}
|
||||
onSortPress={this.onSortPress}
|
||||
onTableOptionChange={this.onTableOptionChange}
|
||||
onClearBlacklistPress={this.onClearBlacklistPress}
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
BlacklistConnector.propTypes = {
|
||||
useCurrentPage: PropTypes.bool.isRequired,
|
||||
isClearingBlacklistExecuting: PropTypes.bool.isRequired,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
fetchBlacklist: PropTypes.func.isRequired,
|
||||
gotoBlacklistFirstPage: PropTypes.func.isRequired,
|
||||
gotoBlacklistPreviousPage: PropTypes.func.isRequired,
|
||||
gotoBlacklistNextPage: PropTypes.func.isRequired,
|
||||
gotoBlacklistLastPage: PropTypes.func.isRequired,
|
||||
gotoBlacklistPage: PropTypes.func.isRequired,
|
||||
removeBlacklistItems: PropTypes.func.isRequired,
|
||||
setBlacklistSort: PropTypes.func.isRequired,
|
||||
setBlacklistTableOption: PropTypes.func.isRequired,
|
||||
clearBlacklist: PropTypes.func.isRequired,
|
||||
executeCommand: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default withCurrentPage(
|
||||
connect(createMapStateToProps, mapDispatchToProps)(BlacklistConnector)
|
||||
);
|
||||
@@ -19,9 +19,9 @@ import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import removeOldSelectedState from 'Utilities/Table/removeOldSelectedState';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
import BlacklistRowConnector from './BlacklistRowConnector';
|
||||
import BlocklistRowConnector from './BlocklistRowConnector';
|
||||
|
||||
class Blacklist extends Component {
|
||||
class Blocklist extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
@@ -101,8 +101,8 @@ class Blacklist extends Component {
|
||||
columns,
|
||||
totalRecords,
|
||||
isRemoving,
|
||||
isClearingBlacklistExecuting,
|
||||
onClearBlacklistPress,
|
||||
isClearingBlocklistExecuting,
|
||||
onClearBlocklistPress,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
@@ -116,7 +116,7 @@ class Blacklist extends Component {
|
||||
const selectedIds = this.getSelectedIds();
|
||||
|
||||
return (
|
||||
<PageContent title={translate('Blacklist')}>
|
||||
<PageContent title={translate('Blocklist')}>
|
||||
<PageToolbar>
|
||||
<PageToolbarSection>
|
||||
<PageToolbarButton
|
||||
@@ -130,8 +130,8 @@ class Blacklist extends Component {
|
||||
<PageToolbarButton
|
||||
label={translate('Clear')}
|
||||
iconName={icons.CLEAR}
|
||||
isSpinning={isClearingBlacklistExecuting}
|
||||
onPress={onClearBlacklistPress}
|
||||
isSpinning={isClearingBlocklistExecuting}
|
||||
onPress={onClearBlocklistPress}
|
||||
/>
|
||||
</PageToolbarSection>
|
||||
|
||||
@@ -157,7 +157,7 @@ class Blacklist extends Component {
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>
|
||||
{translate('UnableToLoadBlacklist')}
|
||||
{translate('UnableToLoadBlocklist')}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ class Blacklist extends Component {
|
||||
{
|
||||
items.map((item) => {
|
||||
return (
|
||||
<BlacklistRowConnector
|
||||
<BlocklistRowConnector
|
||||
key={item.id}
|
||||
isSelected={selectedState[item.id] || false}
|
||||
columns={columns}
|
||||
@@ -209,7 +209,7 @@ class Blacklist extends Component {
|
||||
isOpen={isConfirmRemoveModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title={translate('RemoveSelected')}
|
||||
message={translate('AreYouSureYouWantToRemoveTheSelectedItemsFromBlacklist')}
|
||||
message={translate('AreYouSureYouWantToRemoveTheSelectedItemsFromBlocklist')}
|
||||
confirmLabel={translate('RemoveSelected')}
|
||||
onConfirm={this.onRemoveSelectedConfirmed}
|
||||
onCancel={this.onConfirmRemoveModalClose}
|
||||
@@ -219,7 +219,7 @@ class Blacklist extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
Blacklist.propTypes = {
|
||||
Blocklist.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
@@ -227,9 +227,9 @@ Blacklist.propTypes = {
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
totalRecords: PropTypes.number,
|
||||
isRemoving: PropTypes.bool.isRequired,
|
||||
isClearingBlacklistExecuting: PropTypes.bool.isRequired,
|
||||
isClearingBlocklistExecuting: PropTypes.bool.isRequired,
|
||||
onRemoveSelected: PropTypes.func.isRequired,
|
||||
onClearBlacklistPress: PropTypes.func.isRequired
|
||||
onClearBlocklistPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default Blacklist;
|
||||
export default Blocklist;
|
||||
152
frontend/src/Activity/Blocklist/BlocklistConnector.js
Normal file
152
frontend/src/Activity/Blocklist/BlocklistConnector.js
Normal file
@@ -0,0 +1,152 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import withCurrentPage from 'Components/withCurrentPage';
|
||||
import * as blocklistActions from 'Store/Actions/blocklistActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
|
||||
import Blocklist from './Blocklist';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.blocklist,
|
||||
createCommandExecutingSelector(commandNames.CLEAR_BLOCKLIST),
|
||||
(blocklist, isClearingBlocklistExecuting) => {
|
||||
return {
|
||||
isClearingBlocklistExecuting,
|
||||
...blocklist
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
...blocklistActions,
|
||||
executeCommand
|
||||
};
|
||||
|
||||
class BlocklistConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
const {
|
||||
useCurrentPage,
|
||||
fetchBlocklist,
|
||||
gotoBlocklistFirstPage
|
||||
} = this.props;
|
||||
|
||||
registerPagePopulator(this.repopulate);
|
||||
|
||||
if (useCurrentPage) {
|
||||
fetchBlocklist();
|
||||
} else {
|
||||
gotoBlocklistFirstPage();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.isClearingBlocklistExecuting && !this.props.isClearingBlocklistExecuting) {
|
||||
this.props.gotoBlocklistFirstPage();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.clearBlocklist();
|
||||
unregisterPagePopulator(this.repopulate);
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
repopulate = () => {
|
||||
this.props.fetchBlocklist();
|
||||
}
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onFirstPagePress = () => {
|
||||
this.props.gotoBlocklistFirstPage();
|
||||
}
|
||||
|
||||
onPreviousPagePress = () => {
|
||||
this.props.gotoBlocklistPreviousPage();
|
||||
}
|
||||
|
||||
onNextPagePress = () => {
|
||||
this.props.gotoBlocklistNextPage();
|
||||
}
|
||||
|
||||
onLastPagePress = () => {
|
||||
this.props.gotoBlocklistLastPage();
|
||||
}
|
||||
|
||||
onPageSelect = (page) => {
|
||||
this.props.gotoBlocklistPage({ page });
|
||||
}
|
||||
|
||||
onRemoveSelected = (ids) => {
|
||||
this.props.removeBlocklistItems({ ids });
|
||||
}
|
||||
|
||||
onSortPress = (sortKey) => {
|
||||
this.props.setBlocklistSort({ sortKey });
|
||||
}
|
||||
|
||||
onTableOptionChange = (payload) => {
|
||||
this.props.setBlocklistTableOption(payload);
|
||||
|
||||
if (payload.pageSize) {
|
||||
this.props.gotoBlocklistFirstPage();
|
||||
}
|
||||
}
|
||||
|
||||
onClearBlocklistPress = () => {
|
||||
this.props.executeCommand({ name: commandNames.CLEAR_BLOCKLIST });
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Blocklist
|
||||
onFirstPagePress={this.onFirstPagePress}
|
||||
onPreviousPagePress={this.onPreviousPagePress}
|
||||
onNextPagePress={this.onNextPagePress}
|
||||
onLastPagePress={this.onLastPagePress}
|
||||
onPageSelect={this.onPageSelect}
|
||||
onRemoveSelected={this.onRemoveSelected}
|
||||
onSortPress={this.onSortPress}
|
||||
onTableOptionChange={this.onTableOptionChange}
|
||||
onClearBlocklistPress={this.onClearBlocklistPress}
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
BlocklistConnector.propTypes = {
|
||||
useCurrentPage: PropTypes.bool.isRequired,
|
||||
isClearingBlocklistExecuting: PropTypes.bool.isRequired,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
fetchBlocklist: PropTypes.func.isRequired,
|
||||
gotoBlocklistFirstPage: PropTypes.func.isRequired,
|
||||
gotoBlocklistPreviousPage: PropTypes.func.isRequired,
|
||||
gotoBlocklistNextPage: PropTypes.func.isRequired,
|
||||
gotoBlocklistLastPage: PropTypes.func.isRequired,
|
||||
gotoBlocklistPage: PropTypes.func.isRequired,
|
||||
removeBlocklistItems: PropTypes.func.isRequired,
|
||||
setBlocklistSort: PropTypes.func.isRequired,
|
||||
setBlocklistTableOption: PropTypes.func.isRequired,
|
||||
clearBlocklist: PropTypes.func.isRequired,
|
||||
executeCommand: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default withCurrentPage(
|
||||
connect(createMapStateToProps, mapDispatchToProps)(BlocklistConnector)
|
||||
);
|
||||
@@ -10,7 +10,7 @@ import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
class BlacklistDetailsModal extends Component {
|
||||
class BlocklistDetailsModal extends Component {
|
||||
|
||||
//
|
||||
// Render
|
||||
@@ -78,7 +78,7 @@ class BlacklistDetailsModal extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
BlacklistDetailsModal.propTypes = {
|
||||
BlocklistDetailsModal.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
sourceTitle: PropTypes.string.isRequired,
|
||||
protocol: PropTypes.string.isRequired,
|
||||
@@ -87,4 +87,4 @@ BlacklistDetailsModal.propTypes = {
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default BlacklistDetailsModal;
|
||||
export default BlocklistDetailsModal;
|
||||
@@ -11,10 +11,10 @@ import MovieLanguage from 'Movie/MovieLanguage';
|
||||
import MovieQuality from 'Movie/MovieQuality';
|
||||
import MovieTitleLink from 'Movie/MovieTitleLink';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import BlacklistDetailsModal from './BlacklistDetailsModal';
|
||||
import styles from './BlacklistRow.css';
|
||||
import BlocklistDetailsModal from './BlocklistDetailsModal';
|
||||
import styles from './BlocklistRow.css';
|
||||
|
||||
class BlacklistRow extends Component {
|
||||
class BlocklistRow extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
@@ -166,7 +166,7 @@ class BlacklistRow extends Component {
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
title={translate('RemoveFromBlacklist')}
|
||||
title={translate('RemoveFromBlocklist')}
|
||||
name={icons.REMOVE}
|
||||
kind={kinds.DANGER}
|
||||
onPress={onRemovePress}
|
||||
@@ -179,7 +179,7 @@ class BlacklistRow extends Component {
|
||||
})
|
||||
}
|
||||
|
||||
<BlacklistDetailsModal
|
||||
<BlocklistDetailsModal
|
||||
isOpen={this.state.isDetailsModalOpen}
|
||||
sourceTitle={sourceTitle}
|
||||
protocol={protocol}
|
||||
@@ -193,7 +193,7 @@ class BlacklistRow extends Component {
|
||||
|
||||
}
|
||||
|
||||
BlacklistRow.propTypes = {
|
||||
BlocklistRow.propTypes = {
|
||||
id: PropTypes.number.isRequired,
|
||||
movie: PropTypes.object.isRequired,
|
||||
sourceTitle: PropTypes.string.isRequired,
|
||||
@@ -210,4 +210,4 @@ BlacklistRow.propTypes = {
|
||||
onRemovePress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default BlacklistRow;
|
||||
export default BlocklistRow;
|
||||
@@ -1,8 +1,8 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { removeBlacklistItem } from 'Store/Actions/blacklistActions';
|
||||
import { removeBlocklistItem } from 'Store/Actions/blocklistActions';
|
||||
import createMovieSelector from 'Store/Selectors/createMovieSelector';
|
||||
import BlacklistRow from './BlacklistRow';
|
||||
import BlocklistRow from './BlocklistRow';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
@@ -18,9 +18,9 @@ function createMapStateToProps() {
|
||||
function createMapDispatchToProps(dispatch, props) {
|
||||
return {
|
||||
onRemovePress() {
|
||||
dispatch(removeBlacklistItem({ id: props.id }));
|
||||
dispatch(removeBlocklistItem({ id: props.id }));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(BlacklistRow);
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(BlocklistRow);
|
||||
@@ -42,14 +42,14 @@ class QueueRow extends Component {
|
||||
this.setState({ isRemoveQueueItemModalOpen: true });
|
||||
}
|
||||
|
||||
onRemoveQueueItemModalConfirmed = (blacklist) => {
|
||||
onRemoveQueueItemModalConfirmed = (blocklist) => {
|
||||
const {
|
||||
onRemoveQueueItemPress,
|
||||
onQueueRowModalOpenOrClose
|
||||
} = this.props;
|
||||
|
||||
onQueueRowModalOpenOrClose(false);
|
||||
onRemoveQueueItemPress(blacklist);
|
||||
onRemoveQueueItemPress(blocklist);
|
||||
|
||||
this.setState({ isRemoveQueueItemModalOpen: false });
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class RemoveQueueItemModal extends Component {
|
||||
|
||||
this.state = {
|
||||
remove: true,
|
||||
blacklist: false
|
||||
blocklist: false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class RemoveQueueItemModal extends Component {
|
||||
resetState = function() {
|
||||
this.setState({
|
||||
remove: true,
|
||||
blacklist: false
|
||||
blocklist: false
|
||||
});
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ class RemoveQueueItemModal extends Component {
|
||||
this.setState({ remove: value });
|
||||
}
|
||||
|
||||
onBlacklistChange = ({ value }) => {
|
||||
this.setState({ blacklist: value });
|
||||
onBlocklistChange = ({ value }) => {
|
||||
this.setState({ blocklist: value });
|
||||
}
|
||||
|
||||
onRemoveConfirmed = () => {
|
||||
@@ -69,7 +69,7 @@ class RemoveQueueItemModal extends Component {
|
||||
canIgnore
|
||||
} = this.props;
|
||||
|
||||
const { remove, blacklist } = this.state;
|
||||
const { remove, blocklist } = this.state;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@@ -103,13 +103,13 @@ class RemoveQueueItemModal extends Component {
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('BlacklistRelease')}</FormLabel>
|
||||
<FormLabel>{translate('BlocklistRelease')}</FormLabel>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="blacklist"
|
||||
value={blacklist}
|
||||
helpText={translate('BlacklistHelpText')}
|
||||
onChange={this.onBlacklistChange}
|
||||
name="blocklist"
|
||||
value={blocklist}
|
||||
helpText={translate('BlocklistHelpText')}
|
||||
onChange={this.onBlocklistChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class RemoveQueueItemsModal extends Component {
|
||||
|
||||
this.state = {
|
||||
remove: true,
|
||||
blacklist: false
|
||||
blocklist: false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class RemoveQueueItemsModal extends Component {
|
||||
resetState = function() {
|
||||
this.setState({
|
||||
remove: true,
|
||||
blacklist: false
|
||||
blocklist: false
|
||||
});
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ class RemoveQueueItemsModal extends Component {
|
||||
this.setState({ remove: value });
|
||||
}
|
||||
|
||||
onBlacklistChange = ({ value }) => {
|
||||
this.setState({ blacklist: value });
|
||||
onBlocklistChange = ({ value }) => {
|
||||
this.setState({ blocklist: value });
|
||||
}
|
||||
|
||||
onRemoveConfirmed = () => {
|
||||
@@ -70,7 +70,7 @@ class RemoveQueueItemsModal extends Component {
|
||||
canIgnore
|
||||
} = this.props;
|
||||
|
||||
const { remove, blacklist } = this.state;
|
||||
const { remove, blocklist } = this.state;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@@ -105,15 +105,15 @@ class RemoveQueueItemsModal extends Component {
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>
|
||||
Blacklist Release{selectedCount > 1 ? 's' : ''}
|
||||
Blocklist Release{selectedCount > 1 ? 's' : ''}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="blacklist"
|
||||
value={blacklist}
|
||||
helpText={translate('BlacklistHelpText')}
|
||||
onChange={this.onBlacklistChange}
|
||||
name="blocklist"
|
||||
value={blocklist}
|
||||
helpText={translate('BlocklistHelpText')}
|
||||
onChange={this.onBlocklistChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class AddNewMovie extends Component {
|
||||
className={styles.searchInput}
|
||||
name="movieLookup"
|
||||
value={term}
|
||||
placeholder="eg. The Dark Knight, tmdb:155, imdb:tt0468569"
|
||||
placeholder="e.g. The Dark Knight, tmdb:155, imdb:tt0468569"
|
||||
autoFocus={true}
|
||||
onChange={this.onSearchInputChange}
|
||||
/>
|
||||
@@ -161,7 +161,7 @@ class AddNewMovie extends Component {
|
||||
{translate('YouCanAlsoSearch')}
|
||||
</div>
|
||||
<div>
|
||||
<Link to="https://wiki.servarr.com/Radarr_FAQ#Why_cant_I_add_a_new_movie_to_Radarr">
|
||||
<Link to="https://wiki.servarr.com/radarr/faq#why-cant-i-add-a-new-movie-to-radarr">
|
||||
{translate('CantFindMovie')}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -30,3 +30,9 @@
|
||||
.importButtonIcon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.addErrorAlert {
|
||||
composes: alert from '~Components/Alert.css';
|
||||
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Alert from 'Components/Alert';
|
||||
import FieldSet from 'Components/FieldSet';
|
||||
import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal';
|
||||
import Icon from 'Components/Icon';
|
||||
@@ -72,23 +73,29 @@ class ImportMovieSelectFolder extends Component {
|
||||
isWindows,
|
||||
isFetching,
|
||||
isPopulated,
|
||||
isSaving,
|
||||
error,
|
||||
saveError,
|
||||
items
|
||||
} = this.props;
|
||||
|
||||
const hasRootFolders = items.length > 0;
|
||||
|
||||
return (
|
||||
<PageContent title={translate('ImportMovies')}>
|
||||
<PageContentBody>
|
||||
{
|
||||
isFetching && !isPopulated &&
|
||||
<LoadingIndicator />
|
||||
isFetching && !isPopulated ?
|
||||
<LoadingIndicator /> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
!isFetching && error ?
|
||||
<div>
|
||||
{translate('UnableToLoadRootFolders')}
|
||||
</div>
|
||||
</div> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
@@ -108,7 +115,7 @@ class ImportMovieSelectFolder extends Component {
|
||||
</div>
|
||||
|
||||
{
|
||||
items.length > 0 ?
|
||||
hasRootFolders ?
|
||||
<div className={styles.recentFolders}>
|
||||
<FieldSet legend={translate('RecentFolders')}>
|
||||
<Table
|
||||
@@ -131,35 +138,51 @@ class ImportMovieSelectFolder extends Component {
|
||||
</TableBody>
|
||||
</Table>
|
||||
</FieldSet>
|
||||
|
||||
<Button
|
||||
kind={kinds.PRIMARY}
|
||||
size={sizes.LARGE}
|
||||
onPress={this.onAddNewRootFolderPress}
|
||||
>
|
||||
<Icon
|
||||
className={styles.importButtonIcon}
|
||||
name={icons.DRIVE}
|
||||
/>
|
||||
{translate('ChooseAnotherFolder')}
|
||||
</Button>
|
||||
</div> :
|
||||
|
||||
<div className={styles.startImport}>
|
||||
<Button
|
||||
kind={kinds.PRIMARY}
|
||||
size={sizes.LARGE}
|
||||
onPress={this.onAddNewRootFolderPress}
|
||||
>
|
||||
<Icon
|
||||
className={styles.importButtonIcon}
|
||||
name={icons.DRIVE}
|
||||
/>
|
||||
{translate('StartImport')}
|
||||
</Button>
|
||||
</div>
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
!isSaving && saveError ?
|
||||
<Alert
|
||||
className={styles.addErrorAlert}
|
||||
kind={kinds.DANGER}
|
||||
>
|
||||
{translate('UnableToAddRootFolder')}
|
||||
|
||||
<ul>
|
||||
{
|
||||
saveError.responseJSON.map((e, index) => {
|
||||
return (
|
||||
<li key={index}>
|
||||
{e.errorMessage}
|
||||
</li>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</Alert> :
|
||||
null
|
||||
}
|
||||
|
||||
<div className={hasRootFolders ? undefined : styles.startImport}>
|
||||
<Button
|
||||
kind={kinds.PRIMARY}
|
||||
size={sizes.LARGE}
|
||||
onPress={this.onAddNewRootFolderPress}
|
||||
>
|
||||
<Icon
|
||||
className={styles.importButtonIcon}
|
||||
name={icons.DRIVE}
|
||||
/>
|
||||
{
|
||||
hasRootFolders ?
|
||||
translate('ChooseAnotherFolder') :
|
||||
translate('StartImport')
|
||||
}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<FileBrowserModal
|
||||
isOpen={this.state.isAddNewRootFolderModalOpen}
|
||||
name="rootFolderPath"
|
||||
@@ -179,7 +202,9 @@ ImportMovieSelectFolder.propTypes = {
|
||||
isWindows: PropTypes.bool.isRequired,
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
saveError: PropTypes.object,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onNewRootFolderSelect: PropTypes.func.isRequired,
|
||||
onDeleteRootFolderPress: PropTypes.func.isRequired
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { Redirect, Route } from 'react-router-dom';
|
||||
import BlacklistConnector from 'Activity/Blacklist/BlacklistConnector';
|
||||
import BlocklistConnector from 'Activity/Blocklist/BlocklistConnector';
|
||||
import HistoryConnector from 'Activity/History/HistoryConnector';
|
||||
import QueueConnector from 'Activity/Queue/QueueConnector';
|
||||
import AddNewMovieConnector from 'AddMovie/AddNewMovie/AddNewMovieConnector';
|
||||
@@ -111,8 +111,8 @@ function AppRoutes(props) {
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/activity/blacklist"
|
||||
component={BlacklistConnector}
|
||||
path="/activity/blocklist"
|
||||
component={BlocklistConnector}
|
||||
/>
|
||||
|
||||
{/*
|
||||
|
||||
@@ -54,20 +54,24 @@
|
||||
composes: downloaded from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.downloading {
|
||||
composes: downloading from '~Calendar/Events/CalendarEvent.css';
|
||||
.queue {
|
||||
composes: queue from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.unmonitored {
|
||||
composes: unmonitored from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.missing {
|
||||
composes: missing from '~Calendar/Events/CalendarEvent.css';
|
||||
.missingUnmonitored {
|
||||
composes: missingUnmonitored from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.unreleased {
|
||||
composes: unreleased from '~Calendar/Events/CalendarEvent.css';
|
||||
.missingMonitored {
|
||||
composes: missingMonitored from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.continuing {
|
||||
composes: continuing from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $breakpointSmall) {
|
||||
|
||||
@@ -3,10 +3,10 @@ import moment from 'moment';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import CalendarEventQueueDetails from 'Calendar/Events/CalendarEventQueueDetails';
|
||||
import getStatusStyle from 'Calendar/getStatusStyle';
|
||||
import Icon from 'Components/Icon';
|
||||
import Link from 'Components/Link/Link';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import getStatusStyle from 'Utilities/Movie/getStatusStyle';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AgendaEvent.css';
|
||||
|
||||
@@ -82,7 +82,7 @@ class AgendaEvent extends Component {
|
||||
startTime = moment(startTime);
|
||||
const downloading = !!(queueItem || grabbed);
|
||||
const isMonitored = monitored;
|
||||
const statusStyle = getStatusStyle(hasFile, downloading, isAvailable, isMonitored);
|
||||
const statusStyle = getStatusStyle(null, isMonitored, hasFile, isAvailable, 'style', downloading);
|
||||
const joinedGenres = genres.slice(0, 2).join(', ');
|
||||
const link = `/movie/${titleSlug}`;
|
||||
|
||||
|
||||
@@ -60,39 +60,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.downloading {
|
||||
.queue {
|
||||
border-left-color: $purple !important;
|
||||
}
|
||||
|
||||
.unmonitored {
|
||||
border-left-color: $gray !important;
|
||||
}
|
||||
|
||||
.missingUnmonitored {
|
||||
border-left-color: $warningColor !important;
|
||||
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(45deg, $colorImpairedGradientDark, $colorImpairedGradientDark 5px, $colorImpairedGradient 5px, $colorImpairedGradient 10px);
|
||||
}
|
||||
}
|
||||
|
||||
.onAir {
|
||||
border-left-color: $warningColor !important;
|
||||
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(90deg, $colorImpairedGradientDark, $colorImpairedGradientDark 5px, $colorImpairedGradient 5px, $colorImpairedGradient 10px);
|
||||
}
|
||||
}
|
||||
|
||||
.missing {
|
||||
.missingMonitored {
|
||||
border-left-color: $dangerColor !important;
|
||||
|
||||
&:global(.colorImpaired) {
|
||||
border-left-color: color($dangerColor saturation(+15%)) !important;
|
||||
background: repeating-linear-gradient(90deg, $colorImpairedGradientDark, $colorImpairedGradientDark 5px, $colorImpairedGradient 5px, $colorImpairedGradient 10px);
|
||||
}
|
||||
}
|
||||
|
||||
.unreleased {
|
||||
.continuing {
|
||||
border-left-color: $primaryColor !important;
|
||||
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(90deg, $colorImpairedGradientDark, $colorImpairedGradientDark 5px, $colorImpairedGradient 5px, $colorImpairedGradient 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ import classNames from 'classnames';
|
||||
import moment from 'moment';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import getStatusStyle from 'Calendar/getStatusStyle';
|
||||
import Icon from 'Components/Icon';
|
||||
import Link from 'Components/Link/Link';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import getStatusStyle from 'Utilities/Movie/getStatusStyle';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import CalendarEventQueueDetails from './CalendarEventQueueDetails';
|
||||
import styles from './CalendarEvent.css';
|
||||
@@ -38,7 +38,7 @@ class CalendarEvent extends Component {
|
||||
|
||||
const isDownloading = !!(queueItem || grabbed);
|
||||
const isMonitored = monitored;
|
||||
const statusStyle = getStatusStyle(hasFile, isDownloading, isAvailable, isMonitored);
|
||||
const statusStyle = getStatusStyle(null, isMonitored, hasFile, isAvailable, 'style', isDownloading);
|
||||
const joinedGenres = genres.slice(0, 2).join(', ');
|
||||
const link = `/movie/${titleSlug}`;
|
||||
const eventType = [];
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
function getStatusStyle(hasFile, downloading, isAvailable, isMonitored) {
|
||||
|
||||
if (hasFile) {
|
||||
return 'downloaded';
|
||||
}
|
||||
|
||||
if (downloading) {
|
||||
return 'downloading';
|
||||
}
|
||||
|
||||
if (!isMonitored) {
|
||||
return 'unmonitored';
|
||||
}
|
||||
|
||||
if (isAvailable && !hasFile) {
|
||||
return 'missing';
|
||||
}
|
||||
|
||||
return 'unreleased';
|
||||
}
|
||||
|
||||
export default getStatusStyle;
|
||||
@@ -1,7 +1,7 @@
|
||||
export const APPLICATION_UPDATE = 'ApplicationUpdate';
|
||||
export const BACKUP = 'Backup';
|
||||
export const REFRESH_MONITORED_DOWNLOADS = 'RefreshMonitoredDownloads';
|
||||
export const CLEAR_BLACKLIST = 'ClearBlacklist';
|
||||
export const CLEAR_BLOCKLIST = 'ClearBlocklist';
|
||||
export const CLEAR_LOGS = 'ClearLog';
|
||||
export const CUTOFF_UNMET_MOVIES_SEARCH = 'CutoffUnmetMoviesSearch';
|
||||
export const DELETE_LOG_FILES = 'DeleteLogFiles';
|
||||
|
||||
@@ -129,7 +129,7 @@ class FileBrowserModalContent extends Component {
|
||||
className={styles.mappedDrivesWarning}
|
||||
kind={kinds.WARNING}
|
||||
>
|
||||
<Link to="https://wiki.servarr.com/Radarr_FAQ#Why_cant_Radarr_see_my_files_on_a_remote_server">
|
||||
<Link to="https://wiki.servarr.com/radarr/faq#why-cant-radarr-see-my-files-on-a-remote-server">
|
||||
{translate('MappedDrivesRunningAsService')}
|
||||
</Link> .
|
||||
</Alert>
|
||||
|
||||
@@ -61,8 +61,8 @@ const links = [
|
||||
to: '/activity/history'
|
||||
},
|
||||
{
|
||||
title: translate('Blacklist'),
|
||||
to: '/activity/blacklist'
|
||||
title: translate('Blocklist'),
|
||||
to: '/activity/blocklist'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
background-color: $dangerColor;
|
||||
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(90deg, color($dangerColor shade(5%)), color($dangerColor shade(5%)) 5px, color($dangerColor shade(15%)) 5px, color($dangerColor shade(15%)) 10px);
|
||||
background: repeating-linear-gradient(90deg, $dangerColor, $dangerColor 5px, $dangerColor 5px, $dimColor 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
background-color: $warningColor;
|
||||
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(45deg, $warningColor, $warningColor 5px, color($warningColor tint(15%)) 5px, color($warningColor tint(15%)) 10px);
|
||||
background: repeating-linear-gradient(45deg, $warningColor, $warningColor 5px, $warningColor 5px, $dimColor 10px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
frontend/src/Content/Images/Icons/logo-prowlarr.png
Normal file
BIN
frontend/src/Content/Images/Icons/logo-prowlarr.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
@@ -225,4 +225,4 @@ export const UNSAVED_SETTING = farDotCircle;
|
||||
export const VIEW = fasEye;
|
||||
export const WARNING = fasExclamationTriangle;
|
||||
export const WIKI = fasBookReader;
|
||||
export const BLACKLIST = fasBan;
|
||||
export const BLOCKLIST = fasBan;
|
||||
|
||||
@@ -64,6 +64,7 @@ const columns = [
|
||||
name: icons.DANGER,
|
||||
kind: kinds.DANGER
|
||||
}),
|
||||
isSortable: true,
|
||||
isVisible: true
|
||||
}
|
||||
];
|
||||
|
||||
@@ -67,6 +67,6 @@
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
.blacklist {
|
||||
.blocklist {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class InteractiveSearchRow extends Component {
|
||||
grabError,
|
||||
historyGrabbedData,
|
||||
historyFailedData,
|
||||
blacklistData
|
||||
blocklistData
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@@ -221,12 +221,12 @@ class InteractiveSearchRow extends Component {
|
||||
}
|
||||
|
||||
{
|
||||
blacklistData?.date &&
|
||||
blocklistData?.date &&
|
||||
<Icon
|
||||
className={historyGrabbedData || historyFailedData ? styles.blacklist : ''}
|
||||
name={icons.BLACKLIST}
|
||||
className={historyGrabbedData || historyFailedData ? styles.blocklist : ''}
|
||||
name={icons.BLOCKLIST}
|
||||
kind={kinds.DANGER}
|
||||
title={`${translate('Blacklisted')}: ${formatDateTime(blacklistData.date, longDateFormat, timeFormat, { includeSeconds: true })}`}
|
||||
title={`${translate('Blocklisted')}: ${formatDateTime(blocklistData.date, longDateFormat, timeFormat, { includeSeconds: true })}`}
|
||||
/>
|
||||
}
|
||||
</TableRowCell>
|
||||
@@ -341,7 +341,7 @@ InteractiveSearchRow.propTypes = {
|
||||
onGrabPress: PropTypes.func.isRequired,
|
||||
historyFailedData: PropTypes.object,
|
||||
historyGrabbedData: PropTypes.object,
|
||||
blacklistData: PropTypes.object
|
||||
blocklistData: PropTypes.object
|
||||
};
|
||||
|
||||
InteractiveSearchRow.defaultProps = {
|
||||
|
||||
@@ -8,22 +8,22 @@ function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state, { guid }) => guid,
|
||||
(state) => state.movieHistory.items,
|
||||
(state) => state.movieBlacklist.items,
|
||||
(guid, movieHistory, movieBlacklist) => {
|
||||
(state) => state.movieBlocklist.items,
|
||||
(guid, movieHistory, movieBlocklist) => {
|
||||
|
||||
let blacklistData = {};
|
||||
let blocklistData = {};
|
||||
let historyFailedData = {};
|
||||
|
||||
const historyGrabbedData = movieHistory.find((movie) => movie.eventType === 'grabbed' && movie.data.guid === guid);
|
||||
if (historyGrabbedData) {
|
||||
historyFailedData = movieHistory.find((movie) => movie.eventType === 'downloadFailed' && movie.sourceTitle === historyGrabbedData.sourceTitle);
|
||||
blacklistData = movieBlacklist.find((item) => item.sourceTitle === historyGrabbedData.sourceTitle);
|
||||
blocklistData = movieBlocklist.find((item) => item.sourceTitle === historyGrabbedData.sourceTitle);
|
||||
}
|
||||
|
||||
return {
|
||||
historyGrabbedData,
|
||||
historyFailedData,
|
||||
blacklistData
|
||||
blocklistData
|
||||
};
|
||||
}
|
||||
);
|
||||
@@ -38,7 +38,7 @@ class InteractiveSearchRowConnector extends Component {
|
||||
const {
|
||||
historyGrabbedData,
|
||||
historyFailedData,
|
||||
blacklistData,
|
||||
blocklistData,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
@@ -46,7 +46,7 @@ class InteractiveSearchRowConnector extends Component {
|
||||
<InteractiveSearchRow
|
||||
historyGrabbedData={historyGrabbedData}
|
||||
historyFailedData={historyFailedData}
|
||||
blacklistData={blacklistData}
|
||||
blocklistData={blocklistData}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
@@ -56,7 +56,7 @@ class InteractiveSearchRowConnector extends Component {
|
||||
InteractiveSearchRowConnector.propTypes = {
|
||||
historyGrabbedData: PropTypes.object,
|
||||
historyFailedData: PropTypes.object,
|
||||
blacklistData: PropTypes.object
|
||||
blocklistData: PropTypes.object
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps)(InteractiveSearchRowConnector);
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as commandNames from 'Commands/commandNames';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import { clearExtraFiles, fetchExtraFiles } from 'Store/Actions/extraFileActions';
|
||||
import { toggleMovieMonitored } from 'Store/Actions/movieActions';
|
||||
import { clearMovieBlacklist, fetchMovieBlacklist } from 'Store/Actions/movieBlacklistActions';
|
||||
import { clearMovieBlocklist, fetchMovieBlocklist } from 'Store/Actions/movieBlocklistActions';
|
||||
import { clearMovieCredits, fetchMovieCredits } from 'Store/Actions/movieCreditsActions';
|
||||
import { clearMovieFiles, fetchMovieFiles } from 'Store/Actions/movieFileActions';
|
||||
import { clearMovieHistory, fetchMovieHistory } from 'Store/Actions/movieHistoryActions';
|
||||
@@ -222,11 +222,11 @@ function createMapDispatchToProps(dispatch, props) {
|
||||
onGoToMovie(titleSlug) {
|
||||
dispatch(push(`${window.Radarr.urlBase}/movie/${titleSlug}`));
|
||||
},
|
||||
dispatchFetchMovieBlacklist({ movieId }) {
|
||||
dispatch(fetchMovieBlacklist({ movieId }));
|
||||
dispatchFetchMovieBlocklist({ movieId }) {
|
||||
dispatch(fetchMovieBlocklist({ movieId }));
|
||||
},
|
||||
dispatchClearMovieBlacklist() {
|
||||
dispatch(clearMovieBlacklist());
|
||||
dispatchClearMovieBlocklist() {
|
||||
dispatch(clearMovieBlocklist());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -280,7 +280,7 @@ class MovieDetailsConnector extends Component {
|
||||
const movieId = this.props.id;
|
||||
|
||||
this.props.dispatchFetchMovieFiles({ movieId });
|
||||
this.props.dispatchFetchMovieBlacklist({ movieId });
|
||||
this.props.dispatchFetchMovieBlocklist({ movieId });
|
||||
this.props.dispatchFetchMovieHistory({ movieId });
|
||||
this.props.dispatchFetchExtraFiles({ movieId });
|
||||
this.props.dispatchFetchMovieCredits({ movieId });
|
||||
@@ -290,7 +290,7 @@ class MovieDetailsConnector extends Component {
|
||||
|
||||
unpopulate = () => {
|
||||
this.props.dispatchCancelFetchReleases();
|
||||
this.props.dispatchClearMovieBlacklist();
|
||||
this.props.dispatchClearMovieBlocklist();
|
||||
this.props.dispatchClearMovieFiles();
|
||||
this.props.dispatchClearMovieHistory();
|
||||
this.props.dispatchClearExtraFiles();
|
||||
@@ -362,8 +362,8 @@ MovieDetailsConnector.propTypes = {
|
||||
dispatchClearQueueDetails: PropTypes.func.isRequired,
|
||||
dispatchFetchImportListSchema: PropTypes.func.isRequired,
|
||||
dispatchExecuteCommand: PropTypes.func.isRequired,
|
||||
dispatchFetchMovieBlacklist: PropTypes.func.isRequired,
|
||||
dispatchClearMovieBlacklist: PropTypes.func.isRequired,
|
||||
dispatchFetchMovieBlocklist: PropTypes.func.isRequired,
|
||||
dispatchClearMovieBlocklist: PropTypes.func.isRequired,
|
||||
onGoToMovie: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
background-color: $dangerColor;
|
||||
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(90deg, color($dangerColor shade(5%)), color($dangerColor shade(5%)) 5px, color($dangerColor shade(15%)) 5px, color($dangerColor shade(15%)) 10px);
|
||||
background: repeating-linear-gradient(90deg, $dangerColor, $dangerColor 5px, $dangerColor 5px, $dimColor 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
background-color: $warningColor;
|
||||
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(45deg, $warningColor, $warningColor 5px, color($warningColor tint(15%)) 5px, color($warningColor tint(15%)) 10px);
|
||||
background: repeating-linear-gradient(45deg, $warningColor, $warningColor 5px, $warningColor 5px, $dimColor 10px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ProgressBar from 'Components/ProgressBar';
|
||||
import { sizes } from 'Helpers/Props';
|
||||
import getProgressBarKind from 'Utilities/Movie/getProgressBarKind';
|
||||
import getQueueStatusText from 'Utilities/Movie/getQueueStatusText';
|
||||
import getStatusStyle from 'Utilities/Movie/getStatusStyle';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './MovieIndexProgressBar.css';
|
||||
|
||||
@@ -42,7 +42,7 @@ function MovieIndexProgressBar(props) {
|
||||
className={styles.progressBar}
|
||||
containerClassName={styles.progress}
|
||||
progress={progress}
|
||||
kind={getProgressBarKind(status, monitored, hasFile, isAvailable, queueStatusText)}
|
||||
kind={getStatusStyle(status, monitored, hasFile, isAvailable, 'kinds', queueStatusText)}
|
||||
size={detailedProgressBar ? sizes.MEDIUM : sizes.SMALL}
|
||||
showText={detailedProgressBar}
|
||||
width={posterWidth}
|
||||
|
||||
@@ -45,11 +45,16 @@
|
||||
flex: 0 0 100px;
|
||||
}
|
||||
|
||||
.movieStatus,
|
||||
.movieStatus {
|
||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||
|
||||
flex: 0 0 110px;
|
||||
}
|
||||
|
||||
.certification {
|
||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||
|
||||
flex: 0 0 100px;
|
||||
flex: 0 0 90px;
|
||||
}
|
||||
|
||||
.year {
|
||||
|
||||
@@ -52,11 +52,16 @@
|
||||
flex: 0 0 100px;
|
||||
}
|
||||
|
||||
.movieStatus,
|
||||
.movieStatus {
|
||||
composes: cell;
|
||||
|
||||
flex: 0 0 110px;
|
||||
}
|
||||
|
||||
.certification {
|
||||
composes: cell;
|
||||
|
||||
flex: 0 0 100px;
|
||||
flex: 0 0 90px;
|
||||
}
|
||||
|
||||
.year {
|
||||
|
||||
@@ -2,3 +2,45 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.missingUnmonitoredBackground {
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(45deg, $colorImpairedGradientDark, $colorImpairedGradientDark 5px, $colorImpairedGradient 5px, $colorImpairedGradient 10px);
|
||||
}
|
||||
}
|
||||
|
||||
.missingMonitoredBackground {
|
||||
&:global(.colorImpaired) {
|
||||
background: repeating-linear-gradient(90deg, $colorImpairedGradientDark, $colorImpairedGradientDark 5px, $colorImpairedGradient 5px, $colorImpairedGradient 10px);
|
||||
}
|
||||
}
|
||||
|
||||
.queue {
|
||||
padding-right: 2px;
|
||||
border-left: 5px solid $queueColor;
|
||||
}
|
||||
|
||||
.continuing {
|
||||
padding-right: 2px;
|
||||
border-left: 5px solid $primaryColor;
|
||||
}
|
||||
|
||||
.availNotMonitored {
|
||||
padding-right: 2px;
|
||||
border-left: 5px solid $darkGray;
|
||||
}
|
||||
|
||||
.ended {
|
||||
padding-right: 2px;
|
||||
border-left: 5px solid $successColor;
|
||||
}
|
||||
|
||||
.missingMonitored {
|
||||
padding-right: 2px;
|
||||
border-left: 5px solid $dangerColor;
|
||||
}
|
||||
|
||||
.missingUnmonitored {
|
||||
padding-right: 2px;
|
||||
border-left: 5px solid $warningColor;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Label from 'Components/Label';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import MovieQuality from 'Movie/MovieQuality';
|
||||
import getQueueStatusText from 'Utilities/Movie/getQueueStatusText';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './MovieFileStatus.css';
|
||||
@@ -13,7 +11,8 @@ function MovieFileStatus(props) {
|
||||
monitored,
|
||||
movieFile,
|
||||
queueStatus,
|
||||
queueState
|
||||
queueState,
|
||||
colorImpairedMode
|
||||
} = props;
|
||||
|
||||
const hasMovieFile = !!movieFile;
|
||||
@@ -24,12 +23,8 @@ function MovieFileStatus(props) {
|
||||
|
||||
return (
|
||||
<div className={styles.center}>
|
||||
<Label
|
||||
title={queueStatusText}
|
||||
kind={kinds.QUEUE}
|
||||
>
|
||||
{queueStatusText}
|
||||
</Label>
|
||||
<span className={styles.queue} />
|
||||
{queueStatusText}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -39,51 +34,44 @@ function MovieFileStatus(props) {
|
||||
|
||||
return (
|
||||
<div className={styles.center}>
|
||||
<MovieQuality
|
||||
title={quality.quality.name}
|
||||
size={movieFile.size}
|
||||
quality={quality}
|
||||
isMonitored={monitored}
|
||||
isCutoffNotMet={movieFile.qualityCutoffNotMet}
|
||||
/>
|
||||
<span className={styles.ended} />
|
||||
{quality.quality.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!monitored) {
|
||||
return (
|
||||
<div className={styles.center}>
|
||||
<Label
|
||||
title={translate('NotMonitored')}
|
||||
kind={kinds.WARNING}
|
||||
>
|
||||
{translate('NotMonitored')}
|
||||
</Label>
|
||||
<div className={classNames(
|
||||
styles.center,
|
||||
styles.missingUnmonitoredBackground,
|
||||
colorImpairedMode && 'colorImpaired'
|
||||
)}
|
||||
>
|
||||
<span className={styles.missingUnmonitored} />
|
||||
{translate('NotMonitored')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (hasReleased) {
|
||||
return (
|
||||
<div className={styles.center}>
|
||||
<Label
|
||||
title={translate('MovieAvailableButMissing')}
|
||||
kind={kinds.DANGER}
|
||||
>
|
||||
{translate('Missing')}
|
||||
</Label>
|
||||
<div className={classNames(
|
||||
styles.center,
|
||||
styles.missingMonitoredBackground,
|
||||
colorImpairedMode && 'colorImpaired'
|
||||
)}
|
||||
>
|
||||
<span className={styles.missingMonitored} />
|
||||
{translate('Missing')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.center}>
|
||||
<Label
|
||||
title={translate('NotAvailable')}
|
||||
kind={kinds.INFO}
|
||||
>
|
||||
{translate('NotAvailable')}
|
||||
</Label>
|
||||
<span className={styles.continuing} />
|
||||
{translate('NotAvailable')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -93,7 +81,8 @@ MovieFileStatus.propTypes = {
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
movieFile: PropTypes.object,
|
||||
queueStatus: PropTypes.string,
|
||||
queueState: PropTypes.string
|
||||
queueState: PropTypes.string,
|
||||
colorImpairedMode: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
export default MovieFileStatus;
|
||||
|
||||
@@ -3,18 +3,21 @@ import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import createMovieSelector from 'Store/Selectors/createMovieSelector';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import MovieFileStatus from './MovieFileStatus';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createMovieSelector(),
|
||||
(movie) => {
|
||||
createUISettingsSelector(),
|
||||
(movie, uiSettings) => {
|
||||
return {
|
||||
inCinemas: movie.inCinemas,
|
||||
isAvailable: movie.isAvailable,
|
||||
monitored: movie.monitored,
|
||||
grabbed: movie.grabbed,
|
||||
movieFile: movie.movieFile
|
||||
movieFile: movie.movieFile,
|
||||
colorImpairedMode: uiSettings.enableColorImpairedMode
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -6,10 +6,10 @@ import { fetchCustomFormatSpecifications } from 'Store/Actions/settingsActions';
|
||||
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
||||
import ExportCustomFormatModalContent from './ExportCustomFormatModalContent';
|
||||
|
||||
const blacklistedProperties = ['id', 'implementationName', 'infoLink'];
|
||||
const omittedProperties = ['id', 'implementationName', 'infoLink'];
|
||||
|
||||
function replacer(key, value) {
|
||||
if (blacklistedProperties.includes(key)) {
|
||||
if (omittedProperties.includes(key)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class AddSpecificationModalContent extends Component {
|
||||
</div>
|
||||
<div>
|
||||
{translate('VisitGithubCustomFormatsAphrodite')}
|
||||
<Link to="https://wiki.servarr.com/Radarr_Settings#Custom_Formats_2">{translate('Wiki')}</Link>
|
||||
<Link to="https://wiki.servarr.com/radarr/settings#custom-formats-2">{translate('Wiki')}</Link>
|
||||
</div>
|
||||
</Alert>
|
||||
|
||||
|
||||
@@ -24,10 +24,7 @@ const requiresRestartKeys = [
|
||||
'enableSsl',
|
||||
'sslPort',
|
||||
'sslCertPath',
|
||||
'sslCertPassword',
|
||||
'authenticationMethod',
|
||||
'username',
|
||||
'password'
|
||||
'sslCertPassword'
|
||||
];
|
||||
|
||||
class GeneralSettings extends Component {
|
||||
|
||||
@@ -53,6 +53,7 @@ function HostSettings(props) {
|
||||
name="port"
|
||||
min={1}
|
||||
max={65535}
|
||||
autocomplete="off"
|
||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...port}
|
||||
|
||||
@@ -86,7 +86,6 @@ class SecuritySettings extends Component {
|
||||
name="authenticationMethod"
|
||||
values={authenticationMethodOptions}
|
||||
helpText={translate('AuthenticationMethodHelpText')}
|
||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...authenticationMethod}
|
||||
/>
|
||||
@@ -100,7 +99,6 @@ class SecuritySettings extends Component {
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="username"
|
||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...username}
|
||||
/>
|
||||
@@ -115,7 +113,6 @@ class SecuritySettings extends Component {
|
||||
<FormInputGroup
|
||||
type={inputTypes.PASSWORD}
|
||||
name="password"
|
||||
helpTextWarning={translate('RestartRequiredHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...password}
|
||||
/>
|
||||
|
||||
@@ -55,7 +55,7 @@ function UpdateSettings(props) {
|
||||
type={inputTypes.TEXT}
|
||||
name="branch"
|
||||
helpText={usingExternalUpdateMechanism ? translate('BranchUpdateMechanism') : translate('BranchUpdate')}
|
||||
helpLink="https://wiki.servarr.com/Radarr_Settings#Updates"
|
||||
helpLink="https://wiki.servarr.com/radarr/settings#updates"
|
||||
{...branch}
|
||||
onChange={onInputChange}
|
||||
readOnly={usingExternalUpdateMechanism}
|
||||
@@ -92,7 +92,7 @@ function UpdateSettings(props) {
|
||||
name="updateMechanism"
|
||||
values={updateOptions}
|
||||
helpText={translate('UpdateMechanismHelpText')}
|
||||
helpLink="https://wiki.servarr.com/Radarr_Settings#Updates"
|
||||
helpLink="https://wiki.servarr.com/radarr/settings#updates"
|
||||
onChange={onInputChange}
|
||||
{...updateMechanism}
|
||||
/>
|
||||
|
||||
@@ -43,6 +43,7 @@ function EditIndexerModalContent(props) {
|
||||
enableInteractiveSearch,
|
||||
supportsRss,
|
||||
supportsSearch,
|
||||
tags,
|
||||
fields,
|
||||
priority
|
||||
} = item;
|
||||
@@ -135,6 +136,7 @@ function EditIndexerModalContent(props) {
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
@@ -151,6 +153,18 @@ function EditIndexerModalContent(props) {
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>Tags</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TAG}
|
||||
name="tags"
|
||||
helpText={translate('IndexerTagHelpText')}
|
||||
{...tags}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
}
|
||||
</ModalBody>
|
||||
|
||||
@@ -4,6 +4,7 @@ import Card from 'Components/Card';
|
||||
import Label from 'Components/Label';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import TagList from 'Components/TagList';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditIndexerModalConnector from './EditIndexerModalConnector';
|
||||
@@ -68,6 +69,8 @@ class Indexer extends Component {
|
||||
enableRss,
|
||||
enableAutomaticSearch,
|
||||
enableInteractiveSearch,
|
||||
tags,
|
||||
tagList,
|
||||
supportsRss,
|
||||
supportsSearch,
|
||||
priority,
|
||||
@@ -133,6 +136,11 @@ class Indexer extends Component {
|
||||
}
|
||||
</div>
|
||||
|
||||
<TagList
|
||||
tags={tags}
|
||||
tagList={tagList}
|
||||
/>
|
||||
|
||||
<EditIndexerModalConnector
|
||||
id={id}
|
||||
isOpen={this.state.isEditIndexerModalOpen}
|
||||
@@ -160,6 +168,8 @@ Indexer.propTypes = {
|
||||
enableRss: PropTypes.bool.isRequired,
|
||||
enableAutomaticSearch: PropTypes.bool.isRequired,
|
||||
enableInteractiveSearch: PropTypes.bool.isRequired,
|
||||
tags: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
tagList: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
supportsRss: PropTypes.bool.isRequired,
|
||||
supportsSearch: PropTypes.bool.isRequired,
|
||||
onCloneIndexerPress: PropTypes.func.isRequired,
|
||||
|
||||
@@ -54,6 +54,7 @@ class Indexers extends Component {
|
||||
render() {
|
||||
const {
|
||||
items,
|
||||
tagList,
|
||||
dispatchCloneIndexer,
|
||||
onConfirmDeleteIndexer,
|
||||
...otherProps
|
||||
@@ -79,6 +80,7 @@ class Indexers extends Component {
|
||||
<Indexer
|
||||
key={item.id}
|
||||
{...item}
|
||||
tagList={tagList}
|
||||
showPriority={showPriority}
|
||||
onCloneIndexerPress={this.onCloneIndexerPress}
|
||||
onConfirmDeleteIndexer={onConfirmDeleteIndexer}
|
||||
@@ -119,6 +121,7 @@ Indexers.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
tagList: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
dispatchCloneIndexer: PropTypes.func.isRequired,
|
||||
onConfirmDeleteIndexer: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
@@ -4,13 +4,20 @@ import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { cloneIndexer, deleteIndexer, fetchIndexers } from 'Store/Actions/settingsActions';
|
||||
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
|
||||
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
||||
import sortByName from 'Utilities/Array/sortByName';
|
||||
import Indexers from './Indexers';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createSortedSectionSelector('settings.indexers', sortByName),
|
||||
(indexers) => indexers
|
||||
createTagsSelector(),
|
||||
(indexers, tagList) => {
|
||||
return {
|
||||
...indexers,
|
||||
tagList
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ function IndexerOptions(props) {
|
||||
unit="minutes"
|
||||
helpText={translate('HelpText')}
|
||||
helpTextWarning={translate('RSSSyncIntervalHelpTextWarning')}
|
||||
helpLink="https://wiki.servarr.com/Radarr_FAQ#How_does_Radarr_work"
|
||||
helpLink="https://wiki.servarr.com/radarr/faq#how-does-radarr-work"
|
||||
onChange={onInputChange}
|
||||
{...settings.rssSyncInterval}
|
||||
/>
|
||||
|
||||
@@ -115,10 +115,10 @@ class NamingModal extends Component {
|
||||
];
|
||||
|
||||
const movieTokens = [
|
||||
{ token: '{Movie Title}', example: 'Movie Title!' },
|
||||
{ token: '{Movie Title}', example: 'Movie\'s Title' },
|
||||
{ token: '{Movie Title:DE}', example: 'Filetitle' },
|
||||
{ token: '{Movie CleanTitle}', example: 'Movie Title' },
|
||||
{ token: '{Movie TitleThe}', example: 'Movie Title, The' },
|
||||
{ token: '{Movie CleanTitle}', example: 'Movies Title' },
|
||||
{ token: '{Movie TitleThe}', example: 'Movie\'s Title, The' },
|
||||
{ token: '{Movie OriginalTitle}', example: 'Τίτλος ταινίας' },
|
||||
{ token: '{Movie TitleFirstCharacter}', example: 'M' },
|
||||
{ token: '{Movie Collection}', example: 'The Movie Collection' },
|
||||
@@ -132,8 +132,8 @@ class NamingModal extends Component {
|
||||
];
|
||||
|
||||
const qualityTokens = [
|
||||
{ token: '{Quality Full}', example: 'HDTV 720p Proper' },
|
||||
{ token: '{Quality Title}', example: 'HDTV 720p' }
|
||||
{ token: '{Quality Full}', example: 'HDTV-720p Proper' },
|
||||
{ token: '{Quality Title}', example: 'HDTV-720p' }
|
||||
];
|
||||
|
||||
const mediaInfoTokens = [
|
||||
@@ -164,7 +164,7 @@ class NamingModal extends Component {
|
||||
|
||||
const originalTokens = [
|
||||
{ token: '{Original Title}', example: 'Movie.Title.HDTV.x264-EVOLVE' },
|
||||
{ token: '{Original Filename}', example: 'Movie.title.hdtv.x264-EVOLVE' }
|
||||
{ token: '{Original Filename}', example: 'movie title hdtv.x264-Evolve' }
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
@@ -20,7 +20,8 @@ export const certificationCountryOptions = [
|
||||
{ key: 'gb', value: 'Great Britain' },
|
||||
{ key: 'it', value: 'Italy' },
|
||||
{ key: 'es', value: 'Spain' },
|
||||
{ key: 'us', value: 'United States' }
|
||||
{ key: 'us', value: 'United States' },
|
||||
{ key: 'nz', value: 'New Zealand' }
|
||||
];
|
||||
|
||||
function MetadataOptions(props) {
|
||||
|
||||
@@ -39,8 +39,8 @@ function NotificationEventItems(props) {
|
||||
<FormLabel>{translate('NotificationTriggers')}</FormLabel>
|
||||
<div>
|
||||
<FormInputHelpText
|
||||
text={translate('NotifcationTriggersHelpText')}
|
||||
link="https://wiki.servarr.com/Radarr_Settings#Connections"
|
||||
text={translate('NotificationTriggersHelpText')}
|
||||
link="https://wiki.servarr.com/radarr/settings#connections"
|
||||
/>
|
||||
<div className={styles.events}>
|
||||
<div>
|
||||
|
||||
@@ -22,6 +22,7 @@ function TagDetailsModalContent(props) {
|
||||
notifications,
|
||||
restrictions,
|
||||
importLists,
|
||||
indexers,
|
||||
onModalClose,
|
||||
onDeleteTagPress
|
||||
} = props;
|
||||
@@ -41,7 +42,7 @@ function TagDetailsModalContent(props) {
|
||||
}
|
||||
|
||||
{
|
||||
!!movies.length &&
|
||||
movies.length ?
|
||||
<FieldSet legend={translate('Movies')}>
|
||||
{
|
||||
movies.map((item) => {
|
||||
@@ -52,11 +53,12 @@ function TagDetailsModalContent(props) {
|
||||
);
|
||||
})
|
||||
}
|
||||
</FieldSet>
|
||||
</FieldSet> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
!!delayProfiles.length &&
|
||||
delayProfiles.length ?
|
||||
<FieldSet legend={translate('DelayProfile')}>
|
||||
{
|
||||
delayProfiles.map((item) => {
|
||||
@@ -81,11 +83,12 @@ function TagDetailsModalContent(props) {
|
||||
);
|
||||
})
|
||||
}
|
||||
</FieldSet>
|
||||
</FieldSet> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
!!notifications.length &&
|
||||
notifications.length ?
|
||||
<FieldSet legend={translate('Connections')}>
|
||||
{
|
||||
notifications.map((item) => {
|
||||
@@ -96,11 +99,12 @@ function TagDetailsModalContent(props) {
|
||||
);
|
||||
})
|
||||
}
|
||||
</FieldSet>
|
||||
</FieldSet> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
!!restrictions.length &&
|
||||
restrictions.length ?
|
||||
<FieldSet legend={translate('Restrictions')}>
|
||||
{
|
||||
restrictions.map((item) => {
|
||||
@@ -142,7 +146,24 @@ function TagDetailsModalContent(props) {
|
||||
);
|
||||
})
|
||||
}
|
||||
</FieldSet>
|
||||
</FieldSet> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
indexers.length ?
|
||||
<FieldSet legend="Indexers">
|
||||
{
|
||||
indexers.map((item) => {
|
||||
return (
|
||||
<div key={item.id}>
|
||||
{item.name}
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
</FieldSet> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
@@ -192,6 +213,7 @@ TagDetailsModalContent.propTypes = {
|
||||
notifications: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
restrictions: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
importLists: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
indexers: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onModalClose: PropTypes.func.isRequired,
|
||||
onDeleteTagPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
@@ -69,6 +69,14 @@ function createMatchingImportListsSelector() {
|
||||
);
|
||||
}
|
||||
|
||||
function createMatchingIndexersSelector() {
|
||||
return createSelector(
|
||||
(state, { indexerIds }) => indexerIds,
|
||||
(state) => state.settings.indexers.items,
|
||||
findMatchingItems
|
||||
);
|
||||
}
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createMatchingMoviesSelector(),
|
||||
@@ -76,13 +84,15 @@ function createMapStateToProps() {
|
||||
createMatchingNotificationsSelector(),
|
||||
createMatchingRestrictionsSelector(),
|
||||
createMatchingImportListsSelector(),
|
||||
(movies, delayProfiles, notifications, restrictions, importLists) => {
|
||||
createMatchingIndexersSelector(),
|
||||
(movies, delayProfiles, notifications, restrictions, importLists, indexers) => {
|
||||
return {
|
||||
movies,
|
||||
delayProfiles,
|
||||
notifications,
|
||||
restrictions,
|
||||
importLists
|
||||
importLists,
|
||||
indexers
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -57,7 +57,8 @@ class Tag extends Component {
|
||||
notificationIds,
|
||||
restrictionIds,
|
||||
importListIds,
|
||||
movieIds
|
||||
movieIds,
|
||||
indexerIds
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
@@ -70,7 +71,8 @@ class Tag extends Component {
|
||||
notificationIds.length ||
|
||||
restrictionIds.length ||
|
||||
importListIds.length ||
|
||||
movieIds.length
|
||||
movieIds.length ||
|
||||
indexerIds.length
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -120,6 +122,14 @@ class Tag extends Component {
|
||||
{importListIds.length} list{importListIds.length > 1 && 's'}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
indexerIds.length ?
|
||||
<div>
|
||||
{indexerIds.length} indexer{indexerIds.length > 1 && 's'}
|
||||
</div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -138,6 +148,7 @@ class Tag extends Component {
|
||||
notificationIds={notificationIds}
|
||||
restrictionIds={restrictionIds}
|
||||
importListIds={importListIds}
|
||||
indexerIds={indexerIds}
|
||||
isOpen={isDetailsModalOpen}
|
||||
onModalClose={this.onDetailsModalClose}
|
||||
onDeleteTagPress={this.onDeleteTagPress}
|
||||
@@ -165,6 +176,7 @@ Tag.propTypes = {
|
||||
restrictionIds: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
importListIds: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
movieIds: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
indexerIds: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
onConfirmDeleteTag: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
@@ -173,7 +185,8 @@ Tag.defaultProps = {
|
||||
notificationIds: [],
|
||||
restrictionIds: [],
|
||||
importListIds: [],
|
||||
movieIds: []
|
||||
movieIds: [],
|
||||
indexerIds: []
|
||||
};
|
||||
|
||||
export default Tag;
|
||||
|
||||
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { fetchDelayProfiles, fetchImportLists, fetchNotifications, fetchRestrictions } from 'Store/Actions/settingsActions';
|
||||
import { fetchDelayProfiles, fetchImportLists, fetchIndexers, fetchNotifications, fetchRestrictions } from 'Store/Actions/settingsActions';
|
||||
import { fetchTagDetails } from 'Store/Actions/tagActions';
|
||||
import Tags from './Tags';
|
||||
|
||||
@@ -29,7 +29,8 @@ const mapDispatchToProps = {
|
||||
dispatchFetchDelayProfiles: fetchDelayProfiles,
|
||||
dispatchFetchNotifications: fetchNotifications,
|
||||
dispatchFetchRestrictions: fetchRestrictions,
|
||||
dispatchFetchImportLists: fetchImportLists
|
||||
dispatchFetchImportLists: fetchImportLists,
|
||||
dispatchFetchIndexers: fetchIndexers
|
||||
};
|
||||
|
||||
class MetadatasConnector extends Component {
|
||||
@@ -43,7 +44,8 @@ class MetadatasConnector extends Component {
|
||||
dispatchFetchDelayProfiles,
|
||||
dispatchFetchNotifications,
|
||||
dispatchFetchRestrictions,
|
||||
dispatchFetchImportLists
|
||||
dispatchFetchImportLists,
|
||||
dispatchFetchIndexers
|
||||
} = this.props;
|
||||
|
||||
dispatchFetchTagDetails();
|
||||
@@ -51,6 +53,7 @@ class MetadatasConnector extends Component {
|
||||
dispatchFetchNotifications();
|
||||
dispatchFetchRestrictions();
|
||||
dispatchFetchImportLists();
|
||||
dispatchFetchIndexers();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -70,7 +73,8 @@ MetadatasConnector.propTypes = {
|
||||
dispatchFetchDelayProfiles: PropTypes.func.isRequired,
|
||||
dispatchFetchNotifications: PropTypes.func.isRequired,
|
||||
dispatchFetchRestrictions: PropTypes.func.isRequired,
|
||||
dispatchFetchImportLists: PropTypes.func.isRequired
|
||||
dispatchFetchImportLists: PropTypes.func.isRequired,
|
||||
dispatchFetchIndexers: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(MetadatasConnector);
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import getSectionState from 'Utilities/State/getSectionState';
|
||||
import updateSectionState from 'Utilities/State/updateSectionState';
|
||||
|
||||
const blacklistedProperties = [
|
||||
const omittedProperties = [
|
||||
'section',
|
||||
'id'
|
||||
];
|
||||
@@ -31,7 +31,7 @@ export default function createHandleActions(handlers, defaultState, section) {
|
||||
|
||||
if (section === baseSection) {
|
||||
const newState = Object.assign(getSectionState(state, payloadSection),
|
||||
_.omit(payload, blacklistedProperties));
|
||||
_.omit(payload, omittedProperties));
|
||||
|
||||
return updateSectionState(state, payloadSection, newState);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,9 @@ export default {
|
||||
const promise = createAjaxRequest({
|
||||
method: 'PUT',
|
||||
url: '/qualityDefinition/update',
|
||||
data: JSON.stringify(upatedDefinitions)
|
||||
data: JSON.stringify(upatedDefinitions),
|
||||
contentType: 'application/json',
|
||||
dataType: 'json'
|
||||
}).request;
|
||||
|
||||
promise.done((data) => {
|
||||
|
||||
@@ -123,6 +123,7 @@ export const actionHandlers = handleThunks({
|
||||
const promise = createAjaxRequest({
|
||||
url: '/movie',
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(newMovie)
|
||||
}).request;
|
||||
|
||||
@@ -15,7 +15,7 @@ import createSetTableOptionReducer from './Creators/Reducers/createSetTableOptio
|
||||
//
|
||||
// Variables
|
||||
|
||||
export const section = 'blacklist';
|
||||
export const section = 'blocklist';
|
||||
|
||||
//
|
||||
// State
|
||||
@@ -83,41 +83,41 @@ export const defaultState = {
|
||||
};
|
||||
|
||||
export const persistState = [
|
||||
'blacklist.pageSize',
|
||||
'blacklist.sortKey',
|
||||
'blacklist.sortDirection',
|
||||
'blacklist.columns'
|
||||
'blocklist.pageSize',
|
||||
'blocklist.sortKey',
|
||||
'blocklist.sortDirection',
|
||||
'blocklist.columns'
|
||||
];
|
||||
|
||||
//
|
||||
// Action Types
|
||||
|
||||
export const FETCH_BLACKLIST = 'blacklist/fetchBlacklist';
|
||||
export const GOTO_FIRST_BLACKLIST_PAGE = 'blacklist/gotoBlacklistFirstPage';
|
||||
export const GOTO_PREVIOUS_BLACKLIST_PAGE = 'blacklist/gotoBlacklistPreviousPage';
|
||||
export const GOTO_NEXT_BLACKLIST_PAGE = 'blacklist/gotoBlacklistNextPage';
|
||||
export const GOTO_LAST_BLACKLIST_PAGE = 'blacklist/gotoBlacklistLastPage';
|
||||
export const GOTO_BLACKLIST_PAGE = 'blacklist/gotoBlacklistPage';
|
||||
export const SET_BLACKLIST_SORT = 'blacklist/setBlacklistSort';
|
||||
export const SET_BLACKLIST_TABLE_OPTION = 'blacklist/setBlacklistTableOption';
|
||||
export const REMOVE_BLACKLIST_ITEM = 'blacklist/removeBlacklistItem';
|
||||
export const REMOVE_BLACKLIST_ITEMS = 'blacklist/removeBlacklistItems';
|
||||
export const CLEAR_BLACKLIST = 'blacklist/clearBlacklist';
|
||||
export const FETCH_BLOCKLIST = 'blocklist/fetchBlocklist';
|
||||
export const GOTO_FIRST_BLOCKLIST_PAGE = 'blocklist/gotoBlocklistFirstPage';
|
||||
export const GOTO_PREVIOUS_BLOCKLIST_PAGE = 'blocklist/gotoBlocklistPreviousPage';
|
||||
export const GOTO_NEXT_BLOCKLIST_PAGE = 'blocklist/gotoBlocklistNextPage';
|
||||
export const GOTO_LAST_BLOCKLIST_PAGE = 'blocklist/gotoBlocklistLastPage';
|
||||
export const GOTO_BLOCKLIST_PAGE = 'blocklist/gotoBlocklistPage';
|
||||
export const SET_BLOCKLIST_SORT = 'blocklist/setBlocklistSort';
|
||||
export const SET_BLOCKLIST_TABLE_OPTION = 'blocklist/setBlocklistTableOption';
|
||||
export const REMOVE_BLOCKLIST_ITEM = 'blocklist/removeBlocklistItem';
|
||||
export const REMOVE_BLOCKLIST_ITEMS = 'blocklist/removeBlocklistItems';
|
||||
export const CLEAR_BLOCKLIST = 'blocklist/clearBlocklist';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
|
||||
export const fetchBlacklist = createThunk(FETCH_BLACKLIST);
|
||||
export const gotoBlacklistFirstPage = createThunk(GOTO_FIRST_BLACKLIST_PAGE);
|
||||
export const gotoBlacklistPreviousPage = createThunk(GOTO_PREVIOUS_BLACKLIST_PAGE);
|
||||
export const gotoBlacklistNextPage = createThunk(GOTO_NEXT_BLACKLIST_PAGE);
|
||||
export const gotoBlacklistLastPage = createThunk(GOTO_LAST_BLACKLIST_PAGE);
|
||||
export const gotoBlacklistPage = createThunk(GOTO_BLACKLIST_PAGE);
|
||||
export const setBlacklistSort = createThunk(SET_BLACKLIST_SORT);
|
||||
export const setBlacklistTableOption = createAction(SET_BLACKLIST_TABLE_OPTION);
|
||||
export const removeBlacklistItem = createThunk(REMOVE_BLACKLIST_ITEM);
|
||||
export const removeBlacklistItems = createThunk(REMOVE_BLACKLIST_ITEMS);
|
||||
export const clearBlacklist = createAction(CLEAR_BLACKLIST);
|
||||
export const fetchBlocklist = createThunk(FETCH_BLOCKLIST);
|
||||
export const gotoBlocklistFirstPage = createThunk(GOTO_FIRST_BLOCKLIST_PAGE);
|
||||
export const gotoBlocklistPreviousPage = createThunk(GOTO_PREVIOUS_BLOCKLIST_PAGE);
|
||||
export const gotoBlocklistNextPage = createThunk(GOTO_NEXT_BLOCKLIST_PAGE);
|
||||
export const gotoBlocklistLastPage = createThunk(GOTO_LAST_BLOCKLIST_PAGE);
|
||||
export const gotoBlocklistPage = createThunk(GOTO_BLOCKLIST_PAGE);
|
||||
export const setBlocklistSort = createThunk(SET_BLOCKLIST_SORT);
|
||||
export const setBlocklistTableOption = createAction(SET_BLOCKLIST_TABLE_OPTION);
|
||||
export const removeBlocklistItem = createThunk(REMOVE_BLOCKLIST_ITEM);
|
||||
export const removeBlocklistItems = createThunk(REMOVE_BLOCKLIST_ITEMS);
|
||||
export const clearBlocklist = createAction(CLEAR_BLOCKLIST);
|
||||
|
||||
//
|
||||
// Action Handlers
|
||||
@@ -125,21 +125,21 @@ export const clearBlacklist = createAction(CLEAR_BLACKLIST);
|
||||
export const actionHandlers = handleThunks({
|
||||
...createServerSideCollectionHandlers(
|
||||
section,
|
||||
'/blacklist',
|
||||
fetchBlacklist,
|
||||
'/blocklist',
|
||||
fetchBlocklist,
|
||||
{
|
||||
[serverSideCollectionHandlers.FETCH]: FETCH_BLACKLIST,
|
||||
[serverSideCollectionHandlers.FIRST_PAGE]: GOTO_FIRST_BLACKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.PREVIOUS_PAGE]: GOTO_PREVIOUS_BLACKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.NEXT_PAGE]: GOTO_NEXT_BLACKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.LAST_PAGE]: GOTO_LAST_BLACKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.EXACT_PAGE]: GOTO_BLACKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.SORT]: SET_BLACKLIST_SORT
|
||||
[serverSideCollectionHandlers.FETCH]: FETCH_BLOCKLIST,
|
||||
[serverSideCollectionHandlers.FIRST_PAGE]: GOTO_FIRST_BLOCKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.PREVIOUS_PAGE]: GOTO_PREVIOUS_BLOCKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.NEXT_PAGE]: GOTO_NEXT_BLOCKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.LAST_PAGE]: GOTO_LAST_BLOCKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.EXACT_PAGE]: GOTO_BLOCKLIST_PAGE,
|
||||
[serverSideCollectionHandlers.SORT]: SET_BLOCKLIST_SORT
|
||||
}),
|
||||
|
||||
[REMOVE_BLACKLIST_ITEM]: createRemoveItemHandler(section, '/blacklist'),
|
||||
[REMOVE_BLOCKLIST_ITEM]: createRemoveItemHandler(section, '/blocklist'),
|
||||
|
||||
[REMOVE_BLACKLIST_ITEMS]: function(getState, payload, dispatch) {
|
||||
[REMOVE_BLOCKLIST_ITEMS]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
ids
|
||||
} = payload;
|
||||
@@ -157,15 +157,16 @@ export const actionHandlers = handleThunks({
|
||||
]));
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: '/blacklist/bulk',
|
||||
url: '/blocklist/bulk',
|
||||
method: 'DELETE',
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ ids })
|
||||
}).request;
|
||||
|
||||
promise.done((data) => {
|
||||
// Don't use batchActions with thunks
|
||||
dispatch(fetchBlacklist());
|
||||
dispatch(fetchBlocklist());
|
||||
|
||||
dispatch(set({ section, isRemoving: false }));
|
||||
});
|
||||
@@ -191,9 +192,9 @@ export const actionHandlers = handleThunks({
|
||||
|
||||
export const reducers = createHandleActions({
|
||||
|
||||
[SET_BLACKLIST_TABLE_OPTION]: createSetTableOptionReducer(section),
|
||||
[SET_BLOCKLIST_TABLE_OPTION]: createSetTableOptionReducer(section),
|
||||
|
||||
[CLEAR_BLACKLIST]: createClearReducer(section, {
|
||||
[CLEAR_BLOCKLIST]: createClearReducer(section, {
|
||||
isFetching: false,
|
||||
isPopulated: false,
|
||||
error: null,
|
||||
@@ -139,7 +139,8 @@ export function executeCommandHelper( payload, dispatch) {
|
||||
const promise = createAjaxRequest({
|
||||
url: '/command',
|
||||
method: 'POST',
|
||||
data: JSON.stringify(payload)
|
||||
data: JSON.stringify(payload),
|
||||
dataType: 'json'
|
||||
}).request;
|
||||
|
||||
return promise.then((data) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as addMovie from './addMovieActions';
|
||||
import * as app from './appActions';
|
||||
import * as blacklist from './blacklistActions';
|
||||
import * as blocklist from './blocklistActions';
|
||||
import * as calendar from './calendarActions';
|
||||
import * as captcha from './captchaActions';
|
||||
import * as commands from './commandActions';
|
||||
@@ -11,7 +11,7 @@ import * as history from './historyActions';
|
||||
import * as importMovie from './importMovieActions';
|
||||
import * as interactiveImportActions from './interactiveImportActions';
|
||||
import * as movies from './movieActions';
|
||||
import * as movieBlacklist from './movieBlacklistActions';
|
||||
import * as movieBlocklist from './movieBlocklistActions';
|
||||
import * as movieCredits from './movieCreditsActions';
|
||||
import * as movieFiles from './movieFileActions';
|
||||
import * as movieHistory from './movieHistoryActions';
|
||||
@@ -30,7 +30,7 @@ import * as tags from './tagActions';
|
||||
export default [
|
||||
addMovie,
|
||||
app,
|
||||
blacklist,
|
||||
blocklist,
|
||||
calendar,
|
||||
captcha,
|
||||
commands,
|
||||
@@ -49,7 +49,7 @@ export default [
|
||||
releases,
|
||||
rootFolders,
|
||||
movies,
|
||||
movieBlacklist,
|
||||
movieBlocklist,
|
||||
movieHistory,
|
||||
movieIndex,
|
||||
movieCredits,
|
||||
|
||||
@@ -8,7 +8,7 @@ import createHandleActions from './Creators/createHandleActions';
|
||||
//
|
||||
// Variables
|
||||
|
||||
export const section = 'movieBlacklist';
|
||||
export const section = 'movieBlocklist';
|
||||
|
||||
//
|
||||
// State
|
||||
@@ -23,25 +23,25 @@ export const defaultState = {
|
||||
//
|
||||
// Actions Types
|
||||
|
||||
export const FETCH_MOVIE_BLACKLIST = 'movieBlacklist/fetchMovieBlacklist';
|
||||
export const CLEAR_MOVIE_BLACKLIST = 'movieBlacklist/clearMovieBlacklist';
|
||||
export const FETCH_MOVIE_BLOCKLIST = 'movieBlocklist/fetchMovieBlocklist';
|
||||
export const CLEAR_MOVIE_BLOCKLIST = 'movieBlocklist/clearMovieBlocklist';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
|
||||
export const fetchMovieBlacklist = createThunk(FETCH_MOVIE_BLACKLIST);
|
||||
export const clearMovieBlacklist = createAction(CLEAR_MOVIE_BLACKLIST);
|
||||
export const fetchMovieBlocklist = createThunk(FETCH_MOVIE_BLOCKLIST);
|
||||
export const clearMovieBlocklist = createAction(CLEAR_MOVIE_BLOCKLIST);
|
||||
|
||||
//
|
||||
// Action Handlers
|
||||
|
||||
export const actionHandlers = handleThunks({
|
||||
|
||||
[FETCH_MOVIE_BLACKLIST]: function(getState, payload, dispatch) {
|
||||
[FETCH_MOVIE_BLOCKLIST]: function(getState, payload, dispatch) {
|
||||
dispatch(set({ section, isFetching: true }));
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: '/blacklist/movie',
|
||||
url: '/blocklist/movie',
|
||||
data: payload
|
||||
}).request;
|
||||
|
||||
@@ -74,7 +74,7 @@ export const actionHandlers = handleThunks({
|
||||
|
||||
export const reducers = createHandleActions({
|
||||
|
||||
[CLEAR_MOVIE_BLACKLIST]: (state) => {
|
||||
[CLEAR_MOVIE_BLOCKLIST]: (state) => {
|
||||
return Object.assign({}, state, defaultState);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ export const actionHandlers = handleThunks({
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: `/history/failed/${historyId}`,
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
dataType: 'json'
|
||||
}).request;
|
||||
|
||||
promise.done(() => {
|
||||
@@ -97,4 +98,3 @@ export const reducers = createHandleActions({
|
||||
}
|
||||
|
||||
}, defaultState, section);
|
||||
|
||||
|
||||
@@ -354,13 +354,13 @@ export const actionHandlers = handleThunks({
|
||||
const {
|
||||
id,
|
||||
remove,
|
||||
blacklist
|
||||
blocklist
|
||||
} = payload;
|
||||
|
||||
dispatch(updateItem({ section: paged, id, isRemoving: true }));
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: `/queue/${id}?removeFromClient=${remove}&blacklist=${blacklist}`,
|
||||
url: `/queue/${id}?removeFromClient=${remove}&blocklist=${blocklist}`,
|
||||
method: 'DELETE'
|
||||
}).request;
|
||||
|
||||
@@ -377,7 +377,7 @@ export const actionHandlers = handleThunks({
|
||||
const {
|
||||
ids,
|
||||
remove,
|
||||
blacklist
|
||||
blocklist
|
||||
} = payload;
|
||||
|
||||
dispatch(batchActions([
|
||||
@@ -393,9 +393,10 @@ export const actionHandlers = handleThunks({
|
||||
]));
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: `/queue/bulk?removeFromClient=${remove}&blacklist=${blacklist}`,
|
||||
url: `/queue/bulk?removeFromClient=${remove}&blocklist=${blocklist}`,
|
||||
method: 'DELETE',
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ ids })
|
||||
}).request;
|
||||
|
||||
@@ -453,4 +454,3 @@ export const reducers = createHandleActions({
|
||||
})
|
||||
|
||||
}, defaultState, section);
|
||||
|
||||
|
||||
@@ -240,6 +240,7 @@ export const actionHandlers = handleThunks({
|
||||
const promise = createAjaxRequest({
|
||||
url: '/release',
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(payload)
|
||||
}).request;
|
||||
|
||||
@@ -87,6 +87,13 @@ export const defaultState = {
|
||||
isVisible: true,
|
||||
isModifiable: false
|
||||
},
|
||||
{
|
||||
name: 'time',
|
||||
label: translate('Time'),
|
||||
isSortable: true,
|
||||
isVisible: true,
|
||||
isModifiable: false
|
||||
},
|
||||
{
|
||||
name: 'logger',
|
||||
label: translate('Component'),
|
||||
@@ -100,13 +107,6 @@ export const defaultState = {
|
||||
isVisible: true,
|
||||
isModifiable: false
|
||||
},
|
||||
{
|
||||
name: 'time',
|
||||
label: translate('Time'),
|
||||
isSortable: true,
|
||||
isVisible: true,
|
||||
isModifiable: false
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
columnLabel: translate('Actions'),
|
||||
|
||||
@@ -53,7 +53,8 @@ export const actionHandlers = handleThunks({
|
||||
const promise = createAjaxRequest({
|
||||
url: '/tag',
|
||||
method: 'POST',
|
||||
data: JSON.stringify(payload.tag)
|
||||
data: JSON.stringify(payload.tag),
|
||||
dataType: 'json'
|
||||
}).request;
|
||||
|
||||
promise.done((data) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import persistState from 'redux-localstorage';
|
||||
import actions from 'Store/Actions';
|
||||
import migrate from 'Store/Migrators/migrate';
|
||||
|
||||
const columnPaths = [];
|
||||
|
||||
@@ -98,6 +99,7 @@ const config = {
|
||||
export default function createPersistState() {
|
||||
// Migrate existing local storage before proceeding
|
||||
const persistedState = JSON.parse(localStorage.getItem(config.key));
|
||||
migrate(persistedState);
|
||||
localStorage.setItem(config.key, serialize(persistedState));
|
||||
|
||||
return persistState(paths, config);
|
||||
|
||||
5
frontend/src/Store/Migrators/migrate.js
Normal file
5
frontend/src/Store/Migrators/migrate.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import migrateBlacklistToBlocklist from './migrateBlacklistToBlocklist';
|
||||
|
||||
export default function migrate(persistedState) {
|
||||
migrateBlacklistToBlocklist(persistedState);
|
||||
}
|
||||
12
frontend/src/Store/Migrators/migrateBlacklistToBlocklist.js
Normal file
12
frontend/src/Store/Migrators/migrateBlacklistToBlocklist.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import _, { get } from 'lodash';
|
||||
|
||||
export default function migrateBlacklistToBlocklist(persistedState) {
|
||||
const blocklist = get(persistedState, 'blacklist');
|
||||
|
||||
if (!blocklist) {
|
||||
return;
|
||||
}
|
||||
|
||||
persistedState.blocklist = blocklist;
|
||||
_.remove(persistedState, 'blacklist');
|
||||
}
|
||||
@@ -13,7 +13,7 @@ function createHealthCheckSelector() {
|
||||
source: 'UI',
|
||||
type: 'warning',
|
||||
message: translate('CouldNotConnectSignalR'),
|
||||
wikiUrl: 'https://wiki.servarr.com/Radarr_System#Could_not_connect_to_signalR'
|
||||
wikiUrl: 'https://wiki.servarr.com/radarr/system#could-not-connect-to-signalr'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ module.exports = {
|
||||
//
|
||||
// Calendar
|
||||
|
||||
calendarTodayBackgroundColor: '#ddd',
|
||||
calendarTodayBackgroundColor: '#c5c5c5',
|
||||
calendarBorderColor: '#cecece',
|
||||
calendarTextDim: '#666',
|
||||
|
||||
|
||||
@@ -58,9 +58,9 @@ class LogsTableRow extends Component {
|
||||
render() {
|
||||
const {
|
||||
level,
|
||||
time,
|
||||
logger,
|
||||
message,
|
||||
time,
|
||||
exception,
|
||||
columns
|
||||
} = this.props;
|
||||
@@ -96,6 +96,15 @@ class LogsTableRow extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'time') {
|
||||
return (
|
||||
<RelativeDateCellConnector
|
||||
key={name}
|
||||
date={time}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'logger') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
@@ -112,15 +121,6 @@ class LogsTableRow extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'time') {
|
||||
return (
|
||||
<RelativeDateCellConnector
|
||||
key={name}
|
||||
date={time}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'actions') {
|
||||
return (
|
||||
<TableRowCell
|
||||
@@ -148,9 +148,9 @@ class LogsTableRow extends Component {
|
||||
|
||||
LogsTableRow.propTypes = {
|
||||
level: PropTypes.string.isRequired,
|
||||
time: PropTypes.string.isRequired,
|
||||
logger: PropTypes.string.isRequired,
|
||||
message: PropTypes.string.isRequired,
|
||||
time: PropTypes.string.isRequired,
|
||||
exception: PropTypes.string,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired
|
||||
};
|
||||
|
||||
@@ -20,7 +20,6 @@ class About extends Component {
|
||||
packageVersion,
|
||||
packageAuthor,
|
||||
isNetCore,
|
||||
isMono,
|
||||
isDocker,
|
||||
runtimeVersion,
|
||||
migrationVersion,
|
||||
@@ -48,14 +47,6 @@ class About extends Component {
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
isMono &&
|
||||
<DescriptionListItem
|
||||
title={translate('MonoVersion')}
|
||||
data={runtimeVersion}
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
isNetCore &&
|
||||
<DescriptionListItem
|
||||
@@ -114,7 +105,6 @@ About.propTypes = {
|
||||
packageVersion: PropTypes.string,
|
||||
packageAuthor: PropTypes.string,
|
||||
isNetCore: PropTypes.bool.isRequired,
|
||||
isMono: PropTypes.bool.isRequired,
|
||||
runtimeVersion: PropTypes.string.isRequired,
|
||||
isDocker: PropTypes.bool.isRequired,
|
||||
migrationVersion: PropTypes.number.isRequired,
|
||||
|
||||
@@ -36,6 +36,14 @@ class Donations extends Component {
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={styles.logoContainer} title="Prowlarr">
|
||||
<Link to="https://opencollective.com/prowlarr">
|
||||
<img
|
||||
className={styles.logo}
|
||||
src={`${window.Radarr.urlBase}/Content/Images/Icons/logo-prowlarr.png`}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={styles.logoContainer} title="Sonarr">
|
||||
<Link to="https://opencollective.com/sonarr">
|
||||
<img
|
||||
|
||||
@@ -26,7 +26,7 @@ class MoreInfo extends Component {
|
||||
{translate('Wiki')}
|
||||
</DescriptionListItemTitle>
|
||||
<DescriptionListItemDescription>
|
||||
<Link to="https://wiki.servarr.com/Radarr">{translate('Wiki')}</Link>
|
||||
<Link to="https://wiki.servarr.com/radarr">{translate('Wiki')}</Link>
|
||||
</DescriptionListItemDescription>
|
||||
|
||||
<DescriptionListItemTitle>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
.logoContainer {
|
||||
display: inline-block;
|
||||
margin: 1em;
|
||||
margin: 0.5em;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
outline: none;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { kinds } from 'Helpers/Props';
|
||||
|
||||
function getProgressBarKind(status, monitored, hasFile, isAvailable, queue = false) {
|
||||
if (queue) {
|
||||
return kinds.QUEUE;
|
||||
}
|
||||
|
||||
if (hasFile && monitored) {
|
||||
return kinds.SUCCESS;
|
||||
}
|
||||
|
||||
if (hasFile && !monitored) {
|
||||
return kinds.DEFAULT;
|
||||
}
|
||||
|
||||
if (isAvailable && monitored) {
|
||||
return kinds.DANGER;
|
||||
}
|
||||
|
||||
if (!monitored) {
|
||||
return kinds.WARNING;
|
||||
}
|
||||
|
||||
return kinds.PRIMARY;
|
||||
}
|
||||
|
||||
export default getProgressBarKind;
|
||||
27
frontend/src/Utilities/Movie/getStatusStyle.js
Normal file
27
frontend/src/Utilities/Movie/getStatusStyle.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import { kinds } from 'Helpers/Props';
|
||||
|
||||
function getStatusStyle(status, monitored, hasFile, isAvailable, returnType, queue = false) {
|
||||
if (queue) {
|
||||
return returnType === 'kinds' ? kinds.SUCCESS : 'queue';
|
||||
}
|
||||
|
||||
if (hasFile && monitored) {
|
||||
return returnType === 'kinds' ? kinds.SUCCESS : 'downloaded';
|
||||
}
|
||||
|
||||
if (hasFile && !monitored) {
|
||||
return returnType === 'kinds' ? kinds.DEFAULT : 'unreleased';
|
||||
}
|
||||
|
||||
if (isAvailable && monitored) {
|
||||
return returnType === 'kinds' ? kinds.DANGER : 'missingMonitored';
|
||||
}
|
||||
|
||||
if (!monitored) {
|
||||
return returnType === 'kinds' ? kinds.WARNING : 'missingUnmonitored';
|
||||
}
|
||||
|
||||
return returnType === 'kinds' ? kinds.PRIMARY : 'continuing';
|
||||
}
|
||||
|
||||
export default getStatusStyle;
|
||||
@@ -7,18 +7,6 @@ function isRelative(ajaxOptions) {
|
||||
return !absUrlRegex.test(ajaxOptions.url);
|
||||
}
|
||||
|
||||
function moveBodyToQuery(ajaxOptions) {
|
||||
if (ajaxOptions.data && ajaxOptions.type === 'DELETE') {
|
||||
if (ajaxOptions.url.contains('?')) {
|
||||
ajaxOptions.url += '&';
|
||||
} else {
|
||||
ajaxOptions.url += '?';
|
||||
}
|
||||
ajaxOptions.url += $.param(ajaxOptions.data);
|
||||
delete ajaxOptions.data;
|
||||
}
|
||||
}
|
||||
|
||||
function addRootUrl(ajaxOptions) {
|
||||
ajaxOptions.url = apiRoot + ajaxOptions.url;
|
||||
}
|
||||
@@ -32,7 +20,7 @@ function addContentType(ajaxOptions) {
|
||||
if (
|
||||
ajaxOptions.contentType == null &&
|
||||
ajaxOptions.dataType === 'json' &&
|
||||
(ajaxOptions.method === 'PUT' || ajaxOptions.method === 'POST')) {
|
||||
(ajaxOptions.method === 'PUT' || ajaxOptions.method === 'POST' || ajaxOptions.method === 'DELETE')) {
|
||||
ajaxOptions.contentType = 'application/json';
|
||||
}
|
||||
}
|
||||
@@ -49,10 +37,9 @@ export default function createAjaxRequest(originalAjaxOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
const ajaxOptions = { dataType: 'json', ...originalAjaxOptions };
|
||||
const ajaxOptions = { ...originalAjaxOptions };
|
||||
|
||||
if (isRelative(ajaxOptions)) {
|
||||
moveBodyToQuery(ajaxOptions);
|
||||
addRootUrl(ajaxOptions);
|
||||
addApiKey(ajaxOptions);
|
||||
addContentType(ajaxOptions);
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
</span>
|
||||
|
||||
<a
|
||||
href="https://wiki.servarr.com/Radarr_FAQ#Help_I_have_locked_my_self_out_of_Radarr_and_do_not_know_the_password"
|
||||
href="https://wiki.servarr.com/radarr/faq#help-i-have-locked-myself-out"
|
||||
class="forgot-password"
|
||||
>Forgot your password?</a
|
||||
>
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
"@fortawesome/free-regular-svg-icons": "5.15.3",
|
||||
"@fortawesome/free-solid-svg-icons": "5.15.3",
|
||||
"@fortawesome/react-fontawesome": "0.1.14",
|
||||
"@microsoft/signalr": "5.0.5",
|
||||
"@sentry/browser": "6.3.1",
|
||||
"@sentry/integrations": "6.3.1",
|
||||
"@microsoft/signalr": "5.0.10",
|
||||
"@sentry/browser": "6.13.2",
|
||||
"@sentry/integrations": "6.13.2",
|
||||
"classnames": "2.3.1",
|
||||
"clipboard": "2.0.8",
|
||||
"connected-react-router": "6.9.1",
|
||||
@@ -99,7 +99,6 @@
|
||||
"babel-loader": "8.2.2",
|
||||
"babel-plugin-inline-classnames": "2.0.1",
|
||||
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
|
||||
"copy-webpack-plugin": "8.1.1",
|
||||
"core-js": "3.11.0",
|
||||
"css-loader": "5.2.4",
|
||||
"eslint": "7.25.0",
|
||||
@@ -110,6 +109,7 @@
|
||||
"eslint-plugin-simple-import-sort": "7.0.0",
|
||||
"esprint": "2.0.0",
|
||||
"file-loader": "6.2.0",
|
||||
"filemanager-webpack-plugin": "5.0.0",
|
||||
"html-webpack-plugin": "5.3.1",
|
||||
"loader-utils": "^2.0.0",
|
||||
"mini-css-extract-plugin": "1.5.0",
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;osx-x64;linux-x64;linux-musl-x64;linux-arm;linux-arm64;linux-musl-arm64</RuntimeIdentifiers>
|
||||
<ExcludedRuntimeFrameworkPairs>win-x64:net472;win-x86:net472;osx-x64:net472;linux-arm:net472;linux-arm64:net472;linux-musl-x64:net472;linux-musl-arm64:net472</ExcludedRuntimeFrameworkPairs>
|
||||
|
||||
<RadarrRootDir>$(MSBuildThisFileDirectory)..\</RadarrRootDir>
|
||||
|
||||
@@ -90,9 +89,9 @@
|
||||
|
||||
<!-- Standard testing packages -->
|
||||
<ItemGroup Condition="'$(TestProject)'=='true'">
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
|
||||
<PackageReference Include="NUnit" Version="3.13.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NunitXml.TestLogger" Version="2.1.62" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -100,14 +99,6 @@
|
||||
<PackageReference Include="coverlet.collector" Version="3.0.4-preview.27.ge7cb7c3b40" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Allow building net framework using mono -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(RadarrProject)'=='true' and '$(EnableAnalyzers)'=='false'">
|
||||
<!-- FXCop Built into Net5 SDK now as NETAnalyzers, Enabled by default on net5 projects -->
|
||||
<EnableNETAnalyzers>false</EnableNETAnalyzers>
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
<Project>
|
||||
<!-- below net4.7.1 the new portable pdb format has no line numbers, pdb to mdb probably doesn't like it either -->
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net472'">
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="Targets/PublishAllRids.targets" />
|
||||
<Import Project="Targets/FixBindingRedirects.targets" />
|
||||
<Import Project="Targets/MonoFacades.targets" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and !$(RuntimeIdentifier.StartsWith('win'))" />
|
||||
<Import Project="Targets/CopyRuntimes.targets" />
|
||||
</Project>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user