Compare commits
2 Commits
develop
...
feat/disco
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3369adfb9a | ||
|
|
76f57550fa |
@@ -26,6 +26,8 @@ export interface PublicSettingsResponse {
|
||||
applicationUrl: string;
|
||||
hideAvailable: boolean;
|
||||
localLogin: boolean;
|
||||
movieEnabled: boolean;
|
||||
seriesEnabled: boolean;
|
||||
movie4kEnabled: boolean;
|
||||
series4kEnabled: boolean;
|
||||
region: string;
|
||||
|
||||
@@ -115,6 +115,8 @@ interface FullPublicSettings extends PublicSettings {
|
||||
applicationUrl: string;
|
||||
hideAvailable: boolean;
|
||||
localLogin: boolean;
|
||||
movieEnabled: boolean;
|
||||
seriesEnabled: boolean;
|
||||
movie4kEnabled: boolean;
|
||||
series4kEnabled: boolean;
|
||||
region: string;
|
||||
@@ -491,6 +493,12 @@ class Settings {
|
||||
applicationUrl: this.data.main.applicationUrl,
|
||||
hideAvailable: this.data.main.hideAvailable,
|
||||
localLogin: this.data.main.localLogin,
|
||||
movieEnabled: this.data.radarr.some(
|
||||
(radarr) => !radarr.is4k && radarr.isDefault
|
||||
),
|
||||
seriesEnabled: this.data.sonarr.some(
|
||||
(sonarr) => !sonarr.is4k && sonarr.isDefault
|
||||
),
|
||||
movie4kEnabled: this.data.radarr.some(
|
||||
(radarr) => radarr.is4k && radarr.isDefault
|
||||
),
|
||||
|
||||
@@ -129,6 +129,7 @@ const CollectionDetails = ({ collection }: CollectionDetailsProps) => {
|
||||
}
|
||||
|
||||
const hasRequestable =
|
||||
settings.currentSettings.movieEnabled &&
|
||||
hasPermission([Permission.REQUEST, Permission.REQUEST_MOVIE], {
|
||||
type: 'or',
|
||||
}) &&
|
||||
@@ -237,14 +238,19 @@ const CollectionDetails = ({ collection }: CollectionDetailsProps) => {
|
||||
</div>
|
||||
<div className="media-title">
|
||||
<div className="media-status">
|
||||
<StatusBadge
|
||||
status={collectionStatus}
|
||||
downloadItem={downloadStatus}
|
||||
title={titles}
|
||||
inProgress={data.parts.some(
|
||||
(part) => (part.mediaInfo?.downloadStatus ?? []).length > 0
|
||||
{settings.currentSettings.movieEnabled &&
|
||||
hasPermission([Permission.REQUEST, Permission.REQUEST_MOVIE], {
|
||||
type: 'or',
|
||||
}) && (
|
||||
<StatusBadge
|
||||
status={collectionStatus}
|
||||
downloadItem={downloadStatus}
|
||||
title={titles}
|
||||
inProgress={data.parts.some(
|
||||
(part) => (part.mediaInfo?.downloadStatus ?? []).length > 0
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{settings.currentSettings.movie4kEnabled &&
|
||||
hasPermission(
|
||||
[Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE],
|
||||
@@ -340,6 +346,7 @@ const CollectionDetails = ({ collection }: CollectionDetailsProps) => {
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.mediaInfo?.status}
|
||||
status4k={title.mediaInfo?.status4k}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
|
||||
@@ -61,6 +61,7 @@ const ListView = ({
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.mediaInfo?.status}
|
||||
status4k={title.mediaInfo?.status4k}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
@@ -79,6 +80,7 @@ const ListView = ({
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.mediaInfo?.status}
|
||||
status4k={title.mediaInfo?.status4k}
|
||||
summary={title.overview}
|
||||
title={title.name}
|
||||
userScore={title.voteAverage}
|
||||
|
||||
@@ -72,8 +72,12 @@ const CreateIssueModal = ({
|
||||
const availableSeasons = (data?.mediaInfo?.seasons ?? [])
|
||||
.filter(
|
||||
(season) =>
|
||||
season.status === MediaStatus.AVAILABLE ||
|
||||
season.status === MediaStatus.PARTIALLY_AVAILABLE ||
|
||||
(settings.currentSettings.seriesEnabled &&
|
||||
hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_TV], {
|
||||
type: 'or',
|
||||
}) &&
|
||||
(season.status === MediaStatus.AVAILABLE ||
|
||||
season.status === MediaStatus.PARTIALLY_AVAILABLE)) ||
|
||||
(settings.currentSettings.series4kEnabled &&
|
||||
hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_TV], {
|
||||
type: 'or',
|
||||
|
||||
@@ -468,22 +468,23 @@ const ManageSlideOver = ({
|
||||
{intl.formatMessage(messages.manageModalAdvanced)}
|
||||
</h3>
|
||||
<div className="space-y-2">
|
||||
{data?.mediaInfo.status !== MediaStatus.AVAILABLE && (
|
||||
<Button
|
||||
onClick={() => markAvailable()}
|
||||
className="w-full"
|
||||
buttonType="success"
|
||||
>
|
||||
<CheckCircleIcon />
|
||||
<span>
|
||||
{intl.formatMessage(
|
||||
mediaType === 'movie'
|
||||
? messages.markavailable
|
||||
: messages.markallseasonsavailable
|
||||
)}
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
{data?.mediaInfo.status !== MediaStatus.AVAILABLE &&
|
||||
settings.currentSettings.seriesEnabled && (
|
||||
<Button
|
||||
onClick={() => markAvailable()}
|
||||
className="w-full"
|
||||
buttonType="success"
|
||||
>
|
||||
<CheckCircleIcon />
|
||||
<span>
|
||||
{intl.formatMessage(
|
||||
mediaType === 'movie'
|
||||
? messages.markavailable
|
||||
: messages.markallseasonsavailable
|
||||
)}
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
{data?.mediaInfo.status4k !== MediaStatus.AVAILABLE &&
|
||||
settings.currentSettings.series4kEnabled && (
|
||||
<Button
|
||||
|
||||
@@ -98,6 +98,7 @@ const MediaSlider = ({
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.mediaInfo?.status}
|
||||
status4k={title.mediaInfo?.status4k}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
@@ -112,6 +113,7 @@ const MediaSlider = ({
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.mediaInfo?.status}
|
||||
status4k={title.mediaInfo?.status4k}
|
||||
summary={title.overview}
|
||||
title={title.name}
|
||||
userScore={title.voteAverage}
|
||||
|
||||
@@ -154,6 +154,7 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
const mediaLinks: PlayButtonLink[] = [];
|
||||
|
||||
if (
|
||||
settings.currentSettings.movieEnabled &&
|
||||
plexUrl &&
|
||||
hasPermission([Permission.REQUEST, Permission.REQUEST_MOVIE], {
|
||||
type: 'or',
|
||||
@@ -314,16 +315,28 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
</div>
|
||||
<div className="media-title">
|
||||
<div className="media-status">
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status}
|
||||
downloadItem={data.mediaInfo?.downloadStatus}
|
||||
title={data.title}
|
||||
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
|
||||
tmdbId={data.mediaInfo?.tmdbId}
|
||||
mediaType="movie"
|
||||
plexUrl={plexUrl}
|
||||
serviceUrl={data.mediaInfo?.serviceUrl}
|
||||
/>
|
||||
{settings.currentSettings.movieEnabled &&
|
||||
hasPermission(
|
||||
[
|
||||
Permission.MANAGE_REQUESTS,
|
||||
Permission.REQUEST,
|
||||
Permission.REQUEST_MOVIE,
|
||||
],
|
||||
{
|
||||
type: 'or',
|
||||
}
|
||||
) && (
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status}
|
||||
downloadItem={data.mediaInfo?.downloadStatus}
|
||||
title={data.title}
|
||||
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
|
||||
tmdbId={data.mediaInfo?.tmdbId}
|
||||
mediaType="movie"
|
||||
plexUrl={plexUrl}
|
||||
serviceUrl={data.mediaInfo?.serviceUrl}
|
||||
/>
|
||||
)}
|
||||
{settings.currentSettings.movie4kEnabled &&
|
||||
hasPermission(
|
||||
[
|
||||
@@ -379,7 +392,8 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
tmdbId={data.id}
|
||||
onUpdate={() => revalidate()}
|
||||
/>
|
||||
{(data.mediaInfo?.status === MediaStatus.AVAILABLE ||
|
||||
{((settings.currentSettings.movieEnabled &&
|
||||
data.mediaInfo?.status === MediaStatus.AVAILABLE) ||
|
||||
(settings.currentSettings.movie4kEnabled &&
|
||||
hasPermission(
|
||||
[Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE],
|
||||
|
||||
@@ -159,17 +159,19 @@ const NotificationTypeSelector = ({
|
||||
{ type: 'or' }
|
||||
) ||
|
||||
// Cannot submit non-4K movie requests OR has Auto-Approve perms for non-4K movies
|
||||
((!hasPermission([Permission.REQUEST, Permission.REQUEST_MOVIE], {
|
||||
type: 'or',
|
||||
}) ||
|
||||
((!settings.currentSettings.movieEnabled ||
|
||||
!hasPermission([Permission.REQUEST, Permission.REQUEST_MOVIE], {
|
||||
type: 'or',
|
||||
}) ||
|
||||
hasPermission(
|
||||
[Permission.AUTO_APPROVE, Permission.AUTO_APPROVE_MOVIE],
|
||||
{ type: 'or' }
|
||||
)) &&
|
||||
// Cannot submit non-4K series requests OR has Auto-Approve perms for non-4K series
|
||||
(!hasPermission([Permission.REQUEST, Permission.REQUEST_TV], {
|
||||
type: 'or',
|
||||
}) ||
|
||||
(!settings.currentSettings.seriesEnabled ||
|
||||
!hasPermission([Permission.REQUEST, Permission.REQUEST_TV], {
|
||||
type: 'or',
|
||||
}) ||
|
||||
hasPermission(
|
||||
[Permission.AUTO_APPROVE, Permission.AUTO_APPROVE_TV],
|
||||
{ type: 'or' }
|
||||
|
||||
@@ -145,6 +145,7 @@ const PersonDetails = () => {
|
||||
summary={media.overview}
|
||||
mediaType={media.mediaType as 'movie' | 'tv'}
|
||||
status={media.mediaInfo?.status}
|
||||
status4k={media.mediaInfo?.status4k}
|
||||
canExpand
|
||||
/>
|
||||
{media.character && (
|
||||
@@ -185,6 +186,7 @@ const PersonDetails = () => {
|
||||
summary={media.overview}
|
||||
mediaType={media.mediaType as 'movie' | 'tv'}
|
||||
status={media.mediaInfo?.status}
|
||||
status4k={media.mediaInfo?.status}
|
||||
canExpand
|
||||
/>
|
||||
{media.job && (
|
||||
|
||||
@@ -273,7 +273,9 @@ const RequestButton = ({
|
||||
: Permission.REQUEST_TV,
|
||||
],
|
||||
{ type: 'or' }
|
||||
)
|
||||
) &&
|
||||
((settings.currentSettings.movieEnabled && mediaType === 'movie') ||
|
||||
(settings.currentSettings.seriesEnabled && mediaType === 'tv'))
|
||||
) {
|
||||
buttons.push({
|
||||
id: 'request',
|
||||
@@ -292,7 +294,8 @@ const RequestButton = ({
|
||||
}) &&
|
||||
media &&
|
||||
media.status !== MediaStatus.AVAILABLE &&
|
||||
!isShowComplete
|
||||
!isShowComplete &&
|
||||
settings.currentSettings.seriesEnabled
|
||||
) {
|
||||
buttons.push({
|
||||
id: 'request-more',
|
||||
|
||||
@@ -73,7 +73,10 @@ const StatusBadge = ({
|
||||
type: 'or',
|
||||
}
|
||||
) &&
|
||||
(!is4k ||
|
||||
((!is4k &&
|
||||
(mediaType === 'movie'
|
||||
? settings.currentSettings.movieEnabled
|
||||
: settings.currentSettings.seriesEnabled)) ||
|
||||
(mediaType === 'movie'
|
||||
? settings.currentSettings.movie4kEnabled
|
||||
: settings.currentSettings.series4kEnabled))
|
||||
|
||||
@@ -59,6 +59,7 @@ const TmdbTitleCard = ({
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.mediaInfo?.status}
|
||||
status4k={title.mediaInfo?.status4k}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
@@ -71,6 +72,7 @@ const TmdbTitleCard = ({
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.mediaInfo?.status}
|
||||
status4k={title.mediaInfo?.status4k}
|
||||
summary={title.overview}
|
||||
title={title.name}
|
||||
userScore={title.voteAverage}
|
||||
|
||||
@@ -6,6 +6,7 @@ import RequestModal from '@app/components/RequestModal';
|
||||
import ErrorCard from '@app/components/TitleCard/ErrorCard';
|
||||
import Placeholder from '@app/components/TitleCard/Placeholder';
|
||||
import { useIsTouch } from '@app/hooks/useIsTouch';
|
||||
import useSettings from '@app/hooks/useSettings';
|
||||
import { Permission, useUser } from '@app/hooks/useUser';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import { withProperties } from '@app/utils/typeHelpers';
|
||||
@@ -26,6 +27,7 @@ interface TitleCardProps {
|
||||
userScore?: number;
|
||||
mediaType: MediaType;
|
||||
status?: MediaStatus;
|
||||
status4k?: MediaStatus;
|
||||
canExpand?: boolean;
|
||||
inProgress?: boolean;
|
||||
}
|
||||
@@ -37,6 +39,7 @@ const TitleCard = ({
|
||||
year,
|
||||
title,
|
||||
status,
|
||||
status4k,
|
||||
mediaType,
|
||||
inProgress = false,
|
||||
canExpand = false,
|
||||
@@ -46,8 +49,11 @@ const TitleCard = ({
|
||||
const { hasPermission } = useUser();
|
||||
const [isUpdating, setIsUpdating] = useState(false);
|
||||
const [currentStatus, setCurrentStatus] = useState(status);
|
||||
const [currentStatus4k, setCurrentStatus4k] = useState(status4k);
|
||||
const [showDetail, setShowDetail] = useState(false);
|
||||
const [showRequestModal, setShowRequestModal] = useState(false);
|
||||
const [showRequestModal4k, setShowRequestModal4k] = useState(false);
|
||||
const settings = useSettings();
|
||||
|
||||
// Just to get the year from the date
|
||||
if (year) {
|
||||
@@ -56,7 +62,8 @@ const TitleCard = ({
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentStatus(status);
|
||||
}, [status]);
|
||||
setCurrentStatus4k(status4k);
|
||||
}, [status, status4k]);
|
||||
|
||||
const requestComplete = useCallback((newStatus: MediaStatus) => {
|
||||
setCurrentStatus(newStatus);
|
||||
@@ -70,15 +77,44 @@ const TitleCard = ({
|
||||
|
||||
const closeModal = useCallback(() => setShowRequestModal(false), []);
|
||||
|
||||
const showRequestButton = hasPermission(
|
||||
[
|
||||
Permission.REQUEST,
|
||||
mediaType === 'movie' || mediaType === 'collection'
|
||||
? Permission.REQUEST_MOVIE
|
||||
: Permission.REQUEST_TV,
|
||||
],
|
||||
{ type: 'or' }
|
||||
);
|
||||
const requestComplete4k = useCallback((newStatus: MediaStatus) => {
|
||||
setCurrentStatus4k(newStatus);
|
||||
setShowRequestModal4k(false);
|
||||
}, []);
|
||||
|
||||
const closeModal4k = useCallback(() => setShowRequestModal4k(false), []);
|
||||
|
||||
const showRequestButton =
|
||||
hasPermission(
|
||||
[
|
||||
Permission.REQUEST,
|
||||
mediaType === 'movie' || mediaType === 'collection'
|
||||
? Permission.REQUEST_MOVIE
|
||||
: Permission.REQUEST_TV,
|
||||
],
|
||||
{ type: 'or' }
|
||||
) &&
|
||||
((settings.currentSettings.movieEnabled && mediaType === 'movie') ||
|
||||
(settings.currentSettings.seriesEnabled && mediaType === 'tv'));
|
||||
|
||||
const showRequestButton4k =
|
||||
hasPermission(
|
||||
[
|
||||
Permission.REQUEST_4K,
|
||||
mediaType === 'movie' || mediaType === 'collection'
|
||||
? Permission.REQUEST_4K_MOVIE
|
||||
: Permission.REQUEST_4K_TV,
|
||||
],
|
||||
{ type: 'or' }
|
||||
) &&
|
||||
((settings.currentSettings.movie4kEnabled && mediaType === 'movie') ||
|
||||
(settings.currentSettings.series4kEnabled && mediaType === 'tv'));
|
||||
|
||||
const isRequestable =
|
||||
(showRequestButton &&
|
||||
(!currentStatus || currentStatus === MediaStatus.UNKNOWN)) ||
|
||||
(showRequestButton4k &&
|
||||
(!currentStatus4k || currentStatus4k === MediaStatus.UNKNOWN));
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -99,6 +135,21 @@ const TitleCard = ({
|
||||
onUpdating={requestUpdating}
|
||||
onCancel={closeModal}
|
||||
/>
|
||||
<RequestModal
|
||||
tmdbId={id}
|
||||
show={showRequestModal4k}
|
||||
type={
|
||||
mediaType === 'movie'
|
||||
? 'movie'
|
||||
: mediaType === 'collection'
|
||||
? 'collection'
|
||||
: 'tv'
|
||||
}
|
||||
onComplete={requestComplete4k}
|
||||
onUpdating={requestUpdating}
|
||||
onCancel={closeModal4k}
|
||||
is4k
|
||||
/>
|
||||
<div
|
||||
className={`relative transform-gpu cursor-default overflow-hidden rounded-xl bg-gray-800 bg-cover outline-none ring-1 transition duration-300 ${
|
||||
showDetail
|
||||
@@ -151,15 +202,24 @@ const TitleCard = ({
|
||||
: intl.formatMessage(globalMessages.tvshow)}
|
||||
</div>
|
||||
</div>
|
||||
{currentStatus && currentStatus !== MediaStatus.UNKNOWN && (
|
||||
<div className="pointer-events-none z-40 flex items-center">
|
||||
<div className="pointer-events-none z-40 flex items-center">
|
||||
{currentStatus && currentStatus !== MediaStatus.UNKNOWN ? (
|
||||
<StatusBadgeMini
|
||||
status={currentStatus}
|
||||
inProgress={inProgress}
|
||||
shrink
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
) : (
|
||||
currentStatus4k &&
|
||||
currentStatus4k !== MediaStatus.UNKNOWN && (
|
||||
<StatusBadgeMini
|
||||
status={currentStatus4k}
|
||||
inProgress={inProgress}
|
||||
shrink
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
@@ -178,7 +238,9 @@ const TitleCard = ({
|
||||
|
||||
<Transition
|
||||
as={Fragment}
|
||||
show={!image || showDetail || showRequestModal}
|
||||
show={
|
||||
!image || showDetail || showRequestModal || showRequestModal4k
|
||||
}
|
||||
enter="transition-opacity"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
@@ -206,10 +268,7 @@ const TitleCard = ({
|
||||
<div className="flex h-full w-full items-end">
|
||||
<div
|
||||
className={`px-2 text-white ${
|
||||
!showRequestButton ||
|
||||
(currentStatus && currentStatus !== MediaStatus.UNKNOWN)
|
||||
? 'pb-2'
|
||||
: 'pb-11'
|
||||
!isRequestable ? 'pb-2' : 'pb-11'
|
||||
}`}
|
||||
>
|
||||
{year && (
|
||||
@@ -232,12 +291,7 @@ const TitleCard = ({
|
||||
<div
|
||||
className="whitespace-normal text-xs"
|
||||
style={{
|
||||
WebkitLineClamp:
|
||||
!showRequestButton ||
|
||||
(currentStatus &&
|
||||
currentStatus !== MediaStatus.UNKNOWN)
|
||||
? 5
|
||||
: 3,
|
||||
WebkitLineClamp: !isRequestable ? 5 : 3,
|
||||
display: '-webkit-box',
|
||||
overflow: 'hidden',
|
||||
WebkitBoxOrient: 'vertical',
|
||||
@@ -253,20 +307,39 @@ const TitleCard = ({
|
||||
|
||||
<div className="absolute bottom-0 left-0 right-0 flex justify-between px-2 py-2">
|
||||
{showRequestButton &&
|
||||
(!currentStatus || currentStatus === MediaStatus.UNKNOWN) && (
|
||||
(!currentStatus || currentStatus === MediaStatus.UNKNOWN) ? (
|
||||
<Button
|
||||
buttonType="primary"
|
||||
buttonSize="sm"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setShowRequestModal(true);
|
||||
}}
|
||||
className="h-7 w-full"
|
||||
>
|
||||
<ArrowDownTrayIcon />
|
||||
<span>{intl.formatMessage(globalMessages.request)}</span>
|
||||
</Button>
|
||||
) : (
|
||||
showRequestButton4k &&
|
||||
(!currentStatus4k ||
|
||||
currentStatus4k === MediaStatus.UNKNOWN) && (
|
||||
<Button
|
||||
buttonType="primary"
|
||||
buttonSize="sm"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setShowRequestModal(true);
|
||||
setShowRequestModal4k(true);
|
||||
}}
|
||||
className="h-7 w-full"
|
||||
>
|
||||
<ArrowDownTrayIcon />
|
||||
<span>{intl.formatMessage(globalMessages.request)}</span>
|
||||
<span>
|
||||
{intl.formatMessage(globalMessages.request4k)}
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
@@ -149,7 +149,13 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
|
||||
|
||||
const mediaLinks: PlayButtonLink[] = [];
|
||||
|
||||
if (plexUrl) {
|
||||
if (
|
||||
settings.currentSettings.seriesEnabled &&
|
||||
plexUrl &&
|
||||
hasPermission([Permission.REQUEST, Permission.REQUEST_TV], {
|
||||
type: 'or',
|
||||
})
|
||||
) {
|
||||
mediaLinks.push({
|
||||
text: intl.formatMessage(messages.playonplex),
|
||||
url: plexUrl,
|
||||
@@ -337,16 +343,28 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
|
||||
</div>
|
||||
<div className="media-title">
|
||||
<div className="media-status">
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status}
|
||||
downloadItem={data.mediaInfo?.downloadStatus}
|
||||
title={data.name}
|
||||
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
|
||||
tmdbId={data.mediaInfo?.tmdbId}
|
||||
mediaType="tv"
|
||||
plexUrl={plexUrl}
|
||||
serviceUrl={data.mediaInfo?.serviceUrl}
|
||||
/>
|
||||
{settings.currentSettings.seriesEnabled &&
|
||||
hasPermission(
|
||||
[
|
||||
Permission.MANAGE_REQUESTS,
|
||||
Permission.REQUEST,
|
||||
Permission.REQUEST_TV,
|
||||
],
|
||||
{
|
||||
type: 'or',
|
||||
}
|
||||
) && (
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status}
|
||||
downloadItem={data.mediaInfo?.downloadStatus}
|
||||
title={data.name}
|
||||
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
|
||||
tmdbId={data.mediaInfo?.tmdbId}
|
||||
mediaType="tv"
|
||||
plexUrl={plexUrl}
|
||||
serviceUrl={data.mediaInfo?.serviceUrl}
|
||||
/>
|
||||
)}
|
||||
{settings.currentSettings.series4kEnabled &&
|
||||
hasPermission(
|
||||
[
|
||||
@@ -404,8 +422,12 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
|
||||
isShowComplete={isComplete}
|
||||
is4kShowComplete={is4kComplete}
|
||||
/>
|
||||
{(data.mediaInfo?.status === MediaStatus.AVAILABLE ||
|
||||
data.mediaInfo?.status === MediaStatus.PARTIALLY_AVAILABLE ||
|
||||
{((settings.currentSettings.seriesEnabled &&
|
||||
hasPermission([Permission.REQUEST, Permission.REQUEST_TV], {
|
||||
type: 'or',
|
||||
}) &&
|
||||
(data.mediaInfo?.status === MediaStatus.AVAILABLE ||
|
||||
data?.mediaInfo?.status === MediaStatus.PARTIALLY_AVAILABLE)) ||
|
||||
(settings.currentSettings.series4kEnabled &&
|
||||
hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_TV], {
|
||||
type: 'or',
|
||||
@@ -524,6 +546,18 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
|
||||
.reverse()
|
||||
.filter((season) => season.seasonNumber !== 0)
|
||||
.map((season) => {
|
||||
const showNon4k =
|
||||
settings.currentSettings.seriesEnabled &&
|
||||
hasPermission(
|
||||
[
|
||||
Permission.MANAGE_REQUESTS,
|
||||
Permission.REQUEST,
|
||||
Permission.REQUEST_TV,
|
||||
],
|
||||
{
|
||||
type: 'or',
|
||||
}
|
||||
);
|
||||
const show4k =
|
||||
settings.currentSettings.series4kEnabled &&
|
||||
hasPermission(
|
||||
@@ -588,65 +622,75 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
|
||||
</div>
|
||||
{((!mSeason &&
|
||||
request?.status === MediaRequestStatus.APPROVED) ||
|
||||
mSeason?.status === MediaStatus.PROCESSING) && (
|
||||
<>
|
||||
<div className="hidden md:flex">
|
||||
<Badge badgeType="primary">
|
||||
{intl.formatMessage(globalMessages.requested)}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex md:hidden">
|
||||
<StatusBadgeMini
|
||||
status={MediaStatus.PROCESSING}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
mSeason?.status === MediaStatus.PROCESSING) &&
|
||||
showNon4k && (
|
||||
<>
|
||||
<div className="hidden md:flex">
|
||||
<Badge badgeType="primary">
|
||||
{intl.formatMessage(
|
||||
globalMessages.requested
|
||||
)}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex md:hidden">
|
||||
<StatusBadgeMini
|
||||
status={MediaStatus.PROCESSING}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{((!mSeason &&
|
||||
request?.status === MediaRequestStatus.PENDING) ||
|
||||
mSeason?.status === MediaStatus.PENDING) && (
|
||||
<>
|
||||
<div className="hidden md:flex">
|
||||
<Badge badgeType="warning">
|
||||
{intl.formatMessage(globalMessages.pending)}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex md:hidden">
|
||||
<StatusBadgeMini status={MediaStatus.PENDING} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
mSeason?.status === MediaStatus.PENDING) &&
|
||||
showNon4k && (
|
||||
<>
|
||||
<div className="hidden md:flex">
|
||||
<Badge badgeType="warning">
|
||||
{intl.formatMessage(globalMessages.pending)}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex md:hidden">
|
||||
<StatusBadgeMini
|
||||
status={MediaStatus.PENDING}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{mSeason?.status ===
|
||||
MediaStatus.PARTIALLY_AVAILABLE && (
|
||||
<>
|
||||
<div className="hidden md:flex">
|
||||
<Badge badgeType="success">
|
||||
{intl.formatMessage(
|
||||
globalMessages.partiallyavailable
|
||||
)}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex md:hidden">
|
||||
<StatusBadgeMini
|
||||
status={MediaStatus.PARTIALLY_AVAILABLE}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{mSeason?.status === MediaStatus.AVAILABLE && (
|
||||
<>
|
||||
<div className="hidden md:flex">
|
||||
<Badge badgeType="success">
|
||||
{intl.formatMessage(globalMessages.available)}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex md:hidden">
|
||||
<StatusBadgeMini
|
||||
status={MediaStatus.AVAILABLE}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
MediaStatus.PARTIALLY_AVAILABLE &&
|
||||
showNon4k && (
|
||||
<>
|
||||
<div className="hidden md:flex">
|
||||
<Badge badgeType="success">
|
||||
{intl.formatMessage(
|
||||
globalMessages.partiallyavailable
|
||||
)}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex md:hidden">
|
||||
<StatusBadgeMini
|
||||
status={MediaStatus.PARTIALLY_AVAILABLE}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{mSeason?.status === MediaStatus.AVAILABLE &&
|
||||
showNon4k && (
|
||||
<>
|
||||
<div className="hidden md:flex">
|
||||
<Badge badgeType="success">
|
||||
{intl.formatMessage(
|
||||
globalMessages.available
|
||||
)}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex md:hidden">
|
||||
<StatusBadgeMini
|
||||
status={MediaStatus.AVAILABLE}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{((!mSeason4k &&
|
||||
request4k?.status ===
|
||||
MediaRequestStatus.APPROVED) ||
|
||||
|
||||
@@ -13,6 +13,8 @@ const defaultSettings = {
|
||||
applicationUrl: '',
|
||||
hideAvailable: false,
|
||||
localLogin: true,
|
||||
movieEnabled: false,
|
||||
seriesEnabled: false,
|
||||
movie4kEnabled: false,
|
||||
series4kEnabled: false,
|
||||
region: '',
|
||||
|
||||
@@ -174,6 +174,8 @@ CoreApp.getInitialProps = async (initialProps) => {
|
||||
applicationTitle: '',
|
||||
applicationUrl: '',
|
||||
hideAvailable: false,
|
||||
movieEnabled: false,
|
||||
seriesEnabled: false,
|
||||
movie4kEnabled: false,
|
||||
series4kEnabled: false,
|
||||
localLogin: true,
|
||||
|
||||
Reference in New Issue
Block a user