From abcd7c997584c1310bd8b313ac38f30e335af8d7 Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Sat, 27 Feb 2021 20:42:09 -0500
Subject: [PATCH 001/421] fix(ui): use country-flag-icons instead of
country-flag-emoji for RegionSelector (#1011)
---
package.json | 3 ++-
src/components/RegionSelector/index.tsx | 29 +++++++++++++++++--------
yarn.lock | 13 +++++++----
3 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/package.json b/package.json
index 5d8f25926..867f01c21 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"bowser": "^2.11.0",
"connect-typeorm": "^1.1.4",
"cookie-parser": "^1.4.5",
- "country-code-emoji": "^2.2.0",
+ "country-flag-icons": "^1.2.9",
"csurf": "^1.11.0",
"email-templates": "^8.0.3",
"express": "^4.17.1",
@@ -83,6 +83,7 @@
"@types/bcrypt": "^3.0.0",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
+ "@types/country-flag-icons": "^1.2.0",
"@types/csurf": "^1.11.0",
"@types/email-templates": "^8.0.2",
"@types/express": "^4.17.11",
diff --git a/src/components/RegionSelector/index.tsx b/src/components/RegionSelector/index.tsx
index 5d717c18b..a254eaf16 100644
--- a/src/components/RegionSelector/index.tsx
+++ b/src/components/RegionSelector/index.tsx
@@ -1,10 +1,11 @@
import React, { useEffect, useMemo, useState } from 'react';
import { Listbox, Transition } from '@headlessui/react';
-import { countryCodeEmoji } from 'country-code-emoji';
import useSWR from 'swr';
import type { Region } from '../../../server/lib/settings';
import { defineMessages, useIntl } from 'react-intl';
import useSettings from '../../hooks/useSettings';
+import { hasFlag } from 'country-flag-icons';
+import 'country-flag-icons/3x2/flags.css';
const messages = defineMessages({
regionDefault: 'All Regions',
@@ -64,11 +65,15 @@ const RegionSelector: React.FC = ({
- {selectedRegion && selectedRegion.iso_3166_1 !== 'all' && (
-
- {countryCodeEmoji(selectedRegion.iso_3166_1)}
-
- )}
+ {selectedRegion &&
+ selectedRegion.iso_3166_1 !== 'all' &&
+ hasFlag(selectedRegion?.iso_3166_1) && (
+
+
+
+ )}
{selectedRegion && selectedRegion.iso_3166_1 !== 'all'
? intl.formatDisplayName(selectedRegion.iso_3166_1, {
@@ -180,7 +185,7 @@ const RegionSelector: React.FC = ({
{intl.formatMessage(messages.regionDefault)}
@@ -217,8 +222,14 @@ const RegionSelector: React.FC = ({
: 'text-gray-300'
} cursor-default select-none relative py-2 pl-8 pr-4 flex items-center`}
>
-
- {countryCodeEmoji(region.iso_3166_1)}
+
+
Date: Sat, 27 Feb 2021 21:22:45 -0500
Subject: [PATCH 002/421] chore(github): lock closed support issues (#1045)
[skip ci]
---
.github/workflows/support.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/support.yml b/.github/workflows/support.yml
index 4e9311ec1..9c4bf49e2 100644
--- a/.github/workflows/support.yml
+++ b/.github/workflows/support.yml
@@ -19,7 +19,8 @@ jobs:
to get help with Overseerr.
- [Discord](https://discord.gg/PkCWJSeCk7)
+
- [GitHub Discussions](https://github.com/sct/overseerr/discussions)
close-issue: true
- lock-issue: false
+ lock-issue: true
issue-lock-reason: 'off-topic'
From 3f9a116b17d78eeb04f0f125a4f3af6f907c83dd Mon Sep 17 00:00:00 2001
From: sct
Date: Sun, 28 Feb 2021 03:18:22 +0000
Subject: [PATCH 003/421] fix(plex-sync): no longer incorrectly sets 4k
availability when there isnt any
fixes #990
---
server/job/plexsync/index.ts | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/server/job/plexsync/index.ts b/server/job/plexsync/index.ts
index 486fbf908..f4a57c621 100644
--- a/server/job/plexsync/index.ts
+++ b/server/job/plexsync/index.ts
@@ -666,7 +666,9 @@ class JobPlexSync {
isAllStandardSeasons || shouldStayAvailable
? MediaStatus.AVAILABLE
: media.seasons.some(
- (season) => season.status !== MediaStatus.UNKNOWN
+ (season) =>
+ season.status === MediaStatus.PARTIALLY_AVAILABLE ||
+ season.status === MediaStatus.AVAILABLE
)
? MediaStatus.PARTIALLY_AVAILABLE
: MediaStatus.UNKNOWN;
@@ -675,7 +677,9 @@ class JobPlexSync {
? MediaStatus.AVAILABLE
: this.enable4kShow &&
media.seasons.some(
- (season) => season.status4k !== MediaStatus.UNKNOWN
+ (season) =>
+ season.status4k === MediaStatus.PARTIALLY_AVAILABLE ||
+ season.status4k === MediaStatus.AVAILABLE
)
? MediaStatus.PARTIALLY_AVAILABLE
: MediaStatus.UNKNOWN;
@@ -691,7 +695,9 @@ class JobPlexSync {
status: isAllStandardSeasons
? MediaStatus.AVAILABLE
: newSeasons.some(
- (season) => season.status !== MediaStatus.UNKNOWN
+ (season) =>
+ season.status === MediaStatus.PARTIALLY_AVAILABLE ||
+ season.status === MediaStatus.AVAILABLE
)
? MediaStatus.PARTIALLY_AVAILABLE
: MediaStatus.UNKNOWN,
@@ -700,7 +706,9 @@ class JobPlexSync {
? MediaStatus.AVAILABLE
: this.enable4kShow &&
newSeasons.some(
- (season) => season.status4k !== MediaStatus.UNKNOWN
+ (season) =>
+ season.status4k === MediaStatus.PARTIALLY_AVAILABLE ||
+ season.status4k === MediaStatus.AVAILABLE
)
? MediaStatus.PARTIALLY_AVAILABLE
: MediaStatus.UNKNOWN,
From 3fed26cfbe74cb662ca531fd37b69f159a051ac1 Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Sat, 27 Feb 2021 22:34:56 -0500
Subject: [PATCH 004/421] fix(ui): for server default options, display "All"
region/language option instead of empty string (#1042)
---
src/components/RegionSelector/index.tsx | 48 ++++++++++++-------
.../UserGeneralSettings/index.tsx | 27 +++++++----
src/i18n/locale/en.json | 4 +-
3 files changed, 51 insertions(+), 28 deletions(-)
diff --git a/src/components/RegionSelector/index.tsx b/src/components/RegionSelector/index.tsx
index a254eaf16..4537d5547 100644
--- a/src/components/RegionSelector/index.tsx
+++ b/src/components/RegionSelector/index.tsx
@@ -9,7 +9,7 @@ import 'country-flag-icons/3x2/flags.css';
const messages = defineMessages({
regionDefault: 'All Regions',
- regionServerDefault: '{applicationTitle} Default ({region})',
+ regionServerDefault: 'Default ({region})',
});
interface RegionSelectorProps {
@@ -38,6 +38,10 @@ const RegionSelector: React.FC = ({
[]
);
+ const defaultRegionNameFallback =
+ regions?.find((region) => region.iso_3166_1 === currentSettings.region)
+ ?.english_name ?? currentSettings.region;
+
useEffect(() => {
if (regions && value) {
if (value === 'all') {
@@ -65,15 +69,21 @@ const RegionSelector: React.FC = ({
- {selectedRegion &&
- selectedRegion.iso_3166_1 !== 'all' &&
- hasFlag(selectedRegion?.iso_3166_1) && (
-
-
-
- )}
+ {((selectedRegion && hasFlag(selectedRegion?.iso_3166_1)) ||
+ (isUserSetting &&
+ !selectedRegion &&
+ currentSettings.region &&
+ hasFlag(currentSettings.region))) && (
+
+
+
+ )}
{selectedRegion && selectedRegion.iso_3166_1 !== 'all'
? intl.formatDisplayName(selectedRegion.iso_3166_1, {
@@ -82,12 +92,11 @@ const RegionSelector: React.FC = ({
}) ?? selectedRegion.english_name
: isUserSetting && selectedRegion?.iso_3166_1 !== 'all'
? intl.formatMessage(messages.regionServerDefault, {
- applicationTitle: currentSettings.applicationTitle,
region: currentSettings.region
? intl.formatDisplayName(currentSettings.region, {
type: 'region',
fallback: 'none',
- }) ?? currentSettings.region
+ }) ?? defaultRegionNameFallback
: intl.formatMessage(messages.regionDefault),
})
: intl.formatMessage(messages.regionDefault)}
@@ -130,16 +139,23 @@ const RegionSelector: React.FC = ({
active
? 'text-white bg-indigo-600'
: 'text-gray-300'
- } cursor-default select-none relative py-2 pl-8 pr-4`}
+ } cursor-default select-none relative py-2 pl-8 pr-4 flex items-center`}
>
+
+
+
{intl.formatMessage(messages.regionServerDefault, {
- applicationTitle:
- currentSettings.applicationTitle,
region: currentSettings.region
? intl.formatDisplayName(
currentSettings.region,
@@ -147,7 +163,7 @@ const RegionSelector: React.FC = ({
type: 'region',
fallback: 'none',
}
- ) ?? currentSettings.region
+ ) ?? defaultRegionNameFallback
: intl.formatMessage(messages.regionDefault),
})}
diff --git a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
index 8e0a07655..d426f87cf 100644
--- a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
@@ -30,7 +30,7 @@ const messages = defineMessages({
originallanguageTip:
'Filter content by original language (only applies to the "Popular" and "Upcoming" categories)',
originalLanguageDefault: 'All Languages',
- languageServerDefault: '{applicationTitle} Default ({language})',
+ languageServerDefault: 'Default ({language})',
});
const UserGeneralSettings: React.FC = () => {
@@ -61,6 +61,11 @@ const UserGeneralSettings: React.FC = () => {
return ;
}
+ const defaultLanguageNameFallback =
+ languages.find(
+ (language) => language.iso_639_1 === currentSettings.originalLanguage
+ )?.english_name ?? currentSettings.originalLanguage;
+
return (
<>
@@ -167,15 +172,17 @@ const UserGeneralSettings: React.FC = () => {
>
{intl.formatMessage(messages.languageServerDefault, {
- applicationTitle: currentSettings.applicationTitle,
- language:
- intl.formatDisplayName(
- currentSettings.originalLanguage,
- {
- type: 'language',
- fallback: 'none',
- }
- ) ?? currentSettings.originalLanguage,
+ language: currentSettings.originalLanguage
+ ? intl.formatDisplayName(
+ currentSettings.originalLanguage,
+ {
+ type: 'language',
+ fallback: 'none',
+ }
+ ) ?? defaultLanguageNameFallback
+ : intl.formatMessage(
+ messages.originalLanguageDefault
+ ),
})}
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json
index 677b1aa66..a7ad2a041 100644
--- a/src/i18n/locale/en.json
+++ b/src/i18n/locale/en.json
@@ -139,7 +139,7 @@
"components.PlexLoginButton.signingin": "Signing in…",
"components.PlexLoginButton.signinwithplex": "Sign In",
"components.RegionSelector.regionDefault": "All Regions",
- "components.RegionSelector.regionServerDefault": "{applicationTitle} Default ({region})",
+ "components.RegionSelector.regionServerDefault": "Default ({region})",
"components.RequestBlock.profilechanged": "Quality Profile",
"components.RequestBlock.requestoverrides": "Request Overrides",
"components.RequestBlock.rootfolder": "Root Folder",
@@ -680,7 +680,7 @@
"components.UserProfile.ProfileHeader.settings": "Edit Settings",
"components.UserProfile.UserSettings.UserGeneralSettings.displayName": "Display Name",
"components.UserProfile.UserSettings.UserGeneralSettings.generalsettings": "General Settings",
- "components.UserProfile.UserSettings.UserGeneralSettings.languageServerDefault": "{applicationTitle} Default ({language})",
+ "components.UserProfile.UserSettings.UserGeneralSettings.languageServerDefault": "Default ({language})",
"components.UserProfile.UserSettings.UserGeneralSettings.localuser": "Local User",
"components.UserProfile.UserSettings.UserGeneralSettings.originalLanguageDefault": "All Languages",
"components.UserProfile.UserSettings.UserGeneralSettings.originallanguage": "Discover Language",
From eefcbcd3ddfa5258ee24dbbbd79de5bf50310f27 Mon Sep 17 00:00:00 2001
From: Danshil Mungur
Date: Sun, 28 Feb 2021 07:42:01 +0400
Subject: [PATCH 005/421] fix(ui): show translated string on sonarr
sucesss/failure toast messages (#1035)
---
src/components/Settings/SonarrModal/index.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/Settings/SonarrModal/index.tsx b/src/components/Settings/SonarrModal/index.tsx
index c95b2124c..65d7a157b 100644
--- a/src/components/Settings/SonarrModal/index.tsx
+++ b/src/components/Settings/SonarrModal/index.tsx
@@ -185,7 +185,7 @@ const SonarrModal: React.FC = ({
setIsValidated(true);
setTestResponse(response.data);
if (initialLoad.current) {
- addToast('Sonarr connection established!', {
+ addToast(intl.formatMessage(messages.toastSonarrTestSuccess), {
appearance: 'success',
autoDismiss: true,
});
@@ -193,7 +193,7 @@ const SonarrModal: React.FC = ({
} catch (e) {
setIsValidated(false);
if (initialLoad.current) {
- addToast('Failed to connect to Sonarr server', {
+ addToast(intl.formatMessage(messages.toastSonarrTestFailure), {
appearance: 'error',
autoDismiss: true,
});
From 2771376ecc5e80293d9ac6039b90c0fe7719e09d Mon Sep 17 00:00:00 2001
From: "Weblate (bot)"
Date: Sun, 28 Feb 2021 05:00:43 +0100
Subject: [PATCH 006/421] Translations update from Weblate (#1009)
* feat(lang): translated using Weblate (German)
Currently translated at 100.0% (761 of 761 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: J. Lavoie
Co-authored-by: Marcos
Co-authored-by: Paul Hagedorn
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (French)
Currently translated at 100.0% (761 of 761 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: J. Lavoie
Co-authored-by: Marcos
Co-authored-by: Mathieu VERMEEREN
Co-authored-by: NGVICIOUS
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (Portuguese (Portugal))
Currently translated at 100.0% (761 of 761 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: Marcos
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_PT/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (Serbian)
Currently translated at 32.4% (246 of 759 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: Marcos
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sr/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (761 of 761 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: Marcos
Co-authored-by: Tijuco
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_BR/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (Dutch)
Currently translated at 100.0% (759 of 759 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: Kobe
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (Chinese (Traditional))
Currently translated at 99.4% (757 of 761 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (Italian)
Currently translated at 99.2% (755 of 761 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: J. Lavoie
Co-authored-by: Simone Chiavaccini
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/it/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (Hungarian)
Currently translated at 39.3% (299 of 759 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: Marcos
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hu/
Translation: Overseerr/Overseerr Frontend
* feat(lang): translated using Weblate (Spanish)
Currently translated at 53.8% (409 of 759 strings)
Co-authored-by: Hosted Weblate
Co-authored-by: Marcos
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/es/
Translation: Overseerr/Overseerr Frontend
Co-authored-by: J. Lavoie
Co-authored-by: Marcos
Co-authored-by: Paul Hagedorn
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Co-authored-by: Mathieu VERMEEREN
Co-authored-by: NGVICIOUS
Co-authored-by: Tijuco
Co-authored-by: Kobe
Co-authored-by: Simone Chiavaccini
---
src/i18n/locale/de.json | 8 ++++--
src/i18n/locale/es.json | 54 ++++++++++++++++++------------------
src/i18n/locale/fr.json | 40 +++++++++++++-------------
src/i18n/locale/hu.json | 2 +-
src/i18n/locale/it.json | 51 +++++++++++++++++++---------------
src/i18n/locale/nl.json | 4 +--
src/i18n/locale/pt_BR.json | 23 ++++++++++-----
src/i18n/locale/pt_PT.json | 8 ++++--
src/i18n/locale/sr.json | 14 +++++-----
src/i18n/locale/zh_Hant.json | 7 +++--
10 files changed, 117 insertions(+), 94 deletions(-)
diff --git a/src/i18n/locale/de.json b/src/i18n/locale/de.json
index 6bf44fa15..89036b6f6 100644
--- a/src/i18n/locale/de.json
+++ b/src/i18n/locale/de.json
@@ -408,7 +408,7 @@
"components.UserEdit.autoapproveSeriesDescription": "Gewährt die automatische Genehmigung für Serienanfragen von diesem Benutzer.",
"components.UserEdit.autoapproveMoviesDescription": "Gewährt die automatische Genehmigung für Filmanfragen von diesem Benutzer.",
"components.Settings.Notifications.NotificationsSlack.validationWebhookUrlRequired": "Du musst eine Webhook-URL angeben",
- "components.Settings.Notifications.validationChatIdRequired": "Du musst eine gültige Chat-ID angeben",
+ "components.Settings.Notifications.validationChatIdRequired": "Du musst eine Chat-ID angeben",
"components.Settings.Notifications.validationBotAPIRequired": "Du musst ein Bot-Authentifizierungstoken angeben",
"components.Settings.Notifications.telegramsettingssaved": "Telegram-Benachrichtigungseinstellungen erfolgreich gespeichert!",
"components.Settings.Notifications.telegramsettingsfailed": "Telegram-Benachrichtigungseinstellungen konnten nicht gespeichert werden.",
@@ -445,7 +445,7 @@
"components.Settings.Notifications.NotificationsPushover.notificationtypes": "Benachrichtigungsarten",
"components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Pushover-Benachrichtigungseinstellungen konnten nicht gespeichert werden.",
"components.Settings.Notifications.NotificationsPushover.agentenabled": "Agent aktivieren",
- "components.Settings.Notifications.NotificationsPushover.accessToken": "Anwendungs-/API Token",
+ "components.Settings.Notifications.NotificationsPushover.accessToken": "Anwendungs-/API-Token",
"components.RequestList.sortModified": "Zuletzt geändert",
"components.RequestList.sortAdded": "Anfragedatum",
"components.RequestList.showallrequests": "Zeige alle Anfragen",
@@ -830,5 +830,7 @@
"components.Settings.Notifications.emailNotificationTypesAlert": "E-Mail-Benachrichtigungen-Empfänger",
"components.RegionSelector.regionDefault": "Alle Regionen",
"components.UserProfile.UserSettings.UserGeneralSettings.originalLanguageDefault": "Alle Sprachen",
- "components.Settings.originalLanguageDefault": "Alle Sprachen"
+ "components.Settings.originalLanguageDefault": "Alle Sprachen",
+ "components.UserProfile.UserSettings.UserGeneralSettings.languageServerDefault": "Standard ({language})",
+ "components.RegionSelector.regionServerDefault": "Standard ({region})"
}
diff --git a/src/i18n/locale/es.json b/src/i18n/locale/es.json
index 01746ecbb..7b6502cc6 100644
--- a/src/i18n/locale/es.json
+++ b/src/i18n/locale/es.json
@@ -29,15 +29,15 @@
"components.Settings.SettingsAbout.overseerrinformation": "Información de Overseerr",
"components.Settings.SettingsAbout.githubdiscussions": "Discursiones en GitHub",
"components.Settings.SettingsAbout.gettingsupport": "Soporte",
- "components.Settings.SettingsAbout.clickheretojoindiscord": "Click aquín para unirte a nuestro servidor de Discord.",
- "components.Settings.RadarrModal.validationRootFolderRequired": "Debes seleccionar una carpeta raíz.",
- "components.Settings.RadarrModal.validationProfileRequired": "Debes seleccionar un perfil de calidad.",
- "components.Settings.RadarrModal.validationPortRequired": "Debes proporcionar un puerto.",
- "components.Settings.RadarrModal.validationNameRequired": "Debes proporcionar un nombre de servidor.",
- "components.Settings.RadarrModal.validationHostnameRequired": "Debes proporcionar un hostname/IP.",
- "components.Settings.RadarrModal.validationApiKeyRequired": "Debes proporcionar la clave API.",
+ "components.Settings.SettingsAbout.clickheretojoindiscord": "Click aquín para unirte a nuestro servidor de Discord!",
+ "components.Settings.RadarrModal.validationRootFolderRequired": "Debes seleccionar una carpeta raíz",
+ "components.Settings.RadarrModal.validationProfileRequired": "Debes seleccionar un perfil de calidad",
+ "components.Settings.RadarrModal.validationPortRequired": "Debes proporcionar un puerto",
+ "components.Settings.RadarrModal.validationNameRequired": "Debes proporcionar un nombre de servidor",
+ "components.Settings.RadarrModal.validationHostnameRequired": "Debes proporcionar un hostname/IP",
+ "components.Settings.RadarrModal.validationApiKeyRequired": "Debes proporcionar la clave API",
"components.Settings.RadarrModal.toastRadarrTestSuccess": "¡Conexión con Radarr establecida!",
- "components.Settings.RadarrModal.toastRadarrTestFailure": "Error al connectar al Servidor Radarr",
+ "components.Settings.RadarrModal.toastRadarrTestFailure": "Error al connectar al Radarr.",
"components.Settings.RadarrModal.testing": "Comprobando…",
"components.Settings.RadarrModal.test": "Comprobar",
"components.Settings.RadarrModal.ssl": "SSL",
@@ -65,8 +65,8 @@
"components.Settings.Notifications.webhookUrlPlaceholder": "Ajustes del servidor -> Integraciones -> Webhooks",
"components.Settings.Notifications.webhookUrl": "URL de Webhook",
"components.Settings.Notifications.validationWebhookUrlRequired": "Debes proporcionar una URL del webhook.",
- "components.Settings.Notifications.validationSmtpPortRequired": "Debes proporcionar un puerto SMTP.",
- "components.Settings.Notifications.validationSmtpHostRequired": "Debes proporcionar un host SMTP.",
+ "components.Settings.Notifications.validationSmtpPortRequired": "Debes proporcionar un puerto SMTP",
+ "components.Settings.Notifications.validationSmtpHostRequired": "Debes proporcionar un host SMTP",
"components.Settings.Notifications.validationFromRequired": "Debe proporcionar una dirección de remitente de correo electrónico.",
"components.Settings.Notifications.smtpPort": "Puerto SMTP",
"components.Settings.Notifications.smtpHost": "Host SMTP",
@@ -93,7 +93,7 @@
"components.RequestModal.requestadmin": "Tu petición será aprovada inmediatamente.",
"components.RequestModal.requestSuccess": "{title} solicitado.",
"components.RequestList.showingresults": "Mostrando {from} a {to} de {total} resultados",
- "components.RequestModal.requestCancel": "Solicitud para {title} cancelada",
+ "components.RequestModal.requestCancel": "Solicitud para {title} cancelada.",
"components.RequestModal.request": "Solicitar",
"components.RequestModal.pendingrequest": "Solicitud pendiente para {title}",
"components.RequestModal.numberofepisodes": "# de Episodios",
@@ -174,12 +174,12 @@
"components.Settings.address": "Dirección",
"components.Settings.addradarr": "Agregar servidor Radarr",
"components.Settings.activeProfile": "Perfil activo",
- "components.Settings.SonarrModal.validationRootFolderRequired": "Debes seleccionar una carpeta raíz.",
- "components.Settings.SonarrModal.validationProfileRequired": "Debes seleccionar un perfil.",
- "components.Settings.SonarrModal.validationPortRequired": "Debes proporcionar un puerto.",
- "components.Settings.SonarrModal.validationNameRequired": "Debes proporcionar un nombre de servidor.",
- "components.Settings.SonarrModal.validationHostnameRequired": "Debes proporcionar un hostname/IP.",
- "components.Settings.SonarrModal.validationApiKeyRequired": "Debes proporcionar la clave API.",
+ "components.Settings.SonarrModal.validationRootFolderRequired": "Debes seleccionar una carpeta raíz",
+ "components.Settings.SonarrModal.validationProfileRequired": "Debes seleccionar un perfil",
+ "components.Settings.SonarrModal.validationPortRequired": "Debes proporcionar un puerto",
+ "components.Settings.SonarrModal.validationNameRequired": "Debes proporcionar un nombre de servidor",
+ "components.Settings.SonarrModal.validationHostnameRequired": "Debes proporcionar un hostname/IP",
+ "components.Settings.SonarrModal.validationApiKeyRequired": "Debes proporcionar la clave API",
"components.Settings.SonarrModal.toastRadarrTestSuccess": "¡Conexión con Sonarr establecida!",
"components.Settings.menuLogs": "Registro",
"pages.somethingWentWrong": "{statusCode} – Algo salió mal",
@@ -274,8 +274,8 @@
"components.Setup.continue": "Continuar",
"components.Setup.configureplex": "Configurar Plex",
"components.Setup.configureservices": "Configurar servicios",
- "components.Settings.validationPortRequired": "Debes proporcionar un puerto.",
- "components.Settings.validationHostnameRequired": "Debe proporcionar un nombre de host / IP.",
+ "components.Settings.validationPortRequired": "Debes proporcionar un puerto",
+ "components.Settings.validationHostnameRequired": "Debe proporcionar un nombre de host / IP",
"components.Settings.syncing": "Sincronizando…",
"components.Settings.sync": "Sincronizar bibliotecas de Plex",
"components.Settings.startscan": "Iniciar escaneo",
@@ -316,15 +316,15 @@
"components.Settings.default4k": "4K predeterminado",
"components.Settings.default": "Predeterminado",
"components.Settings.currentlibrary": "Biblioteca actual: {name}",
- "components.Settings.copied": "Clave API copiada en el portapapeles",
+ "components.Settings.copied": "Clave API copiada en el portapapeles.",
"components.Settings.cancelscan": "Cancelar escaneo",
"components.Settings.applicationurl": "URL de la aplicación",
"components.Settings.apikey": "Clave API",
"components.Setup.tip": "Consejo",
"components.Setup.syncingbackground": "La sincronización se ejecutará en segundo plano. Mientras tanto, puede continuar con el proceso de configuración.",
"i18n.deleting": "Eliminando…",
- "components.UserList.userdeleteerror": "Algo salió mal al eliminar al usuario",
- "components.UserList.userdeleted": "Usuario eliminado",
+ "components.UserList.userdeleteerror": "Algo salió mal al eliminar al usuario.",
+ "components.UserList.userdeleted": "Usuario eliminado.",
"components.UserList.deleteuser": "Eliminar usuario",
"components.UserList.deleteconfirm": "¿Está seguro de que desea eliminar este usuario? Se eliminarán todas las solicitudes existentes de este usuario.",
"components.Settings.nodefaultdescription": "Al menos un servidor debe estar marcado como predeterminado antes de que cualquier solicitud llegue a sus servicios.",
@@ -334,7 +334,7 @@
"components.Settings.SonarrModal.testFirstQualityProfiles": "Prueba la conexión para cargar perfiles de calidad",
"components.Settings.SonarrModal.loadingrootfolders": "Cargando carpetas raíz…",
"components.Settings.SonarrModal.loadingprofiles": "Cargando perfiles de calidad…",
- "components.Settings.RadarrModal.validationMinimumAvailabilityRequired": "Debes seleccionar disponibilidad mínima.",
+ "components.Settings.RadarrModal.validationMinimumAvailabilityRequired": "Debes seleccionar disponibilidad mínima",
"components.Settings.RadarrModal.testFirstRootFolders": "Prueba la conexión para cargar carpetas raíz",
"components.Settings.RadarrModal.testFirstQualityProfiles": "Prueba la conexión para cargar perfiles de calidad",
"components.Settings.RadarrModal.loadingrootfolders": "Cargando carpetas raíz…",
@@ -365,7 +365,7 @@
"components.Settings.Notifications.testsent": "¡Notificación de prueba enviada!",
"components.Settings.Notifications.test": "Comprobar",
"components.MovieDetails.studio": "Estudio",
- "components.UserList.importfromplexerror": "Algo salió mal importando usuarios de Plex",
+ "components.UserList.importfromplexerror": "Algo salió mal importando usuarios de Plex.",
"components.UserList.importfromplex": "Importar usuarios de Plex",
"components.UserList.importedfromplex": "{userCount, plural, =0 {Ningún} one {# Nuevo usuario} other {# Nuevos usuarios}} importado/s de Plex",
"components.TvDetails.viewfullcrew": "Ver Equipo Completo",
@@ -405,7 +405,7 @@
"components.Settings.Notifications.NotificationsSlack.saving": "Guardando…",
"components.Settings.Notifications.NotificationsSlack.save": "Guardar cambios",
"components.Settings.Notifications.NotificationsSlack.agentenabled": "Agente habilitado",
- "components.RequestList.RequestItem.failedretry": "Algo salió mal al reintentar la solicitud",
+ "components.RequestList.RequestItem.failedretry": "Algo salió mal al reintentar la solicitud.",
"components.MovieDetails.watchtrailer": "Ver Trailer",
"components.MovieDetails.view": "Ver",
"components.NotificationTypeSelector.mediarequestedDescription": "Envía una notificación cuando se solicitan nuevos medios. Para ciertos agentes, esto solo enviará la notificación a los administradores o usuarios con el permiso \"Administrar solicitudes\".",
@@ -464,7 +464,7 @@
"components.UserList.password": "Contraseña",
"components.UserList.localuser": "Usuario local",
"components.UserList.email": "Dirección de correo electrónico",
- "components.UserList.creating": "Creando",
+ "components.UserList.creating": "Creando…",
"components.UserList.createuser": "Crear usuario",
"components.UserList.createlocaluser": "Crear usuario local",
"components.UserList.create": "Crear",
@@ -498,7 +498,7 @@
"components.RequestModal.requestedited": "Solicitud editada.",
"components.RequestModal.requestcancelled": "Solicitud cancelada.",
"components.RequestModal.request4ktitle": "Solicitar {title} en 4K",
- "components.RequestModal.request4kfrom": "Actualmente hay una solicitud 4K pendiente de {username}",
+ "components.RequestModal.request4kfrom": "Actualmente hay una solicitud 4K pendiente de {username}.",
"components.RequestModal.request4k": "Solicitar 4K",
"components.RequestModal.pending4krequest": "Solicitud pendiente para {title} en 4K",
"components.RequestModal.errorediting": "Algo salió mal al editar la solicitud.",
diff --git a/src/i18n/locale/fr.json b/src/i18n/locale/fr.json
index bce1832ef..b937419f1 100644
--- a/src/i18n/locale/fr.json
+++ b/src/i18n/locale/fr.json
@@ -297,7 +297,7 @@
"i18n.processing": "Traitement en cours…",
"i18n.tvshows": "Séries",
"i18n.unavailable": "Indisponible",
- "pages.internalServerError": "{statusCode} – Erreur du serveur interne",
+ "pages.internalServerError": "{statusCode} – Erreur interne au serveur",
"pages.oops": "Oups",
"pages.pageNotFound": "404 – Page non trouvée",
"pages.returnHome": "Retourner à l'acceuil",
@@ -305,8 +305,8 @@
"pages.somethingWentWrong": "{statusCode} – Une erreur est survenue",
"components.TvDetails.TvCast.fullseriescast": "Casting complet de la série",
"components.MovieDetails.MovieCast.fullcast": "Casting complet",
- "components.Settings.Notifications.emailsettingssaved": "Paramètres de notification par courriel enregistrés avec succès !",
- "components.Settings.Notifications.emailsettingsfailed": "Les paramètres de notification par courriel n'ont pas pu être enregistrés.",
+ "components.Settings.Notifications.emailsettingssaved": "Paramètres de notification par e-mail enregistrés avec succès !",
+ "components.Settings.Notifications.emailsettingsfailed": "Les paramètres de notification par e-mail n'ont pas pu être enregistrés.",
"components.Settings.Notifications.discordsettingssaved": "Paramètres de notification Discord enregistrés avec succès !",
"components.Settings.Notifications.discordsettingsfailed": "Les paramètres de notification Discord n'ont pas pu être enregistrés.",
"components.Settings.validationPortRequired": "Vous devez fournir un port",
@@ -408,7 +408,7 @@
"components.Settings.Notifications.NotificationsSlack.save": "Enregistrer les changements",
"components.Settings.Notifications.NotificationsSlack.agentenabled": "Activer l'agent",
"components.RequestList.RequestItem.failedretry": "Une erreur s'est produite lors du renvoi de la demande d'ajout.",
- "components.Settings.Notifications.validationChatIdRequired": "Vous devez fournir un identifiant de discussion valide",
+ "components.Settings.Notifications.validationChatIdRequired": "Vous devez fournir un identifiant de discussion",
"components.Settings.Notifications.botAPI": "Jeton d'authentification du bot",
"components.Settings.Notifications.validationBotAPIRequired": "Vous devez fournir la clé d'authentification du bot",
"components.Settings.Notifications.telegramsettingssaved": "Paramètres de notification Telegram enregistrés avec succès !",
@@ -418,7 +418,7 @@
"components.Settings.Notifications.settinguptelegramDescription": "Pour configurer les notifications Telegram, vous aurez besoin de créer un bot et obtenir la clé API du bot. De plus, vous aurez besoin de l'identifiant de conversion pour la conversation à laquelle vous souhaitez envoyer des notifications. Vous pouvez le récupérer en ajoutant @get_id_bot à la conversation -de groupe-.",
"components.Settings.Notifications.settinguptelegram": "Configuration des notifications Telegram",
"components.StatusChacker.reloadOverseerr": "Recharger Overseerr",
- "components.StatusChacker.newversionavailable": "Nouvelle version disponible",
+ "components.StatusChacker.newversionavailable": "Une nouvelle version est disponible",
"components.StatusChacker.newversionDescription": "Une mise à jour est maintenant disponible. Cliquez sur le bouton ci-dessous pour recharger l'application.",
"components.Settings.SettingsAbout.documentation": "Documentation",
"components.Settings.Notifications.notificationtypes": "Types de notification",
@@ -437,7 +437,7 @@
"components.Settings.Notifications.NotificationsPushover.userToken": "Clé d'utilisateur",
"components.Settings.Notifications.NotificationsPushover.testsent": "Notification de test envoyée !",
"components.Settings.Notifications.NotificationsPushover.test": "Test",
- "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Pour configurer Pushover, vous aurez besoin d'enregistrer une application et d'ajouter la clé API ci-dessous. Vous pouvez utiliser l'une des icônes présentes dans le dossier public sur GitHub. Vous aurez également besoin du jeton d'utilisateur.",
+ "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Pour configurer Pushover, vous aurez besoin d'enregistrer une application et d'ajouter le jeton API ci-dessous. Vous pouvez utiliser l'une des icônes présentes dans le dossier public sur GitHub. Vous aurez également besoin du jeton d'utilisateur.",
"components.Settings.Notifications.NotificationsPushover.settinguppushover": "Configuration des notifications Pushover",
"components.Settings.Notifications.NotificationsPushover.saving": "Enregistrement…",
"components.Settings.Notifications.NotificationsPushover.save": "Enregistrer les changements",
@@ -459,7 +459,7 @@
"components.UserEdit.request4kMovies": "Demander des films 4K",
"components.UserEdit.request4kDescription": "Accorde la permission de demander des films et séries en 4K.",
"components.UserEdit.request4k": "Demander la 4K",
- "components.StatusBadge.status4k": "{status} 4K",
+ "components.StatusBadge.status4k": "{status} en 4K",
"components.Settings.Notifications.NotificationsWebhook.webhooksettingssaved": "Paramètres de notification Webhook enregistrés avec succès !",
"components.Settings.Notifications.NotificationsWebhook.webhooksettingsfailed": "Échec de l'enregistrement des paramètres de notification du webhook.",
"components.Settings.Notifications.NotificationsWebhook.webhookUrlPlaceholder": "URL webhook distante",
@@ -506,11 +506,11 @@
"components.UserList.createlocaluser": "Créer un utilisateur local",
"components.UserList.create": "Créer",
"components.UserList.autogeneratepassword": "Générer automatiquement le mot de passe",
- "components.UserList.passwordinfodescription": "Les notifications par courrier électronique doivent être configurées et activées afin de pouvoir utiliser les mots de passe générés automatiquement.",
- "components.UserList.email": "Adresse électronique",
+ "components.UserList.passwordinfodescription": "Les notifications par e-mail doivent être configurées et activées afin de pouvoir utiliser les mots de passe générés automatiquement.",
+ "components.UserList.email": "Adresse e-mail",
"components.UserList.validationemailrequired": "Vous devez entrer une adresse électronique valide",
"components.Login.validationpasswordrequired": "Vous devez fournir un mot de passe",
- "components.Login.validationemailrequired": "Vous devez fournir une adresse électronique valide",
+ "components.Login.validationemailrequired": "Vous devez fournir un e-mail valide",
"components.Login.signinwithoverseerr": "Utilisez votre compte {applicationTitle}",
"components.Login.password": "Mot de passe",
"components.Login.loginerror": "Une erreur s'est produite lors de la tentative de connexion.",
@@ -685,7 +685,7 @@
"components.PermissionEdit.viewrequestsDescription": "Accorde l'autorisation de consulter les demandes des autres utilisateurs.",
"components.PermissionEdit.viewrequests": "Voir les demandes",
"components.Discover.discover": "Découverte",
- "components.UserList.validationEmail": "Vous devez fournir une adresse électronique valide",
+ "components.UserList.validationEmail": "Vous devez fournir un e-mail valide",
"components.UserEdit.validationEmail": "Vous devez fournir une adresse électronique valide",
"components.TvDetails.nextAirDate": "Prochaine diffusion",
"components.Settings.SonarrModal.validationBaseUrlTrailingSlash": "L'URL de base ne doit pas se terminer par une barre oblique finale",
@@ -693,21 +693,21 @@
"components.Settings.RadarrModal.validationBaseUrlTrailingSlash": "L'URL de base ne doit pas se terminer par une barre oblique finale",
"components.Settings.RadarrModal.validationBaseUrlLeadingSlash": "L'URL de base doit être précédée d'une barre oblique",
"components.Settings.Notifications.validationWebhookUrl": "Vous devez fournir une URL valide",
- "components.Settings.Notifications.validationEmail": "Vous devez fournir une adresse électronique valide",
+ "components.Settings.Notifications.validationEmail": "Vous devez fournir un e-mail valide",
"components.Settings.Notifications.NotificationsWebhook.validationWebhookUrl": "Vous devez fournir une URL valide",
"components.Settings.Notifications.NotificationsSlack.validationWebhookUrl": "Vous devez fournir une URL valide",
"components.ResetPassword.validationpasswordrequired": "Vous devez fournir un mot de passe",
"components.ResetPassword.validationpasswordminchars": "Le mot de passe est trop court ; il doit comporter au moins 8 caractères",
"components.ResetPassword.validationpasswordmatch": "Le mot de passe doit correspondre",
- "components.ResetPassword.validationemailrequired": "Vous devez fournir une adresse électronique valide",
+ "components.ResetPassword.validationemailrequired": "Vous devez fournir un e-mail valide",
"components.ResetPassword.resetpasswordsuccessmessage": "Le mot de passe a été réinitialisé avec succès, sous réserve que le lien était bien valide et associé à un utilisateur existant.",
"components.ResetPassword.resetpassword": "Réinitialiser votre mot de passe",
- "components.ResetPassword.requestresetlinksuccessmessage": "Un lien de réinitialisation du mot de passe sera envoyé à l'adresse électronique fournie si elle est associée à un utilisateur valide.",
+ "components.ResetPassword.requestresetlinksuccessmessage": "Un lien de réinitialisation du mot de passe sera envoyé à l'e-mail fourni si il est associé à un utilisateur valide.",
"components.ResetPassword.password": "Mot de passe",
"components.ResetPassword.gobacklogin": "Retourner à la page de connexion",
"components.ResetPassword.forgotpassword": "Réinitialiser votre mot de passe",
- "components.ResetPassword.emailresetlink": "M'envoyer un lien de récupération",
- "components.ResetPassword.email": "Adresse électronique",
+ "components.ResetPassword.emailresetlink": "Envoyez-moi un lien de récupération par e-mail",
+ "components.ResetPassword.email": "Adresse e-mail",
"components.ResetPassword.confirmpassword": "Confirmez le mot de passe",
"components.Login.forgotpassword": "Mot de passe oublié ?",
"components.Settings.SettingsJobsCache.process": "Procès",
@@ -825,9 +825,11 @@
"components.Settings.originallanguage": "Langue à découvrir",
"components.RegionSelector.regionDefault": "Toutes les régions",
"components.Settings.Notifications.emailNotificationTypesAlertDescription": "Les notifications « Média demandé » et « Échec d’ajout du média » seront exclusivement envoyées aux utilisateurs bénéficiant de l'autorisation « Gérer les demandes ».",
- "components.Settings.Notifications.emailNotificationTypesAlert": "Destinataires des notifications par courriel",
+ "components.Settings.Notifications.emailNotificationTypesAlert": "Destinataires des notifications par e-mail",
"components.Settings.webhook": "Webhook",
- "components.Settings.email": "Courriel",
+ "components.Settings.email": "E-mail",
"components.UserProfile.UserSettings.UserGeneralSettings.originalLanguageDefault": "Toutes les langues",
- "components.Settings.originalLanguageDefault": "Toutes les langues"
+ "components.Settings.originalLanguageDefault": "Toutes les langues",
+ "components.UserProfile.UserSettings.UserGeneralSettings.languageServerDefault": "Défaut ({language})",
+ "components.RegionSelector.regionServerDefault": "Défaut ({region})"
}
diff --git a/src/i18n/locale/hu.json b/src/i18n/locale/hu.json
index 37e357d5e..523cf40a3 100644
--- a/src/i18n/locale/hu.json
+++ b/src/i18n/locale/hu.json
@@ -43,7 +43,7 @@
"components.PersonDetails.crewmember": "Stáb tag",
"components.PersonDetails.ascharacter": "mint {character}",
"components.PersonDetails.appearsin": "Szerepel a következőkben",
- "components.PermissionEdit.voteDescription": "Engedélyt ad a kérelmek szavazására. (A szavazás funkció még nincs implementálva)",
+ "components.PermissionEdit.voteDescription": "Engedélyt ad a kérelmek szavazására. (A szavazás funkció még nincs implementálva).",
"components.PermissionEdit.vote": "Szavazás",
"components.PermissionEdit.usersDescription": "Engedélyt ad az Overseerr felhasználók kezelésére. Az ezzel az engedéllyel rendelkező felhasználók nem módosíthatják a rendszergazdai jogosultsággal rendelkező felhasználókat, és nem adhatják meg a jogosultságot más felhasználónak.",
"components.PermissionEdit.users": "Felhasználók kezelése",
diff --git a/src/i18n/locale/it.json b/src/i18n/locale/it.json
index db03ff67b..88b7ca71b 100644
--- a/src/i18n/locale/it.json
+++ b/src/i18n/locale/it.json
@@ -8,7 +8,7 @@
"components.Discover.discovermovies": "Film popolari",
"components.UserEdit.email": "Indirizzo e-mail",
"components.Settings.Notifications.validationFromRequired": "È necessario fornire un indirizzo mittente di posta elettronica.",
- "components.Settings.Notifications.emailsettingssaved": "Impostazioni di notifica tramite posta elettronica salvate!",
+ "components.Settings.Notifications.emailsettingssaved": "Impostazioni di notifica tramite posta elettronica salvate con successo!",
"components.Settings.Notifications.emailsettingsfailed": "Impossibile salvare le impostazioni di notifica tramite posta elettronica.",
"components.Settings.Notifications.emailsender": "Indirizzo del mittente",
"components.Settings.SonarrModal.testing": "Test in corso…",
@@ -131,7 +131,7 @@
"i18n.available": "Disponibile",
"i18n.approved": "Approvato",
"i18n.approve": "Approva",
- "components.UserList.usertype": "Tipo di utente",
+ "components.UserList.usertype": "Tipo Utente",
"components.UserList.username": "Nome utente",
"i18n.unavailable": "Non disponibile",
"i18n.tvshows": "Serie",
@@ -208,7 +208,7 @@
"components.Settings.librariesRemaining": "Biblioteche rimanenti: {count}",
"components.Settings.hostname": "Nome host/IP",
"components.Settings.generalsettingsDescription": "Configura le impostazioni globali e predefinite per Overseerr.",
- "components.Settings.generalsettings": "Impostazioni generali",
+ "components.Settings.generalsettings": "Impostazioni Generali",
"components.Settings.edit": "Modifica",
"components.Settings.deleteserverconfirm": "Sei sicuro/a di voler eliminare questo server?",
"components.Settings.delete": "Elimina",
@@ -287,7 +287,7 @@
"components.Settings.Notifications.smtpPort": "Porta SMTP",
"components.Settings.Notifications.smtpHost": "Host SMTP",
"components.Settings.Notifications.enableSsl": "Abilita SSL",
- "components.Settings.Notifications.discordsettingssaved": "Impostazioni di Discord salvate!",
+ "components.Settings.Notifications.discordsettingssaved": "Impostazioni di Discord salvate con successo!",
"components.Settings.Notifications.authUser": "Nome utente SMTP",
"components.Settings.Notifications.authPass": "Password SMTP",
"components.RequestModal.requestseasons": "Richiedi {seasonCount} {seasonCount, plural, one {Season} other {Seasons}}",
@@ -401,7 +401,7 @@
"components.Settings.Notifications.NotificationsSlack.validationWebhookUrlRequired": "È necessario fornire un URL per il webhook.",
"components.Settings.Notifications.NotificationsSlack.test": "Prova",
"components.Settings.Notifications.NotificationsSlack.testsent": "Notifica di prova inviata!",
- "components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Impostazioni di Slack salvate!",
+ "components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Impostazioni di Slack salvate con successo!",
"components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Impossibile salvare le impostazioni di Slack.",
"components.Settings.Notifications.NotificationsSlack.settingupslackDescription": "Per configurare le notifiche con Slack, sarà necessario creare un'integrazione con un Webhook in ingresso e utilizzare l'URL del webhook fornito di seguito.",
"components.Settings.Notifications.NotificationsSlack.settingupslack": "Impostazione delle notifiche di Slack",
@@ -410,13 +410,13 @@
"components.Settings.Notifications.NotificationsSlack.agentenabled": "Abilita Agente",
"components.Settings.Notifications.validationChatIdRequired": "Devi fornire un ID discussione",
"components.Settings.Notifications.validationBotAPIRequired": "Devi fornire una chiave API bot",
- "components.Settings.Notifications.telegramsettingssaved": "Impostazioni di Telegram salvate!",
+ "components.Settings.Notifications.telegramsettingssaved": "Impostazioni di Telegram salvate con successo!",
"components.Settings.Notifications.telegramsettingsfailed": "Impossibile salvare le impostazioni di Telegram.",
"components.Settings.Notifications.senderName": "Nome del mittente",
"components.Settings.Notifications.settinguptelegramDescription": "Per configurare le notifiche di Telegram, è necessario creare un bot e ottenere la chiave API. Inoltre, è necessario l'ID chat per la chat in cui si desidera che il bot invii notifiche. Puoi ottenerlo aggiungendo @get_id_bot alla chat o alla chat di gruppo.",
"components.Settings.Notifications.settinguptelegram": "Configurazione delle notifiche di Telegram",
"components.Settings.Notifications.chatId": "ID chat",
- "components.Settings.Notifications.botAPI": "API bot",
+ "components.Settings.Notifications.botAPI": "Token di autenticazione bot",
"components.StatusChacker.reloadOverseerr": "Ricarica Overseerr",
"components.StatusChacker.newversionavailable": "Nuova versione disponibile",
"components.StatusChacker.newversionDescription": "È ora disponibile un aggiornamento. Fai clic sul pulsante in basso per ricaricare l'applicazione.",
@@ -424,7 +424,7 @@
"components.Settings.Notifications.notificationtypes": "Tipi di notifica",
"components.Settings.Notifications.NotificationsSlack.notificationtypes": "Tipi di notifica",
"components.NotificationTypeSelector.mediarequestedDescription": "Invia una notifica quando un nuovo media viene richiesto. Per alcuni agenti, la notifica verrà inviata solo agli amministratori o agli utenti con l'autorizzazione «Gestione richieste».",
- "components.NotificationTypeSelector.mediarequested": "Media richiesto",
+ "components.NotificationTypeSelector.mediarequested": "Media Richiesto",
"components.NotificationTypeSelector.mediafailedDescription": "Invia una notifica quando il media non viene aggiunto a Radarr o Sonarr.",
"components.NotificationTypeSelector.mediafailed": "Aggiunta media non riuscita",
"components.NotificationTypeSelector.mediaavailableDescription": "Invia una notifica quando il media diventa disponibile.",
@@ -433,19 +433,19 @@
"components.NotificationTypeSelector.mediaavailable": "Media disponibile",
"i18n.request": "Richiedi",
"components.Settings.Notifications.NotificationsPushover.test": "Test",
- "components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "È necessario fornire un token utente",
- "components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "È necessario fornire un token di accesso",
- "components.Settings.Notifications.NotificationsPushover.userToken": "Token utente",
+ "components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "È necessario fornire una chiave utente valida",
+ "components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "È necessario fornire un token di applicazione valido",
+ "components.Settings.Notifications.NotificationsPushover.userToken": "Chiave utente",
"components.Settings.Notifications.NotificationsPushover.testsent": "Notifica di prova inviata!",
"components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Per configurare Pushover è necessario registrare un'applicazione e ottenere il token di accesso. Quando si configura l'applicazione, è possibile utilizzare una delle icone nella cartella pubblica su GitHub. È inoltre necessario il token utente, che può essere trovato nella pagina iniziale di Pushover quando si accede.",
"components.Settings.Notifications.NotificationsPushover.settinguppushover": "Impostazione delle notifiche di Pushover",
"components.Settings.Notifications.NotificationsPushover.saving": "Salvataggio…",
"components.Settings.Notifications.NotificationsPushover.save": "Salva le modifiche",
- "components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Impostazioni di Pushover salvate!",
+ "components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Impostazioni di Pushover salvate con successo!",
"components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Impossibile salvare le impostazioni di Pushover.",
"components.Settings.Notifications.NotificationsPushover.notificationtypes": "Tipi di notifica",
"components.Settings.Notifications.NotificationsPushover.agentenabled": "Abilita Agente",
- "components.Settings.Notifications.NotificationsPushover.accessToken": "Token di accesso",
+ "components.Settings.Notifications.NotificationsPushover.accessToken": "Token di API/applicazione",
"components.RequestList.sortModified": "Ultima modifica",
"components.RequestList.sortAdded": "Data della richiesta",
"components.RequestList.showallrequests": "Mostra tutte le richieste",
@@ -515,17 +515,17 @@
"components.UserEdit.advancedrequest": "Richieste avanzate",
"components.StatusBadge.status4k": "4K {status}",
"components.Settings.hideAvailable": "Nascondi i media disponibili",
- "components.Settings.Notifications.NotificationsWebhook.webhooksettingssaved": "Impostazioni di Webhook salvate!",
+ "components.Settings.Notifications.NotificationsWebhook.webhooksettingssaved": "Impostazioni di Webhook salvate con successo!",
"components.Settings.Notifications.NotificationsWebhook.webhooksettingsfailed": "Impossibile salvare le impostazioni di Webhook.",
"components.Settings.Notifications.NotificationsWebhook.webhookUrlPlaceholder": "URL del webhook remoto",
"components.Settings.Notifications.NotificationsWebhook.webhookUrl": "URL del webhook",
"components.Settings.Notifications.NotificationsWebhook.validationWebhookUrlRequired": "Devi fornire un URL webhook.",
- "components.Settings.Notifications.NotificationsWebhook.validationJsonPayloadRequired": "È necessario fornire un payload JSON",
+ "components.Settings.Notifications.NotificationsWebhook.validationJsonPayloadRequired": "È necessario fornire un payload JSON valido",
"components.Settings.Notifications.NotificationsWebhook.test": "Test",
- "components.Settings.Notifications.NotificationsWebhook.resetPayloadSuccess": "Payload JSON reimpostato correttamente.",
+ "components.Settings.Notifications.NotificationsWebhook.resetPayloadSuccess": "Payload JSON reimpostato correttamente!",
"components.Settings.Notifications.NotificationsWebhook.resetPayload": "Ripristino delle impostazioni predefinite",
"components.Settings.Notifications.NotificationsWebhook.notificationtypes": "Tipi di notifica",
- "components.Settings.Notifications.NotificationsWebhook.customJson": "Payload JSON personalizzato",
+ "components.Settings.Notifications.NotificationsWebhook.customJson": "Payload JSON",
"components.RequestModal.requestedited": "Richiesta modificata.",
"components.RequestModal.requestcancelled": "Richiesta annullata.",
"components.RequestModal.request4kfrom": "Al momento è presente una richiesta 4K in sospeso da {username}.",
@@ -552,7 +552,7 @@
"components.PermissionEdit.settings": "Gestisci le impostazioni",
"components.PermissionEdit.request4kTv": "Richiedi serie in 4K",
"components.PermissionEdit.request4kMovies": "Rechiedi film in 4K",
- "components.PermissionEdit.managerequests": "Gestisci le richieste",
+ "components.PermissionEdit.managerequests": "Gestisci Richieste",
"components.PermissionEdit.autoapproveSeries": "Approva Automaticamente le Serie",
"components.PermissionEdit.autoapproveMovies": "Approva Automaticamente i Film",
"components.PermissionEdit.autoapprove": "Approvazione automatica",
@@ -739,7 +739,7 @@
"components.UserProfile.UserSettings.UserNotificationSettings.notificationsettings": "Impostazioni Notifiche",
"components.UserProfile.UserSettings.UserNotificationSettings.localuser": "Utente Locale",
"components.UserProfile.UserSettings.UserNotificationSettings.enableNotifications": "Abilita Notifiche",
- "components.UserProfile.UserSettings.UserNotificationSettings.discordIdTip": "Il numero ID per il tuo account Discord",
+ "components.UserProfile.UserSettings.UserNotificationSettings.discordIdTip": "ID utente del tuo account Discord",
"components.UserProfile.UserSettings.UserNotificationSettings.discordId": "ID Discord",
"components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsSuccess": "Impostazioni salvate correttamente!",
"components.Settings.Notifications.NotificationsPushbullet.saving": "Salvataggio…",
@@ -764,10 +764,10 @@
"components.Settings.Notifications.NotificationsPushbullet.validationAccessTokenRequired": "È necessario fornire un token di accesso",
"components.Settings.Notifications.NotificationsPushbullet.testSent": "Notifica di prova inviata!",
"components.Settings.Notifications.NotificationsPushbullet.test": "Test",
- "components.Settings.Notifications.NotificationsPushbullet.settingUpPushbulletDescription": "Per configurare le notifiche di Pushbullet, è necessario creare un token di accesso e immetterlo di seguito.",
+ "components.Settings.Notifications.NotificationsPushbullet.settingUpPushbulletDescription": "Per configurare le notifiche di Pushbullet, sarà necessario creare un token di accesso e immetterlo di seguito.",
"components.Settings.Notifications.NotificationsPushbullet.settingUpPushbullet": "Configurazione delle notifiche di Pushover",
"components.Settings.Notifications.NotificationsPushbullet.save": "Salva le modifiche",
- "components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Impostazioni di Pushover salvate!",
+ "components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Impostazioni di Pushover salvate correttamente!",
"components.Layout.UserDropdown.settings": "Impostazioni",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsFailed": "Impossibile salvare le impostazioni di Pushbullet.",
"components.Settings.Notifications.NotificationsPushbullet.notificationTypes": "Tipi di Notifica",
@@ -817,10 +817,15 @@
"components.Settings.originallanguage": "Lingua da scoprire",
"components.Settings.email": "E-mail",
"components.Settings.Notifications.emailNotificationTypesAlert": "Destinatari delle notifiche via posta elettronica",
- "components.RegionSelector.regionDefault": "Tutto",
+ "components.RegionSelector.regionDefault": "Tutte le regioni",
"components.UserProfile.UserSettings.UserGeneralSettings.regionTip": "Filtra contenuto per area (si applica solo alle categorie «Popolare» e «In uscita»)",
"components.UserProfile.UserSettings.UserGeneralSettings.originallanguageTip": "Filtra il contenuto in base alla lingua originale (si applica solo alle categorie «Popolare» e «In uscita»)",
"components.Settings.regionTip": "Filtra contenuto per regione (si applica solo alle categorie «Popolare» e «In uscita»)",
"components.Settings.originallanguageTip": "Filtra il contenuto in base alla lingua originale (si applica solo alle categorie «Popolare» e «In uscita»)",
- "components.Discover.upcomingtv": "Serie in uscita"
+ "components.Discover.upcomingtv": "Serie in uscita",
+ "components.UserProfile.UserSettings.UserGeneralSettings.originalLanguageDefault": "Tutte le lingue",
+ "components.Settings.originalLanguageDefault": "Tutte le lingue",
+ "components.Settings.Notifications.emailNotificationTypesAlertDescription": "Le notifiche «Media richiesto» e «Aggiunta media non riuscita» saranno inviate solo agli utenti con il permesso «Gestisci richieste».",
+ "components.UserProfile.UserSettings.UserGeneralSettings.languageServerDefault": "Predefinito ({language})",
+ "components.RegionSelector.regionServerDefault": "Predefinito ({region})"
}
diff --git a/src/i18n/locale/nl.json b/src/i18n/locale/nl.json
index 8822fdd87..d124367ac 100644
--- a/src/i18n/locale/nl.json
+++ b/src/i18n/locale/nl.json
@@ -390,7 +390,7 @@
"components.Settings.SettingsAbout.Releases.viewchangelog": "Changelog bekijken",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "De wijzigingen in je versie zijn hieronder niet beschikbaar. Bekijk de GitHub repository voor de laatste updates.",
"components.Settings.SettingsAbout.Releases.runningDevelop": "Je gebruikt een ontwikkelversie van Overseerr!",
- "components.Settings.Notifications.validationChatIdRequired": "Je moet een geldige chat-ID opgeven",
+ "components.Settings.Notifications.validationChatIdRequired": "Je moet een chat-ID opgeven",
"components.Settings.Notifications.validationBotAPIRequired": "Je moet een bot-verificatietoken opgeven",
"components.Settings.Notifications.telegramsettingssaved": "Instellingen Telegrammeldingen met succes opgeslagen!",
"components.Settings.Notifications.telegramsettingsfailed": "De instellingen voor Telegrammeldingen konden niet opgeslagen worden.",
@@ -450,7 +450,7 @@
"components.Settings.Notifications.NotificationsPushover.userToken": "Gebruikerssleutel",
"components.Settings.Notifications.NotificationsPushover.testsent": "Testmelding verzonden!",
"components.Settings.Notifications.NotificationsPushover.test": "Test",
- "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Om Pushover in te stellen, moet je een applicatie registreren en de API-sleutel hieronder invoeren. (Je kunt een van onze officiële pictogrammen op GitHub gebruiken.) Je hebt ook je gebruikerssleutel nodig.",
+ "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Om Pushover in te stellen, moet je een applicatie registreren en de API-token hieronder invoeren. (Je kunt een van onze officiële pictogrammen op GitHub gebruiken.) Je hebt ook je gebruikerssleutel nodig.",
"components.Settings.Notifications.NotificationsPushover.settinguppushover": "Pushover-meldingen instellen",
"i18n.request": "Aanvragen",
"components.RequestButton.requestmore4k": "Meer 4K aanvragen",
diff --git a/src/i18n/locale/pt_BR.json b/src/i18n/locale/pt_BR.json
index 8dfb1cc53..163728b9d 100644
--- a/src/i18n/locale/pt_BR.json
+++ b/src/i18n/locale/pt_BR.json
@@ -398,13 +398,13 @@
"components.UserEdit.autoapproveMovies": "Aprovar Filmes Automaticamente",
"components.TvDetails.watchtrailer": "Assisitir Trailer",
"components.TvDetails.firstAirDate": "Primeira Exibição",
- "components.Settings.Notifications.validationChatIdRequired": "Você deve prover um ID válido de Chat",
+ "components.Settings.Notifications.validationChatIdRequired": "Você deve prover um ID de Chat",
"components.Settings.Notifications.validationBotAPIRequired": "Você deve prover uma chave de autenticação do Bot",
"components.Settings.Notifications.senderName": "Nome do Remetente",
"components.Settings.Notifications.telegramsettingssaved": "Configurações de notificação via Telegram salvas com sucesso!",
"components.Settings.Notifications.telegramsettingsfailed": "Falha ao salvar configurações de notificação via Telegram.",
"components.Settings.Notifications.ssldisabletip": "SSL deve ser desabilitado em conexões TLS padrão (porta 587)",
- "components.Settings.Notifications.settinguptelegramDescription": "Para configurar notificações via Telegram, você precisa criar um bot e obter a chave de API do mesmo. Além disso, você irá precisar do ID de Chat de onde você deseja que o bot envie as notificações. Você pode obter o ID de Chat adicionando @get_id_bot ao chat ou grupo ao qual você deseja obter o ID.",
+ "components.Settings.Notifications.settinguptelegramDescription": "Para configurar notificações via Telegram, você precisará criar um bot e obter a chave de API do mesmo. Além disso, você irá precisar do ID de Chat de onde você deseja que o bot envie as notificações. Você pode obter o ID de Chat adicionando @get_id_bot ao chat ou grupo ao qual você deseja obter o ID.",
"components.Settings.Notifications.settinguptelegram": "Configurando Notificações Via Telegram",
"components.Settings.Notifications.chatId": "ID de Chat",
"components.Settings.Notifications.botAPI": "Token de Autenticação do Bot",
@@ -437,7 +437,7 @@
"components.Settings.Notifications.NotificationsPushover.userToken": "Chave do Usuário",
"components.Settings.Notifications.NotificationsPushover.testsent": "Notificação de teste enviada!",
"components.Settings.Notifications.NotificationsPushover.test": "Testar",
- "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Para configurar notificações via Pushover, você precisa registrar um aplicativo e obter a chave de acesso. Quando estiver configurando o aplicativo, você pode usar um dos ícones no diretório público do GitHub. Você também precisa da chave de acesso que pode ser encontrada na página inicial do usuário Pushover.",
+ "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Para configurar notificações via Pushover, você precisará registrar um aplicativo e inserir a chave de API abaixo. (Você pode user um de nossos ícones oficiais .) Você precisará também sua chave de usuário.",
"components.Settings.Notifications.NotificationsPushover.settinguppushover": "Configurando Notificações Via Pushover",
"components.Settings.Notifications.NotificationsPushover.saving": "Salvando…",
"components.Settings.Notifications.NotificationsPushover.save": "Salvar Mudanças",
@@ -830,13 +830,22 @@
"components.CollectionDetails.requestswillbecreated4k": "Serão feitas solicitações em 4K dos seguintes títulos:",
"components.CollectionDetails.requestcollection4k": "Solicitar Coleção em 4K",
"components.CollectionDetails.request4k": "Solicitar 4K",
- "components.UserProfile.UserSettings.UserGeneralSettings.region": "País de Exploração",
+ "components.UserProfile.UserSettings.UserGeneralSettings.region": "Região de Exploração",
"components.UserProfile.UserSettings.UserGeneralSettings.originallanguage": "Idioma de Exploração",
"components.Settings.webhook": "Webhook",
- "components.Settings.region": "País de Exploração",
+ "components.Settings.region": "Região de Exploração",
"components.Settings.originallanguage": "Idioma de Exploração",
"components.Settings.email": "E-mail",
"components.Settings.Notifications.emailNotificationTypesAlert": "E-mail de Destinatários",
- "components.RegionSelector.regionDefault": "Todas",
- "components.Discover.upcomingtv": "Séries Em Breve"
+ "components.RegionSelector.regionDefault": "Todas Regiões",
+ "components.Discover.upcomingtv": "Séries Em Breve",
+ "components.UserProfile.UserSettings.UserGeneralSettings.regionTip": "Filtra conteúdo por região (se aplica apenas às categorias \"Popular\" e \"Em Breve\")",
+ "components.Settings.regionTip": "Filtra conteúdo por região (se aplica apenas às categorias \"Popular\" e \"Em Breve\")",
+ "components.Settings.Notifications.emailNotificationTypesAlertDescription": "Para notificações do tipo \"Mídia Solicitada\" e \"Solicitação Falhou\", as notificações serão enviadas apenas para usuários com permissão de \"Gerenciar Solicitações\".",
+ "components.UserProfile.UserSettings.UserGeneralSettings.originallanguageTip": "Filtra conteúdo pela língua original (se aplica apenas às categorias \"Popular\" e \"Em Breve\")",
+ "components.UserProfile.UserSettings.UserGeneralSettings.originalLanguageDefault": "Todos Idiomas",
+ "components.Settings.originallanguageTip": "Filtra conteúdo pela língua original (se aplica apenas às categorias \"Popular\" e \"Em Breve\")",
+ "components.Settings.originalLanguageDefault": "Todos Idiomas",
+ "components.RegionSelector.regionServerDefault": "Padrão ({region})",
+ "components.UserProfile.UserSettings.UserGeneralSettings.languageServerDefault": "Padrão ({language})"
}
diff --git a/src/i18n/locale/pt_PT.json b/src/i18n/locale/pt_PT.json
index 7d1a85e22..f614f1ac0 100644
--- a/src/i18n/locale/pt_PT.json
+++ b/src/i18n/locale/pt_PT.json
@@ -35,7 +35,7 @@
"components.Settings.Notifications.validationSmtpPortRequired": "Você deve fornecer a porta SMTP",
"components.Settings.Notifications.validationSmtpHostRequired": "Você deve fornecer um servidor SMTP",
"components.Settings.Notifications.validationFromRequired": "Você deve fornecer um endereço do remetente",
- "components.Settings.Notifications.validationChatIdRequired": "Você deve fornecer um ID de chat válido",
+ "components.Settings.Notifications.validationChatIdRequired": "Você deve fornecer um ID de chat",
"components.Settings.Notifications.validationBotAPIRequired": "Você deve fornecer um token de autenticação de bot",
"components.Settings.Notifications.telegramsettingssaved": "Configurações de notificação Telegram salvas com sucesso!",
"components.Settings.Notifications.telegramsettingsfailed": "Falhou o salvar das configurações de notificação Telegram.",
@@ -85,7 +85,7 @@
"components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Configurações de notificação Slack salvas com sucesso!",
"components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Falhou o salvar das configurações de notificação do Slack.",
"components.Settings.Notifications.NotificationsSlack.settingupslackDescription": "Para configurar notificações Slack, você precisará criar uma integração Webhook de entrada insire o URL do webhook fornecido abaixo.",
- "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Para configurar notificações Pushover, você precisará registrar uma aplicação e inserir a chave API abaixo. (Você pode utilizar um dos nossos ícones oficiais no GitHub .) Você também precisará da sua chave de utilizador.",
+ "components.Settings.Notifications.NotificationsPushover.settinguppushoverDescription": "Para configurar notificações Pushover, você precisará registrar uma aplicação e inserir o token do API abaixo. (Você pode utilizar um dos nossos ícones oficiais no GitHub .) Você também precisará da sua chave de utilizador.",
"components.Settings.Notifications.NotificationsPushover.settinguppushover": "Configurando Notificações Pushover",
"components.Settings.Notifications.NotificationsSlack.settingupslack": "Configurando Notificações Slack",
"components.Settings.save": "Salvar Mudanças",
@@ -824,5 +824,7 @@
"components.Settings.Notifications.emailNotificationTypesAlertDescription": "Para os tipos de notificação \"Mídia Solicitada\" e \"Mídia Falhou\", as notificações serão enviadas apenas para utilizadores com a permissão \"Gerir Solicitações\".",
"components.Settings.Notifications.emailNotificationTypesAlert": "Destinatários de E-Mail de Notificação",
"components.UserProfile.UserSettings.UserGeneralSettings.originalLanguageDefault": "Todas as Idiomas",
- "components.Settings.originalLanguageDefault": "Todas as Idiomas"
+ "components.Settings.originalLanguageDefault": "Todas as Idiomas",
+ "components.UserProfile.UserSettings.UserGeneralSettings.languageServerDefault": "Padrão ({language})",
+ "components.RegionSelector.regionServerDefault": "Padrão ({region})"
}
diff --git a/src/i18n/locale/sr.json b/src/i18n/locale/sr.json
index 607784955..f7612d1ba 100644
--- a/src/i18n/locale/sr.json
+++ b/src/i18n/locale/sr.json
@@ -30,7 +30,7 @@
"components.UserList.username": "Korisničko Ime",
"components.UserList.userlist": "Lista Korisnika",
"components.UserList.userdeleteerror": "Neuspešno brisanje korisnika",
- "components.UserList.userdeleted": "Korisnik izbrisan",
+ "components.UserList.userdeleted": "Korisnik izbrisan.",
"components.UserList.user": "Korisnik",
"components.UserList.totalrequests": "Ukupno Zahteva",
"components.UserList.role": "Uloga",
@@ -76,7 +76,7 @@
"components.TvDetails.recommendationssubtext": "Ako vam se svidja {title}, možda vam se svidi…",
"components.TvDetails.recommendations": "Preporuke",
"components.TvDetails.pending": "Na čekanju",
- "components.TvDetails.overviewunavailable": "Pregled nije dostupan",
+ "components.TvDetails.overviewunavailable": "Pregled nije dostupan.",
"components.TvDetails.overview": "Pregled",
"components.TvDetails.originallanguage": "Originalni Jezik",
"components.TvDetails.network": "Mreža",
@@ -94,7 +94,7 @@
"components.TvDetails.TvCast.fullseriescast": "Ceo Repertoar Serije",
"components.TitleCard.tvshow": "Serija",
"components.TitleCard.movie": "Film",
- "components.Slider.noresults": "Nema Rezultata",
+ "components.Slider.noresults": "Nema rezultata.",
"components.Setup.welcome": "Dobrodošli u Overseerr",
"components.Setup.tip": "Savet",
"components.Setup.syncingbackground": "Sinhronizacija će raditi u pozadini. Možete da nastavite podešavanja u toku rada.",
@@ -155,7 +155,7 @@
"components.Settings.default4k": "Defaultno 4K",
"components.Settings.default": "Defaultno",
"components.Settings.currentlibrary": "Trenutna Biblioteka: {name}",
- "components.Settings.copied": "Kopiran API ključ",
+ "components.Settings.copied": "Kopiran API ključ.",
"components.Settings.cancelscan": "Otkaži skeniranje",
"components.Settings.applicationurl": "URL Aplikacije",
"components.Settings.apikey": "API Ključ",
@@ -206,7 +206,7 @@
"components.Settings.SettingsAbout.overseerrinformation": "Overseerr Informacije",
"components.Settings.SettingsAbout.githubdiscussions": "GitHub rasprave",
"components.Settings.SettingsAbout.gettingsupport": "Pomoć",
- "components.Settings.SettingsAbout.clickheretojoindiscord": "Kliknite ovde da se učlanite u naš Discord server.",
+ "components.Settings.SettingsAbout.clickheretojoindiscord": "Kliknite ovde da se učlanite u naš Discord server!",
"components.Settings.RadarrModal.validationRootFolderRequired": "Morate odabrati root folder",
"components.Settings.RadarrModal.validationProfileRequired": "Morate odabrati profil",
"components.Settings.RadarrModal.validationPortRequired": "Morate dodati port",
@@ -274,7 +274,7 @@
"components.RequestModal.requestfrom": "Trenutno postoji zahtev na čekanju od {username}",
"components.RequestModal.requestadmin": "Vaš zahtev će odmah biti prihvaćen.",
"components.RequestModal.requestSuccess": "poslat zahtev za {title} .",
- "components.RequestModal.requestCancel": "Zahtev za {title} otkazan",
+ "components.RequestModal.requestCancel": "Zahtev za {title} otkazan.",
"components.RequestModal.request": "Zahtev",
"components.RequestModal.pendingrequest": "Zahtev za {title} na čekanju",
"components.RequestModal.numberofepisodes": "Broj Epizoda",
@@ -317,7 +317,7 @@
"components.MovieDetails.recommendationssubtext": "Ako vam se svidja {title}, možda vam se dopadne…",
"components.MovieDetails.recommendations": "Predlozi",
"components.MovieDetails.pending": "Na čekanju",
- "components.MovieDetails.overviewunavailable": "Pregled nije dostupan",
+ "components.MovieDetails.overviewunavailable": "Pregled nije dostupan.",
"components.MovieDetails.overview": "Pregled",
"components.MovieDetails.originallanguage": "Originalni Jezik",
"components.MovieDetails.manageModalTitle": "Upravljaj Filmom",
diff --git a/src/i18n/locale/zh_Hant.json b/src/i18n/locale/zh_Hant.json
index b3eb51508..0de177921 100644
--- a/src/i18n/locale/zh_Hant.json
+++ b/src/i18n/locale/zh_Hant.json
@@ -449,7 +449,7 @@
"components.Settings.RadarrModal.validationNameRequired": "必須輸入伺服器名稱",
"components.Settings.RadarrModal.validationHostnameRequired": "必須輸入主機名稱或 IP 位址",
"components.Settings.RadarrModal.validationApiKeyRequired": "必須輸入應用程式密鑰",
- "components.Settings.Notifications.validationChatIdRequired": "必須輸入有效 Chat ID",
+ "components.Settings.Notifications.validationChatIdRequired": "必須輸入 Chat ID",
"components.Settings.Notifications.NotificationsWebhook.validationJsonPayloadRequired": "必須輸入有效的 JSON 有效負載",
"components.Settings.Notifications.NotificationsWebhook.authheader": "Authorization 頭欄位",
"components.Settings.RadarrModal.minimumAvailability": "最低狀態",
@@ -807,5 +807,8 @@
"components.Settings.SettingsJobsCache.jobsDescription": "Overseerr 將定時運行以下的維護任務。手動執行工作不會影響它正常的時間表。",
"components.Settings.plexsettingsDescription": "關於 Plex 伺服器的設置。Overseerr 將定時執行媒體庫掃描。",
"components.UserProfile.UserSettings.UserGeneralSettings.originalLanguageDefault": "所有語言",
- "components.Settings.originalLanguageDefault": "所有語言"
+ "components.Settings.originalLanguageDefault": "所有語言",
+ "components.Settings.manualscanDescription": "在正常情況下,Overseerr 會每24小時掃描您的 Plex 媒體庫。最近添加的媒體將更頻繁掃描。設置新的 Plex 伺服器時,我們建議您執行一次手動掃描!",
+ "components.UserProfile.UserSettings.UserGeneralSettings.languageServerDefault": "默認({language})",
+ "components.RegionSelector.regionServerDefault": "默認({region})"
}
From ddfc5e6aa8fc636931f495d6f23d56367466e3b5 Mon Sep 17 00:00:00 2001
From: sct
Date: Tue, 2 Mar 2021 08:18:31 +0000
Subject: [PATCH 007/421] fix: add correct permission checks to modifying user
password/permissions
---
server/routes/user/index.ts | 5 +++-
server/routes/user/usersettings.ts | 29 ++++++++++++++++---
.../UserSettings/UserPasswordChange/index.tsx | 26 +++++++++++++++--
src/i18n/locale/en.json | 2 ++
4 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/server/routes/user/index.ts b/server/routes/user/index.ts
index 803aed7c5..d29567a61 100644
--- a/server/routes/user/index.ts
+++ b/server/routes/user/index.ts
@@ -167,7 +167,10 @@ router.get<{ id: string }, UserRequestsResponse>(
}
);
-const canMakePermissionsChange = (permissions: number, user?: User) =>
+export const canMakePermissionsChange = (
+ permissions: number,
+ user?: User
+): boolean =>
// Only let the owner grant admin privileges
!(hasPermission(Permission.ADMIN, permissions) && user?.id !== 1) ||
// Only let users with the manage settings permission, grant the same permission
diff --git a/server/routes/user/usersettings.ts b/server/routes/user/usersettings.ts
index c2e075119..e102e2e22 100644
--- a/server/routes/user/usersettings.ts
+++ b/server/routes/user/usersettings.ts
@@ -1,5 +1,6 @@
import { Router } from 'express';
import { getRepository } from 'typeorm';
+import { canMakePermissionsChange } from '.';
import { User } from '../../entity/User';
import { UserSettings } from '../../entity/UserSettings';
import {
@@ -21,6 +22,7 @@ const isOwnProfileOrAdmin = (): Middleware => {
message: "You do not have permission to view this user's settings.",
});
}
+
next();
};
return authMiddleware;
@@ -137,7 +139,19 @@ userSettingsRoutes.post<
if (req.body.newPassword.length < 8) {
return next({
status: 400,
- message: 'Password must be at least 8 characters',
+ message: 'Password must be at least 8 characters.',
+ });
+ }
+
+ if (
+ (user.id === 1 && req.user?.id !== 1) ||
+ (user.hasPermission(Permission.ADMIN) &&
+ user.id !== req.user?.id &&
+ req.user?.id !== 1)
+ ) {
+ return next({
+ status: 403,
+ message: "You do not have permission to modify this user's password.",
});
}
@@ -283,13 +297,20 @@ userSettingsRoutes.post<
return next({ status: 404, message: 'User not found.' });
}
- if (user.id === 1) {
+ // Only let the owner user modify themselves
+ if (user.id === 1 && req.user?.id !== 1) {
return next({
- status: 500,
- message: 'Permissions for user with ID 1 cannot be modified',
+ status: 403,
+ message: 'You do not have permission to modify this user',
});
}
+ if (!canMakePermissionsChange(req.body.permissions, req.user)) {
+ return next({
+ status: 403,
+ message: 'You do not have permission to grant this level of access',
+ });
+ }
user.permissions = req.body.permissions;
await userRepository.save(user);
diff --git a/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx b/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
index cc973aa0d..545cf539b 100644
--- a/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserPasswordChange/index.tsx
@@ -5,7 +5,7 @@ import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
-import { useUser } from '../../../../hooks/useUser';
+import { Permission, useUser } from '../../../../hooks/useUser';
import Error from '../../../../pages/_error';
import Alert from '../../../Common/Alert';
import Button from '../../../Common/Button';
@@ -33,6 +33,9 @@ const messages = defineMessages({
nopasswordsetDescription:
'This user account currently does not have a password specifically for {applicationTitle}.\
Configure a password below to enable this account to sign in as a "local user."',
+ nopermission: 'No Permission',
+ nopermissionDescription:
+ "You do not have permission to modify this user's password.",
});
const UserPasswordChange: React.FC = () => {
@@ -41,14 +44,14 @@ const UserPasswordChange: React.FC = () => {
const { addToast } = useToasts();
const router = useRouter();
const { user: currentUser } = useUser();
- const { user } = useUser({ id: Number(router.query.userId) });
+ const { user, hasPermission } = useUser({ id: Number(router.query.userId) });
const { data, error, revalidate } = useSWR<{ hasPassword: boolean }>(
user ? `/api/v1/user/${user?.id}/settings/password` : null
);
const PasswordChangeSchema = Yup.object().shape({
currentPassword: Yup.lazy(() =>
- data?.hasPassword
+ data?.hasPassword && currentUser?.id === user?.id
? Yup.string().required(
intl.formatMessage(messages.validationCurrentPassword)
)
@@ -73,6 +76,23 @@ const UserPasswordChange: React.FC = () => {
return ;
}
+ if (
+ currentUser?.id !== user?.id &&
+ hasPermission(Permission.ADMIN) &&
+ currentUser?.id !== 1
+ ) {
+ return (
+ <>
+
+
{intl.formatMessage(messages.password)}
+
+
+ {intl.formatMessage(messages.nopermissionDescription)}
+
+ >
+ );
+ }
+
return (
<>
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json
index a7ad2a041..1a4315a81 100644
--- a/src/i18n/locale/en.json
+++ b/src/i18n/locale/en.json
@@ -708,6 +708,8 @@
"components.UserProfile.UserSettings.UserPasswordChange.newpassword": "New Password",
"components.UserProfile.UserSettings.UserPasswordChange.nopasswordset": "No Password Set",
"components.UserProfile.UserSettings.UserPasswordChange.nopasswordsetDescription": "This user account currently does not have a password specifically for {applicationTitle}. Configure a password below to enable this account to sign in as a \"local user.\"",
+ "components.UserProfile.UserSettings.UserPasswordChange.nopermission": "No Permission",
+ "components.UserProfile.UserSettings.UserPasswordChange.nopermissionDescription": "You do not have permission to modify this user's password.",
"components.UserProfile.UserSettings.UserPasswordChange.password": "Password",
"components.UserProfile.UserSettings.UserPasswordChange.save": "Save Changes",
"components.UserProfile.UserSettings.UserPasswordChange.saving": "Saving…",
From 1b55d2dfbc06d900e7370a4ddfd81789a25bf00c Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Tue, 2 Mar 2021 05:06:52 -0500
Subject: [PATCH 008/421] feat(ui): display "Owner" role instead of "Admin" for
user ID 1 (#1050)
* feat(ui): display "Owner" role instead of "Admin" for user ID 1
Also add role to user settings page, and fix the missing "Account Type" string and use the same
verbiage on the user list page
* feat(lang): generate translation keys
* fix: utilize hasPermission returned by useUser instead of importing from server/lib/permissions
---
src/components/UserList/index.tsx | 9 ++++--
.../UserGeneralSettings/index.tsx | 29 +++++++++++++++++--
src/i18n/locale/en.json | 8 ++++-
3 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/src/components/UserList/index.tsx b/src/components/UserList/index.tsx
index ebe88b3af..e9be2cdf9 100644
--- a/src/components/UserList/index.tsx
+++ b/src/components/UserList/index.tsx
@@ -32,13 +32,14 @@ const messages = defineMessages({
'{userCount, plural, =0 {No new users} one {# new user} other {# new users}} imported from Plex.',
user: 'User',
totalrequests: 'Total Requests',
- usertype: 'User Type',
+ accounttype: 'Account Type',
role: 'Role',
created: 'Created',
lastupdated: 'Last Updated',
edit: 'Edit',
bulkedit: 'Bulk Edit',
delete: 'Delete',
+ owner: 'Owner',
admin: 'Admin',
plexuser: 'Plex User',
deleteuser: 'Delete User',
@@ -472,7 +473,7 @@ const UserList: React.FC = () => {
{intl.formatMessage(messages.user)}
{intl.formatMessage(messages.totalrequests)}
-
{intl.formatMessage(messages.usertype)}
+
{intl.formatMessage(messages.accounttype)}
{intl.formatMessage(messages.role)}
{intl.formatMessage(messages.created)}
{intl.formatMessage(messages.lastupdated)}
@@ -543,7 +544,9 @@ const UserList: React.FC = () => {
)}
- {hasPermission(Permission.ADMIN, user.permissions)
+ {user.id === 1
+ ? intl.formatMessage(messages.owner)
+ : hasPermission(Permission.ADMIN, user.permissions)
? intl.formatMessage(messages.admin)
: intl.formatMessage(messages.user)}
diff --git a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
index d426f87cf..3551aff36 100644
--- a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
@@ -7,7 +7,7 @@ import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import { Language } from '../../../../../server/lib/settings';
import useSettings from '../../../../hooks/useSettings';
-import { UserType, useUser } from '../../../../hooks/useUser';
+import { UserType, useUser, Permission } from '../../../../hooks/useUser';
import Error from '../../../../pages/_error';
import Badge from '../../../Common/Badge';
import Button from '../../../Common/Button';
@@ -19,8 +19,13 @@ const messages = defineMessages({
displayName: 'Display Name',
save: 'Save Changes',
saving: 'Saving…',
+ accounttype: 'Account Type',
plexuser: 'Plex User',
localuser: 'Local User',
+ role: 'Role',
+ owner: 'Owner',
+ admin: 'Admin',
+ user: 'User',
toastSettingsSuccess: 'Settings successfully saved!',
toastSettingsFailure: 'Something went wrong while saving settings.',
region: 'Discover Region',
@@ -37,7 +42,9 @@ const UserGeneralSettings: React.FC = () => {
const intl = useIntl();
const { addToast } = useToasts();
const router = useRouter();
- const { user, mutate } = useUser({ id: Number(router.query.userId) });
+ const { user, hasPermission, mutate } = useUser({
+ id: Number(router.query.userId),
+ });
const { currentSettings } = useSettings();
const { data, error, revalidate } = useSWR<{
username?: string;
@@ -107,7 +114,9 @@ const UserGeneralSettings: React.FC = () => {
return (
+
+
+ {intl.formatMessage(messages.botUsername)}
+
+
+
+
+
+ {errors.botUsername && touched.botUsername && (
+
{errors.botUsername}
+ )}
+
+
{intl.formatMessage(messages.botAPI)}
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
index 05f75b3bf..9e3c9f339 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
@@ -19,6 +19,15 @@ const messages = defineMessages({
discordIdTip:
'The ID number for your Discord user account',
validationDiscordId: 'You must provide a valid Discord user ID',
+ telegramChatId: 'Telegram Chat ID',
+ telegramChatIdTip:
+ 'The Chat ID can be aquired by adding @get_id_bot to the chat.',
+ telegramChatIdTipLong:
+ 'Start a chat by clicking here .\
+ Then get the group Chat ID by adding @get_id_bot to that chat and send /my_id to the chat',
+ sendSilently: 'Send Silently',
+ sendSilentlyDescription: 'Send telegram notifications silently',
+ validationTelegramChatId: 'You must provide a valid Telegram Chat ID',
save: 'Save Changes',
saving: 'Saving…',
plexuser: 'Plex User',
@@ -40,6 +49,12 @@ const UserNotificationSettings: React.FC = () => {
discordId: Yup.string()
.optional()
.matches(/^\d{17,18}$/, intl.formatMessage(messages.validationDiscordId)),
+ telegramChatId: Yup.string()
+ .optional()
+ .matches(
+ /^[-]?\d+$/,
+ intl.formatMessage(messages.validationTelegramChatId)
+ ),
});
if (!data && !error) {
@@ -61,6 +76,8 @@ const UserNotificationSettings: React.FC = () => {
initialValues={{
enableNotifications: data?.enableNotifications,
discordId: data?.discordId,
+ telegramChatId: data?.telegramChatId,
+ telegramSendSilently: data?.telegramSendSilently,
}}
validationSchema={UserNotificationSettingsSchema}
enableReinitialize
@@ -71,6 +88,8 @@ const UserNotificationSettings: React.FC = () => {
{
enableNotifications: values.enableNotifications,
discordId: values.discordId,
+ telegramChatId: values.telegramChatId,
+ telegramSendSilently: values.telegramSendSilently,
}
);
@@ -135,6 +154,86 @@ const UserNotificationSettings: React.FC = () => {
)}
+
+
+ {intl.formatMessage(messages.telegramChatId)}
+
+ {data?.telegramBotUsername
+ ? intl.formatMessage(messages.telegramChatIdTipLong, {
+ TelegramBotLink: function TelegramBotLink(msg) {
+ return (
+
+ {msg}
+
+ );
+ },
+ GetIdBotLink: function GetIdBotLink(msg) {
+ return (
+
+ {msg}
+
+ );
+ },
+ })
+ : intl.formatMessage(messages.telegramChatIdTip, {
+ GetIdBotLink: function GetIdBotLink(msg) {
+ return (
+
+ {msg}
+
+ );
+ },
+ })}
+
+
+
+
+
+
+ {errors.telegramChatId && touched.telegramChatId && (
+
{errors.telegramChatId}
+ )}
+
+
+
+
+
+ {intl.formatMessage(messages.sendSilently)}
+
+
+ {intl.formatMessage(messages.sendSilentlyDescription)}
+
+
+
+
+
+
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json
index 4b2b59321..695fbbe8f 100644
--- a/src/i18n/locale/en.json
+++ b/src/i18n/locale/en.json
@@ -306,6 +306,7 @@
"components.Settings.Notifications.authPass": "SMTP Password",
"components.Settings.Notifications.authUser": "SMTP Username",
"components.Settings.Notifications.botAPI": "Bot Authentication Token",
+ "components.Settings.Notifications.botUsername": "Bot Username",
"components.Settings.Notifications.chatId": "Chat ID",
"components.Settings.Notifications.discordsettingsfailed": "Discord notification settings failed to save.",
"components.Settings.Notifications.discordsettingssaved": "Discord notification settings saved successfully!",
@@ -718,9 +719,15 @@
"components.UserProfile.UserSettings.UserNotificationSettings.plexuser": "Plex User",
"components.UserProfile.UserSettings.UserNotificationSettings.save": "Save Changes",
"components.UserProfile.UserSettings.UserNotificationSettings.saving": "Saving…",
+ "components.UserProfile.UserSettings.UserNotificationSettings.sendSilently": "Send Silently",
+ "components.UserProfile.UserSettings.UserNotificationSettings.sendSilentlyDescription": "Send telegram notifications silently",
+ "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatId": "Telegram Chat ID",
+ "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTip": "The Chat ID can be aquired by adding @get_id_bot to the chat.",
+ "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTipLong": "Start a chat by clicking here . Then get the group Chat ID by adding @get_id_bot to that chat and send /my_id to the chat",
"components.UserProfile.UserSettings.UserNotificationSettings.toastSettingsFailure": "Something went wrong while saving settings.",
"components.UserProfile.UserSettings.UserNotificationSettings.toastSettingsSuccess": "Settings successfully saved!",
"components.UserProfile.UserSettings.UserNotificationSettings.validationDiscordId": "You must provide a valid Discord user ID",
+ "components.UserProfile.UserSettings.UserNotificationSettings.validationTelegramChatId": "You must provide a valid Telegram Chat ID",
"components.UserProfile.UserSettings.UserPasswordChange.confirmpassword": "Confirm Password",
"components.UserProfile.UserSettings.UserPasswordChange.currentpassword": "Current Password",
"components.UserProfile.UserSettings.UserPasswordChange.newpassword": "New Password",
From bdf67e732b6c77cbae768a25edfc9a663ef0108b Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Thu, 4 Mar 2021 22:35:08 -0500
Subject: [PATCH 024/421] fix(lang): edit new Telegram-related strings to
conform to style guide (#1093)
---
.../UserNotificationSettings/index.tsx | 19 ++++++++++---------
src/i18n/locale/en.json | 10 +++++-----
2 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx b/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
index 9e3c9f339..372130163 100644
--- a/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
+++ b/src/components/UserProfile/UserSettings/UserNotificationSettings/index.tsx
@@ -20,14 +20,12 @@ const messages = defineMessages({
'The ID number for your Discord user account',
validationDiscordId: 'You must provide a valid Discord user ID',
telegramChatId: 'Telegram Chat ID',
- telegramChatIdTip:
- 'The Chat ID can be aquired by adding @get_id_bot to the chat.',
+ telegramChatIdTip: 'Add @get_id_bot to the chat',
telegramChatIdTipLong:
- 'Start a chat by clicking here .\
- Then get the group Chat ID by adding @get_id_bot to that chat and send /my_id to the chat',
- sendSilently: 'Send Silently',
- sendSilentlyDescription: 'Send telegram notifications silently',
- validationTelegramChatId: 'You must provide a valid Telegram Chat ID',
+ 'Start a chat , add @get_id_bot , and issue the /my_id command',
+ sendSilently: 'Send Telegram Messages Silently',
+ sendSilentlyDescription: 'Send notifications with no sound',
+ validationTelegramChatId: 'You must provide a valid Telegram chat ID',
save: 'Save Changes',
saving: 'Saving…',
plexuser: 'Plex User',
@@ -47,10 +45,10 @@ const UserNotificationSettings: React.FC = () => {
const UserNotificationSettingsSchema = Yup.object().shape({
discordId: Yup.string()
- .optional()
+ .nullable()
.matches(/^\d{17,18}$/, intl.formatMessage(messages.validationDiscordId)),
telegramChatId: Yup.string()
- .optional()
+ .nullable()
.matches(
/^[-]?\d+$/,
intl.formatMessage(messages.validationTelegramChatId)
@@ -184,6 +182,9 @@ const UserNotificationSettings: React.FC = () => {
);
},
+ code: function code(msg) {
+ return {msg};
+ },
})
: intl.formatMessage(messages.telegramChatIdTip, {
GetIdBotLink: function GetIdBotLink(msg) {
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json
index 695fbbe8f..c3821d337 100644
--- a/src/i18n/locale/en.json
+++ b/src/i18n/locale/en.json
@@ -719,15 +719,15 @@
"components.UserProfile.UserSettings.UserNotificationSettings.plexuser": "Plex User",
"components.UserProfile.UserSettings.UserNotificationSettings.save": "Save Changes",
"components.UserProfile.UserSettings.UserNotificationSettings.saving": "Saving…",
- "components.UserProfile.UserSettings.UserNotificationSettings.sendSilently": "Send Silently",
- "components.UserProfile.UserSettings.UserNotificationSettings.sendSilentlyDescription": "Send telegram notifications silently",
+ "components.UserProfile.UserSettings.UserNotificationSettings.sendSilently": "Send Telegram Messages Silently",
+ "components.UserProfile.UserSettings.UserNotificationSettings.sendSilentlyDescription": "Send notifications with no sound",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramChatId": "Telegram Chat ID",
- "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTip": "The Chat ID can be aquired by adding @get_id_bot to the chat.",
- "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTipLong": "Start a chat by clicking here . Then get the group Chat ID by adding @get_id_bot to that chat and send /my_id to the chat",
+ "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTip": "Add @get_id_bot to the chat",
+ "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTipLong": "Start a chat , add @get_id_bot , and issue the /my_id command",
"components.UserProfile.UserSettings.UserNotificationSettings.toastSettingsFailure": "Something went wrong while saving settings.",
"components.UserProfile.UserSettings.UserNotificationSettings.toastSettingsSuccess": "Settings successfully saved!",
"components.UserProfile.UserSettings.UserNotificationSettings.validationDiscordId": "You must provide a valid Discord user ID",
- "components.UserProfile.UserSettings.UserNotificationSettings.validationTelegramChatId": "You must provide a valid Telegram Chat ID",
+ "components.UserProfile.UserSettings.UserNotificationSettings.validationTelegramChatId": "You must provide a valid Telegram chat ID",
"components.UserProfile.UserSettings.UserPasswordChange.confirmpassword": "Confirm Password",
"components.UserProfile.UserSettings.UserPasswordChange.currentpassword": "Current Password",
"components.UserProfile.UserSettings.UserPasswordChange.newpassword": "New Password",
From 420038d5ffdd4070df03e5c5cb6ef8d6208fddb5 Mon Sep 17 00:00:00 2001
From: Jakob Ankarhem
Date: Fri, 5 Mar 2021 08:12:48 +0100
Subject: [PATCH 025/421] fix(requests): add plex url to request item (#1088)
---
src/components/RequestList/RequestItem/index.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx
index 59cdea66d..73c60e988 100644
--- a/src/components/RequestList/RequestItem/index.tsx
+++ b/src/components/RequestList/RequestItem/index.tsx
@@ -209,6 +209,8 @@ const RequestItem: React.FC = ({
).length > 0
}
is4k={requestData.is4k}
+ plexUrl={requestData.media.plexUrl}
+ plexUrl4k={requestData.media.plexUrl4k}
/>
)}
From 0c4637f779d8904037b9cbd5fe9166cf05a891c5 Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Fri, 5 Mar 2021 03:33:20 -0500
Subject: [PATCH 026/421] fix(ui): add alt prop to studio/network logos & fix
blinking text cursor (#1095)
---
src/components/Discover/DiscoverNetwork/index.tsx | 6 +++---
src/components/Discover/DiscoverStudio/index.tsx | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/components/Discover/DiscoverNetwork/index.tsx b/src/components/Discover/DiscoverNetwork/index.tsx
index b73171c40..66b8c1a69 100644
--- a/src/components/Discover/DiscoverNetwork/index.tsx
+++ b/src/components/Discover/DiscoverNetwork/index.tsx
@@ -49,9 +49,9 @@ const DiscoverTvNetwork: React.FC = () => {
{firstResultData?.network.logoPath ? (
) : (
diff --git a/src/components/Discover/DiscoverStudio/index.tsx b/src/components/Discover/DiscoverStudio/index.tsx
index beca4a3f6..f7fd7f7a9 100644
--- a/src/components/Discover/DiscoverStudio/index.tsx
+++ b/src/components/Discover/DiscoverStudio/index.tsx
@@ -49,9 +49,9 @@ const DiscoverMovieStudio: React.FC = () => {
{firstResultData?.studio.logoPath ? (
) : (
From cd21865c4d5be00c13c372e0b7a058f61ec855a2 Mon Sep 17 00:00:00 2001
From: sct
Date: Sat, 6 Mar 2021 00:46:53 +0900
Subject: [PATCH 027/421] feat(ui): request list redesign (#1099)
---
.../RequestList/RequestItem/index.tsx | 440 +++++++++---------
src/components/RequestList/index.tsx | 227 ++++-----
src/i18n/locale/en.json | 8 +-
3 files changed, 344 insertions(+), 331 deletions(-)
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx
index 73c60e988..16a98dd3b 100644
--- a/src/components/RequestList/RequestItem/index.tsx
+++ b/src/components/RequestList/RequestItem/index.tsx
@@ -1,12 +1,7 @@
import React, { useContext, useState } from 'react';
import { useInView } from 'react-intersection-observer';
import type { MediaRequest } from '../../../../server/entity/MediaRequest';
-import {
- useIntl,
- FormattedDate,
- FormattedRelativeTime,
- defineMessages,
-} from 'react-intl';
+import { useIntl, FormattedRelativeTime, defineMessages } from 'react-intl';
import { useUser, Permission } from '../../../hooks/useUser';
import { LanguageContext } from '../../../context/LanguageContext';
import type { MovieDetails } from '../../../../server/models/Movie';
@@ -14,7 +9,6 @@ import type { TvDetails } from '../../../../server/models/Tv';
import useSWR from 'swr';
import Badge from '../../Common/Badge';
import StatusBadge from '../../StatusBadge';
-import Table from '../../Common/Table';
import {
MediaRequestStatus,
MediaStatus,
@@ -25,11 +19,16 @@ import globalMessages from '../../../i18n/globalMessages';
import Link from 'next/link';
import { useToasts } from 'react-toast-notifications';
import RequestModal from '../../RequestModal';
+import ConfirmButton from '../../Common/ConfirmButton';
const messages = defineMessages({
seasons: 'Seasons',
notavailable: 'N/A',
failedretry: 'Something went wrong while retrying the request.',
+ areyousure: 'Are you sure?',
+ status: 'Status',
+ requested: 'Requested',
+ modifiedby: 'Modified By',
});
const isMovie = (movie: MovieDetails | TvDetails): movie is MovieDetails => {
@@ -101,22 +100,24 @@ const RequestItem: React.FC = ({
if (!title && !error) {
return (
-
-
-
+
);
}
if (!title || !requestData) {
return (
-
-
-
+
);
}
return (
-
+ <>
= ({
setShowEditModal(false);
}}
/>
-
-
-
+
+
+
-
-
-
-
-
+ alt=""
+ className="h-full transition duration-300 scale-100 rounded-md shadow-sm cursor-pointer w-14 lg:w-auto lg:h-full transform-gpu hover:scale-105 hover:shadow-md"
+ />
+
= ({
: `/tv/${requestData.media.tmdbId}`
}
>
-
+
{isMovie(title) ? title.title : title.name}
-
+
= ({
{requestData.seasons.length > 0 && (
-
+
{intl.formatMessage(messages.seasons)}
@@ -188,191 +185,204 @@ const RequestItem: React.FC = ({
)}
-
-
- {requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
- MediaStatus.UNKNOWN ||
- requestData.status === MediaRequestStatus.DECLINED ? (
-
- {requestData.status === MediaRequestStatus.DECLINED
- ? intl.formatMessage(globalMessages.declined)
- : intl.formatMessage(globalMessages.failed)}
-
- ) : (
- 0
- }
- is4k={requestData.is4k}
- plexUrl={requestData.media.plexUrl}
- plexUrl4k={requestData.media.plexUrl4k}
- />
- )}
-
-
-
-
-
-
-
-
-
-
- {requestData.modifiedBy ? (
-
-
-
-
- {requestData.modifiedBy.displayName} (
-
- )
-
-
+
+
+ {intl.formatMessage(messages.status)}
+ {requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
+ MediaStatus.UNKNOWN ||
+ requestData.status === MediaRequestStatus.DECLINED ? (
+
+ {requestData.status === MediaRequestStatus.DECLINED
+ ? intl.formatMessage(globalMessages.declined)
+ : intl.formatMessage(globalMessages.failed)}
+
+ ) : (
+ 0
+ }
+ is4k={requestData.is4k}
+ plexUrl={requestData.media.plexUrl}
+ plexUrl4k={requestData.media.plexUrl4k}
+ />
+ )}
+
+
+
+ {intl.formatMessage(messages.requested)}
- ) : (
- N/A
- )}
+
+ {intl.formatDate(requestData.createdAt)}
+
+
+
-
-
- {requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
- MediaStatus.UNKNOWN &&
- requestData.status !== MediaRequestStatus.DECLINED &&
- hasPermission(Permission.MANAGE_REQUESTS) && (
- retryRequest()}
- >
-
+ {requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
+ MediaStatus.UNKNOWN &&
+ requestData.status !== MediaRequestStatus.DECLINED &&
+ hasPermission(Permission.MANAGE_REQUESTS) && (
+ retryRequest()}
>
-
-
-
-
- {intl.formatMessage(globalMessages.retry)}
-
-
- )}
- {requestData.status !== MediaRequestStatus.PENDING &&
- hasPermission(Permission.MANAGE_REQUESTS) && (
- deleteRequest()}
- >
-
+
+
+
+
+ {intl.formatMessage(globalMessages.retry)}
+
+
+ )}
+ {requestData.status !== MediaRequestStatus.PENDING &&
+ hasPermission(Permission.MANAGE_REQUESTS) && (
+ deleteRequest()}
+ confirmText={intl.formatMessage(messages.areyousure)}
+ className="w-full"
>
-
-
-
- {intl.formatMessage(globalMessages.delete)}
-
-
- )}
- {requestData.status === MediaRequestStatus.PENDING &&
- hasPermission(Permission.MANAGE_REQUESTS) && (
- <>
-
- modifyRequest('approve')}
+
-
-
-
-
- {intl.formatMessage(globalMessages.approve)}
+
+
+
+ {intl.formatMessage(globalMessages.delete)}
+
+
+ )}
+ {requestData.status === MediaRequestStatus.PENDING &&
+ hasPermission(Permission.MANAGE_REQUESTS) && (
+ <>
+
+
+ modifyRequest('approve')}
+ >
+
+
+
+
+ {intl.formatMessage(globalMessages.approve)}
+
+
-
-
-
- modifyRequest('decline')}
- >
-
-
-
-
- {intl.formatMessage(globalMessages.decline)}
+
+ modifyRequest('decline')}
+ >
+
+
+
+
+ {intl.formatMessage(globalMessages.decline)}
+
+
-
-
-
- setShowEditModal(true)}
- >
-
+
+ setShowEditModal(true)}
>
-
-
-
- {intl.formatMessage(globalMessages.edit)}
-
-
-
- >
- )}
-
-
+
+
+
+
+ {intl.formatMessage(globalMessages.edit)}
+
+
+
+ >
+ )}
+
+
+ >
);
};
diff --git a/src/components/RequestList/index.tsx b/src/components/RequestList/index.tsx
index 0be3bb008..27db650ca 100644
--- a/src/components/RequestList/index.tsx
+++ b/src/components/RequestList/index.tsx
@@ -1,20 +1,15 @@
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
import useSWR from 'swr';
import type { RequestResultsResponse } from '../../../server/interfaces/api/requestInterfaces';
import LoadingSpinner from '../Common/LoadingSpinner';
import RequestItem from './RequestItem';
import Header from '../Common/Header';
-import Table from '../Common/Table';
import Button from '../Common/Button';
import { defineMessages, useIntl } from 'react-intl';
import PageTitle from '../Common/PageTitle';
const messages = defineMessages({
requests: 'Requests',
- mediaInfo: 'Media Info',
- status: 'Status',
- requestedAt: 'Requested At',
- modifiedBy: 'Last Modified By',
showingresults:
'Showing {from} to {to} of {total} results',
resultsperpage: 'Display {pageSize} results per page',
@@ -46,6 +41,32 @@ const RequestList: React.FC = () => {
pageIndex * currentPageSize
}&filter=${currentFilter}&sort=${currentSort}`
);
+
+ // Restore last set filter values on component mount
+ useEffect(() => {
+ const filterString = window.localStorage.getItem('rl-filter-settings');
+
+ if (filterString) {
+ const filterSettings = JSON.parse(filterString);
+
+ setCurrentFilter(filterSettings.currentFilter);
+ setCurrentSort(filterSettings.currentSort);
+ setCurrentPageSize(filterSettings.currentPageSize);
+ }
+ }, []);
+
+ // Set fitler values to local storage any time they are changed
+ useEffect(() => {
+ window.localStorage.setItem(
+ 'rl-filter-settings',
+ JSON.stringify({
+ currentFilter,
+ currentSort,
+ currentPageSize,
+ })
+ );
+ }, [currentFilter, currentSort, currentPageSize]);
+
if (!data && !error) {
return ;
}
@@ -60,7 +81,7 @@ const RequestList: React.FC = () => {
return (
<>
-
+
{intl.formatMessage(messages.requests)}
@@ -140,114 +161,96 @@ const RequestList: React.FC = () => {
-
-
-
- {intl.formatMessage(messages.mediaInfo)}
- {intl.formatMessage(messages.status)}
- {intl.formatMessage(messages.requestedAt)}
- {intl.formatMessage(messages.modifiedBy)}
-
-
-
-
- {data.results.map((request) => {
- return (
- revalidate()}
- />
- );
- })}
+ {data.results.map((request) => {
+ return (
+
+ revalidate()}
+ />
+
+ );
+ })}
- {data.results.length === 0 && (
-
-
-
-
- {intl.formatMessage(messages.noresults)}
-
- {currentFilter !== 'all' && (
-
- setCurrentFilter('all')}
- >
- {intl.formatMessage(messages.showallrequests)}
-
-
- )}
-
-
-
- )}
-
-
-
+
+ {intl.formatMessage(messages.noresults)}
+
+ {currentFilter !== 'all' && (
+
+
setCurrentFilter('all')}
>
-
-
- {data.results.length > 0 &&
- intl.formatMessage(messages.showingresults, {
- from: pageIndex * currentPageSize + 1,
- to:
- data.results.length < currentPageSize
- ? pageIndex * currentPageSize + data.results.length
- : (pageIndex + 1) * currentPageSize,
- total: data.pageInfo.results,
- strong: function strong(msg) {
- return {msg} ;
- },
- })}
-
-
-
-
- {intl.formatMessage(messages.resultsperpage, {
- pageSize: (
- {
- setPageIndex(0);
- setCurrentPageSize(Number(e.target.value));
- }}
- value={currentPageSize}
- className="inline short"
- >
- 5
- 10
- 25
- 50
- 100
-
- ),
- })}
-
-
-
- setPageIndex((current) => current - 1)}
+ {intl.formatMessage(messages.showallrequests)}
+
+
+ )}
+
+ )}
+
+
+
+
+ {data.results.length > 0 &&
+ intl.formatMessage(messages.showingresults, {
+ from: pageIndex * currentPageSize + 1,
+ to:
+ data.results.length < currentPageSize
+ ? pageIndex * currentPageSize + data.results.length
+ : (pageIndex + 1) * currentPageSize,
+ total: data.pageInfo.results,
+ strong: function strong(msg) {
+ return {msg} ;
+ },
+ })}
+
+
+
+
+ {intl.formatMessage(messages.resultsperpage, {
+ pageSize: (
+ {
+ setPageIndex(0);
+ setCurrentPageSize(Number(e.target.value));
+ }}
+ value={currentPageSize}
+ className="inline short"
>
- {intl.formatMessage(messages.previous)}
-
- setPageIndex((current) => current + 1)}
- >
- {intl.formatMessage(messages.next)}
-
-
-
-
-
-
-
+
5
+
10
+
25
+
50
+
100
+
+ ),
+ })}
+
+
+
+ setPageIndex((current) => current - 1)}
+ >
+ {intl.formatMessage(messages.previous)}
+
+ setPageIndex((current) => current + 1)}
+ >
+ {intl.formatMessage(messages.next)}
+
+
+
+
>
);
};
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json
index c3821d337..eafcb6924 100644
--- a/src/i18n/locale/en.json
+++ b/src/i18n/locale/en.json
@@ -165,27 +165,27 @@
"components.RequestButton.viewrequest4k": "View 4K Request",
"components.RequestCard.all": "All",
"components.RequestCard.seasons": "Seasons",
+ "components.RequestList.RequestItem.areyousure": "Are you sure?",
"components.RequestList.RequestItem.failedretry": "Something went wrong while retrying the request.",
+ "components.RequestList.RequestItem.modifiedby": "Modified By",
"components.RequestList.RequestItem.notavailable": "N/A",
+ "components.RequestList.RequestItem.requested": "Requested",
"components.RequestList.RequestItem.seasons": "Seasons",
+ "components.RequestList.RequestItem.status": "Status",
"components.RequestList.filterAll": "All",
"components.RequestList.filterApproved": "Approved",
"components.RequestList.filterAvailable": "Available",
"components.RequestList.filterPending": "Pending",
"components.RequestList.filterProcessing": "Processing",
- "components.RequestList.mediaInfo": "Media Info",
- "components.RequestList.modifiedBy": "Last Modified By",
"components.RequestList.next": "Next",
"components.RequestList.noresults": "No results.",
"components.RequestList.previous": "Previous",
- "components.RequestList.requestedAt": "Requested At",
"components.RequestList.requests": "Requests",
"components.RequestList.resultsperpage": "Display {pageSize} results per page",
"components.RequestList.showallrequests": "Show All Requests",
"components.RequestList.showingresults": "Showing {from} to {to} of {total} results",
"components.RequestList.sortAdded": "Request Date",
"components.RequestList.sortModified": "Last Modified",
- "components.RequestList.status": "Status",
"components.RequestModal.AdvancedRequester.advancedoptions": "Advanced Options",
"components.RequestModal.AdvancedRequester.animenote": "* This series is an anime.",
"components.RequestModal.AdvancedRequester.default": "(Default)",
From 778dda67d54df87347dd79577ef1bdc88d3c1d3f Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Fri, 5 Mar 2021 10:52:43 -0500
Subject: [PATCH 028/421] fix(frontend): check for ID instead of email after
initial setup Plex login (#1097)
---
src/components/Setup/LoginWithPlex.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/Setup/LoginWithPlex.tsx b/src/components/Setup/LoginWithPlex.tsx
index 3dc0404e2..d62db786b 100644
--- a/src/components/Setup/LoginWithPlex.tsx
+++ b/src/components/Setup/LoginWithPlex.tsx
@@ -25,7 +25,7 @@ const LoginWithPlex: React.FC = ({ onComplete }) => {
const login = async () => {
const response = await axios.post('/api/v1/auth/plex', { authToken });
- if (response.data?.email) {
+ if (response.data?.id) {
revalidate();
}
};
From b5ce7f0cabd8c58a768c874b00a1b21c4ddf4a0f Mon Sep 17 00:00:00 2001
From: nuro <4991309+NuroDev@users.noreply.github.com>
Date: Fri, 5 Mar 2021 16:04:51 +0000
Subject: [PATCH 029/421] docs: added Docker compose installation example
(#1072) [skip ci]
* Added Docker compose installation example
* Update docs/getting-started/installation.md
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
* Updated compose example formatting
* Added complete docker-compose file example
* Update docs/getting-started/installation.md
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
* Added Docker compose installation example
* Update docs/getting-started/installation.md
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
* Updated compose example formatting
* Added complete docker-compose file example
* Update docs/getting-started/installation.md
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Co-authored-by: sct
---
docs/getting-started/installation.md | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md
index b0efe68d2..29327b7c1 100644
--- a/docs/getting-started/installation.md
+++ b/docs/getting-started/installation.md
@@ -25,6 +25,30 @@ docker run -d \
{% endtab %}
+{% tab title="Compose" %}
+
+**docker-compose.yml:**
+
+```yaml
+---
+version: "3"
+
+services:
+ overseerr:
+ image: sctx/overseerr:latest
+ container_name: overseerr
+ environment:
+ - LOG_LEVEL=info
+ - TZ=Asia/Tokyo
+ ports:
+ - 5055:5055
+ volumes:
+ - /path/to/appdata/config:/app/config
+ restart: unless-stopped
+```
+
+{% endtab %}
+
{% tab title="UID/GID" %}
```text
From 4f1a8a0a7823cc385263dddb37c1861eb692482d Mon Sep 17 00:00:00 2001
From: "allcontributors[bot]"
<46447321+allcontributors[bot]@users.noreply.github.com>
Date: Sat, 6 Mar 2021 01:05:34 +0900
Subject: [PATCH 030/421] docs: add NuroDev as a contributor (#1100) [skip ci]
* docs: update README.md [skip ci]
* docs: update .all-contributorsrc [skip ci]
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
---
.all-contributorsrc | 9 +++++++++
README.md | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/.all-contributorsrc b/.all-contributorsrc
index 3671ef223..523764a9c 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -312,6 +312,15 @@
"contributions": [
"code"
]
+ },
+ {
+ "login": "NuroDev",
+ "name": "nuro",
+ "avatar_url": "https://avatars.githubusercontent.com/u/4991309?v=4",
+ "profile": "https://nuro.dev",
+ "contributions": [
+ "doc"
+ ]
}
],
"badgeTemplate": " -orange.svg\"/> ",
diff --git a/README.md b/README.md
index 70bd55d5d..5d0fe2f4e 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
-
+
@@ -140,6 +140,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
David 💻
Douglas Parker 📖
Daniel Carter 💻
+ nuro 📖
From 92508b3f42aa445ccca82db7518e75f343a97ade Mon Sep 17 00:00:00 2001
From: "allcontributors[bot]"
<46447321+allcontributors[bot]@users.noreply.github.com>
Date: Sat, 6 Mar 2021 01:15:23 +0900
Subject: [PATCH 031/421] docs: add onedr0p as a contributor (#1101) [skip ci]
* docs: update README.md [skip ci]
* docs: update .all-contributorsrc [skip ci]
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
---
.all-contributorsrc | 9 +++++++++
README.md | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/.all-contributorsrc b/.all-contributorsrc
index 523764a9c..d693838ed 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -321,6 +321,15 @@
"contributions": [
"doc"
]
+ },
+ {
+ "login": "onedr0p",
+ "name": "ᗪєνιη ᗷυнʟ",
+ "avatar_url": "https://avatars.githubusercontent.com/u/213795?v=4",
+ "profile": "https://github.com/onedr0p",
+ "contributions": [
+ "infra"
+ ]
}
],
"badgeTemplate": " -orange.svg\"/> ",
diff --git a/README.md b/README.md
index 5d0fe2f4e..be86fdf23 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
-
+
@@ -141,6 +141,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Douglas Parker 📖
Daniel Carter 💻
nuro 📖
+ ᗪєνιη ᗷυнʟ 🚇
From e98f2b96058fb9c5af77be2e8a1bd07fb8fcca06 Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Fri, 5 Mar 2021 20:16:56 -0500
Subject: [PATCH 032/421] fix(ui): correct language usage re: "sync" vs. "scan"
(#1079)
---
overseerr-api.yml | 12 +++----
server/job/plexsync/index.ts | 10 +++---
server/job/radarrsync/index.ts | 6 ++--
server/job/schedule.ts | 34 ++++++++++---------
server/job/sonarrsync/index.ts | 6 ++--
src/components/MovieDetails/index.tsx | 3 +-
src/components/Settings/RadarrModal/index.tsx | 2 +-
.../Settings/SettingsJobsCache/index.tsx | 12 ++++---
src/components/Settings/SettingsPlex.tsx | 8 ++---
src/components/Settings/SonarrModal/index.tsx | 2 +-
src/components/Setup/index.tsx | 7 ++--
src/components/TvDetails/index.tsx | 3 +-
src/i18n/locale/en.json | 22 ++++++------
13 files changed, 67 insertions(+), 60 deletions(-)
diff --git a/overseerr-api.yml b/overseerr-api.yml
index 03667870c..fc96da70b 100644
--- a/overseerr-api.yml
+++ b/overseerr-api.yml
@@ -1716,13 +1716,13 @@ paths:
$ref: '#/components/schemas/PlexLibrary'
/settings/plex/sync:
get:
- summary: Get status of full Plex library sync
- description: Returns sync progress in a JSON array.
+ summary: Get status of full Plex library scan
+ description: Returns scan progress in a JSON array.
tags:
- settings
responses:
'200':
- description: Status of Plex sync
+ description: Status of Plex scan
content:
application/json:
schema:
@@ -1744,8 +1744,8 @@ paths:
items:
$ref: '#/components/schemas/PlexLibrary'
post:
- summary: Start full Plex library sync
- description: Runs a full Plex library sync and returns the progress in a JSON array.
+ summary: Start full Plex library scan
+ description: Runs a full Plex library scan and returns the progress in a JSON array.
tags:
- settings
requestBody:
@@ -1762,7 +1762,7 @@ paths:
example: false
responses:
'200':
- description: Status of Plex sync
+ description: Status of Plex scan
content:
application/json:
schema:
diff --git a/server/job/plexsync/index.ts b/server/job/plexsync/index.ts
index f4a57c621..60840e0ba 100644
--- a/server/job/plexsync/index.ts
+++ b/server/job/plexsync/index.ts
@@ -77,7 +77,7 @@ class JobPlexSync {
if (!metadata.Guid) {
logger.debug('No Guid metadata for this title. Skipping', {
- label: 'Plex Sync',
+ label: 'Plex Scan',
ratingKey: plexitem.ratingKey,
});
return;
@@ -794,7 +794,7 @@ class JobPlexSync {
level: 'info' | 'error' | 'debug' | 'warn' = 'debug',
optional?: Record
): void {
- logger[level](message, { label: 'Plex Sync', ...optional });
+ logger[level](message, { label: 'Plex Scan', ...optional });
}
// checks if any of this.libraries has Hama agent set in Plex
@@ -812,7 +812,7 @@ class JobPlexSync {
const settings = getSettings();
const sessionId = uuid();
this.sessionId = sessionId;
- logger.info('Plex Sync Starting', { sessionId, label: 'Plex Sync' });
+ logger.info('Plex scan starting', { sessionId, label: 'Plex Scan' });
try {
this.running = true;
const userRepository = getRepository(User);
@@ -822,7 +822,7 @@ class JobPlexSync {
});
if (!admin) {
- return this.log('No admin configured. Plex sync skipped.', 'warn');
+ return this.log('No admin configured. Plex scan skipped.', 'warn');
}
this.plexClient = new PlexAPI({ plexToken: admin.plexToken });
@@ -896,7 +896,7 @@ class JobPlexSync {
);
} catch (e) {
logger.error('Sync interrupted', {
- label: 'Plex Sync',
+ label: 'Plex Scan',
errorMessage: e.message,
});
} finally {
diff --git a/server/job/radarrsync/index.ts b/server/job/radarrsync/index.ts
index 57f88ee05..e8b0c8909 100644
--- a/server/job/radarrsync/index.ts
+++ b/server/job/radarrsync/index.ts
@@ -32,7 +32,7 @@ class JobRadarrSync {
const settings = getSettings();
const sessionId = uuid();
this.sessionId = sessionId;
- this.log('Radarr sync starting', 'info', { sessionId });
+ this.log('Radarr scan starting', 'info', { sessionId });
try {
this.running = true;
@@ -75,7 +75,7 @@ class JobRadarrSync {
}
}
- this.log('Radarr sync complete', 'info');
+ this.log('Radarr scan complete', 'info');
} catch (e) {
this.log('Something went wrong.', 'error', { errorMessage: e.message });
} finally {
@@ -241,7 +241,7 @@ class JobRadarrSync {
level: 'info' | 'error' | 'debug' | 'warn' = 'debug',
optional?: Record
): void {
- logger[level](message, { label: 'Radarr Sync', ...optional });
+ logger[level](message, { label: 'Radarr Scan', ...optional });
}
}
diff --git a/server/job/schedule.ts b/server/job/schedule.ts
index 342f54a16..7bbf580d2 100644
--- a/server/job/schedule.ts
+++ b/server/job/schedule.ts
@@ -17,13 +17,13 @@ interface ScheduledJob {
export const scheduledJobs: ScheduledJob[] = [];
export const startJobs = (): void => {
- // Run recently added plex sync every 5 minutes
+ // Run recently added plex scan every 5 minutes
scheduledJobs.push({
- id: 'plex-recently-added-sync',
- name: 'Plex Recently Added Sync',
+ id: 'plex-recently-added-scan',
+ name: 'Plex Recently Added Scan',
type: 'process',
job: schedule.scheduleJob('0 */5 * * * *', () => {
- logger.info('Starting scheduled job: Plex Recently Added Sync', {
+ logger.info('Starting scheduled job: Plex Recently Added Scan', {
label: 'Jobs',
});
jobPlexRecentSync.run();
@@ -32,39 +32,41 @@ export const startJobs = (): void => {
cancelFn: () => jobPlexRecentSync.cancel(),
});
- // Run full plex sync every 24 hours
+ // Run full plex scan every 24 hours
scheduledJobs.push({
- id: 'plex-full-sync',
- name: 'Plex Full Library Sync',
+ id: 'plex-full-scan',
+ name: 'Plex Full Library Scan',
type: 'process',
job: schedule.scheduleJob('0 0 3 * * *', () => {
- logger.info('Starting scheduled job: Plex Full Sync', { label: 'Jobs' });
+ logger.info('Starting scheduled job: Plex Full Library Scan', {
+ label: 'Jobs',
+ });
jobPlexFullSync.run();
}),
running: () => jobPlexFullSync.status().running,
cancelFn: () => jobPlexFullSync.cancel(),
});
- // Run full radarr sync every 24 hours
+ // Run full radarr scan every 24 hours
scheduledJobs.push({
- id: 'radarr-sync',
- name: 'Radarr Sync',
+ id: 'radarr-scan',
+ name: 'Radarr Scan',
type: 'process',
job: schedule.scheduleJob('0 0 4 * * *', () => {
- logger.info('Starting scheduled job: Radarr Sync', { label: 'Jobs' });
+ logger.info('Starting scheduled job: Radarr Scan', { label: 'Jobs' });
jobRadarrSync.run();
}),
running: () => jobRadarrSync.status().running,
cancelFn: () => jobRadarrSync.cancel(),
});
- // Run full sonarr sync every 24 hours
+ // Run full sonarr scan every 24 hours
scheduledJobs.push({
- id: 'sonarr-sync',
- name: 'Sonarr Sync',
+ id: 'sonarr-scan',
+ name: 'Sonarr Scan',
type: 'process',
job: schedule.scheduleJob('0 30 4 * * *', () => {
- logger.info('Starting scheduled job: Sonarr Sync', { label: 'Jobs' });
+ logger.info('Starting scheduled job: Sonarr Scan', { label: 'Jobs' });
jobSonarrSync.run();
}),
running: () => jobSonarrSync.status().running,
diff --git a/server/job/sonarrsync/index.ts b/server/job/sonarrsync/index.ts
index 3685af484..affcdbb41 100644
--- a/server/job/sonarrsync/index.ts
+++ b/server/job/sonarrsync/index.ts
@@ -35,7 +35,7 @@ class JobSonarrSync {
const settings = getSettings();
const sessionId = uuid();
this.sessionId = sessionId;
- this.log('Sonarr sync starting', 'info', { sessionId });
+ this.log('Sonarr scan starting', 'info', { sessionId });
try {
this.running = true;
@@ -78,7 +78,7 @@ class JobSonarrSync {
}
}
- this.log('Sonarr sync complete', 'info');
+ this.log('Sonarr scan complete', 'info');
} catch (e) {
this.log('Something went wrong.', 'error', { errorMessage: e.message });
} finally {
@@ -374,7 +374,7 @@ class JobSonarrSync {
level: 'info' | 'error' | 'debug' | 'warn' = 'debug',
optional?: Record
): void {
- logger[level](message, { label: 'Sonarr Sync', ...optional });
+ logger[level](message, { label: 'Sonarr Scan', ...optional });
}
}
diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx
index afedec957..c0049f8d8 100644
--- a/src/components/MovieDetails/index.tsx
+++ b/src/components/MovieDetails/index.tsx
@@ -60,7 +60,8 @@ const messages = defineMessages({
manageModalNoRequests: 'No Requests',
manageModalClearMedia: 'Clear All Media Data',
manageModalClearMediaWarning:
- 'This will irreversibly remove all data for this movie, including any requests. If this item exists in your Plex library, the media information will be recreated during the next sync.',
+ 'This will irreversibly remove all data for this movie, including any requests.\
+ If this item exists in your Plex library, the media information will be recreated during the next scan.',
approve: 'Approve',
decline: 'Decline',
studio: 'Studio',
diff --git a/src/components/Settings/RadarrModal/index.tsx b/src/components/Settings/RadarrModal/index.tsx
index 967bb7ee9..7932447af 100644
--- a/src/components/Settings/RadarrModal/index.tsx
+++ b/src/components/Settings/RadarrModal/index.tsx
@@ -35,7 +35,7 @@ const messages = defineMessages({
apiKeyPlaceholder: 'Your Radarr API key',
baseUrl: 'Base URL',
baseUrlPlaceholder: 'Example: /radarr',
- syncEnabled: 'Enable Sync',
+ syncEnabled: 'Enable Scan',
externalUrl: 'External URL',
externalUrlPlaceholder: 'External URL pointing to your Radarr server',
qualityprofile: 'Quality Profile',
diff --git a/src/components/Settings/SettingsJobsCache/index.tsx b/src/components/Settings/SettingsJobsCache/index.tsx
index 0e70b6b49..b327a1877 100644
--- a/src/components/Settings/SettingsJobsCache/index.tsx
+++ b/src/components/Settings/SettingsJobsCache/index.tsx
@@ -19,7 +19,9 @@ import { formatBytes } from '../../../utils/numberHelpers';
const messages: { [messageName: string]: MessageDescriptor } = defineMessages({
jobs: 'Jobs',
jobsDescription:
- 'Overseerr performs certain maintenance tasks as regularly-scheduled jobs, but they can also be manually triggered below. Manually running a job will not alter its schedule.',
+ 'Overseerr performs certain maintenance tasks as regularly-scheduled jobs,\
+ but they can also be manually triggered below.\
+ Manually running a job will not alter its schedule.',
jobname: 'Job Name',
jobtype: 'Type',
nextexecution: 'Next Execution',
@@ -41,10 +43,10 @@ const messages: { [messageName: string]: MessageDescriptor } = defineMessages({
cachevsize: 'Value Size',
flushcache: 'Flush Cache',
unknownJob: 'Unknown Job',
- 'plex-recently-added-sync': 'Plex Recently Added Sync',
- 'plex-full-sync': 'Plex Full Library Sync',
- 'radarr-sync': 'Radarr Sync',
- 'sonarr-sync': 'Sonarr Sync',
+ 'plex-recently-added-scan': 'Plex Recently Added Scan',
+ 'plex-full-scan': 'Plex Full Library Scan',
+ 'radarr-scan': 'Radarr Scan',
+ 'sonarr-scan': 'Sonarr Scan',
'download-sync': 'Download Sync',
'download-sync-reset': 'Download Sync Reset',
});
diff --git a/src/components/Settings/SettingsPlex.tsx b/src/components/Settings/SettingsPlex.tsx
index 4fa588733..fb95aae84 100644
--- a/src/components/Settings/SettingsPlex.tsx
+++ b/src/components/Settings/SettingsPlex.tsx
@@ -49,8 +49,8 @@ const messages = defineMessages({
plexlibraries: 'Plex Libraries',
plexlibrariesDescription:
'The libraries Overseerr scans for titles. Set up and save your Plex connection settings, then click the button below if no libraries are listed.',
- syncing: 'Syncing',
- sync: 'Sync Plex Libraries',
+ scanning: 'Scanning…',
+ scan: 'Scan Plex Libraries',
manualscan: 'Manual Library Scan',
manualscanDescription:
"Normally, this will only be run once every 24 hours. Overseerr will check your Plex server's recently added more aggressively. If this is your first time configuring Plex, a one-time full manual library scan is recommended!",
@@ -563,8 +563,8 @@ const SettingsPlex: React.FC = ({ onComplete }) => {
/>
{isSyncing
- ? intl.formatMessage(messages.syncing)
- : intl.formatMessage(messages.sync)}
+ ? intl.formatMessage(messages.scanning)
+ : intl.formatMessage(messages.scan)}
{data?.libraries.map((library) => (
diff --git a/src/components/Settings/SonarrModal/index.tsx b/src/components/Settings/SonarrModal/index.tsx
index 65d7a157b..a41fead9d 100644
--- a/src/components/Settings/SonarrModal/index.tsx
+++ b/src/components/Settings/SonarrModal/index.tsx
@@ -52,7 +52,7 @@ const messages = defineMessages({
testFirstRootFolders: 'Test connection to load root folders',
loadinglanguageprofiles: 'Loading language profiles…',
testFirstLanguageProfiles: 'Test connection to load language profiles',
- syncEnabled: 'Enable Sync',
+ syncEnabled: 'Enable Scan',
externalUrl: 'External URL',
externalUrlPlaceholder: 'External URL pointing to your Sonarr server',
preventSearch: 'Disable Auto-Search',
diff --git a/src/components/Setup/index.tsx b/src/components/Setup/index.tsx
index e0a21e5f6..b174887f3 100644
--- a/src/components/Setup/index.tsx
+++ b/src/components/Setup/index.tsx
@@ -22,8 +22,9 @@ const messages = defineMessages({
configureplex: 'Configure Plex',
configureservices: 'Configure Services',
tip: 'Tip',
- syncingbackground:
- 'Syncing will run in the background. You can continue the setup process in the meantime.',
+ scanbackground:
+ 'Scanning will run in the background.\
+ You can continue the setup process in the meantime.',
});
const Setup: React.FC = () => {
@@ -104,7 +105,7 @@ const Setup: React.FC = () => {
{intl.formatMessage(messages.tip)}
- {intl.formatMessage(messages.syncingbackground)}
+ {intl.formatMessage(messages.scanbackground)}
diff --git a/src/components/TvDetails/index.tsx b/src/components/TvDetails/index.tsx
index fcc12bbf3..e93fa94ce 100644
--- a/src/components/TvDetails/index.tsx
+++ b/src/components/TvDetails/index.tsx
@@ -56,7 +56,8 @@ const messages = defineMessages({
manageModalNoRequests: 'No Requests',
manageModalClearMedia: 'Clear All Media Data',
manageModalClearMediaWarning:
- 'This will irreversibly remove all data for this TV series, including any requests. If this item exists in your Plex library, the media information will be recreated during the next sync.',
+ 'This will irreversibly remove all data for this TV series, including any requests.\
+ If this item exists in your Plex library, the media information will be recreated during the next scan.',
approve: 'Approve',
decline: 'Decline',
showtype: 'Show Type',
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json
index eafcb6924..16c261a68 100644
--- a/src/i18n/locale/en.json
+++ b/src/i18n/locale/en.json
@@ -63,7 +63,7 @@
"components.MovieDetails.decline": "Decline",
"components.MovieDetails.downloadstatus": "Download Status",
"components.MovieDetails.manageModalClearMedia": "Clear All Media Data",
- "components.MovieDetails.manageModalClearMediaWarning": "* This will irreversibly remove all data for this movie, including any requests. If this item exists in your Plex library, the media information will be recreated during the next sync.",
+ "components.MovieDetails.manageModalClearMediaWarning": "* This will irreversibly remove all data for this movie, including any requests. If this item exists in your Plex library, the media information will be recreated during the next scan.",
"components.MovieDetails.manageModalNoRequests": "No Requests",
"components.MovieDetails.manageModalRequests": "Requests",
"components.MovieDetails.manageModalTitle": "Manage Movie",
@@ -366,7 +366,7 @@
"components.Settings.RadarrModal.servername": "Server Name",
"components.Settings.RadarrModal.servernamePlaceholder": "A Radarr Server",
"components.Settings.RadarrModal.ssl": "SSL",
- "components.Settings.RadarrModal.syncEnabled": "Enable Sync",
+ "components.Settings.RadarrModal.syncEnabled": "Enable Scan",
"components.Settings.RadarrModal.test": "Test",
"components.Settings.RadarrModal.testFirstQualityProfiles": "Test connection to load quality profiles",
"components.Settings.RadarrModal.testFirstRootFolders": "Test connection to load root folders",
@@ -426,12 +426,12 @@
"components.Settings.SettingsJobsCache.jobstarted": "{jobname} started.",
"components.Settings.SettingsJobsCache.jobtype": "Type",
"components.Settings.SettingsJobsCache.nextexecution": "Next Execution",
- "components.Settings.SettingsJobsCache.plex-full-sync": "Plex Full Library Sync",
- "components.Settings.SettingsJobsCache.plex-recently-added-sync": "Plex Recently Added Sync",
+ "components.Settings.SettingsJobsCache.plex-full-scan": "Plex Full Library Scan",
+ "components.Settings.SettingsJobsCache.plex-recently-added-scan": "Plex Recently Added Scan",
"components.Settings.SettingsJobsCache.process": "Process",
- "components.Settings.SettingsJobsCache.radarr-sync": "Radarr Sync",
+ "components.Settings.SettingsJobsCache.radarr-scan": "Radarr Scan",
"components.Settings.SettingsJobsCache.runnow": "Run Now",
- "components.Settings.SettingsJobsCache.sonarr-sync": "Sonarr Sync",
+ "components.Settings.SettingsJobsCache.sonarr-scan": "Sonarr Scan",
"components.Settings.SettingsJobsCache.unknownJob": "Unknown Job",
"components.Settings.SonarrModal.add": "Add Server",
"components.Settings.SonarrModal.animelanguageprofile": "Anime Language Profile",
@@ -465,7 +465,7 @@
"components.Settings.SonarrModal.servername": "Server Name",
"components.Settings.SonarrModal.servernamePlaceholder": "A Sonarr Server",
"components.Settings.SonarrModal.ssl": "SSL",
- "components.Settings.SonarrModal.syncEnabled": "Enable Sync",
+ "components.Settings.SonarrModal.syncEnabled": "Enable Scan",
"components.Settings.SonarrModal.test": "Test",
"components.Settings.SonarrModal.testFirstLanguageProfiles": "Test connection to load language profiles",
"components.Settings.SonarrModal.testFirstQualityProfiles": "Test connection to load quality profiles",
@@ -544,6 +544,8 @@
"components.Settings.regionTip": "Filter content by region (only applies to the \"Popular\" and \"Upcoming\" categories)",
"components.Settings.save": "Save Changes",
"components.Settings.saving": "Saving…",
+ "components.Settings.scan": "Scan Plex Libraries",
+ "components.Settings.scanning": "Scanning…",
"components.Settings.serverConnected": "connected",
"components.Settings.serverLocal": "local",
"components.Settings.serverRemote": "remote",
@@ -562,8 +564,6 @@
"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.timeout": "Timeout",
"components.Settings.toastApiKeyFailure": "Something went wrong while generating a new API key.",
"components.Settings.toastApiKeySuccess": "New API key generated!",
@@ -589,9 +589,9 @@
"components.Setup.finish": "Finish Setup",
"components.Setup.finishing": "Finishing…",
"components.Setup.loginwithplex": "Sign in with Plex",
+ "components.Setup.scanbackground": "Scanning will run in the background. You can continue the setup process in the meantime.",
"components.Setup.setup": "Setup",
"components.Setup.signinMessage": "Get started by signing in with your Plex account",
- "components.Setup.syncingbackground": "Syncing will run in the background. You can continue the setup process in the meantime.",
"components.Setup.tip": "Tip",
"components.Setup.welcome": "Welcome to Overseerr",
"components.Slider.noresults": "No results.",
@@ -614,7 +614,7 @@
"components.TvDetails.downloadstatus": "Download Status",
"components.TvDetails.firstAirDate": "First Air Date",
"components.TvDetails.manageModalClearMedia": "Clear All Media Data",
- "components.TvDetails.manageModalClearMediaWarning": "* This will irreversibly remove all data for this TV series, including any requests. If this item exists in your Plex library, the media information will be recreated during the next sync.",
+ "components.TvDetails.manageModalClearMediaWarning": "* This will irreversibly remove all data for this TV series, including any requests. If this item exists in your Plex library, the media information will be recreated during the next scan.",
"components.TvDetails.manageModalNoRequests": "No Requests",
"components.TvDetails.manageModalRequests": "Requests",
"components.TvDetails.manageModalTitle": "Manage Series",
From 1f8b03ff6f67ce76051667de05166da54ed3dc89 Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Fri, 5 Mar 2021 20:54:31 -0500
Subject: [PATCH 033/421] fix(ui): improve responsive design on new request
list UI (#1105)
---
src/components/RequestCard/index.tsx | 101 ++++----
.../RequestList/RequestItem/index.tsx | 241 ++++++++++--------
src/components/RequestList/index.tsx | 11 +-
src/i18n/locale/en.json | 5 +-
src/styles/globals.css | 16 +-
5 files changed, 213 insertions(+), 161 deletions(-)
diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx
index b65df670c..12692e74a 100644
--- a/src/components/RequestCard/index.tsx
+++ b/src/components/RequestCard/index.tsx
@@ -5,7 +5,10 @@ import type { TvDetails } from '../../../server/models/Tv';
import type { MovieDetails } from '../../../server/models/Movie';
import useSWR from 'swr';
import { LanguageContext } from '../../context/LanguageContext';
-import { MediaRequestStatus } from '../../../server/constants/media';
+import {
+ MediaRequestStatus,
+ MediaStatus,
+} from '../../../server/constants/media';
import Badge from '../Common/Badge';
import { useUser, Permission } from '../../hooks/useUser';
import axios from 'axios';
@@ -17,6 +20,7 @@ import globalMessages from '../../i18n/globalMessages';
import StatusBadge from '../StatusBadge';
const messages = defineMessages({
+ status: 'Status',
seasons: 'Seasons',
all: 'All',
});
@@ -100,39 +104,48 @@ const RequestCard: React.FC
= ({ request, onTitleData }) => {
}}
>
-
-
-
-
-
- {requestData.requestedBy.displayName}
-
- {requestData.media.status && (
-
+
+
+
+ {intl.formatMessage(messages.status)}
+
+ {requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
+ MediaStatus.UNKNOWN ||
+ requestData.status === MediaRequestStatus.DECLINED ? (
+
+ {requestData.status === MediaRequestStatus.DECLINED
+ ? intl.formatMessage(globalMessages.declined)
+ : intl.formatMessage(globalMessages.failed)}
+
+ ) : (
= ({ request, onTitleData }) => {
] ?? []
).length > 0
}
+ is4k={requestData.is4k}
/>
-
- )}
+ )}
+
{request.seasons.length > 0 && (
-
-
{intl.formatMessage(messages.seasons)}
+
+
+ {intl.formatMessage(messages.seasons)}
+
{!isMovie(title) &&
title.seasons.filter((season) => season.seasonNumber !== 0)
.length === request.seasons.length ? (
@@ -215,15 +231,14 @@ const RequestCard: React.FC = ({ request, onTitleData }) => {
)}
-
+
+
);
};
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx
index 16a98dd3b..190b8be2a 100644
--- a/src/components/RequestList/RequestItem/index.tsx
+++ b/src/components/RequestList/RequestItem/index.tsx
@@ -23,12 +23,14 @@ import ConfirmButton from '../../Common/ConfirmButton';
const messages = defineMessages({
seasons: 'Seasons',
+ all: 'All',
notavailable: 'N/A',
failedretry: 'Something went wrong while retrying the request.',
areyousure: 'Are you sure?',
status: 'Status',
requested: 'Requested',
- modifiedby: 'Modified By',
+ modified: 'Modified',
+ modifieduserdate: '{date} by {user}',
});
const isMovie = (movie: MovieDetails | TvDetails): movie is MovieDetails => {
@@ -130,114 +132,122 @@ const RequestItem: React.FC = ({
setShowEditModal(false);
}}
/>
-
+
-
-
-
-
+
+
-
- {isMovie(title) ? title.title : title.name}
-
-
-
-
-
-
- {requestData.requestedBy.displayName}
-
-
-
- {requestData.seasons.length > 0 && (
-
-
- {intl.formatMessage(messages.seasons)}
-
- {requestData.seasons.map((season) => (
-
- {season.seasonNumber}
-
- ))}
+ alt=""
+ className="h-full transition duration-300 scale-100 rounded-md shadow-sm cursor-pointer w-14 lg:w-auto lg:h-full transform-gpu hover:scale-105 hover:shadow-md"
+ />
+
+
+
+ {isMovie(title) ? title.title : title.name}
+
+
+
- )}
+ {request.seasons.length > 0 && (
+
+
+ {intl.formatMessage(messages.seasons)}
+
+ {!isMovie(title) &&
+ title.seasons.filter((season) => season.seasonNumber !== 0)
+ .length === request.seasons.length ? (
+
+ {intl.formatMessage(messages.all)}
+
+ ) : (
+
+ {request.seasons.map((season) => (
+
+ {season.seasonNumber}
+
+ ))}
+
+ )}
+
+ )}
+
-
-
-
- {intl.formatMessage(messages.status)}
- {requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
- MediaStatus.UNKNOWN ||
- requestData.status === MediaRequestStatus.DECLINED ? (
-
- {requestData.status === MediaRequestStatus.DECLINED
- ? intl.formatMessage(globalMessages.declined)
- : intl.formatMessage(globalMessages.failed)}
-
- ) : (
- 0
- }
- is4k={requestData.is4k}
- plexUrl={requestData.media.plexUrl}
- plexUrl4k={requestData.media.plexUrl4k}
- />
- )}
-
-
-
- {intl.formatMessage(messages.requested)}
-
-
- {intl.formatDate(requestData.createdAt)}
-
-
-
diff --git a/src/components/RequestList/index.tsx b/src/components/RequestList/index.tsx
index 27db650ca..126b08825 100644
--- a/src/components/RequestList/index.tsx
+++ b/src/components/RequestList/index.tsx
@@ -173,14 +173,13 @@ const RequestList: React.FC = () => {
})}
{data.results.length === 0 && (
-
-
+
+
{intl.formatMessage(messages.noresults)}
{currentFilter !== 'all' && (
setCurrentFilter('all')}
>
@@ -190,9 +189,9 @@ const RequestList: React.FC = () => {
)}
)}
-
+
@@ -212,7 +211,7 @@ const RequestList: React.FC = () => {
-
+
{intl.formatMessage(messages.resultsperpage, {
pageSize: (
li {
@apply max-w-2xl mt-1 text-sm leading-5 text-gray-500;
}
+img.avatar-sm {
+ @apply w-5 mr-1 pr-0.5 rounded-full;
+}
+
+.card-field {
+ @apply flex items-center my-0.5 sm:my-1 text-sm;
+}
+
+.card-field-name {
+ @apply mr-2 font-medium;
+}
+
.section {
@apply mt-6 mb-10 text-white;
}
@@ -75,7 +87,7 @@ ul.cardList > li {
}
.actions {
- @apply pt-5 mt-8 border-t border-gray-700;
+ @apply pt-5 mt-8 text-white border-t border-gray-700;
}
input[type='checkbox'] {
@@ -104,7 +116,7 @@ select.rounded-r-only {
input.short,
select.short {
- @apply w-20;
+ width: 4.875rem;
}
.protocol {
From 7289872937d5bb94d027424760ee1ceb94095604 Mon Sep 17 00:00:00 2001
From: sct
Date: Sat, 6 Mar 2021 07:49:41 +0000
Subject: [PATCH 034/421] fix(ui): add link to poster image on request items
---
.../RequestList/RequestItem/index.tsx | 30 ++++++++++++-------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx
index 190b8be2a..0a1b75038 100644
--- a/src/components/RequestList/RequestItem/index.tsx
+++ b/src/components/RequestList/RequestItem/index.tsx
@@ -139,17 +139,27 @@ const RequestItem: React.FC = ({
backgroundImage: `linear-gradient(90deg, rgba(31, 41, 55, 0.47) 0%, rgba(31, 41, 55, 1) 100%), url(//image.tmdb.org/t/p/w1920_and_h800_multi_faces/${title.backdropPath})`,
}}
/>
-
-
-
+
+
+ >
+
+
+
+
Date: Sat, 6 Mar 2021 08:15:39 +0000
Subject: [PATCH 035/421] refactor(ui): request list now adds a page query
parameter for switching pages
this helps return back to the page you were last looking at when navigated to and from the request
list.
---
.../RequestList/RequestItem/index.tsx | 4 ++-
src/components/RequestList/index.tsx | 34 +++++++++++++------
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx
index 0a1b75038..be99ec19d 100644
--- a/src/components/RequestList/RequestItem/index.tsx
+++ b/src/components/RequestList/RequestItem/index.tsx
@@ -136,7 +136,9 @@ const RequestItem: React.FC
= ({
diff --git a/src/components/RequestList/index.tsx b/src/components/RequestList/index.tsx
index 126b08825..7d1aceff4 100644
--- a/src/components/RequestList/index.tsx
+++ b/src/components/RequestList/index.tsx
@@ -7,6 +7,7 @@ import Header from '../Common/Header';
import Button from '../Common/Button';
import { defineMessages, useIntl } from 'react-intl';
import PageTitle from '../Common/PageTitle';
+import { useRouter } from 'next/router';
const messages = defineMessages({
requests: 'Requests',
@@ -30,12 +31,15 @@ type Filter = 'all' | 'pending' | 'approved' | 'processing' | 'available';
type Sort = 'added' | 'modified';
const RequestList: React.FC = () => {
+ const router = useRouter();
const intl = useIntl();
- const [pageIndex, setPageIndex] = useState(0);
const [currentFilter, setCurrentFilter] = useState
('pending');
const [currentSort, setCurrentSort] = useState('added');
const [currentPageSize, setCurrentPageSize] = useState(10);
+ const page = router.query.page ? Number(router.query.page) : 1;
+ const pageIndex = page - 1;
+
const { data, error, revalidate } = useSWR(
`/api/v1/request?take=${currentPageSize}&skip=${
pageIndex * currentPageSize
@@ -103,8 +107,8 @@ const RequestList: React.FC = () => {
id="filter"
name="filter"
onChange={(e) => {
- setPageIndex(0);
setCurrentFilter(e.target.value as Filter);
+ router.push(router.pathname);
}}
value={currentFilter}
className="rounded-r-only"
@@ -141,12 +145,8 @@ const RequestList: React.FC = () => {
id="sort"
name="sort"
onChange={(e) => {
- setPageIndex(0);
- setCurrentSort(e.target.value as Sort);
- }}
- onBlur={(e) => {
- setPageIndex(0);
setCurrentSort(e.target.value as Sort);
+ router.push(router.pathname);
}}
value={currentSort}
className="rounded-r-only"
@@ -218,8 +218,10 @@ const RequestList: React.FC = () => {
id="pageSize"
name="pageSize"
onChange={(e) => {
- setPageIndex(0);
setCurrentPageSize(Number(e.target.value));
+ router
+ .push(router.pathname)
+ .then(() => window.scrollTo(0, 0));
}}
value={currentPageSize}
className="inline short"
@@ -237,13 +239,25 @@ const RequestList: React.FC = () => {
setPageIndex((current) => current - 1)}
+ onClick={() =>
+ router
+ .push(`${router.pathname}?page=${page - 1}`, undefined, {
+ shallow: true,
+ })
+ .then(() => window.scrollTo(0, 0))
+ }
>
{intl.formatMessage(messages.previous)}
setPageIndex((current) => current + 1)}
+ onClick={() =>
+ router
+ .push(`${router.pathname}?page=${page + 1}`, undefined, {
+ shallow: true,
+ })
+ .then(() => window.scrollTo(0, 0))
+ }
>
{intl.formatMessage(messages.next)}
From 9966632c64ed08a085691498bf3625d5563d17fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E1=97=AA=D1=94=CE=BD=CE=B9=CE=B7=20=E1=97=B7=CF=85=D0=BD?=
=?UTF-8?q?=CA=9F?=
Date: Sat, 6 Mar 2021 04:50:28 -0500
Subject: [PATCH 036/421] ci: build arm64 and amd64 container images for ci
images (#1036)
---
.github/workflows/ci.yml | 1 +
Dockerfile | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ffc747549..10d27b979 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -59,6 +59,7 @@ jobs:
with:
context: .
file: ./Dockerfile
+ platforms: linux/amd64,linux/arm64
push: true
build-args: |
COMMIT_TAG=${{ github.sha }}
diff --git a/Dockerfile b/Dockerfile
index 52c236473..447734ac7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,11 +1,20 @@
FROM node:14.16-alpine AS BUILD_IMAGE
+ARG TARGETPLATFORM
+ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
+
ARG COMMIT_TAG
ENV COMMIT_TAG=${COMMIT_TAG}
COPY . /app
WORKDIR /app
+RUN \
+ case "${TARGETPLATFORM}" in \
+ 'linux/arm64') apk add --no-cache python make g++ ;; \
+ 'linux/arm/v7') apk add --no-cache python make g++ ;; \
+ esac
+
RUN yarn --frozen-lockfile && \
yarn build
From f86d907c7421c78aa055ccaf96b12d7d26040264 Mon Sep 17 00:00:00 2001
From: sct
Date: Sat, 6 Mar 2021 11:12:18 +0000
Subject: [PATCH 037/421] ci: also add arm/v7 build for develop tag
---
.github/workflows/ci.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 10d27b979..0b255ff7c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -59,7 +59,7 @@ jobs:
with:
context: .
file: ./Dockerfile
- platforms: linux/amd64,linux/arm64
+ platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
build-args: |
COMMIT_TAG=${{ github.sha }}
From 9d0b52a2420ca7351c943ba142f8cccf6fcd9ad4 Mon Sep 17 00:00:00 2001
From: sct
Date: Sat, 6 Mar 2021 15:17:04 +0000
Subject: [PATCH 038/421] ci: add network-timeout to yarn install
---
Dockerfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dockerfile b/Dockerfile
index 447734ac7..9a5af8ca7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,7 @@ RUN \
'linux/arm/v7') apk add --no-cache python make g++ ;; \
esac
-RUN yarn --frozen-lockfile && \
+RUN yarn --frozen-lockfile --network-timeout 1000000 && \
yarn build
# remove development dependencies
From 85076919c6ccbf052699b7d5f4ba8b6e5e5af74d Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Sat, 6 Mar 2021 20:40:47 -0500
Subject: [PATCH 039/421] fix(ui): fix request list UI behavior when season
list is too long (#1106)
* fix(ui): fix request list UI behavior when season list is too long
* fix: add default variants to Tailwind scale
---
src/components/RequestCard/index.tsx | 2 +-
.../RequestList/RequestItem/index.tsx | 38 ++++++++++---------
src/styles/globals.css | 4 +-
tailwind.config.js | 1 +
4 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx
index 12692e74a..5f537cdd5 100644
--- a/src/components/RequestCard/index.tsx
+++ b/src/components/RequestCard/index.tsx
@@ -111,7 +111,7 @@ const RequestCard: React.FC = ({ request, onTitleData }) => {
: `/tv/${requestData.media.tmdbId}`
}
>
-
+
{isMovie(title) ? title.title : title.name}
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx
index be99ec19d..fb2b888d6 100644
--- a/src/components/RequestList/RequestItem/index.tsx
+++ b/src/components/RequestList/RequestItem/index.tsx
@@ -132,7 +132,7 @@ const RequestItem: React.FC = ({
setShowEditModal(false);
}}
/>
-
+
= ({
: undefined,
}}
/>
-
-
+
+
= ({
/>
-
-
-
- {isMovie(title) ? title.title : title.name}
-
-
+
-
+
{intl.formatMessage(messages.status)}
@@ -275,7 +277,7 @@ const RequestItem: React.FC = ({
{requestData.modifiedBy.displayName}
@@ -292,7 +294,7 @@ const RequestItem: React.FC = ({
-
+
{requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
MediaStatus.UNKNOWN &&
requestData.status !== MediaRequestStatus.DECLINED &&
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 691cd081f..d845958db 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -55,11 +55,11 @@ ul.cardList > li {
}
img.avatar-sm {
- @apply w-5 mr-1 pr-0.5 rounded-full;
+ @apply w-5 h-5 mr-1.5 rounded-full transition duration-300 scale-100 transform-gpu group-hover:scale-105;
}
.card-field {
- @apply flex items-center my-0.5 sm:my-1 text-sm;
+ @apply flex items-center py-0.5 sm:py-1 text-sm;
}
.card-field-name {
diff --git a/tailwind.config.js b/tailwind.config.js
index 8f821bb5a..39c11938b 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -63,6 +63,7 @@ module.exports = {
margin: ['first', 'last', 'responsive'],
boxShadow: ['group-focus'],
opacity: ['disabled', 'hover', 'group-hover'],
+ scale: ['hover', 'focus', 'group-hover'],
zIndex: ['hover', 'responsive'],
},
plugins: [
From 239202d9c11f27410b0fa084bcc4c824b7136081 Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Sun, 7 Mar 2021 18:06:50 -0500
Subject: [PATCH 040/421] fix(ui): list all movie studios instead of just the
first result (#1110)
---
src/components/MovieDetails/index.tsx | 25 +++++++++++++++----------
src/components/TvDetails/index.tsx | 6 ++++--
src/i18n/locale/en.json | 4 ++--
3 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx
index c0049f8d8..9d8988150 100644
--- a/src/components/MovieDetails/index.tsx
+++ b/src/components/MovieDetails/index.tsx
@@ -64,7 +64,7 @@ const messages = defineMessages({
If this item exists in your Plex library, the media information will be recreated during the next scan.',
approve: 'Approve',
decline: 'Decline',
- studio: 'Studio',
+ studio: '{studioCount, plural, one {Studio} other {Studios}}',
viewfullcrew: 'View Full Crew',
view: 'View',
areyousure: 'Are you sure?',
@@ -667,19 +667,24 @@ const MovieDetails: React.FC = ({ movie }) => {
)}
- {data.productionCompanies[0] && (
+ {data.productionCompanies.length > 0 && (
- {intl.formatMessage(messages.studio)}
+ {intl.formatMessage(messages.studio, {
+ studioCount: data.productionCompanies.length,
+ })}
-
-
- {data.productionCompanies[0].name}
-
-
+ {data.productionCompanies.map((s) => {
+ return (
+
+ {s.name}
+
+ );
+ })}
)}
diff --git a/src/components/TvDetails/index.tsx b/src/components/TvDetails/index.tsx
index e93fa94ce..930f6a6a1 100644
--- a/src/components/TvDetails/index.tsx
+++ b/src/components/TvDetails/index.tsx
@@ -62,7 +62,7 @@ const messages = defineMessages({
decline: 'Decline',
showtype: 'Show Type',
anime: 'Anime',
- network: 'Network',
+ network: '{networkCount, plural, one {Network} other {Networks}}',
viewfullcrew: 'View Full Crew',
areyousure: 'Are you sure?',
opensonarr: 'Open Series in Sonarr',
@@ -694,7 +694,9 @@ const TvDetails: React.FC
= ({ tv }) => {
{data.networks.length > 0 && (
- {intl.formatMessage(messages.network)}
+ {intl.formatMessage(messages.network, {
+ networkCount: data.networks.length,
+ })}
{data.networks
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json
index 87e56b6be..b31125ed3 100644
--- a/src/i18n/locale/en.json
+++ b/src/i18n/locale/en.json
@@ -85,7 +85,7 @@
"components.MovieDetails.similar": "Similar Titles",
"components.MovieDetails.similarsubtext": "Other movies similar to {title}",
"components.MovieDetails.status": "Status",
- "components.MovieDetails.studio": "Studio",
+ "components.MovieDetails.studio": "{studioCount, plural, one {Studio} other {Studios}}",
"components.MovieDetails.unavailable": "Unavailable",
"components.MovieDetails.userrating": "User Rating",
"components.MovieDetails.view": "View",
@@ -623,7 +623,7 @@
"components.TvDetails.manageModalTitle": "Manage Series",
"components.TvDetails.mark4kavailable": "Mark 4K as Available",
"components.TvDetails.markavailable": "Mark as Available",
- "components.TvDetails.network": "Network",
+ "components.TvDetails.network": "{networkCount, plural, one {Network} other {Networks}}",
"components.TvDetails.nextAirDate": "Next Air Date",
"components.TvDetails.opensonarr": "Open Series in Sonarr",
"components.TvDetails.opensonarr4k": "Open Series in 4K Sonarr",
From 74e39b0b458590e4f56c9eb582a2fbe33f1563a5 Mon Sep 17 00:00:00 2001
From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>
Date: Sun, 7 Mar 2021 16:41:52 -0800
Subject: [PATCH 041/421] docs(proxy): add nginx subfolder reverse proxy
(#1114) [skip ci]
---
.../reverse-proxy-examples.md | 53 +++++++++++++++++--
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/docs/extending-overseerr/reverse-proxy-examples.md b/docs/extending-overseerr/reverse-proxy-examples.md
index 8fa120ee9..659feb88b 100644
--- a/docs/extending-overseerr/reverse-proxy-examples.md
+++ b/docs/extending-overseerr/reverse-proxy-examples.md
@@ -1,12 +1,12 @@
# Reverse Proxy Examples
{% hint style="warning" %}
-Base URLs cannot be configured in Overseerr. With this limitation, only subdomain configurations are supported.
+Base URLs cannot be configured in Overseerr. With this limitation, only subdomain configurations are supported. However, a Nginx subfolder workaround configuration is provided below to use at your own risk.
{% endhint %}
-## [SWAG (Secure Web Application Gateway, formerly known as `letsencrypt`)](https://github.com/linuxserver/docker-swag)
+## SWAG
-A sample proxy configuration is included in SWAG. However, this page is still the only source of truth, so the SWAG sample configuration is not guaranteed to be up-to-date. If you find an inconsistency, please [report it to the LinuxServer team](https://github.com/linuxserver/reverse-proxy-confs/issues/new) or [submit a pull request to update it](https://github.com/linuxserver/reverse-proxy-confs/pulls).
+A sample proxy configuration is included in [SWAG (Secure Web Application Gateway)](https://github.com/linuxserver/docker-swag). However, this page is still the only source of truth, so the SWAG sample configuration is not guaranteed to be up-to-date. If you find an inconsistency, please [report it to the LinuxServer team](https://github.com/linuxserver/reverse-proxy-confs/issues/new) or [submit a pull request to update it](https://github.com/linuxserver/reverse-proxy-confs/pulls).
To use the bundled configuration file, simply rename `overseerr.subdomain.conf.sample` in the `proxy-confs` folder to `overseerr.subdomain.conf`. Alternatively, create a new file `overseerr.subdomain.conf` in `proxy-confs` with the following configuration:
@@ -53,11 +53,14 @@ labels:
For more information, see the Traefik documentation for a [basic example](https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/).
-## `nginx`
+## Nginx
+
+{% tabs %}
+{% tab title="Subdomain" %}
Add the following configuration to a new file `/etc/nginx/sites-available/overseerr.example.com.conf`:
-```text
+```nginx
server {
listen 80;
server_name overseerr.example.com;
@@ -111,6 +114,46 @@ Then, create a symlink to `/etc/nginx/sites-enabled`:
```bash
sudo ln -s /etc/nginx/sites-available/overseerr.example.com.conf /etc/nginx/sites-enabled/overseerr.example.com.conf
```
+{% endtab %}
+
+{% tab title="Subfolder" %}
+
+{% hint style="warning" %}
+Nginx subfolder reverse proxy is unsupported. The sub filters may stop working when Overseerr is updated. Use at your own risk!
+{% endhint %}
+
+Add the following location block to your existing `nginx.conf` file.
+
+```nginx
+location ^~ /overseerr {
+ set $app 'overseerr';
+ # Remove /overseerr path to pass to the app
+ rewrite ^/overseerr/?(.*)$ /$1 break;
+ proxy_pass http://127.0.0.1:5055; # NO TRAILING SLASH
+ # Redirect location headers
+ proxy_redirect ^ /$app;
+ proxy_redirect /setup /$app/setup;
+ proxy_redirect /login /$app/login;
+ # Sub filters to replace hardcoded paths
+ proxy_set_header Accept-Encoding "";
+ sub_filter_once off;
+ sub_filter_types *;
+ sub_filter 'href="/"' 'href="/$app"';
+ sub_filter 'href="/login"' 'href="/$app/login"';
+ sub_filter 'href:"/"' 'href:"/$app"';
+ sub_filter '/_next' '/$app/_next';
+ sub_filter '/api/v1' '/$app/api/v1';
+ sub_filter '/login/plex/loading' '/$app/login/plex/loading';
+ sub_filter '/images/' '/$app/images/';
+ sub_filter '/android-' '/$app/android-';
+ sub_filter '/apple-' '/$app/apple-';
+ sub_filter '/favicon' '/$app/favicon';
+ sub_filter '/logo.png' '/$app/logo.png';
+ sub_filter '/site.webmanifest' '/$app/site.webmanifest';
+}
+```
+{% endtab %}
+{% endtabs %}
Next, test the configuration:
From f900d953a0e0639ce3b477fb1aae756dfd1ce4ab Mon Sep 17 00:00:00 2001
From: "allcontributors[bot]"
<46447321+allcontributors[bot]@users.noreply.github.com>
Date: Mon, 8 Mar 2021 10:52:11 +0900
Subject: [PATCH 042/421] docs: add JonnyWong16 as a contributor (#1115) [skip
ci]
* docs: update README.md [skip ci]
* docs: update .all-contributorsrc [skip ci]
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
---
.all-contributorsrc | 9 +++++++++
README.md | 5 ++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/.all-contributorsrc b/.all-contributorsrc
index d693838ed..db2b66cd0 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -330,6 +330,15 @@
"contributions": [
"infra"
]
+ },
+ {
+ "login": "JonnyWong16",
+ "name": "JonnyWong16",
+ "avatar_url": "https://avatars.githubusercontent.com/u/9099342?v=4",
+ "profile": "https://github.com/JonnyWong16",
+ "contributions": [
+ "doc"
+ ]
}
],
"badgeTemplate": " -orange.svg\"/> ",
diff --git a/README.md b/README.md
index be86fdf23..81f43f2cf 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
-
+
@@ -143,6 +143,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
nuro 📖
ᗪєνιη ᗷυнʟ 🚇
+
+ JonnyWong16 📖
+
From d0fa5f3dbe77b5e4d1f9925979c9840237f91754 Mon Sep 17 00:00:00 2001
From: "allcontributors[bot]"
<46447321+allcontributors[bot]@users.noreply.github.com>
Date: Mon, 8 Mar 2021 10:53:25 +0900
Subject: [PATCH 043/421] docs: add Roxedus as a contributor (#1118) [skip ci]
* docs: update README.md [skip ci]
* docs: update .all-contributorsrc [skip ci]
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
---
.all-contributorsrc | 9 +++++++++
README.md | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/.all-contributorsrc b/.all-contributorsrc
index db2b66cd0..e6566b7ae 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -339,6 +339,15 @@
"contributions": [
"doc"
]
+ },
+ {
+ "login": "Roxedus",
+ "name": "Roxedus",
+ "avatar_url": "https://avatars.githubusercontent.com/u/7110194?v=4",
+ "profile": "https://github.com/Roxedus",
+ "contributions": [
+ "doc"
+ ]
}
],
"badgeTemplate": "
-orange.svg\"/>",
diff --git a/README.md b/README.md
index 81f43f2cf..87fc5be04 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
-
+
@@ -145,6 +145,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
JonnyWong16 📖
+ Roxedus 📖
From 1a7dc1acf57888d3d0285b58c1c97a824a232216 Mon Sep 17 00:00:00 2001
From: Brandon Cohen
Date: Mon, 8 Mar 2021 11:00:51 -0500
Subject: [PATCH 044/421] fix(frontend): status, requested by, and modified
alignment fix (#1109)
---
src/components/RequestCard/index.tsx | 48 +++++++++----------
.../RequestList/RequestItem/index.tsx | 2 +-
2 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx
index 5f537cdd5..7edaa5934 100644
--- a/src/components/RequestCard/index.tsx
+++ b/src/components/RequestCard/index.tsx
@@ -129,8 +129,30 @@ const RequestCard: React.FC = ({ request, onTitleData }) => {
-
-
+ {request.seasons.length > 0 && (
+
+
+ {intl.formatMessage(messages.seasons)}
+
+ {!isMovie(title) &&
+ title.seasons.filter((season) => season.seasonNumber !== 0)
+ .length === request.seasons.length ? (
+
+ {intl.formatMessage(messages.all)}
+
+ ) : (
+
+ {request.seasons.map((season) => (
+
+ {season.seasonNumber}
+
+ ))}
+
+ )}
+
+ )}
+
+
{intl.formatMessage(messages.status)}
{requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
@@ -157,28 +179,6 @@ const RequestCard: React.FC = ({ request, onTitleData }) => {
/>
)}
- {request.seasons.length > 0 && (
-
-
- {intl.formatMessage(messages.seasons)}
-
- {!isMovie(title) &&
- title.seasons.filter((season) => season.seasonNumber !== 0)
- .length === request.seasons.length ? (
-
- {intl.formatMessage(messages.all)}
-
- ) : (
-
- {request.seasons.map((season) => (
-
- {season.seasonNumber}
-
- ))}
-
- )}
-
- )}
{requestData.status === MediaRequestStatus.PENDING &&
hasPermission(Permission.MANAGE_REQUESTS) && (
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx
index fb2b888d6..442a44322 100644
--- a/src/components/RequestList/RequestItem/index.tsx
+++ b/src/components/RequestList/RequestItem/index.tsx
@@ -214,7 +214,7 @@ const RequestItem: React.FC = ({
)}
-
+
{intl.formatMessage(messages.status)}
From 48387e5b2f26c0c33acd436c6e1cf902d6c32101 Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Mon, 8 Mar 2021 14:22:03 -0500
Subject: [PATCH 045/421] feat(notif): include poster image in Telegram
notifications (#1112)
---
server/lib/notifications/agents/telegram.ts | 55 +++++++++++++++------
1 file changed, 40 insertions(+), 15 deletions(-)
diff --git a/server/lib/notifications/agents/telegram.ts b/server/lib/notifications/agents/telegram.ts
index 1e82a04da..c3c890172 100644
--- a/server/lib/notifications/agents/telegram.ts
+++ b/server/lib/notifications/agents/telegram.ts
@@ -4,13 +4,21 @@ import logger from '../../../logger';
import { getSettings, NotificationAgentTelegram } from '../../settings';
import { BaseAgent, NotificationAgent, NotificationPayload } from './agent';
-interface TelegramPayload {
+interface TelegramMessagePayload {
text: string;
parse_mode: string;
chat_id: string;
disable_notification: boolean;
}
+interface TelegramPhotoPayload {
+ photo: string;
+ caption: string;
+ parse_mode: string;
+ chat_id: string;
+ disable_notification: boolean;
+}
+
class TelegramAgent
extends BaseAgent
implements NotificationAgent {
@@ -125,14 +133,22 @@ class TelegramAgent
try {
const endpoint = `${this.baseUrl}bot${
this.getSettings().options.botAPI
- }/sendMessage`;
+ }/${payload.image ? 'sendPhoto' : 'sendMessage'}`;
- await axios.post(endpoint, {
- text: this.buildMessage(type, payload),
- parse_mode: 'MarkdownV2',
- chat_id: `${this.getSettings().options.chatId}`,
- disable_notification: this.getSettings().options.sendSilently,
- } as TelegramPayload);
+ await (payload.image
+ ? axios.post(endpoint, {
+ photo: payload.image,
+ caption: this.buildMessage(type, payload),
+ parse_mode: 'MarkdownV2',
+ chat_id: `${this.getSettings().options.chatId}`,
+ disable_notification: this.getSettings().options.sendSilently,
+ } as TelegramPhotoPayload)
+ : axios.post(endpoint, {
+ text: this.buildMessage(type, payload),
+ parse_mode: 'MarkdownV2',
+ chat_id: `${this.getSettings().options.chatId}`,
+ disable_notification: this.getSettings().options.sendSilently,
+ } as TelegramMessagePayload));
if (
payload.notifyUser.settings?.enableNotifications &&
@@ -140,13 +156,22 @@ class TelegramAgent
payload.notifyUser.settings?.telegramChatId !==
this.getSettings().options.chatId
) {
- await axios.post(endpoint, {
- text: this.buildMessage(type, payload),
- parse_mode: 'MarkdownV2',
- chat_id: `${payload.notifyUser.settings.telegramChatId}`,
- disable_notification:
- payload.notifyUser.settings.telegramSendSilently,
- } as TelegramPayload);
+ await (payload.image
+ ? axios.post(endpoint, {
+ photo: payload.image,
+ caption: this.buildMessage(type, payload),
+ parse_mode: 'MarkdownV2',
+ chat_id: `${payload.notifyUser.settings.telegramChatId}`,
+ disable_notification:
+ payload.notifyUser.settings.telegramSendSilently,
+ } as TelegramPhotoPayload)
+ : axios.post(endpoint, {
+ text: this.buildMessage(type, payload),
+ parse_mode: 'MarkdownV2',
+ chat_id: `${payload.notifyUser.settings.telegramChatId}`,
+ disable_notification:
+ payload.notifyUser.settings.telegramSendSilently,
+ } as TelegramMessagePayload));
}
return true;
From 57bc3408400a3d20e599d0735c7ee3024b471145 Mon Sep 17 00:00:00 2001
From: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Date: Mon, 8 Mar 2021 17:56:45 -0500
Subject: [PATCH 046/421] ci(docker): don't cache first build stage, and add
temp fix for growing cache (#1124)
* ci(docker): don't cache first build stage, and add temp fix for growing cache
---
.github/workflows/ci.yml | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0b255ff7c..66d2d2988 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -24,6 +24,7 @@ jobs:
run: yarn lint
- name: build
run: yarn build
+
build_and_push:
name: Build & Publish to Docker Hub
needs: test
@@ -69,7 +70,15 @@ jobs:
ghcr.io/sct/overseerr:develop
ghcr.io/sct/overseerr:${{ github.sha }}
cache-from: type=local,src=/tmp/.buildx-cache
- cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
+ cache-to: type=local,dest=/tmp/.buildx-cache-new
+ - # Temporary fix
+ # https://github.com/docker/build-push-action/issues/252
+ # https://github.com/moby/buildkit/issues/1896
+ name: Move cache
+ run: |
+ rm -rf /tmp/.buildx-cache
+ mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+
discord:
name: Send Discord Notification
needs: build_and_push
@@ -78,7 +87,6 @@ jobs:
steps:
- name: Get Build Job Status
uses: technote-space/workflow-conclusion-action@v2.1.2
-
- name: Combine Job Status
id: status
run: |
@@ -88,7 +96,6 @@ jobs:
else
echo ::set-output name=status::$WORKFLOW_CONCLUSION
fi
-
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1
with:
From 1c6914f5ce5c0d171c4609813915b50233a8e3ad Mon Sep 17 00:00:00 2001
From: sct
Date: Tue, 9 Mar 2021 02:23:29 +0000
Subject: [PATCH 047/421] feat: add studio/network sliders to discover
includes some adjustments to titlecard design
---
src/components/CompanyCard/index.tsx | 46 ++++++
.../Discover/DiscoverNetwork/index.tsx | 2 +-
.../Discover/DiscoverStudio/index.tsx | 2 +-
.../Discover/NetworkSlider/index.tsx | 151 ++++++++++++++++++
.../Discover/StudioSlider/index.tsx | 109 +++++++++++++
src/components/Discover/index.tsx | 4 +
.../MediaSlider/ShowMoreCard/index.tsx | 2 +-
src/components/PersonCard/index.tsx | 12 +-
src/components/RequestCard/index.tsx | 4 +-
.../RequestList/RequestItem/index.tsx | 6 +-
src/components/TitleCard/Placeholder.tsx | 2 +-
src/components/TitleCard/index.tsx | 12 +-
src/i18n/locale/en.json | 2 +
src/styles/globals.css | 2 +-
14 files changed, 336 insertions(+), 20 deletions(-)
create mode 100644 src/components/CompanyCard/index.tsx
create mode 100644 src/components/Discover/NetworkSlider/index.tsx
create mode 100644 src/components/Discover/StudioSlider/index.tsx
diff --git a/src/components/CompanyCard/index.tsx b/src/components/CompanyCard/index.tsx
new file mode 100644
index 000000000..dd6af067a
--- /dev/null
+++ b/src/components/CompanyCard/index.tsx
@@ -0,0 +1,46 @@
+import Link from 'next/link';
+import React, { useState } from 'react';
+
+interface CompanyCardProps {
+ name: string;
+ image: string;
+ url: string;
+}
+
+const CompanyCard: React.FC = ({ image, url, name }) => {
+ const [isHovered, setHovered] = useState(false);
+
+ return (
+
+ {
+ setHovered(true);
+ }}
+ onMouseLeave={() => setHovered(false)}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter') {
+ setHovered(true);
+ }
+ }}
+ role="link"
+ tabIndex={0}
+ >
+
+
+
+
+ );
+};
+
+export default CompanyCard;
diff --git a/src/components/Discover/DiscoverNetwork/index.tsx b/src/components/Discover/DiscoverNetwork/index.tsx
index 66b8c1a69..c2e96421b 100644
--- a/src/components/Discover/DiscoverNetwork/index.tsx
+++ b/src/components/Discover/DiscoverNetwork/index.tsx
@@ -49,7 +49,7 @@ const DiscoverTvNetwork: React.FC = () => {
{firstResultData?.network.logoPath ? (
diff --git a/src/components/Discover/DiscoverStudio/index.tsx b/src/components/Discover/DiscoverStudio/index.tsx
index f7fd7f7a9..bc7e270d3 100644
--- a/src/components/Discover/DiscoverStudio/index.tsx
+++ b/src/components/Discover/DiscoverStudio/index.tsx
@@ -49,7 +49,7 @@ const DiscoverMovieStudio: React.FC = () => {
{firstResultData?.studio.logoPath ? (
diff --git a/src/components/Discover/NetworkSlider/index.tsx b/src/components/Discover/NetworkSlider/index.tsx
new file mode 100644
index 000000000..69b2b2bb7
--- /dev/null
+++ b/src/components/Discover/NetworkSlider/index.tsx
@@ -0,0 +1,151 @@
+import React from 'react';
+import { defineMessages, useIntl } from 'react-intl';
+import CompanyCard from '../../CompanyCard';
+import Slider from '../../Slider';
+
+const messages = defineMessages({
+ networks: 'Networks',
+});
+
+interface Network {
+ name: string;
+ image: string;
+ url: string;
+}
+
+const networks: Network[] = [
+ {
+ name: 'Netflix',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/wwemzKWzjKYJFfCeiB57q3r4Bcm.png',
+ url: '/discover/tv/network/213',
+ },
+ {
+ name: 'Disney+',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/gJ8VX6JSu3ciXHuC2dDGAo2lvwM.png',
+ url: '/discover/tv/network/2739',
+ },
+ {
+ name: 'Prime Video',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/ifhbNuuVnlwYy5oXA5VIb2YR8AZ.png',
+ url: '/discover/tv/network/1024',
+ },
+ {
+ name: 'HBO',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/tuomPhY2UtuPTqqFnKMVHvSb724.png',
+ url: '/discover/tv/network/49',
+ },
+ {
+ name: 'ABC',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/ndAvF4JLsliGreX87jAc9GdjmJY.png',
+ url: '/discover/tv/network/2',
+ },
+ {
+ name: 'FOX',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/1DSpHrWyOORkL9N2QHX7Adt31mQ.png',
+ url: '/discover/tv/network/19',
+ },
+ {
+ name: 'Cinemax',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/6mSHSquNpfLgDdv6VnOOvC5Uz2h.png',
+ url: '/discover/tv/network/359',
+ },
+ {
+ name: 'AMC',
+ image:
+ 'https://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/pmvRmATOCaDykE6JrVoeYxlFHw3.png',
+ url: '/discover/tv/network/174',
+ },
+ {
+ name: 'Showtime',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/Allse9kbjiP6ExaQrnSpIhkurEi.png',
+ url: '/discover/tv/network/67',
+ },
+ {
+ name: 'Starz',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/8GJjw3HHsAJYwIWKIPBPfqMxlEa.png',
+ url: '/discover/tv/network/318',
+ },
+ {
+ name: 'The CW',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/ge9hzeaU7nMtQ4PjkFlc68dGAJ9.png',
+ url: '/discover/tv/network/71',
+ },
+ {
+ name: 'NBC',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/o3OedEP0f9mfZr33jz2BfXOUK5.png',
+ url: '/discover/tv/network/6',
+ },
+ {
+ name: 'CBS',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/nm8d7P7MJNiBLdgIzUK0gkuEA4r.png',
+ url: '/discover/tv/network/16',
+ },
+ {
+ name: 'BBC One',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/mVn7xESaTNmjBUyUtGNvDQd3CT1.png',
+ url: '/discover/tv/network/4',
+ },
+ {
+ name: 'Cartoon Network',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/c5OC6oVCg6QP4eqzW6XIq17CQjI.png',
+ url: '/discover/tv/network/56',
+ },
+ {
+ name: 'Adult Swim',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/9AKyspxVzywuaMuZ1Bvilu8sXly.png',
+ url: '/discover/tv/network/80',
+ },
+ {
+ name: 'Nickelodeon',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/ikZXxg6GnwpzqiZbRPhJGaZapqB.png',
+ url: '/discover/tv/network/13',
+ },
+];
+
+const NetworkSlider: React.FC = () => {
+ const intl = useIntl();
+
+ return (
+ <>
+
+
+
+ {intl.formatMessage(messages.networks)}
+
+
+
+
(
+
+ ))}
+ emptyMessage=""
+ />
+ >
+ );
+};
+
+export default NetworkSlider;
diff --git a/src/components/Discover/StudioSlider/index.tsx b/src/components/Discover/StudioSlider/index.tsx
new file mode 100644
index 000000000..b3ec8fef6
--- /dev/null
+++ b/src/components/Discover/StudioSlider/index.tsx
@@ -0,0 +1,109 @@
+import React from 'react';
+import { defineMessages, useIntl } from 'react-intl';
+import CompanyCard from '../../CompanyCard';
+import Slider from '../../Slider';
+
+const messages = defineMessages({
+ studios: 'Studios',
+});
+
+interface Studio {
+ name: string;
+ image: string;
+ url: string;
+}
+
+const studios: Studio[] = [
+ {
+ name: 'Disney',
+ image:
+ 'https://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/wdrCwmRnLFJhEoH8GSfymY85KHT.png',
+ url: '/discover/movies/studio/2',
+ },
+ {
+ name: '20th Century Fox',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/qZCc1lty5FzX30aOCVRBLzaVmcp.png',
+ url: '/discover/movies/studio/25',
+ },
+ {
+ name: 'Sony Pictures',
+ image:
+ 'https://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/GagSvqWlyPdkFHMfQ3pNq6ix9P.png',
+ url: '/discover/movies/studio/34',
+ },
+ {
+ name: 'Warner Bros. Pictures',
+ image:
+ 'https://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/ky0xOc5OrhzkZ1N6KyUxacfQsCk.png',
+ url: '/discover/movies/studio/174',
+ },
+ {
+ name: 'Universal',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/8lvHyhjr8oUKOOy2dKXoALWKdp0.png',
+ url: '/discover/movies/studio/33',
+ },
+ {
+ name: 'Paramount',
+ image:
+ 'https://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/fycMZt242LVjagMByZOLUGbCvv3.png',
+ url: '/discover/movies/studio/4',
+ },
+ {
+ name: 'Pixar',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/1TjvGVDMYsj6JBxOAkUHpPEwLf7.png',
+ url: '/discover/movies/studio/3',
+ },
+ {
+ name: 'Dreamworks',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/kP7t6RwGz2AvvTkvnI1uteEwHet.png',
+ url: '/discover/movies/studio/521',
+ },
+ {
+ name: 'Marvel Studios',
+ image:
+ 'http://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/hUzeosd33nzE5MCNsZxCGEKTXaQ.png',
+ url: '/discover/movies/studio/420',
+ },
+ {
+ name: 'DC',
+ image:
+ 'https://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/2Tc1P3Ac8M479naPp1kYT3izLS5.png',
+ url: '/discover/movies/studio/9993',
+ },
+];
+
+const StudioSlider: React.FC = () => {
+ const intl = useIntl();
+
+ return (
+ <>
+
+
+
+ {intl.formatMessage(messages.studios)}
+
+
+
+ (
+
+ ))}
+ emptyMessage=""
+ />
+ >
+ );
+};
+
+export default StudioSlider;
diff --git a/src/components/Discover/index.tsx b/src/components/Discover/index.tsx
index 1af3b58e6..bea1b414b 100644
--- a/src/components/Discover/index.tsx
+++ b/src/components/Discover/index.tsx
@@ -9,6 +9,8 @@ import type { RequestResultsResponse } from '../../../server/interfaces/api/requ
import RequestCard from '../RequestCard';
import MediaSlider from '../MediaSlider';
import PageTitle from '../Common/PageTitle';
+import StudioSlider from './StudioSlider';
+import NetworkSlider from './NetworkSlider';
const messages = defineMessages({
discover: 'Discover',
@@ -112,6 +114,7 @@ const Discover: React.FC = () => {
linkUrl="/discover/movies/upcoming"
url="/api/v1/discover/movies/upcoming"
/>
+
{
url="/api/v1/discover/tv/upcoming"
linkUrl="/discover/tv/upcoming"
/>
+
>
);
};
diff --git a/src/components/MediaSlider/ShowMoreCard/index.tsx b/src/components/MediaSlider/ShowMoreCard/index.tsx
index 169675c03..d61f262ec 100644
--- a/src/components/MediaSlider/ShowMoreCard/index.tsx
+++ b/src/components/MediaSlider/ShowMoreCard/index.tsx
@@ -32,7 +32,7 @@ const ShowMoreCard: React.FC = ({ url, posters }) => {
>
diff --git a/src/components/PersonCard/index.tsx b/src/components/PersonCard/index.tsx
index f01756878..5e5416f41 100644
--- a/src/components/PersonCard/index.tsx
+++ b/src/components/PersonCard/index.tsx
@@ -37,8 +37,8 @@ const PersonCard: React.FC
= ({
@@ -47,7 +47,7 @@ const PersonCard: React.FC
= ({
{profilePath ? (
) : (
@@ -79,7 +79,11 @@ const PersonCard: React.FC = ({
{subName}
)}
-
+
diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx
index 7edaa5934..40c826054 100644
--- a/src/components/RequestCard/index.tsx
+++ b/src/components/RequestCard/index.tsx
@@ -31,7 +31,7 @@ const isMovie = (movie: MovieDetails | TvDetails): movie is MovieDetails => {
const RequestCardPlaceholder: React.FC = () => {
return (
-