Compare commits

..

1 Commits

Author SHA1 Message Date
ta264 0e05d86a58 Fixed: Handle wonky timestamps from Orpheus 2022-04-08 04:14:26 +01:00
678 changed files with 15269 additions and 82882 deletions
+8 -4
View File
@@ -19,10 +19,10 @@ indent_size = 4
dotnet_sort_system_directives_first = true dotnet_sort_system_directives_first = true
# Avoid "this." and "Me." if not necessary # Avoid "this." and "Me." if not necessary
dotnet_style_qualification_for_field = false:warning dotnet_style_qualification_for_field = false:refactoring
dotnet_style_qualification_for_property = false:warning dotnet_style_qualification_for_property = false:refactoring
dotnet_style_qualification_for_method = false:warning dotnet_style_qualification_for_method = false:refactoring
dotnet_style_qualification_for_event = false:warning dotnet_style_qualification_for_event = false:refactoring
# Indentation preferences # Indentation preferences
csharp_indent_block_contents = true csharp_indent_block_contents = true
@@ -32,6 +32,10 @@ csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true csharp_indent_switch_labels = true
csharp_indent_labels = flush_left csharp_indent_labels = flush_left
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
dotnet_naming_style.instance_field_style.capitalization = camel_case dotnet_naming_style.instance_field_style.capitalization = camel_case
dotnet_naming_style.instance_field_style.required_prefix = _ dotnet_naming_style.instance_field_style.required_prefix = _
+2 -2
View File
@@ -5,9 +5,9 @@ body:
- type: checkboxes - type: checkboxes
attributes: attributes:
label: Is there an existing issue for this? label: Is there an existing issue for this?
description: Please search to see if an open or closed issue already exists for the bug you encountered. If a bug exists and is closed note that it may only be fixed in an unstable branch. description: Please search to see if an issue already exists for the bug you encountered.
options: options:
- label: I have searched the existing open and closed issues - label: I have searched the existing issues
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
+2 -2
View File
@@ -5,9 +5,9 @@ body:
- type: checkboxes - type: checkboxes
attributes: attributes:
label: Is there an existing issue for this? label: Is there an existing issue for this?
description: Please search to see if an open or closed issue already exists for the feature you are requesting. If a request exists and is closed note that it may only be fixed in an unstable branch. description: Please search to see if an issue already exists for the feature you are requesting.
options: options:
- label: I have searched the existing open and closed issues - label: I have searched the existing issues
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
-132
View File
@@ -1,132 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
<development@prowlarr.com>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
+3
View File
@@ -27,7 +27,10 @@ Prowlarr is an indexer manager/proxy built on the popular \*arr .net/reactjs bas
## Support ## Support
Note: Prowlarr is currently early in life, thus bugs should be expected
[![Wiki](https://img.shields.io/badge/servarr-wiki-181717.svg?maxAge=60)](https://wiki.servarr.com/prowlarr) [![Wiki](https://img.shields.io/badge/servarr-wiki-181717.svg?maxAge=60)](https://wiki.servarr.com/prowlarr)
[![Discord](https://img.shields.io/badge/discord-chat-7289DA.svg?maxAge=60)](https://prowlarr.com/discord) [![Discord](https://img.shields.io/badge/discord-chat-7289DA.svg?maxAge=60)](https://prowlarr.com/discord)
[![Reddit](https://img.shields.io/badge/reddit-discussion-FF4500.svg?maxAge=60)](https://www.reddit.com/r/Prowlarr) [![Reddit](https://img.shields.io/badge/reddit-discussion-FF4500.svg?maxAge=60)](https://www.reddit.com/r/Prowlarr)
+78 -230
View File
@@ -7,20 +7,16 @@ variables:
outputFolder: './_output' outputFolder: './_output'
artifactsFolder: './_artifacts' artifactsFolder: './_artifacts'
testsFolder: './_tests' testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn majorVersion: '0.2.0'
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '1.1.2'
minorVersion: $[counter('minorVersion', 1)] minorVersion: $[counter('minorVersion', 1)]
prowlarrVersion: '$(majorVersion).$(minorVersion)' prowlarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(prowlarrVersion)' buildName: '$(Build.SourceBranchName).$(prowlarrVersion)'
sentryOrg: 'servarr' sentryOrg: 'servarr'
sentryUrl: 'https://sentry.servarr.com' sentryUrl: 'https://sentry.servarr.com'
dotnetVersion: '6.0.405' dotnetVersion: '6.0.201'
innoVersion: '6.2.0' innoVersion: '6.2.0'
nodeVersion: '16.x' nodeVersion: '16.x'
windowsImage: 'windows-2022' yarnCacheFolder: $(Pipeline.Workspace)/.yarn
linuxImage: 'ubuntu-20.04'
macImage: 'macOS-11'
trigger: trigger:
branches: branches:
@@ -44,7 +40,7 @@ stages:
- job: - job:
displayName: Build Variables displayName: Build Variables
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: 'ubuntu-18.04'
steps: steps:
# Set the build name properly. The 'name' property won't recursively expand so hack here: # Set the build name properly. The 'name' property won't recursively expand so hack here:
- bash: echo "##vso[build.updatebuildnumber]$PROWLARRVERSION" - bash: echo "##vso[build.updatebuildnumber]$PROWLARRVERSION"
@@ -70,15 +66,15 @@ stages:
matrix: matrix:
Linux: Linux:
osName: 'Linux' osName: 'Linux'
imageName: ${{ variables.linuxImage }} imageName: 'ubuntu-18.04'
enableAnalysis: 'true' enableAnalysis: 'true'
Mac: Mac:
osName: 'Mac' osName: 'Mac'
imageName: ${{ variables.macImage }} imageName: 'macos-10.15'
enableAnalysis: 'false' enableAnalysis: 'false'
Windows: Windows:
osName: 'Windows' osName: 'Windows'
imageName: ${{ variables.windowsImage }} imageName: 'windows-2019'
enableAnalysis: 'false' enableAnalysis: 'false'
pool: pool:
@@ -97,14 +93,15 @@ stages:
- bash: | - bash: |
BUNDLEDVERSIONS=${AGENT_TOOLSDIRECTORY}/dotnet/sdk/${DOTNETVERSION}/Microsoft.NETCoreSdk.BundledVersions.props BUNDLEDVERSIONS=${AGENT_TOOLSDIRECTORY}/dotnet/sdk/${DOTNETVERSION}/Microsoft.NETCoreSdk.BundledVersions.props
echo $BUNDLEDVERSIONS echo $BUNDLEDVERSIONS
grep osx-x64 $BUNDLEDVERSIONS
if grep -q freebsd-x64 $BUNDLEDVERSIONS; then if grep -q freebsd-x64 $BUNDLEDVERSIONS; then
echo "Extra platforms already enabled" echo "BSD already enabled"
else else
echo "Enabling extra platform support" echo "Enabling BSD support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64/' $BUNDLEDVERSIONS
fi fi
displayName: Enable Extra Platform Support displayName: Enable FreeBSD Support
- bash: ./build.sh --backend --enable-extra-platforms - bash: ./build.sh --backend --enable-bsd
displayName: Build Prowlarr Backend displayName: Build Prowlarr Backend
- bash: | - bash: |
find ${OUTPUTFOLDER} -type f ! -path "*/publish/*" -exec rm -rf {} \; find ${OUTPUTFOLDER} -type f ! -path "*/publish/*" -exec rm -rf {} \;
@@ -118,28 +115,24 @@ stages:
displayName: Publish Backend displayName: Publish Backend
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/win-x64/publish' - publish: '$(testsFolder)/net6.0/win-x64/publish'
artifact: win-x64-tests artifact: WindowsCoreTests
displayName: Publish win-x64 Test Package displayName: Publish Windows Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-x64/publish' - publish: '$(testsFolder)/net6.0/linux-x64/publish'
artifact: linux-x64-tests artifact: LinuxCoreTests
displayName: Publish linux-x64 Test Package displayName: Publish Linux Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-x86/publish'
artifact: linux-x86-tests
displayName: Publish linux-x86 Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/linux-musl-x64/publish' - publish: '$(testsFolder)/net6.0/linux-musl-x64/publish'
artifact: linux-musl-x64-tests artifact: LinuxMuslCoreTests
displayName: Publish linux-musl-x64 Test Package displayName: Publish Linux Musl Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/freebsd-x64/publish' - publish: '$(testsFolder)/net6.0/freebsd-x64/publish'
artifact: freebsd-x64-tests artifact: FreebsdCoreTests
displayName: Publish freebsd-x64 Test Package displayName: Publish FreeBSD Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net6.0/osx-x64/publish' - publish: '$(testsFolder)/net6.0/osx-x64/publish'
artifact: osx-x64-tests artifact: MacCoreTests
displayName: Publish osx-x64 Test Package displayName: Publish MacOS Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows')) condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- stage: Build_Frontend - stage: Build_Frontend
@@ -151,13 +144,13 @@ stages:
matrix: matrix:
Linux: Linux:
osName: 'Linux' osName: 'Linux'
imageName: ${{ variables.linuxImage }} imageName: 'ubuntu-18.04'
Mac: Mac:
osName: 'Mac' osName: 'Mac'
imageName: ${{ variables.macImage }} imageName: 'macos-10.15'
Windows: Windows:
osName: 'Windows' osName: 'Windows'
imageName: ${{ variables.windowsImage }} imageName: 'windows-2019'
pool: pool:
vmImage: $(imageName) vmImage: $(imageName)
steps: steps:
@@ -193,7 +186,7 @@ stages:
- job: Windows_Installer - job: Windows_Installer
displayName: Create Installer displayName: Create Installer
pool: pool:
vmImage: ${{ variables.windowsImage }} vmImage: 'windows-2019'
steps: steps:
- checkout: self - checkout: self
fetchDepth: 1 fetchDepth: 1
@@ -226,7 +219,7 @@ stages:
- job: Other_Packages - job: Other_Packages
displayName: Create Standard Packages displayName: Create Standard Packages
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: 'ubuntu-18.04'
steps: steps:
- checkout: self - checkout: self
fetchDepth: 1 fetchDepth: 1
@@ -242,35 +235,35 @@ stages:
artifactName: WindowsFrontend artifactName: WindowsFrontend
targetPath: _output targetPath: _output
displayName: Fetch Frontend displayName: Fetch Frontend
- bash: ./build.sh --packages --enable-extra-platforms - bash: ./build.sh --packages --enable-bsd
displayName: Create Packages displayName: Create Packages
- bash: | - bash: |
find . -name "Prowlarr" -exec chmod a+x {} \; find . -name "Prowlarr" -exec chmod a+x {} \;
find . -name "Prowlarr.Update" -exec chmod a+x {} \; find . -name "Prowlarr.Update" -exec chmod a+x {} \;
displayName: Set executable bits displayName: Set executable bits
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create win-x64 zip displayName: Create Windows Core zip
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x64.zip' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x64.zip'
archiveType: 'zip' archiveType: 'zip'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/win-x64/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create win-x86 zip displayName: Create Windows x86 Core zip
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x86.zip' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).windows-core-x86.zip'
archiveType: 'zip' archiveType: 'zip'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/win-x86/net6.0 rootFolderOrFile: $(artifactsFolder)/win-x86/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create osx-x64 app displayName: Create MacOS x64 Core app
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-x64.zip' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-x64.zip'
archiveType: 'zip' archiveType: 'zip'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net6.0 rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create osx-x64 tar displayName: Create MacOS x64 Core tar
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-core-x64.tar.gz' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-core-x64.tar.gz'
archiveType: 'tar' archiveType: 'tar'
@@ -278,14 +271,14 @@ stages:
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/osx-x64/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create osx-arm64 app displayName: Create MacOS arm64 Core app
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-arm64.zip' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-app-core-arm64.zip'
archiveType: 'zip' archiveType: 'zip'
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net6.0 rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create osx-arm64 tar displayName: Create MacOS arm64 Core tar
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-core-arm64.tar.gz' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).osx-core-arm64.tar.gz'
archiveType: 'tar' archiveType: 'tar'
@@ -293,7 +286,7 @@ stages:
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net6.0 rootFolderOrFile: $(artifactsFolder)/osx-arm64/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-x64 tar displayName: Create Linux Core tar
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-core-x64.tar.gz' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-core-x64.tar.gz'
archiveType: 'tar' archiveType: 'tar'
@@ -301,7 +294,7 @@ stages:
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-x64/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-musl-x64 tar displayName: Create Linux Musl Core tar
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-musl-core-x64.tar.gz' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-musl-core-x64.tar.gz'
archiveType: 'tar' archiveType: 'tar'
@@ -309,15 +302,7 @@ stages:
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-x86 tar displayName: Create ARM32 Linux Core tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-core-x86.tar.gz'
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x86/net6.0
- task: ArchiveFiles@2
displayName: Create linux-arm tar
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-core-arm.tar.gz' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-core-arm.tar.gz'
archiveType: 'tar' archiveType: 'tar'
@@ -325,7 +310,7 @@ stages:
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-arm/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-musl-arm tar displayName: Create ARM32 Linux Musl Core tar
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-musl-core-arm.tar.gz' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-musl-core-arm.tar.gz'
archiveType: 'tar' archiveType: 'tar'
@@ -333,7 +318,7 @@ stages:
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-arm64 tar displayName: Create ARM64 Linux Core tar
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-core-arm64.tar.gz' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-core-arm64.tar.gz'
archiveType: 'tar' archiveType: 'tar'
@@ -341,7 +326,7 @@ stages:
includeRootFolder: false includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net6.0 rootFolderOrFile: $(artifactsFolder)/linux-arm64/net6.0
- task: ArchiveFiles@2 - task: ArchiveFiles@2
displayName: Create linux-musl-arm64 tar displayName: Create ARM64 Linux Musl Core tar
inputs: inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-musl-core-arm64.tar.gz' archiveFile: '$(Build.ArtifactStagingDirectory)/Prowlarr.$(buildName).linux-musl-core-arm64.tar.gz'
archiveType: 'tar' archiveType: 'tar'
@@ -394,7 +379,7 @@ stages:
jobs: jobs:
- job: Prepare - job: Prepare
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: 'ubuntu-18.04'
steps: steps:
- checkout: none - checkout: none
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
@@ -416,22 +401,22 @@ stages:
matrix: matrix:
MacCore: MacCore:
osName: 'Mac' osName: 'Mac'
testName: 'osx-x64' testName: 'MacCore'
poolName: 'Azure Pipelines' poolName: 'Azure Pipelines'
imageName: ${{ variables.macImage }} imageName: 'macos-10.15'
WindowsCore: WindowsCore:
osName: 'Windows' osName: 'Windows'
testName: 'win-x64' testName: 'WindowsCore'
poolName: 'Azure Pipelines' poolName: 'Azure Pipelines'
imageName: ${{ variables.windowsImage }} imageName: 'windows-2019'
LinuxCore: LinuxCore:
osName: 'Linux' osName: 'Linux'
testName: 'linux-x64' testName: 'LinuxCore'
poolName: 'Azure Pipelines' poolName: 'Azure Pipelines'
imageName: ${{ variables.linuxImage }} imageName: 'ubuntu-18.04'
FreebsdCore: FreebsdCore:
osName: 'Linux' osName: 'Linux'
testName: 'freebsd-x64' testName: 'FreebsdCore'
poolName: 'FreeBSD' poolName: 'FreeBSD'
imageName: imageName:
@@ -450,7 +435,7 @@ stages:
displayName: Download Test Artifact displayName: Download Test Artifact
inputs: inputs:
buildType: 'current' buildType: 'current'
artifactName: '$(testName)-tests' artifactName: '$(testName)Tests'
targetPath: $(testsFolder) targetPath: $(testsFolder)
- powershell: Set-Service SCardSvr -StartupType Manual - powershell: Set-Service SCardSvr -StartupType Manual
displayName: Enable Windows Test Service displayName: Enable Windows Test Service
@@ -480,15 +465,11 @@ stages:
matrix: matrix:
alpine: alpine:
testName: 'Musl Net Core' testName: 'Musl Net Core'
artifactName: linux-musl-x64-tests artifactName: LinuxMuslCoreTests
containerImage: ghcr.io/servarr/testimages:alpine containerImage: ghcr.io/servarr/testimages:alpine
linux-x86:
testName: 'linux-x86'
artifactName: linux-x86-tests
containerImage: ghcr.io/servarr/testimages:linux-x86
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: 'ubuntu-18.04'
container: $[ variables['containerImage'] ] container: $[ variables['containerImage'] ]
@@ -496,15 +477,9 @@ stages:
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .NET' displayName: 'Install .net core'
inputs: inputs:
version: $(dotnetVersion) version: $(dotnetVersion)
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
- bash: |
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
displayName: 'Install .NET'
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
- checkout: none - checkout: none
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
displayName: Download Test Artifact displayName: Download Test Artifact
@@ -527,58 +502,6 @@ stages:
testResultsFiles: '**/TestResult.xml' testResultsFiles: '**/TestResult.xml'
testRunTitle: '$(testName) Unit Tests' testRunTitle: '$(testName) Unit Tests'
failTaskOnFailedTests: true failTaskOnFailedTests: true
- job: Unit_LinuxCore_Postgres
displayName: Unit Native LinuxCore with Postgres Database
dependsOn: Prepare
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
variables:
pattern: 'Prowlarr.*.linux-core-x64.tar.gz'
artifactName: linux-x64-tests
Prowlarr__Postgres__Host: 'localhost'
Prowlarr__Postgres__Port: '5432'
Prowlarr__Postgres__User: 'prowlarr'
Prowlarr__Postgres__Password: 'prowlarr'
pool:
vmImage: ${{ variables.linuxImage }}
timeoutInMinutes: 10
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
inputs:
version: $(dotnetVersion)
- checkout: none
- task: DownloadPipelineArtifact@2
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: $(artifactName)
targetPath: $(testsFolder)
- bash: find ${TESTSFOLDER} -name "Prowlarr.Test.Dummy" -exec chmod a+x {} \;
displayName: Make Test Dummy Executable
condition: and(succeeded(), ne(variables['osName'], 'Windows'))
- bash: |
docker run -d --name=postgres14 \
-e POSTGRES_PASSWORD=prowlarr \
-e POSTGRES_USER=prowlarr \
-p 5432:5432/tcp \
postgres:14
displayName: Start postgres
- bash: |
chmod a+x ${TESTSFOLDER}/test.sh
ls -lR ${TESTSFOLDER}
${TESTSFOLDER}/test.sh Linux Unit Test
displayName: Run Tests
- task: PublishTestResults@2
displayName: Publish Test Results
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'LinuxCore Postgres Unit Tests'
failTaskOnFailedTests: true
- stage: Integration - stage: Integration
displayName: Integration displayName: Integration
@@ -587,7 +510,7 @@ stages:
jobs: jobs:
- job: Prepare - job: Prepare
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: 'ubuntu-18.04'
steps: steps:
- checkout: none - checkout: none
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
@@ -606,18 +529,18 @@ stages:
matrix: matrix:
MacCore: MacCore:
osName: 'Mac' osName: 'Mac'
testName: 'osx-x64' testName: 'MacCore'
imageName: ${{ variables.macImage }} imageName: 'macos-10.15'
pattern: 'Prowlarr.*.osx-core-x64.tar.gz' pattern: 'Prowlarr.*.osx-core-x64.tar.gz'
WindowsCore: WindowsCore:
osName: 'Windows' osName: 'Windows'
testName: 'win-x64' testName: 'WindowsCore'
imageName: ${{ variables.windowsImage }} imageName: 'windows-2019'
pattern: 'Prowlarr.*.windows-core-x64.zip' pattern: 'Prowlarr.*.windows-core-x64.zip'
LinuxCore: LinuxCore:
osName: 'Linux' osName: 'Linux'
testName: 'linux-x64' testName: 'LinuxCore'
imageName: ${{ variables.linuxImage }} imageName: 'ubuntu-18.04'
pattern: 'Prowlarr.*.linux-core-x64.tar.gz' pattern: 'Prowlarr.*.linux-core-x64.tar.gz'
pool: pool:
@@ -633,7 +556,7 @@ stages:
displayName: Download Test Artifact displayName: Download Test Artifact
inputs: inputs:
buildType: 'current' buildType: 'current'
artifactName: '$(testName)-tests' artifactName: '$(testName)Tests'
targetPath: $(testsFolder) targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
displayName: Download Build Artifact displayName: Download Build Artifact
@@ -663,67 +586,6 @@ stages:
failTaskOnFailedTests: true failTaskOnFailedTests: true
displayName: Publish Test Results displayName: Publish Test Results
- job: Integration_LinuxCore_Postgres
displayName: Integration Native LinuxCore with Postgres Database
dependsOn: Prepare
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
variables:
pattern: 'Prowlarr.*.linux-core-x64.tar.gz'
Prowlarr__Postgres__Host: 'localhost'
Prowlarr__Postgres__Port: '5432'
Prowlarr__Postgres__User: 'prowlarr'
Prowlarr__Postgres__Password: 'prowlarr'
pool:
vmImage: ${{ variables.linuxImage }}
steps:
- task: UseDotNet@2
displayName: 'Install .net core'
inputs:
version: $(dotnetVersion)
- checkout: none
- task: DownloadPipelineArtifact@2
displayName: Download Test Artifact
inputs:
buildType: 'current'
artifactName: 'linux-x64-tests'
targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2
displayName: Download Build Artifact
inputs:
buildType: 'current'
artifactName: Packages
itemPattern: '**/$(pattern)'
targetPath: $(Build.ArtifactStagingDirectory)
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
displayName: Extract Package
- bash: |
mkdir -p ./bin/
cp -r -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin/Prowlarr/. ./bin/
displayName: Move Package Contents
- bash: |
docker run -d --name=postgres14 \
-e POSTGRES_PASSWORD=prowlarr \
-e POSTGRES_USER=prowlarr \
-p 5432:5432/tcp \
postgres:14
displayName: Start postgres
- bash: |
chmod a+x ${TESTSFOLDER}/test.sh
${TESTSFOLDER}/test.sh Linux Integration Test
displayName: Run Integration Tests
- task: PublishTestResults@2
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '**/TestResult.xml'
testRunTitle: 'Integration LinuxCore Postgres Database Integration Tests'
failTaskOnFailedTests: true
displayName: Publish Test Results
- job: Integration_FreeBSD - job: Integration_FreeBSD
displayName: Integration Native FreeBSD displayName: Integration Native FreeBSD
dependsOn: Prepare dependsOn: Prepare
@@ -741,14 +603,14 @@ stages:
displayName: Download Test Artifact displayName: Download Test Artifact
inputs: inputs:
buildType: 'current' buildType: 'current'
artifactName: 'freebsd-x64-tests' artifactName: 'FreebsdCoreTests'
targetPath: $(testsFolder) targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
displayName: Download Build Artifact displayName: Download Build Artifact
inputs: inputs:
buildType: 'current' buildType: 'current'
artifactName: Packages artifactName: Packages
itemPattern: '**/$(pattern)' itemPattern: '/$(pattern)'
targetPath: $(Build.ArtifactStagingDirectory) targetPath: $(Build.ArtifactStagingDirectory)
- bash: | - bash: |
mkdir -p ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin mkdir -p ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin
@@ -777,17 +639,13 @@ stages:
strategy: strategy:
matrix: matrix:
alpine: alpine:
testName: 'linux-musl-x64' testName: 'Musl Net Core'
artifactName: linux-musl-x64-tests artifactName: LinuxMuslCoreTests
containerImage: ghcr.io/servarr/testimages:alpine containerImage: ghcr.io/servarr/testimages:alpine
pattern: 'Prowlarr.*.linux-musl-core-x64.tar.gz' pattern: 'Prowlarr.*.linux-musl-core-x64.tar.gz'
linux-x86:
testName: 'linux-x86'
artifactName: linux-x86-tests
containerImage: ghcr.io/servarr/testimages:linux-x86
pattern: 'Prowlarr.*.linux-core-x86.tar.gz'
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: 'ubuntu-18.04'
container: $[ variables['containerImage'] ] container: $[ variables['containerImage'] ]
@@ -795,15 +653,9 @@ stages:
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .NET' displayName: 'Install .net core'
inputs: inputs:
version: $(dotnetVersion) version: $(dotnetVersion)
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
- bash: |
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
displayName: 'Install .NET'
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
- checkout: none - checkout: none
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
displayName: Download Test Artifact displayName: Download Test Artifact
@@ -849,20 +701,17 @@ stages:
matrix: matrix:
Linux: Linux:
osName: 'Linux' osName: 'Linux'
artifactName: 'linux-x64' imageName: 'ubuntu-18.04'
imageName: ${{ variables.linuxImage }}
pattern: 'Prowlarr.*.linux-core-x64.tar.gz' pattern: 'Prowlarr.*.linux-core-x64.tar.gz'
failBuild: true failBuild: true
Mac: Mac:
osName: 'Mac' osName: 'Mac'
artifactName: 'osx-x64' imageName: 'macos-10.15'
imageName: ${{ variables.macImage }}
pattern: 'Prowlarr.*.osx-core-x64.tar.gz' pattern: 'Prowlarr.*.osx-core-x64.tar.gz'
failBuild: true failBuild: true
Windows: Windows:
osName: 'Windows' osName: 'Windows'
artifactName: 'win-x64' imageName: 'windows-2019'
imageName: ${{ variables.windowsImage }}
pattern: 'Prowlarr.*.windows-core-x64.zip' pattern: 'Prowlarr.*.windows-core-x64.zip'
failBuild: true failBuild: true
@@ -879,7 +728,7 @@ stages:
displayName: Download Test Artifact displayName: Download Test Artifact
inputs: inputs:
buildType: 'current' buildType: 'current'
artifactName: '$(artifactName)-tests' artifactName: '$(osName)CoreTests'
targetPath: $(testsFolder) targetPath: $(testsFolder)
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
displayName: Download Build Artifact displayName: Download Build Artifact
@@ -928,7 +777,7 @@ stages:
jobs: jobs:
- job: Prepare - job: Prepare
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: 'ubuntu-18.04'
steps: steps:
- checkout: none - checkout: none
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
@@ -945,10 +794,10 @@ stages:
matrix: matrix:
Linux: Linux:
osName: 'Linux' osName: 'Linux'
imageName: ${{ variables.linuxImage }} imageName: 'ubuntu-18.04'
Windows: Windows:
osName: 'Windows' osName: 'Windows'
imageName: ${{ variables.windowsImage }} imageName: 'windows-2019'
pool: pool:
vmImage: $(imageName) vmImage: $(imageName)
steps: steps:
@@ -983,7 +832,7 @@ stages:
) )
pool: pool:
vmImage: ${{ variables.windowsImage }} vmImage: windows-2019
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
@@ -1035,7 +884,7 @@ stages:
EnableAnalyzers: 'false' EnableAnalyzers: 'false'
pool: pool:
vmImage: ${{ variables.windowsImage }} vmImage: windows-2019
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
@@ -1092,7 +941,7 @@ stages:
- job: - job:
displayName: Discord Notification displayName: Discord Notification
pool: pool:
vmImage: ${{ variables.linuxImage }} vmImage: 'ubuntu-18.04'
steps: steps:
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2
continueOnError: true continueOnError: true
@@ -1108,5 +957,4 @@ stages:
SYSTEM_ACCESSTOKEN: $(System.AccessToken) SYSTEM_ACCESSTOKEN: $(System.AccessToken)
DISCORDCHANNELID: $(discordChannelId) DISCORDCHANNELID: $(discordChannelId)
DISCORDWEBHOOKKEY: $(discordWebhookKey) DISCORDWEBHOOKKEY: $(discordWebhookKey)
DISCORDTHREADID: $(discordThreadId)
+13 -32
View File
@@ -25,22 +25,15 @@ UpdateVersionNumber()
fi fi
} }
EnableExtraPlatformsInSDK() EnableBsdSupport()
{ {
SDK_PATH=$(dotnet --list-sdks | grep -P '6\.\d\.\d+' | head -1 | sed 's/\(6\.[0-9]*\.[0-9]*\).*\[\(.*\)\]/\2\/\1/g') #todo enable sdk with
BUNDLEDVERSIONS="${SDK_PATH}/Microsoft.NETCoreSdk.BundledVersions.props" #SDK_PATH=$(dotnet --list-sdks | grep -P '5\.\d\.\d+' | head -1 | sed 's/\(5\.[0-9]*\.[0-9]*\).*\[\(.*\)\]/\2\/\1/g')
if grep -q freebsd-x64 $BUNDLEDVERSIONS; then # BUNDLED_VERSIONS="${SDK_PATH}/Microsoft.NETCoreSdk.BundledVersions.props"
echo "Extra platforms already enabled"
else
echo "Enabling extra platform support"
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS
fi
}
EnableExtraPlatforms()
{
if grep -qv freebsd-x64 src/Directory.Build.props; then if grep -qv freebsd-x64 src/Directory.Build.props; then
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64;linux-x86</RuntimeIdentifiers>^g" src/Directory.Build.props 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 fi
} }
@@ -300,8 +293,7 @@ if [ $# -eq 0 ]; then
PACKAGES=YES PACKAGES=YES
INSTALLER=NO INSTALLER=NO
LINT=YES LINT=YES
ENABLE_EXTRA_PLATFORMS=NO ENABLE_BSD=NO
ENABLE_EXTRA_PLATFORMS_IN_SDK=NO
fi fi
while [[ $# -gt 0 ]] while [[ $# -gt 0 ]]
@@ -313,12 +305,8 @@ case $key in
BACKEND=YES BACKEND=YES
shift # past argument shift # past argument
;; ;;
--enable-bsd|--enable-extra-platforms) --enable-bsd)
ENABLE_EXTRA_PLATFORMS=YES ENABLE_BSD=YES
shift # past argument
;;
--enable-extra-platforms-in-sdk)
ENABLE_EXTRA_PLATFORMS_IN_SDK=YES
shift # past argument shift # past argument
;; ;;
-r|--runtime) -r|--runtime)
@@ -362,17 +350,12 @@ esac
done done
set -- "${POSITIONAL[@]}" # restore positional parameters set -- "${POSITIONAL[@]}" # restore positional parameters
if [ "$ENABLE_EXTRA_PLATFORMS_IN_SDK" = "YES" ];
then
EnableExtraPlatformsInSDK
fi
if [ "$BACKEND" = "YES" ]; if [ "$BACKEND" = "YES" ];
then then
UpdateVersionNumber UpdateVersionNumber
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ]; if [ "$ENABLE_BSD" = "YES" ];
then then
EnableExtraPlatforms EnableBsdSupport
fi fi
Build Build
if [[ -z "$RID" || -z "$FRAMEWORK" ]]; if [[ -z "$RID" || -z "$FRAMEWORK" ]];
@@ -382,10 +365,9 @@ then
PackageTests "net6.0" "linux-x64" PackageTests "net6.0" "linux-x64"
PackageTests "net6.0" "linux-musl-x64" PackageTests "net6.0" "linux-musl-x64"
PackageTests "net6.0" "osx-x64" PackageTests "net6.0" "osx-x64"
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ]; if [ "$ENABLE_BSD" = "YES" ];
then then
PackageTests "net6.0" "freebsd-x64" PackageTests "net6.0" "freebsd-x64"
PackageTests "net6.0" "linux-x86"
fi fi
else else
PackageTests "$FRAMEWORK" "$RID" PackageTests "$FRAMEWORK" "$RID"
@@ -424,10 +406,9 @@ then
Package "net6.0" "linux-musl-arm" Package "net6.0" "linux-musl-arm"
Package "net6.0" "osx-x64" Package "net6.0" "osx-x64"
Package "net6.0" "osx-arm64" Package "net6.0" "osx-arm64"
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ]; if [ "$ENABLE_BSD" = "YES" ];
then then
Package "net6.0" "freebsd-x64" Package "net6.0" "freebsd-x64"
Package "net6.0" "linux-x86"
fi fi
else else
Package "$FRAMEWORK" "$RID" Package "$FRAMEWORK" "$RID"
+2 -2
View File
@@ -142,8 +142,8 @@ module.exports = (env) => {
module: { module: {
rules: [ rules: [
{ {
test: /\.jsx?$/, test: /\.js?$/,
exclude: /[\\/]node_modules[\\/](?!(@sentry\/browser|@sentry\/integrations|chart.js|filesize|normalize.css)[\\/])/, exclude: /(node_modules|JsLibraries)/,
use: [ use: [
{ {
loader: 'babel-loader', loader: 'babel-loader',
+2 -1
View File
@@ -1,6 +1,7 @@
const reload = require('require-nocache')(module); const reload = require('require-nocache')(module);
const cssVarsFiles = [ const cssVarsFiles = [
'./src/Styles/Variables/colors',
'./src/Styles/Variables/dimensions', './src/Styles/Variables/dimensions',
'./src/Styles/Variables/fonts', './src/Styles/Variables/fonts',
'./src/Styles/Variables/animations', './src/Styles/Variables/animations',
@@ -28,4 +29,4 @@ module.exports = {
'postcss-color-function', 'postcss-color-function',
'postcss-nested' 'postcss-nested'
] ]
}; };
+4 -7
View File
@@ -4,19 +4,16 @@ import React from 'react';
import DocumentTitle from 'react-document-title'; import DocumentTitle from 'react-document-title';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import PageConnector from 'Components/Page/PageConnector'; import PageConnector from 'Components/Page/PageConnector';
import ApplyTheme from './ApplyTheme';
import AppRoutes from './AppRoutes'; import AppRoutes from './AppRoutes';
function App({ store, history }) { function App({ store, history }) {
return ( return (
<DocumentTitle title={window.Prowlarr.instanceName}> <DocumentTitle title="Prowlarr">
<Provider store={store}> <Provider store={store}>
<ConnectedRouter history={history}> <ConnectedRouter history={history}>
<ApplyTheme> <PageConnector>
<PageConnector> <AppRoutes app={App} />
<AppRoutes app={App} /> </PageConnector>
</PageConnector>
</ApplyTheme>
</ConnectedRouter> </ConnectedRouter>
</Provider> </Provider>
</DocumentTitle> </DocumentTitle>
-49
View File
@@ -1,49 +0,0 @@
import PropTypes from 'prop-types';
import React, { Fragment, useEffect } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import themes from 'Styles/Themes';
function createMapStateToProps() {
return createSelector(
(state) => state.settings.ui.item.theme || window.Prowlarr.theme,
(
theme
) => {
return {
theme
};
}
);
}
function ApplyTheme({ theme, children }) {
// Update the CSS Variables
function updateCSSVariables() {
const arrayOfVariableKeys = Object.keys(themes[theme]);
const arrayOfVariableValues = Object.values(themes[theme]);
// Loop through each array key and set the CSS Variables
arrayOfVariableKeys.forEach((cssVariableKey, index) => {
// Based on our snippet from MDN
document.documentElement.style.setProperty(
`--${cssVariableKey}`,
arrayOfVariableValues[index]
);
});
}
// On Component Mount and Component Update
useEffect(() => {
updateCSSVariables(theme);
}, [theme]);
return <Fragment>{children}</Fragment>;
}
ApplyTheme.propTypes = {
theme: PropTypes.string.isRequired,
children: PropTypes.object.isRequired
};
export default connect(createMapStateToProps)(ApplyTheme);
+12 -12
View File
@@ -7,25 +7,25 @@
} }
.danger { .danger {
border-color: var(--alertDangerBorderColor); border-color: $alertDangerBorderColor;
background-color: var(--alertDangerBackgroundColor); background-color: $alertDangerBackgroundColor;
color: var(--alertDangerColor); color: $alertDangerColor;
} }
.info { .info {
border-color: var(--alertInfoBorderColor); border-color: $alertInfoBorderColor;
background-color: var(--alertInfoBackgroundColor); background-color: $alertInfoBackgroundColor;
color: var(--alertInfoColor); color: $alertInfoColor;
} }
.success { .success {
border-color: var(--alertSuccessBorderColor); border-color: $alertSuccessBorderColor;
background-color: var(--alertSuccessBackgroundColor); background-color: $alertSuccessBackgroundColor;
color: var(--alertSuccessColor); color: $alertSuccessColor;
} }
.warning { .warning {
border-color: var(--alertWarningBorderColor); border-color: $alertWarningBorderColor;
background-color: var(--alertWarningBackgroundColor); background-color: $alertWarningBackgroundColor;
color: var(--alertWarningColor); color: $alertWarningColor;
} }
+3 -3
View File
@@ -3,9 +3,9 @@
margin: 10px; margin: 10px;
padding: 10px; padding: 10px;
border-radius: 3px; border-radius: 3px;
background-color: var(--cardBackgroundColor); background-color: $white;
box-shadow: 0 0 10px 1px var(--cardShadowColor); box-shadow: 0 0 10px 1px $cardShadowColor;
color: var(--defaultColor); color: $defaultColor;
} }
.underlay { .underlay {
+3 -4
View File
@@ -2,16 +2,15 @@ import Chart from 'chart.js/auto';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { kinds } from 'Helpers/Props'; import { kinds } from 'Helpers/Props';
import colors from 'Styles/Variables/colors';
function getColors(kind) { function getColors(kind) {
const style = getComputedStyle(document.body);
if (kind === kinds.WARNING) { if (kind === kinds.WARNING) {
return style.getPropertyValue('--failedColors').split(','); return colors.failedColors.reverse();
} }
return style.getPropertyValue('--chartColors').split(','); return colors.chartColors;
} }
class BarChart extends Component { class BarChart extends Component {
@@ -1,12 +1,7 @@
import Chart from 'chart.js/auto'; import Chart from 'chart.js/auto';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import colors from 'Styles/Variables/colors';
function getColors(kind) {
const style = getComputedStyle(document.body);
return style.getPropertyValue('--chartColorsDiversified').split(',');
}
class DoughnutChart extends Component { class DoughnutChart extends Component {
constructor(props) { constructor(props) {
@@ -34,7 +29,7 @@ class DoughnutChart extends Component {
datasets: [{ datasets: [{
label: this.props.title, label: this.props.title,
data: this.props.data.map((d) => d.value), data: this.props.data.map((d) => d.value),
backgroundColor: getColors() backgroundColor: colors.chartColors
}] }]
} }
}); });
@@ -1,12 +1,7 @@
import Chart from 'chart.js/auto'; import Chart from 'chart.js/auto';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import colors from 'Styles/Variables/colors';
function getColors(index) {
const style = getComputedStyle(document.body);
return style.getPropertyValue('--chartColorsDiversified').split(',')[index];
}
class StackedBarChart extends Component { class StackedBarChart extends Component {
constructor(props) { constructor(props) {
@@ -46,7 +41,7 @@ class StackedBarChart extends Component {
return { return {
label: d.label, label: d.label,
data: d.data, data: d.data,
backgroundColor: getColors(index) backgroundColor: colors.chartColors[index]
}; };
}) })
} }
@@ -59,7 +54,7 @@ class StackedBarChart extends Component {
return { return {
label: d.label, label: d.label,
data: d.data, data: d.data,
backgroundColor: getColors(index) backgroundColor: colors.chartColors[index]
}; };
}); });
this.myChart.update(); this.myChart.update();
+1 -1
View File
@@ -13,7 +13,7 @@
width: 100%; width: 100%;
border: 0; border: 0;
border-bottom: 1px solid #e5e5e5; border-bottom: 1px solid #e5e5e5;
color: var(--textColor); color: #3a3f51;
font-size: 21px; font-size: 21px;
line-height: inherit; line-height: inherit;
} }
@@ -13,7 +13,7 @@
} }
.faqLink { .faqLink {
color: var(--alertWarningColor); color: $alertWarningColor;
font-weight: bold; font-weight: bold;
} }
@@ -160,7 +160,6 @@ class DateFilterBuilderRowValue extends Component {
<TextInput <TextInput
name={NAME} name={NAME}
value={filterValue} value={filterValue}
type="date"
placeholder="yyyy-mm-dd" placeholder="yyyy-mm-dd"
onChange={this.onValueChange} onChange={this.onValueChange}
/> />
@@ -3,7 +3,7 @@
margin-bottom: 5px; margin-bottom: 5px;
&:hover { &:hover {
background-color: var(--tableRowHoverBackgroundColor); background-color: $tableRowHoverBackgroundColor;
} }
} }
@@ -17,5 +17,5 @@
.or { .or {
margin: 0 3px; margin: 0 3px;
color: var(--themeDarkColor); color: $themeDarkColor;
} }
@@ -4,7 +4,7 @@
padding: 5px; padding: 5px;
&:hover { &:hover {
background-color: var(--tableRowHoverBackgroundColor); background-color: $tableRowHoverBackgroundColor;
} }
} }
@@ -27,10 +27,10 @@
overflow-y: auto; overflow-y: auto;
max-height: 200px; max-height: 200px;
width: 100%; width: 100%;
border: 1px solid var(--inputBorderColor); border: 1px solid $inputBorderColor;
border-radius: 4px; border-radius: 4px;
background-color: var(--inputBackgroundColor); background-color: $white;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor;
} }
} }
@@ -46,5 +46,5 @@
} }
.suggestionHighlighted { .suggestionHighlighted {
background-color: var(--menuItemHoverBackgroundColor); background-color: $menuItemHoverBackgroundColor;
} }
+16 -16
View File
@@ -32,21 +32,21 @@
height: 20px; height: 20px;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 2px; border-radius: 2px;
background-color: var(--white); background-color: $white;
color: var(--white); color: $white;
text-align: center; text-align: center;
line-height: 20px; line-height: 20px;
} }
.checkbox:focus + .input { .checkbox:focus + .input {
outline: 0; outline: 0;
border-color: var(--inputFocusBorderColor); border-color: $inputFocusBorderColor;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor), 0 0 8px var(--inputFocusBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor, 0 0 8px $inputFocusBoxShadowColor;
} }
.dangerIsChecked { .dangerIsChecked {
border-color: var(--dangerColor); border-color: $dangerColor;
background-color: var(--dangerColor); background-color: $dangerColor;
&.isDisabled { &.isDisabled {
opacity: 0.7; opacity: 0.7;
@@ -54,8 +54,8 @@
} }
.primaryIsChecked { .primaryIsChecked {
border-color: var(--primaryColor); border-color: $primaryColor;
background-color: var(--primaryColor); background-color: $primaryColor;
&.isDisabled { &.isDisabled {
opacity: 0.7; opacity: 0.7;
@@ -63,8 +63,8 @@
} }
.successIsChecked { .successIsChecked {
border-color: var(--successColor); border-color: $successColor;
background-color: var(--successColor); background-color: $successColor;
&.isDisabled { &.isDisabled {
opacity: 0.7; opacity: 0.7;
@@ -72,8 +72,8 @@
} }
.warningIsChecked { .warningIsChecked {
border-color: var(--warningColor); border-color: $warningColor;
background-color: var(--warningColor); background-color: $warningColor;
&.isDisabled { &.isDisabled {
opacity: 0.7; opacity: 0.7;
@@ -82,15 +82,15 @@
.isNotChecked { .isNotChecked {
&.isDisabled { &.isDisabled {
border-color: var(--disabledCheckInputColor); border-color: $disabledCheckInputColor;
background-color: var(--disabledCheckInputColor); background-color: $disabledCheckInputColor;
opacity: 0.7; opacity: 0.7;
} }
} }
.isIndeterminate { .isIndeterminate {
border-color: var(--gray); border-color: $gray;
background-color: var(--gray); background-color: $gray;
} }
.helpText { .helpText {
@@ -39,7 +39,7 @@
.dropdownArrowContainerDisabled { .dropdownArrowContainerDisabled {
composes: dropdownArrowContainer; composes: dropdownArrowContainer;
color: var(--disabledInputColor); color: $disabledInputColor;
} }
.optionsContainer { .optionsContainer {
@@ -50,9 +50,9 @@
.options { .options {
composes: scroller from '~Components/Scroller/Scroller.css'; composes: scroller from '~Components/Scroller/Scroller.css';
border: 1px solid var(--inputBorderColor); border: 1px solid $inputBorderColor;
border-radius: 4px; border-radius: 4px;
background-color: var(--inputBackgroundColor); background-color: $white;
} }
.optionsModal { .optionsModal {
@@ -76,9 +76,9 @@
.optionsModalScroller { .optionsModalScroller {
composes: scroller from '~Components/Scroller/Scroller.css'; composes: scroller from '~Components/Scroller/Scroller.css';
border: 1px solid var(--inputBorderColor); border: 1px solid $inputBorderColor;
border-radius: 4px; border-radius: 4px;
background-color: var(--inputBackgroundColor); background-color: $white;
} }
.loading { .loading {
@@ -90,7 +90,7 @@
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
height: 40px; height: 40px;
border-bottom: 1px solid var(--borderColor); border-bottom: 1px solid $borderColor;
} }
.mobileCloseButton { .mobileCloseButton {
@@ -100,6 +100,6 @@
line-height: 40px; line-height: 40px;
&:hover { &:hover {
color: var(--modalCloseButtonHoverColor); color: $modalCloseButtonHoverColor;
} }
} }
@@ -7,7 +7,7 @@
cursor: default; cursor: default;
&:hover { &:hover {
background-color: var(--inputHoverBackgroundColor); background-color: #f8f8f8;
} }
} }
@@ -24,17 +24,17 @@
} }
.isSelected { .isSelected {
background-color: var(--inputSelectedBackgroundColor); background-color: #e2e2e2;
&:hover { &:hover {
background-color: var(--inputSelectedBackgroundColor); background-color: #e2e2e2;
} }
&.isMobile { &.isMobile {
background-color: inherit; background-color: inherit;
.iconContainer { .iconContainer {
color: var(--primaryColor); color: $primaryColor;
} }
} }
} }
@@ -49,7 +49,7 @@
.isMobile { .isMobile {
height: 50px; height: 50px;
border-bottom: 1px solid var(--borderColor); border-bottom: 1px solid $borderColor;
&:last-child { &:last-child {
border: none; border: none;
@@ -3,5 +3,5 @@
} }
.isDisabled { .isDisabled {
color: var(--disabledInputColor); color: $disabledInputColor;
} }
@@ -40,7 +40,7 @@
} }
.pendingChangesIcon { .pendingChangesIcon {
color: var(--warningColor); color: $warningColor;
font-size: 20px; font-size: 20px;
line-height: 35px; line-height: 35px;
} }
@@ -16,7 +16,6 @@ import FormInputHelpText from './FormInputHelpText';
import IndexerFlagsSelectInputConnector from './IndexerFlagsSelectInputConnector'; import IndexerFlagsSelectInputConnector from './IndexerFlagsSelectInputConnector';
import InfoInput from './InfoInput'; import InfoInput from './InfoInput';
import KeyValueListInput from './KeyValueListInput'; import KeyValueListInput from './KeyValueListInput';
import NewznabCategorySelectInputConnector from './NewznabCategorySelectInputConnector';
import NumberInput from './NumberInput'; import NumberInput from './NumberInput';
import OAuthInputConnector from './OAuthInputConnector'; import OAuthInputConnector from './OAuthInputConnector';
import PasswordInput from './PasswordInput'; import PasswordInput from './PasswordInput';
@@ -69,9 +68,6 @@ function getComponent(type) {
case inputTypes.PATH: case inputTypes.PATH:
return PathInputConnector; return PathInputConnector;
case inputTypes.CATEGORY_SELECT:
return NewznabCategorySelectInputConnector;
case inputTypes.INDEXER_FLAGS_SELECT: case inputTypes.INDEXER_FLAGS_SELECT:
return IndexerFlagsSelectInputConnector; return IndexerFlagsSelectInputConnector;
@@ -1,14 +1,14 @@
.helpText { .helpText {
margin-top: 5px; margin-top: 5px;
color: var(--helpTextColor); color: $helpTextColor;
line-height: 20px; line-height: 20px;
} }
.isError { .isError {
color: var(--dangerColor); color: $dangerColor;
.link { .link {
color: var(--dangerColor); color: $dangerColor;
&:hover { &:hover {
color: #e01313; color: #e01313;
@@ -17,10 +17,10 @@
} }
.isWarning { .isWarning {
color: var(--warningColor); color: $warningColor;
.link { .link {
color: var(--warningColor); color: $warningColor;
&:hover { &:hover {
color: #e36c00; color: #e36c00;
+2 -2
View File
@@ -7,11 +7,11 @@
} }
.hasError { .hasError {
color: var(--dangerColor); color: $dangerColor;
} }
.isAdvanced { .isAdvanced {
color: var(--advancedFormLabelColor); color: $advancedFormLabelColor;
} }
@media only screen and (max-width: $breakpointLarge) { @media only screen and (max-width: $breakpointLarge) {
@@ -18,6 +18,6 @@
@add-mixin truncate; @add-mixin truncate;
margin-left: 15px; margin-left: 15px;
color: var(--darkGray); color: $darkGray;
font-size: $smallFontSize; font-size: $smallFontSize;
} }
@@ -18,7 +18,7 @@
flex: 1 10 0; flex: 1 10 0;
margin-left: 15px; margin-left: 15px;
color: var(--gray); color: $gray;
text-align: right; text-align: right;
font-size: $smallFontSize; font-size: $smallFontSize;
} }
+9 -10
View File
@@ -2,27 +2,26 @@
padding: 6px 16px; padding: 6px 16px;
width: 100%; width: 100%;
height: 35px; height: 35px;
border: 1px solid var(--inputBorderColor); border: 1px solid $inputBorderColor;
border-radius: 4px; border-radius: 4px;
background-color: var(--inputBackgroundColor); background-color: $white;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor;
color: var(--textColor);
&:focus { &:focus {
outline: 0; outline: 0;
border-color: var(--inputFocusBorderColor); border-color: $inputFocusBorderColor;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor), 0 0 8px var(--inputFocusBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor, 0 0 8px $inputFocusBoxShadowColor;
} }
} }
.hasError { .hasError {
border-color: var(--inputErrorBorderColor); border-color: $inputErrorBorderColor;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor), 0 0 8px var(--inputErrorBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor, 0 0 8px $inputErrorBoxShadowColor;
} }
.hasWarning { .hasWarning {
border-color: var(--inputWarningBorderColor); border-color: $inputWarningBorderColor;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor), 0 0 8px var(--inputWarningBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor, 0 0 8px $inputWarningBoxShadowColor;
} }
.hasButton { .hasButton {
@@ -7,8 +7,8 @@
&.isFocused { &.isFocused {
outline: 0; outline: 0;
border-color: var(--inputFocusBorderColor); border-color: $inputFocusBorderColor;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor), 0 0 8px var(--inputFocusBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor, 0 0 8px $inputFocusBoxShadowColor;
} }
} }
@@ -1,7 +1,7 @@
.itemContainer { .itemContainer {
display: flex; display: flex;
margin-bottom: 3px; margin-bottom: 3px;
border-bottom: 1px solid var(--inputBorderColor); border-bottom: 1px solid $inputBorderColor;
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
@@ -31,7 +31,7 @@ function createMapStateToProps() {
}); });
return { return {
value: value || [], value,
values values
}; };
} }
+2 -4
View File
@@ -7,8 +7,8 @@
&.isFocused { &.isFocused {
outline: 0; outline: 0;
border-color: var(--inputFocusBorderColor); border-color: $inputFocusBorderColor;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor), 0 0 8px var(--inputFocusBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor, 0 0 8px $inputFocusBoxShadowColor;
} }
} }
@@ -20,6 +20,4 @@
width: 0%; width: 0%;
height: 31px; height: 31px;
border: none; border: none;
background-color: var(--inputBackground);
color: var(--textColor);
} }
@@ -36,6 +36,7 @@ class TagInputInput extends Component {
<div <div
ref={forwardedRef} ref={forwardedRef}
className={className} className={className}
component="div"
onMouseDown={this.onMouseDown} onMouseDown={this.onMouseDown}
> >
{ {
+1 -1
View File
@@ -7,7 +7,7 @@
} }
.readOnly { .readOnly {
background-color: var(--inputReadOnlyBackgroundColor); background-color: #eee;
} }
.hasError { .hasError {
+1 -1
View File
@@ -3,7 +3,7 @@
} }
.readOnly { .readOnly {
background-color: var(--inputReadOnlyBackgroundColor); background-color: #eee;
} }
.hasError { .hasError {
+10 -6
View File
@@ -1,5 +1,5 @@
.danger { .danger {
color: var(--dangerColor); color: $dangerColor;
} }
.default { .default {
@@ -7,21 +7,25 @@
} }
.disabled { .disabled {
color: var(--disabledColor); color: $disabledColor;
} }
.info { .info {
color: var(--infoColor); color: $infoColor;
}
.pink {
color: $pink;
} }
.success { .success {
color: var(--successColor); color: $successColor;
} }
.warning { .warning {
color: var(--warningColor); color: $warningColor;
} }
.purple { .purple {
color: var(--purple); color: $purple;
} }
+3 -3
View File
@@ -1,7 +1,7 @@
.label { .label {
display: inline-block; display: inline-block;
margin: 2px; margin: 2px;
color: var(--white); color: $white;
/** text-align: center; **/ /** text-align: center; **/
white-space: nowrap; white-space: nowrap;
line-height: 1; line-height: 1;
@@ -10,7 +10,7 @@
.title { .title {
margin-bottom: 2px; margin-bottom: 2px;
color: var(--helpTextColor); color: $helpTextColor;
font-size: 10px; font-size: 10px;
} }
@@ -36,5 +36,5 @@
/** Outline **/ /** Outline **/
.outline { .outline {
background-color: var(--cardBackgroundColor); background-color: $white;
} }
+37 -28
View File
@@ -3,7 +3,7 @@
margin: 2px; margin: 2px;
border: 1px solid; border: 1px solid;
border-radius: 2px; border-radius: 2px;
color: var(--white); color: $white;
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
line-height: 1; line-height: 1;
@@ -13,77 +13,86 @@
/** Kinds **/ /** Kinds **/
.danger { .danger {
border-color: var(--dangerColor); border-color: $dangerColor;
background-color: var(--dangerColor); background-color: $dangerColor;
&.outline { &.outline {
color: var(--dangerColor); color: $dangerColor;
} }
} }
.default { .default {
border-color: var(--themeLightColor); border-color: $themeLightColor;
background-color: var(--themeLightColor); background-color: $themeLightColor;
&.outline { &.outline {
color: var(--themeLightColor); color: $themeLightColor;
} }
} }
.disabled { .disabled {
border-color: var(--disabledColor); border-color: $disabledColor;
background-color: var(--disabledColor); background-color: $disabledColor;
&.outline { &.outline {
color: var(--disabledColor); color: $disabledColor;
} }
} }
.info { .info {
border-color: var(--infoColor); border-color: $infoColor;
background-color: var(--infoColor); background-color: $infoColor;
&.outline { &.outline {
color: var(--infoColor); color: $infoColor;
} }
} }
.inverse { .inverse {
border-color: var(--inverseLabelColor); border-color: $lightGray;
background-color: var(--inverseLabelColor); background-color: $lightGray;
color: var(--inverseLabelTextColor); color: $defaultColor;
&.outline { &.outline {
background-color: var(--inverseLabelTextColor) !important; background-color: $defaultColor !important;
color: var(--inverseLabelColor); color: $lightGray;
} }
} }
.primary { .primary {
border-color: var(--primaryColor); border-color: $primaryColor;
background-color: var(--primaryColor); background-color: $primaryColor;
&.outline { &.outline {
color: var(--primaryColor); color: $primaryColor;
} }
} }
.success { .success {
border-color: var(--successColor); border-color: $successColor;
background-color: var(--successColor); background-color: $successColor;
color: #eee; color: #eee;
&.outline { &.outline {
color: var(--successColor); color: $successColor;
} }
} }
.warning { .warning {
border-color: var(--warningColor); border-color: $warningColor;
background-color: var(--warningColor); background-color: $warningColor;
&.outline { &.outline {
color: var(--warningColor); color: $warningColor;
}
}
.queue {
border-color: $queueColor;
background-color: $queueColor;
&.outline {
color: $queueColor;
} }
} }
@@ -108,5 +117,5 @@
/** Outline **/ /** Outline **/
.outline { .outline {
background-color: var(--cardBackgroundColor); background-color: $white;
} }
+30 -30
View File
@@ -19,62 +19,62 @@
} }
.danger { .danger {
border-color: var(--dangerBorderColor); border-color: $dangerBorderColor;
background-color: var(--dangerBackgroundColor); background-color: $dangerBackgroundColor;
color: var(--white); color: $white;
&:hover { &:hover {
border-color: var(--dangerHoverBorderColor); border-color: $dangerHoverBorderColor;
background-color: var(--dangerHoverBackgroundColor); background-color: $dangerHoverBackgroundColor;
color: var(--white); color: $white;
} }
} }
.default { .default {
border-color: var(--defaultBorderColor); border-color: $defaultBorderColor;
background-color: var(--defaultButtonBackgroundColor); background-color: $defaultBackgroundColor;
color: var(--defaultButtonTextColor); color: $defaultColor;
&:hover { &:hover {
border-color: var(--defaultHoverBorderColor); border-color: $defaultHoverBorderColor;
background-color: var(--defaultHoverBackgroundColor); background-color: $defaultHoverBackgroundColor;
color: var(--defaultButtonTextColor); color: $defaultColor;
} }
} }
.primary { .primary {
border-color: var(--primaryBorderColor); border-color: $primaryBorderColor;
background-color: var(--primaryBackgroundColor); background-color: $primaryBackgroundColor;
color: var(--white); color: $white;
&:hover { &:hover {
border-color: var(--primaryHoverBorderColor); border-color: $primaryHoverBorderColor;
background-color: var(--primaryHoverBackgroundColor); background-color: $primaryHoverBackgroundColor;
color: var(--white); color: $white;
} }
} }
.success { .success {
border-color: var(--successBorderColor); border-color: $successBorderColor;
background-color: var(--successBackgroundColor); background-color: $successBackgroundColor;
color: var(--white); color: $white;
&:hover { &:hover {
border-color: var(--successHoverBorderColor); border-color: $successHoverBorderColor;
background-color: var(--successHoverBackgroundColor); background-color: $successHoverBackgroundColor;
color: var(--white); color: $white;
} }
} }
.warning { .warning {
border-color: var(--warningBorderColor); border-color: $warningBorderColor;
background-color: var(--warningBackgroundColor); background-color: $warningBackgroundColor;
color: var(--white); color: $white;
&:hover { &:hover {
border-color: var(--warningHoverBorderColor); border-color: $warningHoverBorderColor;
background-color: var(--warningHoverBackgroundColor); background-color: $warningHoverBackgroundColor;
color: var(--white); color: $white;
} }
} }
+2 -2
View File
@@ -12,10 +12,10 @@
&:hover { &:hover {
border: none; border: none;
background-color: inherit; background-color: inherit;
color: var(--iconButtonHoverColor); color: $iconButtonHoverColor;
} }
&.isDisabled { &.isDisabled {
color: var(--iconButtonDisabledColor); color: $iconButtonDisabledColor;
} }
} }
+2 -2
View File
@@ -15,10 +15,10 @@
} }
.to { .to {
color: var(--linkColor); color: $linkColor;
&:hover { &:hover {
color: var(--linkHoverColor); color: $linkHoverColor;
text-decoration: underline; text-decoration: underline;
} }
} }
@@ -26,7 +26,7 @@
.ripple { .ripple {
position: absolute; position: absolute;
border: 2px solid var(--themeDarkColor); border: 2px solid #3a3f51;
border-radius: 100%; border-radius: 100%;
animation: rippleContainer 1.25s 0s infinite cubic-bezier(0.21, 0.53, 0.56, 0.8); animation: rippleContainer 1.25s 0s infinite cubic-bezier(0.21, 0.53, 0.56, 0.8);
animation-fill-mode: both; animation-fill-mode: both;
+2 -2
View File
@@ -10,12 +10,12 @@
} }
&:hover { &:hover {
color: var(--toobarButtonHoverColor); color: $toobarButtonHoverColor;
} }
} }
.isDisabled { .isDisabled {
color: var(--disabledColor); color: $disabledColor;
pointer-events: none; pointer-events: none;
} }
+1 -1
View File
@@ -2,7 +2,7 @@
z-index: $popperZIndex; z-index: $popperZIndex;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: var(--toolbarMenuItemBackgroundColor); background-color: $toolbarMenuItemBackgroundColor;
line-height: 20px; line-height: 20px;
} }
+5 -5
View File
@@ -5,19 +5,19 @@
padding: 10px 20px; padding: 10px 20px;
min-width: 150px; min-width: 150px;
max-width: 250px; max-width: 250px;
background-color: var(--toolbarMenuItemBackgroundColor); background-color: $toolbarMenuItemBackgroundColor;
color: var(--menuItemColor); color: $menuItemColor;
line-height: 20px; line-height: 20px;
&:hover, &:hover,
&:focus { &:focus {
background-color: var(--toolbarMenuItemHoverBackgroundColor); background-color: $toolbarMenuItemHoverBackgroundColor;
color: var(--menuItemHoverColor); color: $menuItemHoverColor;
text-decoration: none; text-decoration: none;
} }
} }
.isDisabled { .isDisabled {
color: var(--disabledColor); color: $disabledColor;
pointer-events: none; pointer-events: none;
} }
@@ -2,5 +2,5 @@
overflow: hidden; overflow: hidden;
min-height: 1px; min-height: 1px;
height: 1px; height: 1px;
background-color: var(--themeDarkColor); background-color: $themeDarkColor;
} }
+1 -1
View File
@@ -12,7 +12,7 @@
justify-content: center; justify-content: center;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: var(--modalBackdropBackgroundColor); background-color: $modalBackdropBackgroundColor;
opacity: 1; opacity: 1;
} }
@@ -4,7 +4,7 @@
flex-direction: column; flex-direction: column;
flex-grow: 1; flex-grow: 1;
width: 100%; width: 100%;
background-color: var(--modalBackgroundColor); background-color: $modalBackgroundColor;
} }
.closeButton { .closeButton {
@@ -18,6 +18,6 @@
line-height: 60px; line-height: 60px;
&:hover { &:hover {
color: var(--modalCloseButtonHoverColor); color: $modalCloseButtonHoverColor;
} }
} }
@@ -4,7 +4,7 @@
justify-content: flex-end; justify-content: flex-end;
flex-shrink: 0; flex-shrink: 0;
padding: 15px 30px; padding: 15px 30px;
border-top: 1px solid var(--borderColor); border-top: 1px solid $borderColor;
a, a,
button { button {
@@ -3,6 +3,6 @@
flex-shrink: 0; flex-shrink: 0;
padding: 15px 50px 15px 30px; padding: 15px 50px 15px 30px;
border-bottom: 1px solid var(--borderColor); border-bottom: 1px solid $borderColor;
font-size: 18px; font-size: 18px;
} }
@@ -12,22 +12,22 @@
.ripple { .ripple {
composes: ripple from '~Components/Loading/LoadingIndicator.css'; composes: ripple from '~Components/Loading/LoadingIndicator.css';
border: 1px solid var(--toolbarColor); border: 1px solid $toolbarColor;
} }
.input { .input {
margin-left: 8px; margin-left: 8px;
width: 200px; width: 200px;
border: none; border: none;
border-bottom: solid 1px var(--white); border-bottom: solid 1px $white;
border-radius: 0; border-radius: 0;
background-color: transparent; background-color: transparent;
box-shadow: none; box-shadow: none;
color: var(--white); color: $white;
transition: border 0.3s ease-out; transition: border 0.3s ease-out;
&::placeholder { &::placeholder {
color: var(--white); color: $white;
transition: color 0.3s ease-out; transition: color 0.3s ease-out;
} }
@@ -60,13 +60,13 @@
overflow-y: auto; overflow-y: auto;
min-width: 100%; min-width: 100%;
max-height: 230px; max-height: 230px;
border: 1px solid var(--themeDarkColor); border: 1px solid $themeDarkColor;
border-radius: 4px; border-radius: 4px;
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
background-color: var(--themeDarkColor); background-color: $themeDarkColor;
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor); box-shadow: inset 0 1px 1px $inputBoxShadowColor;
color: var(--menuItemColor); color: $menuItemColor;
} }
} }
@@ -82,12 +82,12 @@
} }
.highlighted { .highlighted {
background-color: var(--themeLightColor); background-color: $themeLightColor;
} }
.sectionTitle { .sectionTitle {
padding: 5px 8px; padding: 5px 8px;
color: var(--disabledColor); color: $disabledColor;
} }
.addNewMovieSuggestion { .addNewMovieSuggestion {
@@ -21,7 +21,7 @@
.alternateTitle { .alternateTitle {
composes: title; composes: title;
color: var(--disabledColor); color: $disabledColor;
font-size: $smallFontSize; font-size: $smallFontSize;
} }
@@ -8,8 +8,8 @@
.key { .key {
padding: 2px 4px; padding: 2px 4px;
border-radius: 3px; border-radius: 3px;
background-color: var(--defaultColor); background-color: $defaultColor;
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
color: var(--white); color: $white;
font-size: 16px; font-size: 16px;
} }
@@ -4,9 +4,9 @@
align-items: center; align-items: center;
flex: 0 0 auto; flex: 0 0 auto;
height: $headerHeight; height: $headerHeight;
background-color: var(--pageHeaderBackgroundColor); background-color: $prowlarrOrange;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
color: var(--white); color: $white;
} }
.logoContainer { .logoContainer {
@@ -80,7 +80,7 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 30px; width: 30px;
color: var(--themeRed); color: $themeRed;
text-align: center; text-align: center;
line-height: 60px; line-height: 60px;
@@ -74,7 +74,7 @@ class PageHeader extends Component {
<IconButton <IconButton
className={styles.donate} className={styles.donate}
name={icons.HEART} name={icons.HEART}
to="https://prowlarr.com/donate" to="https://opencollective.com/prowlarr"
size={14} size={14}
/> />
<IconButton <IconButton
@@ -5,7 +5,7 @@
text-align: center; text-align: center;
&:hover { &:hover {
color: #515253; color: $toobarButtonHoverColor;
} }
} }
@@ -1,7 +1,5 @@
.page { .page {
composes: page from '~./Page.css'; composes: page from '~./Page.css';
background-color: var(--pageBackground);
} }
.logoFull { .logoFull {
-7
View File
@@ -4,7 +4,6 @@ import AppUpdatedModalConnector from 'App/AppUpdatedModalConnector';
import ColorImpairedContext from 'App/ColorImpairedContext'; import ColorImpairedContext from 'App/ColorImpairedContext';
import ConnectionLostModalConnector from 'App/ConnectionLostModalConnector'; import ConnectionLostModalConnector from 'App/ConnectionLostModalConnector';
import SignalRConnector from 'Components/SignalRConnector'; import SignalRConnector from 'Components/SignalRConnector';
import AuthenticationRequiredModal from 'FirstRun/AuthenticationRequiredModal';
import locationShape from 'Helpers/Props/Shapes/locationShape'; import locationShape from 'Helpers/Props/Shapes/locationShape';
import PageHeader from './Header/PageHeader'; import PageHeader from './Header/PageHeader';
import PageSidebar from './Sidebar/PageSidebar'; import PageSidebar from './Sidebar/PageSidebar';
@@ -76,7 +75,6 @@ class Page extends Component {
isSmallScreen, isSmallScreen,
isSidebarVisible, isSidebarVisible,
enableColorImpairedMode, enableColorImpairedMode,
authenticationEnabled,
onSidebarToggle, onSidebarToggle,
onSidebarVisibleChange onSidebarVisibleChange
} = this.props; } = this.props;
@@ -111,10 +109,6 @@ class Page extends Component {
isOpen={this.state.isConnectionLostModalOpen} isOpen={this.state.isConnectionLostModalOpen}
onModalClose={this.onConnectionLostModalClose} onModalClose={this.onConnectionLostModalClose}
/> />
<AuthenticationRequiredModal
isOpen={!authenticationEnabled}
/>
</div> </div>
</ColorImpairedContext.Provider> </ColorImpairedContext.Provider>
); );
@@ -130,7 +124,6 @@ Page.propTypes = {
isUpdated: PropTypes.bool.isRequired, isUpdated: PropTypes.bool.isRequired,
isDisconnected: PropTypes.bool.isRequired, isDisconnected: PropTypes.bool.isRequired,
enableColorImpairedMode: PropTypes.bool.isRequired, enableColorImpairedMode: PropTypes.bool.isRequired,
authenticationEnabled: PropTypes.bool.isRequired,
onResize: PropTypes.func.isRequired, onResize: PropTypes.func.isRequired,
onSidebarToggle: PropTypes.func.isRequired, onSidebarToggle: PropTypes.func.isRequired,
onSidebarVisibleChange: PropTypes.func.isRequired onSidebarVisibleChange: PropTypes.func.isRequired
+15 -6
View File
@@ -7,11 +7,10 @@ import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
import { fetchCustomFilters } from 'Store/Actions/customFilterActions'; import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
import { fetchIndexers } from 'Store/Actions/indexerActions'; import { fetchIndexers } from 'Store/Actions/indexerActions';
import { fetchIndexerStatus } from 'Store/Actions/indexerStatusActions'; import { fetchIndexerStatus } from 'Store/Actions/indexerStatusActions';
import { fetchAppProfiles, fetchGeneralSettings, fetchIndexerCategories, fetchUISettings } from 'Store/Actions/settingsActions'; import { fetchAppProfiles, fetchGeneralSettings, fetchIndexerCategories, fetchLanguages, fetchUISettings } from 'Store/Actions/settingsActions';
import { fetchStatus } from 'Store/Actions/systemActions'; import { fetchStatus } from 'Store/Actions/systemActions';
import { fetchTags } from 'Store/Actions/tagActions'; import { fetchTags } from 'Store/Actions/tagActions';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector';
import ErrorPage from './ErrorPage'; import ErrorPage from './ErrorPage';
import LoadingPage from './LoadingPage'; import LoadingPage from './LoadingPage';
import Page from './Page'; import Page from './Page';
@@ -49,6 +48,7 @@ const selectIsPopulated = createSelector(
(state) => state.tags.isPopulated, (state) => state.tags.isPopulated,
(state) => state.settings.ui.isPopulated, (state) => state.settings.ui.isPopulated,
(state) => state.settings.general.isPopulated, (state) => state.settings.general.isPopulated,
(state) => state.settings.languages.isPopulated,
(state) => state.settings.appProfiles.isPopulated, (state) => state.settings.appProfiles.isPopulated,
(state) => state.indexers.isPopulated, (state) => state.indexers.isPopulated,
(state) => state.indexerStatus.isPopulated, (state) => state.indexerStatus.isPopulated,
@@ -59,6 +59,7 @@ const selectIsPopulated = createSelector(
tagsIsPopulated, tagsIsPopulated,
uiSettingsIsPopulated, uiSettingsIsPopulated,
generalSettingsIsPopulated, generalSettingsIsPopulated,
languagesIsPopulated,
appProfilesIsPopulated, appProfilesIsPopulated,
indexersIsPopulated, indexersIsPopulated,
indexerStatusIsPopulated, indexerStatusIsPopulated,
@@ -70,6 +71,7 @@ const selectIsPopulated = createSelector(
tagsIsPopulated && tagsIsPopulated &&
uiSettingsIsPopulated && uiSettingsIsPopulated &&
generalSettingsIsPopulated && generalSettingsIsPopulated &&
languagesIsPopulated &&
appProfilesIsPopulated && appProfilesIsPopulated &&
indexersIsPopulated && indexersIsPopulated &&
indexerStatusIsPopulated && indexerStatusIsPopulated &&
@@ -84,6 +86,7 @@ const selectErrors = createSelector(
(state) => state.tags.error, (state) => state.tags.error,
(state) => state.settings.ui.error, (state) => state.settings.ui.error,
(state) => state.settings.general.error, (state) => state.settings.general.error,
(state) => state.settings.languages.error,
(state) => state.settings.appProfiles.error, (state) => state.settings.appProfiles.error,
(state) => state.indexers.error, (state) => state.indexers.error,
(state) => state.indexerStatus.error, (state) => state.indexerStatus.error,
@@ -94,6 +97,7 @@ const selectErrors = createSelector(
tagsError, tagsError,
uiSettingsError, uiSettingsError,
generalSettingsError, generalSettingsError,
languagesError,
appProfilesError, appProfilesError,
indexersError, indexersError,
indexerStatusError, indexerStatusError,
@@ -105,6 +109,7 @@ const selectErrors = createSelector(
tagsError || tagsError ||
uiSettingsError || uiSettingsError ||
generalSettingsError || generalSettingsError ||
languagesError ||
appProfilesError || appProfilesError ||
indexersError || indexersError ||
indexerStatusError || indexerStatusError ||
@@ -118,6 +123,7 @@ const selectErrors = createSelector(
tagsError, tagsError,
uiSettingsError, uiSettingsError,
generalSettingsError, generalSettingsError,
languagesError,
appProfilesError, appProfilesError,
indexersError, indexersError,
indexerStatusError, indexerStatusError,
@@ -134,21 +140,18 @@ function createMapStateToProps() {
selectErrors, selectErrors,
selectAppProps, selectAppProps,
createDimensionsSelector(), createDimensionsSelector(),
createSystemStatusSelector(),
( (
enableColorImpairedMode, enableColorImpairedMode,
isPopulated, isPopulated,
errors, errors,
app, app,
dimensions, dimensions
systemStatus
) => { ) => {
return { return {
...app, ...app,
...errors, ...errors,
isPopulated, isPopulated,
isSmallScreen: dimensions.isSmallScreen, isSmallScreen: dimensions.isSmallScreen,
authenticationEnabled: systemStatus.authentication !== 'none',
enableColorImpairedMode enableColorImpairedMode
}; };
} }
@@ -163,6 +166,9 @@ function createMapDispatchToProps(dispatch, props) {
dispatchFetchTags() { dispatchFetchTags() {
dispatch(fetchTags()); dispatch(fetchTags());
}, },
dispatchFetchLanguages() {
dispatch(fetchLanguages());
},
dispatchFetchIndexers() { dispatchFetchIndexers() {
dispatch(fetchIndexers()); dispatch(fetchIndexers());
}, },
@@ -210,6 +216,7 @@ class PageConnector extends Component {
if (!this.props.isPopulated) { if (!this.props.isPopulated) {
this.props.dispatchFetchCustomFilters(); this.props.dispatchFetchCustomFilters();
this.props.dispatchFetchTags(); this.props.dispatchFetchTags();
this.props.dispatchFetchLanguages();
this.props.dispatchFetchAppProfiles(); this.props.dispatchFetchAppProfiles();
this.props.dispatchFetchIndexers(); this.props.dispatchFetchIndexers();
this.props.dispatchFetchIndexerStatus(); this.props.dispatchFetchIndexerStatus();
@@ -235,6 +242,7 @@ class PageConnector extends Component {
isPopulated, isPopulated,
hasError, hasError,
dispatchFetchTags, dispatchFetchTags,
dispatchFetchLanguages,
dispatchFetchAppProfiles, dispatchFetchAppProfiles,
dispatchFetchIndexers, dispatchFetchIndexers,
dispatchFetchIndexerStatus, dispatchFetchIndexerStatus,
@@ -275,6 +283,7 @@ PageConnector.propTypes = {
isSidebarVisible: PropTypes.bool.isRequired, isSidebarVisible: PropTypes.bool.isRequired,
dispatchFetchCustomFilters: PropTypes.func.isRequired, dispatchFetchCustomFilters: PropTypes.func.isRequired,
dispatchFetchTags: PropTypes.func.isRequired, dispatchFetchTags: PropTypes.func.isRequired,
dispatchFetchLanguages: PropTypes.func.isRequired,
dispatchFetchAppProfiles: PropTypes.func.isRequired, dispatchFetchAppProfiles: PropTypes.func.isRequired,
dispatchFetchIndexers: PropTypes.func.isRequired, dispatchFetchIndexers: PropTypes.func.isRequired,
dispatchFetchIndexerStatus: PropTypes.func.isRequired, dispatchFetchIndexerStatus: PropTypes.func.isRequired,
+1 -1
View File
@@ -14,7 +14,7 @@ function PageContent(props) {
return ( return (
<ErrorBoundary errorComponent={PageContentError}> <ErrorBoundary errorComponent={PageContentError}>
<DocumentTitle title={title ? `${title} - ${window.Prowlarr.instanceName}` : window.Prowlarr.instanceName}> <DocumentTitle title={title ? `${title} - Prowlarr` : 'Prowlarr'}>
<div className={className}> <div className={className}>
{children} {children}
</div> </div>
@@ -2,7 +2,7 @@
display: flex; display: flex;
flex: 0 0 auto; flex: 0 0 auto;
padding: 20px; padding: 20px;
background-color: var(--pageFooterBackground); background-color: #f1f1f1;
} }
@media only screen and (max-width: $breakpointSmall) { @media only screen and (max-width: $breakpointSmall) {
@@ -1,6 +1,6 @@
.jumpBarItem { .jumpBarItem {
flex: 1 1 $jumpBarItemHeight; flex: 1 1 $jumpBarItemHeight;
border-bottom: 1px solid var(--borderColor); border-bottom: 1px solid $borderColor;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
@@ -1,6 +1,6 @@
.message { .message {
display: flex; display: flex;
border-left: 3px solid var(--infoColor); border-left: 3px solid $infoColor;
} }
.iconContainer, .iconContainer,
@@ -9,7 +9,7 @@
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
padding: 2px 0; padding: 2px 0;
color: var(--sidebarColor); color: $sidebarColor;
} }
.iconContainer { .iconContainer {
@@ -26,17 +26,17 @@
/* Types */ /* Types */
.error { .error {
border-left-color: var(--dangerColor); border-left-color: $dangerColor;
} }
.info { .info {
border-left-color: var(--infoColor); border-left-color: $infoColor;
} }
.success { .success {
border-left-color: var(--successColor); border-left-color: $successColor;
} }
.warning { .warning {
border-left-color: var(--warningColor); border-left-color: $warningColor;
} }
@@ -2,7 +2,7 @@
flex: 0 0 $sidebarWidth; flex: 0 0 $sidebarWidth;
overflow: hidden; overflow: hidden;
width: $sidebarWidth; width: $sidebarWidth;
background-color: var(--sidebarBackgroundColor); background-color: $sidebarBackgroundColor;
transition: transform 300ms ease-in-out; transition: transform 300ms ease-in-out;
transform: translateX(0); transform: translateX(0);
} }
@@ -11,8 +11,8 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
background-color: var(--sidebarBackgroundColor); background-color: $sidebarBackgroundColor;
color: var(--white); color: $white;
} }
@media only screen and (max-width: $breakpointSmall) { @media only screen and (max-width: $breakpointSmall) {
@@ -20,9 +20,9 @@ const SIDEBAR_WIDTH = parseInt(dimensions.sidebarWidth);
const links = [ const links = [
{ {
iconName: icons.MOVIE_CONTINUING, iconName: icons.MOVIE_CONTINUING,
title: translate('Indexers'), title: 'Indexers',
to: '/', to: '/',
alias: '/indexers', alias: '/movies',
children: [ children: [
{ {
title: translate('Stats'), title: translate('Stats'),
@@ -33,13 +33,13 @@ const links = [
{ {
iconName: icons.SEARCH, iconName: icons.SEARCH,
title: translate('Search'), title: 'Search',
to: '/search' to: '/search'
}, },
{ {
iconName: icons.ACTIVITY, iconName: icons.ACTIVITY,
title: translate('History'), title: 'History',
to: '/history' to: '/history'
}, },
@@ -1,21 +1,21 @@
.item { .item {
border-left: 3px solid transparent; border-left: 3px solid transparent;
color: var(--sidebarColor); color: $sidebarColor;
transition: border-left 0.3s ease-in-out; transition: border-left 0.3s ease-in-out;
} }
.isActiveItem { .isActiveItem {
border-left: 3px solid var(--themeBlue); border-left: 3px solid $themeBlue;
} }
.link { .link {
display: block; display: block;
padding: 12px 24px; padding: 12px 24px;
color: var(--sidebarColor); color: $sidebarColor;
&:hover, &:hover,
&:focus { &:focus {
color: var(--themeBlue); color: $themeBlue;
text-decoration: none; text-decoration: none;
} }
} }
@@ -27,11 +27,11 @@
} }
.isActiveLink { .isActiveLink {
color: var(--themeBlue); color: $themeBlue;
} }
.isActiveParentLink { .isActiveParentLink {
background-color: var(--sidebarActiveBackgroundColor); background-color: $sidebarActiveBackgroundColor;
} }
.iconContainer { .iconContainer {
@@ -4,8 +4,8 @@
flex: 0 0 auto; flex: 0 0 auto;
padding: 0 20px; padding: 0 20px;
height: $toolbarHeight; height: $toolbarHeight;
background-color: var(--toolbarBackgroundColor); background-color: $toolbarBackgroundColor;
color: var(--toolbarColor); color: $toolbarColor;
line-height: 60px; line-height: 60px;
} }
@@ -6,16 +6,16 @@
text-align: center; text-align: center;
&:hover { &:hover {
color: var(--toobarButtonHoverColor); color: $toobarButtonHoverColor;
} }
&.isDisabled { &.isDisabled {
color: var(--disabledColor); color: $disabledColor;
} }
} }
.isDisabled { .isDisabled {
color: var(--disabledColor); color: $disabledColor;
} }
.labelContainer { .labelContainer {
@@ -27,7 +27,7 @@
.label { .label {
padding: 0 3px; padding: 0 3px;
color: var(--toolbarLabelColor); color: $toolbarLabelColor;
font-size: $extraSmallFontSize; font-size: $extraSmallFontSize;
line-height: calc($extraSmallFontSize + 1px); line-height: calc($extraSmallFontSize + 1px);
} }
+14 -10
View File
@@ -14,13 +14,13 @@
width: 0; width: 0;
height: 100%; height: 100%;
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
color: var(--white); color: $white;
transition: width 0.6s ease; transition: width 0.6s ease;
} }
.frontTextContainer { .frontTextContainer {
z-index: 1; z-index: 1;
color: var(--white); color: $white;
} }
.backTextContainer, .backTextContainer,
@@ -42,35 +42,39 @@
} }
.primary { .primary {
background-color: var(--primaryColor); background-color: $primaryColor;
} }
.danger { .danger {
background-color: var(--dangerColor); background-color: $dangerColor;
&:global(.colorImpaired) { &:global(.colorImpaired) {
background: repeating-linear-gradient(90deg, color(var(--dangerColor) shade(5%)), color(var(--dangerColor) shade(5%)) 5px, color(var(--dangerColor) shade(15%)) 5px, color(var(--dangerColor) shade(15%)) 10px); background: repeating-linear-gradient(90deg, color($dangerColor shade(5%)), color($dangerColor shade(5%)) 5px, color($dangerColor shade(15%)) 5px, color($dangerColor shade(15%)) 10px);
} }
} }
.success { .success {
background-color: var(--successColor); background-color: $successColor;
} }
.purple { .purple {
background-color: var(--purple); background-color: $purple;
} }
.warning { .warning {
background-color: var(--warningColor); background-color: $warningColor;
&:global(.colorImpaired) { &:global(.colorImpaired) {
background: repeating-linear-gradient(45deg, var(--warningColor), var(--warningColor) 5px, color(var(--warningColor) tint(15%)) 5px, color(var(--warningColor) tint(15%)) 10px); background: repeating-linear-gradient(45deg, $warningColor, $warningColor 5px, color($warningColor tint(15%)) 5px, color($warningColor tint(15%)) 10px);
} }
} }
.info { .info {
background-color: var(--infoColor); background-color: $infoColor;
}
.queue {
background-color: $queueColor;
} }
.small { .small {
@@ -10,10 +10,10 @@
min-height: 100px; min-height: 100px;
border: 1px solid transparent; border: 1px solid transparent;
border-radius: 5px; border-radius: 5px;
background-color: var(--scrollbarBackgroundColor); background-color: $scrollbarBackgroundColor;
background-clip: padding-box; background-clip: padding-box;
&:hover { &:hover {
background-color: var(--scrollbarHoverBackgroundColor); background-color: $scrollbarHoverBackgroundColor;
} }
} }
@@ -4,7 +4,7 @@
width: 100%; width: 100%;
border: 1px solid #aaa; border: 1px solid #aaa;
border-radius: 4px; border-radius: 4px;
background: var(--inputBackgroundColor); background: #fafafa;
} }
.checkContainer { .checkContainer {
+2 -2
View File
@@ -46,11 +46,11 @@
} }
.records { .records {
color: var(--disabledColor); color: $disabledColor;
} }
.disabledPageButton { .disabledPageButton {
color: var(--disabledColor); color: $disabledColor;
} }
.pageSelect { .pageSelect {
+1 -1
View File
@@ -2,6 +2,6 @@
transition: background-color 500ms; transition: background-color 500ms;
&:hover { &:hover {
background-color: var(--tableRowHoverBackgroundColor); background-color: $tableRowHoverBackgroundColor;
} }
} }
@@ -3,7 +3,7 @@
transition: background-color 500ms; transition: background-color 500ms;
&:hover { &:hover {
background-color: var(--tableRowHoverBackgroundColor); background-color: #fafbfc;
} }
} }
+2 -2
View File
@@ -1,7 +1,7 @@
.title { .title {
padding: 10px 20px; padding: 10px 20px;
border-bottom: 1px solid var(--popoverTitleBorderColor); border-bottom: 1px solid $popoverTitleBorderColor;
background-color: var(--popoverTitleBackgroundColor); background-color: $popoverTitleBackgroundColor;
font-size: 16px; font-size: 16px;
} }
+20 -20
View File
@@ -7,13 +7,13 @@
position: relative; position: relative;
&.default { &.default {
background-color: var(--popoverBodyBackgroundColor); background-color: $white;
box-shadow: 0 5px 10px var(--popoverShadowColor); box-shadow: 0 5px 10px $popoverShadowColor;
} }
&.inverse { &.inverse {
background-color: var(--themeDarkColor); background-color: $themeDarkColor;
box-shadow: 0 5px 10px var(--popoverShadowInverseColor); box-shadow: 0 5px 10px $popoverShadowInverseColor;
} }
} }
@@ -49,20 +49,20 @@
content: ' '; content: ' ';
&.default { &.default {
border-top-color: var(--popoverArrowBorderColor); border-top-color: $popoverArrowBorderColor;
} }
&.inverse { &.inverse {
border-top-color: var(--popoverArrowBorderInverseColor); border-top-color: $popoverArrowBorderInverseColor;
} }
} }
&.default { &.default {
border-top-color: var(--popoverArrowBorderColor); border-top-color: $popoverArrowBorderColor;
} }
&.inverse { &.inverse {
border-top-color: var(--popoverArrowBorderInverseColor); border-top-color: $popoverArrowBorderInverseColor;
} }
} }
@@ -78,20 +78,20 @@
content: ' '; content: ' ';
&.default { &.default {
border-right-color: var(--popoverArrowBorderColor); border-right-color: $popoverArrowBorderColor;
} }
&.inverse { &.inverse {
border-right-color: var(--popoverArrowBorderInverseColor); border-right-color: $popoverArrowBorderInverseColor;
} }
} }
&.default { &.default {
border-right-color: var(--popoverArrowBorderColor); border-right-color: $popoverArrowBorderColor;
} }
&.inverse { &.inverse {
border-right-color: var(--popoverArrowBorderInverseColor); border-right-color: $popoverArrowBorderInverseColor;
} }
} }
@@ -107,20 +107,20 @@
content: ' '; content: ' ';
&.default { &.default {
border-bottom-color: var(--popoverArrowBorderColor); border-bottom-color: $popoverArrowBorderColor;
} }
&.inverse { &.inverse {
border-bottom-color: var(--popoverArrowBorderInverseColor); border-bottom-color: $popoverArrowBorderInverseColor;
} }
} }
&.default { &.default {
border-bottom-color: var(--popoverArrowBorderColor); border-bottom-color: $popoverArrowBorderColor;
} }
&.inverse { &.inverse {
border-bottom-color: var(--popoverArrowBorderInverseColor); border-bottom-color: $popoverArrowBorderInverseColor;
} }
} }
@@ -136,20 +136,20 @@
content: ' '; content: ' ';
&.default { &.default {
border-left-color: var(--popoverArrowBorderColor); border-left-color: $popoverArrowBorderColor;
} }
&.inverse { &.inverse {
border-left-color: var(--popoverArrowBorderInverseColor); border-left-color: $popoverArrowBorderInverseColor;
} }
} }
&.default { &.default {
border-left-color: var(--popoverArrowBorderColor); border-left-color: $popoverArrowBorderColor;
} }
&.inverse { &.inverse {
border-left-color: var(--popoverArrowBorderInverseColor); border-left-color: $popoverArrowBorderInverseColor;
} }
} }
@@ -1,34 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import AuthenticationRequiredModalContentConnector from './AuthenticationRequiredModalContentConnector';
function onModalClose() {
// No-op
}
function AuthenticationRequiredModal(props) {
const {
isOpen
} = props;
return (
<Modal
size={sizes.MEDIUM}
isOpen={isOpen}
closeOnBackgroundClick={false}
onModalClose={onModalClose}
>
<AuthenticationRequiredModalContentConnector
onModalClose={onModalClose}
/>
</Modal>
);
}
AuthenticationRequiredModal.propTypes = {
isOpen: PropTypes.bool.isRequired
};
export default AuthenticationRequiredModal;
@@ -1,5 +0,0 @@
.authRequiredAlert {
composes: alert from '~Components/Alert.css';
margin-bottom: 20px;
}
@@ -1,165 +0,0 @@
import PropTypes from 'prop-types';
import React, { useEffect, useRef } from 'react';
import Alert from 'Components/Alert';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import SpinnerButton from 'Components/Link/SpinnerButton';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes, kinds } from 'Helpers/Props';
import { authenticationMethodOptions, authenticationRequiredOptions, authenticationRequiredWarning } from 'Settings/General/SecuritySettings';
import translate from 'Utilities/String/translate';
import styles from './AuthenticationRequiredModalContent.css';
function onModalClose() {
// No-op
}
function AuthenticationRequiredModalContent(props) {
const {
isPopulated,
error,
isSaving,
settings,
onInputChange,
onSavePress,
dispatchFetchStatus
} = props;
const {
authenticationMethod,
authenticationRequired,
username,
password
} = settings;
const authenticationEnabled = authenticationMethod && authenticationMethod.value !== 'none';
const didMount = useRef(false);
useEffect(() => {
if (!isSaving && didMount.current) {
dispatchFetchStatus();
}
didMount.current = true;
}, [isSaving, dispatchFetchStatus]);
return (
<ModalContent
showCloseButton={false}
onModalClose={onModalClose}
>
<ModalHeader>
{translate('AuthenticationRequired')}
</ModalHeader>
<ModalBody>
<Alert
className={styles.authRequiredAlert}
kind={kinds.WARNING}
>
{authenticationRequiredWarning}
</Alert>
{
isPopulated && !error ?
<div>
<FormGroup>
<FormLabel>{translate('Authentication')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="authenticationMethod"
values={authenticationMethodOptions}
helpText={translate('AuthenticationMethodHelpText')}
onChange={onInputChange}
{...authenticationMethod}
/>
</FormGroup>
{
authenticationEnabled ?
<FormGroup>
<FormLabel>{translate('AuthenticationRequired')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="authenticationRequired"
values={authenticationRequiredOptions}
helpText={translate('AuthenticationRequiredHelpText')}
onChange={onInputChange}
{...authenticationRequired}
/>
</FormGroup> :
null
}
{
authenticationEnabled ?
<FormGroup>
<FormLabel>{translate('Username')}</FormLabel>
<FormInputGroup
type={inputTypes.TEXT}
name="username"
onChange={onInputChange}
{...username}
/>
</FormGroup> :
null
}
{
authenticationEnabled ?
<FormGroup>
<FormLabel>{translate('Password')}</FormLabel>
<FormInputGroup
type={inputTypes.PASSWORD}
name="password"
onChange={onInputChange}
{...password}
/>
</FormGroup> :
null
}
</div> :
null
}
{
!isPopulated && !error ? <LoadingIndicator /> : null
}
</ModalBody>
<ModalFooter>
<SpinnerButton
kind={kinds.PRIMARY}
isSpinning={isSaving}
isDisabled={!authenticationEnabled}
onPress={onSavePress}
>
{translate('Save')}
</SpinnerButton>
</ModalFooter>
</ModalContent>
);
}
AuthenticationRequiredModalContent.propTypes = {
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
isSaving: PropTypes.bool.isRequired,
saveError: PropTypes.object,
settings: PropTypes.object.isRequired,
onInputChange: PropTypes.func.isRequired,
onSavePress: PropTypes.func.isRequired,
dispatchFetchStatus: PropTypes.func.isRequired
};
export default AuthenticationRequiredModalContent;
@@ -1,86 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { clearPendingChanges } from 'Store/Actions/baseActions';
import { fetchGeneralSettings, saveGeneralSettings, setGeneralSettingsValue } from 'Store/Actions/settingsActions';
import { fetchStatus } from 'Store/Actions/systemActions';
import createSettingsSectionSelector from 'Store/Selectors/createSettingsSectionSelector';
import AuthenticationRequiredModalContent from './AuthenticationRequiredModalContent';
const SECTION = 'general';
function createMapStateToProps() {
return createSelector(
createSettingsSectionSelector(SECTION),
(sectionSettings) => {
return {
...sectionSettings
};
}
);
}
const mapDispatchToProps = {
dispatchClearPendingChanges: clearPendingChanges,
dispatchSetGeneralSettingsValue: setGeneralSettingsValue,
dispatchSaveGeneralSettings: saveGeneralSettings,
dispatchFetchGeneralSettings: fetchGeneralSettings,
dispatchFetchStatus: fetchStatus
};
class AuthenticationRequiredModalContentConnector extends Component {
//
// Lifecycle
componentDidMount() {
this.props.dispatchFetchGeneralSettings();
}
componentWillUnmount() {
this.props.dispatchClearPendingChanges({ section: `settings.${SECTION}` });
}
//
// Listeners
onInputChange = ({ name, value }) => {
this.props.dispatchSetGeneralSettingsValue({ name, value });
};
onSavePress = () => {
this.props.dispatchSaveGeneralSettings();
};
//
// Render
render() {
const {
dispatchClearPendingChanges,
dispatchFetchGeneralSettings,
dispatchSetGeneralSettingsValue,
dispatchSaveGeneralSettings,
...otherProps
} = this.props;
return (
<AuthenticationRequiredModalContent
{...otherProps}
onInputChange={this.onInputChange}
onSavePress={this.onSavePress}
/>
);
}
}
AuthenticationRequiredModalContentConnector.propTypes = {
dispatchClearPendingChanges: PropTypes.func.isRequired,
dispatchFetchGeneralSettings: PropTypes.func.isRequired,
dispatchSetGeneralSettingsValue: PropTypes.func.isRequired,
dispatchSaveGeneralSettings: PropTypes.func.isRequired,
dispatchFetchStatus: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(AuthenticationRequiredModalContentConnector);
-2
View File
@@ -8,7 +8,6 @@ export const DEVICE = 'device';
export const KEY_VALUE_LIST = 'keyValueList'; export const KEY_VALUE_LIST = 'keyValueList';
export const INFO = 'info'; export const INFO = 'info';
export const MOVIE_MONITORED_SELECT = 'movieMonitoredSelect'; export const MOVIE_MONITORED_SELECT = 'movieMonitoredSelect';
export const CATEGORY_SELECT = 'newznabCategorySelect';
export const NUMBER = 'number'; export const NUMBER = 'number';
export const OAUTH = 'oauth'; export const OAUTH = 'oauth';
export const PASSWORD = 'password'; export const PASSWORD = 'password';
@@ -33,7 +32,6 @@ export const all = [
KEY_VALUE_LIST, KEY_VALUE_LIST,
INFO, INFO,
MOVIE_MONITORED_SELECT, MOVIE_MONITORED_SELECT,
CATEGORY_SELECT,
NUMBER, NUMBER,
OAUTH, OAUTH,
PASSWORD, PASSWORD,
+2
View File
@@ -3,6 +3,7 @@ export const DEFAULT = 'default';
export const DISABLED = 'disabled'; export const DISABLED = 'disabled';
export const INFO = 'info'; export const INFO = 'info';
export const INVERSE = 'inverse'; export const INVERSE = 'inverse';
export const PINK = 'pink';
export const PRIMARY = 'primary'; export const PRIMARY = 'primary';
export const PURPLE = 'purple'; export const PURPLE = 'purple';
export const SUCCESS = 'success'; export const SUCCESS = 'success';
@@ -15,6 +16,7 @@ export const all = [
DISABLED, DISABLED,
INFO, INFO,
INVERSE, INVERSE,
PINK,
PRIMARY, PRIMARY,
PURPLE, PURPLE,
SUCCESS, SUCCESS,
-45
View File
@@ -226,42 +226,6 @@ class HistoryRow extends Component {
null null
} }
{
data.label ?
<HistoryRowParameter
title='Label'
value={data.label}
/> :
null
}
{
data.track ?
<HistoryRowParameter
title='Track'
value={data.track}
/> :
null
}
{
data.year ?
<HistoryRowParameter
title='Year'
value={data.year}
/> :
null
}
{
data.genre ?
<HistoryRowParameter
title='Genre'
value={data.genre}
/> :
null
}
{ {
data.author ? data.author ?
<HistoryRowParameter <HistoryRowParameter
@@ -279,15 +243,6 @@ class HistoryRow extends Component {
/> : /> :
null null
} }
{
data.publisher ?
<HistoryRowParameter
title='Publisher'
value={data.publisher}
/> :
null
}
</TableRowCell> </TableRowCell>
); );
} }
+4 -4
View File
@@ -3,9 +3,9 @@
align-items: stretch; align-items: stretch;
overflow: hidden; overflow: hidden;
margin: 2px 4px; margin: 2px 4px;
border: 1px solid var(--borderColor); border: 1px solid $borderColor;
border-radius: 4px; border-radius: 4px;
background-color: var(--defaultHoverBackgroundColor); background-color: #eee;
cursor: default; cursor: default;
} }
@@ -16,7 +16,7 @@
.value { .value {
padding: 0 4px; padding: 0 4px;
background-color: var(--defaultButtonBackgroundColor); background-color: $white;
color: var(--defaultColor); color: $defaultColor;
white-space: nowrap; white-space: nowrap;
} }
@@ -123,7 +123,7 @@ class AddIndexerModalContent extends Component {
const filteredIndexers = indexers.filter((indexer) => { const filteredIndexers = indexers.filter((indexer) => {
const { filter, filterProtocols, filterLanguages, filterPrivacyLevels } = this.state; const { filter, filterProtocols, filterLanguages, filterPrivacyLevels } = this.state;
if (!indexer.name.toLowerCase().includes(filter.toLocaleLowerCase()) && !indexer.description.toLowerCase().includes(filter.toLocaleLowerCase())) { if (!indexer.name.toLowerCase().includes(filter.toLocaleLowerCase())) {
return false; return false;
} }
@@ -112,7 +112,7 @@ function EditIndexerModalContent(props) {
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>{translate('SyncProfile')}</FormLabel> <FormLabel>{translate('AppProfile')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.APP_PROFILE_SELECT} type={inputTypes.APP_PROFILE_SELECT}
@@ -9,5 +9,5 @@
.path { .path {
margin-left: 5px; margin-left: 5px;
color: var(--dangerColor); color: $dangerColor;
} }
@@ -133,7 +133,7 @@ class IndexerEditorFooter extends Component {
<div className={styles.inputContainer}> <div className={styles.inputContainer}>
<IndexerEditorFooterLabel <IndexerEditorFooterLabel
label={translate('SyncProfile')} label={translate('AppProfile')}
isSaving={isSaving && appProfileId !== NO_CHANGE} isSaving={isSaving && appProfileId !== NO_CHANGE}
/> />
+1 -13
View File
@@ -221,7 +221,7 @@ class IndexerIndex extends Component {
onKeyUp = (event) => { onKeyUp = (event) => {
const jumpBarItems = this.state.jumpBarItems.order; const jumpBarItems = this.state.jumpBarItems.order;
if (event.composedPath && event.composedPath().length === 4) { if (event.path.length === 4) {
if (event.keyCode === keyCodes.HOME && event.ctrlKey) { if (event.keyCode === keyCodes.HOME && event.ctrlKey) {
this.setState({ jumpToCharacter: jumpBarItems[0] }); this.setState({ jumpToCharacter: jumpBarItems[0] });
} }
@@ -272,7 +272,6 @@ class IndexerIndex extends Component {
saveError, saveError,
isDeleting, isDeleting,
isTestingAll, isTestingAll,
isSyncingIndexers,
deleteError, deleteError,
onScroll, onScroll,
onSortSelect, onSortSelect,
@@ -310,15 +309,6 @@ class IndexerIndex extends Component {
onPress={this.onAddIndexerPress} onPress={this.onAddIndexerPress}
/> />
<PageToolbarSeparator />
<PageToolbarButton
label={translate('SyncAppIndexers')}
iconName={icons.REFRESH}
isSpinning={isSyncingIndexers}
onPress={this.props.onAppIndexerSyncPress}
/>
<PageToolbarButton <PageToolbarButton
label={translate('TestAllIndexers')} label={translate('TestAllIndexers')}
iconName={icons.TEST} iconName={icons.TEST}
@@ -503,12 +493,10 @@ IndexerIndex.propTypes = {
saveError: PropTypes.object, saveError: PropTypes.object,
isDeleting: PropTypes.bool.isRequired, isDeleting: PropTypes.bool.isRequired,
isTestingAll: PropTypes.bool.isRequired, isTestingAll: PropTypes.bool.isRequired,
isSyncingIndexers: PropTypes.bool.isRequired,
deleteError: PropTypes.object, deleteError: PropTypes.object,
onSortSelect: PropTypes.func.isRequired, onSortSelect: PropTypes.func.isRequired,
onFilterSelect: PropTypes.func.isRequired, onFilterSelect: PropTypes.func.isRequired,
onTestAllPress: PropTypes.func.isRequired, onTestAllPress: PropTypes.func.isRequired,
onAppIndexerSyncPress: PropTypes.func.isRequired,
onScroll: PropTypes.func.isRequired, onScroll: PropTypes.func.isRequired,
onSaveSelected: PropTypes.func.isRequired onSaveSelected: PropTypes.func.isRequired
}; };
@@ -2,13 +2,10 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import * as commandNames from 'Commands/commandNames';
import withScrollPosition from 'Components/withScrollPosition'; import withScrollPosition from 'Components/withScrollPosition';
import { executeCommand } from 'Store/Actions/commandActions';
import { testAllIndexers } from 'Store/Actions/indexerActions'; import { testAllIndexers } from 'Store/Actions/indexerActions';
import { saveIndexerEditor, setMovieFilter, setMovieSort, setMovieTableOption } from 'Store/Actions/indexerIndexActions'; import { saveIndexerEditor, setMovieFilter, setMovieSort, setMovieTableOption } from 'Store/Actions/indexerIndexActions';
import scrollPositions from 'Store/scrollPositions'; import scrollPositions from 'Store/scrollPositions';
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import createIndexerClientSideCollectionItemsSelector from 'Store/Selectors/createIndexerClientSideCollectionItemsSelector'; import createIndexerClientSideCollectionItemsSelector from 'Store/Selectors/createIndexerClientSideCollectionItemsSelector';
import IndexerIndex from './IndexerIndex'; import IndexerIndex from './IndexerIndex';
@@ -16,16 +13,13 @@ import IndexerIndex from './IndexerIndex';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
createIndexerClientSideCollectionItemsSelector('indexerIndex'), createIndexerClientSideCollectionItemsSelector('indexerIndex'),
createCommandExecutingSelector(commandNames.APP_INDEXER_SYNC),
createDimensionsSelector(), createDimensionsSelector(),
( (
indexers, indexers,
isSyncingIndexers,
dimensionsState dimensionsState
) => { ) => {
return { return {
...indexers, ...indexers,
isSyncingIndexers,
isSmallScreen: dimensionsState.isSmallScreen isSmallScreen: dimensionsState.isSmallScreen
}; };
} }
@@ -52,12 +46,6 @@ function createMapDispatchToProps(dispatch, props) {
onTestAllPress() { onTestAllPress() {
dispatch(testAllIndexers()); dispatch(testAllIndexers());
},
onAppIndexerSyncPress() {
dispatch(executeCommand({
name: commandNames.APP_INDEXER_SYNC
}));
} }
}; };
} }
@@ -21,28 +21,28 @@
.disabled { .disabled {
composes: legendItemColor; composes: legendItemColor;
background-color: var(--darkGray); background-color: $darkGray;
} }
.enabled { .enabled {
composes: legendItemColor; composes: legendItemColor;
background-color: var(--successColor); background-color: $successColor;
} }
.redirected { .redirected {
composes: legendItemColor; composes: legendItemColor;
background-color: var(--infoColor); background-color: $infoColor;
} }
.error { .error {
composes: legendItemColor; composes: legendItemColor;
background-color: var(--dangerColor); background-color: $dangerColor;
&:global(.colorImpaired) { &:global(.colorImpaired) {
background: repeating-linear-gradient(90deg, color(var(--dangerColor) shade(5%)), color(var(--dangerColor) shade(5%)) 5px, color(var(--dangerColor) shade(15%)) 5px, color(var(--dangerColor) shade(15%)) 10px); background: repeating-linear-gradient(90deg, color($dangerColor shade(5%)), color($dangerColor shade(5%)) 5px, color($dangerColor shade(15%)) 5px, color($dangerColor shade(15%)) 10px);
} }
} }
@@ -35,21 +35,21 @@ class IndexerIndexFooter extends PureComponent {
<div className={styles.legendItem}> <div className={styles.legendItem}>
<div className={styles.enabled} /> <div className={styles.enabled} />
<div> <div>
{translate('Enabled')} Enabled
</div> </div>
</div> </div>
<div className={styles.legendItem}> <div className={styles.legendItem}>
<div className={styles.redirected} /> <div className={styles.redirected} />
<div> <div>
{translate('EnabledRedirected')} Enabled, Redirected
</div> </div>
</div> </div>
<div className={styles.legendItem}> <div className={styles.legendItem}>
<div className={styles.disabled} /> <div className={styles.disabled} />
<div> <div>
{translate('Disabled')} Disabled
</div> </div>
</div> </div>
@@ -60,7 +60,7 @@ class IndexerIndexFooter extends PureComponent {
)} )}
/> />
<div> <div>
{translate('Error')} Error
</div> </div>
</div> </div>
</div> </div>
@@ -53,7 +53,7 @@ function IndexerIndexSortMenu(props) {
sortDirection={sortDirection} sortDirection={sortDirection}
onPress={onSortSelect} onPress={onSortSelect}
> >
{translate('SyncProfile')} {translate('AppProfile')}
</SortMenuItem> </SortMenuItem>
<SortMenuItem <SortMenuItem
@@ -14,7 +14,7 @@ function CapabilitiesLabel(props) {
let filteredList = categories.filter((item) => item.id < 100000); let filteredList = categories.filter((item) => item.id < 100000);
if (categoryFilter.length > 0) { if (categoryFilter.length > 0) {
filteredList = filteredList.filter((item) => categoryFilter.includes(item.id) || (item.subCategories && item.subCategories.some((r) => categoryFilter.includes(r.id)))); filteredList = filteredList.filter((item) => categoryFilter.includes(item.id));
} }
const nameList = filteredList.map((item) => item.name).sort(); const nameList = filteredList.map((item) => item.name).sort();

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