From 1f9cbbfdf1ac98e54de5b8777c52c7bfc69c7e20 Mon Sep 17 00:00:00 2001 From: sct Date: Wed, 14 Oct 2020 14:50:33 +0000 Subject: [PATCH] feat(frontend): cancel movie request modal also includes tons of performance fixes for the modals --- src/assets/download.svg | 1 + src/components/Common/Badge/index.tsx | 4 +- src/components/Common/Modal/index.tsx | 235 ++++++++++-------- src/components/MovieDetails/index.tsx | 137 +++------- .../RequestModal/MovieRequestModal.tsx | 122 +++++---- .../RequestModal/TvRequestModal.tsx | 13 +- src/components/RequestModal/index.tsx | 52 ++-- src/components/TitleCard/index.tsx | 23 +- src/components/TvDetails/index.tsx | 17 -- 9 files changed, 300 insertions(+), 304 deletions(-) create mode 100644 src/assets/download.svg diff --git a/src/assets/download.svg b/src/assets/download.svg new file mode 100644 index 000000000..8f1589785 --- /dev/null +++ b/src/assets/download.svg @@ -0,0 +1 @@ + diff --git a/src/components/Common/Badge/index.tsx b/src/components/Common/Badge/index.tsx index 3cd1453d1..7cabbd501 100644 --- a/src/components/Common/Badge/index.tsx +++ b/src/components/Common/Badge/index.tsx @@ -14,10 +14,10 @@ const Badge: React.FC = ({ badgeType = 'default', children }) => { badgeStyle.push('bg-red-600 text-red-100'); break; case 'warning': - badgeStyle.push('bg-orange-400 text-orange-100'); + badgeStyle.push('bg-orange-500 text-orange-100'); break; case 'success': - badgeStyle.push('bg-green-500 text-green-100'); + badgeStyle.push('bg-green-400 text-green-100'); break; default: badgeStyle.push('bg-indigo-500 text-indigo-100'); diff --git a/src/components/Common/Modal/index.tsx b/src/components/Common/Modal/index.tsx index f1740c666..522488f7d 100644 --- a/src/components/Common/Modal/index.tsx +++ b/src/components/Common/Modal/index.tsx @@ -6,16 +6,23 @@ import { useLockBodyScroll } from '../../../hooks/useLockBodyScroll'; import LoadingSpinner from '../LoadingSpinner'; import useClickOutside from '../../../hooks/useClickOutside'; -interface ModalProps { +interface ModalProps extends React.HTMLAttributes { title?: string; onCancel?: (e?: MouseEvent) => void; - onOk?: (e: MouseEvent) => void; + onOk?: (e?: MouseEvent) => void; + onSecondary?: (e?: MouseEvent) => void; + onTertiary?: (e?: MouseEvent) => void; cancelText?: string; okText?: string; + secondaryText?: string; + tertiaryText?: string; okDisabled?: boolean; cancelButtonType?: ButtonType; okButtonType?: ButtonType; - visible?: boolean; + secondaryButtonType?: ButtonType; + secondaryDisabled?: boolean; + tertiaryDisabled?: boolean; + tertiaryButtonType?: ButtonType; disableScrollLock?: boolean; backgroundClickable?: boolean; iconSvg?: ReactNode; @@ -29,14 +36,22 @@ const Modal: React.FC = ({ cancelText, okText, okDisabled = false, - cancelButtonType, - okButtonType, + cancelButtonType = 'default', + okButtonType = 'primary', children, - visible, disableScrollLock, backgroundClickable = true, iconSvg, loading = false, + secondaryButtonType = 'default', + secondaryDisabled = false, + onSecondary, + secondaryText, + tertiaryButtonType = 'default', + tertiaryDisabled = false, + tertiaryText, + onTertiary, + ...props }) => { const modalRef = useRef(null); useClickOutside(modalRef, () => { @@ -44,123 +59,129 @@ const Modal: React.FC = ({ ? onCancel() : undefined; }); - useLockBodyScroll(!!visible, disableScrollLock); - const transitions = useTransition(visible, null, { - from: { opacity: 0, backdropFilter: 'blur(0px)' }, - enter: { opacity: 1, backdropFilter: 'blur(3px)' }, - leave: { opacity: 0, backdropFilter: 'blur(0px)' }, - config: { tension: 500, velocity: 40, friction: 60 }, - }); - const containerTransitions = useTransition(visible && !loading, null, { + useLockBodyScroll(true, disableScrollLock); + const containerTransitions = useTransition(!loading, null, { from: { opacity: 0, transform: 'scale(0.5)' }, enter: { opacity: 1, transform: 'scale(1)' }, leave: { opacity: 0, transform: 'scale(0.5)' }, config: { tension: 500, velocity: 40, friction: 60 }, }); - const loadingTransitions = useTransition(visible && loading, null, { + const loadingTransitions = useTransition(loading, null, { from: { opacity: 0, transform: 'scale(0.5)' }, enter: { opacity: 1, transform: 'scale(1)' }, leave: { opacity: 0, transform: 'scale(0.5)' }, config: { tension: 500, velocity: 40, friction: 60 }, }); - const cancelType = cancelButtonType ?? 'default'; - const okType = okButtonType ?? 'primary'; - return ( <> - {transitions.map( - ({ props, item, key }) => - item && - ReactDOM.createPortal( - { - if (e.key === 'Escape') { - typeof onCancel === 'function' && backgroundClickable - ? onCancel() - : undefined; - } - }} - > - {loadingTransitions.map( - ({ props, item, key }) => - item && ( - - - - ) - )} - {containerTransitions.map( - ({ props, item, key }) => - item && ( - -
- {iconSvg && ( -
- {iconSvg} -
- )} -
- {title && ( - - )} -
+ {ReactDOM.createPortal( + { + if (e.key === 'Escape') { + typeof onCancel === 'function' && backgroundClickable + ? onCancel() + : undefined; + } + }} + > + {loadingTransitions.map( + ({ props, item, key }) => + item && ( + + + + ) + )} + {containerTransitions.map( + ({ props, item, key }) => + item && ( + +
+ {iconSvg && ( +
+ {iconSvg}
- {children && ( -
-

- {children} -

-
+ )} +
+ {title && ( + + )} +
+
+ {children && ( +
+

+ {children} +

+
+ )} + {(onCancel || onOk || onSecondary || onTertiary) && ( +
+ {typeof onOk === 'function' && ( + + )} + {typeof onSecondary === 'function' && secondaryText && ( + + )} + {typeof onTertiary === 'function' && tertiaryText && ( + )} - {(onCancel || onOk) && ( -
- {typeof onOk === 'function' && ( - - )} - {typeof onCancel === 'function' && ( - - )} -
+ {typeof onCancel === 'function' && ( + )} - - ) - )} - , - document.body - ) +
+ )} +
+ ) + )} +
, + document.body )} ); diff --git a/src/components/MovieDetails/index.tsx b/src/components/MovieDetails/index.tsx index 44ee1af71..9a187d0a9 100644 --- a/src/components/MovieDetails/index.tsx +++ b/src/components/MovieDetails/index.tsx @@ -38,6 +38,7 @@ const messages = defineMessages({ available: 'Available', unavailable: 'Unavailable', request: 'Request', + viewrequest: 'View Request', pending: 'Pending', overviewunavailable: 'Overview unavailable', }); @@ -53,13 +54,6 @@ interface SearchResult { results: MovieResult[]; } -enum MediaRequestStatus { - PENDING = 1, - APPROVED, - DECLINED, - AVAILABLE, -} - const MovieDetails: React.FC = ({ movie }) => { const { hasPermission } = useUser(); const router = useRouter(); @@ -87,6 +81,11 @@ const MovieDetails: React.FC = ({ movie }) => { return
Broken?
; } + console.log(MediaStatus); + console.log(data); + + const activeRequest = data?.mediaInfo?.requests?.[0]; + return (
= ({ movie }) => {
{(!data.mediaInfo || - data.mediaInfo?.status === MediaStatus.UNKNOWN) && ( + data.mediaInfo?.status === MediaStatus.UNKNOWN || + activeRequest) && ( - )} - {data.mediaInfo?.status === MediaStatus.PENDING && ( - - )} - {data.mediaInfo?.status === MediaStatus.PROCESSING && ( - - )} - {data.mediaInfo?.status === MediaStatus.AVAILABLE && ( - )} - {hasPermission(Permission.MANAGE_REQUESTS) && ( )} - {hasPermission(Permission.MANAGE_REQUESTS) && (