From 9891a7577cc0874f41c38ff0e6e5a6b4d8315281 Mon Sep 17 00:00:00 2001 From: Gauthier Date: Wed, 12 Mar 2025 08:25:54 +0100 Subject: [PATCH 01/14] fix(proxy): update http proxy to accept bypass list with undici v7 (#1456) With the update of undici to v7, the bypass list of addresses (no_proxy addresses) was not ignored anymore. fix #1454 --- server/utils/customProxyAgent.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/server/utils/customProxyAgent.ts b/server/utils/customProxyAgent.ts index 96ea7fed7..5f163c3de 100644 --- a/server/utils/customProxyAgent.ts +++ b/server/utils/customProxyAgent.ts @@ -8,8 +8,9 @@ export default async function createCustomProxyAgent( ) { const defaultAgent = new Agent({ keepAliveTimeout: 5000 }); - const skipUrl = (url: string) => { - const hostname = new URL(url).hostname; + const skipUrl = (url: string | URL) => { + const hostname = + typeof url === 'string' ? new URL(url).hostname : url.hostname; if (proxySettings.bypassLocalAddresses && isLocalAddress(hostname)) { return true; @@ -38,8 +39,7 @@ export default async function createCustomProxyAgent( dispatch: Dispatcher['dispatch'] ): Dispatcher['dispatch'] => { return (opts, handler) => { - const url = opts.origin?.toString(); - return url && skipUrl(url) + return opts.origin && skipUrl(opts.origin) ? defaultAgent.dispatch(opts, handler) : dispatch(opts, handler); }; @@ -60,13 +60,10 @@ export default async function createCustomProxyAgent( ':' + proxySettings.port, token, - interceptors: { - Client: [noProxyInterceptor], - }, keepAliveTimeout: 5000, }); - setGlobalDispatcher(proxyAgent); + setGlobalDispatcher(proxyAgent.compose(noProxyInterceptor)); } catch (e) { logger.error('Failed to connect to the proxy: ' + e.message, { label: 'Proxy', @@ -95,7 +92,11 @@ export default async function createCustomProxyAgent( } function isLocalAddress(hostname: string) { - if (hostname === 'localhost' || hostname === '127.0.0.1') { + if ( + hostname === 'localhost' || + hostname === '127.0.0.1' || + hostname === '::1' + ) { return true; } From 33e7a153aa64461a715595d070fba53d52b34767 Mon Sep 17 00:00:00 2001 From: Gauthier Date: Wed, 12 Mar 2025 08:28:31 +0100 Subject: [PATCH 02/14] fix(requestlist): hide the remove from *arr button when no service exists (#1457) This PR hide the "Remove from *arr" button in the request list when the service of the request doesn't exist anymore. fix #1449 --- .../RequestList/RequestItem/index.tsx | 75 +++++++++++++------ src/components/RequestList/index.tsx | 13 +++- 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx index 5e764ecbb..037590e5d 100644 --- a/src/components/RequestList/RequestItem/index.tsx +++ b/src/components/RequestList/RequestItem/index.tsx @@ -17,9 +17,10 @@ import { TrashIcon, XMarkIcon, } from '@heroicons/react/24/solid'; -import { MediaRequestStatus } from '@server/constants/media'; +import { MediaRequestStatus, MediaType } from '@server/constants/media'; import type { MediaRequest } from '@server/entity/MediaRequest'; import type { NonFunctionProperties } from '@server/interfaces/api/common'; +import type { RadarrSettings, SonarrSettings } from '@server/lib/settings'; import type { MovieDetails } from '@server/models/Movie'; import type { TvDetails } from '@server/models/Tv'; import Link from 'next/link'; @@ -293,9 +294,16 @@ const RequestItemError = ({ interface RequestItemProps { request: NonFunctionProperties & { profileName?: string }; revalidateList: () => void; + radarrData?: RadarrSettings[]; + sonarrData?: SonarrSettings[]; } -const RequestItem = ({ request, revalidateList }: RequestItemProps) => { +const RequestItem = ({ + request, + revalidateList, + radarrData, + sonarrData, +}: RequestItemProps) => { const settings = useSettings(); const { ref, inView } = useInView({ triggerOnce: true, @@ -390,6 +398,23 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => { iOSPlexUrl4k: requestData?.media?.iOSPlexUrl4k, }); + const serviceExists = () => { + if (title?.mediaInfo) { + if (title?.mediaInfo.mediaType === MediaType.MOVIE) { + return ( + radarrData?.find((radarr) => radarr.id === request.serverId) !== + undefined + ); + } else { + return ( + sonarrData?.find((sonarr) => sonarr.id === request.serverId) !== + undefined + ); + } + } + return false; + }; + if (!title && !error) { return (
{ )} {requestData.status !== MediaRequestStatus.PENDING && hasPermission(Permission.MANAGE_REQUESTS) && ( - <> - deleteRequest()} - confirmText={intl.formatMessage(globalMessages.areyousure)} - className="w-full" - > - - {intl.formatMessage(messages.deleterequest)} - - deleteMediaFile()} - confirmText={intl.formatMessage(globalMessages.areyousure)} - className="w-full" - > - - - {intl.formatMessage(messages.removearr, { - arr: request.type === 'movie' ? 'Radarr' : 'Sonarr', - })} - - - + deleteRequest()} + confirmText={intl.formatMessage(globalMessages.areyousure)} + className="w-full" + > + + {intl.formatMessage(messages.deleterequest)} + + )} + {hasPermission(Permission.MANAGE_REQUESTS) && + title?.mediaInfo?.serviceId && + serviceExists() && ( + deleteMediaFile()} + confirmText={intl.formatMessage(globalMessages.areyousure)} + className="w-full" + > + + + {intl.formatMessage(messages.removearr, { + arr: request.type === 'movie' ? 'Radarr' : 'Sonarr', + })} + + )} {requestData.status === MediaRequestStatus.PENDING && hasPermission(Permission.MANAGE_REQUESTS) && ( diff --git a/src/components/RequestList/index.tsx b/src/components/RequestList/index.tsx index 6cdf5b0bf..468c0853e 100644 --- a/src/components/RequestList/index.tsx +++ b/src/components/RequestList/index.tsx @@ -17,6 +17,8 @@ import { FunnelIcon, } from '@heroicons/react/24/solid'; import type { RequestResultsResponse } from '@server/interfaces/api/requestInterfaces'; +import { Permission } from '@server/lib/permissions'; +import type { RadarrSettings, SonarrSettings } from '@server/lib/settings'; import Link from 'next/link'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; @@ -51,7 +53,7 @@ const RequestList = () => { const { user } = useUser({ id: Number(router.query.userId), }); - const { user: currentUser } = useUser(); + const { user: currentUser, hasPermission } = useUser(); const [currentFilter, setCurrentFilter] = useState(Filter.PENDING); const [currentSort, setCurrentSort] = useState('added'); const [currentSortDirection, setCurrentSortDirection] = @@ -62,6 +64,13 @@ const RequestList = () => { const pageIndex = page - 1; const updateQueryParams = useUpdateQueryParams({ page: page.toString() }); + const { data: radarrData } = useSWR( + hasPermission(Permission.ADMIN) ? '/api/v1/settings/radarr' : null + ); + const { data: sonarrData } = useSWR( + hasPermission(Permission.ADMIN) ? '/api/v1/settings/sonarr' : null + ); + const { data, error, @@ -245,6 +254,8 @@ const RequestList = () => { revalidate()} + radarrData={radarrData} + sonarrData={sonarrData} />
); From b085e12ff9df9f57d71ca1fe27fefa8319229a2a Mon Sep 17 00:00:00 2001 From: Kugelstift <100831349+Kugelstift@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:20:33 +0100 Subject: [PATCH 03/14] fix(auth): Bitwarden autofill fix on local/Jellyfin login (#1459) * Update LocalLogin.tsx remove data-bwignore="false" from attributes to let Bitwarden Autofill * Update JellyfinLogin.tsx remove data-bwignore="false" from attributes to let Bitwarden Autofill --- src/components/Login/JellyfinLogin.tsx | 1 - src/components/Login/LocalLogin.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/components/Login/JellyfinLogin.tsx b/src/components/Login/JellyfinLogin.tsx index 0b2776e3e..239e45693 100644 --- a/src/components/Login/JellyfinLogin.tsx +++ b/src/components/Login/JellyfinLogin.tsx @@ -161,7 +161,6 @@ const JellyfinLogin: React.FC = ({ data-form-type="password" data-1pignore="false" data-lpignore="false" - data-bwignore="false" />
diff --git a/src/components/Login/LocalLogin.tsx b/src/components/Login/LocalLogin.tsx index 169a5a8f5..1b9a5fe75 100644 --- a/src/components/Login/LocalLogin.tsx +++ b/src/components/Login/LocalLogin.tsx @@ -118,7 +118,6 @@ const LocalLogin = ({ revalidate }: LocalLoginProps) => { className="!bg-gray-700/80 placeholder:text-gray-400" data-1pignore="false" data-lpignore="false" - data-bwignore="false" />
From 4d1163c34384efa59fe9b5401c5bd42d7f0435fc Mon Sep 17 00:00:00 2001 From: Gauthier Date: Wed, 12 Mar 2025 21:05:16 +0100 Subject: [PATCH 04/14] fix(blacklist): add back the blacklist button on TitleCard for Plex (#1463) The PR #1398 introduced an issue where the blacklist button was not visible anymore on the TitleCards for Plex. This PR fixes it. --- src/components/TitleCard/index.tsx | 41 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/components/TitleCard/index.tsx b/src/components/TitleCard/index.tsx index 5bfb90e9e..037afbc85 100644 --- a/src/components/TitleCard/index.tsx +++ b/src/components/TitleCard/index.tsx @@ -373,11 +373,10 @@ const TitleCard = ({ : intl.formatMessage(globalMessages.tvshow)}
- {showDetail && - currentStatus !== MediaStatus.BLACKLISTED && - user?.userType !== UserType.PLEX && ( -
- {toggleWatchlist ? ( + {showDetail && currentStatus !== MediaStatus.BLACKLISTED && ( +
+ {user?.userType !== UserType.PLEX && + (toggleWatchlist ? ( + ))} + {showHideButton && + currentStatus !== MediaStatus.PROCESSING && + currentStatus !== MediaStatus.AVAILABLE && + currentStatus !== MediaStatus.PARTIALLY_AVAILABLE && + currentStatus !== MediaStatus.PENDING && ( + )} - {showHideButton && - currentStatus !== MediaStatus.PROCESSING && - currentStatus !== MediaStatus.AVAILABLE && - currentStatus !== MediaStatus.PARTIALLY_AVAILABLE && - currentStatus !== MediaStatus.PENDING && ( - - )} -
- )} +
+ )} {showDetail && showHideButton && currentStatus == MediaStatus.BLACKLISTED && ( From a6dd4a8fedb9af9810581b1cc18cfea53b3cfd39 Mon Sep 17 00:00:00 2001 From: Gauthier Date: Wed, 12 Mar 2025 22:13:00 +0100 Subject: [PATCH 05/14] fix(ui): move watch trailer button above the 4k request button (#1465) Fix a z-index issue with the "Watch Trailer" button being under the "Request in 4k" button fix #1462 --- src/components/MovieDetails/index.tsx | 4 +++- src/components/TvDetails/index.tsx | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx index 45cb0388e..6d4a3be36 100644 --- a/src/components/MovieDetails/index.tsx +++ b/src/components/MovieDetails/index.tsx @@ -629,7 +629,9 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => { )} )} - +
+ +
{ )} )} - +
+ +
revalidate()} From 418d51590d658a0148d7ab67a0c9fccf445bf6ba Mon Sep 17 00:00:00 2001 From: Ludovic Ortega Date: Wed, 12 Mar 2025 22:20:19 +0100 Subject: [PATCH 06/14] chore(helm): upgrade jellyseerr app to 2.5.0 (#1464) Signed-off-by: Ludovic Ortega --- charts/jellyseerr-chart/Chart.yaml | 4 ++-- charts/jellyseerr-chart/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/jellyseerr-chart/Chart.yaml b/charts/jellyseerr-chart/Chart.yaml index 15f182106..5408ac1a5 100644 --- a/charts/jellyseerr-chart/Chart.yaml +++ b/charts/jellyseerr-chart/Chart.yaml @@ -3,8 +3,8 @@ kubeVersion: ">=1.23.0-0" name: jellyseerr-chart description: Jellyseerr helm chart for Kubernetes type: application -version: 2.2.0 -appVersion: "2.4.0" +version: 2.3.0 +appVersion: "2.5.0" maintainers: - name: Jellyseerr url: https://github.com/Fallenbagel/jellyseerr diff --git a/charts/jellyseerr-chart/README.md b/charts/jellyseerr-chart/README.md index 94850b96a..eae3c6d69 100644 --- a/charts/jellyseerr-chart/README.md +++ b/charts/jellyseerr-chart/README.md @@ -1,6 +1,6 @@ # jellyseerr-chart -![Version: 2.2.0](https://img.shields.io/badge/Version-2.2.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.4.0](https://img.shields.io/badge/AppVersion-2.4.0-informational?style=flat-square) +![Version: 2.3.0](https://img.shields.io/badge/Version-2.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.5.0](https://img.shields.io/badge/AppVersion-2.5.0-informational?style=flat-square) Jellyseerr helm chart for Kubernetes From ebb7f00305d5be0c3d60baa351d4820afea38c0b Mon Sep 17 00:00:00 2001 From: fallenbagel <98979876+fallenbagel@users.noreply.github.com> Date: Thu, 13 Mar 2025 16:22:24 +0800 Subject: [PATCH 07/14] docs: add more troubleshooting steps (#1468) --- docs/troubleshooting.mdx | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/troubleshooting.mdx b/docs/troubleshooting.mdx index 2f3fed66c..78b7e073e 100644 --- a/docs/troubleshooting.mdx +++ b/docs/troubleshooting.mdx @@ -24,6 +24,12 @@ or for Cloudflare's DNS: ```bash --dns=1.1.1.1 ``` +or for Quad9 DNS: +```bash +--dns=9.9.9.9 +``` + +You can try them all and see which one works for your network. @@ -45,6 +51,16 @@ services: dns: - 1.1.1.1 ``` +or for Quad9's DNS: +```yaml +--- +services: + jellyseerr: + dns: + - 9.9.9.9 +``` + +You can try them all and see which one works for your network. @@ -56,7 +72,7 @@ services: 4. Click on Change adapter settings. 5. Right-click the network interface connected to the internet and select Properties. 6. Select Internet Protocol Version 4 (TCP/IPv4) and click Properties. -7. Select Use the following DNS server addresses and enter `8.8.8.8` for Google's DNS or `1.1.1.1` for Cloudflare's DNS. +7. Select Use the following DNS server addresses and enter `8.8.8.8` for Google's DNS or `1.1.1.1` for Cloudflare's DNS or `9.9.9.9` for Quad9's DNS. @@ -73,6 +89,10 @@ services: ```bash nameserver 1.1.1.1 ``` + or for Quad9's DNS: + ```bash + nameserver 9.9.9.9 + ``` @@ -81,7 +101,7 @@ services: Sometimes there are configuration issues with IPV6 that prevent the hostname resolution from working correctly. -You can try to force the resolution to use IPV4 first by setting the `FORCE_IPV4_FIRST` environment variable to `true`: +You can try to force the resolution to use IPV4 first by going to `Settings > Networking > Advanced Networking` and enabling `Force IPv4 Resolution First` setting and restarting. You can also add the environment variable, `FORCE_IPV4_FIRST=true`: From b8425d6388003322edd7b4b2473aeb24c06e4802 Mon Sep 17 00:00:00 2001 From: 0xsysr3ll <31414959+0xSysR3ll@users.noreply.github.com> Date: Thu, 13 Mar 2025 12:52:30 +0100 Subject: [PATCH 08/14] fix(smtp-notification-test): missing allowSelfSigned option in test function (#1461) * fix(smtp-notification-test): missing allowSelfSigned option in test function * fix: indent error --- src/components/Settings/Notifications/NotificationsEmail.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Settings/Notifications/NotificationsEmail.tsx b/src/components/Settings/Notifications/NotificationsEmail.tsx index ac3853ddc..a2431be02 100644 --- a/src/components/Settings/Notifications/NotificationsEmail.tsx +++ b/src/components/Settings/Notifications/NotificationsEmail.tsx @@ -221,6 +221,7 @@ const NotificationsEmail = () => { requireTls: values.encryption === 'opportunistic', authUser: values.authUser, authPass: values.authPass, + allowSelfSigned: values.allowSelfSigned, senderName: values.senderName, pgpPrivateKey: values.pgpPrivateKey, pgpPassword: values.pgpPassword, From 8394eb5ad405a90e840952d5977712e1ab890530 Mon Sep 17 00:00:00 2001 From: fallenbagel <98979876+fallenbagel@users.noreply.github.com> Date: Sat, 15 Mar 2025 03:49:54 +0800 Subject: [PATCH 09/14] revert(airdate): reverts airdate offset & changes relative time to only display date (not time) (#1467) * revert(airdate): reverts airdate offset and changes relative time to only display date (not time) This reverts #1390 as it created more confusion when we offsetted the air date in relevance to the timezone. It also changes the relative time to use date instead of time (so it will say `aired yesterday` `today` `5 days ago` instead of `aired x hours ago` since we dont really the airtime data. * fix: relate time in days instead of hours * fix: relative time in days * fix: relative time in days (but properly) --- src/components/AirDateBadge/index.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/AirDateBadge/index.tsx b/src/components/AirDateBadge/index.tsx index a51f39fc3..1143c3e3e 100644 --- a/src/components/AirDateBadge/index.tsx +++ b/src/components/AirDateBadge/index.tsx @@ -14,17 +14,13 @@ type AirDateBadgeProps = { const AirDateBadge = ({ airDate }: AirDateBadgeProps) => { const WEEK = 1000 * 60 * 60 * 24 * 8; const intl = useIntl(); - const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; const dAirDate = new Date(airDate); const nowDate = new Date(); const alreadyAired = dAirDate.getTime() < nowDate.getTime(); - const compareWeek = new Date( alreadyAired ? Date.now() - WEEK : Date.now() + WEEK ); - let showRelative = false; - if ( (alreadyAired && dAirDate.getTime() > compareWeek.getTime()) || (!alreadyAired && dAirDate.getTime() < compareWeek.getTime()) @@ -32,6 +28,10 @@ const AirDateBadge = ({ airDate }: AirDateBadgeProps) => { showRelative = true; } + const diffInDays = Math.round( + (dAirDate.getTime() - nowDate.getTime()) / (1000 * 60 * 60 * 24) + ); + return (
@@ -39,7 +39,7 @@ const AirDateBadge = ({ airDate }: AirDateBadgeProps) => { year: 'numeric', month: 'long', day: 'numeric', - timeZone, + timeZone: 'UTC', })} {showRelative && ( @@ -49,9 +49,9 @@ const AirDateBadge = ({ airDate }: AirDateBadgeProps) => { { relativeTime: ( ), } From 767a24164d6c9d101e613c53960985f4fbe2ce93 Mon Sep 17 00:00:00 2001 From: Gauthier Date: Sat, 15 Mar 2025 16:35:23 +0100 Subject: [PATCH 10/14] fix(ui): resolve streaming region dropdown overlap (#1477) The streaming region selection field is always in the foreground and overlaps other open dropdowns. fix #1475 --- .../UserProfile/UserSettings/UserGeneralSettings/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx index d8f0ded05..90fbb13c7 100644 --- a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx +++ b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx @@ -415,7 +415,7 @@ const UserGeneralSettings = () => {
-
+
{
-
+
Date: Sat, 15 Mar 2025 22:42:17 +0100 Subject: [PATCH 11/14] fix: check if the file still exists in the service before deleting (#1476) This PR add a check to verify if the item to be deleted inside the *arr service still exists before actually sending the delete request. --- server/routes/media.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/server/routes/media.ts b/server/routes/media.ts index 60191e5de..3ad197c9d 100644 --- a/server/routes/media.ts +++ b/server/routes/media.ts @@ -237,6 +237,19 @@ mediaRoutes.delete( } if (isMovie) { + // check if the movie exists + try { + await (service as RadarrAPI).getMovie({ + id: parseInt( + is4k + ? (media.externalServiceSlug4k as string) + : (media.externalServiceSlug as string) + ), + }); + } catch { + return res.status(204).send(); + } + // remove the movie await (service as RadarrAPI).removeMovie( parseInt( is4k @@ -251,6 +264,13 @@ mediaRoutes.delete( if (!tvdbId) { throw new Error('TVDB ID not found'); } + // check if the series exists + try { + await (service as SonarrAPI).getSeriesByTvdbId(tvdbId); + } catch { + return res.status(204).send(); + } + // remove the series await (service as SonarrAPI).removeSerie(tvdbId); } From 77a36f971444ee5dc0d15b2d34a8daaf4e1f28b5 Mon Sep 17 00:00:00 2001 From: Gauthier Date: Sun, 16 Mar 2025 21:57:14 +0100 Subject: [PATCH 12/14] fix(job): resolve edge case issue with season availability updates (#1483) Ensure media availability updates correctly for shows marked as UNKNOWN and yet having AVAILABLE or PARTIALLY_AVAILABLE seasons --- server/lib/availabilitySync.ts | 48 ++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/server/lib/availabilitySync.ts b/server/lib/availabilitySync.ts index b85d29e47..0fdfd6276 100644 --- a/server/lib/availabilitySync.ts +++ b/server/lib/availabilitySync.ts @@ -404,6 +404,34 @@ class AvailabilitySync { }); } + if ( + !showExists && + (media.status === MediaStatus.AVAILABLE || + media.status === MediaStatus.PARTIALLY_AVAILABLE || + media.seasons.some( + (season) => season.status === MediaStatus.AVAILABLE + ) || + media.seasons.some( + (season) => season.status === MediaStatus.PARTIALLY_AVAILABLE + )) + ) { + await this.mediaUpdater(media, false, mediaServerType); + } + + if ( + !showExists4k && + (media.status4k === MediaStatus.AVAILABLE || + media.status4k === MediaStatus.PARTIALLY_AVAILABLE || + media.seasons.some( + (season) => season.status4k === MediaStatus.AVAILABLE + ) || + media.seasons.some( + (season) => season.status4k === MediaStatus.PARTIALLY_AVAILABLE + )) + ) { + await this.mediaUpdater(media, true, mediaServerType); + } + // TODO: Figure out how to run seasonUpdater for each season if ([...finalSeasons.values()].includes(false)) { @@ -423,22 +451,6 @@ class AvailabilitySync { mediaServerType ); } - - if ( - !showExists && - (media.status === MediaStatus.AVAILABLE || - media.status === MediaStatus.PARTIALLY_AVAILABLE) - ) { - await this.mediaUpdater(media, false, mediaServerType); - } - - if ( - !showExists4k && - (media.status4k === MediaStatus.AVAILABLE || - media.status4k === MediaStatus.PARTIALLY_AVAILABLE) - ) { - await this.mediaUpdater(media, true, mediaServerType); - } } } } catch (ex) { @@ -466,6 +478,10 @@ class AvailabilitySync { { status: MediaStatus.PARTIALLY_AVAILABLE }, { status4k: MediaStatus.AVAILABLE }, { status4k: MediaStatus.PARTIALLY_AVAILABLE }, + { seasons: { status: MediaStatus.AVAILABLE } }, + { seasons: { status: MediaStatus.PARTIALLY_AVAILABLE } }, + { seasons: { status4k: MediaStatus.AVAILABLE } }, + { seasons: { status4k: MediaStatus.PARTIALLY_AVAILABLE } }, ]; let mediaPage: Media[]; From c2d9d00b415fecbb5a8d7ca28a6ed76ea3ba3c19 Mon Sep 17 00:00:00 2001 From: Gauthier Date: Sun, 16 Mar 2025 22:44:25 +0100 Subject: [PATCH 13/14] fix(mediarequest): correct download sync for Radarr (#1484) This PR fixes a bug introduced by #1376, where `radarrSettings` was incorrectly replaced by `radarrMovie`. --- server/entity/MediaRequest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/entity/MediaRequest.ts b/server/entity/MediaRequest.ts index 8ef614b1e..a06053745 100644 --- a/server/entity/MediaRequest.ts +++ b/server/entity/MediaRequest.ts @@ -999,7 +999,7 @@ export class MediaRequest { radarrMovie.id, [this.is4k ? 'externalServiceSlug4k' : 'externalServiceSlug']: radarrMovie.titleSlug, - [this.is4k ? 'serviceId4k' : 'serviceId']: radarrMovie?.id, + [this.is4k ? 'serviceId4k' : 'serviceId']: radarrSettings?.id, }; await mediaRepository.update({ id: this.media.id }, updateFields); From f884ac9c660d1931c8b3815dcaefd109da249f2a Mon Sep 17 00:00:00 2001 From: Gauthier Date: Sun, 16 Mar 2025 23:24:28 +0100 Subject: [PATCH 14/14] fix(ui): correct seasons badge order (#1485) This PR corrects the order of the seasons displayed on the request card, because it was not always ordered. --- src/components/RequestModal/TvRequestModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/RequestModal/TvRequestModal.tsx b/src/components/RequestModal/TvRequestModal.tsx index 0ef1afd1a..339b3768c 100644 --- a/src/components/RequestModal/TvRequestModal.tsx +++ b/src/components/RequestModal/TvRequestModal.tsx @@ -217,7 +217,7 @@ const TvRequestModal = ({ mediaType: 'tv', is4k, seasons: settings.currentSettings.partialRequestsEnabled - ? selectedSeasons + ? selectedSeasons.sort((a, b) => a - b) : getAllSeasons().filter( (season) => !getAllRequestedSeasons().includes(season) ),