mirror of
https://github.com/fallenbagel/jellyseerr.git
synced 2026-01-08 23:57:59 -05:00
refactor: update Next.js, React.js and Node.js (#815)
* refactor: update Next.js and React.js * refactor: update Next.js images * refactor: update ESLint rules and fix warnings/errors * fix: remove old intl polyfill * fix: add proper size to next/image components * fix: adjust full-size for next/image components * fix: temporary allow all domains for image optimization * build: fixes an issue where dev env could lead to javascript heap out of memory * fix: resolve webpack cache issue with country-flag-icons * refactor: switch compiler from Babel to SWC * fix: resize logo in sidebar * fix: break word on long path to avoid text overflow * chore: added sharp for production image optimisation * fix: change extract script for i18n to a custom script * fix: resolve GitHub CodeQL alert * chore: temporarily remove builds for ARMv7 * fix: resize avatar images * refactor: update Node.js to v20 * fix: resolve various UI issues * build: migrate yarn to pnpm and restrict engine to node@^20.0.0 * ci: specify the pnpm version to use in workflow actions * ci: fix typo in pnpm action-setup for cypress workflow * test(cypress): use pnpm instead of yarn * style: ran prettier on pnpm-lock * ci(cypress): setup nodejs v20 in cypress workflow * ci: pnpm cache to reduce install time * ci: use sh shell to get pnpm store directory * build(dockerfile): migrate to pnpm from yarn in docker builds * build(dockerfile): copy the proper pnpm lockfile * build: install pnpm for all platforms * build(dockerfile): remove unnecessary `&&` on apk installation steps * build: migrate pnpm 8 to 9 * build(dockerfile): add node-gyp back in * build(dockerfile): install node-gyp through npm * build(dockerfile): ignore scripts to not run husky install when devdependencies are pruned * build: migrate to pnpm from yarn * chore: remove a section that is no longer relevant --------- Co-authored-by: fallenbagel <98979876+Fallenbagel@users.noreply.github.com>
This commit is contained in:
@@ -3,13 +3,14 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
|
||||
import PageTitle from '@app/components/Common/PageTitle';
|
||||
import PersonCard from '@app/components/PersonCard';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import type { MovieDetails } from '@server/models/Movie';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
const messages = defineMessages('components.MovieDetails.MovieCast', {
|
||||
fullcast: 'Full Cast',
|
||||
});
|
||||
|
||||
@@ -34,8 +35,8 @@ const MovieCast = () => {
|
||||
<div className="mt-1 mb-5">
|
||||
<Header
|
||||
subtext={
|
||||
<Link href={`/movie/${data.id}`}>
|
||||
<a className="hover:underline">{data.title}</a>
|
||||
<Link href={`/movie/${data.id}`} className="hover:underline">
|
||||
{data.title}
|
||||
</Link>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -3,13 +3,14 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
|
||||
import PageTitle from '@app/components/Common/PageTitle';
|
||||
import PersonCard from '@app/components/PersonCard';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import type { MovieDetails } from '@server/models/Movie';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
const messages = defineMessages('components.MovieDetails.MovieCrew', {
|
||||
fullcrew: 'Full Crew',
|
||||
});
|
||||
|
||||
@@ -34,8 +35,8 @@ const MovieCrew = () => {
|
||||
<div className="mt-1 mb-5">
|
||||
<Header
|
||||
subtext={
|
||||
<Link href={`/movie/${data.id}`}>
|
||||
<a className="hover:underline">{data.title}</a>
|
||||
<Link href={`/movie/${data.id}`} className="hover:underline">
|
||||
{data.title}
|
||||
</Link>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -3,14 +3,15 @@ import ListView from '@app/components/Common/ListView';
|
||||
import PageTitle from '@app/components/Common/PageTitle';
|
||||
import useDiscover from '@app/hooks/useDiscover';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import type { MovieDetails } from '@server/models/Movie';
|
||||
import type { MovieResult } from '@server/models/Search';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
const messages = defineMessages('components.MovieDetails', {
|
||||
recommendations: 'Recommendations',
|
||||
});
|
||||
|
||||
@@ -44,8 +45,8 @@ const MovieRecommendations = () => {
|
||||
<div className="mt-1 mb-5">
|
||||
<Header
|
||||
subtext={
|
||||
<Link href={`/movie/${movieData?.id}`}>
|
||||
<a className="hover:underline">{movieData?.title}</a>
|
||||
<Link href={`/movie/${movieData?.id}`} className="hover:underline">
|
||||
{movieData?.title}
|
||||
</Link>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -3,14 +3,15 @@ import ListView from '@app/components/Common/ListView';
|
||||
import PageTitle from '@app/components/Common/PageTitle';
|
||||
import useDiscover from '@app/hooks/useDiscover';
|
||||
import Error from '@app/pages/_error';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import type { MovieDetails } from '@server/models/Movie';
|
||||
import type { MovieResult } from '@server/models/Search';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
const messages = defineMessages('components.MovieDetails', {
|
||||
similar: 'Similar Titles',
|
||||
});
|
||||
|
||||
@@ -42,8 +43,8 @@ const MovieSimilar = () => {
|
||||
<div className="mt-1 mb-5">
|
||||
<Header
|
||||
subtext={
|
||||
<Link href={`/movie/${movieData?.id}`}>
|
||||
<a className="hover:underline">{movieData?.title}</a>
|
||||
<Link href={`/movie/${movieData?.id}`} className="hover:underline">
|
||||
{movieData?.title}
|
||||
</Link>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -27,6 +27,7 @@ import { Permission, useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import Error from '@app/pages/_error';
|
||||
import { sortCrewPriority } from '@app/utils/creditHelpers';
|
||||
import defineMessages from '@app/utils/defineMessages';
|
||||
import { refreshIntervalHelper } from '@app/utils/refreshIntervalHelper';
|
||||
import {
|
||||
ArrowRightCircleIcon,
|
||||
@@ -46,17 +47,17 @@ import { IssueStatus } from '@server/constants/issue';
|
||||
import { MediaStatus } from '@server/constants/media';
|
||||
import { MediaServerType } from '@server/constants/server';
|
||||
import type { MovieDetails as MovieDetailsType } from '@server/models/Movie';
|
||||
import { hasFlag } from 'country-flag-icons';
|
||||
import { countries } from 'country-flag-icons';
|
||||
import 'country-flag-icons/3x2/flags.css';
|
||||
import { uniqBy } from 'lodash';
|
||||
import getConfig from 'next/config';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const messages = defineMessages({
|
||||
const messages = defineMessages('components.MovieDetails', {
|
||||
originaltitle: 'Original Title',
|
||||
releasedate:
|
||||
'{releaseCount, plural, one {Release Date} other {Release Dates}}',
|
||||
@@ -239,8 +240,12 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
movieAttributes.push(
|
||||
data.genres
|
||||
.map((g) => (
|
||||
<Link href={`/discover/movies?genre=${g.id}`} key={`genre-${g.id}`}>
|
||||
<a className="hover:underline">{g.name}</a>
|
||||
<Link
|
||||
href={`/discover/movies?genre=${g.id}`}
|
||||
key={`genre-${g.id}`}
|
||||
className="hover:underline"
|
||||
>
|
||||
{g.name}
|
||||
</Link>
|
||||
))
|
||||
.reduce((prev, curr) => (
|
||||
@@ -294,8 +299,8 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
<CachedImage
|
||||
alt=""
|
||||
src={`https://image.tmdb.org/t/p/w1920_and_h800_multi_faces/${data.backdropPath}`}
|
||||
layout="fill"
|
||||
objectFit="cover"
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
fill
|
||||
priority
|
||||
/>
|
||||
<div
|
||||
@@ -336,7 +341,8 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
: '/images/overseerr_poster_not_found.png'
|
||||
}
|
||||
alt=""
|
||||
layout="responsive"
|
||||
sizes="100vw"
|
||||
style={{ width: '100%', height: 'auto' }}
|
||||
width={600}
|
||||
height={900}
|
||||
priority
|
||||
@@ -483,18 +489,19 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
{sortedCrew.slice(0, 6).map((person) => (
|
||||
<li key={`crew-${person.job}-${person.id}`}>
|
||||
<span>{person.job}</span>
|
||||
<Link href={`/person/${person.id}`}>
|
||||
<a className="crew-name">{person.name}</a>
|
||||
<Link href={`/person/${person.id}`} className="crew-name">
|
||||
{person.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="mt-4 flex justify-end">
|
||||
<Link href={`/movie/${data.id}/crew`}>
|
||||
<a className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100">
|
||||
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
||||
<ArrowRightCircleIcon className="ml-1.5 inline-block h-5 w-5" />
|
||||
</a>
|
||||
<Link
|
||||
href={`/movie/${data.id}/crew`}
|
||||
className="flex items-center text-gray-400 transition duration-300 hover:text-gray-100"
|
||||
>
|
||||
<span>{intl.formatMessage(messages.viewfullcrew)}</span>
|
||||
<ArrowRightCircleIcon className="ml-1.5 inline-block h-5 w-5" />
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
@@ -505,10 +512,9 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
<Link
|
||||
href={`/discover/movies?keywords=${keyword.id}`}
|
||||
key={`keyword-id-${keyword.id}`}
|
||||
className="mb-2 mr-2 inline-flex last:mr-0"
|
||||
>
|
||||
<a className="mb-2 mr-2 inline-flex last:mr-0">
|
||||
<Tag>{keyword.name}</Tag>
|
||||
</a>
|
||||
<Tag>{keyword.name}</Tag>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
@@ -518,31 +524,33 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
{data.collection && (
|
||||
<div className="mb-6">
|
||||
<Link href={`/collection/${data.collection.id}`}>
|
||||
<a>
|
||||
<div className="group relative z-0 scale-100 transform-gpu cursor-pointer overflow-hidden rounded-lg bg-gray-800 bg-cover bg-center shadow-md ring-1 ring-gray-700 transition duration-300 hover:scale-105 hover:ring-gray-500">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<CachedImage
|
||||
src={`https://image.tmdb.org/t/p/w1440_and_h320_multi_faces/${data.collection.backdropPath}`}
|
||||
alt=""
|
||||
layout="fill"
|
||||
objectFit="cover"
|
||||
/>
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'linear-gradient(180deg, rgba(31, 41, 55, 0.47) 0%, rgba(31, 41, 55, 0.80) 100%)',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative z-10 flex h-full items-center justify-between p-4 text-gray-200 transition duration-300 group-hover:text-white">
|
||||
<div>{data.collection.name}</div>
|
||||
<Button buttonSize="sm">
|
||||
{intl.formatMessage(globalMessages.view)}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="group relative z-0 scale-100 transform-gpu cursor-pointer overflow-hidden rounded-lg bg-gray-800 bg-cover bg-center shadow-md ring-1 ring-gray-700 transition duration-300 hover:scale-105 hover:ring-gray-500">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<CachedImage
|
||||
src={`https://image.tmdb.org/t/p/w1440_and_h320_multi_faces/${data.collection.backdropPath}`}
|
||||
alt=""
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
}}
|
||||
fill
|
||||
/>
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'linear-gradient(180deg, rgba(31, 41, 55, 0.47) 0%, rgba(31, 41, 55, 0.80) 100%)',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<div className="relative z-10 flex h-full items-center justify-between p-4 text-gray-200 transition duration-300 group-hover:text-white">
|
||||
<div>{data.collection.name}</div>
|
||||
<Button buttonSize="sm">
|
||||
{intl.formatMessage(globalMessages.view)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
@@ -739,15 +747,13 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
<Link
|
||||
href={`/discover/movies/language/${data.originalLanguage}`}
|
||||
>
|
||||
<a>
|
||||
{intl.formatDisplayName(data.originalLanguage, {
|
||||
type: 'language',
|
||||
fallback: 'none',
|
||||
}) ??
|
||||
data.spokenLanguages.find(
|
||||
(lng) => lng.iso_639_1 === data.originalLanguage
|
||||
)?.name}
|
||||
</a>
|
||||
{intl.formatDisplayName(data.originalLanguage, {
|
||||
type: 'language',
|
||||
fallback: 'none',
|
||||
}) ??
|
||||
data.spokenLanguages.find(
|
||||
(lng) => lng.iso_639_1 === data.originalLanguage
|
||||
)?.name}
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
@@ -766,7 +772,7 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
className="flex items-center justify-end"
|
||||
key={`prodcountry-${c.iso_3166_1}`}
|
||||
>
|
||||
{hasFlag(c.iso_3166_1) && (
|
||||
{countries.includes(c.iso_3166_1) && (
|
||||
<span
|
||||
className={`mr-1.5 text-xs leading-5 flag:${c.iso_3166_1}`}
|
||||
/>
|
||||
@@ -803,8 +809,9 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
<Link
|
||||
href={`/discover/movies/studio/${s.id}`}
|
||||
key={`studio-${s.id}`}
|
||||
className="block"
|
||||
>
|
||||
<a className="block">{s.name}</a>
|
||||
{s.name}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
@@ -864,11 +871,13 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
{data.credits.cast.length > 0 && (
|
||||
<>
|
||||
<div className="slider-header">
|
||||
<Link href="/movie/[movieId]/cast" as={`/movie/${data.id}/cast`}>
|
||||
<a className="slider-title">
|
||||
<span>{intl.formatMessage(messages.cast)}</span>
|
||||
<ArrowRightCircleIcon />
|
||||
</a>
|
||||
<Link
|
||||
href="/movie/[movieId]/cast"
|
||||
as={`/movie/${data.id}/cast`}
|
||||
className="slider-title"
|
||||
>
|
||||
<span>{intl.formatMessage(messages.cast)}</span>
|
||||
<ArrowRightCircleIcon />
|
||||
</Link>
|
||||
</div>
|
||||
<Slider
|
||||
|
||||
Reference in New Issue
Block a user