diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index ce6e6e1be..83effbfff 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -56,7 +56,7 @@ const Player = ({ urlParams, queryParams }) => { const [speedMenuOpen, , closeSpeedMenu, toggleSpeedMenu] = useBinaryState(false); const [statisticsMenuOpen, , closeStatisticsMenu, toggleStatisticsMenu] = useBinaryState(false); const [nextVideoPopupOpen, openNextVideoPopup, closeNextVideoPopup] = useBinaryState(false); - const [sideDrawerOpen, openSideDrawer, closeSideDrawer, toggleSideDrawer] = useBinaryState(false); + const [sideDrawerOpen, , closeSideDrawer, toggleSideDrawer] = useBinaryState(false); const menusOpen = React.useMemo(() => { return optionsMenuOpen || subtitlesMenuOpen || speedMenuOpen || statisticsMenuOpen; @@ -67,6 +67,7 @@ const Player = ({ urlParams, queryParams }) => { closeSubtitlesMenu(); closeSpeedMenu(); closeStatisticsMenu(); + closeSideDrawer(); }, []); const overlayHidden = React.useMemo(() => { @@ -407,13 +408,6 @@ const Player = ({ urlParams, queryParams }) => { } }, [video.state.playbackSpeed]); - React.useEffect(() => { - if (sideDrawerOpen) { - closeMenus(); - setImmersed(true); - } - }, [sideDrawerOpen]); - React.useEffect(() => { const toastFilter = (item) => item?.dataset?.type === 'CoreEvent'; toast.addFilter(toastFilter); @@ -700,14 +694,12 @@ const Player = ({ urlParams, queryParams }) => { null } { - player.metaItem !== null && player.metaItem.type === 'Ready' ? + player.metaItem !== null && player.metaItem.type === 'Ready' && sideDrawerOpen ? : null } diff --git a/src/routes/Player/SideDrawer/SideDrawer.less b/src/routes/Player/SideDrawer/SideDrawer.less index dfcde350a..575e3fbc4 100644 --- a/src/routes/Player/SideDrawer/SideDrawer.less +++ b/src/routes/Player/SideDrawer/SideDrawer.less @@ -9,201 +9,107 @@ @padding: 1rem; .side-drawer { - position: fixed; - top: 0; - right: 0; - overflow: visible; + display: flex; + flex-direction: column; + padding: @padding; + height: 100dvh; + max-width: 35rem; + overflow-y: auto; position: relative; + border-top-left-radius: var(--border-radius); + border-bottom-left-radius: var(--border-radius); + background-color: var(--modal-background-color); + box-shadow: 0 1.35rem 2.7rem var(--color-background-dark5-40), 0 1.1rem 0.85rem var(--color-background-dark5-20); + backdrop-filter: blur(15px); + transition: transform 0.3s ease-in-out; + z-index: 1; - .overlay { - position: absolute; - top: 0; - right: 0; - width: 100dvw; - height: 100dvh; - background-color: rgba(0, 0, 0, 0.2); + .close-button { display: none; - } - - .open-button { position: absolute; - right: -4rem; - top: 50%; - height: 12.5rem; - width: 7.5rem; - transform: translateY(-50%); - display: flex; - justify-content: center; - align-items: center; - background-color: var(--modal-background-color); + top: 1.3rem; + right: 1.3rem; + padding: 0.5rem; + background-color: transparent; cursor: pointer; - border-radius: 50%; + z-index: 2; + border-radius: var(--border-radius); + transition: 0.3s all ease-in-out; -webkit-tap-highlight-color: transparent; - vertical-align: middle; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); - transition: opacity 0.3s ease-in-out, border-radius 0.3s ease-in-out; - will-change: transform, opacity; - opacity: 1; .icon { - width: 2.5rem; - height: 2.5rem; color: var(--primary-foreground-color); + width: 2rem; + height: 2rem; opacity: 0.6; - margin-right: 4rem; + transition: 0.3s opacity ease-in-out; } &:hover { + background-color: var(--overlay-color); + .icon { opacity: 1; } } } - .content { - display: flex; - flex-direction: column; + .info { padding: @padding; - height: 100dvh; - max-width: 35rem; overflow-y: auto; - position: relative; - border-top-left-radius: var(--border-radius); - border-bottom-left-radius: var(--border-radius); - background-color: var(--modal-background-color); - box-shadow: 0 1.35rem 2.7rem var(--color-background-dark5-40), 0 1.1rem 0.85rem var(--color-background-dark5-20); - backdrop-filter: blur(15px); - transition: transform 0.3s ease-in-out; - transform: translateX(100%); - pointer-events: none; - z-index: 1; + flex: none; - .close-button { - display: none; - position: absolute; - top: 1.3rem; - right: 1.3rem; - padding: 0.5rem; - background-color: transparent; - cursor: pointer; - z-index: 2; - border-radius: var(--border-radius); - transition: 0.3s all ease-in-out; - -webkit-tap-highlight-color: transparent; - - .icon { - color: var(--primary-foreground-color); - width: 2rem; - height: 2rem; - opacity: 0.6; - transition: 0.3s opacity ease-in-out; - } - - &:hover { - background-color: var(--overlay-color); - - .icon { - opacity: 1; - } - } - } - - .info { - padding: @padding; - overflow-y: auto; - flex: none; - - .side-drawer-meta-preview { - .action-buttons-container { - padding-top: 0; - margin-top: 0; - } - } - } - - .series-content { - flex: 2; - display: flex; - flex-direction: column; - - .videos { - overflow-y: auto; + .side-drawer-meta-preview { + .action-buttons-container { + padding-top: 0; + margin-top: 0; } } } - &.open { - .overlay { - display: block; - } + .series-content { + flex: 2; + display: flex; + flex-direction: column; - .content { - transform: translateX(0); - pointer-events: auto; - - .open-button { - opacity: 0; - } + .videos { + overflow-y: auto; } } } @media screen and (max-width: @small) { .side-drawer { - .content { - max-width: 40dvw; - } + max-width: 40dvw; } } @media (orientation: portrait) and (max-width: @xsmall) { .side-drawer { - .content { - max-width: 100dvw; + max-width: 100dvw; - .close-button { - display: block; - } + .close-button { + display: block; } } } @media (orientation: landscape) and (max-width: @xsmall) { .side-drawer { - .content { - max-width: 50dvw; + max-width: 50dvw; - .info { - max-height: 30dvh; - } - } - } -} - -@media screen and (max-width: @xsmall) { - .side-drawer { - .open-button { - height: 8rem; - width: 4.5rem; - right: -2.5rem; - - .icon { - width: 2rem; - height: 2rem; - margin-right: 2.5rem; - } + .info { + max-height: 30dvh; } } } @media screen and (max-width: @xxsmall) { .side-drawer { - .content { - padding: calc(@padding / 2); + padding: calc(@padding / 2); - .info { - padding: calc(@padding / 2); - } + .info { + padding: calc(@padding / 2); } } } diff --git a/src/routes/Player/SideDrawer/SideDrawer.tsx b/src/routes/Player/SideDrawer/SideDrawer.tsx index 3768386ea..d5578ef8d 100644 --- a/src/routes/Player/SideDrawer/SideDrawer.tsx +++ b/src/routes/Player/SideDrawer/SideDrawer.tsx @@ -7,19 +7,19 @@ import classNames from 'classnames'; import styles from './SideDrawer.less'; import { useServices } from 'stremio/services'; import Icon from '@stremio/stremio-icons/react'; +import useOutsideClick from 'stremio/common/useOutsideClick'; type Props = { seriesInfo: { season: number, episode: number }; metaItem: MetaItem; className?: string; - openSideDrawer: () => void; - closeSideBar: () => void; - sideDrawerOpen: boolean; + closeSideDrawer: () => void; }; -const SideDrawer = ({ seriesInfo, className, openSideDrawer, closeSideBar, sideDrawerOpen, ...props }: Props) => { +const SideDrawer = ({ seriesInfo, className, closeSideDrawer, ...props }: Props) => { const { core } = useServices(); const [season, setSeason] = useState(seriesInfo?.season); + const sideDrawerRef = useOutsideClick(() => closeSideDrawer()); const metaItem = useMemo(() => { return seriesInfo ? { @@ -59,61 +59,53 @@ const SideDrawer = ({ seriesInfo, className, openSideDrawer, closeSideBar, sideD }, []); return ( -
-
-
- +
+
+
- {/* @ts-expect-error inert is not recognisable on div element; we need it to not focus the sideDrawer when closed */} -
-
- -
-
- -
- { - seriesInfo ? -
- -
- {videos.map((video, index) => ( -
+
+ +
+ { + seriesInfo ? +
+ +
+ {videos.map((video, index) => ( +
- : null - } - -
+
+ : null + }
); diff --git a/src/routes/Player/styles.less b/src/routes/Player/styles.less index b9708135c..28d388777 100644 --- a/src/routes/Player/styles.less +++ b/src/routes/Player/styles.less @@ -115,7 +115,7 @@ html:not(.active-slider-within) { } &.side-drawer-layer { - top: 0; + bottom: 0; right: 0; left: initial; bottom: initial;