diff --git a/src/components/Common/Badge/index.tsx b/src/components/Common/Badge/index.tsx index 9118415f2..3868e8a40 100644 --- a/src/components/Common/Badge/index.tsx +++ b/src/components/Common/Badge/index.tsx @@ -3,36 +3,64 @@ import React from 'react'; interface BadgeProps { badgeType?: 'default' | 'primary' | 'danger' | 'warning' | 'success'; className?: string; + url?: string; } const Badge: React.FC = ({ badgeType = 'default', className, + url, children, }) => { const badgeStyle = [ - 'px-2 inline-flex text-xs leading-5 font-semibold rounded-full cursor-default', + 'px-2 inline-flex text-xs leading-5 font-semibold rounded-full', ]; + if (url) { + badgeStyle.push('transition cursor-pointer'); + } else { + badgeStyle.push('cursor-default'); + } + switch (badgeType) { case 'danger': badgeStyle.push('bg-red-600 text-red-100'); + if (url) { + badgeStyle.push('hover:bg-red-500'); + } break; case 'warning': badgeStyle.push('bg-yellow-500 text-yellow-100'); + if (url) { + badgeStyle.push('hover:bg-yellow-400'); + } break; case 'success': badgeStyle.push('bg-green-500 text-green-100'); + if (url) { + badgeStyle.push('hover:bg-green-400'); + } break; default: badgeStyle.push('bg-indigo-500 text-indigo-100'); + if (url) { + badgeStyle.push('hover:bg-indigo-400'); + } } if (className) { badgeStyle.push(className); } - return {children}; + if (url) { + return ( + + {children} + + ); + } else { + return {children}; + } }; export default Badge; diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx index 3faf23636..b1d5bcdf9 100644 --- a/src/components/MovieDetails/index.tsx +++ b/src/components/MovieDetails/index.tsx @@ -420,6 +420,11 @@ const MovieDetails: React.FC = ({ movie }) => { status={data.mediaInfo?.status} inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0} plexUrl={data.mediaInfo?.plexUrl} + serviceUrl={ + hasPermission(Permission.ADMIN) + ? data.mediaInfo?.serviceUrl + : undefined + } /> {settings.currentSettings.movie4kEnabled && hasPermission( @@ -434,7 +439,12 @@ const MovieDetails: React.FC = ({ movie }) => { inProgress={ (data.mediaInfo?.downloadStatus4k ?? []).length > 0 } - plexUrl4k={data.mediaInfo?.plexUrl4k} + plexUrl={data.mediaInfo?.plexUrl4k} + serviceUrl={ + hasPermission(Permission.ADMIN) + ? data.mediaInfo?.serviceUrl4k + : undefined + } /> )} diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx index 13d6119a2..08cc9ec69 100644 --- a/src/components/RequestCard/index.tsx +++ b/src/components/RequestCard/index.tsx @@ -292,8 +292,18 @@ const RequestCard: React.FC = ({ request, onTitleData }) => { ).length > 0 } is4k={requestData.is4k} - plexUrl={requestData.media.plexUrl} - plexUrl4k={requestData.media.plexUrl4k} + plexUrl={ + requestData.is4k + ? requestData.media.plexUrl4k + : requestData.media.plexUrl + } + serviceUrl={ + hasPermission(Permission.ADMIN) + ? requestData.is4k + ? requestData.media.serviceUrl4k + : requestData.media.serviceUrl + : undefined + } /> )} diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx index 93e28caf8..a3a203e7f 100644 --- a/src/components/RequestList/RequestItem/index.tsx +++ b/src/components/RequestList/RequestItem/index.tsx @@ -294,8 +294,18 @@ const RequestItem: React.FC = ({ ).length > 0 } is4k={requestData.is4k} - plexUrl={requestData.media.plexUrl} - plexUrl4k={requestData.media.plexUrl4k} + plexUrl={ + requestData.is4k + ? requestData.media.plexUrl4k + : requestData.media.plexUrl + } + serviceUrl={ + hasPermission(Permission.ADMIN) + ? requestData.is4k + ? requestData.media.serviceUrl4k + : requestData.media.serviceUrl + : undefined + } /> )} diff --git a/src/components/StatusBadge/index.tsx b/src/components/StatusBadge/index.tsx index ece5a512a..86c935bcc 100644 --- a/src/components/StatusBadge/index.tsx +++ b/src/components/StatusBadge/index.tsx @@ -6,6 +6,7 @@ import globalMessages from '../../i18n/globalMessages'; import Badge from '../Common/Badge'; const messages = defineMessages({ + status: '{status}', status4k: '4K {status}', }); @@ -14,7 +15,7 @@ interface StatusBadgeProps { is4k?: boolean; inProgress?: boolean; plexUrl?: string; - plexUrl4k?: string; + serviceUrl?: string; } const StatusBadge: React.FC = ({ @@ -22,158 +23,64 @@ const StatusBadge: React.FC = ({ is4k = false, inProgress = false, plexUrl, - plexUrl4k, + serviceUrl, }) => { const intl = useIntl(); - if (is4k) { - switch (status) { - case MediaStatus.AVAILABLE: - if (plexUrl4k) { - return ( - - - {intl.formatMessage(messages.status4k, { - status: intl.formatMessage(globalMessages.available), - })} - - - ); - } - - return ( - - {intl.formatMessage(messages.status4k, { - status: intl.formatMessage(globalMessages.available), - })} - - ); - case MediaStatus.PARTIALLY_AVAILABLE: - if (plexUrl4k) { - return ( - - - {intl.formatMessage(messages.status4k, { - status: intl.formatMessage(globalMessages.partiallyavailable), - })} - - - ); - } - - return ( - - {intl.formatMessage(messages.status4k, { - status: intl.formatMessage(globalMessages.partiallyavailable), - })} - - ); - case MediaStatus.PROCESSING: - return ( - -
- - {intl.formatMessage(messages.status4k, { - status: inProgress - ? intl.formatMessage(globalMessages.processing) - : intl.formatMessage(globalMessages.requested), - })} - - {inProgress && } -
-
- ); - case MediaStatus.PENDING: - return ( - - {intl.formatMessage(messages.status4k, { - status: intl.formatMessage(globalMessages.pending), - })} - - ); - default: - return null; - } - } - switch (status) { case MediaStatus.AVAILABLE: - if (plexUrl) { - return ( - - -
- {intl.formatMessage(globalMessages.available)} - {inProgress && } -
-
-
- ); - } - return ( - +
- {intl.formatMessage(globalMessages.available)} + + {intl.formatMessage(is4k ? messages.status4k : messages.status, { + status: intl.formatMessage(globalMessages.available), + })} + {inProgress && }
); - case MediaStatus.PARTIALLY_AVAILABLE: - if (plexUrl) { - return ( - - -
- - {intl.formatMessage(globalMessages.partiallyavailable)} - - {inProgress && } -
-
-
- ); - } + case MediaStatus.PARTIALLY_AVAILABLE: return ( - +
- {intl.formatMessage(globalMessages.partiallyavailable)} + + {intl.formatMessage(is4k ? messages.status4k : messages.status, { + status: intl.formatMessage(globalMessages.partiallyavailable), + })} + {inProgress && }
); + case MediaStatus.PROCESSING: return ( - +
- {inProgress - ? intl.formatMessage(globalMessages.processing) - : intl.formatMessage(globalMessages.requested)} + {intl.formatMessage(is4k ? messages.status4k : messages.status, { + status: inProgress + ? intl.formatMessage(globalMessages.processing) + : intl.formatMessage(globalMessages.requested), + })} {inProgress && }
); + case MediaStatus.PENDING: return ( - {intl.formatMessage(globalMessages.pending)} + {intl.formatMessage(is4k ? messages.status4k : messages.status, { + status: intl.formatMessage(globalMessages.pending), + })} ); + default: return null; } diff --git a/src/components/TvDetails/index.tsx b/src/components/TvDetails/index.tsx index 44554ba56..6ccc60499 100644 --- a/src/components/TvDetails/index.tsx +++ b/src/components/TvDetails/index.tsx @@ -430,6 +430,11 @@ const TvDetails: React.FC = ({ tv }) => { status={data.mediaInfo?.status} inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0} plexUrl={data.mediaInfo?.plexUrl} + serviceUrl={ + hasPermission(Permission.ADMIN) + ? data.mediaInfo?.serviceUrl + : undefined + } /> {settings.currentSettings.series4kEnabled && hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_TV], { @@ -441,7 +446,12 @@ const TvDetails: React.FC = ({ tv }) => { inProgress={ (data.mediaInfo?.downloadStatus4k ?? []).length > 0 } - plexUrl4k={data.mediaInfo?.plexUrl4k} + plexUrl={data.mediaInfo?.plexUrl4k} + serviceUrl={ + hasPermission(Permission.ADMIN) + ? data.mediaInfo?.serviceUrl4k + : undefined + } /> )} diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index 6fd4f737b..789d05a7e 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -673,6 +673,7 @@ "components.Setup.signinMessage": "Get started by signing in with your Plex account", "components.Setup.tip": "Tip", "components.Setup.welcome": "Welcome to Overseerr", + "components.StatusBadge.status": "{status}", "components.StatusBadge.status4k": "4K {status}", "components.StatusChacker.newversionDescription": "Overseerr has been updated! Please click the button below to reload the page.", "components.StatusChacker.newversionavailable": "Application Update", diff --git a/src/styles/globals.css b/src/styles/globals.css index 4970c54b5..fec0c7127 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -1,7 +1,6 @@ @tailwind base; @tailwind components; @tailwind utilities; -@tailwind screens; html { min-height: calc(100% + env(safe-area-inset-top)); @@ -182,7 +181,7 @@ a.crew-name, } .media-ratings { - @apply flex items-center justify-center px-4 py-2 border-b border-gray-700 last:border-b-0; + @apply flex items-center justify-center px-4 py-2 font-medium border-b border-gray-700 last:border-b-0; } .media-rating { @@ -213,6 +212,10 @@ img.avatar-sm { @apply mr-2 font-bold; } +.card-field a { + @apply transition duration-300 hover:text-white hover:underline; +} + .section { @apply mt-6 mb-10 text-white; }