Merge remote-tracking branch 'overseerr/develop' into develop

This commit is contained in:
notfakie
2022-12-29 13:37:07 +13:00
14 changed files with 427 additions and 84 deletions

View File

@@ -1,11 +1,13 @@
import Spinner from '@app/assets/spinner.svg';
import Badge from '@app/components/Common/Badge';
import Tooltip from '@app/components/Common/Tooltip';
import DownloadBlock from '@app/components/DownloadBlock';
import useSettings from '@app/hooks/useSettings';
import { Permission, useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import { MediaStatus } from '@server/constants/media';
import { MediaServerType } from '@server/constants/server';
import type { DownloadingItem } from '@server/lib/downloadtracker';
import getConfig from 'next/config';
import { defineMessages, useIntl } from 'react-intl';
@@ -15,26 +17,31 @@ const messages = defineMessages({
playonplex: 'Play on {mediaServerName}',
openinarr: 'Open in {arr}',
managemedia: 'Manage {mediaType}',
seasonepisodenumber: 'S{seasonNumber}E{episodeNumber}',
});
interface StatusBadgeProps {
status?: MediaStatus;
downloadItem?: DownloadingItem[];
is4k?: boolean;
inProgress?: boolean;
plexUrl?: string;
serviceUrl?: string;
tmdbId?: number;
mediaType?: 'movie' | 'tv';
title?: string | string[];
}
const StatusBadge = ({
status,
downloadItem = [],
is4k = false,
inProgress = false,
plexUrl,
serviceUrl,
tmdbId,
mediaType,
title,
}: StatusBadgeProps) => {
const intl = useIntl();
const { hasPermission } = useUser();
@@ -44,6 +51,10 @@ const StatusBadge = ({
let mediaLink: string | undefined;
let mediaLinkDescription: string | undefined;
const calculateDownloadProgress = (media: DownloadingItem) => {
return Math.round(((media?.size - media?.sizeLeft) / media?.size) * 100);
};
if (
mediaType &&
plexUrl &&
@@ -95,21 +106,87 @@ const StatusBadge = ({
}
}
const tooltipContent = (
<ul>
{downloadItem.map((status, index) => (
<li
key={`dl-status-${status.externalId}-${index}`}
className="border-b border-gray-700 last:border-b-0"
>
<DownloadBlock
downloadItem={status}
title={Array.isArray(title) ? title[index] : title}
is4k={is4k}
/>
</li>
))}
</ul>
);
const badgeDownloadProgress = (
<div
className={`
absolute top-0 left-0 z-10 flex h-full ${
status === MediaStatus.PROCESSING ? 'bg-indigo-500' : 'bg-green-500'
} transition-all duration-200 ease-in-out
`}
style={{
width: `${
downloadItem ? calculateDownloadProgress(downloadItem[0]) : 0
}%`,
}}
/>
);
switch (status) {
case MediaStatus.AVAILABLE:
return (
<Tooltip content={mediaLinkDescription}>
<Badge badgeType="success" href={mediaLink}>
<div className="flex items-center">
<Tooltip
content={inProgress ? tooltipContent : mediaLinkDescription}
className={`${
inProgress && 'hidden max-h-96 w-96 overflow-y-auto sm:block'
}`}
tooltipConfig={{
...(inProgress && { interactive: true, delayHide: 100 }),
}}
>
<Badge
badgeType="success"
href={mediaLink}
className={`${
inProgress &&
'relative !bg-gray-700 !bg-opacity-80 !px-0 hover:!bg-gray-700'
} overflow-hidden`}
>
{inProgress && badgeDownloadProgress}
<div
className={`relative z-20 flex items-center ${
inProgress && 'px-2'
}`}
>
<span>
{intl.formatMessage(
is4k ? messages.status4k : messages.status,
{
status: intl.formatMessage(globalMessages.available),
status: inProgress
? intl.formatMessage(globalMessages.processing)
: intl.formatMessage(globalMessages.available),
}
)}
</span>
{inProgress && <Spinner className="ml-1 h-3 w-3" />}
{inProgress && (
<>
{mediaType === 'tv' && (
<span className="ml-1">
{intl.formatMessage(messages.seasonepisodenumber, {
seasonNumber: downloadItem[0].episode?.seasonNumber,
episodeNumber: downloadItem[0].episode?.episodeNumber,
})}
</span>
)}
<Spinner className="ml-1 h-3 w-3" />
</>
)}
</div>
</Badge>
</Tooltip>
@@ -117,20 +194,52 @@ const StatusBadge = ({
case MediaStatus.PARTIALLY_AVAILABLE:
return (
<Tooltip content={mediaLinkDescription}>
<Badge badgeType="success" href={mediaLink}>
<div className="flex items-center">
<Tooltip
content={inProgress ? tooltipContent : mediaLinkDescription}
className={`${
inProgress && 'hidden max-h-96 w-96 overflow-y-auto sm:block'
}`}
tooltipConfig={{
...(inProgress && { interactive: true, delayHide: 100 }),
}}
>
<Badge
badgeType="success"
href={mediaLink}
className={`${
inProgress &&
'relative !bg-gray-700 !bg-opacity-80 !px-0 hover:!bg-gray-700'
} overflow-hidden`}
>
{inProgress && badgeDownloadProgress}
<div
className={`relative z-20 flex items-center ${
inProgress && 'px-2'
}`}
>
<span>
{intl.formatMessage(
is4k ? messages.status4k : messages.status,
{
status: intl.formatMessage(
globalMessages.partiallyavailable
),
status: inProgress
? intl.formatMessage(globalMessages.processing)
: intl.formatMessage(globalMessages.partiallyavailable),
}
)}
</span>
{inProgress && <Spinner className="ml-1 h-3 w-3" />}
{inProgress && (
<>
{mediaType === 'tv' && (
<span className="ml-1">
{intl.formatMessage(messages.seasonepisodenumber, {
seasonNumber: downloadItem[0].episode?.seasonNumber,
episodeNumber: downloadItem[0].episode?.episodeNumber,
})}
</span>
)}
<Spinner className="ml-1 h-3 w-3" />
</>
)}
</div>
</Badge>
</Tooltip>
@@ -138,9 +247,29 @@ const StatusBadge = ({
case MediaStatus.PROCESSING:
return (
<Tooltip content={mediaLinkDescription}>
<Badge badgeType="primary" href={mediaLink}>
<div className="flex items-center">
<Tooltip
content={inProgress ? tooltipContent : mediaLinkDescription}
className={`${
inProgress && 'hidden max-h-96 w-96 overflow-y-auto sm:block'
}`}
tooltipConfig={{
...(inProgress && { interactive: true, delayHide: 100 }),
}}
>
<Badge
badgeType="primary"
href={mediaLink}
className={`${
inProgress &&
'relative !bg-gray-700 !bg-opacity-80 !px-0 hover:!bg-gray-700'
} overflow-hidden`}
>
{inProgress && badgeDownloadProgress}
<div
className={`relative z-20 flex items-center ${
inProgress && 'px-2'
}`}
>
<span>
{intl.formatMessage(
is4k ? messages.status4k : messages.status,
@@ -151,7 +280,19 @@ const StatusBadge = ({
}
)}
</span>
{inProgress && <Spinner className="ml-1 h-3 w-3" />}
{inProgress && (
<>
{mediaType === 'tv' && (
<span className="ml-1">
{intl.formatMessage(messages.seasonepisodenumber, {
seasonNumber: downloadItem[0].episode?.seasonNumber,
episodeNumber: downloadItem[0].episode?.episodeNumber,
})}
</span>
)}
<Spinner className="ml-1 h-3 w-3" />
</>
)}
</div>
</Badge>
</Tooltip>