Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17df5dd072 | ||
|
|
4b48a36ad3 | ||
|
|
2d3359a7e3 | ||
|
|
6d08b10820 | ||
|
|
78af1a3e6d | ||
|
|
16bd3e9fd5 | ||
|
|
6360c82898 | ||
|
|
67a8f7fbfe | ||
|
|
e17c637483 | ||
|
|
15013d6c5d | ||
|
|
8cb05c413a | ||
|
|
2098a2d3d2 | ||
|
|
6c1ee830a1 | ||
|
|
0658b7943e | ||
|
|
f1df9eeb2f | ||
|
|
edbbccf3ae | ||
|
|
a3973791fb | ||
|
|
cb5c0403c1 | ||
|
|
7bf924f7e9 | ||
|
|
c53dc3b15d | ||
|
|
b96bd33982 | ||
|
|
92c9001c9d | ||
|
|
157ab80be1 | ||
|
|
ac0f95b773 | ||
|
|
5f09e83ed8 | ||
|
|
27349ec953 | ||
|
|
2ce6e0a94a | ||
|
|
da65988926 | ||
|
|
b3b8e7b0cc | ||
|
|
c8f1756a2b | ||
|
|
f943701e13 | ||
|
|
7bf9addd13 | ||
|
|
93983c976b | ||
|
|
05a2fddf4a | ||
|
|
7f2be51a7e | ||
|
|
de01e13dda | ||
|
|
beca52715a | ||
|
|
61ed508a56 | ||
|
|
ce9d9fdf13 | ||
|
|
e32b585e97 | ||
|
|
6d2abfa863 | ||
|
|
d02724770d | ||
|
|
5fa37b5913 | ||
|
|
5155a4caf2 | ||
|
|
42381ed5cb | ||
|
|
b99f9e6888 | ||
|
|
e6c5d6ff7c | ||
|
|
4f9514885b | ||
|
|
52e695bd08 | ||
|
|
051f1b3e89 | ||
|
|
4392a881aa | ||
|
|
0949c9b334 | ||
|
|
30d04ce35a | ||
|
|
83efb0e3d4 | ||
|
|
08e968fd00 | ||
|
|
0d8e0d0352 | ||
|
|
1ab3a4b80a | ||
|
|
b6e60a412b | ||
|
|
d4cc727d52 | ||
|
|
45ebfb937e | ||
|
|
85325cda7f | ||
|
|
3fa7ff9858 | ||
|
|
b16fbafa1f | ||
|
|
ccb98553f1 | ||
|
|
d8060afe02 | ||
|
|
6502feb1a5 | ||
|
|
8cd067b6e9 | ||
|
|
d6eb3ae64e | ||
|
|
02d6b46448 | ||
|
|
df94db050b | ||
|
|
8d8e750982 | ||
|
|
6c7f1cad8b | ||
|
|
74c36ac31d | ||
|
|
385fb23b72 | ||
|
|
adc07a9624 | ||
|
|
335377e250 | ||
|
|
383c79c19a | ||
|
|
44dbb745b6 | ||
|
|
30a8934626 | ||
|
|
2d0afb29d3 | ||
|
|
86cadb8283 | ||
|
|
a494507dfe | ||
|
|
887f5dd487 | ||
|
|
8da357aea0 | ||
|
|
a304742828 | ||
|
|
a14af7c21c | ||
|
|
ff5106bf42 | ||
|
|
42788adb75 | ||
|
|
5774445dd7 | ||
|
|
dc7d1aabb8 | ||
|
|
b22eb5a49a | ||
|
|
d38b28d206 | ||
|
|
b0c663bacc | ||
|
|
5ff8ae32ec | ||
|
|
29e932252f | ||
|
|
a0e594a292 | ||
|
|
96f3861c90 | ||
|
|
77f3f99fbb | ||
|
|
e2b99b68e3 | ||
|
|
86addbc4dd |
100
.all-contributorsrc
Normal file
100
.all-contributorsrc
Normal file
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"files": [
|
||||
"README.md"
|
||||
],
|
||||
"imageSize": 100,
|
||||
"commit": false,
|
||||
"contributors": [
|
||||
{
|
||||
"login": "sct",
|
||||
"name": "sct",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/234213?v=4",
|
||||
"profile": "https://sct.dev",
|
||||
"contributions": [
|
||||
"code",
|
||||
"design",
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "azoitos",
|
||||
"name": "Alex Zoitos",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/26529049?v=4",
|
||||
"profile": "https://github.com/azoitos",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "OwsleyJr",
|
||||
"name": "Brandon Cohen",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/8635678?v=4",
|
||||
"profile": "https://github.com/OwsleyJr",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Ahreluth",
|
||||
"name": "Ahreluth",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/75682440?v=4",
|
||||
"profile": "https://github.com/Ahreluth",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "KovalevArtem",
|
||||
"name": "KovalevArtem",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/36500228?v=4",
|
||||
"profile": "https://github.com/KovalevArtem",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "GiyomuWeb",
|
||||
"name": "GiyomuWeb",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/62489209?v=4",
|
||||
"profile": "https://github.com/GiyomuWeb",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "angrycuban13",
|
||||
"name": "Angry Cuban",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/39564898?v=4",
|
||||
"profile": "https://github.com/angrycuban13",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jvennik",
|
||||
"name": "jvennik",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/6672637?v=4",
|
||||
"profile": "https://github.com/jvennik",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "darknessgp",
|
||||
"name": "darknessgp",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/1521243?v=4",
|
||||
"profile": "https://github.com/darknessgp",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"badgeTemplate": "<a href=\"#contributors-\"><img alt=\"All Contributors\" src=\"https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg\"/></a>",
|
||||
"contributorsPerLine": 7,
|
||||
"projectName": "overseerr",
|
||||
"projectOwner": "sct",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true
|
||||
}
|
||||
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Are you on latest or develop branch?**
|
||||
Please fill in which docker image you are currently using.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Support via Discord
|
||||
url: https://discord.gg/PkCWJSeCk7
|
||||
about: Chat with users and devs on support and setup related topics.
|
||||
- name: Support via GitHub Discussions
|
||||
url: https://github.com/sct/overseerr/discussions
|
||||
about: Ask questions and discuss with other community members
|
||||
19
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#### Description
|
||||
|
||||
#### Screenshot (if UI related)
|
||||
|
||||
#### Todos
|
||||
|
||||
- [ ] Sucessfully builds `yarn build`
|
||||
- [ ] Translation Keys `yarn i18n:extract`
|
||||
- [ ] Database migration created (if required)
|
||||
|
||||
#### Issues Fixed or Closed by this PR
|
||||
|
||||
- Fixes #XXXX
|
||||
38
.github/lock.yml
vendored
Normal file
38
.github/lock.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app
|
||||
|
||||
# Number of days of inactivity before a closed issue or pull request is locked
|
||||
daysUntilLock: 365
|
||||
|
||||
# Skip issues and pull requests created before a given timestamp. Timestamp must
|
||||
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
|
||||
skipCreatedBefore: false
|
||||
|
||||
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
|
||||
exemptLabels:
|
||||
- dependencies
|
||||
|
||||
# Label to add before locking, such as `outdated`. Set to `false` to disable
|
||||
lockLabel: false
|
||||
|
||||
# Comment to post before locking. Set to `false` to disable
|
||||
lockComment: >
|
||||
This thread has been automatically locked since there has not been
|
||||
any recent activity after it was closed. Please open a new issue for
|
||||
related bugs.
|
||||
|
||||
# Assign `resolved` as the reason for locking. Set to `false` to disable
|
||||
setLockReason: true
|
||||
# Limit to only `issues` or `pulls`
|
||||
# only: issues
|
||||
|
||||
# Optionally, specify configuration settings just for `issues` or `pulls`
|
||||
# issues:
|
||||
# exemptLabels:
|
||||
# - help-wanted
|
||||
# lockLabel: outdated
|
||||
|
||||
# pulls:
|
||||
# daysUntilLock: 30
|
||||
|
||||
# Repository to extend settings from
|
||||
# _extends: repo
|
||||
18
.github/stale.yml
vendored
Normal file
18
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
- dependencies
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: wontfix
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
build_and_push:
|
||||
name: Build and push Docker image to Docker Hub
|
||||
needs: test
|
||||
if: github.ref == 'refs/heads/develop'
|
||||
if: github.ref == 'refs/heads/develop' && !contains(github.event.head_commit.message, 'skip ci')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
run: yarn lint
|
||||
- name: build
|
||||
run: yarn build
|
||||
semnatic-release:
|
||||
semantic-release:
|
||||
name: Tag and release latest version
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
25
.github/workflows/support.yml
vendored
Normal file
25
.github/workflows/support.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: 'Support requests'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled, unlabeled, reopened]
|
||||
|
||||
jobs:
|
||||
support:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/support-requests@v2
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
support-label: 'support'
|
||||
issue-comment: >
|
||||
:wave: @{issue-author}, we use the issue tracker exclusively
|
||||
for bug reports and feature requests. However, this issue appears
|
||||
to be a support request. Please use our support channels
|
||||
to get help with Overseerr.
|
||||
|
||||
- [Discord](https://discord.gg/PkCWJSeCk7)
|
||||
- [GitHub Discussions](https://github.com/sct/overseerr/discussions)
|
||||
close-issue: true
|
||||
lock-issue: false
|
||||
issue-lock-reason: 'off-topic'
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -6,7 +6,7 @@
|
||||
"typescript",
|
||||
"typescriptreact"
|
||||
],
|
||||
"typescript.tsdk": "./app/node_modules/typescript/lib",
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"sqltools.connections": [
|
||||
{
|
||||
"previewLimit": 50,
|
||||
|
||||
83
CHANGELOG.md
83
CHANGELOG.md
@@ -1,3 +1,86 @@
|
||||
# [1.4.0](https://github.com/sct/overseerr/compare/v1.3.2...v1.4.0) (2020-12-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* changing parameter name to use correct 'port' [#276](https://github.com/sct/overseerr/issues/276) ([#277](https://github.com/sct/overseerr/issues/277)) ([6d08b10](https://github.com/sct/overseerr/commit/6d08b108200177ca3068c852e60a0df75ce2232a))
|
||||
* **services:** include radarr/sonarr baseUrl when adding media ([78af1a3](https://github.com/sct/overseerr/commit/78af1a3e6d00a5645a05e7bf3cf56a59439b6cc9))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** Translations update from Weblate ([#240](https://github.com/sct/overseerr/issues/240)) ([e17c637](https://github.com/sct/overseerr/commit/e17c63748362b6a480693e003ef5eec614dcec43))
|
||||
|
||||
## [1.3.2](https://github.com/sct/overseerr/compare/v1.3.1...v1.3.2) (2020-12-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** convert plex port to a number before posting to the api ([8cb05c4](https://github.com/sct/overseerr/commit/8cb05c413a15a4b74e37ece5e24367d115995b32))
|
||||
* **frontend:** converts email smtp port to a number before posting to the api ([2098a2d](https://github.com/sct/overseerr/commit/2098a2d3d2981fd2ae54392aec3ef81327f2858e)), closes [#251](https://github.com/sct/overseerr/issues/251)
|
||||
* **frontend:** encode special characters in search input to prevent crashing router ([15013d6](https://github.com/sct/overseerr/commit/15013d6c5dbff15704c7c30d261d68a265e7f2d7)), closes [#252](https://github.com/sct/overseerr/issues/252)
|
||||
* **plex sync:** catch errors that occur during processMovie ([edbbccf](https://github.com/sct/overseerr/commit/edbbccf3ae623430294f1a5c3fd2728dbd42e555)), closes [#244](https://github.com/sct/overseerr/issues/244) [#246](https://github.com/sct/overseerr/issues/246) [#250](https://github.com/sct/overseerr/issues/250)
|
||||
* **services:** improve logging for adding movies to Radarr ([6c1ee83](https://github.com/sct/overseerr/commit/6c1ee830a183f89bb1fe96a181a7d61684e23b22))
|
||||
* **services:** radarr/sonarr will use the correct default server ([0658b79](https://github.com/sct/overseerr/commit/0658b7943e1ab25816db9da34d4c9ea808d9203d))
|
||||
|
||||
## [1.3.1](https://github.com/sct/overseerr/compare/v1.3.0...v1.3.1) (2020-12-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** also convert activeProfileId to a number for radarr/sonarr submissions ([7bf924f](https://github.com/sct/overseerr/commit/7bf924f7e94a0e0834f41b4ec067ed277c652766))
|
||||
* **frontend:** also convert ports to numbers when saving radarr/sonarr servers ([c53dc3b](https://github.com/sct/overseerr/commit/c53dc3b15da522c6e6ab76bbc9d15008a8a9fb9d))
|
||||
* **frontend:** new radarr/sonarr ports will be converted to a number before posting ([92c9001](https://github.com/sct/overseerr/commit/92c9001c9d1f2cbd272a5897ea1157d2cadbce2d))
|
||||
|
||||
# [1.3.0](https://github.com/sct/overseerr/compare/v1.2.0...v1.3.0) (2020-12-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** correctly generate clientId on first startup ([5f09e83](https://github.com/sct/overseerr/commit/5f09e83ed870336638d3e9d94fcf55ead928e737))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **frontend:** add full cast page for movies and series ([051f1b3](https://github.com/sct/overseerr/commit/051f1b3e899bf749e632743e5c8d45a02b621998))
|
||||
* **lang:** translated using Weblate (Dutch) ([1ab3a4b](https://github.com/sct/overseerr/commit/1ab3a4b80a081d7e4a201f1290cd270ed5b38ac7))
|
||||
* **lang:** translated using Weblate (English) ([0949c9b](https://github.com/sct/overseerr/commit/0949c9b334b3a4b6c342517a157a9e2b7596f2f0))
|
||||
* **lang:** translated using Weblate (French) ([f943701](https://github.com/sct/overseerr/commit/f943701e13c7f0de5a711302597858cc898b16e2))
|
||||
* **lang:** translated using Weblate (French) ([30d04ce](https://github.com/sct/overseerr/commit/30d04ce35adc21070cce37ab10384154afda191b))
|
||||
* **lang:** translated using Weblate (German) ([7bf9add](https://github.com/sct/overseerr/commit/7bf9addd13a707aac23b64ef3f1733e491d40a4e))
|
||||
* **lang:** translated using Weblate (German) ([b6e60a4](https://github.com/sct/overseerr/commit/b6e60a412b30907aea751a4cf1ce0cc8230f9814))
|
||||
* **lang:** translated using Weblate (Japanese) ([08e968f](https://github.com/sct/overseerr/commit/08e968fd0097ec7b2a65de064ed5b07e7c49ef39))
|
||||
* **lang:** translated using Weblate (Norwegian Bokmål) ([83efb0e](https://github.com/sct/overseerr/commit/83efb0e3d4d96b6a2d2ebdd85d36c9d78c1717b2))
|
||||
* **lang:** translated using Weblate (Russian) ([0d8e0d0](https://github.com/sct/overseerr/commit/0d8e0d0352f72fdb65ee8f054371eae08c39fe33))
|
||||
|
||||
# [1.2.0](https://github.com/sct/overseerr/compare/v1.1.0...v1.2.0) (2020-12-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** person cards now show correctly in ListView's ([ccb9855](https://github.com/sct/overseerr/commit/ccb98553f104c1aebd33796b7090cc9bbe964bd7))
|
||||
* **frontend:** properly remove site overlay when closing modals ([3fa7ff9](https://github.com/sct/overseerr/commit/3fa7ff9858d14d132151f3329164d55d74638f53))
|
||||
* **frontend:** switch to using Transition component for modals ([b16fbaf](https://github.com/sct/overseerr/commit/b16fbafa1f3d5e105c0a4ba6f1d66aa064019636)), closes [#220](https://github.com/sct/overseerr/issues/220)
|
||||
* fix missing personid in Discover ([d8060af](https://github.com/sct/overseerr/commit/d8060afe02574337f51b88cab0a0f824976ac721))
|
||||
* missing personId in ListView component ([6502feb](https://github.com/sct/overseerr/commit/6502feb1a5be3c6daab33230814fe74632c87f7e))
|
||||
* **frontend:** update overflow issues with seasons + email ([#217](https://github.com/sct/overseerr/issues/217)) ([2d0afb2](https://github.com/sct/overseerr/commit/2d0afb29d37798a626e3f182571ccce43d80063c)), closes [#216](https://github.com/sct/overseerr/issues/216)
|
||||
* **lang:** fix missing i18n string for agent enabled in email notification page ([42788ad](https://github.com/sct/overseerr/commit/42788adb75f7d23e68327688b1c542dd047e9609))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** update language files ([8cd067b](https://github.com/sct/overseerr/commit/8cd067b6e9df1a3c8f4056789436a31177703986))
|
||||
* person details page ([d6eb3ae](https://github.com/sct/overseerr/commit/d6eb3ae64ef46bd62145010d3029e272676487c3))
|
||||
* **lang:** add nb-NO and de language support to app ([d38b28d](https://github.com/sct/overseerr/commit/d38b28d2061b38366989ff412957a5dee5766c6f))
|
||||
* **lang:** add support for dutch language ([df94db0](https://github.com/sct/overseerr/commit/df94db050bf68a925118e0ce865d27178b702f9e))
|
||||
* **lang:** add support for russian languge ([8d8e750](https://github.com/sct/overseerr/commit/8d8e7509826514eebc859374d2e1ab212cc442d1))
|
||||
* **lang:** added translation using Weblate (Russian) ([887f5dd](https://github.com/sct/overseerr/commit/887f5dd487b61676029652d99cbc5b40213aa22e))
|
||||
* **lang:** translated using Weblate (French) ([30a8934](https://github.com/sct/overseerr/commit/30a8934626fa2d47e95b5925d7e4227a0d0aa728))
|
||||
* **lang:** translated using Weblate (German) ([44dbb74](https://github.com/sct/overseerr/commit/44dbb745b6216ce19fab4740520785c6414cf367))
|
||||
* **lang:** translated using Weblate (Japanese) ([a494507](https://github.com/sct/overseerr/commit/a494507dfeafb0cfd2bd66fb01138522e0e80737))
|
||||
* **lang:** translated using Weblate (Russian) ([86cadb8](https://github.com/sct/overseerr/commit/86cadb8283fcab8745b4c09f8429fd9e46708813))
|
||||
* **lang:** translations update from Weblate ([#201](https://github.com/sct/overseerr/issues/201)) ([b0c663b](https://github.com/sct/overseerr/commit/b0c663baccd994e234b4d41d86486c3af4906344))
|
||||
|
||||
# [1.1.0](https://github.com/sct/overseerr/compare/v1.0.0...v1.1.0) (2020-12-08)
|
||||
|
||||
|
||||
|
||||
132
CODE_OF_CONDUCT.md
Normal file
132
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# 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, 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
|
||||
[ryan@sct.dev](mailto:ryan@sct.dev).
|
||||
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.0, available at
|
||||
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
|
||||
|
||||
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.0]: https://www.contributor-covenant.org/version/2/0/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
|
||||
49
CONTRIBUTING.md
Normal file
49
CONTRIBUTING.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Contributing to Overseerr
|
||||
|
||||
All help is welcome and greatly appreciated. If you would like to contribute to the project the steps below can get you started:
|
||||
|
||||
## Development
|
||||
|
||||
### Tools Required
|
||||
|
||||
- HTML/Typescript/Javascript editor of choice. ([VSCode](https://code.visualstudio.com/) is recommended. Upon opening the project, a few extensions will be automatically recommended for install.)
|
||||
- [NodeJS](https://nodejs.org/en/download/) (Node 12.x.x or higher)
|
||||
- [Yarn](https://yarnpkg.com/)
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
|
||||
### Getting Started
|
||||
|
||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) the repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
|
||||
2. Create a new branch `git checkout -b BRANCH_NAME`
|
||||
|
||||
- Its recommended to name the branch something relevant to the feature or fix you are working on.
|
||||
- An example of this would be `fix-title-cards` or `feature-new-system`.
|
||||
- Bad examples would be `patch` or `bug`.
|
||||
|
||||
3. Install dependencies `yarn`
|
||||
4. `yarn dev` to build and watch for changes
|
||||
|
||||
You can also run the development environment in [Docker](https://www.docker.com/) with `docker-compose up -d`. This method does not require installing NodeJS or Yarn on your machine directly.
|
||||
|
||||
### Contributing Code
|
||||
|
||||
- If you are taking on an existing bug or feature ticket, please comment on the [GitHub Issue](https://github.com/sct/overseerr/issues) to avoid multiple people working on the same thing.
|
||||
- All commits **must** follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
|
||||
- It is okay if you squash your PR down to be a single commit that fits this standard.
|
||||
- PRs with commits not following this standard will not be merged.
|
||||
- Please make meaningful commits, or squash them
|
||||
- Always rebase your commit to the latest `develop` branch. Do not merge develop into your branch.
|
||||
- It is your responsbility to keep your branch up to date. It will not be merged unless its rebased off the latest develop branch.
|
||||
- You can create a Draft pull request early to get feedback on your work.
|
||||
- Your code must be formatted correctly or the tests will fail.
|
||||
- We use Prettier to format our codebase. It should auto run with a git hook, but its recommended to have a Prettier extension installed in your editor and have it format on save.
|
||||
- If you have questions or need help, you can reach out in [GitHub Discussions](https://github.com/sct/overseerr/discussions) or in our [Discord](https://discord.gg/PkCWJSeCk7).
|
||||
- Only open pull requests to `develop`. Never `master`. Any PR's opened to master will be closed.
|
||||
|
||||
## Translation
|
||||
|
||||
We use [Weblate](https://hosted.weblate.org/engage/overseerr/) for our translations so please feel free to contribute to localizing Overseerr!
|
||||
|
||||
## Attribution
|
||||
|
||||
This contribution guide was inspired by the [Next.js](https://github.com/vercel/next.js) and [Radarr](https://github.com/Radarr/Radarr) contribution guides.
|
||||
86
README.md
86
README.md
@@ -6,7 +6,7 @@
|
||||
<img src="https://github.com/sct/overseerr/workflows/Overseerr%20CI/badge.svg" alt="Overseerr CI">
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://discord.gg/ySfaEUcQ">
|
||||
<a href="https://discord.gg/PkCWJSeCk7">
|
||||
<img src="https://img.shields.io/discord/783137440809746482" alt="Discord">
|
||||
</a>
|
||||
<img src="https://img.shields.io/docker/pulls/sctx/overseerr" alt="Docker pulls">
|
||||
@@ -14,48 +14,53 @@
|
||||
<img src="https://hosted.weblate.org/widgets/overseerr/-/overseerr-frontend/svg-badge.svg" alt="Translation status" />
|
||||
</a>
|
||||
<a href="https://lgtm.com/projects/g/sct/overseerr/context:javascript"><img alt="Language grade: JavaScript" src="https://img.shields.io/lgtm/grade/javascript/g/sct/overseerr.svg?logo=lgtm&logoWidth=18"/></a>
|
||||
<img alt="GitHub" src="https://img.shields.io/github/license/sct/overseerr">
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
<a href="#contributors-"><img alt="All Contributors" src="https://img.shields.io/badge/all_contributors-9-orange.svg"/></a>
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
</p>
|
||||
|
||||
**Overseerr** is a tool for managing requests for your media library. It integrates with existing services such as **Sonarr** and **Radarr**!
|
||||
**Overseerr** is a free and open source software application for managing requests for your media library. It integrates with your existing services such as **Sonarr**, **Radarr** and **Plex**!
|
||||
|
||||
## Current Features
|
||||
|
||||
- Full Plex integration. Login and manage user access with Plex!
|
||||
- Integrates easily with your existing services. Currently Overseerr supports Sonarr and Radarr. More in the future!
|
||||
- Integrates easily with your existing services. Currently Overseerr supports Sonarr and Radarr. More to come!
|
||||
- Syncs to your Plex library to know what titles you already have.
|
||||
- Complex request system that allows users to request individual seasons or movies in a friendly, easy to use UI.
|
||||
- Complex request system allowing users to request individual seasons or movies in a friendly, easy to use UI.
|
||||
- Incredibly simple request management UI. Don't dig through the app to simply approve recent requests.
|
||||
- Granular permissions system
|
||||
- Granular permission system
|
||||
- Mobile friendly design, for when you need to approve requests on the go!
|
||||
|
||||
## In Development
|
||||
|
||||
- User profiles
|
||||
- User settings page to give users the ability to modify their Overseerr experience to their liking
|
||||
- Version update notifications in-app
|
||||
- User profiles.
|
||||
- User settings page (to give users the ability to modify their Overseerr experience to their liking).
|
||||
- Version update notifications in-app.
|
||||
- 4K requests (Includes multi-radarr/sonarr management for media)
|
||||
|
||||
## Planned Features
|
||||
|
||||
- More notification types (Slack/Telegram/etc)
|
||||
- More notification types (Slack/Telegram/etc.).
|
||||
- Issues system. This will allow users to report issues with content on your media server.
|
||||
- Local user system (for those who do not use Plex)
|
||||
- Compatiblity APIs to work with existing tools in your system
|
||||
- Local user system (for those who don't use Plex).
|
||||
- Compatiblity APIs (to work with existing tools in your system).
|
||||
|
||||
## Running Overseerr
|
||||
|
||||
Currently, the only distribution of Overseerr is through Docker images. If you have Docker, you can run Overseerr with the following command:
|
||||
Currently, Overseerr is only distributed through Docker images. If you have Docker, you can run Overseerr as per:
|
||||
|
||||
```
|
||||
docker run -d \
|
||||
-e LOG_LEVEL=info \
|
||||
-e TZ=Asia/Tokyo \
|
||||
-p 5055:3000 \
|
||||
-v /path/to/appdata/config:/config \
|
||||
-v /path/to/appdata/config:/app/config \
|
||||
--restart unless-stopped \
|
||||
sctx/overseer
|
||||
sctx/overseerr
|
||||
```
|
||||
|
||||
After running Overseerr for the first time, visit the web UI at http://[address]:5055 and complete the setup steps to configure Overseerr.
|
||||
After running Overseerr for the first time, configure it by visiting the web UI at http://[address]:5055 and completing the setup steps.
|
||||
|
||||
⚠️ Overseerr is currently under very heavy, rapid development and things are likely to break often. We need all the help we can get to find bugs and get them fixed to hit a more stable release. If you would like to help test the bleeding edge, please use the image **sctx/overseerr:develop** instead! ⚠️
|
||||
|
||||
@@ -65,34 +70,47 @@ After running Overseerr for the first time, visit the web UI at http://[address]
|
||||
|
||||
## Support
|
||||
|
||||
- You can reach us for support on [Discord](https://discord.gg/ySfaEUcQ).
|
||||
- Bugs can be opened with an issue on [Github](https://github.com/sct/overseerr/issues).
|
||||
- You can get support on [Discord](https://discord.gg/PkCWJSeCk7).
|
||||
- You can ask questions in the Help category of our [GitHub Discussions](https://github.com/sct/overseerr/discussions).
|
||||
- Bugs/Feature Requests can be opened via a [GitHub issue](https://github.com/sct/overseerr/issues).
|
||||
|
||||
## API Documentation
|
||||
|
||||
Full API documentation will soon be published automatically and available outside of running the app. But currently, you can access the api docs by running Overseerr locally and visiting http://localhost:3000/api-docs
|
||||
Full API documentation will soon be published automatically and available outside of running the app. Currently, you can access the API docs by running Overseerr locally and visiting http://localhost:3000/api-docs
|
||||
|
||||
## Contribution
|
||||
## Community
|
||||
|
||||
Anyone is welcome to contribute to Docker and pull requests are greatly appreciated! Contributors will be recognized in the future on this very README.
|
||||
You can ask questions, share ideas, and more in [GitHub Discussions](https://github.com/sct/overseerr/discussions).
|
||||
|
||||
### Developing Overseerr
|
||||
If you would like to chat with community members you can join the [Overseerr Discord](https://discord.gg/PkCWJSeCk7).
|
||||
|
||||
You can develop Overseer entirely in docker. Make sure you have [Docker Desktop](https://www.docker.com/products/docker-desktop) installed before continuing.
|
||||
Our [Code of Conduct](https://github.com/sct/overseerr/blob/develop/CODE_OF_CONDUCT.md) applies to all Overseerr community channels.
|
||||
|
||||
1. Make sure you have [Docker Desktop](https://www.docker.com/products/docker-desktop) installed.
|
||||
2. Run `docker-compose up -d` to start the server.
|
||||
3. Access the container at http://localhost:3000
|
||||
## Contributors
|
||||
|
||||
If Docker isn't your jam, you can always run Overseer with the following yarn commands:
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://sct.dev"><img src="https://avatars1.githubusercontent.com/u/234213?v=4" width="100px;" alt=""/><br /><sub><b>sct</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=sct" title="Code">💻</a> <a href="#design-sct" title="Design">🎨</a> <a href="#ideas-sct" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center"><a href="https://github.com/azoitos"><img src="https://avatars2.githubusercontent.com/u/26529049?v=4" width="100px;" alt=""/><br /><sub><b>Alex Zoitos</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=azoitos" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/OwsleyJr"><img src="https://avatars3.githubusercontent.com/u/8635678?v=4" width="100px;" alt=""/><br /><sub><b>Brandon Cohen</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=OwsleyJr" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=OwsleyJr" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/Ahreluth"><img src="https://avatars2.githubusercontent.com/u/75682440?v=4" width="100px;" alt=""/><br /><sub><b>Ahreluth</b></sub></a><br /><a href="#translation-Ahreluth" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/KovalevArtem"><img src="https://avatars0.githubusercontent.com/u/36500228?v=4" width="100px;" alt=""/><br /><sub><b>KovalevArtem</b></sub></a><br /><a href="#translation-KovalevArtem" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/GiyomuWeb"><img src="https://avatars0.githubusercontent.com/u/62489209?v=4" width="100px;" alt=""/><br /><sub><b>GiyomuWeb</b></sub></a><br /><a href="#translation-GiyomuWeb" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/angrycuban13"><img src="https://avatars3.githubusercontent.com/u/39564898?v=4" width="100px;" alt=""/><br /><sub><b>Angry Cuban</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=angrycuban13" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/jvennik"><img src="https://avatars3.githubusercontent.com/u/6672637?v=4" width="100px;" alt=""/><br /><sub><b>jvennik</b></sub></a><br /><a href="#translation-jvennik" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/darknessgp"><img src="https://avatars0.githubusercontent.com/u/1521243?v=4" width="100px;" alt=""/><br /><sub><b>darknessgp</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=darknessgp" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
```
|
||||
yarn
|
||||
yarn dev
|
||||
```
|
||||
<!-- markdownlint-enable -->
|
||||
<!-- prettier-ignore-end -->
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
You will need NodeJS installed. Once it's built and running, access it locally at http://localhost:3000 just like Docker.
|
||||
## Contributing
|
||||
|
||||
### Translation
|
||||
|
||||
We use [Weblate](https://hosted.weblate.org/engage/overseerr/) for our translations so please feel free to contribute to localizing Overseerr!
|
||||
You can help build Overseerr too! Check out our [Contribution Guide](https://github.com/sct/overseerr/blob/develop/CONTRIBUTING.md) to get started.
|
||||
|
||||
@@ -375,6 +375,7 @@ components:
|
||||
example: 1
|
||||
logoPath:
|
||||
type: string
|
||||
nullable: true
|
||||
originCountry:
|
||||
type: string
|
||||
name:
|
||||
@@ -428,7 +429,8 @@ components:
|
||||
releaseDate:
|
||||
type: string
|
||||
revenue:
|
||||
type: string
|
||||
type: number
|
||||
nullable: true
|
||||
runtime:
|
||||
type: number
|
||||
spokenLanguages:
|
||||
@@ -476,6 +478,7 @@ components:
|
||||
type: string
|
||||
airDate:
|
||||
type: string
|
||||
nullable: true
|
||||
episodeNumber:
|
||||
type: number
|
||||
overview:
|
||||
@@ -483,11 +486,12 @@ components:
|
||||
productionCode:
|
||||
type: string
|
||||
seasonNumber:
|
||||
type: string
|
||||
type: number
|
||||
showId:
|
||||
type: number
|
||||
stillPath:
|
||||
type: string
|
||||
nullable: true
|
||||
voteAverage:
|
||||
type: number
|
||||
voteCount:
|
||||
@@ -499,6 +503,7 @@ components:
|
||||
type: number
|
||||
airDate:
|
||||
type: string
|
||||
nullable: true
|
||||
episodeCount:
|
||||
type: number
|
||||
name:
|
||||
@@ -536,6 +541,7 @@ components:
|
||||
type: number
|
||||
profilePath:
|
||||
type: string
|
||||
nullable: true
|
||||
episodeRunTime:
|
||||
type: array
|
||||
items:
|
||||
@@ -658,6 +664,7 @@ components:
|
||||
tvdbId:
|
||||
type: number
|
||||
readOnly: true
|
||||
nullable: true
|
||||
status:
|
||||
type: number
|
||||
requests:
|
||||
@@ -696,6 +703,7 @@ components:
|
||||
type: number
|
||||
profilePath:
|
||||
type: string
|
||||
nullable: true
|
||||
Crew:
|
||||
type: object
|
||||
properties:
|
||||
@@ -715,25 +723,34 @@ components:
|
||||
type: string
|
||||
profilePath:
|
||||
type: string
|
||||
nullable: true
|
||||
ExternalIds:
|
||||
type: object
|
||||
properties:
|
||||
facebookId:
|
||||
type: string
|
||||
nullable: true
|
||||
freebaseId:
|
||||
type: string
|
||||
nullable: true
|
||||
freebaseMid:
|
||||
type: string
|
||||
nullable: true
|
||||
imdbId:
|
||||
type: string
|
||||
nullable: true
|
||||
instagramId:
|
||||
type: string
|
||||
nullable: true
|
||||
tvdbId:
|
||||
type: string
|
||||
type: number
|
||||
nullable: true
|
||||
tvrageId:
|
||||
type: string
|
||||
type: number
|
||||
nullable: true
|
||||
twitterId:
|
||||
type: string
|
||||
nullable: true
|
||||
ServiceProfile:
|
||||
type: object
|
||||
properties:
|
||||
@@ -887,6 +904,8 @@ components:
|
||||
type: string
|
||||
character:
|
||||
type: string
|
||||
mediaInfo:
|
||||
$ref: '#/components/schemas/MediaInfo'
|
||||
CreditCrew:
|
||||
type: object
|
||||
properties:
|
||||
@@ -941,6 +960,8 @@ components:
|
||||
type: string
|
||||
job:
|
||||
type: string
|
||||
mediaInfo:
|
||||
$ref: '#/components/schemas/MediaInfo'
|
||||
securitySchemes:
|
||||
cookieAuth:
|
||||
type: apiKey
|
||||
@@ -2374,7 +2395,7 @@ paths:
|
||||
crew:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/CreditCrew"
|
||||
$ref: '#/components/schemas/CreditCrew'
|
||||
id:
|
||||
type: number
|
||||
/media:
|
||||
|
||||
51
package.json
51
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "overseerr",
|
||||
"version": "1.1.0",
|
||||
"version": "1.4.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nodemon -e ts --watch server --watch overseerr-api.yml -e .json,.ts,.yml -x ts-node --files --project server/tsconfig.json server/index.ts",
|
||||
@@ -9,50 +9,51 @@
|
||||
"build": "yarn build:next && yarn build:server",
|
||||
"lint": "eslint \"./server/**/*.{ts,tsx}\" \"./src/**/*.{ts,tsx}\"",
|
||||
"start": "NODE_ENV=production node dist/index.js",
|
||||
"i18n:extract": "extract-messages -l=en,ja,fr -o src/i18n/locale -d en --flat true './src/**/!(*.test).{ts,tsx}'",
|
||||
"i18n:extract": "extract-messages -l=en -o src/i18n/locale -d en --flat true --overwriteDefault false './src/**/!(*.test).{ts,tsx}'",
|
||||
"migration:generate": "ts-node --project server/tsconfig.json ./node_modules/.bin/typeorm migration:generate",
|
||||
"migration:create": "ts-node --project server/tsconfig.json ./node_modules/.bin/typeorm migration:create",
|
||||
"migration:run": "ts-node --project server/tsconfig.json ./node_modules/.bin/typeorm migration:run",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@svgr/webpack": "^5.4.0",
|
||||
"axios": "^0.20.0",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"axios": "^0.21.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"bowser": "^2.11.0",
|
||||
"connect-typeorm": "^1.1.4",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"email-templates": "^8.0.0",
|
||||
"email-templates": "^8.0.2",
|
||||
"express": "^4.17.1",
|
||||
"express-openapi-validator": "^3.16.15",
|
||||
"express-openapi-validator": "^4.8.0",
|
||||
"express-session": "^1.17.1",
|
||||
"formik": "^2.2.1",
|
||||
"formik": "^2.2.5",
|
||||
"intl": "^1.2.5",
|
||||
"lodash": "^4.17.20",
|
||||
"next": "^10.0.3",
|
||||
"node-schedule": "^1.3.2",
|
||||
"nodemailer": "^6.4.16",
|
||||
"nookies": "^2.4.0",
|
||||
"nookies": "^2.5.0",
|
||||
"plex-api": "^5.3.1",
|
||||
"pug": "^3.0.0",
|
||||
"react": "16.13.1",
|
||||
"react-dom": "16.13.1",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"react-intersection-observer": "^8.31.0",
|
||||
"react-intl": "^5.8.5",
|
||||
"react-intl": "^5.10.6",
|
||||
"react-spring": "^8.0.27",
|
||||
"react-toast-notifications": "^2.4.0",
|
||||
"react-transition-group": "^4.4.1",
|
||||
"react-use-clipboard": "1.0.1",
|
||||
"react-use-clipboard": "1.0.2",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"sqlite3": "^5.0.0",
|
||||
"swagger-ui-express": "^4.1.4",
|
||||
"swr": "^0.3.5",
|
||||
"typeorm": "^0.2.26",
|
||||
"uuid": "^8.3.1",
|
||||
"swagger-ui-express": "^4.1.5",
|
||||
"swr": "^0.3.9",
|
||||
"typeorm": "^0.2.29",
|
||||
"uuid": "^8.3.2",
|
||||
"winston": "^3.3.3",
|
||||
"xml2js": "^0.4.23",
|
||||
"yamljs": "^0.3.0",
|
||||
"yup": "^0.29.3"
|
||||
"yup": "^0.32.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.12.8",
|
||||
@@ -68,10 +69,10 @@
|
||||
"@types/body-parser": "^1.19.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/email-templates": "^7.1.0",
|
||||
"@types/express": "^4.17.8",
|
||||
"@types/express": "^4.17.9",
|
||||
"@types/express-session": "^1.17.0",
|
||||
"@types/lodash": "^4.14.165",
|
||||
"@types/node": "^14.14.10",
|
||||
"@types/node": "^14.14.11",
|
||||
"@types/node-schedule": "^1.3.1",
|
||||
"@types/nodemailer": "^6.4.0",
|
||||
"@types/react": "^17.0.0",
|
||||
@@ -86,10 +87,10 @@
|
||||
"@typescript-eslint/eslint-plugin": "^4.9.1",
|
||||
"@typescript-eslint/parser": "^4.9.1",
|
||||
"autoprefixer": "^9",
|
||||
"babel-plugin-react-intl": "^8.2.2",
|
||||
"babel-plugin-react-intl": "^8.2.21",
|
||||
"babel-plugin-react-intl-auto": "^3.3.0",
|
||||
"commitizen": "^4.2.1",
|
||||
"copyfiles": "^2.4.0",
|
||||
"commitizen": "^4.2.2",
|
||||
"copyfiles": "^2.4.1",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"eslint": "^7.15.0",
|
||||
"eslint-config-prettier": "^7.0.0",
|
||||
@@ -104,12 +105,12 @@
|
||||
"nodemon": "^2.0.6",
|
||||
"postcss": "^7",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"prettier": "^2.1.2",
|
||||
"prettier": "^2.2.1",
|
||||
"semantic-release": "^17.3.0",
|
||||
"semantic-release-docker": "^2.2.0",
|
||||
"tailwindcss": "npm:@tailwindcss/postcss7-compat",
|
||||
"ts-node": "^9.0.0",
|
||||
"typescript": "^4.0.2"
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.1.2"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
|
||||
@@ -61,7 +61,7 @@ class PlexAPI {
|
||||
|
||||
this.plexClient = new NodePlexAPI({
|
||||
hostname: settings.plex.ip,
|
||||
post: settings.plex.port,
|
||||
port: settings.plex.port,
|
||||
token: plexToken,
|
||||
authenticator: {
|
||||
authenticate: (
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Axios, { AxiosInstance } from 'axios';
|
||||
import logger from '../logger';
|
||||
|
||||
interface RadarrMovieOptions {
|
||||
title: string;
|
||||
@@ -96,6 +97,11 @@ class RadarrAPI {
|
||||
|
||||
return response.data;
|
||||
} catch (e) {
|
||||
logger.error('Something went wrong adding a movie to Radarr', {
|
||||
label: 'Radarr',
|
||||
message: e.message,
|
||||
options,
|
||||
});
|
||||
throw new Error(`[Radarr] Failed to add movie: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -234,13 +234,24 @@ export class MediaRequest {
|
||||
return;
|
||||
}
|
||||
|
||||
const radarrSettings = settings.radarr.find(
|
||||
(radarr) => radarr.isDefault && !radarr.is4k
|
||||
);
|
||||
|
||||
if (!radarrSettings) {
|
||||
logger.info(
|
||||
'There is no default radarr configured. Did you set any of your Radarr servers as default?',
|
||||
{ label: 'Media Request' }
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const tmdb = new TheMovieDb();
|
||||
const radarrSettings = settings.radarr[0];
|
||||
const radarr = new RadarrAPI({
|
||||
apiKey: radarrSettings.apiKey,
|
||||
url: `${radarrSettings.useSsl ? 'https' : 'http'}://${
|
||||
radarrSettings.hostname
|
||||
}:${radarrSettings.port}/api`,
|
||||
}:${radarrSettings.port}${radarrSettings.baseUrl ?? ''}/api`,
|
||||
});
|
||||
const movie = await tmdb.getMovie({ movieId: this.media.tmdbId });
|
||||
|
||||
@@ -283,6 +294,18 @@ export class MediaRequest {
|
||||
return;
|
||||
}
|
||||
|
||||
const sonarrSettings = settings.sonarr.find(
|
||||
(sonarr) => sonarr.isDefault && !sonarr.is4k
|
||||
);
|
||||
|
||||
if (!sonarrSettings) {
|
||||
logger.info(
|
||||
'There is no default sonarr configured. Did you set any of your Sonarr servers as default?',
|
||||
{ label: 'Media Request' }
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const media = await mediaRepository.findOne({
|
||||
where: { id: this.media.id },
|
||||
relations: ['requests'],
|
||||
@@ -293,12 +316,11 @@ export class MediaRequest {
|
||||
}
|
||||
|
||||
const tmdb = new TheMovieDb();
|
||||
const sonarrSettings = settings.sonarr[0];
|
||||
const sonarr = new SonarrAPI({
|
||||
apiKey: sonarrSettings.apiKey,
|
||||
url: `${sonarrSettings.useSsl ? 'https' : 'http'}://${
|
||||
sonarrSettings.hostname
|
||||
}:${sonarrSettings.port}/api`,
|
||||
}:${sonarrSettings.port}${sonarrSettings.baseUrl ?? ''}/api`,
|
||||
});
|
||||
const series = await tmdb.getTvShow({ tvId: media.tmdbId });
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import session, { Store } from 'express-session';
|
||||
import { TypeormStore } from 'connect-typeorm/out';
|
||||
import YAML from 'yamljs';
|
||||
import swaggerUi from 'swagger-ui-express';
|
||||
import { OpenApiValidator } from 'express-openapi-validator';
|
||||
import * as OpenApiValidator from 'express-openapi-validator';
|
||||
import { Session } from './entity/Session';
|
||||
import { getSettings } from './lib/settings';
|
||||
import logger from './logger';
|
||||
@@ -61,11 +61,12 @@ app
|
||||
);
|
||||
const apiDocs = YAML.load(API_SPEC_PATH);
|
||||
server.use('/api-docs', swaggerUi.serve, swaggerUi.setup(apiDocs));
|
||||
await new OpenApiValidator({
|
||||
apiSpec: API_SPEC_PATH,
|
||||
validateRequests: true,
|
||||
validateResponses: true,
|
||||
}).install(server);
|
||||
server.use(
|
||||
OpenApiValidator.middleware({
|
||||
apiSpec: API_SPEC_PATH,
|
||||
validateRequests: true,
|
||||
})
|
||||
);
|
||||
/**
|
||||
* This is a workaround to convert dates to strings before they are validated by
|
||||
* OpenAPI validator. Otherwise, they are treated as objects instead of strings
|
||||
|
||||
7
server/interfaces/api/personInterfaces.ts
Normal file
7
server/interfaces/api/personInterfaces.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { PersonCreditCast, PersonCreditCrew } from '../../models/Person';
|
||||
|
||||
export interface PersonCombinedCreditsResponse {
|
||||
id: number;
|
||||
cast: PersonCreditCast[];
|
||||
crew: PersonCreditCrew[];
|
||||
}
|
||||
@@ -51,64 +51,81 @@ class JobPlexSync {
|
||||
|
||||
private async processMovie(plexitem: PlexLibraryItem) {
|
||||
const mediaRepository = getRepository(Media);
|
||||
if (plexitem.guid.match(plexRegex)) {
|
||||
const metadata = await this.plexClient.getMetadata(plexitem.ratingKey);
|
||||
const newMedia = new Media();
|
||||
try {
|
||||
if (plexitem.guid.match(plexRegex)) {
|
||||
const metadata = await this.plexClient.getMetadata(plexitem.ratingKey);
|
||||
const newMedia = new Media();
|
||||
|
||||
metadata.Guid.forEach((ref) => {
|
||||
if (ref.id.match(imdbRegex)) {
|
||||
newMedia.imdbId = ref.id.match(imdbRegex)?.[1] ?? undefined;
|
||||
} else if (ref.id.match(tmdbRegex)) {
|
||||
const tmdbMatch = ref.id.match(tmdbRegex)?.[1];
|
||||
newMedia.tmdbId = Number(tmdbMatch);
|
||||
if (!metadata.Guid) {
|
||||
logger.debug('No Guid metadata for this title. Skipping', {
|
||||
label: 'Plex Sync',
|
||||
ratingKey: plexitem.ratingKey,
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
const existing = await this.getExisting(newMedia.tmdbId);
|
||||
|
||||
if (existing && existing.status === MediaStatus.AVAILABLE) {
|
||||
this.log(`Title exists and is already available ${metadata.title}`);
|
||||
} else if (existing && existing.status !== MediaStatus.AVAILABLE) {
|
||||
existing.status = MediaStatus.AVAILABLE;
|
||||
mediaRepository.save(existing);
|
||||
this.log(
|
||||
`Request for ${metadata.title} exists. Setting status AVAILABLE`,
|
||||
'info'
|
||||
);
|
||||
} else {
|
||||
newMedia.status = MediaStatus.AVAILABLE;
|
||||
newMedia.mediaType = MediaType.MOVIE;
|
||||
await mediaRepository.save(newMedia);
|
||||
this.log(`Saved ${plexitem.title}`);
|
||||
}
|
||||
} else {
|
||||
const matchedid = plexitem.guid.match(/imdb:\/\/(tt[0-9]+)/);
|
||||
|
||||
if (matchedid?.[1]) {
|
||||
const tmdbMovie = await this.tmdb.getMovieByImdbId({
|
||||
imdbId: matchedid[1],
|
||||
metadata.Guid.forEach((ref) => {
|
||||
if (ref.id.match(imdbRegex)) {
|
||||
newMedia.imdbId = ref.id.match(imdbRegex)?.[1] ?? undefined;
|
||||
} else if (ref.id.match(tmdbRegex)) {
|
||||
const tmdbMatch = ref.id.match(tmdbRegex)?.[1];
|
||||
newMedia.tmdbId = Number(tmdbMatch);
|
||||
}
|
||||
});
|
||||
|
||||
const existing = await this.getExisting(tmdbMovie.id);
|
||||
const existing = await this.getExisting(newMedia.tmdbId);
|
||||
|
||||
if (existing && existing.status === MediaStatus.AVAILABLE) {
|
||||
this.log(`Title exists and is already available ${plexitem.title}`);
|
||||
this.log(`Title exists and is already available ${metadata.title}`);
|
||||
} else if (existing && existing.status !== MediaStatus.AVAILABLE) {
|
||||
existing.status = MediaStatus.AVAILABLE;
|
||||
await mediaRepository.save(existing);
|
||||
mediaRepository.save(existing);
|
||||
this.log(
|
||||
`Request for ${plexitem.title} exists. Setting status AVAILABLE`,
|
||||
`Request for ${metadata.title} exists. Setting status AVAILABLE`,
|
||||
'info'
|
||||
);
|
||||
} else if (tmdbMovie) {
|
||||
const newMedia = new Media();
|
||||
newMedia.imdbId = tmdbMovie.external_ids.imdb_id;
|
||||
newMedia.tmdbId = tmdbMovie.id;
|
||||
} else {
|
||||
newMedia.status = MediaStatus.AVAILABLE;
|
||||
newMedia.mediaType = MediaType.MOVIE;
|
||||
await mediaRepository.save(newMedia);
|
||||
this.log(`Saved ${tmdbMovie.title}`);
|
||||
this.log(`Saved ${plexitem.title}`);
|
||||
}
|
||||
} else {
|
||||
const matchedid = plexitem.guid.match(/imdb:\/\/(tt[0-9]+)/);
|
||||
|
||||
if (matchedid?.[1]) {
|
||||
const tmdbMovie = await this.tmdb.getMovieByImdbId({
|
||||
imdbId: matchedid[1],
|
||||
});
|
||||
|
||||
const existing = await this.getExisting(tmdbMovie.id);
|
||||
if (existing && existing.status === MediaStatus.AVAILABLE) {
|
||||
this.log(`Title exists and is already available ${plexitem.title}`);
|
||||
} else if (existing && existing.status !== MediaStatus.AVAILABLE) {
|
||||
existing.status = MediaStatus.AVAILABLE;
|
||||
await mediaRepository.save(existing);
|
||||
this.log(
|
||||
`Request for ${plexitem.title} exists. Setting status AVAILABLE`,
|
||||
'info'
|
||||
);
|
||||
} else if (tmdbMovie) {
|
||||
const newMedia = new Media();
|
||||
newMedia.imdbId = tmdbMovie.external_ids.imdb_id;
|
||||
newMedia.tmdbId = tmdbMovie.id;
|
||||
newMedia.status = MediaStatus.AVAILABLE;
|
||||
newMedia.mediaType = MediaType.MOVIE;
|
||||
await mediaRepository.save(newMedia);
|
||||
this.log(`Saved ${tmdbMovie.title}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
this.log(
|
||||
`Failed to process plex item. ratingKey: ${
|
||||
plexitem.parentRatingKey ?? plexitem.ratingKey
|
||||
}`,
|
||||
'error'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +270,7 @@ class JobPlexSync {
|
||||
this.progress = start;
|
||||
await this.processItems(slicedItems);
|
||||
|
||||
await new Promise((resolve) =>
|
||||
await new Promise<void>((resolve) =>
|
||||
setTimeout(async () => {
|
||||
await this.loop({
|
||||
start: start + BUNDLE_SIZE,
|
||||
|
||||
@@ -100,7 +100,7 @@ class Settings {
|
||||
|
||||
constructor(initialSettings?: AllSettings) {
|
||||
this.data = {
|
||||
clientId: '',
|
||||
clientId: uuidv4(),
|
||||
main: {
|
||||
apiKey: '',
|
||||
applicationUrl: '',
|
||||
@@ -222,10 +222,10 @@ class Settings {
|
||||
* @param overrideSettings If passed in, will override all existing settings with these
|
||||
* values
|
||||
*/
|
||||
public load(overrideSettings?: AllSettings): AllSettings {
|
||||
public load(overrideSettings?: AllSettings): Settings {
|
||||
if (overrideSettings) {
|
||||
this.data = overrideSettings;
|
||||
return this.data;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(SETTINGS_PATH)) {
|
||||
@@ -237,7 +237,7 @@ class Settings {
|
||||
this.data = merge(this.data, JSON.parse(data));
|
||||
this.save();
|
||||
}
|
||||
return this.data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public save(): void {
|
||||
|
||||
20
server/migration/1607928251245-DropImdbIdConstraint.ts
Normal file
20
server/migration/1607928251245-DropImdbIdConstraint.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { MigrationInterface, QueryRunner, TableUnique } from 'typeorm';
|
||||
|
||||
export class DropImdbIdConstraint1607928251245 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.dropUniqueConstraint(
|
||||
'media',
|
||||
'UQ_7ff2d11f6a83cb52386eaebe74b'
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.createUniqueConstraint(
|
||||
'media',
|
||||
new TableUnique({
|
||||
name: 'UQ_7ff2d11f6a83cb52386eaebe74b',
|
||||
columnNames: ['imdbId'],
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
TmdbPersonCreditCrew,
|
||||
TmdbPersonDetail,
|
||||
} from '../api/themoviedb';
|
||||
import Media from '../entity/Media';
|
||||
|
||||
export interface PersonDetail {
|
||||
id: number;
|
||||
@@ -42,6 +43,7 @@ export interface PersonCredit {
|
||||
title: string;
|
||||
adult: boolean;
|
||||
releaseDate: string;
|
||||
mediaInfo?: Media;
|
||||
}
|
||||
|
||||
export interface PersonCreditCast extends PersonCredit {
|
||||
@@ -76,7 +78,8 @@ export const mapPersonDetails = (person: TmdbPersonDetail): PersonDetail => ({
|
||||
});
|
||||
|
||||
export const mapCastCredits = (
|
||||
cast: TmdbPersonCreditCast
|
||||
cast: TmdbPersonCreditCast,
|
||||
media?: Media
|
||||
): PersonCreditCast => ({
|
||||
id: cast.id,
|
||||
originalLanguage: cast.original_language,
|
||||
@@ -100,10 +103,12 @@ export const mapCastCredits = (
|
||||
adult: cast.adult,
|
||||
releaseDate: cast.release_date,
|
||||
character: cast.character,
|
||||
mediaInfo: media,
|
||||
});
|
||||
|
||||
export const mapCrewCredits = (
|
||||
crew: TmdbPersonCreditCrew
|
||||
crew: TmdbPersonCreditCrew,
|
||||
media?: Media
|
||||
): PersonCreditCrew => ({
|
||||
id: crew.id,
|
||||
originalLanguage: crew.original_language,
|
||||
@@ -128,4 +133,5 @@ export const mapCrewCredits = (
|
||||
releaseDate: crew.release_date,
|
||||
department: crew.department,
|
||||
job: crew.job,
|
||||
mediaInfo: media,
|
||||
});
|
||||
|
||||
@@ -12,8 +12,8 @@ const mediaRoutes = Router();
|
||||
mediaRoutes.get('/', async (req, res, next) => {
|
||||
const mediaRepository = getRepository(Media);
|
||||
|
||||
const pageSize = Number(req.query.take) ?? 20;
|
||||
const skip = Number(req.query.skip) ?? 0;
|
||||
const pageSize = req.query.take ? Number(req.query.take) : 20;
|
||||
const skip = req.query.skip ? Number(req.query.skip) : 0;
|
||||
|
||||
let statusFilter:
|
||||
| MediaStatus
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Router } from 'express';
|
||||
import TheMovieDb from '../api/themoviedb';
|
||||
import Media from '../entity/Media';
|
||||
import logger from '../logger';
|
||||
import {
|
||||
mapCastCredits,
|
||||
@@ -32,9 +33,27 @@ personRoutes.get('/:id/combined_credits', async (req, res) => {
|
||||
language: req.query.language as string,
|
||||
});
|
||||
|
||||
const castMedia = await Media.getRelatedMedia(
|
||||
combinedCredits.cast.map((result) => result.id)
|
||||
);
|
||||
|
||||
const crewMedia = await Media.getRelatedMedia(
|
||||
combinedCredits.crew.map((result) => result.id)
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
cast: combinedCredits.cast.map((result) => mapCastCredits(result)),
|
||||
crew: combinedCredits.crew.map((result) => mapCrewCredits(result)),
|
||||
cast: combinedCredits.cast.map((result) =>
|
||||
mapCastCredits(
|
||||
result,
|
||||
castMedia.find((med) => med.tmdbId === result.id)
|
||||
)
|
||||
),
|
||||
crew: combinedCredits.crew.map((result) =>
|
||||
mapCrewCredits(
|
||||
result,
|
||||
crewMedia.find((med) => med.tmdbId === result.id)
|
||||
)
|
||||
),
|
||||
id: combinedCredits.id,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,12 +15,12 @@ const requestRoutes = Router();
|
||||
requestRoutes.get('/', async (req, res, next) => {
|
||||
const requestRepository = getRepository(MediaRequest);
|
||||
try {
|
||||
const pageSize = Number(req.query.take) ?? 20;
|
||||
const skip = Number(req.query.skip) ?? 0;
|
||||
const pageSize = req.query.take ? Number(req.query.take) : 20;
|
||||
const skip = req.query.skip ? Number(req.query.skip) : 0;
|
||||
|
||||
let statusFilter:
|
||||
| MediaRequestStatus
|
||||
| FindOperator<MediaRequestStatus>
|
||||
| FindOperator<string | MediaRequestStatus>
|
||||
| undefined = undefined;
|
||||
|
||||
switch (req.query.filter) {
|
||||
|
||||
2
server/types/plex-api.d.ts
vendored
2
server/types/plex-api.d.ts
vendored
@@ -2,7 +2,7 @@ declare module 'plex-api' {
|
||||
export default class PlexAPI {
|
||||
constructor(intiialOptions: {
|
||||
hostname: string;
|
||||
post: number;
|
||||
port: number;
|
||||
token?: string;
|
||||
authenticator: {
|
||||
authenticate: (
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
interface HeaderProps {
|
||||
extraMargin?: number;
|
||||
subtext?: string;
|
||||
subtext?: React.ReactNode;
|
||||
}
|
||||
|
||||
const Header: React.FC<HeaderProps> = ({
|
||||
|
||||
@@ -69,6 +69,7 @@ const ListView: React.FC<ListViewProps> = ({
|
||||
case 'person':
|
||||
titleCard = (
|
||||
<PersonCard
|
||||
personId={title.id}
|
||||
name={title.name}
|
||||
profilePath={title.profilePath}
|
||||
canExpand
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React, { MouseEvent, ReactNode, useRef } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Button, { ButtonType } from '../Button';
|
||||
import { useTransition, animated } from 'react-spring';
|
||||
import { useLockBodyScroll } from '../../../hooks/useLockBodyScroll';
|
||||
import LoadingSpinner from '../LoadingSpinner';
|
||||
import useClickOutside from '../../../hooks/useClickOutside';
|
||||
import { useIntl } from 'react-intl';
|
||||
import globalMessages from '../../../i18n/globalMessages';
|
||||
import Transition from '../../Transition';
|
||||
|
||||
interface ModalProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
title?: string;
|
||||
@@ -53,7 +53,6 @@ const Modal: React.FC<ModalProps> = ({
|
||||
tertiaryDisabled = false,
|
||||
tertiaryText,
|
||||
onTertiary,
|
||||
...props
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
@@ -63,134 +62,123 @@ const Modal: React.FC<ModalProps> = ({
|
||||
: undefined;
|
||||
});
|
||||
useLockBodyScroll(true, disableScrollLock);
|
||||
const containerTransitions = useTransition(!loading, null, {
|
||||
from: { opacity: 0, transform: 'scale(0.5)' },
|
||||
enter: { opacity: 1, transform: 'scale(1)' },
|
||||
leave: { opacity: 0, transform: 'scale(0.5)' },
|
||||
config: { tension: 500, velocity: 40, friction: 60 },
|
||||
});
|
||||
const loadingTransitions = useTransition(loading, null, {
|
||||
from: { opacity: 0, transform: 'scale(0.5)' },
|
||||
enter: { opacity: 1, transform: 'scale(1)' },
|
||||
leave: { opacity: 0, transform: 'scale(0.5)' },
|
||||
config: { tension: 500, velocity: 40, friction: 60 },
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{ReactDOM.createPortal(
|
||||
<animated.div
|
||||
className="fixed top-0 left-0 right-0 bottom-0 bg-gray-800 bg-opacity-50 w-full h-full z-50 flex justify-center items-center"
|
||||
style={props.style}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Escape') {
|
||||
typeof onCancel === 'function' && backgroundClickable
|
||||
? onCancel()
|
||||
: undefined;
|
||||
}
|
||||
}}
|
||||
return ReactDOM.createPortal(
|
||||
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
||||
<div
|
||||
className="fixed top-0 left-0 right-0 bottom-0 bg-gray-800 bg-opacity-50 w-full h-full z-50 flex justify-center items-center"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Escape') {
|
||||
typeof onCancel === 'function' && backgroundClickable
|
||||
? onCancel()
|
||||
: undefined;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Transition
|
||||
enter="transition opacity-0 duration-300 transform scale-75"
|
||||
enterFrom="opacity-0 scale-75"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="transition opacity-100 duration-300"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
show={loading}
|
||||
>
|
||||
<div style={{ position: 'absolute' }}>
|
||||
<LoadingSpinner />
|
||||
</div>
|
||||
</Transition>
|
||||
<Transition
|
||||
enter="transition opacity-0 duration-300 transform scale-75"
|
||||
enterFrom="opacity-0 scale-75"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="transition opacity-100 duration-300"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
show={!loading}
|
||||
>
|
||||
<div
|
||||
className="inline-block align-bottom bg-gray-700 sm:rounded-lg px-4 pt-5 pb-4 text-left overflow-auto shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-3xl w-full sm:p-6 max-h-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline"
|
||||
ref={modalRef}
|
||||
>
|
||||
{loadingTransitions.map(
|
||||
({ props, item, key }) =>
|
||||
item && (
|
||||
<animated.div
|
||||
style={{ ...props, position: 'absolute' }}
|
||||
key={key}
|
||||
<div className="sm:flex sm:items-center">
|
||||
{iconSvg && (
|
||||
<div className="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-gray-600 text-white sm:mx-0 sm:h-10 sm:w-10">
|
||||
{iconSvg}
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`mt-3 text-center sm:mt-0 sm:text-left ${
|
||||
iconSvg ? 'sm:ml-4' : 'mb-6'
|
||||
}`}
|
||||
>
|
||||
{title && (
|
||||
<h3
|
||||
className="text-lg leading-6 font-medium text-white"
|
||||
id="modal-headline"
|
||||
>
|
||||
<LoadingSpinner />
|
||||
</animated.div>
|
||||
)
|
||||
{title}
|
||||
</h3>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{children && (
|
||||
<div className="mt-4 text-sm leading-5 text-gray-300">
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
{containerTransitions.map(
|
||||
({ props, item, key }) =>
|
||||
item && (
|
||||
<animated.div
|
||||
style={props}
|
||||
className="inline-block align-bottom bg-gray-700 sm:rounded-lg px-4 pt-5 pb-4 text-left overflow-auto shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-3xl w-full sm:p-6 max-h-full"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline"
|
||||
key={key}
|
||||
ref={modalRef}
|
||||
{(onCancel || onOk || onSecondary || onTertiary) && (
|
||||
<div className="mt-5 sm:mt-4 flex justify-center sm:justify-start flex-row-reverse">
|
||||
{typeof onOk === 'function' && (
|
||||
<Button
|
||||
buttonType={okButtonType}
|
||||
onClick={onOk}
|
||||
className="ml-3"
|
||||
disabled={okDisabled}
|
||||
>
|
||||
<div className="sm:flex sm:items-center">
|
||||
{iconSvg && (
|
||||
<div className="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-gray-600 text-white sm:mx-0 sm:h-10 sm:w-10">
|
||||
{iconSvg}
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`mt-3 text-center sm:mt-0 sm:text-left ${
|
||||
iconSvg ? 'sm:ml-4' : 'mb-6'
|
||||
}`}
|
||||
>
|
||||
{title && (
|
||||
<h3
|
||||
className="text-lg leading-6 font-medium text-white"
|
||||
id="modal-headline"
|
||||
>
|
||||
{title}
|
||||
</h3>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{children && (
|
||||
<div className="mt-4 text-sm leading-5 text-gray-300">
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
{(onCancel || onOk || onSecondary || onTertiary) && (
|
||||
<div className="mt-5 sm:mt-4 flex justify-center sm:justify-start flex-row-reverse">
|
||||
{typeof onOk === 'function' && (
|
||||
<Button
|
||||
buttonType={okButtonType}
|
||||
onClick={onOk}
|
||||
className="ml-3"
|
||||
disabled={okDisabled}
|
||||
>
|
||||
{okText ? okText : 'Ok'}
|
||||
</Button>
|
||||
)}
|
||||
{typeof onSecondary === 'function' && secondaryText && (
|
||||
<Button
|
||||
buttonType={secondaryButtonType}
|
||||
onClick={onSecondary}
|
||||
className="ml-3"
|
||||
disabled={secondaryDisabled}
|
||||
>
|
||||
{secondaryText}
|
||||
</Button>
|
||||
)}
|
||||
{typeof onTertiary === 'function' && tertiaryText && (
|
||||
<Button
|
||||
buttonType={tertiaryButtonType}
|
||||
onClick={onTertiary}
|
||||
className="ml-3"
|
||||
disabled={tertiaryDisabled}
|
||||
>
|
||||
{tertiaryText}
|
||||
</Button>
|
||||
)}
|
||||
{typeof onCancel === 'function' && (
|
||||
<Button
|
||||
buttonType={cancelButtonType}
|
||||
onClick={onCancel}
|
||||
className="ml-3 sm:ml-0 sm:px-4"
|
||||
>
|
||||
{cancelText
|
||||
? cancelText
|
||||
: intl.formatMessage(globalMessages.cancel)}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</animated.div>
|
||||
)
|
||||
{okText ? okText : 'Ok'}
|
||||
</Button>
|
||||
)}
|
||||
{typeof onSecondary === 'function' && secondaryText && (
|
||||
<Button
|
||||
buttonType={secondaryButtonType}
|
||||
onClick={onSecondary}
|
||||
className="ml-3"
|
||||
disabled={secondaryDisabled}
|
||||
>
|
||||
{secondaryText}
|
||||
</Button>
|
||||
)}
|
||||
{typeof onTertiary === 'function' && tertiaryText && (
|
||||
<Button
|
||||
buttonType={tertiaryButtonType}
|
||||
onClick={onTertiary}
|
||||
className="ml-3"
|
||||
disabled={tertiaryDisabled}
|
||||
>
|
||||
{tertiaryText}
|
||||
</Button>
|
||||
)}
|
||||
{typeof onCancel === 'function' && (
|
||||
<Button
|
||||
buttonType={cancelButtonType}
|
||||
onClick={onCancel}
|
||||
className="ml-3 sm:ml-0 sm:px-4"
|
||||
>
|
||||
{cancelText
|
||||
? cancelText
|
||||
: intl.formatMessage(globalMessages.cancel)}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</animated.div>,
|
||||
document.body
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -57,9 +57,12 @@ const Discover: React.FC = () => {
|
||||
`/api/v1/discover/tv?language=${locale}`
|
||||
);
|
||||
|
||||
const { data: movieUpcomingData, error: movieUpcomingError } = useSWR<
|
||||
MovieDiscoverResult
|
||||
>(`/api/v1/discover/movies/upcoming?language=${locale}`);
|
||||
const {
|
||||
data: movieUpcomingData,
|
||||
error: movieUpcomingError,
|
||||
} = useSWR<MovieDiscoverResult>(
|
||||
`/api/v1/discover/movies/upcoming?language=${locale}`
|
||||
);
|
||||
|
||||
const { data: trendingData, error: trendingError } = useSWR<MixedResult>(
|
||||
`/api/v1/discover/trending?language=${locale}`
|
||||
@@ -69,9 +72,12 @@ const Discover: React.FC = () => {
|
||||
'/api/v1/media?filter=available&take=20&sort=modified'
|
||||
);
|
||||
|
||||
const { data: requests, error: requestError } = useSWR<
|
||||
RequestResultsResponse
|
||||
>('/api/v1/request?filter=unavailable&take=10&sort=modified&skip=0');
|
||||
const {
|
||||
data: requests,
|
||||
error: requestError,
|
||||
} = useSWR<RequestResultsResponse>(
|
||||
'/api/v1/request?filter=unavailable&take=10&sort=modified&skip=0'
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -236,7 +242,11 @@ const Discover: React.FC = () => {
|
||||
);
|
||||
case 'person':
|
||||
return (
|
||||
<PersonCard name={title.name} profilePath={title.profilePath} />
|
||||
<PersonCard
|
||||
personId={title.id}
|
||||
name={title.name}
|
||||
profilePath={title.profilePath}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
|
||||
@@ -29,6 +29,22 @@ const availableLanguages: AvailableLanguageObject = {
|
||||
code: 'fr',
|
||||
display: 'Français',
|
||||
},
|
||||
'nb-NO': {
|
||||
code: 'nb-NO',
|
||||
display: 'Norwegian Bokmål',
|
||||
},
|
||||
de: {
|
||||
code: 'de',
|
||||
display: 'German',
|
||||
},
|
||||
ru: {
|
||||
code: 'ru',
|
||||
display: 'Russian',
|
||||
},
|
||||
nl: {
|
||||
code: 'nl',
|
||||
display: 'Nederlands',
|
||||
},
|
||||
};
|
||||
|
||||
const LanguagePicker: React.FC = () => {
|
||||
@@ -61,10 +77,10 @@ const LanguagePicker: React.FC = () => {
|
||||
</div>
|
||||
<Transition
|
||||
show={isDropdownOpen}
|
||||
enter="transition ease-out duration-100"
|
||||
enter="transition ease-out duration-100 opacity-0"
|
||||
enterFrom="transform opacity-0 scale-95"
|
||||
enterTo="transform opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75"
|
||||
leave="transition ease-in duration-75 opacity-100"
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
|
||||
66
src/components/MovieDetails/MovieCast/index.tsx
Normal file
66
src/components/MovieDetails/MovieCast/index.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useContext } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
import { MovieDetails } from '../../../../server/models/Movie';
|
||||
import { LanguageContext } from '../../../context/LanguageContext';
|
||||
import Error from '../../../pages/_error';
|
||||
import Header from '../../Common/Header';
|
||||
import LoadingSpinner from '../../Common/LoadingSpinner';
|
||||
import PersonCard from '../../PersonCard';
|
||||
|
||||
const messages = defineMessages({
|
||||
fullcast: 'Full Cast',
|
||||
});
|
||||
|
||||
const MovieCast: React.FC = () => {
|
||||
const router = useRouter();
|
||||
const intl = useIntl();
|
||||
const { locale } = useContext(LanguageContext);
|
||||
const { data, error } = useSWR<MovieDetails>(
|
||||
`/api/v1/movie/${router.query.movieId}?language=${locale}`
|
||||
);
|
||||
|
||||
if (!data && !error) {
|
||||
return <LoadingSpinner />;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return <Error statusCode={404} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header
|
||||
subtext={
|
||||
<Link href={`/movie/${data.id}`}>
|
||||
<a className="hover:underline">{data.title}</a>
|
||||
</Link>
|
||||
}
|
||||
>
|
||||
{intl.formatMessage(messages.fullcast)}
|
||||
</Header>
|
||||
<ul className="grid grid-cols-2 gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-7 2xl:grid-cols-8">
|
||||
{data?.credits.cast.map((person) => {
|
||||
return (
|
||||
<li
|
||||
key={person.id}
|
||||
className="col-span-1 flex flex-col text-center items-center"
|
||||
>
|
||||
<PersonCard
|
||||
name={person.name}
|
||||
personId={person.id}
|
||||
subName={person.character}
|
||||
profilePath={person.profilePath}
|
||||
canExpand
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MovieCast;
|
||||
@@ -527,6 +527,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
items={data?.credits.cast.slice(0, 20).map((person) => (
|
||||
<PersonCard
|
||||
key={`cast-item-${person.id}`}
|
||||
personId={person.id}
|
||||
name={person.name}
|
||||
subName={person.character}
|
||||
profilePath={person.profilePath}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import Link from 'next/link';
|
||||
import React from 'react';
|
||||
|
||||
interface PersonCardProps {
|
||||
personId: number;
|
||||
name: string;
|
||||
subName?: string;
|
||||
profilePath?: string;
|
||||
@@ -8,50 +10,55 @@ interface PersonCardProps {
|
||||
}
|
||||
|
||||
const PersonCard: React.FC<PersonCardProps> = ({
|
||||
personId,
|
||||
name,
|
||||
subName,
|
||||
profilePath,
|
||||
canExpand = false,
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={`relative ${
|
||||
canExpand ? 'w-full' : 'w-36 sm:w-36 md:w-44'
|
||||
} bg-gray-600 rounded-lg text-white shadow-lg hover:bg-gray-500 transition ease-in-out duration-150 cursor-pointer`}
|
||||
>
|
||||
<div style={{ paddingBottom: '150%' }}>
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center">
|
||||
{profilePath && (
|
||||
<div
|
||||
style={{
|
||||
backgroundImage: `url(https://image.tmdb.org/t/p/w600_and_h900_bestv2${profilePath})`,
|
||||
}}
|
||||
className="rounded-full w-28 h-28 md:w-32 md:h-32 bg-cover bg-center mb-6"
|
||||
/>
|
||||
)}
|
||||
{!profilePath && (
|
||||
<svg
|
||||
className="w-28 h-28 md:w-32 md:h-32 mb-6"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-6-3a2 2 0 11-4 0 2 2 0 014 0zm-2 4a5 5 0 00-4.546 2.916A5.986 5.986 0 0010 16a5.986 5.986 0 004.546-2.084A5 5 0 0010 11z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
<div className="whitespace-normal text-center">{name}</div>
|
||||
{subName && (
|
||||
<div className="whitespace-normal text-center text-sm text-gray-300">
|
||||
{subName}
|
||||
<Link href={`/person/${personId}`}>
|
||||
<a className={canExpand ? 'w-full' : 'w-36 sm:w-36 md:w-44'}>
|
||||
<div
|
||||
className={`relative ${
|
||||
canExpand ? 'w-full' : 'w-36 sm:w-36 md:w-44'
|
||||
} bg-gray-600 rounded-lg text-white shadow-lg hover:bg-gray-500 transition ease-in-out duration-150 cursor-pointer`}
|
||||
>
|
||||
<div style={{ paddingBottom: '150%' }}>
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center">
|
||||
{profilePath && (
|
||||
<div
|
||||
style={{
|
||||
backgroundImage: `url(https://image.tmdb.org/t/p/w600_and_h900_bestv2${profilePath})`,
|
||||
}}
|
||||
className="rounded-full w-28 h-28 md:w-32 md:h-32 bg-cover bg-center mb-6"
|
||||
/>
|
||||
)}
|
||||
{!profilePath && (
|
||||
<svg
|
||||
className="w-28 h-28 md:w-32 md:h-32 mb-6"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-6-3a2 2 0 11-4 0 2 2 0 014 0zm-2 4a5 5 0 00-4.546 2.916A5.986 5.986 0 0010 16a5.986 5.986 0 004.546-2.084A5 5 0 0010 11z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
<div className="whitespace-normal text-center">{name}</div>
|
||||
{subName && (
|
||||
<div className="whitespace-normal text-center text-sm text-gray-300">
|
||||
{subName}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
131
src/components/PersonDetails/index.tsx
Normal file
131
src/components/PersonDetails/index.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useContext } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import type { PersonDetail } from '../../../server/models/Person';
|
||||
import type { PersonCombinedCreditsResponse } from '../../../server/interfaces/api/personInterfaces';
|
||||
import Error from '../../pages/_error';
|
||||
import LoadingSpinner from '../Common/LoadingSpinner';
|
||||
import TitleCard from '../TitleCard';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { LanguageContext } from '../../context/LanguageContext';
|
||||
|
||||
const messages = defineMessages({
|
||||
appearsin: 'Appears in',
|
||||
ascharacter: 'as {character}',
|
||||
nobiography: 'No biography available.',
|
||||
});
|
||||
|
||||
const PersonDetails: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const { locale } = useContext(LanguageContext);
|
||||
const router = useRouter();
|
||||
const { data, error } = useSWR<PersonDetail>(
|
||||
`/api/v1/person/${router.query.personId}`
|
||||
);
|
||||
|
||||
const {
|
||||
data: combinedCredits,
|
||||
error: errorCombinedCredits,
|
||||
} = useSWR<PersonCombinedCreditsResponse>(
|
||||
`/api/v1/person/${router.query.personId}/combined_credits?language=${locale}`
|
||||
);
|
||||
|
||||
if (!data && !error) {
|
||||
return <LoadingSpinner />;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return <Error statusCode={404} />;
|
||||
}
|
||||
|
||||
const sortedCast = combinedCredits?.cast.sort((a, b) => {
|
||||
const aDate =
|
||||
a.mediaType === 'movie'
|
||||
? a.releaseDate?.slice(0, 4) ?? 0
|
||||
: a.firstAirDate?.slice(0, 4) ?? 0;
|
||||
const bDate =
|
||||
b.mediaType === 'movie'
|
||||
? b.releaseDate?.slice(0, 4) ?? 0
|
||||
: b.firstAirDate?.slice(0, 4) ?? 0;
|
||||
if (aDate > bDate) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
const isLoading = !combinedCredits && !errorCombinedCredits;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex mt-8 mb-8 flex-col md:flex-row items-center md:items-start">
|
||||
{data.profilePath && (
|
||||
<div
|
||||
style={{
|
||||
backgroundImage: `url(https://image.tmdb.org/t/p/w600_and_h900_bestv2${data.profilePath})`,
|
||||
}}
|
||||
className="rounded-full w-36 h-36 md:w-44 md:h-44 bg-cover bg-center mb-6 md:mb-0 mr-0 md:mr-6 flex-shrink-0"
|
||||
/>
|
||||
)}
|
||||
<div className="text-gray-300 text-center md:text-left">
|
||||
<h1 className="text-3xl md:text-4xl text-white mb-4">{data.name}</h1>
|
||||
<div>
|
||||
{data.biography
|
||||
? data.biography
|
||||
: intl.formatMessage(messages.nobiography)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:flex md:items-center md:justify-between mb-4 mt-6">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="inline-flex text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate items-center">
|
||||
<span>{intl.formatMessage(messages.appearsin)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul className="grid grid-cols-2 gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-7 2xl:grid-cols-8">
|
||||
{sortedCast?.map((media) => {
|
||||
return (
|
||||
<li
|
||||
key={`list-cast-item-${media.id}`}
|
||||
className="col-span-1 flex flex-col text-center items-center"
|
||||
>
|
||||
<TitleCard
|
||||
id={media.id}
|
||||
title={media.mediaType === 'movie' ? media.title : media.name}
|
||||
userScore={media.voteAverage}
|
||||
year={
|
||||
media.mediaType === 'movie'
|
||||
? media.releaseDate
|
||||
: media.firstAirDate
|
||||
}
|
||||
image={media.posterPath}
|
||||
summary={media.overview}
|
||||
mediaType={media.mediaType as 'movie' | 'tv'}
|
||||
status={media.mediaInfo?.status}
|
||||
canExpand
|
||||
/>
|
||||
{media.character && (
|
||||
<div className="mt-2 text-gray-300 text-xs truncate w-36 sm:w-36 md:w-44 text-center">
|
||||
{intl.formatMessage(messages.ascharacter, {
|
||||
character: media.character,
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
{isLoading &&
|
||||
[...Array(20)].map((_item, i) => (
|
||||
<li
|
||||
key={`placeholder-${i}`}
|
||||
className="col-span-1 flex flex-col text-center items-center"
|
||||
>
|
||||
<TitleCard.Placeholder canExpand />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PersonDetails;
|
||||
@@ -19,6 +19,7 @@ import StatusBadge from '../StatusBadge';
|
||||
const messages = defineMessages({
|
||||
requestedby: 'Requested by {username}',
|
||||
seasons: 'Seasons',
|
||||
all: 'All',
|
||||
});
|
||||
|
||||
const isMovie = (movie: MovieDetails | TvDetails): movie is MovieDetails => {
|
||||
@@ -53,9 +54,11 @@ const RequestCard: React.FC<RequestCardProps> = ({ request }) => {
|
||||
const { data: title, error } = useSWR<MovieDetails | TvDetails>(
|
||||
inView ? `${url}?language=${locale}` : null
|
||||
);
|
||||
const { data: requestData, error: requestError, revalidate } = useSWR<
|
||||
MediaRequest
|
||||
>(`/api/v1/request/${request.id}`, {
|
||||
const {
|
||||
data: requestData,
|
||||
error: requestError,
|
||||
revalidate,
|
||||
} = useSWR<MediaRequest>(`/api/v1/request/${request.id}`, {
|
||||
initialData: request,
|
||||
});
|
||||
|
||||
@@ -103,7 +106,7 @@ const RequestCard: React.FC<RequestCardProps> = ({ request }) => {
|
||||
{isMovie(title) ? title.title : title.name}
|
||||
</Link>
|
||||
</h2>
|
||||
<div className="text-xs sm:text-sm">
|
||||
<div className="text-xs sm:text-sm truncate">
|
||||
{intl.formatMessage(messages.requestedby, {
|
||||
username: requestData.requestedBy.username,
|
||||
})}
|
||||
@@ -116,11 +119,21 @@ const RequestCard: React.FC<RequestCardProps> = ({ request }) => {
|
||||
{request.seasons.length > 0 && (
|
||||
<div className="hidden mt-2 text-sm sm:flex items-center">
|
||||
<span className="mr-2">{intl.formatMessage(messages.seasons)}</span>
|
||||
{request.seasons.map((season) => (
|
||||
<span key={`season-${season.id}`} className="mr-2">
|
||||
<Badge>{season.seasonNumber}</Badge>
|
||||
{!isMovie(title) &&
|
||||
title.seasons.filter((season) => season.seasonNumber !== 0)
|
||||
.length === request.seasons.length ? (
|
||||
<span className="mr-2 uppercase">
|
||||
<Badge>{intl.formatMessage(messages.all)}</Badge>
|
||||
</span>
|
||||
))}
|
||||
) : (
|
||||
<div className="hide-scrollbar overflow-x-scroll">
|
||||
{request.seasons.map((season) => (
|
||||
<span key={`season-${season.id}`} className="mr-2">
|
||||
<Badge>{season.seasonNumber}</Badge>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{requestData.status === MediaRequestStatus.PENDING &&
|
||||
|
||||
@@ -43,7 +43,6 @@ const MovieRequestModal: React.FC<RequestModalProps> = ({
|
||||
onComplete,
|
||||
tmdbId,
|
||||
onUpdating,
|
||||
...props
|
||||
}) => {
|
||||
const [isUpdating, setIsUpdating] = useState(false);
|
||||
const { addToast } = useToasts();
|
||||
@@ -140,7 +139,6 @@ const MovieRequestModal: React.FC<RequestModalProps> = ({
|
||||
okButtonType={'danger'}
|
||||
cancelText={intl.formatMessage(messages.close)}
|
||||
iconSvg={<DownloadIcon className="w-6 h-6" />}
|
||||
{...props}
|
||||
>
|
||||
{intl.formatMessage(messages.requestfrom, {
|
||||
username: activeRequest.requestedBy.username,
|
||||
@@ -164,7 +162,6 @@ const MovieRequestModal: React.FC<RequestModalProps> = ({
|
||||
}
|
||||
okButtonType={'primary'}
|
||||
iconSvg={<DownloadIcon className="w-6 h-6" />}
|
||||
{...props}
|
||||
>
|
||||
{text}
|
||||
</Modal>
|
||||
|
||||
@@ -47,7 +47,6 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
||||
onComplete,
|
||||
tmdbId,
|
||||
onUpdating,
|
||||
...props
|
||||
}) => {
|
||||
const { addToast } = useToasts();
|
||||
const { data, error } = useSWR<TvDetails>(`/api/v1/tv/${tmdbId}`);
|
||||
@@ -222,7 +221,6 @@ const TvRequestModal: React.FC<RequestModalProps> = ({
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
{...props}
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
<div className="-mx-4 sm:mx-0 overflow-auto max-h-96">
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import MovieRequestModal from './MovieRequestModal';
|
||||
import type { MediaStatus } from '../../../server/constants/media';
|
||||
import TvRequestModal from './TvRequestModal';
|
||||
import { useTransition } from 'react-spring';
|
||||
import Transition from '../Transition';
|
||||
|
||||
interface RequestModalProps {
|
||||
show: boolean;
|
||||
@@ -22,49 +22,44 @@ const RequestModal: React.FC<RequestModalProps> = ({
|
||||
onUpdating,
|
||||
onCancel,
|
||||
}) => {
|
||||
const transitions = useTransition(show, null, {
|
||||
from: { opacity: 0, backdropFilter: 'blur(0px)' },
|
||||
enter: { opacity: 1, backdropFilter: 'blur(3px)' },
|
||||
leave: { opacity: 0, backdropFilter: 'blur(0px)' },
|
||||
config: { tension: 500, velocity: 40, friction: 60 },
|
||||
});
|
||||
|
||||
if (type === 'tv') {
|
||||
return (
|
||||
<>
|
||||
{transitions.map(
|
||||
({ props, item, key }) =>
|
||||
item && (
|
||||
<TvRequestModal
|
||||
onComplete={onComplete}
|
||||
onCancel={onCancel}
|
||||
tmdbId={tmdbId}
|
||||
onUpdating={onUpdating}
|
||||
style={props}
|
||||
key={key}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
<Transition
|
||||
enter="transition opacity-0 duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="transition opacity-100 duration-300"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
show={show}
|
||||
>
|
||||
<TvRequestModal
|
||||
onComplete={onComplete}
|
||||
onCancel={onCancel}
|
||||
tmdbId={tmdbId}
|
||||
onUpdating={onUpdating}
|
||||
/>
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{transitions.map(
|
||||
({ props, item, key }) =>
|
||||
item && (
|
||||
<MovieRequestModal
|
||||
onComplete={onComplete}
|
||||
onCancel={onCancel}
|
||||
tmdbId={tmdbId}
|
||||
onUpdating={onUpdating}
|
||||
style={props}
|
||||
key={key}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
<Transition
|
||||
enter="transition opacity-0 duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="transition opacity-100 duration-300"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
show={show}
|
||||
>
|
||||
<MovieRequestModal
|
||||
onComplete={onComplete}
|
||||
onCancel={onCancel}
|
||||
tmdbId={tmdbId}
|
||||
onUpdating={onUpdating}
|
||||
/>
|
||||
</Transition>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import ListView from '../Common/ListView';
|
||||
import { LanguageContext } from '../../context/LanguageContext';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import Header from '../Common/Header';
|
||||
import globalMessages from '../../i18n/globalMessages';
|
||||
|
||||
const messages = defineMessages({
|
||||
searchresults: 'Search Results',
|
||||
@@ -66,25 +65,7 @@ const Search: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="md:flex md:items-center md:justify-between mb-6 sm:mb-0 mt-6">
|
||||
<Header>{intl.formatMessage(messages.searchresults)}</Header>
|
||||
<div className="mt-4 flex md:mt-0 md:ml-4">
|
||||
<span className="relative z-0 inline-flex shadow-sm rounded-md">
|
||||
<button
|
||||
type="button"
|
||||
className="relative inline-flex items-center px-4 py-2 rounded-l-md border border-indigo-900 bg-indigo-500 hover:bg-indigo-400 text-sm leading-5 font-medium text-gray-100 hover:text-white focus:z-10 focus:outline-none focus:border-blue-300 focus:ring-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150"
|
||||
>
|
||||
{intl.formatMessage(globalMessages.movies)}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="-ml-px relative inline-flex items-center px-4 py-2 rounded-r-md border border-indigo-900 bg-indigo-500 text-sm leading-5 font-medium text-gray-100 hover:text-white focus:z-10 focus:outline-none focus:border-blue-300 focus:ring-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150"
|
||||
>
|
||||
{intl.formatMessage(globalMessages.tvshows)}
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<Header>{intl.formatMessage(messages.searchresults)}</Header>
|
||||
<ListView
|
||||
items={titles}
|
||||
isEmpty={isEmpty}
|
||||
|
||||
@@ -6,6 +6,7 @@ import Button from '../../Common/Button';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import Axios from 'axios';
|
||||
import * as Yup from 'yup';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
|
||||
const messages = defineMessages({
|
||||
save: 'Save Changes',
|
||||
@@ -14,10 +15,13 @@ const messages = defineMessages({
|
||||
webhookUrl: 'Webhook URL',
|
||||
validationWebhookUrlRequired: 'You must provide a webhook URL',
|
||||
webhookUrlPlaceholder: 'Server Settings -> Integrations -> Webhooks',
|
||||
discordsettingssaved: 'Discord notification settings saved!',
|
||||
discordsettingsfailed: 'Discord notification settings failed to save.',
|
||||
});
|
||||
|
||||
const NotificationsDiscord: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const { addToast } = useToasts();
|
||||
const { data, error, revalidate } = useSWR(
|
||||
'/api/v1/settings/notifications/discord'
|
||||
);
|
||||
@@ -49,8 +53,15 @@ const NotificationsDiscord: React.FC = () => {
|
||||
webhookUrl: values.webhookUrl,
|
||||
},
|
||||
});
|
||||
addToast(intl.formatMessage(messages.discordsettingssaved), {
|
||||
appearance: 'success',
|
||||
autoDismiss: true,
|
||||
});
|
||||
} catch (e) {
|
||||
// TODO show error
|
||||
addToast(intl.formatMessage(messages.discordsettingsfailed), {
|
||||
appearance: 'error',
|
||||
autoDismiss: true,
|
||||
});
|
||||
} finally {
|
||||
revalidate();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import Button from '../../Common/Button';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import Axios from 'axios';
|
||||
import * as Yup from 'yup';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
|
||||
const messages = defineMessages({
|
||||
save: 'Save Changes',
|
||||
@@ -20,10 +21,13 @@ const messages = defineMessages({
|
||||
enableSsl: 'Enable SSL',
|
||||
authUser: 'Auth User',
|
||||
authPass: 'Auth Pass',
|
||||
emailsettingssaved: 'Email notification settings saved!',
|
||||
emailsettingsfailed: 'Email notification settings failed to save.',
|
||||
});
|
||||
|
||||
const NotificationsEmail: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const { addToast } = useToasts();
|
||||
const { data, error, revalidate } = useSWR(
|
||||
'/api/v1/settings/notifications/email'
|
||||
);
|
||||
@@ -65,14 +69,21 @@ const NotificationsEmail: React.FC = () => {
|
||||
options: {
|
||||
emailFrom: values.emailFrom,
|
||||
smtpHost: values.smtpHost,
|
||||
smtpPort: values.smtpPort,
|
||||
smtpPort: Number(values.smtpPort),
|
||||
secure: values.secure,
|
||||
authUser: values.authUser,
|
||||
authPass: values.authPass,
|
||||
},
|
||||
});
|
||||
addToast(intl.formatMessage(messages.emailsettingssaved), {
|
||||
appearance: 'success',
|
||||
autoDismiss: true,
|
||||
});
|
||||
} catch (e) {
|
||||
// TODO show error
|
||||
addToast(intl.formatMessage(messages.emailsettingsfailed), {
|
||||
appearance: 'error',
|
||||
autoDismiss: true,
|
||||
});
|
||||
} finally {
|
||||
revalidate();
|
||||
}
|
||||
@@ -86,7 +97,7 @@ const NotificationsEmail: React.FC = () => {
|
||||
htmlFor="isDefault"
|
||||
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
|
||||
>
|
||||
Agent Enabled
|
||||
{intl.formatMessage(messages.agentenabled)}
|
||||
</label>
|
||||
<div className="mt-1 sm:mt-0 sm:col-span-2">
|
||||
<Field
|
||||
|
||||
@@ -108,7 +108,7 @@ const RadarrModal: React.FC<RadarrModalProps> = ({
|
||||
{
|
||||
hostname,
|
||||
apiKey,
|
||||
port,
|
||||
port: Number(port),
|
||||
baseUrl,
|
||||
useSsl,
|
||||
}
|
||||
@@ -185,11 +185,11 @@ const RadarrModal: React.FC<RadarrModalProps> = ({
|
||||
const submission = {
|
||||
name: values.name,
|
||||
hostname: values.hostname,
|
||||
port: values.port,
|
||||
port: Number(values.port),
|
||||
apiKey: values.apiKey,
|
||||
useSsl: values.ssl,
|
||||
baseUrl: values.baseUrl,
|
||||
activeProfileId: values.activeProfileId,
|
||||
activeProfileId: Number(values.activeProfileId),
|
||||
activeProfileName: profileName,
|
||||
activeDirectory: values.rootFolder,
|
||||
is4k: values.is4k,
|
||||
|
||||
@@ -78,7 +78,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
|
||||
try {
|
||||
await axios.post('/api/v1/settings/plex', {
|
||||
ip: values.hostname,
|
||||
port: values.port,
|
||||
port: Number(values.port),
|
||||
} as PlexSettings);
|
||||
|
||||
revalidate();
|
||||
|
||||
@@ -111,7 +111,7 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
|
||||
{
|
||||
hostname,
|
||||
apiKey,
|
||||
port,
|
||||
port: Number(port),
|
||||
baseUrl,
|
||||
useSsl,
|
||||
}
|
||||
@@ -188,11 +188,11 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
|
||||
const submission = {
|
||||
name: values.name,
|
||||
hostname: values.hostname,
|
||||
port: values.port,
|
||||
port: Number(values.port),
|
||||
apiKey: values.apiKey,
|
||||
useSsl: values.ssl,
|
||||
baseUrl: values.baseUrl,
|
||||
activeProfileId: values.activeProfileId,
|
||||
activeProfileId: Number(values.activeProfileId),
|
||||
activeProfileName: profileName,
|
||||
activeDirectory: values.rootFolder,
|
||||
is4k: values.is4k,
|
||||
|
||||
@@ -117,7 +117,7 @@ const Slider: React.FC<SliderProps> = ({
|
||||
to: {
|
||||
x: newX,
|
||||
},
|
||||
onFrame: (props) => {
|
||||
onFrame: (props: { x: number }) => {
|
||||
if (containerRef.current) {
|
||||
containerRef.current.scrollLeft = props.x;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ const Slider: React.FC<SliderProps> = ({
|
||||
to: {
|
||||
x: newX,
|
||||
},
|
||||
onFrame: (props) => {
|
||||
onFrame: (props: { x: number }) => {
|
||||
if (containerRef.current) {
|
||||
containerRef.current.scrollLeft = props.x;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
||||
mediaType === 'movie' ? 'bg-blue-500' : 'bg-purple-600'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center text-center text-xs text-white h-4 px-2 py-1 font-normal">
|
||||
<div className="flex items-center text-center text-xs text-white h-4 px-2 py-1 font-normal uppercase">
|
||||
{mediaType === 'movie'
|
||||
? intl.formatMessage(messages.movie)
|
||||
: intl.formatMessage(messages.tvshow)}
|
||||
|
||||
66
src/components/TvDetails/TvCast/index.tsx
Normal file
66
src/components/TvDetails/TvCast/index.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useContext } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
import type { TvDetails } from '../../../../server/models/Tv';
|
||||
import { LanguageContext } from '../../../context/LanguageContext';
|
||||
import Error from '../../../pages/_error';
|
||||
import Header from '../../Common/Header';
|
||||
import LoadingSpinner from '../../Common/LoadingSpinner';
|
||||
import PersonCard from '../../PersonCard';
|
||||
|
||||
const messages = defineMessages({
|
||||
fullseriescast: 'Full Series Cast',
|
||||
});
|
||||
|
||||
const TvCast: React.FC = () => {
|
||||
const router = useRouter();
|
||||
const intl = useIntl();
|
||||
const { locale } = useContext(LanguageContext);
|
||||
const { data, error } = useSWR<TvDetails>(
|
||||
`/api/v1/tv/${router.query.tvId}?language=${locale}`
|
||||
);
|
||||
|
||||
if (!data && !error) {
|
||||
return <LoadingSpinner />;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return <Error statusCode={404} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header
|
||||
subtext={
|
||||
<Link href={`/tv/${data.id}`}>
|
||||
<a className="hover:underline">{data.name}</a>
|
||||
</Link>
|
||||
}
|
||||
>
|
||||
{intl.formatMessage(messages.fullseriescast)}
|
||||
</Header>
|
||||
<ul className="grid grid-cols-2 gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-7 2xl:grid-cols-8">
|
||||
{data?.credits.cast.map((person) => {
|
||||
return (
|
||||
<li
|
||||
key={person.id}
|
||||
className="col-span-1 flex flex-col text-center items-center"
|
||||
>
|
||||
<PersonCard
|
||||
name={person.name}
|
||||
personId={person.id}
|
||||
subName={person.character}
|
||||
profilePath={person.profilePath}
|
||||
canExpand
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default TvCast;
|
||||
@@ -478,6 +478,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
items={data?.credits.cast.slice(0, 20).map((person) => (
|
||||
<PersonCard
|
||||
key={`cast-item-${person.id}`}
|
||||
personId={person.id}
|
||||
name={person.name}
|
||||
subName={person.character}
|
||||
profilePath={person.profilePath}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
|
||||
export type AvailableLocales = 'en' | 'ja' | 'fr';
|
||||
export type AvailableLocales =
|
||||
| 'en'
|
||||
| 'ja'
|
||||
| 'fr'
|
||||
| 'nb-NO'
|
||||
| 'de'
|
||||
| 'ru'
|
||||
| 'nl';
|
||||
|
||||
interface LanguageContextProps {
|
||||
locale: AvailableLocales;
|
||||
|
||||
@@ -15,11 +15,11 @@ const useClickOutside = (
|
||||
): void => {
|
||||
useEffect(() => {
|
||||
const handleBodyClick = (e: MouseEvent) => {
|
||||
if (!ref.current?.contains(e.target as Node)) {
|
||||
if (ref.current && !ref.current.contains(e.target as Node)) {
|
||||
callback(e);
|
||||
}
|
||||
};
|
||||
document.body.addEventListener('click', handleBodyClick);
|
||||
document.body.addEventListener('click', handleBodyClick, { capture: true });
|
||||
|
||||
return () => {
|
||||
document.body.removeEventListener('click', handleBodyClick);
|
||||
|
||||
@@ -7,6 +7,10 @@ import type { Nullable } from '../utils/typeHelpers';
|
||||
|
||||
type Url = string | UrlObject;
|
||||
|
||||
const encodeURIExtraParams = (string: string): string => {
|
||||
return encodeURIComponent(string).replace(/!/g, '%21');
|
||||
};
|
||||
|
||||
interface SearchObject {
|
||||
searchValue: string;
|
||||
searchOpen: boolean;
|
||||
@@ -35,14 +39,17 @@ const useSearchInput = (): SearchObject => {
|
||||
if (router.pathname.startsWith('/search')) {
|
||||
router.replace({
|
||||
pathname: router.pathname,
|
||||
query: { ...router.query, query: debouncedValue },
|
||||
query: {
|
||||
...router.query,
|
||||
query: encodeURIExtraParams(debouncedValue),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
setLastRoute(router.asPath);
|
||||
router
|
||||
.push({
|
||||
pathname: '/search',
|
||||
query: { query: debouncedValue },
|
||||
query: { query: encodeURIExtraParams(debouncedValue) },
|
||||
})
|
||||
.then(() => window.scrollTo(0, 0));
|
||||
}
|
||||
@@ -85,8 +92,12 @@ const useSearchInput = (): SearchObject => {
|
||||
* is on /search
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (router.query.query !== debouncedValue) {
|
||||
setSearchValue((router.query.query as string) ?? '');
|
||||
if (router.query.query !== encodeURIExtraParams(debouncedValue)) {
|
||||
setSearchValue(
|
||||
router.query.query
|
||||
? decodeURIComponent(router.query.query as string)
|
||||
: ''
|
||||
);
|
||||
|
||||
if (!router.pathname.startsWith('/search') && !router.query.query) {
|
||||
setIsOpen(false);
|
||||
|
||||
308
src/i18n/locale/de.json
Normal file
308
src/i18n/locale/de.json
Normal file
@@ -0,0 +1,308 @@
|
||||
{
|
||||
"components.Discover.discovermovies": "Beliebte Filme",
|
||||
"components.Discover.discovertv": "Beliebte Serie",
|
||||
"components.Discover.nopending": "Keine ausstehenden Anträge",
|
||||
"components.Discover.popularmovies": "Beliebte Filme",
|
||||
"components.Discover.populartv": "Beliebte Serie",
|
||||
"components.Discover.recentlyAdded": "Kürzlich hinzugefügt",
|
||||
"components.Discover.recentrequests": "Letzte Anträge",
|
||||
"components.Discover.trending": "Trends",
|
||||
"components.Discover.upcoming": "Bald erscheinende Filme",
|
||||
"components.Discover.upcomingmovies": "Bald erscheinende Filme",
|
||||
"components.Layout.LanguagePicker.changelanguage": "Sprache ändern",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "Nach Filme und Fernsehsendungen suchen",
|
||||
"components.Layout.Sidebar.dashboard": "Entdecken",
|
||||
"components.Layout.Sidebar.requests": "Anträge",
|
||||
"components.Layout.Sidebar.settings": "Einstellungen",
|
||||
"components.Layout.Sidebar.users": "Benutzer",
|
||||
"components.Layout.UserDropdown.signout": "Abmelden",
|
||||
"components.Layout.alphawarning": "Dies ist ALPHA-Software. Fast alles muss fast kaputt und/oder instabil sein. Bitte melden Sie Probleme auf der GitHub-Seite!",
|
||||
"components.Login.signinplex": "Melden Sie sich an, um fortzufahren",
|
||||
"components.MovieDetails.approve": "Genehmigen",
|
||||
"components.MovieDetails.available": "Verfügbar",
|
||||
"components.MovieDetails.budget": "Budget",
|
||||
"components.MovieDetails.cancelrequest": "Antrag abbrechen",
|
||||
"components.MovieDetails.cast": "Besetzung",
|
||||
"components.MovieDetails.decline": "Ablehnen",
|
||||
"components.MovieDetails.manageModalClearMedia": "Alle Mediendaten löschen",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "Dadurch werden alle Mediendaten einschließlich aller Anträge für dieses Element entfernt. Diese Aktion ist irreversibel. Wenn dieses Element in Ihrer Plex-Bibliothek vorhanden ist, werden die Medieninformationen bei der nächsten Synchronisierung neu erstellt.",
|
||||
"components.MovieDetails.manageModalNoRequests": "Keine Anträge",
|
||||
"components.MovieDetails.manageModalRequests": "Anträge",
|
||||
"components.MovieDetails.manageModalTitle": "Filme verwalten",
|
||||
"components.MovieDetails.originallanguage": "Originalsprache",
|
||||
"components.MovieDetails.overview": "Übersicht",
|
||||
"components.MovieDetails.overviewunavailable": "Übersicht nicht verfügbar",
|
||||
"components.MovieDetails.pending": "Ausstehend",
|
||||
"components.MovieDetails.recommendations": "Empfehlungen",
|
||||
"components.MovieDetails.recommendationssubtext": "Wenn Ihnen {title} gefallen hat, könnte Ihnen auch gefallen …",
|
||||
"components.MovieDetails.releasedate": "Erscheinungsdatum",
|
||||
"components.MovieDetails.request": "Antrag",
|
||||
"components.MovieDetails.revenue": "Einnahmen",
|
||||
"components.MovieDetails.runtime": "{minutes} Minuten",
|
||||
"components.MovieDetails.similar": "Ähnliche Titel",
|
||||
"components.MovieDetails.similarsubtext": "Andere Filme, die {title} ähneln",
|
||||
"components.MovieDetails.status": "Status",
|
||||
"components.MovieDetails.unavailable": "Nicht verfügbar",
|
||||
"components.MovieDetails.userrating": "Benutzerbewertung",
|
||||
"components.MovieDetails.viewrequest": "Antrag anzeigen",
|
||||
"components.PersonDetails.appearsin": "Erscheint in",
|
||||
"components.PersonDetails.ascharacter": "als {character}",
|
||||
"components.PersonDetails.nobiography": "Keine Biografie verfügbar.",
|
||||
"components.PlexLoginButton.loading": "Wird geladen …",
|
||||
"components.PlexLoginButton.loggingin": "Wird angemeldet …",
|
||||
"components.PlexLoginButton.loginwithplex": "Anmeldung mit Plex",
|
||||
"components.RequestBlock.seasons": "Staffeln",
|
||||
"components.RequestCard.all": "Alle",
|
||||
"components.RequestCard.requestedby": "Antrag von {username}",
|
||||
"components.RequestCard.seasons": "Staffeln",
|
||||
"components.RequestList.RequestItem.notavailable": "entf.",
|
||||
"components.RequestList.RequestItem.requestedby": "Antrag von {username}",
|
||||
"components.RequestList.RequestItem.seasons": "Staffeln",
|
||||
"components.RequestList.mediaInfo": "Medieninfos",
|
||||
"components.RequestList.modifiedBy": "Zuletzt geändert von",
|
||||
"components.RequestList.next": "Nächste",
|
||||
"components.RequestList.previous": "Vorherige",
|
||||
"components.RequestList.requestedAt": "Antrag erstellt am",
|
||||
"components.RequestList.requests": "Anträge",
|
||||
"components.RequestList.showingresults": "Anzeigen von <strong>{from}</strong> bis <strong> {to} </strong> von <strong> {total} </strong> Ergebnissen",
|
||||
"components.RequestList.status": "Status",
|
||||
"components.RequestModal.cancel": "Antrag abbrechen",
|
||||
"components.RequestModal.cancelling": "Abbrechen …",
|
||||
"components.RequestModal.cancelrequest": "Dadurch wird Ihre Antrag entfernt. Sind Sie sicher, dass Sie weitermachen wollen?",
|
||||
"components.RequestModal.close": "Schließen",
|
||||
"components.RequestModal.extras": "Extras",
|
||||
"components.RequestModal.notrequested": "Nicht angefordert",
|
||||
"components.RequestModal.numberofepisodes": "Anzahl der Folgen",
|
||||
"components.RequestModal.pendingrequest": "Ausstehender Antrag für {title}",
|
||||
"components.RequestModal.request": "Antrag",
|
||||
"components.RequestModal.requestCancel": "Antrag für <strong>{title}</strong> storniert",
|
||||
"components.RequestModal.requestSuccess": "<strong>{title}</strong> angefordert.",
|
||||
"components.RequestModal.requestadmin": "Ihr Antrag wird sofort genehmigt.",
|
||||
"components.RequestModal.requestfrom": "Derzeit ist ein Antrag von {username} ausstehend",
|
||||
"components.RequestModal.requesting": "Antrag wird erstellt …",
|
||||
"components.RequestModal.requestseasons": "{seasonCount} {seasonCount, plural, one {Season} other {Seasons}} anfordern",
|
||||
"components.RequestModal.requesttitle": "{title} anfordern",
|
||||
"components.RequestModal.season": "Staffel",
|
||||
"components.RequestModal.seasonnumber": "Staffel {number}",
|
||||
"components.RequestModal.selectseason": "Staffel(n) auswählen",
|
||||
"components.RequestModal.status": "Status",
|
||||
"components.Search.searchresults": "Suchergebnisse",
|
||||
"components.Settings.Notifications.agentenabled": "Agent aktiviert",
|
||||
"components.Settings.Notifications.authPass": "Authentifizierungspasswort",
|
||||
"components.Settings.Notifications.authUser": "Authentifizierungsbenutzername",
|
||||
"components.Settings.Notifications.emailsender": "E-Mail-Absenderadresse",
|
||||
"components.Settings.Notifications.enableSsl": "SSL aktivieren",
|
||||
"components.Settings.Notifications.save": "Änderungen speichern",
|
||||
"components.Settings.Notifications.saving": "Speichern …",
|
||||
"components.Settings.Notifications.smtpHost": "SMTP-Host",
|
||||
"components.Settings.Notifications.smtpPort": "SMTP-Port",
|
||||
"components.Settings.Notifications.validationFromRequired": "Sie müssen eine E-Mail-Absenderadresse angeben",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "Sie müssen einen SMTP-Host bereitstellen",
|
||||
"components.Settings.Notifications.validationSmtpPortRequired": "Sie müssen einen SMTP-Port bereitstellen",
|
||||
"components.Settings.Notifications.validationWebhookUrlRequired": "Sie müssen eine Webhook-URL angeben",
|
||||
"components.Settings.Notifications.webhookUrl": "Webhook-URL",
|
||||
"components.Settings.Notifications.webhookUrlPlaceholder": "Servereinstellungen -> Integrationen -> Webhooks",
|
||||
"components.Settings.RadarrModal.add": "Server hinzufügen",
|
||||
"components.Settings.RadarrModal.apiKey": "API-Schlüssel",
|
||||
"components.Settings.RadarrModal.apiKeyPlaceholder": "Ihr Radarr-API-Schlüssel",
|
||||
"components.Settings.RadarrModal.baseUrl": "Basis-URL",
|
||||
"components.Settings.RadarrModal.baseUrlPlaceholder": "Beispiel: /radarr",
|
||||
"components.Settings.RadarrModal.createradarr": "Einen neuen Radarr-Server erstellen",
|
||||
"components.Settings.RadarrModal.defaultserver": "Standardserver",
|
||||
"components.Settings.RadarrModal.editradarr": "Radarr-Server bearbeiten",
|
||||
"components.Settings.RadarrModal.hostname": "Hostname",
|
||||
"components.Settings.RadarrModal.minimumAvailability": "Mindestverfügbarkeit",
|
||||
"components.Settings.RadarrModal.port": "Port",
|
||||
"components.Settings.RadarrModal.qualityprofile": "Qualitätsprofil",
|
||||
"components.Settings.RadarrModal.rootfolder": "Stammordner",
|
||||
"components.Settings.RadarrModal.save": "Änderungen speichern",
|
||||
"components.Settings.RadarrModal.saving": "Speichern …",
|
||||
"components.Settings.RadarrModal.selectMinimumAvailability": "Wählen Sie die Mindestverfügbarkeit",
|
||||
"components.Settings.RadarrModal.selectQualityProfile": "Wählen Sie ein Qualitätsprofil",
|
||||
"components.Settings.RadarrModal.selectRootFolder": "Wählen Sie einen Stammordner",
|
||||
"components.Settings.RadarrModal.server4k": "4K-Server",
|
||||
"components.Settings.RadarrModal.servername": "Servername",
|
||||
"components.Settings.RadarrModal.servernamePlaceholder": "Ein Radarr-Server",
|
||||
"components.Settings.RadarrModal.ssl": "SSL",
|
||||
"components.Settings.RadarrModal.test": "Test",
|
||||
"components.Settings.RadarrModal.testing": "Testen …",
|
||||
"components.Settings.RadarrModal.toastRadarrTestFailure": "Verbindung zum Radarr-Server fehlgeschlagen",
|
||||
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Radarr-Verbindung hergestellt!",
|
||||
"components.Settings.RadarrModal.validationApiKeyRequired": "Sie müssen einen API-Schlüssel angeben",
|
||||
"components.Settings.RadarrModal.validationHostnameRequired": "Sie müssen einen Hostnamen/IP angeben",
|
||||
"components.Settings.RadarrModal.validationPortRequired": "Sie müssen einen Port angeben",
|
||||
"components.Settings.RadarrModal.validationProfileRequired": "Sie müssen ein Profil auswählen",
|
||||
"components.Settings.RadarrModal.validationRootFolderRequired": "Sie müssen einen Stammordner auswählen",
|
||||
"components.Settings.SonarrModal.add": "Server hinzufügen",
|
||||
"components.Settings.SonarrModal.apiKey": "API-Schlüssel",
|
||||
"components.Settings.SonarrModal.apiKeyPlaceholder": "Ihr Sonarr-API-Schlüssel",
|
||||
"components.Settings.SonarrModal.baseUrl": "Basis-URL",
|
||||
"components.Settings.SonarrModal.baseUrlPlaceholder": "Beispiel: /sonarr",
|
||||
"components.Settings.SonarrModal.createsonarr": "Neuen Sonarr-Server erstellen",
|
||||
"components.Settings.SonarrModal.defaultserver": "Standardserver",
|
||||
"components.Settings.SonarrModal.editsonarr": "Sonarr-Server bearbeiten",
|
||||
"components.Settings.SonarrModal.hostname": "Hostname",
|
||||
"components.Settings.SonarrModal.port": "Port",
|
||||
"components.Settings.SonarrModal.qualityprofile": "Qualitätsprofil",
|
||||
"components.Settings.SonarrModal.rootfolder": "Stammordner",
|
||||
"components.Settings.SonarrModal.save": "Änderungen speichern",
|
||||
"components.Settings.SonarrModal.saving": "Speichern …",
|
||||
"components.Settings.SonarrModal.seasonfolders": "Staffelnordner",
|
||||
"components.Settings.SonarrModal.selectQualityProfile": "Wählen Sie ein Qualitätsprofil",
|
||||
"components.Settings.SonarrModal.selectRootFolder": "Wählen Sie einen Stammordner",
|
||||
"components.Settings.SonarrModal.server4k": "4K-Server",
|
||||
"components.Settings.SonarrModal.servername": "Servername",
|
||||
"components.Settings.SonarrModal.servernamePlaceholder": "Ein Sonarr-Server",
|
||||
"components.Settings.SonarrModal.ssl": "SSL",
|
||||
"components.Settings.SonarrModal.test": "Test",
|
||||
"components.Settings.SonarrModal.testing": "Testen …",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "Es konnte keine Verbindung zu Sonarr-Server hergestellt werden",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Sonarr-Verbindung hergestellt!",
|
||||
"components.Settings.SonarrModal.validationApiKeyRequired": "Sie müssen einen API-Schlüssel angeben",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "Sie müssen einen Hostnamen/IP angeben",
|
||||
"components.Settings.SonarrModal.validationPortRequired": "Sie müssen einen Port angeben",
|
||||
"components.Settings.SonarrModal.validationProfileRequired": "Sie müssen ein Profil auswählen",
|
||||
"components.Settings.SonarrModal.validationRootFolderRequired": "Sie müssen einen Stammordner auswählen",
|
||||
"components.Settings.activeProfile": "Aktives Profil",
|
||||
"components.Settings.addradarr": "Radarr-Server hinzufügen",
|
||||
"components.Settings.address": "Adresse",
|
||||
"components.Settings.addsonarr": "Sonarr-Server hinzufügen",
|
||||
"components.Settings.apikey": "API-Schlüssel",
|
||||
"components.Settings.applicationurl": "Anwendungs-URL",
|
||||
"components.Settings.cancelscan": "Scan abbrechen",
|
||||
"components.Settings.copied": "Kopierter API-Schlüssel in die Zwischenablage",
|
||||
"components.Settings.currentlibrary": "Aktuelle Bibliothek: {name}",
|
||||
"components.Settings.default": "Standardmäßig",
|
||||
"components.Settings.default4k": "Standard-4K",
|
||||
"components.Settings.delete": "Löschen",
|
||||
"components.Settings.deleteserverconfirm": "Sind Sie sicher, dass Sie diesen Server löschen möchten?",
|
||||
"components.Settings.edit": "Bearbeiten",
|
||||
"components.Settings.generalsettings": "Allgemeine Einstellungen",
|
||||
"components.Settings.generalsettingsDescription": "Dies sind Einstellungen, die sich auf die allgemeine Overseerr-Konfiguration beziehen.",
|
||||
"components.Settings.hostname": "Hostname/IP",
|
||||
"components.Settings.jobname": "Auftragsname",
|
||||
"components.Settings.librariesRemaining": "Verbleibende Bibliotheken: {count}",
|
||||
"components.Settings.manualscan": "Manueller Bibliotheksscan",
|
||||
"components.Settings.manualscanDescription": "Normalerweise wird dies nur einmal alle 6 Stunden ausgeführt. Overseerr überprüft die kürzlich hinzugefügten Plex-Server aggressiver. Wenn Sie Plex zum ersten Mal konfigurieren, wird ein einmaliger vollständiger manueller Bibliotheksscan empfohlen!",
|
||||
"components.Settings.menuAbout": "Über",
|
||||
"components.Settings.menuGeneralSettings": "Allgemeine Einstellungen",
|
||||
"components.Settings.menuJobs": "Anträge",
|
||||
"components.Settings.menuLogs": "Protokolle",
|
||||
"components.Settings.menuNotifications": "Benachrichtigungen",
|
||||
"components.Settings.menuPlexSettings": "Plex",
|
||||
"components.Settings.menuServices": "Dienste",
|
||||
"components.Settings.nextexecution": "Nächste Ausführung",
|
||||
"components.Settings.notificationsettings": "Benachrichtigungseinstellungen",
|
||||
"components.Settings.notificationsettingsDescription": "Hier können Sie auswählen, welche Arten von Benachrichtigungen gesendet werden sollen und über welche Arten von Diensten.",
|
||||
"components.Settings.notrunning": "Nicht aktiv",
|
||||
"components.Settings.plexlibraries": "Plex-Bibliotheken",
|
||||
"components.Settings.plexlibrariesDescription": "Die Bibliotheken-Overseerr sucht nach Titeln. Richten Sie Ihre Plex-Verbindungseinstellungen ein und speichern Sie sie, und klicken Sie auf die Schaltfläche unten, wenn keine aufgeführt sind.",
|
||||
"components.Settings.plexsettings": "Plex-Einstellungen",
|
||||
"components.Settings.plexsettingsDescription": "Konfigurieren Sie die Einstellungen für Ihren Plex-Server. Overseerr verwendet Ihren Plex-Server, um Ihre Bibliothek in regelmäßigen Abständen zu scannen und festzustellen, welche Inhalte verfügbar sind.",
|
||||
"components.Settings.port": "Port",
|
||||
"components.Settings.radarrSettingsDescription": "Richten Sie unten Ihre Radarr-Verbindung ein. Sie können jederzeit mehrere, aber nur zwei standardmäßig aktiv haben (eine für Standard-HD und eine für 4K). Administratoren können überschreiben, welcher Server für neue Anforderungen verwendet wird.",
|
||||
"components.Settings.radarrsettings": "Radarr-Einstellungen",
|
||||
"components.Settings.runnow": "Jetzt ausführen",
|
||||
"components.Settings.save": "Änderungen speichern",
|
||||
"components.Settings.saving": "Speichern …",
|
||||
"components.Settings.servername": "Servername (automatisch festgelegt)",
|
||||
"components.Settings.servernamePlaceholder": "Plex-Servername",
|
||||
"components.Settings.sonarrSettingsDescription": "Richten Sie unten Ihre Sonarr-Verbindung ein. Sie können jederzeit mehrere, aber nur zwei standardmäßig aktiv haben (eine für Standard-HD und eine für 4K). Administratoren können überschreiben, welcher Server für neue Anforderungen verwendet wird.",
|
||||
"components.Settings.sonarrsettings": "Sonarr-Einstellungen",
|
||||
"components.Settings.ssl": "SSL",
|
||||
"components.Settings.startscan": "Scan starten",
|
||||
"components.Settings.sync": "Plex-Bibliotheken synchronisieren",
|
||||
"components.Settings.syncing": "Synchronisierung …",
|
||||
"components.Setup.configureplex": "Plex konfigurieren",
|
||||
"components.Setup.configureservices": "Dienste konfigurieren",
|
||||
"components.Setup.continue": "Fortfahren",
|
||||
"components.Setup.finish": "Konfiguration beenden",
|
||||
"components.Setup.finishing": "Fertigstellung …",
|
||||
"components.Setup.loginwithplex": "Anmeldung mit Plex",
|
||||
"components.Setup.signinMessage": "Melden Sie sich zunächst mit Ihrem Plex-Konto an",
|
||||
"components.Setup.welcome": "Willkommen bei Overseerr",
|
||||
"components.Slider.noresults": "Keine Ergebnisse",
|
||||
"components.TitleCard.movie": "Film",
|
||||
"components.TitleCard.tvshow": "Serie",
|
||||
"components.TvDetails.approve": "Genehmigen",
|
||||
"components.TvDetails.approverequests": "{requestCount} {requestCount, plural, one {Request} other {Requests}} genehmigen",
|
||||
"components.TvDetails.available": "Verfügbar",
|
||||
"components.TvDetails.cancelrequest": "Antrag abbrechen",
|
||||
"components.TvDetails.cast": "Besetzung",
|
||||
"components.TvDetails.decline": "Ablehnen",
|
||||
"components.TvDetails.declinerequests": "{requestCount} {requestCount, plural, one {Request} andere {Requests}} ablehnen",
|
||||
"components.TvDetails.manageModalClearMedia": "Alle Mediendaten löschen",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "Dadurch werden alle Mediendaten einschließlich aller Anträge für dieses Element irreversibel entfernt. Wenn dieses Element in Ihrer Plex-Bibliothek vorhanden ist, werden die Medieninformationen bei der nächsten Synchronisierung neu erstellt.",
|
||||
"components.TvDetails.manageModalNoRequests": "Keine Anträge",
|
||||
"components.TvDetails.manageModalRequests": "Anträge",
|
||||
"components.TvDetails.manageModalTitle": "Serien verwalten",
|
||||
"components.TvDetails.originallanguage": "Originalsprache",
|
||||
"components.TvDetails.overview": "Übersicht",
|
||||
"components.TvDetails.overviewunavailable": "Übersicht nicht verfügbar",
|
||||
"components.TvDetails.pending": "Ausstehend",
|
||||
"components.TvDetails.recommendations": "Empfehlungen",
|
||||
"components.TvDetails.recommendationssubtext": "Wenn Ihnen {title} gefallen hat, könnte Ihnen auch gefallen …",
|
||||
"components.TvDetails.request": "Antrag",
|
||||
"components.TvDetails.requestmore": "Mehr anfordern",
|
||||
"components.TvDetails.similar": "Ähnliche Serien",
|
||||
"components.TvDetails.similarsubtext": "Andere Serien {title} ähnlich",
|
||||
"components.TvDetails.status": "Status",
|
||||
"components.TvDetails.unavailable": "Nicht verfügbar",
|
||||
"components.TvDetails.userrating": "Benutzerbewertung",
|
||||
"components.UserEdit.admin": "Administrator/in",
|
||||
"components.UserEdit.adminDescription": "Voller Administratorzugriff. Umgeht alle Berechtigungsprüfungen.",
|
||||
"components.UserEdit.autoapprove": "Automatische Genehmigung",
|
||||
"components.UserEdit.autoapproveDescription": "Gewährt die automatische Genehmigung für alle Anträge dieses Benutzers.",
|
||||
"components.UserEdit.avatar": "Avatar",
|
||||
"components.UserEdit.edituser": "Benutzer/in bearbeiten",
|
||||
"components.UserEdit.email": "E-Mail",
|
||||
"components.UserEdit.managerequests": "Anträge verwalten",
|
||||
"components.UserEdit.managerequestsDescription": "Erteilt die Berechtigung zum Verwalten von Overseerr-Anträgen. Dies umfasst das Genehmigen und Ablehnen von Anträgen.",
|
||||
"components.UserEdit.permissions": "Berechtigungen",
|
||||
"components.UserEdit.request": "Antrag",
|
||||
"components.UserEdit.requestDescription": "Erteilt die Berechtigung zum Anfordern von Filmen und Serien.",
|
||||
"components.UserEdit.save": "Speichern",
|
||||
"components.UserEdit.saving": "Speichern …",
|
||||
"components.UserEdit.settings": "Einstellungen verwalten",
|
||||
"components.UserEdit.settingsDescription": "Erteilt die Berechtigung zum Ändern aller Overseerr-Einstellungen. Ein/e Benutzer/in muss über diese Berechtigung verfügen, um sie anderen Personen erteilen zu können.",
|
||||
"components.UserEdit.userfail": "Beim Speichern des Benutzers ist ein Fehler aufgetreten.",
|
||||
"components.UserEdit.username": "Benutzername",
|
||||
"components.UserEdit.users": "Benutzer verwalten",
|
||||
"components.UserEdit.usersDescription": "Erteilt die Berechtigung zum Verwalten von Overseerr-Benutzern. Benutzer/innen mit dieser Berechtigung können Benutzer/innen mit Administratorrechten nicht ändern oder gewähren.",
|
||||
"components.UserEdit.usersaved": "Benutzer/in gespeichert",
|
||||
"components.UserEdit.vote": "Abstimmen",
|
||||
"components.UserEdit.voteDescription": "Erteilt die Erlaubnis, über Anträge abzustimmen (Abstimmung noch nicht durchgeführt)",
|
||||
"components.UserList.admin": "Admin",
|
||||
"components.UserList.created": "Erstellt",
|
||||
"components.UserList.delete": "Löschen",
|
||||
"components.UserList.edit": "Bearbeiten",
|
||||
"components.UserList.lastupdated": "Zuletzt aktualisiert",
|
||||
"components.UserList.plexuser": "Plex-Benutzer/in",
|
||||
"components.UserList.role": "Rolle",
|
||||
"components.UserList.totalrequests": "Anträge insgesamt",
|
||||
"components.UserList.user": "Benutzer/in",
|
||||
"components.UserList.userlist": "Benutzer/innen-Liste",
|
||||
"components.UserList.username": "Benutzername",
|
||||
"components.UserList.usertype": "Benutzertyp",
|
||||
"i18n.approve": "Genehmigen",
|
||||
"i18n.approved": "Genehmigt",
|
||||
"i18n.available": "Verfügbar",
|
||||
"i18n.cancel": "Abbrechen",
|
||||
"i18n.decline": "Ablehnen",
|
||||
"i18n.declined": "Abgelehnt",
|
||||
"i18n.delete": "Löschen",
|
||||
"i18n.movies": "Films",
|
||||
"i18n.partiallyavailable": "Teilweise verfügbar",
|
||||
"i18n.pending": "Ausstehend",
|
||||
"i18n.processing": "Verarbeitung …",
|
||||
"i18n.tvshows": "Serien",
|
||||
"i18n.unavailable": "Nicht verfügbar",
|
||||
"pages.internalServerError": "{statusCode} – Interner Serverfehler",
|
||||
"pages.oops": "Hoppla",
|
||||
"pages.pageNotFound": "404 – Seite nicht gefunden",
|
||||
"pages.returnHome": "Zur Starseite",
|
||||
"pages.serviceUnavailable": "{statusCode} – Dienst nicht verfügbar",
|
||||
"pages.somethingWentWrong": "{statusCode} – Es ist ein Fehler aufgetreten",
|
||||
"components.TvDetails.TvCast.fullseriescast": "Vollserienbesetzung",
|
||||
"components.MovieDetails.MovieCast.fullcast": "Vollständige Besetzung"
|
||||
}
|
||||
@@ -16,8 +16,9 @@
|
||||
"components.Layout.Sidebar.settings": "Settings",
|
||||
"components.Layout.Sidebar.users": "Users",
|
||||
"components.Layout.UserDropdown.signout": "Sign Out",
|
||||
"components.Layout.alphawarning": "This is ALPHA software. Almost everything is bound to be nearly broken and/or unstable. Please report issues to the Overseerr Github!",
|
||||
"components.Layout.alphawarning": "This is ALPHA software. Almost everything is bound to be nearly broken and/or unstable. Please report issues to the Overseerr GitHub!",
|
||||
"components.Login.signinplex": "Sign in to continue",
|
||||
"components.MovieDetails.MovieCast.fullcast": "Full Cast",
|
||||
"components.MovieDetails.approve": "Approve",
|
||||
"components.MovieDetails.available": "Available",
|
||||
"components.MovieDetails.budget": "Budget",
|
||||
@@ -25,7 +26,7 @@
|
||||
"components.MovieDetails.cast": "Cast",
|
||||
"components.MovieDetails.decline": "Decline",
|
||||
"components.MovieDetails.manageModalClearMedia": "Clear All Media Data",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "This will remove all media data including all requests for this item. This action is irreversible. If this item exists in your Plex library, the media information will be recreated next sync.",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "This will remove all media data including all requests for this item irreversibly. If this item exists in your Plex library, the media info will be recreated next sync.",
|
||||
"components.MovieDetails.manageModalNoRequests": "No Requests",
|
||||
"components.MovieDetails.manageModalRequests": "Requests",
|
||||
"components.MovieDetails.manageModalTitle": "Manage Movie",
|
||||
@@ -45,10 +46,14 @@
|
||||
"components.MovieDetails.unavailable": "Unavailable",
|
||||
"components.MovieDetails.userrating": "User Rating",
|
||||
"components.MovieDetails.viewrequest": "View Request",
|
||||
"components.PersonDetails.appearsin": "Appears in",
|
||||
"components.PersonDetails.ascharacter": "as {character}",
|
||||
"components.PersonDetails.nobiography": "No biography available.",
|
||||
"components.PlexLoginButton.loading": "Loading...",
|
||||
"components.PlexLoginButton.loggingin": "Logging in...",
|
||||
"components.PlexLoginButton.loginwithplex": "Login with Plex",
|
||||
"components.RequestBlock.seasons": "Seasons",
|
||||
"components.RequestCard.all": "All",
|
||||
"components.RequestCard.requestedby": "Requested by {username}",
|
||||
"components.RequestCard.seasons": "Seasons",
|
||||
"components.RequestList.RequestItem.notavailable": "N/A",
|
||||
@@ -72,10 +77,10 @@
|
||||
"components.RequestModal.pendingrequest": "Pending request for {title}",
|
||||
"components.RequestModal.request": "Request",
|
||||
"components.RequestModal.requestCancel": "Request for <strong>{title}</strong> cancelled",
|
||||
"components.RequestModal.requestSuccess": "<strong>{title}</strong> successfully requested!",
|
||||
"components.RequestModal.requestSuccess": "<strong>{title}</strong> requested.",
|
||||
"components.RequestModal.requestadmin": "Your request will be immediately approved.",
|
||||
"components.RequestModal.requestfrom": "There is currently a pending request from {username}",
|
||||
"components.RequestModal.requesting": "Requesting...",
|
||||
"components.RequestModal.requesting": "Requesting…",
|
||||
"components.RequestModal.requestseasons": "Request {seasonCount} {seasonCount, plural, one {Season} other {Seasons}}",
|
||||
"components.RequestModal.requesttitle": "Request {title}",
|
||||
"components.RequestModal.season": "Season",
|
||||
@@ -86,7 +91,11 @@
|
||||
"components.Settings.Notifications.agentenabled": "Agent Enabled",
|
||||
"components.Settings.Notifications.authPass": "Auth Pass",
|
||||
"components.Settings.Notifications.authUser": "Auth User",
|
||||
"components.Settings.Notifications.discordsettingsfailed": "Discord notification settings failed to save.",
|
||||
"components.Settings.Notifications.discordsettingssaved": "Discord notification settings saved!",
|
||||
"components.Settings.Notifications.emailsender": "Email Sender Address",
|
||||
"components.Settings.Notifications.emailsettingsfailed": "Email notification settings failed to save.",
|
||||
"components.Settings.Notifications.emailsettingssaved": "Email notification settings saved!",
|
||||
"components.Settings.Notifications.enableSsl": "Enable SSL",
|
||||
"components.Settings.Notifications.save": "Save Changes",
|
||||
"components.Settings.Notifications.saving": "Saving...",
|
||||
@@ -152,7 +161,7 @@
|
||||
"components.Settings.SonarrModal.ssl": "SSL",
|
||||
"components.Settings.SonarrModal.test": "Test",
|
||||
"components.Settings.SonarrModal.testing": "Testing...",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "Failed to connect to Sonarr Server",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "Could not connect to Sonarr Server",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Sonarr connection established!",
|
||||
"components.Settings.SonarrModal.validationApiKeyRequired": "You must provide an API key",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "You must provide a hostname/IP",
|
||||
@@ -192,23 +201,23 @@
|
||||
"components.Settings.notificationsettingsDescription": "Here you can pick and choose what types of notifications to send and through what types of services.",
|
||||
"components.Settings.notrunning": "Not Running",
|
||||
"components.Settings.plexlibraries": "Plex Libraries",
|
||||
"components.Settings.plexlibrariesDescription": "These are the libraries Overseerr will scan for titles. If you see no libraries listed, you will need to run at least one sync by clicking the button below. You must first configure and save your plex connection settings before you will be able to retrieve your libraries.",
|
||||
"components.Settings.plexlibrariesDescription": "The libraries Overseerr scans for titles. Set up and save your Plex connection settings and click the button below if none are listed.",
|
||||
"components.Settings.plexsettings": "Plex Settings",
|
||||
"components.Settings.plexsettingsDescription": "Configure the settings for your Plex server. Overseerr uses your Plex server to scan your library at an interval and see what content is available.",
|
||||
"components.Settings.port": "Port",
|
||||
"components.Settings.radarrSettingsDescription": "Configure your Radarr connection below. You can have multiple Radarr configurations but only two can be active as defaults at any time (one for standard HD and one for 4K). Administrators can override which server will be used when a new request is made.",
|
||||
"components.Settings.radarrSettingsDescription": "Set up your Radarr connection below. You can have multiple, but only two active as defaults at any time (one for standard HD, and one for 4K). Administrators can override which server is used for new requests.",
|
||||
"components.Settings.radarrsettings": "Radarr Settings",
|
||||
"components.Settings.runnow": "Run Now",
|
||||
"components.Settings.save": "Save Changes",
|
||||
"components.Settings.saving": "Saving...",
|
||||
"components.Settings.servername": "Server Name (Automatically Set)",
|
||||
"components.Settings.servernamePlaceholder": "Plex Server Name",
|
||||
"components.Settings.sonarrSettingsDescription": "Configure your Sonarr connection below. You can have multiple Sonarr configurations but only two can be active as defaults at any time (one for standard HD and one for 4K). Administrators can override which server will be used when a new request is made.",
|
||||
"components.Settings.sonarrSettingsDescription": "Set up your Sonarr connection below. You can have multiple, but only two active as defaults at any time (one for standard HD and one for 4K). Administrators can override which server is used for new requests.",
|
||||
"components.Settings.sonarrsettings": "Sonarr Settings",
|
||||
"components.Settings.ssl": "SSL",
|
||||
"components.Settings.startscan": "Start Scan",
|
||||
"components.Settings.sync": "Sync Plex Libraries",
|
||||
"components.Settings.syncing": "Syncing",
|
||||
"components.Settings.syncing": "Syncing…",
|
||||
"components.Setup.configureplex": "Configure Plex",
|
||||
"components.Setup.configureservices": "Configure Services",
|
||||
"components.Setup.continue": "Continue",
|
||||
@@ -218,8 +227,9 @@
|
||||
"components.Setup.signinMessage": "Get started by logging in with your Plex account",
|
||||
"components.Setup.welcome": "Welcome to Overseerr",
|
||||
"components.Slider.noresults": "No Results",
|
||||
"components.TitleCard.movie": "MOVIE",
|
||||
"components.TitleCard.tvshow": "SERIES",
|
||||
"components.TitleCard.movie": "Movie",
|
||||
"components.TitleCard.tvshow": "Series",
|
||||
"components.TvDetails.TvCast.fullseriescast": "Full Series Cast",
|
||||
"components.TvDetails.approve": "Approve",
|
||||
"components.TvDetails.approverequests": "Approve {requestCount} {requestCount, plural, one {Request} other {Requests}}",
|
||||
"components.TvDetails.available": "Available",
|
||||
@@ -228,7 +238,7 @@
|
||||
"components.TvDetails.decline": "Decline",
|
||||
"components.TvDetails.declinerequests": "Decline {requestCount} {requestCount, plural, one {Request} other {Requests}}",
|
||||
"components.TvDetails.manageModalClearMedia": "Clear All Media Data",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "This will remove all media data including all requests for this item. This action is irreversible. If this item exists in your Plex library, the media information will be recreated next sync.",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "This will remove all media data including all requests for this item, irreversibly. If this item exists in your Plex library, the media info will be recreated next sync.",
|
||||
"components.TvDetails.manageModalNoRequests": "No Requests",
|
||||
"components.TvDetails.manageModalRequests": "Requests",
|
||||
"components.TvDetails.manageModalTitle": "Manage Series",
|
||||
@@ -256,16 +266,16 @@
|
||||
"components.UserEdit.managerequestsDescription": "Grants permission to manage Overseerr requests. This includes approving and denying requests.",
|
||||
"components.UserEdit.permissions": "Permissions",
|
||||
"components.UserEdit.request": "Request",
|
||||
"components.UserEdit.requestDescription": "Grants permission to make requests for movies or tv shows.",
|
||||
"components.UserEdit.requestDescription": "Grants permission to request movies and series.",
|
||||
"components.UserEdit.save": "Save",
|
||||
"components.UserEdit.saving": "Saving...",
|
||||
"components.UserEdit.settings": "Manage Settings",
|
||||
"components.UserEdit.settingsDescription": "Grants permission to modify all Overseerr settings. User must have this permission to be able to grant it to others.",
|
||||
"components.UserEdit.settingsDescription": "Grants permission to modify all Overseerr settings. A user must have this permission to grant it to others.",
|
||||
"components.UserEdit.userfail": "Something went wrong saving the user.",
|
||||
"components.UserEdit.username": "Username",
|
||||
"components.UserEdit.users": "Manage Users",
|
||||
"components.UserEdit.usersDescription": "Grants permission to manage Overseerr users. Users with this permission cannot modify users with Administrator privilege, or grant it.",
|
||||
"components.UserEdit.usersaved": "User succesfully saved",
|
||||
"components.UserEdit.usersaved": "User saved",
|
||||
"components.UserEdit.vote": "Vote",
|
||||
"components.UserEdit.voteDescription": "Grants permission to vote on requests (voting not yet implemented)",
|
||||
"components.UserList.admin": "Admin",
|
||||
@@ -290,7 +300,7 @@
|
||||
"i18n.movies": "Movies",
|
||||
"i18n.partiallyavailable": "Partially Available",
|
||||
"i18n.pending": "Pending",
|
||||
"i18n.processing": "Processing",
|
||||
"i18n.processing": "Processing…",
|
||||
"i18n.tvshows": "Series",
|
||||
"i18n.unavailable": "Unavailable",
|
||||
"pages.internalServerError": "{statusCode} - Internal Server Error",
|
||||
|
||||
@@ -1,81 +1,85 @@
|
||||
{
|
||||
"components.Discover.discovermovies": "Films Populaires",
|
||||
"components.Discover.discovertv": "Séries Populaires",
|
||||
"components.Discover.discovermovies": "Films populaires",
|
||||
"components.Discover.discovertv": "Séries populaires",
|
||||
"components.Discover.nopending": "Aucune demande en attente",
|
||||
"components.Discover.popularmovies": "Films Populaires",
|
||||
"components.Discover.populartv": "Séries Populaires",
|
||||
"components.Discover.recentlyAdded": "Ajouts Récents",
|
||||
"components.Discover.recentrequests": "Demandes d'Ajouts Récentes",
|
||||
"components.Discover.popularmovies": "Films populaires",
|
||||
"components.Discover.populartv": "Séries populaires",
|
||||
"components.Discover.recentlyAdded": "Ajouts récents",
|
||||
"components.Discover.recentrequests": "Demandes d'ajouts récentes",
|
||||
"components.Discover.trending": "Tendances",
|
||||
"components.Discover.upcoming": "Prochaines Sorties",
|
||||
"components.Discover.upcomingmovies": "Prochaines Sorties",
|
||||
"components.Discover.upcoming": "Prochaines sorties",
|
||||
"components.Discover.upcomingmovies": "Prochaines sorties",
|
||||
"components.Layout.LanguagePicker.changelanguage": "Changer la langue",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "Rechercher Film & TV",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "Rechercher des films et des séries",
|
||||
"components.Layout.Sidebar.dashboard": "Découverte",
|
||||
"components.Layout.Sidebar.requests": "Demandes d'Ajouts",
|
||||
"components.Layout.Sidebar.requests": "Demandes d'ajouts",
|
||||
"components.Layout.Sidebar.settings": "Paramètres",
|
||||
"components.Layout.Sidebar.users": "Utilisateurs",
|
||||
"components.Layout.UserDropdown.signout": "Déconnexion",
|
||||
"components.Layout.alphawarning": "Ce logiciel est en version ALPHA. Presque tout est succeptible d'être buggé et/ou instable. Veuillez signaler tout problème sur le Github d'Overseerr!",
|
||||
"components.Layout.UserDropdown.signout": "Se déconnecter",
|
||||
"components.Layout.alphawarning": "Ce logiciel est en version ALPHA. Presque tout est succeptible de mal fonctionner ou d'être instable. Veuillez signaler tout problème sur le GitHub d'Overseerr !",
|
||||
"components.Login.signinplex": "S'identifier pour continuer",
|
||||
"components.MovieDetails.approve": "Valider",
|
||||
"components.MovieDetails.available": "Disponible",
|
||||
"components.MovieDetails.budget": "Budget",
|
||||
"components.MovieDetails.cancelrequest": "Annuler la Demande",
|
||||
"components.MovieDetails.cancelrequest": "Annuler la demande",
|
||||
"components.MovieDetails.cast": "Casting",
|
||||
"components.MovieDetails.decline": "Refuser",
|
||||
"components.MovieDetails.manageModalClearMedia": "Effacer toutes les données médias",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "Toutes les donnés de médias vont être éffacées pour cet élément. Cette action est irréversible. Si cet élément existe dans votre librairie Plex, les informations du média seront recrées à la prochaine synchronisation ",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "Toutes les donnés de médias vont être éffacées pour cet élément irréversiblement. Si cet élément existe dans votre bibliothèque Plex, les informations du média seront recrées à la prochaine synchronisation.",
|
||||
"components.MovieDetails.manageModalNoRequests": "Aucune demande",
|
||||
"components.MovieDetails.manageModalRequests": "Demandes d'Ajouts",
|
||||
"components.MovieDetails.manageModalRequests": "Demandes d'ajout",
|
||||
"components.MovieDetails.manageModalTitle": "Gérer les films",
|
||||
"components.MovieDetails.originallanguage": "Langue originale",
|
||||
"components.MovieDetails.overview": "Résumé",
|
||||
"components.MovieDetails.overviewunavailable": "Résumé indisponible",
|
||||
"components.MovieDetails.pending": "En Attente",
|
||||
"components.MovieDetails.pending": "En attente",
|
||||
"components.MovieDetails.recommendations": "Recommendations",
|
||||
"components.MovieDetails.recommendationssubtext": "Si vous avez aimé {title}, vous aimerez peut-être...",
|
||||
"components.MovieDetails.releasedate": "Date de sortie",
|
||||
"components.MovieDetails.request": "Demande d'Ajout",
|
||||
"components.MovieDetails.request": "Demande d'ajout",
|
||||
"components.MovieDetails.revenue": "Revenus",
|
||||
"components.MovieDetails.runtime": "{minutes} minutes",
|
||||
"components.MovieDetails.similar": "Titres Similaires",
|
||||
"components.MovieDetails.similar": "Titres similaires",
|
||||
"components.MovieDetails.similarsubtext": "Films similaires à {title}",
|
||||
"components.MovieDetails.status": "Statut",
|
||||
"components.MovieDetails.unavailable": "Indisponible",
|
||||
"components.MovieDetails.userrating": "Note Utilisateur",
|
||||
"components.MovieDetails.userrating": "Note utilisateur",
|
||||
"components.MovieDetails.viewrequest": "Voir la demande",
|
||||
"components.PlexLoginButton.loading": "Chargement...",
|
||||
"components.PlexLoginButton.loggingin": "Connexion en cours...",
|
||||
"components.PlexLoginButton.loginwithplex": "Se Connecter avec Plex",
|
||||
"components.PersonDetails.appearsin": "Apparaît dans",
|
||||
"components.PersonDetails.ascharacter": "comme {character}",
|
||||
"components.PersonDetails.nobiography": "Aucune biographie disponible.",
|
||||
"components.PlexLoginButton.loading": "Chargement…",
|
||||
"components.PlexLoginButton.loggingin": "Connexion en cours…",
|
||||
"components.PlexLoginButton.loginwithplex": "Se connecter avec Plex",
|
||||
"components.RequestBlock.seasons": "Saisons",
|
||||
"components.RequestCard.all": "Toutes",
|
||||
"components.RequestCard.requestedby": "Demandé par {username}",
|
||||
"components.RequestCard.seasons": "Saisons",
|
||||
"components.RequestList.RequestItem.notavailable": "",
|
||||
"components.RequestList.RequestItem.requestedby": "",
|
||||
"components.RequestList.RequestItem.seasons": "",
|
||||
"components.RequestList.mediaInfo": "",
|
||||
"components.RequestList.modifiedBy": "",
|
||||
"components.RequestList.next": "",
|
||||
"components.RequestList.previous": "",
|
||||
"components.RequestList.requestedAt": "",
|
||||
"components.RequestList.requests": "",
|
||||
"components.RequestList.showingresults": "",
|
||||
"components.RequestList.status": "",
|
||||
"components.RequestModal.cancel": "Annuler la Demande",
|
||||
"components.RequestModal.cancelling": "Annulation...",
|
||||
"components.RequestModal.cancelrequest": "Votre demande d'ajout va être annulée. Êtes-vous sûr de vouloir annuler?",
|
||||
"components.RequestList.RequestItem.notavailable": "s.o.",
|
||||
"components.RequestList.RequestItem.requestedby": "Demandé par {username}",
|
||||
"components.RequestList.RequestItem.seasons": "Saisons",
|
||||
"components.RequestList.mediaInfo": "Infos média",
|
||||
"components.RequestList.modifiedBy": "Dernière modification par",
|
||||
"components.RequestList.next": "Suivant",
|
||||
"components.RequestList.previous": "Précédent",
|
||||
"components.RequestList.requestedAt": "Demandé le",
|
||||
"components.RequestList.requests": "Demandes",
|
||||
"components.RequestList.showingresults": "Affichage de <strong>{from}</strong> à <strong>{to}</strong> sur <strong>{total </strong> résultats",
|
||||
"components.RequestList.status": "Statut",
|
||||
"components.RequestModal.cancel": "Annuler la demande",
|
||||
"components.RequestModal.cancelling": "Annulation…",
|
||||
"components.RequestModal.cancelrequest": "Votre demande d'ajout va être annulée. Êtes-vous sûr(e) de vouloir annuler ?",
|
||||
"components.RequestModal.close": "Fermer",
|
||||
"components.RequestModal.extras": "Extras",
|
||||
"components.RequestModal.notrequested": "Non Demandé",
|
||||
"components.RequestModal.numberofepisodes": "# d'épisodes",
|
||||
"components.RequestModal.notrequested": "Non demandé",
|
||||
"components.RequestModal.numberofepisodes": "Nbr d'épisodes",
|
||||
"components.RequestModal.pendingrequest": "Demande en attente pour {title}",
|
||||
"components.RequestModal.request": "Demande d'Ajout",
|
||||
"components.RequestModal.request": "Demande d'ajout",
|
||||
"components.RequestModal.requestCancel": "Demande pour <strong>{title}</strong> annulée",
|
||||
"components.RequestModal.requestSuccess": "<strong>{title}</strong> demandé avec succès!",
|
||||
"components.RequestModal.requestadmin": "Votre demande d'ajout va être approuvée immédiatement ",
|
||||
"components.RequestModal.requestSuccess": "<strong>{title}</strong> demandé.",
|
||||
"components.RequestModal.requestadmin": "Votre demande d'ajout va être validée immédiatement.",
|
||||
"components.RequestModal.requestfrom": "Une demande d'ajout de {username} est en attente",
|
||||
"components.RequestModal.requesting": "Demande en cours...",
|
||||
"components.RequestModal.requesting": "Demande en cours…",
|
||||
"components.RequestModal.requestseasons": "Demander {seasonCount} {seasonCount, plural, one {Season} other {Seasons}}",
|
||||
"components.RequestModal.requesttitle": "Demander l'ajout de {title}",
|
||||
"components.RequestModal.season": "Saison",
|
||||
@@ -86,217 +90,219 @@
|
||||
"components.Settings.Notifications.agentenabled": "Agent activé",
|
||||
"components.Settings.Notifications.authPass": "Auth Pass",
|
||||
"components.Settings.Notifications.authUser": "Auth User",
|
||||
"components.Settings.Notifications.emailsender": "Adresse e-mail de l'expéditeur",
|
||||
"components.Settings.Notifications.emailsender": "e-mail de l'expéditeur",
|
||||
"components.Settings.Notifications.enableSsl": "Activer le SSL",
|
||||
"components.Settings.Notifications.save": "Sauvegarder les changements",
|
||||
"components.Settings.Notifications.saving": "Sauvegarde en cours...",
|
||||
"components.Settings.Notifications.saving": "Sauvegarde en cours…",
|
||||
"components.Settings.Notifications.smtpHost": "Hôte SMTP",
|
||||
"components.Settings.Notifications.smtpPort": "Port SMTP",
|
||||
"components.Settings.Notifications.validationFromRequired": "Vous devez fournir une adresse e-mail d'expéditeur",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "Vous devez fournir un hôte SSL ",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "Vous devez fournir un hôte SSL",
|
||||
"components.Settings.Notifications.validationSmtpPortRequired": "Vous devez fournir un port SMTP",
|
||||
"components.Settings.Notifications.validationWebhookUrlRequired": "Vous devez fournir une URL de webhook",
|
||||
"components.Settings.Notifications.webhookUrl": "URL de webhook",
|
||||
"components.Settings.Notifications.webhookUrlPlaceholder": "Paramètres du serveur -> Intégrations -> Webhooks",
|
||||
"components.Settings.RadarrModal.add": "Ajouter un Serveur",
|
||||
"components.Settings.RadarrModal.add": "Ajouter un serveur",
|
||||
"components.Settings.RadarrModal.apiKey": "Clé d'API",
|
||||
"components.Settings.RadarrModal.apiKeyPlaceholder": "Votre clé Radarr API",
|
||||
"components.Settings.RadarrModal.baseUrl": "URL de base",
|
||||
"components.Settings.RadarrModal.baseUrlPlaceholder": "Exemple: /radarr",
|
||||
"components.Settings.RadarrModal.createradarr": "Créer Nouveau Serveur Radarr",
|
||||
"components.Settings.RadarrModal.defaultserver": "Serveur par Défaut",
|
||||
"components.Settings.RadarrModal.editradarr": "Éditer Serveur Radarr",
|
||||
"components.Settings.RadarrModal.hostname": "Hostname",
|
||||
"components.Settings.RadarrModal.minimumAvailability": "Disponibilité Minimum",
|
||||
"components.Settings.RadarrModal.baseUrlPlaceholder": "Exemple : /radarr",
|
||||
"components.Settings.RadarrModal.createradarr": "Créer un nouveau serveur Radarr",
|
||||
"components.Settings.RadarrModal.defaultserver": "Serveur par défaut",
|
||||
"components.Settings.RadarrModal.editradarr": "Modifier le serveur Radarr",
|
||||
"components.Settings.RadarrModal.hostname": "Nom d'hôte",
|
||||
"components.Settings.RadarrModal.minimumAvailability": "Disponibilité minimale",
|
||||
"components.Settings.RadarrModal.port": "Port",
|
||||
"components.Settings.RadarrModal.qualityprofile": "Profil Qualité",
|
||||
"components.Settings.RadarrModal.rootfolder": "Dossier Racine",
|
||||
"components.Settings.RadarrModal.save": "Sauvegarder les changements",
|
||||
"components.Settings.RadarrModal.saving": "Sauvegarde en cours...",
|
||||
"components.Settings.RadarrModal.selectMinimumAvailability": "Sélectionner Disponibilté Minimum",
|
||||
"components.Settings.RadarrModal.selectQualityProfile": "Sélectionner un Profil Qualité",
|
||||
"components.Settings.RadarrModal.selectRootFolder": "Sélectionner un Dossier Racine",
|
||||
"components.Settings.RadarrModal.qualityprofile": "Profil qualité",
|
||||
"components.Settings.RadarrModal.rootfolder": "Dossier racine",
|
||||
"components.Settings.RadarrModal.save": "Enregsitrer les changements",
|
||||
"components.Settings.RadarrModal.saving": "Enregsitrement en cours…",
|
||||
"components.Settings.RadarrModal.selectMinimumAvailability": "Sélectionner une disponibilté minimale",
|
||||
"components.Settings.RadarrModal.selectQualityProfile": "Sélectionner un profil qualité",
|
||||
"components.Settings.RadarrModal.selectRootFolder": "Sélectionner un dossier racine",
|
||||
"components.Settings.RadarrModal.server4k": "Serveur 4K",
|
||||
"components.Settings.RadarrModal.servername": "Nom du Serveur",
|
||||
"components.Settings.RadarrModal.servername": "Nom du serveur",
|
||||
"components.Settings.RadarrModal.servernamePlaceholder": "Serveur Radarr",
|
||||
"components.Settings.RadarrModal.ssl": "SSL",
|
||||
"components.Settings.RadarrModal.test": "Test",
|
||||
"components.Settings.RadarrModal.testing": "Test en cours...",
|
||||
"components.Settings.RadarrModal.toastRadarrTestFailure": "Echec de la connexion au Serveur Radarr ",
|
||||
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Connexion avec le Serveur Radarr établie!",
|
||||
"components.Settings.RadarrModal.testing": "Test en cours…",
|
||||
"components.Settings.RadarrModal.toastRadarrTestFailure": "Échec de la connexion au Serveur Radarr",
|
||||
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Connexion avec le Serveur Radarr établie !",
|
||||
"components.Settings.RadarrModal.validationApiKeyRequired": "Vous devez fournir une clé d'API",
|
||||
"components.Settings.RadarrModal.validationHostnameRequired": "Vous devez fournir un hostname/IP",
|
||||
"components.Settings.RadarrModal.validationHostnameRequired": "Vous devez fournir un nom d'hôte/IP",
|
||||
"components.Settings.RadarrModal.validationPortRequired": "Vous devez fournir un port",
|
||||
"components.Settings.RadarrModal.validationProfileRequired": "Vous devez sélectionner un profil",
|
||||
"components.Settings.RadarrModal.validationRootFolderRequired": "Vous devez sélectionner un dossier racine",
|
||||
"components.Settings.SonarrModal.add": "Ajouter un Serveur",
|
||||
"components.Settings.SonarrModal.add": "Ajouter un serveur",
|
||||
"components.Settings.SonarrModal.apiKey": "Clé API",
|
||||
"components.Settings.SonarrModal.apiKeyPlaceholder": "Votre clé d'API Sonarr",
|
||||
"components.Settings.SonarrModal.baseUrl": "URL de base",
|
||||
"components.Settings.SonarrModal.baseUrlPlaceholder": "Exemple: /sonarr",
|
||||
"components.Settings.SonarrModal.createsonarr": "Créer Nouveau Serveur Sonarr",
|
||||
"components.Settings.SonarrModal.defaultserver": "Serveur par Défaut",
|
||||
"components.Settings.SonarrModal.editsonarr": "Modifier Serveur Sonarr",
|
||||
"components.Settings.SonarrModal.hostname": "Hostname",
|
||||
"components.Settings.SonarrModal.baseUrlPlaceholder": "Exemple : /sonarr",
|
||||
"components.Settings.SonarrModal.createsonarr": "Créer un nouveau serveur Sonarr",
|
||||
"components.Settings.SonarrModal.defaultserver": "Serveur par défaut",
|
||||
"components.Settings.SonarrModal.editsonarr": "Modifier le serveur Sonarr",
|
||||
"components.Settings.SonarrModal.hostname": "Nom d'hôte",
|
||||
"components.Settings.SonarrModal.port": "Port",
|
||||
"components.Settings.SonarrModal.qualityprofile": "Profil Qualité",
|
||||
"components.Settings.SonarrModal.rootfolder": "Dossier Racine",
|
||||
"components.Settings.SonarrModal.qualityprofile": "Profil qualité",
|
||||
"components.Settings.SonarrModal.rootfolder": "Dossier racine",
|
||||
"components.Settings.SonarrModal.save": "Sauvegarder les changements",
|
||||
"components.Settings.SonarrModal.saving": "Sauvegarde en cours...",
|
||||
"components.Settings.SonarrModal.seasonfolders": "Dossier Saison",
|
||||
"components.Settings.SonarrModal.selectQualityProfile": "Sélectionner un profil Qualité",
|
||||
"components.Settings.SonarrModal.selectRootFolder": "Sélectionner un Dossier Racine",
|
||||
"components.Settings.SonarrModal.saving": "Enregistrement en cours…",
|
||||
"components.Settings.SonarrModal.seasonfolders": "Dossier saison",
|
||||
"components.Settings.SonarrModal.selectQualityProfile": "Sélectionner un profil qualité",
|
||||
"components.Settings.SonarrModal.selectRootFolder": "Sélectionner un dossier racine",
|
||||
"components.Settings.SonarrModal.server4k": "Serveur 4K",
|
||||
"components.Settings.SonarrModal.servername": "Nom du Serveur",
|
||||
"components.Settings.SonarrModal.servernamePlaceholder": "Serveur Sonarr",
|
||||
"components.Settings.SonarrModal.servername": "Nom du serveur",
|
||||
"components.Settings.SonarrModal.servernamePlaceholder": "Un serveur Sonarr",
|
||||
"components.Settings.SonarrModal.ssl": "SSL",
|
||||
"components.Settings.SonarrModal.test": "Test",
|
||||
"components.Settings.SonarrModal.testing": "Test en cours",
|
||||
"components.Settings.SonarrModal.testing": "Test en cours…",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "Échec de la connexion au Serveur Sonarr",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Connexion avec le Serveur Sonarr établie!",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Connexion avec le Serveur Sonarr établie !",
|
||||
"components.Settings.SonarrModal.validationApiKeyRequired": "Vous devez fournir une clé d'API",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "Vous devez fournir un hostname/IP",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "Vous devez fournir un nom d'hôte/IP",
|
||||
"components.Settings.SonarrModal.validationPortRequired": "Vous devez fournir un port",
|
||||
"components.Settings.SonarrModal.validationProfileRequired": "Vous devez sélectionner un profil",
|
||||
"components.Settings.SonarrModal.validationRootFolderRequired": "Vous devez sélectionner un dossier racine",
|
||||
"components.Settings.activeProfile": "Profil Actif",
|
||||
"components.Settings.addradarr": "Ajouter Serveur Radarr",
|
||||
"components.Settings.activeProfile": "Profil actif",
|
||||
"components.Settings.addradarr": "Ajouter un serveur Radarr",
|
||||
"components.Settings.address": "Adresse",
|
||||
"components.Settings.addsonarr": "Ajouter Serveur Sonarr",
|
||||
"components.Settings.addsonarr": "Ajouter un serveur Sonarr",
|
||||
"components.Settings.apikey": "Clé d'API",
|
||||
"components.Settings.applicationurl": "URL de l'Application",
|
||||
"components.Settings.cancelscan": "Annuler le Scan",
|
||||
"components.Settings.applicationurl": "URL de l'application",
|
||||
"components.Settings.cancelscan": "Annuler le scan",
|
||||
"components.Settings.copied": "Clé d'API copiée dans le presse-papier",
|
||||
"components.Settings.currentlibrary": "Librairie Actuelle: {name}",
|
||||
"components.Settings.default": "Par Défaut",
|
||||
"components.Settings.default4k": "4K Par Défaut",
|
||||
"components.Settings.currentlibrary": "Bibliothèque actuelle : {name}",
|
||||
"components.Settings.default": "Par défaut",
|
||||
"components.Settings.default4k": "4K par défaut",
|
||||
"components.Settings.delete": "Supprimer",
|
||||
"components.Settings.deleteserverconfirm": "Êtes-vous sûr de vouloir supprimer ce serveur?",
|
||||
"components.Settings.deleteserverconfirm": "Êtes-vous sûr(e) de vouloir supprimer ce serveur ?",
|
||||
"components.Settings.edit": "Modifier",
|
||||
"components.Settings.generalsettings": "Paramètres Généraux",
|
||||
"components.Settings.generalsettingsDescription": "Ces paramètres concernent la configuration générale d'Overseerr",
|
||||
"components.Settings.hostname": "Hostname/IP",
|
||||
"components.Settings.jobname": "Nom de la Tâche",
|
||||
"components.Settings.librariesRemaining": "Librairies Restantes: {count}",
|
||||
"components.Settings.manualscan": "Scan Manuel des Librairies",
|
||||
"components.Settings.manualscanDescription": "Normalement, le scan sera effectué une fois toutes les 6 heures seulement. Overseerr va vérifier les ajouts récents de votre serveur Plex de manière plus agressive. Si c'est votre première configuration de Plex, un scan complet unique de la librairie est recommandé!",
|
||||
"components.Settings.menuAbout": "À Propos",
|
||||
"components.Settings.menuGeneralSettings": "Paramètres Généraux",
|
||||
"components.Settings.generalsettings": "Paramètres généraux",
|
||||
"components.Settings.generalsettingsDescription": "Ces paramètres concernent la configuration générale d'Overseerr.",
|
||||
"components.Settings.hostname": "Nom d'hôte/IP",
|
||||
"components.Settings.jobname": "Nom de la tâche",
|
||||
"components.Settings.librariesRemaining": "Bibliothèques restantes : {count}",
|
||||
"components.Settings.manualscan": "Scan manuel des bibliothèques",
|
||||
"components.Settings.manualscanDescription": "Normalement, le scan sera effectué une fois toutes les 6 heures seulement. Overseerr va vérifier les ajouts récents de votre serveur Plex de manière plus agressive. Si c'est votre première configuration de Plex, un scan complet unique de la bibliothèque est recommandé !",
|
||||
"components.Settings.menuAbout": "À propos",
|
||||
"components.Settings.menuGeneralSettings": "Paramètres généraux",
|
||||
"components.Settings.menuJobs": "Tâches",
|
||||
"components.Settings.menuLogs": "Rapports",
|
||||
"components.Settings.menuLogs": "Journaux",
|
||||
"components.Settings.menuNotifications": "Notifications",
|
||||
"components.Settings.menuPlexSettings": "Plex",
|
||||
"components.Settings.menuServices": "Services",
|
||||
"components.Settings.nextexecution": "Prochaine Exécution",
|
||||
"components.Settings.notificationsettings": "Paramètres de Notifications",
|
||||
"components.Settings.nextexecution": "Prochaine exécution",
|
||||
"components.Settings.notificationsettings": "Paramètres de notification",
|
||||
"components.Settings.notificationsettingsDescription": "Ici vous pouvez choisir quel type de notifications envoyer et avec quel service.",
|
||||
"components.Settings.notrunning": "Pas en Marche",
|
||||
"components.Settings.plexlibraries": "Librairies Plex",
|
||||
"components.Settings.plexlibrariesDescription": "Ce sont les librairies que Overseerr va scanner pour les titres. Si vous ne voyez aucune librairie listée, vous devrez lancer au moins une synchro en cliquant sur le bouton ci-dessous. Vous devez configurer et sauvergarder vos paramètres de connexion à Plex avant de pouvoir retrouver vos librairies.",
|
||||
"components.Settings.notrunning": "Pas en exécution",
|
||||
"components.Settings.plexlibraries": "Bibliothèques Plex",
|
||||
"components.Settings.plexlibrariesDescription": "Les bibliothèques Overseerr recherche les titres. Configurez et enregistrez vos paramètres de connexion Plex et cliquez sur le bouton ci-dessous si aucun n'est répertorié.",
|
||||
"components.Settings.plexsettings": "Paramètres Plex",
|
||||
"components.Settings.plexsettingsDescription": "Configurer les paramètres de votre serveur Plex. Overseerr utilise votre serveur Plex pour scanner votre librairie par intervalles et voir quels contenus sont disponibles.",
|
||||
"components.Settings.plexsettingsDescription": "Configurer les paramètres de votre serveur Plex. Overseerr utilise votre serveur Plex pour scanner votre bibliothèque par intervalles et voir quels contenus sont disponibles.",
|
||||
"components.Settings.port": "Port",
|
||||
"components.Settings.radarrSettingsDescription": "Configurez votre connexion Radarr ci-dessous. Vous pouvez avoir plusieurs configurations de Radarr mais seulement deux peuvent être actives en tant que config par défaut en même temps (une pour HD Standar et une pour la 4K). Les admins peuvent décider quel serveur sera utilisé lorsqu'une nouvelle demande est effectuée.",
|
||||
"components.Settings.radarrSettingsDescription": "Configurez votre connexion Radarr ci-dessous. Vous pouvez en avoir plusieurs, mais seulement deux actives par défaut à tout moment (une pour la HD standard et un pour la 4K). Les administrateurs peuvent remplacer le serveur utilisé pour les nouvelles demandes.",
|
||||
"components.Settings.radarrsettings": "Paramètres Radarr",
|
||||
"components.Settings.runnow": "Lancer Maintenant",
|
||||
"components.Settings.runnow": "Lancer maintenant",
|
||||
"components.Settings.save": "Sauvegarder les changements",
|
||||
"components.Settings.saving": "Sauvergarde en cours...",
|
||||
"components.Settings.servername": "Nom du Serveur (Nom Automatique)",
|
||||
"components.Settings.servernamePlaceholder": "Nom de Serveur Plex",
|
||||
"components.Settings.sonarrSettingsDescription": "Configurez votre connexion Radarr ci-dessous. Vous pouvez avoir plusieurs configurations de Radarr mais seulement deux peuvent être actives en tant que config par défaut en même temps (une pour HD Standar et une pour la 4K). Les admins peuvent décider quel serveur sera utilisé lorsqu'une nouvelle demande est effectuée.",
|
||||
"components.Settings.saving": "Enregistrement en cours…",
|
||||
"components.Settings.servername": "Nom du serveur (défini automatiquement)",
|
||||
"components.Settings.servernamePlaceholder": "Nom de serveur Plex",
|
||||
"components.Settings.sonarrSettingsDescription": "Configurez votre connexion Sonarr ci-dessous. Vous pouvez avoir plusieurs, mais seulement deux actives par défaut à tout moment (une pour la HD standard et un pour la 4K). Les administrateurs peuvent remplacer le serveur utilisé pour les nouvelles demandes.",
|
||||
"components.Settings.sonarrsettings": "Paramètres Sonarr",
|
||||
"components.Settings.ssl": "SSL",
|
||||
"components.Settings.startscan": "Commencer le scan",
|
||||
"components.Settings.sync": "Synchroniser les Librairies Plex",
|
||||
"components.Settings.syncing": "Synchronisation en cours...",
|
||||
"components.Settings.sync": "Synchroniser les bibliothèques Plex",
|
||||
"components.Settings.syncing": "Synchronisation…",
|
||||
"components.Setup.configureplex": "Configurer Plex",
|
||||
"components.Setup.configureservices": "Configurer les Services",
|
||||
"components.Setup.continue": "Continue",
|
||||
"components.Setup.finish": "Finir la Configuration",
|
||||
"components.Setup.finishing": "Finalisation...",
|
||||
"components.Setup.continue": "Continuer",
|
||||
"components.Setup.finish": "Finir la configuration",
|
||||
"components.Setup.finishing": "Finalisation…",
|
||||
"components.Setup.loginwithplex": "Se connecter avec Plex",
|
||||
"components.Setup.signinMessage": "Commencez en vous connectant avec votre compte Plex",
|
||||
"components.Setup.welcome": "Bienvenue sur Overseerr",
|
||||
"components.Slider.noresults": "Aucun résultats",
|
||||
"components.TitleCard.movie": "FILMS",
|
||||
"components.TitleCard.tvshow": "SÉRIES",
|
||||
"components.Slider.noresults": "Aucun résultat",
|
||||
"components.TitleCard.movie": "Film",
|
||||
"components.TitleCard.tvshow": "Séries",
|
||||
"components.TvDetails.approve": "Valider",
|
||||
"components.TvDetails.approverequests": "Valider {requestCount} {requestCount, plural, one {Request} other {Requests}}",
|
||||
"components.TvDetails.available": "Disponible",
|
||||
"components.TvDetails.cancelrequest": "Annuler la Demande",
|
||||
"components.TvDetails.cancelrequest": "Annuler la demande",
|
||||
"components.TvDetails.cast": "Casting",
|
||||
"components.TvDetails.decline": "Refuser",
|
||||
"components.TvDetails.declinerequests": "Refuser {requestCount} {requestCount, plural, one {Request} other {Requests}}",
|
||||
"components.TvDetails.manageModalClearMedia": "Éffacer toutes les Données Média",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "Vous aller éffacer toutes les données média incluant toutes les demandes pour cet élement. Cette action est irréversible. Si cet élement existe dans votre librairie Plex, les inforations du média seront recrées à la prochaine synchronisation ",
|
||||
"components.TvDetails.manageModalNoRequests": "Aucune Demandes",
|
||||
"components.TvDetails.manageModalClearMedia": "Effacer toutes les données média",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "Ceci supprimera toutes les données multimédias, y compris toutes les demandes pour cet élément, irréversiblement. Si cet élément existe dans votre bibliothèque Plex, les informations multimédias seront recréées lors de la prochaine synchronisation.",
|
||||
"components.TvDetails.manageModalNoRequests": "Aucune demande",
|
||||
"components.TvDetails.manageModalRequests": "Demandes",
|
||||
"components.TvDetails.manageModalTitle": "Gérer les Séries",
|
||||
"components.TvDetails.originallanguage": "Langue Originale",
|
||||
"components.TvDetails.manageModalTitle": "Gérer les séries",
|
||||
"components.TvDetails.originallanguage": "Langue originale",
|
||||
"components.TvDetails.overview": "Résumé",
|
||||
"components.TvDetails.overviewunavailable": "Résumé indisponible",
|
||||
"components.TvDetails.pending": "En Attente",
|
||||
"components.TvDetails.pending": "En attente",
|
||||
"components.TvDetails.recommendations": "Recommandations",
|
||||
"components.TvDetails.recommendationssubtext": "Si vous avez aimé {title}, vous aimerez peut-être...",
|
||||
"components.TvDetails.request": "Demande d'Ajout",
|
||||
"components.TvDetails.requestmore": "Demander Plus",
|
||||
"components.TvDetails.similar": "Séries Similaires",
|
||||
"components.TvDetails.similarsubtext": "Autres Séries Similaires à {title} ",
|
||||
"components.TvDetails.recommendationssubtext": "Si vous avez aimé {title}, vous aimerez peut-être…",
|
||||
"components.TvDetails.request": "Demande d'ajout",
|
||||
"components.TvDetails.requestmore": "Demander plus",
|
||||
"components.TvDetails.similar": "Séries similaires",
|
||||
"components.TvDetails.similarsubtext": "Autres séries similaires à {title}",
|
||||
"components.TvDetails.status": "Statut",
|
||||
"components.TvDetails.unavailable": "Indisponible",
|
||||
"components.TvDetails.userrating": "Note Utilisateurs",
|
||||
"components.TvDetails.userrating": "Note utilisateurs",
|
||||
"components.UserEdit.admin": "Administrateur",
|
||||
"components.UserEdit.adminDescription": "Accès administrateur complet. Contourner toutes les demandes de permissions",
|
||||
"components.UserEdit.autoapprove": "Validation Automatique",
|
||||
"components.UserEdit.autoapproveDescription": "Active la validation automatique de toutes les demandes d'ajouts de cet utilisateur",
|
||||
"components.UserEdit.adminDescription": "Accès administrateur complet. Contourne toutes les demandes de permissions.",
|
||||
"components.UserEdit.autoapprove": "Validation automatique",
|
||||
"components.UserEdit.autoapproveDescription": "Active la validation automatique de toutes les demandes d'ajouts de cet utilisateur.",
|
||||
"components.UserEdit.avatar": "Avatar",
|
||||
"components.UserEdit.edituser": "Modifier l'Utilisateur",
|
||||
"components.UserEdit.email": "Email",
|
||||
"components.UserEdit.managerequests": "Gérer les Demandes d'Ajouts",
|
||||
"components.UserEdit.managerequestsDescription": "Donne la permission de gérer les demandes d'ajouts sur Overseerr. Ceci inclut la possibilité de valider ou refuser une demande",
|
||||
"components.UserEdit.permissions": "Permissions",
|
||||
"components.UserEdit.request": "Demandes d'Ajouts",
|
||||
"components.UserEdit.requestDescription": "Donne la permission de faire des demandes d'ajouts pour les films et séries",
|
||||
"components.UserEdit.edituser": "Modifier l'utilisateur",
|
||||
"components.UserEdit.email": "e-mail",
|
||||
"components.UserEdit.managerequests": "Gérer les demandes d'ajouts",
|
||||
"components.UserEdit.managerequestsDescription": "Donne la permission de gérer les demandes d'ajouts sur Overseerr. Ceci inclut la possibilité de valider ou refuser une demande.",
|
||||
"components.UserEdit.permissions": "Autorisations",
|
||||
"components.UserEdit.request": "Demandes d'ajouts",
|
||||
"components.UserEdit.requestDescription": "Accorde l'autorisation de demander des films et des séries.",
|
||||
"components.UserEdit.save": "Sauvegarder",
|
||||
"components.UserEdit.saving": "Sauvegarde en cours...",
|
||||
"components.UserEdit.settings": "Gérer les Paramètres",
|
||||
"components.UserEdit.settingsDescription": "Donne la permission de modifier tous les paramètres d'Overseerr. L'utilisateur doit avoir cette permission pour pouvoir la donner à d'autres.",
|
||||
"components.UserEdit.userfail": "Une erreur est survenue dans la sauvegarde de cet utilisateur",
|
||||
"components.UserEdit.username": "Nom d'Utilisateur",
|
||||
"components.UserEdit.users": "Gérer les Utilisateurs",
|
||||
"components.UserEdit.saving": "Enregistrement en cours…",
|
||||
"components.UserEdit.settings": "Gérer les paramètres",
|
||||
"components.UserEdit.settingsDescription": "Donne la permission de modifier tous les paramètres d'Overseerr. Un utilisateur doit avoir cette permission pour pouvoir la donner à d'autres.",
|
||||
"components.UserEdit.userfail": "Une erreur est survenue dans la sauvegarde de cet utilisateur.",
|
||||
"components.UserEdit.username": "Nom d'utilisateur",
|
||||
"components.UserEdit.users": "Gérer les utilisateurs",
|
||||
"components.UserEdit.usersDescription": "Donne la permission de gérer les utilisateurs d'Overseerr. Les utilisateurs avec cette permission ne peuvent pas modifier les utilisateurs avec un des privilèges Admin, ni en donner.",
|
||||
"components.UserEdit.usersaved": "Utilisateur sauvegardé avec succès",
|
||||
"components.UserEdit.usersaved": "Utilisateur sauvegardé",
|
||||
"components.UserEdit.vote": "Vote",
|
||||
"components.UserEdit.voteDescription": "Donne la permission de voter pour les demandes d'ajouts (La fonction de vote n'est pas encore active)",
|
||||
"components.UserList.admin": "Admin",
|
||||
"components.UserList.created": "Crée",
|
||||
"components.UserList.created": "Créé",
|
||||
"components.UserList.delete": "Supprimer",
|
||||
"components.UserList.edit": "Modifier",
|
||||
"components.UserList.lastupdated": "Denière Mise à Jour",
|
||||
"components.UserList.lastupdated": "Denière mise à jour",
|
||||
"components.UserList.plexuser": "Utilisateur Plex",
|
||||
"components.UserList.role": "Rôle",
|
||||
"components.UserList.totalrequests": "Demandes d'Ajouts total",
|
||||
"components.UserList.totalrequests": "Demandes d'ajout totales",
|
||||
"components.UserList.user": "Utilisateur",
|
||||
"components.UserList.userlist": "Liste des Utilisateurs",
|
||||
"components.UserList.username": "Nom d'Utilisateur",
|
||||
"components.UserList.usertype": "Type d'Utilisateur",
|
||||
"components.UserList.userlist": "Liste des utilisateurs",
|
||||
"components.UserList.username": "Nom d'utilisateur",
|
||||
"components.UserList.usertype": "Type d'utilisateur",
|
||||
"i18n.approve": "Valider",
|
||||
"i18n.approved": "Validé",
|
||||
"i18n.available": "Disponible",
|
||||
"i18n.cancel": "Annuler",
|
||||
"i18n.decline": "Refuser",
|
||||
"i18n.declined": "Refusé",
|
||||
"i18n.delete": "",
|
||||
"i18n.delete": "Supprimer",
|
||||
"i18n.movies": "Films",
|
||||
"i18n.partiallyavailable": "Partiellement Disponible",
|
||||
"i18n.pending": "En Attente",
|
||||
"i18n.processing": "En Cours",
|
||||
"i18n.partiallyavailable": "Partiellement disponible",
|
||||
"i18n.pending": "En attente",
|
||||
"i18n.processing": "Traitement en cours…",
|
||||
"i18n.tvshows": "Séries",
|
||||
"i18n.unavailable": "Indisponible",
|
||||
"pages.internalServerError": "{statusCode} - Erreur du Serveur Interne",
|
||||
"pages.internalServerError": "{statusCode} – Erreur du serveur interne",
|
||||
"pages.oops": "Oups",
|
||||
"pages.pageNotFound": "404 - Page Non Trouvée",
|
||||
"pages.returnHome": "Retourner à l'Acceuil",
|
||||
"pages.serviceUnavailable": "{statusCode} - Service Indisponible",
|
||||
"pages.somethingWentWrong": "{statusCode} - Il y a eu un problème"
|
||||
"pages.pageNotFound": "404 – Page non trouvée",
|
||||
"pages.returnHome": "Retourner à l'acceuil",
|
||||
"pages.serviceUnavailable": "{statusCode} – Service indisponible",
|
||||
"pages.somethingWentWrong": "{statusCode} – Une erreur est survenue",
|
||||
"components.TvDetails.TvCast.fullseriescast": "Casting complet de la série",
|
||||
"components.MovieDetails.MovieCast.fullcast": "Casting complet"
|
||||
}
|
||||
|
||||
@@ -1,302 +1,306 @@
|
||||
{
|
||||
"components.Discover.discovermovies": "人気の映画",
|
||||
"components.Discover.discovertv": "人気のテレビ番組",
|
||||
"components.Discover.nopending": "",
|
||||
"components.Discover.nopending": "保留中のリクエストがありません",
|
||||
"components.Discover.popularmovies": "人気の映画",
|
||||
"components.Discover.populartv": "人気のテレビ番組",
|
||||
"components.Discover.recentlyAdded": "",
|
||||
"components.Discover.recentlyAdded": "最近追加された動画",
|
||||
"components.Discover.recentrequests": "最近のリクエスト",
|
||||
"components.Discover.trending": "",
|
||||
"components.Discover.upcoming": "",
|
||||
"components.Discover.upcomingmovies": "",
|
||||
"components.Discover.trending": "トレンド",
|
||||
"components.Discover.upcoming": "今後リリースされる映画",
|
||||
"components.Discover.upcomingmovies": "今後リリースされる映画",
|
||||
"components.Layout.LanguagePicker.changelanguage": "言語",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "作品名で検索",
|
||||
"components.Layout.Sidebar.dashboard": "ホーム",
|
||||
"components.Layout.Sidebar.requests": "リクエスト",
|
||||
"components.Layout.Sidebar.settings": "設定",
|
||||
"components.Layout.Sidebar.users": "",
|
||||
"components.Layout.UserDropdown.signout": "",
|
||||
"components.Layout.alphawarning": "",
|
||||
"components.Login.signinplex": "",
|
||||
"components.MovieDetails.approve": "",
|
||||
"components.MovieDetails.available": "",
|
||||
"components.MovieDetails.budget": "興行収入",
|
||||
"components.MovieDetails.cancelrequest": "チャンセルリクエスト",
|
||||
"components.Layout.Sidebar.users": "ユーザー",
|
||||
"components.Layout.UserDropdown.signout": "ログアウト",
|
||||
"components.Layout.alphawarning": "このソフトはアルファ版です。ほとんどの機能は不安定又は故障している可能性があります。バグを発見した場合、OverseerrのGithubまでご連絡ください!",
|
||||
"components.Login.signinplex": "続けるにはログインしてください",
|
||||
"components.MovieDetails.approve": "承認",
|
||||
"components.MovieDetails.available": "鑑賞可能",
|
||||
"components.MovieDetails.budget": "予算",
|
||||
"components.MovieDetails.cancelrequest": "リクエストを取り消す",
|
||||
"components.MovieDetails.cast": "キャスト",
|
||||
"components.MovieDetails.decline": "",
|
||||
"components.MovieDetails.manageModalClearMedia": "",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "",
|
||||
"components.MovieDetails.manageModalNoRequests": "",
|
||||
"components.MovieDetails.decline": "拒否",
|
||||
"components.MovieDetails.manageModalClearMedia": "メディア情報を消去",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "リクエストを含め、すべての詳細情報が消去されます。この操作は元に戻すことができません。この作品が Plex ライブラリに存在する場合、詳細情報は次の同期で再作成されます。",
|
||||
"components.MovieDetails.manageModalNoRequests": "リクエストがありません",
|
||||
"components.MovieDetails.manageModalRequests": "リクエスト",
|
||||
"components.MovieDetails.manageModalTitle": "",
|
||||
"components.MovieDetails.originallanguage": "言語",
|
||||
"components.MovieDetails.manageModalTitle": "映画を管理",
|
||||
"components.MovieDetails.originallanguage": "原語",
|
||||
"components.MovieDetails.overview": "ストーリー",
|
||||
"components.MovieDetails.overviewunavailable": "",
|
||||
"components.MovieDetails.overviewunavailable": "ストーリー情報がありません",
|
||||
"components.MovieDetails.pending": "リクエスト中",
|
||||
"components.MovieDetails.recommendations": "オススメの作品",
|
||||
"components.MovieDetails.recommendationssubtext": "",
|
||||
"components.MovieDetails.recommendationssubtext": "{title}が好きだった人は、こんなのも好きかもしれません...",
|
||||
"components.MovieDetails.releasedate": "公開日",
|
||||
"components.MovieDetails.request": "リクエストする",
|
||||
"components.MovieDetails.revenue": "製作費",
|
||||
"components.MovieDetails.revenue": "収益",
|
||||
"components.MovieDetails.runtime": "{minutes}分",
|
||||
"components.MovieDetails.similar": "関連作品",
|
||||
"components.MovieDetails.similarsubtext": "",
|
||||
"components.MovieDetails.similarsubtext": "{title}に関連する作品",
|
||||
"components.MovieDetails.status": "状態",
|
||||
"components.MovieDetails.unavailable": "",
|
||||
"components.MovieDetails.unavailable": "鑑賞不可",
|
||||
"components.MovieDetails.userrating": "ユーザー評価",
|
||||
"components.MovieDetails.viewrequest": "",
|
||||
"components.PlexLoginButton.loading": "",
|
||||
"components.PlexLoginButton.loggingin": "",
|
||||
"components.PlexLoginButton.loginwithplex": "",
|
||||
"components.RequestBlock.seasons": "",
|
||||
"components.RequestCard.requestedby": "",
|
||||
"components.RequestCard.seasons": "",
|
||||
"components.RequestList.RequestItem.notavailable": "",
|
||||
"components.RequestList.RequestItem.requestedby": "",
|
||||
"components.RequestList.RequestItem.seasons": "",
|
||||
"components.RequestList.mediaInfo": "",
|
||||
"components.RequestList.modifiedBy": "",
|
||||
"components.RequestList.next": "",
|
||||
"components.RequestList.previous": "",
|
||||
"components.RequestList.requestedAt": "",
|
||||
"components.RequestList.requests": "",
|
||||
"components.RequestList.showingresults": "",
|
||||
"components.RequestList.status": "",
|
||||
"components.RequestModal.cancel": "チャンセルリクエスト",
|
||||
"components.RequestModal.cancelling": "",
|
||||
"components.MovieDetails.viewrequest": "リクエストを閲覧",
|
||||
"components.PersonDetails.appearsin": "出演作品",
|
||||
"components.PersonDetails.ascharacter": "{character}役",
|
||||
"components.PersonDetails.nobiography": "出演作品の情報はありません。",
|
||||
"components.PlexLoginButton.loading": "ロード中…",
|
||||
"components.PlexLoginButton.loggingin": "ログイン中…",
|
||||
"components.PlexLoginButton.loginwithplex": "Plexでログイン",
|
||||
"components.RequestBlock.seasons": "シーズン",
|
||||
"components.RequestCard.all": "すべて",
|
||||
"components.RequestCard.requestedby": "{username}のリクエスト",
|
||||
"components.RequestCard.seasons": "シーズン",
|
||||
"components.RequestList.RequestItem.notavailable": "N/A",
|
||||
"components.RequestList.RequestItem.requestedby": "{username}のリクエスト",
|
||||
"components.RequestList.RequestItem.seasons": "シーズン",
|
||||
"components.RequestList.mediaInfo": "詳細情報",
|
||||
"components.RequestList.modifiedBy": "最終更新者",
|
||||
"components.RequestList.next": "次",
|
||||
"components.RequestList.previous": "戻る",
|
||||
"components.RequestList.requestedAt": "リクエスト日時",
|
||||
"components.RequestList.requests": "リクエスト",
|
||||
"components.RequestList.showingresults": "<strong>{total}</strong>中<strong>{from}</strong>~<strong>{to}</strong>件",
|
||||
"components.RequestList.status": "状態",
|
||||
"components.RequestModal.cancel": "キャンセルリクエスト",
|
||||
"components.RequestModal.cancelling": "取り消し中...",
|
||||
"components.RequestModal.cancelrequest": "このリクエストをキャンセルしてよろしいですか?",
|
||||
"components.RequestModal.close": "",
|
||||
"components.RequestModal.extras": "",
|
||||
"components.RequestModal.notrequested": "",
|
||||
"components.RequestModal.numberofepisodes": "",
|
||||
"components.RequestModal.pendingrequest": "",
|
||||
"components.RequestModal.close": "閉じる",
|
||||
"components.RequestModal.extras": "おまけ",
|
||||
"components.RequestModal.notrequested": "リクエストされていない",
|
||||
"components.RequestModal.numberofepisodes": "エピソード数",
|
||||
"components.RequestModal.pendingrequest": "{title}がリクエスト中",
|
||||
"components.RequestModal.request": "リクエストする",
|
||||
"components.RequestModal.requestCancel": "",
|
||||
"components.RequestModal.requestSuccess": "",
|
||||
"components.RequestModal.requestadmin": "このリクエストが今すぐ承認致します。よろしいですか?",
|
||||
"components.RequestModal.requestfrom": "",
|
||||
"components.RequestModal.requesting": "",
|
||||
"components.RequestModal.requestseasons": "",
|
||||
"components.RequestModal.requesttitle": "",
|
||||
"components.RequestModal.season": "",
|
||||
"components.RequestModal.seasonnumber": "",
|
||||
"components.RequestModal.selectseason": "",
|
||||
"components.RequestModal.requestCancel": "<strong>{title}</strong>のリクエストは取り消されました",
|
||||
"components.RequestModal.requestSuccess": "<strong>{title}</strong>のリクエストは完了しました。",
|
||||
"components.RequestModal.requestadmin": "このリクエストは今すぐ承認されます。",
|
||||
"components.RequestModal.requestfrom": "{username}はすでにリクエストを上げています",
|
||||
"components.RequestModal.requesting": "リクエスト中…",
|
||||
"components.RequestModal.requestseasons": "{seasonCount} {seasonCount, plural, one {Season} other {Seasons}}をリクエスト",
|
||||
"components.RequestModal.requesttitle": "{title}をリクエスト",
|
||||
"components.RequestModal.season": "シーズン",
|
||||
"components.RequestModal.seasonnumber": "シーズン{number}",
|
||||
"components.RequestModal.selectseason": "シーズンを選ぶ",
|
||||
"components.RequestModal.status": "状態",
|
||||
"components.Search.searchresults": "",
|
||||
"components.Settings.Notifications.agentenabled": "",
|
||||
"components.Settings.Notifications.authPass": "",
|
||||
"components.Settings.Notifications.authUser": "",
|
||||
"components.Settings.Notifications.emailsender": "",
|
||||
"components.Settings.Notifications.enableSsl": "",
|
||||
"components.Settings.Notifications.save": "",
|
||||
"components.Settings.Notifications.saving": "",
|
||||
"components.Settings.Notifications.smtpHost": "",
|
||||
"components.Settings.Notifications.smtpPort": "",
|
||||
"components.Settings.Notifications.validationFromRequired": "",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "",
|
||||
"components.Settings.Notifications.validationSmtpPortRequired": "",
|
||||
"components.Settings.Notifications.validationWebhookUrlRequired": "",
|
||||
"components.Settings.Notifications.webhookUrl": "",
|
||||
"components.Settings.Notifications.webhookUrlPlaceholder": "",
|
||||
"components.Settings.RadarrModal.add": "",
|
||||
"components.Settings.RadarrModal.apiKey": "",
|
||||
"components.Settings.RadarrModal.apiKeyPlaceholder": "",
|
||||
"components.Settings.RadarrModal.baseUrl": "",
|
||||
"components.Settings.RadarrModal.baseUrlPlaceholder": "",
|
||||
"components.Settings.RadarrModal.createradarr": "",
|
||||
"components.Settings.RadarrModal.defaultserver": "",
|
||||
"components.Settings.RadarrModal.editradarr": "",
|
||||
"components.Settings.RadarrModal.hostname": "",
|
||||
"components.Settings.RadarrModal.minimumAvailability": "",
|
||||
"components.Settings.RadarrModal.port": "",
|
||||
"components.Settings.RadarrModal.qualityprofile": "",
|
||||
"components.Settings.RadarrModal.rootfolder": "",
|
||||
"components.Settings.RadarrModal.save": "",
|
||||
"components.Settings.RadarrModal.saving": "",
|
||||
"components.Settings.RadarrModal.selectMinimumAvailability": "",
|
||||
"components.Settings.RadarrModal.selectQualityProfile": "",
|
||||
"components.Settings.RadarrModal.selectRootFolder": "",
|
||||
"components.Settings.RadarrModal.server4k": "",
|
||||
"components.Settings.RadarrModal.servername": "",
|
||||
"components.Settings.RadarrModal.servernamePlaceholder": "",
|
||||
"components.Settings.RadarrModal.ssl": "",
|
||||
"components.Settings.RadarrModal.test": "",
|
||||
"components.Settings.RadarrModal.testing": "",
|
||||
"components.Settings.RadarrModal.toastRadarrTestFailure": "",
|
||||
"components.Settings.RadarrModal.toastRadarrTestSuccess": "",
|
||||
"components.Settings.RadarrModal.validationApiKeyRequired": "",
|
||||
"components.Settings.RadarrModal.validationHostnameRequired": "",
|
||||
"components.Settings.RadarrModal.validationPortRequired": "",
|
||||
"components.Settings.RadarrModal.validationProfileRequired": "",
|
||||
"components.Settings.RadarrModal.validationRootFolderRequired": "",
|
||||
"components.Settings.SonarrModal.add": "",
|
||||
"components.Settings.SonarrModal.apiKey": "",
|
||||
"components.Settings.SonarrModal.apiKeyPlaceholder": "",
|
||||
"components.Settings.SonarrModal.baseUrl": "",
|
||||
"components.Settings.SonarrModal.baseUrlPlaceholder": "",
|
||||
"components.Settings.SonarrModal.createsonarr": "",
|
||||
"components.Settings.SonarrModal.defaultserver": "",
|
||||
"components.Settings.SonarrModal.editsonarr": "",
|
||||
"components.Settings.SonarrModal.hostname": "",
|
||||
"components.Settings.SonarrModal.port": "",
|
||||
"components.Settings.SonarrModal.qualityprofile": "",
|
||||
"components.Settings.SonarrModal.rootfolder": "",
|
||||
"components.Settings.SonarrModal.save": "",
|
||||
"components.Settings.SonarrModal.saving": "",
|
||||
"components.Settings.SonarrModal.seasonfolders": "",
|
||||
"components.Settings.SonarrModal.selectQualityProfile": "",
|
||||
"components.Settings.SonarrModal.selectRootFolder": "",
|
||||
"components.Settings.SonarrModal.server4k": "",
|
||||
"components.Settings.SonarrModal.servername": "",
|
||||
"components.Settings.SonarrModal.servernamePlaceholder": "",
|
||||
"components.Settings.SonarrModal.ssl": "",
|
||||
"components.Settings.SonarrModal.test": "",
|
||||
"components.Settings.SonarrModal.testing": "",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "",
|
||||
"components.Settings.SonarrModal.validationApiKeyRequired": "",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "",
|
||||
"components.Settings.SonarrModal.validationPortRequired": "",
|
||||
"components.Settings.SonarrModal.validationProfileRequired": "",
|
||||
"components.Settings.SonarrModal.validationRootFolderRequired": "",
|
||||
"components.Settings.activeProfile": "",
|
||||
"components.Settings.addradarr": "",
|
||||
"components.Settings.address": "",
|
||||
"components.Settings.addsonarr": "",
|
||||
"components.Settings.apikey": "",
|
||||
"components.Settings.applicationurl": "",
|
||||
"components.Settings.cancelscan": "",
|
||||
"components.Settings.copied": "",
|
||||
"components.Settings.currentlibrary": "",
|
||||
"components.Settings.default": "",
|
||||
"components.Settings.default4k": "",
|
||||
"components.Settings.delete": "",
|
||||
"components.Settings.deleteserverconfirm": "",
|
||||
"components.Settings.edit": "",
|
||||
"components.Settings.generalsettings": "",
|
||||
"components.Settings.generalsettingsDescription": "",
|
||||
"components.Settings.hostname": "",
|
||||
"components.Settings.jobname": "",
|
||||
"components.Settings.librariesRemaining": "",
|
||||
"components.Settings.manualscan": "",
|
||||
"components.Settings.manualscanDescription": "",
|
||||
"components.Settings.menuAbout": "",
|
||||
"components.Settings.menuGeneralSettings": "",
|
||||
"components.Settings.menuJobs": "",
|
||||
"components.Settings.menuLogs": "",
|
||||
"components.Settings.menuNotifications": "",
|
||||
"components.Settings.menuPlexSettings": "",
|
||||
"components.Settings.menuServices": "",
|
||||
"components.Settings.nextexecution": "",
|
||||
"components.Settings.notificationsettings": "",
|
||||
"components.Settings.notificationsettingsDescription": "",
|
||||
"components.Settings.notrunning": "",
|
||||
"components.Settings.plexlibraries": "",
|
||||
"components.Settings.plexlibrariesDescription": "",
|
||||
"components.Settings.plexsettings": "",
|
||||
"components.Settings.plexsettingsDescription": "",
|
||||
"components.Settings.port": "",
|
||||
"components.Settings.radarrSettingsDescription": "",
|
||||
"components.Settings.radarrsettings": "",
|
||||
"components.Settings.runnow": "",
|
||||
"components.Settings.save": "",
|
||||
"components.Settings.saving": "",
|
||||
"components.Settings.servername": "",
|
||||
"components.Settings.servernamePlaceholder": "",
|
||||
"components.Settings.sonarrSettingsDescription": "",
|
||||
"components.Settings.sonarrsettings": "",
|
||||
"components.Settings.ssl": "",
|
||||
"components.Settings.startscan": "",
|
||||
"components.Settings.sync": "",
|
||||
"components.Settings.syncing": "",
|
||||
"components.Setup.configureplex": "",
|
||||
"components.Setup.configureservices": "",
|
||||
"components.Setup.continue": "",
|
||||
"components.Setup.finish": "",
|
||||
"components.Setup.finishing": "",
|
||||
"components.Setup.loginwithplex": "",
|
||||
"components.Setup.signinMessage": "",
|
||||
"components.Setup.welcome": "",
|
||||
"components.Slider.noresults": "",
|
||||
"components.TitleCard.movie": "",
|
||||
"components.TitleCard.tvshow": "",
|
||||
"components.TvDetails.approve": "",
|
||||
"components.TvDetails.approverequests": "",
|
||||
"components.TvDetails.available": "",
|
||||
"components.Search.searchresults": "検索結果",
|
||||
"components.Settings.Notifications.agentenabled": "エージェントを有効にする",
|
||||
"components.Settings.Notifications.authPass": "認証パスワード",
|
||||
"components.Settings.Notifications.authUser": "認証ユーザー",
|
||||
"components.Settings.Notifications.emailsender": "配信元メールアドレス",
|
||||
"components.Settings.Notifications.enableSsl": "SSLを有効にする",
|
||||
"components.Settings.Notifications.save": "変更を保存",
|
||||
"components.Settings.Notifications.saving": "保存中...",
|
||||
"components.Settings.Notifications.smtpHost": "SMTPホスト",
|
||||
"components.Settings.Notifications.smtpPort": "SMTPポート",
|
||||
"components.Settings.Notifications.validationFromRequired": "配信元メールアドレスの入力は必要です",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "SMTPホストの入力は必要です",
|
||||
"components.Settings.Notifications.validationSmtpPortRequired": "SMTPポートの入力は必要です",
|
||||
"components.Settings.Notifications.validationWebhookUrlRequired": "ウェブフックURLの入力は必要です",
|
||||
"components.Settings.Notifications.webhookUrl": "ウェブフックURL",
|
||||
"components.Settings.Notifications.webhookUrlPlaceholder": "サーバー設定 > 連携サービス > ウェブフック",
|
||||
"components.Settings.RadarrModal.add": "サーバーを追加",
|
||||
"components.Settings.RadarrModal.apiKey": "APIキー",
|
||||
"components.Settings.RadarrModal.apiKeyPlaceholder": "RadarrのAPIキー",
|
||||
"components.Settings.RadarrModal.baseUrl": "ベースURL",
|
||||
"components.Settings.RadarrModal.baseUrlPlaceholder": "例:/radarr",
|
||||
"components.Settings.RadarrModal.createradarr": "Radarrサーバーを追加",
|
||||
"components.Settings.RadarrModal.defaultserver": "デフォルトサーバー",
|
||||
"components.Settings.RadarrModal.editradarr": "Radarrサーバーを編集",
|
||||
"components.Settings.RadarrModal.hostname": "ホスト名",
|
||||
"components.Settings.RadarrModal.minimumAvailability": "最低リリース状況",
|
||||
"components.Settings.RadarrModal.port": "ポート",
|
||||
"components.Settings.RadarrModal.qualityprofile": "画質プロファイル",
|
||||
"components.Settings.RadarrModal.rootfolder": "ルートフォルダー",
|
||||
"components.Settings.RadarrModal.save": "変更を保存",
|
||||
"components.Settings.RadarrModal.saving": "保存中...",
|
||||
"components.Settings.RadarrModal.selectMinimumAvailability": "最低リリース状況を選ぶ",
|
||||
"components.Settings.RadarrModal.selectQualityProfile": "画質プロファイルを選ぶ",
|
||||
"components.Settings.RadarrModal.selectRootFolder": "ルートフォルダーを選ぶ",
|
||||
"components.Settings.RadarrModal.server4k": "4Kサーバー",
|
||||
"components.Settings.RadarrModal.servername": "サーバー名",
|
||||
"components.Settings.RadarrModal.servernamePlaceholder": "Radarrサーバー",
|
||||
"components.Settings.RadarrModal.ssl": "SSL",
|
||||
"components.Settings.RadarrModal.test": "テストする",
|
||||
"components.Settings.RadarrModal.testing": "テスト中...",
|
||||
"components.Settings.RadarrModal.toastRadarrTestFailure": "Radarrサーバーの接続は失敗しました",
|
||||
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Radarrサーバーの接続は成功しました!",
|
||||
"components.Settings.RadarrModal.validationApiKeyRequired": "APIキーの入力が必要です",
|
||||
"components.Settings.RadarrModal.validationHostnameRequired": "ホスト名/IPの入力が必要です",
|
||||
"components.Settings.RadarrModal.validationPortRequired": "ポートの入力が必要です",
|
||||
"components.Settings.RadarrModal.validationProfileRequired": "プロファイルの選択が必要です",
|
||||
"components.Settings.RadarrModal.validationRootFolderRequired": "ルートフォルダーの選択が必要です",
|
||||
"components.Settings.SonarrModal.add": "サーバーを追加",
|
||||
"components.Settings.SonarrModal.apiKey": "APIキー",
|
||||
"components.Settings.SonarrModal.apiKeyPlaceholder": "SonarrのAPIキー",
|
||||
"components.Settings.SonarrModal.baseUrl": "ベースURL",
|
||||
"components.Settings.SonarrModal.baseUrlPlaceholder": "例:/sonarr",
|
||||
"components.Settings.SonarrModal.createsonarr": "Sonarrサーバーを追加",
|
||||
"components.Settings.SonarrModal.defaultserver": "デフォルトサーバー",
|
||||
"components.Settings.SonarrModal.editsonarr": "Sonarrサーバーを編集",
|
||||
"components.Settings.SonarrModal.hostname": "ホスト名",
|
||||
"components.Settings.SonarrModal.port": "ポート",
|
||||
"components.Settings.SonarrModal.qualityprofile": "画質プロファイル",
|
||||
"components.Settings.SonarrModal.rootfolder": "ルートフォルダー",
|
||||
"components.Settings.SonarrModal.save": "変更を保存",
|
||||
"components.Settings.SonarrModal.saving": "保存中...",
|
||||
"components.Settings.SonarrModal.seasonfolders": "シーズンフォルダー",
|
||||
"components.Settings.SonarrModal.selectQualityProfile": "画質プロファイルを選ぶ",
|
||||
"components.Settings.SonarrModal.selectRootFolder": "ルートフォルダーを選ぶ",
|
||||
"components.Settings.SonarrModal.server4k": "4Kサーバー",
|
||||
"components.Settings.SonarrModal.servername": "サーバー名",
|
||||
"components.Settings.SonarrModal.servernamePlaceholder": "Sonarrサーバー",
|
||||
"components.Settings.SonarrModal.ssl": "SSL",
|
||||
"components.Settings.SonarrModal.test": "テストする",
|
||||
"components.Settings.SonarrModal.testing": "テスト中...",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "Sonarrサーバーに接続できませんでした",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Sonarrサーバーの接続が成功しました!",
|
||||
"components.Settings.SonarrModal.validationApiKeyRequired": "APIキーの入力が必要です",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "ホスト名/IPの入力が必要です",
|
||||
"components.Settings.SonarrModal.validationPortRequired": "ポートの入力が必要です",
|
||||
"components.Settings.SonarrModal.validationProfileRequired": "プロファイルの選択が必要です",
|
||||
"components.Settings.SonarrModal.validationRootFolderRequired": "ルートフォルダーの選択が必要です",
|
||||
"components.Settings.activeProfile": "アクティブプロファイル",
|
||||
"components.Settings.addradarr": "Radarrサーバーを追加",
|
||||
"components.Settings.address": "アドレス",
|
||||
"components.Settings.addsonarr": "Sonarrサーバーを追加",
|
||||
"components.Settings.apikey": "APIキー",
|
||||
"components.Settings.applicationurl": "アプリケーションURL",
|
||||
"components.Settings.cancelscan": "スキャンをキャンセル",
|
||||
"components.Settings.copied": "APIキーをクリップボードにコピーされた",
|
||||
"components.Settings.currentlibrary": "現在のライブラリー: {name}",
|
||||
"components.Settings.default": "デフォルト",
|
||||
"components.Settings.default4k": "デフォルト4K",
|
||||
"components.Settings.delete": "削除",
|
||||
"components.Settings.deleteserverconfirm": "このサーバーを削除しますか?",
|
||||
"components.Settings.edit": "編集",
|
||||
"components.Settings.generalsettings": "一般設定",
|
||||
"components.Settings.generalsettingsDescription": "Overseerrの構成に関する設定です。",
|
||||
"components.Settings.hostname": "ホスト名/IP",
|
||||
"components.Settings.jobname": "ジョブ名",
|
||||
"components.Settings.librariesRemaining": "残りのライブラリー: {count}",
|
||||
"components.Settings.manualscan": "手動ライブラリースキャン",
|
||||
"components.Settings.manualscanDescription": "通常は6時間に一度しか実行されません。Overseerr は、Plex サーバーの最近追加されたフォルダをより頻繁にチェックします。初めて Plex を設定する場合は、一度手動でライブラリーをスキャンすることをお勧めします。",
|
||||
"components.Settings.menuAbout": "Overseerrについて",
|
||||
"components.Settings.menuGeneralSettings": "一般設定",
|
||||
"components.Settings.menuJobs": "ジョブ",
|
||||
"components.Settings.menuLogs": "ログ",
|
||||
"components.Settings.menuNotifications": "通知",
|
||||
"components.Settings.menuPlexSettings": "Plex",
|
||||
"components.Settings.menuServices": "連携サービス",
|
||||
"components.Settings.nextexecution": "次の実行",
|
||||
"components.Settings.notificationsettings": "通知設定",
|
||||
"components.Settings.notificationsettingsDescription": "ここでは、どのような通知を送信する又はどのサービスを使って送信するかを設定できます。",
|
||||
"components.Settings.notrunning": "実行されていない",
|
||||
"components.Settings.plexlibraries": "Plexライブラリー",
|
||||
"components.Settings.plexlibrariesDescription": "Overseerrがスキャンしてタイトルを探すライブラリ。リストにない場合、Plexの接続設定を保存し、下のボタンをクリックしてください。",
|
||||
"components.Settings.plexsettings": "Plexの設定",
|
||||
"components.Settings.plexsettingsDescription": "Plex サーバーの設定。Overseerr は、Plex サーバーを使用して、間隔をおいてライブラリをスキャンし、利用可能なコンテンツを確認します。",
|
||||
"components.Settings.port": "ポート",
|
||||
"components.Settings.radarrSettingsDescription": "Radarr接続設定。複数のサーバーを繋ぐことができますが、デフォルトで常にアクティブなのは2つのみ(1つは標準HD用、もう1つは4K用)。管理者は、新しいリクエストに使用するサーバーを選択することができます。",
|
||||
"components.Settings.radarrsettings": "Radarr設定",
|
||||
"components.Settings.runnow": "今すぐ実行",
|
||||
"components.Settings.save": "変更を保存",
|
||||
"components.Settings.saving": "保存中...",
|
||||
"components.Settings.servername": "サーバー名 (自動設定)",
|
||||
"components.Settings.servernamePlaceholder": "Plexサーバー名",
|
||||
"components.Settings.sonarrSettingsDescription": "Sonarr接続設定。複数のサーバーを繋ぐことができますが、デフォルトで常にアクティブなのは2つのみ(1つは標準HD用、もう1つは4K用)。管理者は、新しいリクエストに使用するサーバーを選択することができます。",
|
||||
"components.Settings.sonarrsettings": "Sonarr設定",
|
||||
"components.Settings.ssl": "SSL",
|
||||
"components.Settings.startscan": "スキャンを開始",
|
||||
"components.Settings.sync": "Plexライブラリーの同期",
|
||||
"components.Settings.syncing": "同期中…",
|
||||
"components.Setup.configureplex": "Plexの設定",
|
||||
"components.Setup.configureservices": "連携サービスの設定",
|
||||
"components.Setup.continue": "続行",
|
||||
"components.Setup.finish": "セットアップを完了",
|
||||
"components.Setup.finishing": "保存中...",
|
||||
"components.Setup.loginwithplex": "Plexでログイン",
|
||||
"components.Setup.signinMessage": "Plexアカウントでログインして始める",
|
||||
"components.Setup.welcome": "Overseerrへようこそ",
|
||||
"components.Slider.noresults": "結果はありません",
|
||||
"components.TitleCard.movie": "映画",
|
||||
"components.TitleCard.tvshow": "シリーズ",
|
||||
"components.TvDetails.approve": "承認",
|
||||
"components.TvDetails.approverequests": "{requestCount}つの{requestCount, plural, one {リクエスト} other {リクエスト}}を承認する",
|
||||
"components.TvDetails.available": "鑑賞可能",
|
||||
"components.TvDetails.cancelrequest": "チャンセルリクエスト",
|
||||
"components.TvDetails.cast": "キャスト",
|
||||
"components.TvDetails.decline": "",
|
||||
"components.TvDetails.declinerequests": "",
|
||||
"components.TvDetails.manageModalClearMedia": "",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "",
|
||||
"components.TvDetails.manageModalNoRequests": "",
|
||||
"components.TvDetails.decline": "拒否する",
|
||||
"components.TvDetails.declinerequests": "{requestCount}つの{requestCount, plural, one {リクエスト} other {リクエスト}}を拒否する",
|
||||
"components.TvDetails.manageModalClearMedia": "メディアのデータを消去",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "リクエストを含め、メーディアのデータをすべて消去されます。この操作は元に戻すことができません。このアイテムが Plex ライブラリに存在する場合、メディア情報は次の同期で再作成されます。",
|
||||
"components.TvDetails.manageModalNoRequests": "リクエストがありません",
|
||||
"components.TvDetails.manageModalRequests": "リクエスト",
|
||||
"components.TvDetails.manageModalTitle": "",
|
||||
"components.TvDetails.manageModalTitle": "シリーズの管理",
|
||||
"components.TvDetails.originallanguage": "言語",
|
||||
"components.TvDetails.overview": "ストーリー",
|
||||
"components.TvDetails.overviewunavailable": "",
|
||||
"components.TvDetails.overviewunavailable": "ストーリー情報がありません",
|
||||
"components.TvDetails.pending": "リクエスト中",
|
||||
"components.TvDetails.recommendations": "オススメの作品",
|
||||
"components.TvDetails.recommendationssubtext": "",
|
||||
"components.TvDetails.recommendationssubtext": "{title}が好きだった人は、こんなのも好きかもしれません...",
|
||||
"components.TvDetails.request": "リクエストする",
|
||||
"components.TvDetails.requestmore": "",
|
||||
"components.TvDetails.similar": "",
|
||||
"components.TvDetails.similarsubtext": "",
|
||||
"components.TvDetails.requestmore": "もっとリクエストする",
|
||||
"components.TvDetails.similar": "類似シリーズ",
|
||||
"components.TvDetails.similarsubtext": "{title}に類似したシリーズ",
|
||||
"components.TvDetails.status": "状態",
|
||||
"components.TvDetails.unavailable": "",
|
||||
"components.TvDetails.unavailable": "鑑賞不可",
|
||||
"components.TvDetails.userrating": "ユーザー評価",
|
||||
"components.UserEdit.admin": "",
|
||||
"components.UserEdit.adminDescription": "",
|
||||
"components.UserEdit.autoapprove": "",
|
||||
"components.UserEdit.autoapproveDescription": "",
|
||||
"components.UserEdit.avatar": "",
|
||||
"components.UserEdit.edituser": "",
|
||||
"components.UserEdit.email": "",
|
||||
"components.UserEdit.managerequests": "",
|
||||
"components.UserEdit.managerequestsDescription": "",
|
||||
"components.UserEdit.permissions": "",
|
||||
"components.UserEdit.admin": "管理者",
|
||||
"components.UserEdit.adminDescription": "管理者のフルアクセス。すべての権限チェックをバイパスします。",
|
||||
"components.UserEdit.autoapprove": "自動承認",
|
||||
"components.UserEdit.autoapproveDescription": "このユーザーが行ったリクエストの自動承認をします。",
|
||||
"components.UserEdit.avatar": "アバター",
|
||||
"components.UserEdit.edituser": "ユーザーの編集",
|
||||
"components.UserEdit.email": "メール",
|
||||
"components.UserEdit.managerequests": "リクエストの管理",
|
||||
"components.UserEdit.managerequestsDescription": "Overseerr のリクエストを管理する権限を付与します。リクエストの承認と拒否を含みます。",
|
||||
"components.UserEdit.permissions": "アクセス権限",
|
||||
"components.UserEdit.request": "リクエストする",
|
||||
"components.UserEdit.requestDescription": "",
|
||||
"components.UserEdit.save": "",
|
||||
"components.UserEdit.saving": "",
|
||||
"components.UserEdit.settings": "",
|
||||
"components.UserEdit.settingsDescription": "",
|
||||
"components.UserEdit.userfail": "",
|
||||
"components.UserEdit.username": "",
|
||||
"components.UserEdit.users": "",
|
||||
"components.UserEdit.usersDescription": "",
|
||||
"components.UserEdit.usersaved": "",
|
||||
"components.UserEdit.vote": "",
|
||||
"components.UserEdit.voteDescription": "",
|
||||
"components.UserList.admin": "",
|
||||
"components.UserList.created": "",
|
||||
"components.UserList.delete": "",
|
||||
"components.UserList.edit": "",
|
||||
"components.UserList.lastupdated": "",
|
||||
"components.UserList.plexuser": "",
|
||||
"components.UserList.role": "",
|
||||
"components.UserList.totalrequests": "",
|
||||
"components.UserList.user": "",
|
||||
"components.UserList.userlist": "",
|
||||
"components.UserList.username": "",
|
||||
"components.UserList.usertype": "",
|
||||
"i18n.approve": "",
|
||||
"i18n.approved": "",
|
||||
"i18n.available": "",
|
||||
"i18n.cancel": "",
|
||||
"i18n.decline": "",
|
||||
"i18n.declined": "",
|
||||
"i18n.delete": "",
|
||||
"i18n.movies": "",
|
||||
"i18n.partiallyavailable": "",
|
||||
"components.UserEdit.requestDescription": "映画やテレビ番組のリクエスト権限を付与します。",
|
||||
"components.UserEdit.save": "保存",
|
||||
"components.UserEdit.saving": "保存中...",
|
||||
"components.UserEdit.settings": "設定の管理",
|
||||
"components.UserEdit.settingsDescription": "すべてのOverseerrの設定を変更する権限を付与します。他の人にこの権限を付与するには、ユーザーがこの権限を持っていなければなりません。",
|
||||
"components.UserEdit.userfail": "ユーザーの保存する時に問題が発生しました。",
|
||||
"components.UserEdit.username": "ユーザー名",
|
||||
"components.UserEdit.users": "ユーザーの管理",
|
||||
"components.UserEdit.usersDescription": "Overseerrユーザーを管理する権限を付与します。この権限を持つユーザーは、管理者権限を持つユーザーを変更したり、付与したりすることはできません。",
|
||||
"components.UserEdit.usersaved": "ユーザーが保存された",
|
||||
"components.UserEdit.vote": "投票",
|
||||
"components.UserEdit.voteDescription": "リクエストに投票する権限を付与します(投票はまだ実装されていません)",
|
||||
"components.UserList.admin": "管理者",
|
||||
"components.UserList.created": "作成日",
|
||||
"components.UserList.delete": "削除",
|
||||
"components.UserList.edit": "編集",
|
||||
"components.UserList.lastupdated": "最終更新日",
|
||||
"components.UserList.plexuser": "Plexユーザー",
|
||||
"components.UserList.role": "役割",
|
||||
"components.UserList.totalrequests": "総リクエスト数",
|
||||
"components.UserList.user": "ユーザー",
|
||||
"components.UserList.userlist": "ユーザーリスト",
|
||||
"components.UserList.username": "ユーザー名",
|
||||
"components.UserList.usertype": "ユーザーの種類",
|
||||
"i18n.approve": "承認",
|
||||
"i18n.approved": "承認済み",
|
||||
"i18n.available": "鑑賞可能",
|
||||
"i18n.cancel": "キャンセル",
|
||||
"i18n.decline": "拒否する",
|
||||
"i18n.declined": "拒否済み",
|
||||
"i18n.delete": "削除",
|
||||
"i18n.movies": "映画",
|
||||
"i18n.partiallyavailable": "一部鑑賞可能",
|
||||
"i18n.pending": "リクエスト中",
|
||||
"i18n.processing": "",
|
||||
"i18n.tvshows": "",
|
||||
"i18n.unavailable": "",
|
||||
"pages.internalServerError": "",
|
||||
"i18n.processing": "処理中…",
|
||||
"i18n.tvshows": "シリーズ",
|
||||
"i18n.unavailable": "鑑賞不可",
|
||||
"pages.internalServerError": "{statusCode} - 内部サーバーエラー",
|
||||
"pages.oops": "ああ",
|
||||
"pages.pageNotFound": "",
|
||||
"pages.pageNotFound": "404 - ページが見つかりません",
|
||||
"pages.returnHome": "ホームへ戻る",
|
||||
"pages.serviceUnavailable": "",
|
||||
"pages.somethingWentWrong": ""
|
||||
"pages.serviceUnavailable": "{statusCode} - サービスが利用できません",
|
||||
"pages.somethingWentWrong": "{statusCode} - 問題が発生しました"
|
||||
}
|
||||
|
||||
306
src/i18n/locale/nb_NO.json
Normal file
306
src/i18n/locale/nb_NO.json
Normal file
@@ -0,0 +1,306 @@
|
||||
{
|
||||
"components.Discover.discovermovies": "Populære filmer",
|
||||
"components.Discover.discovertv": "Populære serier",
|
||||
"components.Discover.nopending": "Ingen ventende forespørsler",
|
||||
"components.Discover.popularmovies": "Populære filmer",
|
||||
"components.Discover.populartv": "Populære serier",
|
||||
"components.Discover.recentlyAdded": "Nylig tillagt",
|
||||
"components.Discover.recentrequests": "Nylige forespørsler",
|
||||
"components.Discover.trending": "På vei opp",
|
||||
"components.Discover.upcoming": "Kommende filmer",
|
||||
"components.Discover.upcomingmovies": "Kommende filmer",
|
||||
"components.Layout.LanguagePicker.changelanguage": "Endre språk",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "Søk i filmer og TV-serier",
|
||||
"components.Layout.Sidebar.dashboard": "Oppdag",
|
||||
"components.Layout.Sidebar.requests": "Forespørsler",
|
||||
"components.Layout.Sidebar.settings": "Innstillinger",
|
||||
"components.Layout.Sidebar.users": "Brukere",
|
||||
"components.Layout.UserDropdown.signout": "Logg ut",
|
||||
"components.Layout.alphawarning": "Dette er programvare i alfa-stadie. Nesten alt vil være ufunksjonelt eller ustabilt. Innrapporter feil til Overseerr på GitHub.",
|
||||
"components.Login.signinplex": "Logg inn for å fortsette",
|
||||
"components.MovieDetails.approve": "Godta",
|
||||
"components.MovieDetails.available": "Tilgjengelig",
|
||||
"components.MovieDetails.budget": "Budsjett",
|
||||
"components.MovieDetails.cancelrequest": "Kan ikke forespørre",
|
||||
"components.MovieDetails.cast": "Besetning",
|
||||
"components.MovieDetails.decline": "Avslå",
|
||||
"components.MovieDetails.manageModalClearMedia": "Tøm all mediadata",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "Dette vil fjerne all mediadata, inkludert alle forespørsler for dette elementet, for godt. Hvis elementet finnes i ditt Plex-bibliotek, vil mediainfoen gjenskapes ved neste synkronisering.",
|
||||
"components.MovieDetails.manageModalNoRequests": "Ingen forespørsler",
|
||||
"components.MovieDetails.manageModalRequests": "Forespørsler",
|
||||
"components.MovieDetails.manageModalTitle": "Håndter film",
|
||||
"components.MovieDetails.originallanguage": "Originalspråk",
|
||||
"components.MovieDetails.overview": "Oversikt",
|
||||
"components.MovieDetails.overviewunavailable": "Oversikt utilgjengelig",
|
||||
"components.MovieDetails.pending": "Ventende",
|
||||
"components.MovieDetails.recommendations": "Anbefalninger",
|
||||
"components.MovieDetails.recommendationssubtext": "Hvis du likte {title}, kan det hende du også liker …",
|
||||
"components.MovieDetails.releasedate": "Utgivelsesdato",
|
||||
"components.MovieDetails.request": "Forespørsel",
|
||||
"components.MovieDetails.revenue": "Inntekter",
|
||||
"components.MovieDetails.runtime": "{minutes} minutter",
|
||||
"components.MovieDetails.similar": "Lignende titler",
|
||||
"components.MovieDetails.similarsubtext": "Andre filmer som ligner {title}",
|
||||
"components.MovieDetails.status": "Status",
|
||||
"components.MovieDetails.unavailable": "Utilgjengelig",
|
||||
"components.MovieDetails.userrating": "Brukervurdering",
|
||||
"components.MovieDetails.viewrequest": "Vis forespørsel",
|
||||
"components.PersonDetails.appearsin": "Finnes i",
|
||||
"components.PersonDetails.ascharacter": "som {character}",
|
||||
"components.PersonDetails.nobiography": "Ingen biografi tilgjengelig.",
|
||||
"components.PlexLoginButton.loading": "Laster inn …",
|
||||
"components.PlexLoginButton.loggingin": "Logger inn …",
|
||||
"components.PlexLoginButton.loginwithplex": "Logg inn med Plex",
|
||||
"components.RequestBlock.seasons": "Sesonger",
|
||||
"components.RequestCard.all": "Alle",
|
||||
"components.RequestCard.requestedby": "Forespurt av {username}",
|
||||
"components.RequestCard.seasons": "Sesonger",
|
||||
"components.RequestList.RequestItem.notavailable": "I/T",
|
||||
"components.RequestList.RequestItem.requestedby": "Fjernet av {username}",
|
||||
"components.RequestList.RequestItem.seasons": "Sesonger",
|
||||
"components.RequestList.mediaInfo": "Mediainfo",
|
||||
"components.RequestList.modifiedBy": "Sist endret av",
|
||||
"components.RequestList.next": "Neste",
|
||||
"components.RequestList.previous": "Forrige",
|
||||
"components.RequestList.requestedAt": "Forespurt",
|
||||
"components.RequestList.requests": "Forespørsler",
|
||||
"components.RequestList.showingresults": "Viser <strong>{from}</strong> til <strong>{to}</strong> av <strong>{total}</strong> resultater",
|
||||
"components.RequestList.status": "Status",
|
||||
"components.RequestModal.cancel": "Avbryt forespørsel",
|
||||
"components.RequestModal.cancelling": "Avbryter …",
|
||||
"components.RequestModal.cancelrequest": "Dette vil fjerne din forespørsel. Er du sikker på at du vil fortsette?",
|
||||
"components.RequestModal.close": "Lukk",
|
||||
"components.RequestModal.extras": "Ekstra",
|
||||
"components.RequestModal.notrequested": "Ikke forespurt",
|
||||
"components.RequestModal.numberofepisodes": "Antall episoder",
|
||||
"components.RequestModal.pendingrequest": "Ventende forespørsel for {title}",
|
||||
"components.RequestModal.request": "Forespørsel",
|
||||
"components.RequestModal.requestCancel": "Forespørsel for <strong>{title}</strong> avbrutt",
|
||||
"components.RequestModal.requestSuccess": "<strong>{title}</strong> forespurt.",
|
||||
"components.RequestModal.requestadmin": "Din forespørsel vil bli godkjent umiddelbart.",
|
||||
"components.RequestModal.requestfrom": "Det er for tiden en ventende forespørsel fra {username}",
|
||||
"components.RequestModal.requesting": "Forespør …",
|
||||
"components.RequestModal.requestseasons": "Forespør {seasonCount} {seasonCount, plural, one {Season} other {Seasons}}",
|
||||
"components.RequestModal.requesttitle": "Forespør {title}",
|
||||
"components.RequestModal.season": "Sesong",
|
||||
"components.RequestModal.seasonnumber": "Sesong {number}",
|
||||
"components.RequestModal.selectseason": "Velg sesong(er)",
|
||||
"components.RequestModal.status": "Status",
|
||||
"components.Search.searchresults": "Søkeresultater",
|
||||
"components.Settings.Notifications.agentenabled": "Agent påskrudd",
|
||||
"components.Settings.Notifications.authPass": "Identitetsbekreftelsespassord",
|
||||
"components.Settings.Notifications.authUser": "Identitetsbekreftelsesbrukernavn",
|
||||
"components.Settings.Notifications.emailsender": "E-postforsendelsesadresse",
|
||||
"components.Settings.Notifications.enableSsl": "Skru på SSL",
|
||||
"components.Settings.Notifications.save": "Lagre endringer",
|
||||
"components.Settings.Notifications.saving": "Lagrer …",
|
||||
"components.Settings.Notifications.smtpHost": "SMTP-vert",
|
||||
"components.Settings.Notifications.smtpPort": "SMTP-port",
|
||||
"components.Settings.Notifications.validationFromRequired": "Du må angi en e-postforsendelsesadresse",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "Du må angi en SMTP-vert",
|
||||
"components.Settings.Notifications.validationSmtpPortRequired": "Du må angi en SMTP-port",
|
||||
"components.Settings.Notifications.validationWebhookUrlRequired": "Du må angi en vevkroksnettadresse",
|
||||
"components.Settings.Notifications.webhookUrl": "Vevkroksnettadresse",
|
||||
"components.Settings.Notifications.webhookUrlPlaceholder": "Tjenerinnstillinger → Integrasjoner → Vevkroker",
|
||||
"components.Settings.RadarrModal.add": "Legg til tjener",
|
||||
"components.Settings.RadarrModal.apiKey": "API-nøkkel",
|
||||
"components.Settings.RadarrModal.apiKeyPlaceholder": "Din API-nøkkel for Radarr",
|
||||
"components.Settings.RadarrModal.baseUrl": "Grunn-nettadresse",
|
||||
"components.Settings.RadarrModal.baseUrlPlaceholder": "Eksempel: /radarr",
|
||||
"components.Settings.RadarrModal.createradarr": "Opprett ny Radarr-tjener",
|
||||
"components.Settings.RadarrModal.defaultserver": "Forvalgt tjener",
|
||||
"components.Settings.RadarrModal.editradarr": "Rediger Radarr-tjener",
|
||||
"components.Settings.RadarrModal.hostname": "Vertsnavn",
|
||||
"components.Settings.RadarrModal.minimumAvailability": "Minimumstilgjengelighet",
|
||||
"components.Settings.RadarrModal.port": "Port",
|
||||
"components.Settings.RadarrModal.qualityprofile": "Kvalitetsprofil",
|
||||
"components.Settings.RadarrModal.rootfolder": "Rotmappe",
|
||||
"components.Settings.RadarrModal.save": "Lagre endringer",
|
||||
"components.Settings.RadarrModal.saving": "Lagrer …",
|
||||
"components.Settings.RadarrModal.selectMinimumAvailability": "Velg minimumstilgjengelighet",
|
||||
"components.Settings.RadarrModal.selectQualityProfile": "Velg en kvalitetsmappe",
|
||||
"components.Settings.RadarrModal.selectRootFolder": "Legg til en rotmappe",
|
||||
"components.Settings.RadarrModal.server4k": "4K-tjener",
|
||||
"components.Settings.RadarrModal.servername": "Tjenernavn",
|
||||
"components.Settings.RadarrModal.servernamePlaceholder": "En Radarr-tjener",
|
||||
"components.Settings.RadarrModal.ssl": "SSL",
|
||||
"components.Settings.RadarrModal.test": "Test",
|
||||
"components.Settings.RadarrModal.testing": "Tester …",
|
||||
"components.Settings.RadarrModal.toastRadarrTestFailure": "Klarte ikke å koble til Radarr-tjener",
|
||||
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Radarr-tilknytning opprettet.",
|
||||
"components.Settings.RadarrModal.validationApiKeyRequired": "Du må angi en API-nøkkel",
|
||||
"components.Settings.RadarrModal.validationHostnameRequired": "Du må angi vertsnavn/IP",
|
||||
"components.Settings.RadarrModal.validationPortRequired": "Du må angi en port",
|
||||
"components.Settings.RadarrModal.validationProfileRequired": "Du må velge en profil",
|
||||
"components.Settings.RadarrModal.validationRootFolderRequired": "Du må velge en rotmappe",
|
||||
"components.Settings.SonarrModal.add": "Legg til tjener",
|
||||
"components.Settings.SonarrModal.apiKey": "API-nøkkel",
|
||||
"components.Settings.SonarrModal.apiKeyPlaceholder": "Din API-nøkkel for Sonarr",
|
||||
"components.Settings.SonarrModal.baseUrl": "Grunn-nettadresse",
|
||||
"components.Settings.SonarrModal.baseUrlPlaceholder": "Eksempel: /sonarr",
|
||||
"components.Settings.SonarrModal.createsonarr": "Opprett ny Sonarr-tjener",
|
||||
"components.Settings.SonarrModal.defaultserver": "Forvalgt tjener",
|
||||
"components.Settings.SonarrModal.editsonarr": "Rediger Sonarr-tjener",
|
||||
"components.Settings.SonarrModal.hostname": "Vertsnavn",
|
||||
"components.Settings.SonarrModal.port": "Port",
|
||||
"components.Settings.SonarrModal.qualityprofile": "Kvalitetsprofil",
|
||||
"components.Settings.SonarrModal.rootfolder": "Rotmappe",
|
||||
"components.Settings.SonarrModal.save": "Lagre endringer",
|
||||
"components.Settings.SonarrModal.saving": "Lagrer …",
|
||||
"components.Settings.SonarrModal.seasonfolders": "Sesongmapper",
|
||||
"components.Settings.SonarrModal.selectQualityProfile": "Velg en kvalitetsprofil",
|
||||
"components.Settings.SonarrModal.selectRootFolder": "Velg en rotmappe",
|
||||
"components.Settings.SonarrModal.server4k": "4K-tjener",
|
||||
"components.Settings.SonarrModal.servername": "Tjenernavn",
|
||||
"components.Settings.SonarrModal.servernamePlaceholder": "En Sonarr-tjener",
|
||||
"components.Settings.SonarrModal.ssl": "SSL",
|
||||
"components.Settings.SonarrModal.test": "Test",
|
||||
"components.Settings.SonarrModal.testing": "Tester …",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "Klarte ikke å koble til Sonarr-tjener",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Sonarr-tilknytning opprettet.",
|
||||
"components.Settings.SonarrModal.validationApiKeyRequired": "Du må angi en API-nøkkel",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "Du må angi vertsnavn/IP",
|
||||
"components.Settings.SonarrModal.validationPortRequired": "Du må angi en port",
|
||||
"components.Settings.SonarrModal.validationProfileRequired": "Du må velge en porfil",
|
||||
"components.Settings.SonarrModal.validationRootFolderRequired": "Du må velge en rotmappe",
|
||||
"components.Settings.activeProfile": "Aktiv profil",
|
||||
"components.Settings.addradarr": "Legg til Radarr-tjener",
|
||||
"components.Settings.address": "Adresse",
|
||||
"components.Settings.addsonarr": "Legg til Sonarr-tjener",
|
||||
"components.Settings.apikey": "API-nøkkel",
|
||||
"components.Settings.applicationurl": "Program-nettadresse",
|
||||
"components.Settings.cancelscan": "Avbryt skanning",
|
||||
"components.Settings.copied": "AP-nøkkel kopiert til utklippstavle",
|
||||
"components.Settings.currentlibrary": "Nåværende bibliotek: {name}",
|
||||
"components.Settings.default": "Forvalg",
|
||||
"components.Settings.default4k": "Forvalgt 4K",
|
||||
"components.Settings.delete": "Slett",
|
||||
"components.Settings.deleteserverconfirm": "Er du sikker på at du vil slette denne tjeneren?",
|
||||
"components.Settings.edit": "Rediger",
|
||||
"components.Settings.generalsettings": "Generelle innstilinger",
|
||||
"components.Settings.generalsettingsDescription": "Dette er innstillinger som har med det generelle Overseerr-oppsettet å gjøre.",
|
||||
"components.Settings.hostname": "Vertsnavn/IP",
|
||||
"components.Settings.jobname": "Jobbnavn",
|
||||
"components.Settings.librariesRemaining": "Bibliotek som gjenstår: {count}",
|
||||
"components.Settings.manualscan": "Manuell biblioteksskanning",
|
||||
"components.Settings.manualscanDescription": "Normalt vil dette kun kjøres hver sjette time. Overseerr sjekker din Plex-tjeners nylig tillagte mer aggresivt. Hvis dette er første gangen du setter opp Plex, anbefales en full manuell biblioteksskanning.",
|
||||
"components.Settings.menuAbout": "Om",
|
||||
"components.Settings.menuGeneralSettings": "Generelle innstillinger",
|
||||
"components.Settings.menuJobs": "Jobber",
|
||||
"components.Settings.menuLogs": "Logger",
|
||||
"components.Settings.menuNotifications": "Merknader",
|
||||
"components.Settings.menuPlexSettings": "Plex",
|
||||
"components.Settings.menuServices": "Tjenester",
|
||||
"components.Settings.nextexecution": "Neste kjøring",
|
||||
"components.Settings.notificationsettings": "Merknadsinnstillinger",
|
||||
"components.Settings.notificationsettingsDescription": "Har kan du velge hvilke type merknader som skal sendes gjennom en del tjenester.",
|
||||
"components.Settings.notrunning": "Kjører ikke",
|
||||
"components.Settings.plexlibraries": "Plex-bibliotek",
|
||||
"components.Settings.plexlibrariesDescription": "Bibliotekene Overseerr skanner for titler. Sett opp og lagre dine Plex-tilkoblingsinnstillinger og klikk på knappen nedenfor hvis ingen vises.",
|
||||
"components.Settings.plexsettings": "Plex-innstillinger",
|
||||
"components.Settings.plexsettingsDescription": "Sett opp innstillingene for din Plex-tjener. Overseerr bruker din Plex-tjener til å skanne ditt bibliotek med gjevne mellomrom for å se hvilket innhold som er tilgjengelig.",
|
||||
"components.Settings.port": "Port",
|
||||
"components.Settings.radarrSettingsDescription": "Sett opp din Radarr-tilkobling nedenfor. Du kan ha flere, men kun to aktive som forvalg (en for standard HD, og en for 4K). Administratorer kan overstyre hvilken tjener som brukes for nye forespørsler.",
|
||||
"components.Settings.radarrsettings": "Radarr-innstillinger",
|
||||
"components.Settings.runnow": "Kjør nå",
|
||||
"components.Settings.save": "Lagre endringer",
|
||||
"components.Settings.saving": "Lagrer …",
|
||||
"components.Settings.servername": "Tjenernavn (automatisk valgt)",
|
||||
"components.Settings.servernamePlaceholder": "Plex-tjenernavn",
|
||||
"components.Settings.sonarrSettingsDescription": "Sett opp din Sonarr-tilkobling nedenfor. Du kan ha flere, men kun to aktive som forvalg (en for standard HD, og en for 4K). Administratorer kan overstyre hvilken tjener som brukes for nye forespørsler.",
|
||||
"components.Settings.sonarrsettings": "Sonarr-innstillinger",
|
||||
"components.Settings.ssl": "SSL",
|
||||
"components.Settings.startscan": "Start skanning",
|
||||
"components.Settings.sync": "Synkroniser Plex-bibliotek",
|
||||
"components.Settings.syncing": "Synkroniserer …",
|
||||
"components.Setup.configureplex": "Sett opp Plex",
|
||||
"components.Setup.configureservices": "Sett opp tjenester",
|
||||
"components.Setup.continue": "Fortsett",
|
||||
"components.Setup.finish": "Fullfør oppsett",
|
||||
"components.Setup.finishing": "Fullfører …",
|
||||
"components.Setup.loginwithplex": "Logg inn med Plex",
|
||||
"components.Setup.signinMessage": "Start med å logge inn på din Plex-konto",
|
||||
"components.Setup.welcome": "Velkommen til Overseerr",
|
||||
"components.Slider.noresults": "Resultatløst",
|
||||
"components.TitleCard.movie": "Film",
|
||||
"components.TitleCard.tvshow": "Serier",
|
||||
"components.TvDetails.approve": "Godta",
|
||||
"components.TvDetails.approverequests": "Godkjenn {requestCount} {requestCount, plural, one {Request} other {Requests}}",
|
||||
"components.TvDetails.available": "Tilgjengelig",
|
||||
"components.TvDetails.cancelrequest": "Avbryt forespørsel",
|
||||
"components.TvDetails.cast": "Besetning",
|
||||
"components.TvDetails.decline": "Avslå",
|
||||
"components.TvDetails.declinerequests": "Avslå {requestCount} {requestCount, plural, one {Request} other {Requests}}",
|
||||
"components.TvDetails.manageModalClearMedia": "Tøm all mediadata",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "Dette vil fjerne all mediadata, inkludert alle forespørsler om dette elementet, for godt. Hvis dette elementet finnes i ditt Plex-bibliotek, vil mediainfoen ble gjenskapt ved neste synkronisering.",
|
||||
"components.TvDetails.manageModalNoRequests": "Ingen forespørsler",
|
||||
"components.TvDetails.manageModalRequests": "Forespørsler",
|
||||
"components.TvDetails.manageModalTitle": "Håndter serier",
|
||||
"components.TvDetails.originallanguage": "Originalspråk",
|
||||
"components.TvDetails.overview": "Oversikt",
|
||||
"components.TvDetails.overviewunavailable": "Oversikt utilgjengelig",
|
||||
"components.TvDetails.pending": "Ventende",
|
||||
"components.TvDetails.recommendations": "Anbefalninger",
|
||||
"components.TvDetails.recommendationssubtext": "Hvis du likte {title}, kan det hende du også liker …",
|
||||
"components.TvDetails.request": "Forespør",
|
||||
"components.TvDetails.requestmore": "Forespør flere",
|
||||
"components.TvDetails.similar": "Lignende serier",
|
||||
"components.TvDetails.similarsubtext": "Andre serier som ligner {title}",
|
||||
"components.TvDetails.status": "Status",
|
||||
"components.TvDetails.unavailable": "Utilgjengelig",
|
||||
"components.TvDetails.userrating": "Brukervurdering",
|
||||
"components.UserEdit.admin": "Administrator",
|
||||
"components.UserEdit.adminDescription": "Full administratortilgang. Unngår alle tilgangssjekker.",
|
||||
"components.UserEdit.autoapprove": "Godkjenn automatisk",
|
||||
"components.UserEdit.autoapproveDescription": "Innvilger automatisk godkjennelse av forespørsler gjort av denne brukeren.",
|
||||
"components.UserEdit.avatar": "Avatar",
|
||||
"components.UserEdit.edituser": "Rediger bruker",
|
||||
"components.UserEdit.email": "E-post",
|
||||
"components.UserEdit.managerequests": "Håndter forespørsler",
|
||||
"components.UserEdit.managerequestsDescription": "Innvilger tilgang til håndtering av Overseerr-forespørsler. Dette inkluderer godkjenning og avslag av forespørsler.",
|
||||
"components.UserEdit.permissions": "Tilganger",
|
||||
"components.UserEdit.request": "Forespørsel",
|
||||
"components.UserEdit.requestDescription": "Innvilger tilgang til å gjøre forespørsler for filmer og TV-programmer.",
|
||||
"components.UserEdit.save": "Lagre",
|
||||
"components.UserEdit.saving": "Lagrer …",
|
||||
"components.UserEdit.settings": "Håndter innstillinger",
|
||||
"components.UserEdit.settingsDescription": "Innvilger tilgang til å endre alle Overseerr-innstillinger. En bruker må ha denne tilgangen for å innvilge den til andre.",
|
||||
"components.UserEdit.userfail": "Noe gikk galt under lagring av brukeren.",
|
||||
"components.UserEdit.username": "Brukernavn",
|
||||
"components.UserEdit.users": "Håndter brukere",
|
||||
"components.UserEdit.usersDescription": "Innvilger tilgang til håndtering av Overseerr-brukere. Brukere med denne tilgangen kan ikke endre brukere med Administrator-tilgang, eller innvilge det.",
|
||||
"components.UserEdit.usersaved": "Bruker lagret",
|
||||
"components.UserEdit.vote": "Stemme",
|
||||
"components.UserEdit.voteDescription": "Innvilger tilgang til stemming over forespørsler (stemmegivning er ikke implementert enda)",
|
||||
"components.UserList.admin": "Administrator",
|
||||
"components.UserList.created": "Opprettet",
|
||||
"components.UserList.delete": "Slett",
|
||||
"components.UserList.edit": "Rediger",
|
||||
"components.UserList.lastupdated": "Sist oppdatert",
|
||||
"components.UserList.plexuser": "Plex-bruker",
|
||||
"components.UserList.role": "Rolle",
|
||||
"components.UserList.totalrequests": "Alle forespørsler",
|
||||
"components.UserList.user": "Bruker",
|
||||
"components.UserList.userlist": "Brukerliste",
|
||||
"components.UserList.username": "Brukernavn",
|
||||
"components.UserList.usertype": "Brukertype",
|
||||
"i18n.approve": "Godta",
|
||||
"i18n.approved": "Godtatt",
|
||||
"i18n.available": "Tilgjengelig",
|
||||
"i18n.cancel": "Avbryt",
|
||||
"i18n.decline": "Avslå",
|
||||
"i18n.declined": "Avslått",
|
||||
"i18n.delete": "Slett",
|
||||
"i18n.movies": "Filmer",
|
||||
"i18n.partiallyavailable": "Delvis tilgjengelig",
|
||||
"i18n.pending": "Venter",
|
||||
"i18n.processing": "Behandler …",
|
||||
"i18n.tvshows": "Seier",
|
||||
"i18n.unavailable": "Utilgjengelig",
|
||||
"pages.internalServerError": "{statusCode} - Intern tjenerfeil",
|
||||
"pages.oops": "Oida",
|
||||
"pages.pageNotFound": "404 - Fant ikke siden",
|
||||
"pages.returnHome": "Helt tilbake",
|
||||
"pages.serviceUnavailable": "{statusCode} - Tjenesten er utilgjengelig",
|
||||
"pages.somethingWentWrong": "{statusCode} - Noe gikk galt"
|
||||
}
|
||||
312
src/i18n/locale/nl.json
Normal file
312
src/i18n/locale/nl.json
Normal file
@@ -0,0 +1,312 @@
|
||||
{
|
||||
"components.Discover.discovermovies": "Populaire Films",
|
||||
"components.Discover.discovertv": "Populaire Series",
|
||||
"components.Discover.nopending": "Geen Wachtende Verzoeken",
|
||||
"components.Discover.popularmovies": "Populaire Films",
|
||||
"components.Discover.populartv": "Populaire Series",
|
||||
"components.Discover.recentlyAdded": "Recentelijk Toegevoegd",
|
||||
"components.Discover.recentrequests": "Recente Verzoeken",
|
||||
"components.Discover.trending": "Trending",
|
||||
"components.Discover.upcoming": "Verwachte Films",
|
||||
"components.Discover.upcomingmovies": "Verwachte Films",
|
||||
"components.Layout.LanguagePicker.changelanguage": "Wijzig Taal",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "Zoek Films & TV",
|
||||
"components.Layout.Sidebar.dashboard": "Ontdek",
|
||||
"components.Layout.Sidebar.requests": "Verzoeken",
|
||||
"components.Layout.Sidebar.settings": "Instellingen",
|
||||
"components.Layout.Sidebar.users": "Gebruikers",
|
||||
"components.Layout.UserDropdown.signout": "Uitloggen",
|
||||
"components.Layout.alphawarning": "Dit is ALPHA software. Bijna alles is waarschijnlijk kapot of onstabiel. Rapporteer issues bij de Overseerr GitHub!",
|
||||
"components.Login.signinplex": "Log in om door te gaan",
|
||||
"components.MovieDetails.approve": "Goedkeuren",
|
||||
"components.MovieDetails.available": "Beschikbaar",
|
||||
"components.MovieDetails.budget": "Budget",
|
||||
"components.MovieDetails.cancelrequest": "Annuleer Verzoek",
|
||||
"components.MovieDetails.cast": "Acteurs",
|
||||
"components.MovieDetails.decline": "Weigeren",
|
||||
"components.MovieDetails.manageModalClearMedia": "Wis Alle Media Data",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "Dit wist alle media data inclusief alle verzoeken voor dit item zonder herstelmogelijkheden. Als dit item in je Plex bibliotheek bestaat zal alle media info bij de volgende sync hersteld worden.",
|
||||
"components.MovieDetails.manageModalNoRequests": "Geen Verzoeken",
|
||||
"components.MovieDetails.manageModalRequests": "Verzoeken",
|
||||
"components.MovieDetails.manageModalTitle": "Beheer Film",
|
||||
"components.MovieDetails.originallanguage": "Originele Taal",
|
||||
"components.MovieDetails.overview": "Overzicht",
|
||||
"components.MovieDetails.overviewunavailable": "Overzicht onbeschikbaar",
|
||||
"components.MovieDetails.pending": "Wachtende",
|
||||
"components.MovieDetails.recommendations": "Aanbevelingen",
|
||||
"components.MovieDetails.recommendationssubtext": "Als je {title} leuk vond, vind je dit misschien ook leuk...",
|
||||
"components.MovieDetails.releasedate": "Release Datum",
|
||||
"components.MovieDetails.request": "Verzoek",
|
||||
"components.MovieDetails.revenue": "Omzet",
|
||||
"components.MovieDetails.runtime": "{minutes} minuten",
|
||||
"components.MovieDetails.similar": "Vergelijkbare Titels",
|
||||
"components.MovieDetails.similarsubtext": "Andere films vergelijkbaar met {title}",
|
||||
"components.MovieDetails.status": "Status",
|
||||
"components.MovieDetails.unavailable": "Onbeschikbaar",
|
||||
"components.MovieDetails.userrating": "Gebruikersbeoordeling",
|
||||
"components.MovieDetails.viewrequest": "Verzoek Bekijken",
|
||||
"components.PersonDetails.appearsin": "Verschijnt in",
|
||||
"components.PersonDetails.ascharacter": "als {character}",
|
||||
"components.PersonDetails.nobiography": "Geen biografie beschikbaar.",
|
||||
"components.PlexLoginButton.loading": "Bezig met laden...",
|
||||
"components.PlexLoginButton.loggingin": "Bezig met inloggen...",
|
||||
"components.PlexLoginButton.loginwithplex": "Login met Plex",
|
||||
"components.RequestBlock.seasons": "Seizoenen",
|
||||
"components.RequestCard.all": "Alle",
|
||||
"components.RequestCard.requestedby": "Verzocht door {username}",
|
||||
"components.RequestCard.seasons": "Seizoenen",
|
||||
"components.RequestList.RequestItem.notavailable": "Nvt",
|
||||
"components.RequestList.RequestItem.requestedby": "Verzocht door {username}",
|
||||
"components.RequestList.RequestItem.seasons": "Seizoenen",
|
||||
"components.RequestList.mediaInfo": "Media Info",
|
||||
"components.RequestList.modifiedBy": "Laatst Aangepast Door",
|
||||
"components.RequestList.next": "Volgende",
|
||||
"components.RequestList.previous": "Vorige",
|
||||
"components.RequestList.requestedAt": "Aangevraagd Om",
|
||||
"components.RequestList.requests": "Verzoeken",
|
||||
"components.RequestList.showingresults": "<strong>{from}</strong> tot <strong>{to}</strong> van de <strong>{total}</strong> resultaten worden weergegeven",
|
||||
"components.RequestList.status": "Status",
|
||||
"components.RequestModal.cancel": "Verzoek Annuleren",
|
||||
"components.RequestModal.cancelling": "Bezig met annuleren...",
|
||||
"components.RequestModal.cancelrequest": "Hiermee wordt je verzoek verwijderd. Weet je zeker dat je door wilt gaan?",
|
||||
"components.RequestModal.close": "Sluiten",
|
||||
"components.RequestModal.extras": "Extra",
|
||||
"components.RequestModal.notrequested": "Niet Verzocht",
|
||||
"components.RequestModal.numberofepisodes": "# Afleveringen",
|
||||
"components.RequestModal.pendingrequest": "Wachtend verzoek voor {title}",
|
||||
"components.RequestModal.request": "Verzoek",
|
||||
"components.RequestModal.requestCancel": "Verzoek voor <strong>{title}</strong> is geannuleerd",
|
||||
"components.RequestModal.requestSuccess": "<strong>{title}</strong> is verzocht.",
|
||||
"components.RequestModal.requestadmin": "Je verzoek zal onmiddelijk goedgekeurd worden.",
|
||||
"components.RequestModal.requestfrom": "Er is een afwachtend verzoek van {user}",
|
||||
"components.RequestModal.requesting": "Bezig met verzoeken…",
|
||||
"components.RequestModal.requestseasons": "Verzoek {seasonCount} {seasonCount, plural, één {Season} andere {Seasons}}",
|
||||
"components.RequestModal.requesttitle": "Verzoek {title}",
|
||||
"components.RequestModal.season": "Seizoen",
|
||||
"components.RequestModal.seasonnumber": "Seizoen {number}",
|
||||
"components.RequestModal.selectseason": "Selecteer seizoen(en)",
|
||||
"components.RequestModal.status": "Status",
|
||||
"components.Search.searchresults": "Zoekresultaten",
|
||||
"components.Settings.Notifications.agentenabled": "Agent Ingeschakeld",
|
||||
"components.Settings.Notifications.authPass": "Wachtwoord",
|
||||
"components.Settings.Notifications.authUser": "Gebruikersnaam",
|
||||
"components.Settings.Notifications.emailsender": "E-mail Adres Van Afzender",
|
||||
"components.Settings.Notifications.enableSsl": "Schakel SSL in",
|
||||
"components.Settings.Notifications.save": "Wijzigingen Opslaan",
|
||||
"components.Settings.Notifications.saving": "Bezig met opslaan...",
|
||||
"components.Settings.Notifications.smtpHost": "SMTP Host",
|
||||
"components.Settings.Notifications.smtpPort": "SMTP Poort",
|
||||
"components.Settings.Notifications.validationFromRequired": "Je moet een afzender adres opgeven",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "Je moet een SMTP host opgeven",
|
||||
"components.Settings.Notifications.validationSmtpPortRequired": "Je moet een SMTP poort opgeven",
|
||||
"components.Settings.Notifications.validationWebhookUrlRequired": "Je moet een webhook URL opgeven",
|
||||
"components.Settings.Notifications.webhookUrl": "Webhook URL",
|
||||
"components.Settings.Notifications.webhookUrlPlaceholder": "Server instellingen -> Integraties -> Webhooks",
|
||||
"components.Settings.RadarrModal.add": "Server Toevoegen",
|
||||
"components.Settings.RadarrModal.apiKey": "API Key",
|
||||
"components.Settings.RadarrModal.apiKeyPlaceholder": "Je Radarr API Key",
|
||||
"components.Settings.RadarrModal.baseUrl": "Basis URL",
|
||||
"components.Settings.RadarrModal.baseUrlPlaceholder": "Voorbeeld: /radarr",
|
||||
"components.Settings.RadarrModal.createradarr": "Maak Een Nieuwe Radarr Server Aan",
|
||||
"components.Settings.RadarrModal.defaultserver": "Standaard Server",
|
||||
"components.Settings.RadarrModal.editradarr": "Wijzig Radarr Server",
|
||||
"components.Settings.RadarrModal.hostname": "Hostnaam",
|
||||
"components.Settings.RadarrModal.minimumAvailability": "Minimale Beschikbaarheid",
|
||||
"components.Settings.RadarrModal.port": "Poort",
|
||||
"components.Settings.RadarrModal.qualityprofile": "Kwaliteitsprofiel",
|
||||
"components.Settings.RadarrModal.rootfolder": "Hoofdmap",
|
||||
"components.Settings.RadarrModal.save": "Wijzigingen Opslaan",
|
||||
"components.Settings.RadarrModal.saving": "Bezig met opslaan...",
|
||||
"components.Settings.RadarrModal.selectMinimumAvailability": "Selecteer minimale beschikbaarheid",
|
||||
"components.Settings.RadarrModal.selectQualityProfile": "Selecteer een kwaliteitsprofiel",
|
||||
"components.Settings.RadarrModal.selectRootFolder": "Selecteer een Hoofdmap",
|
||||
"components.Settings.RadarrModal.server4k": "4K Server",
|
||||
"components.Settings.RadarrModal.servername": "Server Naam",
|
||||
"components.Settings.RadarrModal.servernamePlaceholder": "Een Radarr Server",
|
||||
"components.Settings.RadarrModal.ssl": "SSL",
|
||||
"components.Settings.RadarrModal.test": "Test",
|
||||
"components.Settings.RadarrModal.testing": "Bezig met testen...",
|
||||
"components.Settings.RadarrModal.toastRadarrTestFailure": "Kon niet verbinden met de Radarr Server",
|
||||
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Verbonden met de Radarr server!",
|
||||
"components.Settings.RadarrModal.validationApiKeyRequired": "Je moet een API key opgeven",
|
||||
"components.Settings.RadarrModal.validationHostnameRequired": "Je moet een hostnaam/IP opgeven",
|
||||
"components.Settings.RadarrModal.validationPortRequired": "Je moet een poort opgeven",
|
||||
"components.Settings.RadarrModal.validationProfileRequired": "Je moet een profiel selecteren",
|
||||
"components.Settings.RadarrModal.validationRootFolderRequired": "Je moet een hoofdmap selecteren",
|
||||
"components.Settings.SonarrModal.add": "Server Toevoegen",
|
||||
"components.Settings.SonarrModal.apiKey": "API Key",
|
||||
"components.Settings.SonarrModal.apiKeyPlaceholder": "Je Sonarr API Key",
|
||||
"components.Settings.SonarrModal.baseUrl": "Basis URL",
|
||||
"components.Settings.SonarrModal.baseUrlPlaceholder": "Voorbeeld: /sonarr",
|
||||
"components.Settings.SonarrModal.createsonarr": "Maak Nieuwe Sonar Server Aan",
|
||||
"components.Settings.SonarrModal.defaultserver": "Standaard Server",
|
||||
"components.Settings.SonarrModal.editsonarr": "Wijzig Sonarr Server",
|
||||
"components.Settings.SonarrModal.hostname": "Hostnaam",
|
||||
"components.Settings.SonarrModal.port": "Poort",
|
||||
"components.Settings.SonarrModal.qualityprofile": "Kwaliteitsprofiel",
|
||||
"components.Settings.SonarrModal.rootfolder": "Basisfolder",
|
||||
"components.Settings.SonarrModal.save": "Wijzigingen Opslaan",
|
||||
"components.Settings.SonarrModal.saving": "Bezig met opslaan...",
|
||||
"components.Settings.SonarrModal.seasonfolders": "Seizoen Folders",
|
||||
"components.Settings.SonarrModal.selectQualityProfile": "Selecteer een Kwaliteitsprofiel",
|
||||
"components.Settings.SonarrModal.selectRootFolder": "Selecteer een Basisfolder",
|
||||
"components.Settings.SonarrModal.server4k": "4K Server",
|
||||
"components.Settings.SonarrModal.servername": "Sever Naam",
|
||||
"components.Settings.SonarrModal.servernamePlaceholder": "Een Sonarr Server",
|
||||
"components.Settings.SonarrModal.ssl": "SSL",
|
||||
"components.Settings.SonarrModal.test": "Test",
|
||||
"components.Settings.SonarrModal.testing": "Bezig met testen...",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "Kon niet verbinden met de Sonarr Server",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Verbonden met de Sonarr server!",
|
||||
"components.Settings.SonarrModal.validationApiKeyRequired": "Je moet een API key opgeven",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "Je moet een hostnaam/IP opgeven",
|
||||
"components.Settings.SonarrModal.validationPortRequired": "Je moet een poort opgeven",
|
||||
"components.Settings.SonarrModal.validationProfileRequired": "Je moet een profiel selecteren",
|
||||
"components.Settings.SonarrModal.validationRootFolderRequired": "Je moet een hoofdfolder selecteren",
|
||||
"components.Settings.activeProfile": "Actief profiel",
|
||||
"components.Settings.addradarr": "Radarr Server Toevoegen",
|
||||
"components.Settings.address": "Adres",
|
||||
"components.Settings.addsonarr": "Sonarr Server Toevoegen",
|
||||
"components.Settings.apikey": "API Key",
|
||||
"components.Settings.applicationurl": "Applicatie URL",
|
||||
"components.Settings.cancelscan": "Scan Annuleren",
|
||||
"components.Settings.copied": "API key gekopieerd naar het klembord",
|
||||
"components.Settings.currentlibrary": "Huidige Bibliotheek: {name}",
|
||||
"components.Settings.default": "Standaard",
|
||||
"components.Settings.default4k": "Standaard 4K",
|
||||
"components.Settings.delete": "Verwijderen",
|
||||
"components.Settings.deleteserverconfirm": "Weet je zeker dat je deze server wil verwijderen?",
|
||||
"components.Settings.edit": "Wijzig",
|
||||
"components.Settings.generalsettings": "Algemene Instellingen",
|
||||
"components.Settings.generalsettingsDescription": "Deze instellingen zijn gerelateerd aan de algemene Overseer configuratie.",
|
||||
"components.Settings.hostname": "Hostnaam/IP",
|
||||
"components.Settings.jobname": "Taaknaam",
|
||||
"components.Settings.librariesRemaining": "Resterende Bibliotheken: {count}",
|
||||
"components.Settings.manualscan": "Handmatige Bibliotheek Scan",
|
||||
"components.Settings.manualscanDescription": "Normaal gesproken wordt dit eens elke 6 uur gedraaid. Overseerr controleert de recentelijk toegoevoegde items van je Plex Server aggresiever. Als dit je eerst keer is om Plex te configuren raden wij aan om eenmaal een volledige bibliotheek scan handmatig te draaien!",
|
||||
"components.Settings.menuAbout": "Over",
|
||||
"components.Settings.menuGeneralSettings": "Algemene Instellingen",
|
||||
"components.Settings.menuJobs": "Taken",
|
||||
"components.Settings.menuLogs": "Logboeken",
|
||||
"components.Settings.menuNotifications": "Notificaties",
|
||||
"components.Settings.menuPlexSettings": "Plex",
|
||||
"components.Settings.menuServices": "Diensten",
|
||||
"components.Settings.nextexecution": "Volgende Uitvoering",
|
||||
"components.Settings.notificationsettings": "Notificatie Instellingen",
|
||||
"components.Settings.notificationsettingsDescription": "Hier kun je kiezen welke soort notificaties er worden verstuurd en door welke type diensten.",
|
||||
"components.Settings.notrunning": "Draait niet",
|
||||
"components.Settings.plexlibraries": "Plex Bibliotheken",
|
||||
"components.Settings.plexlibrariesDescription": "The bibliotheken die Overseerr scanned voor titels. Stel je Plex connectie instellingen in en sla ze op. Klik op de onderstaande knop als er geen connecties staan.",
|
||||
"components.Settings.plexsettings": "Plex Instellingen",
|
||||
"components.Settings.plexsettingsDescription": "Configureer de instellingen voor je Plex server. Overseerr gebruikt je Plex server om je bibliotheek met een interval te scannen om te zien welke content beschikbaar is.",
|
||||
"components.Settings.port": "Poort",
|
||||
"components.Settings.radarrSettingsDescription": "Stel hier onder je Radarr connectie in. Je kan er meerdere hebben, maar slechts twee actief hebben als standaard (één voor standaard HD, en één voor 4K). Beheerders kunnen bepalen welke server gebruikt wordt voor nieuwe verzoeken.",
|
||||
"components.Settings.radarrsettings": "Radarr Instellingen",
|
||||
"components.Settings.runnow": "Nu Starten",
|
||||
"components.Settings.save": "Wijzigingen Opslaan",
|
||||
"components.Settings.saving": "Bezig met opslaan...",
|
||||
"components.Settings.servername": "Server Naam (Automatisch Ingesteld)",
|
||||
"components.Settings.servernamePlaceholder": "Plex Server Naam",
|
||||
"components.Settings.sonarrSettingsDescription": "Stel hier onder je Sonarr connectie in. Je kan er meerdere hebben, maar slechts twee actief hebben als standaard (één voor standaard HD, en één voor 4K). Beheerders kunnen bepalen welke server gebruikt wordt voor nieuwe verzoeken.",
|
||||
"components.Settings.sonarrsettings": "Sonarr Instellingen",
|
||||
"components.Settings.ssl": "SSL",
|
||||
"components.Settings.startscan": "Scan Starten",
|
||||
"components.Settings.sync": "Sync Plex Bibliotheken",
|
||||
"components.Settings.syncing": "Bezig met synchronizeren…",
|
||||
"components.Setup.configureplex": "Configureer Plex",
|
||||
"components.Setup.configureservices": "Configureer Diensten",
|
||||
"components.Setup.continue": "Doorgaan",
|
||||
"components.Setup.finish": "Installatie Voltooien",
|
||||
"components.Setup.finishing": "Bezig met voltooien...",
|
||||
"components.Setup.loginwithplex": "Login met Plex",
|
||||
"components.Setup.signinMessage": "Ga aan de slag door in te loggen met je Plex account",
|
||||
"components.Setup.welcome": "Welcome bij Overseerr",
|
||||
"components.Slider.noresults": "Geen Resultaten",
|
||||
"components.TitleCard.movie": "Film",
|
||||
"components.TitleCard.tvshow": "Series",
|
||||
"components.TvDetails.approve": "Goedkeuren",
|
||||
"components.TvDetails.approverequests": "Keur {requestCount} {requestCount, plural, één {Request} meerdere {Requests}} goed",
|
||||
"components.TvDetails.available": "Beschikbaar",
|
||||
"components.TvDetails.cancelrequest": "Verzoek Annuleren",
|
||||
"components.TvDetails.cast": "Cast",
|
||||
"components.TvDetails.decline": "Weigeren",
|
||||
"components.TvDetails.declinerequests": "Weiger {requestCount} {requestCount, plural, één {Request} meerdere {Requests}}",
|
||||
"components.TvDetails.manageModalClearMedia": "Wis Alle Media Data",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "Dit wist alle media data inclusief alle verzoeken voor dit item zonder herstelmogelijkheden. Als dit item in je Plex bibliotheek bestaat zal alle media info bij de volgende sync hersteld worden.",
|
||||
"components.TvDetails.manageModalNoRequests": "Geen Verzoeken",
|
||||
"components.TvDetails.manageModalRequests": "Verzoeken",
|
||||
"components.TvDetails.manageModalTitle": "Beheer Series",
|
||||
"components.TvDetails.originallanguage": "Originele Taal",
|
||||
"components.TvDetails.overview": "Overzicht",
|
||||
"components.TvDetails.overviewunavailable": "Overzicht onbeschikbaar",
|
||||
"components.TvDetails.pending": "Wachtende",
|
||||
"components.TvDetails.recommendations": "Aanbevelingen",
|
||||
"components.TvDetails.recommendationssubtext": "Als je {title} leuk vond, vind je dit misschien ook leuk...",
|
||||
"components.TvDetails.request": "Verzoek",
|
||||
"components.TvDetails.requestmore": "Verzoek Meer",
|
||||
"components.TvDetails.similar": "Soortgelijke Series",
|
||||
"components.TvDetails.similarsubtext": "Andere series gelijk aan {title}",
|
||||
"components.TvDetails.status": "Status",
|
||||
"components.TvDetails.unavailable": "Onbeschikbaar",
|
||||
"components.TvDetails.userrating": "Gebruikersbeoordeling",
|
||||
"components.UserEdit.admin": "Beheerder",
|
||||
"components.UserEdit.adminDescription": "Volledige beheerderstoegang. Omzeilt alle toestemmingscontroles.",
|
||||
"components.UserEdit.autoapprove": "Automatisch Goedkeuren",
|
||||
"components.UserEdit.autoapproveDescription": "Geeft automatische goedkeuring voor alle verzoeken van deze gebruiker.",
|
||||
"components.UserEdit.avatar": "Avatar",
|
||||
"components.UserEdit.edituser": "Wijzig Gebruiker",
|
||||
"components.UserEdit.email": "E-mail",
|
||||
"components.UserEdit.managerequests": "Beheer Verzoeken",
|
||||
"components.UserEdit.managerequestsDescription": "Geeft toestemming om Overseerr-verzoeken te beheren. Inclusief het goedkeuren en weigeren van verzoeken.",
|
||||
"components.UserEdit.permissions": "Rechten",
|
||||
"components.UserEdit.request": "Verzoek",
|
||||
"components.UserEdit.requestDescription": "Geeft toestemming om films en series aan te vragen.",
|
||||
"components.UserEdit.save": "Sla op",
|
||||
"components.UserEdit.saving": "Bezig met opslaan...",
|
||||
"components.UserEdit.settings": "Instellingen Beheren",
|
||||
"components.UserEdit.settingsDescription": "Geeft toestemming om alle Overseerr-instellingen te wijzigen. Een gebruiker moet deze toestemming hebben om deze aan anderen te verlenen.",
|
||||
"components.UserEdit.userfail": "Er ging iets verkeerd bij het opslaan van de gebruiker.",
|
||||
"components.UserEdit.username": "Gebruikersnaam",
|
||||
"components.UserEdit.users": "Beheer Gebruikers",
|
||||
"components.UserEdit.usersDescription": "Geeft toestemming om Overseerr-gebruikers te beheren. Gebruikers met deze toestemming kunnen gebruikers met beheerdersrechten niet wijzigen of deze toestemming geven.",
|
||||
"components.UserEdit.usersaved": "Gebruiker opgeslagen",
|
||||
"components.UserEdit.vote": "Stem",
|
||||
"components.UserEdit.voteDescription": "Geeft toestemming om te stemmen op verzoeken (stemmen is nog niet geïmplementeerd)",
|
||||
"components.UserList.admin": "Beheerder",
|
||||
"components.UserList.created": "Gemaakt",
|
||||
"components.UserList.delete": "Verwijderen",
|
||||
"components.UserList.edit": "Wijzig",
|
||||
"components.UserList.lastupdated": "Laatst Aangepast",
|
||||
"components.UserList.plexuser": "Plex Gebruiker",
|
||||
"components.UserList.role": "Rol",
|
||||
"components.UserList.totalrequests": "Totale Verzoeken",
|
||||
"components.UserList.user": "Gebruiker",
|
||||
"components.UserList.userlist": "Gebruikerslijst",
|
||||
"components.UserList.username": "Gebruikersnaam",
|
||||
"components.UserList.usertype": "Gebruikerstype",
|
||||
"i18n.approve": "Goedkeuren",
|
||||
"i18n.approved": "Goedgekeurd",
|
||||
"i18n.available": "Beschikbaar",
|
||||
"i18n.cancel": "Annuleer",
|
||||
"i18n.decline": "Weigeren",
|
||||
"i18n.declined": "Geweigerd",
|
||||
"i18n.delete": "Verwijder",
|
||||
"i18n.movies": "Films",
|
||||
"i18n.partiallyavailable": "Gedeeltelijk Beschikbaar",
|
||||
"i18n.pending": "Afwachtende",
|
||||
"i18n.processing": "Bezig met verwerken…",
|
||||
"i18n.tvshows": "Series",
|
||||
"i18n.unavailable": "Onbeschikbaar",
|
||||
"pages.internalServerError": "{statusCode} - Interne Server Error",
|
||||
"pages.oops": "Oeps",
|
||||
"pages.pageNotFound": "404 - Pagina Niet Gevonden",
|
||||
"pages.returnHome": "Terug naar de Home pagina",
|
||||
"pages.serviceUnavailable": "{statusCode} - Service Onbeschikbaar",
|
||||
"pages.somethingWentWrong": "{statusCode} - Er is iets verkeerd gegaan",
|
||||
"components.MovieDetails.MovieCast.fullcast": "Volledige Cast",
|
||||
"components.TvDetails.TvCast.fullseriescast": "Volledige Cast van de Series",
|
||||
"components.Settings.Notifications.emailsettingssaved": "E-mail notificatie instellingen zijn opgeslagen!",
|
||||
"components.Settings.Notifications.emailsettingsfailed": "E-mail notificatie instellingen konden niet opgeslagen worden.",
|
||||
"components.Settings.Notifications.discordsettingssaved": "Discord notificatie instellingen zijn opgeslagen!",
|
||||
"components.Settings.Notifications.discordsettingsfailed": "Discord notificatie instellingen konden niet opgeslagen worden."
|
||||
}
|
||||
306
src/i18n/locale/ru.json
Normal file
306
src/i18n/locale/ru.json
Normal file
@@ -0,0 +1,306 @@
|
||||
{
|
||||
"components.Discover.discovermovies": "Популярные фильмы",
|
||||
"components.Discover.discovertv": "Популярные серии",
|
||||
"components.Discover.nopending": "Нет отложенных запросов",
|
||||
"components.Discover.popularmovies": "Популярные фильмы",
|
||||
"components.Discover.populartv": "Популярные серии",
|
||||
"components.Discover.recentlyAdded": "Недавно добавленные",
|
||||
"components.Discover.recentrequests": "Последние запросы",
|
||||
"components.Discover.trending": "Тренды",
|
||||
"components.Discover.upcoming": "Предстоящие фильмы",
|
||||
"components.Discover.upcomingmovies": "Предстоящие фильмы",
|
||||
"components.Layout.LanguagePicker.changelanguage": "Изменить язык",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "Поиск фильмов и сериалов",
|
||||
"components.Layout.Sidebar.dashboard": "",
|
||||
"components.Layout.Sidebar.requests": "Запросы",
|
||||
"components.Layout.Sidebar.settings": "Настройки",
|
||||
"components.Layout.Sidebar.users": "Пользователи",
|
||||
"components.Layout.UserDropdown.signout": "Выход",
|
||||
"components.Layout.alphawarning": "",
|
||||
"components.Login.signinplex": "Войдите, чтобы продолжить",
|
||||
"components.MovieDetails.approve": "Одобрить",
|
||||
"components.MovieDetails.available": "Доступно",
|
||||
"components.MovieDetails.budget": "Бюджет",
|
||||
"components.MovieDetails.cancelrequest": "Отменить запрос",
|
||||
"components.MovieDetails.cast": "В ролях",
|
||||
"components.MovieDetails.decline": "",
|
||||
"components.MovieDetails.manageModalClearMedia": "Очистить все медиаданные",
|
||||
"components.MovieDetails.manageModalClearMediaWarning": "",
|
||||
"components.MovieDetails.manageModalNoRequests": "Нет запросов",
|
||||
"components.MovieDetails.manageModalRequests": "Запросы",
|
||||
"components.MovieDetails.manageModalTitle": "",
|
||||
"components.MovieDetails.originallanguage": "Оригинальный язык",
|
||||
"components.MovieDetails.overview": "Обзор",
|
||||
"components.MovieDetails.overviewunavailable": "",
|
||||
"components.MovieDetails.pending": "В ожидании",
|
||||
"components.MovieDetails.recommendations": "Рекомендации",
|
||||
"components.MovieDetails.recommendationssubtext": "",
|
||||
"components.MovieDetails.releasedate": "Дата выпуска",
|
||||
"components.MovieDetails.request": "Запрос",
|
||||
"components.MovieDetails.revenue": "Доход",
|
||||
"components.MovieDetails.runtime": "{minutes} минут",
|
||||
"components.MovieDetails.similar": "",
|
||||
"components.MovieDetails.similarsubtext": "",
|
||||
"components.MovieDetails.status": "Статус",
|
||||
"components.MovieDetails.unavailable": "Недоступен",
|
||||
"components.MovieDetails.userrating": "Пользовательский рейтинг",
|
||||
"components.MovieDetails.viewrequest": "Просмотр запроса",
|
||||
"components.PersonDetails.appearsin": "",
|
||||
"components.PersonDetails.ascharacter": "",
|
||||
"components.PersonDetails.nobiography": "",
|
||||
"components.PlexLoginButton.loading": "Загрузка...",
|
||||
"components.PlexLoginButton.loggingin": "",
|
||||
"components.PlexLoginButton.loginwithplex": "Войти через Plex",
|
||||
"components.RequestBlock.seasons": "Сезонов",
|
||||
"components.RequestCard.all": "",
|
||||
"components.RequestCard.requestedby": "По запросу {username}",
|
||||
"components.RequestCard.seasons": "Сезонов",
|
||||
"components.RequestList.RequestItem.notavailable": "",
|
||||
"components.RequestList.RequestItem.requestedby": "По запросу {username}",
|
||||
"components.RequestList.RequestItem.seasons": "Сезонов",
|
||||
"components.RequestList.mediaInfo": "",
|
||||
"components.RequestList.modifiedBy": "Автор последнего изменения",
|
||||
"components.RequestList.next": "Следующий",
|
||||
"components.RequestList.previous": "Предыдущий",
|
||||
"components.RequestList.requestedAt": "",
|
||||
"components.RequestList.requests": "Запросы",
|
||||
"components.RequestList.showingresults": "",
|
||||
"components.RequestList.status": "Статус",
|
||||
"components.RequestModal.cancel": "Отменить запрос",
|
||||
"components.RequestModal.cancelling": "",
|
||||
"components.RequestModal.cancelrequest": "",
|
||||
"components.RequestModal.close": "Закрыть",
|
||||
"components.RequestModal.extras": "Дополнительно",
|
||||
"components.RequestModal.notrequested": "",
|
||||
"components.RequestModal.numberofepisodes": "",
|
||||
"components.RequestModal.pendingrequest": "",
|
||||
"components.RequestModal.request": "Запрос",
|
||||
"components.RequestModal.requestCancel": "",
|
||||
"components.RequestModal.requestSuccess": "",
|
||||
"components.RequestModal.requestadmin": "",
|
||||
"components.RequestModal.requestfrom": "",
|
||||
"components.RequestModal.requesting": "",
|
||||
"components.RequestModal.requestseasons": "",
|
||||
"components.RequestModal.requesttitle": "Запрос {title}",
|
||||
"components.RequestModal.season": "Сезон",
|
||||
"components.RequestModal.seasonnumber": "Сезон {number}",
|
||||
"components.RequestModal.selectseason": "Выберите сезон(ы)",
|
||||
"components.RequestModal.status": "Статус",
|
||||
"components.Search.searchresults": "Результаты поиска",
|
||||
"components.Settings.Notifications.agentenabled": "Агент включен",
|
||||
"components.Settings.Notifications.authPass": "",
|
||||
"components.Settings.Notifications.authUser": "",
|
||||
"components.Settings.Notifications.emailsender": "",
|
||||
"components.Settings.Notifications.enableSsl": "Включить SSL",
|
||||
"components.Settings.Notifications.save": "Сохранить изменения",
|
||||
"components.Settings.Notifications.saving": "Сохранение...",
|
||||
"components.Settings.Notifications.smtpHost": "",
|
||||
"components.Settings.Notifications.smtpPort": "",
|
||||
"components.Settings.Notifications.validationFromRequired": "",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "",
|
||||
"components.Settings.Notifications.validationSmtpPortRequired": "",
|
||||
"components.Settings.Notifications.validationWebhookUrlRequired": "",
|
||||
"components.Settings.Notifications.webhookUrl": "",
|
||||
"components.Settings.Notifications.webhookUrlPlaceholder": "",
|
||||
"components.Settings.RadarrModal.add": "Добавить сервер",
|
||||
"components.Settings.RadarrModal.apiKey": "Ключ API",
|
||||
"components.Settings.RadarrModal.apiKeyPlaceholder": "",
|
||||
"components.Settings.RadarrModal.baseUrl": "",
|
||||
"components.Settings.RadarrModal.baseUrlPlaceholder": "",
|
||||
"components.Settings.RadarrModal.createradarr": "",
|
||||
"components.Settings.RadarrModal.defaultserver": "Сервер по умолчанию",
|
||||
"components.Settings.RadarrModal.editradarr": "",
|
||||
"components.Settings.RadarrModal.hostname": "Имя хоста",
|
||||
"components.Settings.RadarrModal.minimumAvailability": "",
|
||||
"components.Settings.RadarrModal.port": "Порт",
|
||||
"components.Settings.RadarrModal.qualityprofile": "",
|
||||
"components.Settings.RadarrModal.rootfolder": "Корневая папка",
|
||||
"components.Settings.RadarrModal.save": "Сохранить изменения",
|
||||
"components.Settings.RadarrModal.saving": "Сохранение...",
|
||||
"components.Settings.RadarrModal.selectMinimumAvailability": "",
|
||||
"components.Settings.RadarrModal.selectQualityProfile": "",
|
||||
"components.Settings.RadarrModal.selectRootFolder": "Выберите корневую папку",
|
||||
"components.Settings.RadarrModal.server4k": "",
|
||||
"components.Settings.RadarrModal.servername": "Название сервера",
|
||||
"components.Settings.RadarrModal.servernamePlaceholder": "",
|
||||
"components.Settings.RadarrModal.ssl": "SSL",
|
||||
"components.Settings.RadarrModal.test": "Тест",
|
||||
"components.Settings.RadarrModal.testing": "Тестирование...",
|
||||
"components.Settings.RadarrModal.toastRadarrTestFailure": "",
|
||||
"components.Settings.RadarrModal.toastRadarrTestSuccess": "",
|
||||
"components.Settings.RadarrModal.validationApiKeyRequired": "",
|
||||
"components.Settings.RadarrModal.validationHostnameRequired": "",
|
||||
"components.Settings.RadarrModal.validationPortRequired": "",
|
||||
"components.Settings.RadarrModal.validationProfileRequired": "Вы должны выбрать профиль",
|
||||
"components.Settings.RadarrModal.validationRootFolderRequired": "Вы должны выбрать корневую папку",
|
||||
"components.Settings.SonarrModal.add": "Добавить сервер",
|
||||
"components.Settings.SonarrModal.apiKey": "Ключ API",
|
||||
"components.Settings.SonarrModal.apiKeyPlaceholder": "",
|
||||
"components.Settings.SonarrModal.baseUrl": "",
|
||||
"components.Settings.SonarrModal.baseUrlPlaceholder": "",
|
||||
"components.Settings.SonarrModal.createsonarr": "",
|
||||
"components.Settings.SonarrModal.defaultserver": "",
|
||||
"components.Settings.SonarrModal.editsonarr": "",
|
||||
"components.Settings.SonarrModal.hostname": "",
|
||||
"components.Settings.SonarrModal.port": "",
|
||||
"components.Settings.SonarrModal.qualityprofile": "",
|
||||
"components.Settings.SonarrModal.rootfolder": "",
|
||||
"components.Settings.SonarrModal.save": "",
|
||||
"components.Settings.SonarrModal.saving": "",
|
||||
"components.Settings.SonarrModal.seasonfolders": "",
|
||||
"components.Settings.SonarrModal.selectQualityProfile": "",
|
||||
"components.Settings.SonarrModal.selectRootFolder": "",
|
||||
"components.Settings.SonarrModal.server4k": "",
|
||||
"components.Settings.SonarrModal.servername": "",
|
||||
"components.Settings.SonarrModal.servernamePlaceholder": "",
|
||||
"components.Settings.SonarrModal.ssl": "",
|
||||
"components.Settings.SonarrModal.test": "",
|
||||
"components.Settings.SonarrModal.testing": "",
|
||||
"components.Settings.SonarrModal.toastRadarrTestFailure": "",
|
||||
"components.Settings.SonarrModal.toastRadarrTestSuccess": "",
|
||||
"components.Settings.SonarrModal.validationApiKeyRequired": "",
|
||||
"components.Settings.SonarrModal.validationHostnameRequired": "",
|
||||
"components.Settings.SonarrModal.validationPortRequired": "",
|
||||
"components.Settings.SonarrModal.validationProfileRequired": "",
|
||||
"components.Settings.SonarrModal.validationRootFolderRequired": "",
|
||||
"components.Settings.activeProfile": "",
|
||||
"components.Settings.addradarr": "",
|
||||
"components.Settings.address": "",
|
||||
"components.Settings.addsonarr": "",
|
||||
"components.Settings.apikey": "",
|
||||
"components.Settings.applicationurl": "",
|
||||
"components.Settings.cancelscan": "",
|
||||
"components.Settings.copied": "",
|
||||
"components.Settings.currentlibrary": "",
|
||||
"components.Settings.default": "",
|
||||
"components.Settings.default4k": "",
|
||||
"components.Settings.delete": "",
|
||||
"components.Settings.deleteserverconfirm": "",
|
||||
"components.Settings.edit": "",
|
||||
"components.Settings.generalsettings": "",
|
||||
"components.Settings.generalsettingsDescription": "",
|
||||
"components.Settings.hostname": "",
|
||||
"components.Settings.jobname": "",
|
||||
"components.Settings.librariesRemaining": "",
|
||||
"components.Settings.manualscan": "",
|
||||
"components.Settings.manualscanDescription": "",
|
||||
"components.Settings.menuAbout": "",
|
||||
"components.Settings.menuGeneralSettings": "",
|
||||
"components.Settings.menuJobs": "",
|
||||
"components.Settings.menuLogs": "",
|
||||
"components.Settings.menuNotifications": "",
|
||||
"components.Settings.menuPlexSettings": "",
|
||||
"components.Settings.menuServices": "",
|
||||
"components.Settings.nextexecution": "",
|
||||
"components.Settings.notificationsettings": "",
|
||||
"components.Settings.notificationsettingsDescription": "",
|
||||
"components.Settings.notrunning": "",
|
||||
"components.Settings.plexlibraries": "",
|
||||
"components.Settings.plexlibrariesDescription": "",
|
||||
"components.Settings.plexsettings": "",
|
||||
"components.Settings.plexsettingsDescription": "",
|
||||
"components.Settings.port": "",
|
||||
"components.Settings.radarrSettingsDescription": "",
|
||||
"components.Settings.radarrsettings": "",
|
||||
"components.Settings.runnow": "",
|
||||
"components.Settings.save": "",
|
||||
"components.Settings.saving": "",
|
||||
"components.Settings.servername": "",
|
||||
"components.Settings.servernamePlaceholder": "",
|
||||
"components.Settings.sonarrSettingsDescription": "",
|
||||
"components.Settings.sonarrsettings": "",
|
||||
"components.Settings.ssl": "",
|
||||
"components.Settings.startscan": "",
|
||||
"components.Settings.sync": "",
|
||||
"components.Settings.syncing": "",
|
||||
"components.Setup.configureplex": "",
|
||||
"components.Setup.configureservices": "",
|
||||
"components.Setup.continue": "",
|
||||
"components.Setup.finish": "",
|
||||
"components.Setup.finishing": "",
|
||||
"components.Setup.loginwithplex": "",
|
||||
"components.Setup.signinMessage": "",
|
||||
"components.Setup.welcome": "",
|
||||
"components.Slider.noresults": "",
|
||||
"components.TitleCard.movie": "",
|
||||
"components.TitleCard.tvshow": "",
|
||||
"components.TvDetails.approve": "",
|
||||
"components.TvDetails.approverequests": "",
|
||||
"components.TvDetails.available": "",
|
||||
"components.TvDetails.cancelrequest": "Отменить запрос",
|
||||
"components.TvDetails.cast": "",
|
||||
"components.TvDetails.decline": "",
|
||||
"components.TvDetails.declinerequests": "",
|
||||
"components.TvDetails.manageModalClearMedia": "",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "",
|
||||
"components.TvDetails.manageModalNoRequests": "",
|
||||
"components.TvDetails.manageModalRequests": "",
|
||||
"components.TvDetails.manageModalTitle": "",
|
||||
"components.TvDetails.originallanguage": "",
|
||||
"components.TvDetails.overview": "",
|
||||
"components.TvDetails.overviewunavailable": "",
|
||||
"components.TvDetails.pending": "",
|
||||
"components.TvDetails.recommendations": "",
|
||||
"components.TvDetails.recommendationssubtext": "",
|
||||
"components.TvDetails.request": "",
|
||||
"components.TvDetails.requestmore": "",
|
||||
"components.TvDetails.similar": "",
|
||||
"components.TvDetails.similarsubtext": "",
|
||||
"components.TvDetails.status": "Статус",
|
||||
"components.TvDetails.unavailable": "",
|
||||
"components.TvDetails.userrating": "",
|
||||
"components.UserEdit.admin": "",
|
||||
"components.UserEdit.adminDescription": "",
|
||||
"components.UserEdit.autoapprove": "",
|
||||
"components.UserEdit.autoapproveDescription": "",
|
||||
"components.UserEdit.avatar": "",
|
||||
"components.UserEdit.edituser": "",
|
||||
"components.UserEdit.email": "",
|
||||
"components.UserEdit.managerequests": "",
|
||||
"components.UserEdit.managerequestsDescription": "",
|
||||
"components.UserEdit.permissions": "",
|
||||
"components.UserEdit.request": "",
|
||||
"components.UserEdit.requestDescription": "",
|
||||
"components.UserEdit.save": "",
|
||||
"components.UserEdit.saving": "",
|
||||
"components.UserEdit.settings": "",
|
||||
"components.UserEdit.settingsDescription": "",
|
||||
"components.UserEdit.userfail": "",
|
||||
"components.UserEdit.username": "",
|
||||
"components.UserEdit.users": "",
|
||||
"components.UserEdit.usersDescription": "",
|
||||
"components.UserEdit.usersaved": "",
|
||||
"components.UserEdit.vote": "",
|
||||
"components.UserEdit.voteDescription": "",
|
||||
"components.UserList.admin": "",
|
||||
"components.UserList.created": "",
|
||||
"components.UserList.delete": "",
|
||||
"components.UserList.edit": "",
|
||||
"components.UserList.lastupdated": "",
|
||||
"components.UserList.plexuser": "",
|
||||
"components.UserList.role": "",
|
||||
"components.UserList.totalrequests": "",
|
||||
"components.UserList.user": "",
|
||||
"components.UserList.userlist": "",
|
||||
"components.UserList.username": "",
|
||||
"components.UserList.usertype": "",
|
||||
"i18n.approve": "",
|
||||
"i18n.approved": "",
|
||||
"i18n.available": "",
|
||||
"i18n.cancel": "",
|
||||
"i18n.decline": "",
|
||||
"i18n.declined": "",
|
||||
"i18n.delete": "",
|
||||
"i18n.movies": "",
|
||||
"i18n.partiallyavailable": "",
|
||||
"i18n.pending": "",
|
||||
"i18n.processing": "",
|
||||
"i18n.tvshows": "",
|
||||
"i18n.unavailable": "",
|
||||
"pages.internalServerError": "",
|
||||
"pages.oops": "",
|
||||
"pages.pageNotFound": "",
|
||||
"pages.returnHome": "",
|
||||
"pages.serviceUnavailable": "",
|
||||
"pages.somethingWentWrong": ""
|
||||
}
|
||||
@@ -20,6 +20,14 @@ const loadLocaleData = (locale: string): Promise<any> => {
|
||||
return import('../i18n/locale/ja.json');
|
||||
case 'fr':
|
||||
return import('../i18n/locale/fr.json');
|
||||
case 'nb-NO':
|
||||
return import('../i18n/locale/nb_NO.json');
|
||||
case 'de':
|
||||
return import('../i18n/locale/de.json');
|
||||
case 'ru':
|
||||
return import('../i18n/locale/ru.json');
|
||||
case 'nl':
|
||||
return import('../i18n/locale/nl.json');
|
||||
default:
|
||||
return import('../i18n/locale/en.json');
|
||||
}
|
||||
|
||||
9
src/pages/movie/[movieId]/cast.tsx
Normal file
9
src/pages/movie/[movieId]/cast.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { NextPage } from 'next';
|
||||
import React from 'react';
|
||||
import MovieCast from '../../../components/MovieDetails/MovieCast';
|
||||
|
||||
const MovieCastPage: NextPage = () => {
|
||||
return <MovieCast />;
|
||||
};
|
||||
|
||||
export default MovieCastPage;
|
||||
9
src/pages/person/[personId]/index.tsx
Normal file
9
src/pages/person/[personId]/index.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import { NextPage } from 'next';
|
||||
import PersonDetails from '../../../components/PersonDetails';
|
||||
|
||||
const MoviePage: NextPage = () => {
|
||||
return <PersonDetails />;
|
||||
};
|
||||
|
||||
export default MoviePage;
|
||||
9
src/pages/tv/[tvId]/cast.tsx
Normal file
9
src/pages/tv/[tvId]/cast.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { NextPage } from 'next';
|
||||
import React from 'react';
|
||||
import TvCast from '../../../components/TvDetails/TvCast';
|
||||
|
||||
const TvCastPage: NextPage = () => {
|
||||
return <TvCast />;
|
||||
};
|
||||
|
||||
export default TvCastPage;
|
||||
@@ -36,3 +36,14 @@ body {
|
||||
.error-message {
|
||||
@apply flex items-center justify-center text-center text-gray-300 relative top-0 left-0 bottom-0 right-0 h-screen flex-col;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for IE, Edge and Firefox */
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user