mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-24 04:47:46 +00:00
feat: init side drawer component
This commit is contained in:
parent
2f8a5df83d
commit
a726ffb60d
7 changed files with 268 additions and 67 deletions
|
|
@ -35,9 +35,9 @@ const ControlBar = ({
|
|||
onVolumeChangeRequested,
|
||||
onSeekRequested,
|
||||
onToggleSubtitlesMenu,
|
||||
onToggleInfoMenu,
|
||||
// onToggleInfoMenu,
|
||||
onToggleSpeedMenu,
|
||||
onToggleVideosMenu,
|
||||
onToggleSideDrawer,
|
||||
onToggleOptionsMenu,
|
||||
onToggleStatisticsMenu,
|
||||
...props
|
||||
|
|
@ -48,9 +48,9 @@ const ControlBar = ({
|
|||
const onSubtitlesButtonMouseDown = React.useCallback((event) => {
|
||||
event.nativeEvent.subtitlesMenuClosePrevented = true;
|
||||
}, []);
|
||||
const onInfoButtonMouseDown = React.useCallback((event) => {
|
||||
event.nativeEvent.infoMenuClosePrevented = true;
|
||||
}, []);
|
||||
// const onInfoButtonMouseDown = React.useCallback((event) => {
|
||||
// event.nativeEvent.infoMenuClosePrevented = true;
|
||||
// }, []);
|
||||
const onSpeedButtonMouseDown = React.useCallback((event) => {
|
||||
event.nativeEvent.speedMenuClosePrevented = true;
|
||||
}, []);
|
||||
|
|
@ -151,9 +151,9 @@ const ControlBar = ({
|
|||
<Button className={classnames(styles['control-bar-button'], { 'disabled': playbackSpeed === null })} tabIndex={-1} onMouseDown={onSpeedButtonMouseDown} onClick={onToggleSpeedMenu}>
|
||||
<Icon className={styles['icon']} name={'speed'} />
|
||||
</Button>
|
||||
<Button className={classnames(styles['control-bar-button'], { 'disabled': metaItem === null || metaItem.type !== 'Ready' })} tabIndex={-1} onMouseDown={onInfoButtonMouseDown} onClick={onToggleInfoMenu}>
|
||||
{/* <Button className={classnames(styles['control-bar-button'], { 'disabled': metaItem === null || metaItem.type !== 'Ready' })} tabIndex={-1} onMouseDown={onInfoButtonMouseDown} onClick={onToggleInfoMenu}>
|
||||
<Icon className={styles['icon']} name={'about'} />
|
||||
</Button>
|
||||
</Button> */}
|
||||
<Button className={classnames(styles['control-bar-button'], { 'disabled': !chromecastServiceActive })} tabIndex={-1} onClick={onChromecastButtonClick}>
|
||||
<Icon className={styles['icon']} name={'cast'} />
|
||||
</Button>
|
||||
|
|
@ -162,7 +162,7 @@ const ControlBar = ({
|
|||
</Button>
|
||||
{
|
||||
metaItem?.content?.videos?.length > 0 ?
|
||||
<Button className={styles['control-bar-button']} tabIndex={-1} onMouseDown={onVideosButtonMouseDown} onClick={onToggleVideosMenu}>
|
||||
<Button className={styles['control-bar-button']} tabIndex={-1} onMouseDown={onVideosButtonMouseDown} onClick={onToggleSideDrawer}>
|
||||
<Icon className={styles['icon']} name={'episodes'} />
|
||||
</Button>
|
||||
:
|
||||
|
|
@ -202,7 +202,7 @@ ControlBar.propTypes = {
|
|||
onToggleSubtitlesMenu: PropTypes.func,
|
||||
onToggleInfoMenu: PropTypes.func,
|
||||
onToggleSpeedMenu: PropTypes.func,
|
||||
onToggleVideosMenu: PropTypes.func,
|
||||
onToggleSideDrawer: PropTypes.func,
|
||||
onToggleOptionsMenu: PropTypes.func,
|
||||
onToggleStatisticsMenu: PropTypes.func,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@ const Error = require('./Error');
|
|||
const ControlBar = require('./ControlBar');
|
||||
const NextVideoPopup = require('./NextVideoPopup');
|
||||
const StatisticsMenu = require('./StatisticsMenu');
|
||||
const InfoMenu = require('./InfoMenu');
|
||||
const OptionsMenu = require('./OptionsMenu');
|
||||
const VideosMenu = require('./VideosMenu');
|
||||
const SubtitlesMenu = require('./SubtitlesMenu');
|
||||
const SpeedMenu = require('./SpeedMenu');
|
||||
const usePlayer = require('./usePlayer');
|
||||
|
|
@ -26,6 +24,8 @@ const useStatistics = require('./useStatistics');
|
|||
const useVideo = require('./useVideo');
|
||||
const styles = require('./styles');
|
||||
const Video = require('./Video');
|
||||
const { default: SideDrawer } = require('./SideDrawer/SideDrawer');
|
||||
const { default: Icon } = require('@stremio/stremio-icons/react');
|
||||
|
||||
const Player = ({ urlParams, queryParams }) => {
|
||||
const { t } = useTranslation();
|
||||
|
|
@ -54,27 +54,24 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
|
||||
const [optionsMenuOpen, , closeOptionsMenu, toggleOptionsMenu] = useBinaryState(false);
|
||||
const [subtitlesMenuOpen, , closeSubtitlesMenu, toggleSubtitlesMenu] = useBinaryState(false);
|
||||
const [infoMenuOpen, , closeInfoMenu, toggleInfoMenu] = useBinaryState(false);
|
||||
const [speedMenuOpen, , closeSpeedMenu, toggleSpeedMenu] = useBinaryState(false);
|
||||
const [videosMenuOpen, , closeVideosMenu, toggleVideosMenu] = useBinaryState(false);
|
||||
const [statisticsMenuOpen, , closeStatisticsMenu, toggleStatisticsMenu] = useBinaryState(false);
|
||||
const [nextVideoPopupOpen, openNextVideoPopup, closeNextVideoPopup] = useBinaryState(false);
|
||||
const [sideDrawerOpen, openSideDrawer, closeSideDrawer, toggleSideDrawer] = useBinaryState(false);
|
||||
|
||||
const menusOpen = React.useMemo(() => {
|
||||
return optionsMenuOpen || subtitlesMenuOpen || infoMenuOpen || speedMenuOpen || videosMenuOpen || statisticsMenuOpen;
|
||||
}, [optionsMenuOpen, subtitlesMenuOpen, infoMenuOpen, speedMenuOpen, videosMenuOpen, statisticsMenuOpen]);
|
||||
return optionsMenuOpen || subtitlesMenuOpen || speedMenuOpen || statisticsMenuOpen;
|
||||
}, [optionsMenuOpen, subtitlesMenuOpen, speedMenuOpen, statisticsMenuOpen]);
|
||||
|
||||
const closeMenus = React.useCallback(() => {
|
||||
closeOptionsMenu();
|
||||
closeSubtitlesMenu();
|
||||
closeInfoMenu();
|
||||
closeSpeedMenu();
|
||||
closeVideosMenu();
|
||||
closeStatisticsMenu();
|
||||
}, []);
|
||||
|
||||
const overlayHidden = React.useMemo(() => {
|
||||
return immersed && !casting && video.state.paused !== null && !video.state.paused && !menusOpen && !nextVideoPopupOpen;
|
||||
return immersed && !casting && video.state.paused !== null && !video.state.paused && !menusOpen && !nextVideoPopupOpen && !sideDrawerOpen;
|
||||
}, [immersed, casting, video.state.paused, menusOpen, nextVideoPopupOpen]);
|
||||
|
||||
const nextVideoPopupDismissed = React.useRef(false);
|
||||
|
|
@ -237,15 +234,9 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
if (!event.nativeEvent.subtitlesMenuClosePrevented) {
|
||||
closeSubtitlesMenu();
|
||||
}
|
||||
if (!event.nativeEvent.infoMenuClosePrevented) {
|
||||
closeInfoMenu();
|
||||
}
|
||||
if (!event.nativeEvent.speedMenuClosePrevented) {
|
||||
closeSpeedMenu();
|
||||
}
|
||||
if (!event.nativeEvent.videosMenuClosePrevented) {
|
||||
closeVideosMenu();
|
||||
}
|
||||
if (!event.nativeEvent.statisticsMenuClosePrevented) {
|
||||
closeStatisticsMenu();
|
||||
}
|
||||
|
|
@ -412,19 +403,19 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
}
|
||||
}, [video.state.audioTracks, video.state.subtitlesTracks, video.state.extraSubtitlesTracks]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (player.metaItem === null || player.metaItem.type !== 'Ready') {
|
||||
closeInfoMenu();
|
||||
closeVideosMenu();
|
||||
}
|
||||
}, [player.metaItem]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (video.state.playbackSpeed === null) {
|
||||
closeSpeedMenu();
|
||||
}
|
||||
}, [video.state.playbackSpeed]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (sideDrawerOpen) {
|
||||
closeMenus();
|
||||
setImmersed(true);
|
||||
}
|
||||
}, [sideDrawerOpen]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const toastFilter = (item) => item?.dataset?.type === 'CoreEvent';
|
||||
toast.addFilter(toastFilter);
|
||||
|
|
@ -521,7 +512,7 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
case 'KeyI': {
|
||||
closeMenus();
|
||||
if (player.metaItem !== null && player.metaItem.type === 'Ready') {
|
||||
toggleInfoMenu();
|
||||
toggleSideDrawer();
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -534,14 +525,6 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
|
||||
break;
|
||||
}
|
||||
case 'KeyV': {
|
||||
closeMenus();
|
||||
if (player.metaItem !== null && player.metaItem.type === 'Ready' && player.metaItem?.content?.videos?.length > 0) {
|
||||
toggleVideosMenu();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 'KeyD': {
|
||||
closeMenus();
|
||||
if (streamingServer.statistics !== null && streamingServer.statistics.type !== 'Err' && player.selected && typeof player.selected.stream.infoHash === 'string' && typeof player.selected.stream.fileIdx === 'number') {
|
||||
|
|
@ -563,11 +546,11 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
};
|
||||
const onWheel = ({ deltaY }) => {
|
||||
if (deltaY > 0) {
|
||||
if (!menusOpen && video.state.volume !== null) {
|
||||
if (!menusOpen && !sideDrawerOpen && video.state.volume !== null) {
|
||||
onVolumeChangeRequested(video.state.volume - 5);
|
||||
}
|
||||
} else {
|
||||
if (!menusOpen && video.state.volume !== null) {
|
||||
if (!menusOpen && !sideDrawerOpen && video.state.volume !== null) {
|
||||
onVolumeChangeRequested(video.state.volume + 5);
|
||||
}
|
||||
}
|
||||
|
|
@ -582,7 +565,7 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
window.removeEventListener('keyup', onKeyUp);
|
||||
window.removeEventListener('wheel', onWheel);
|
||||
};
|
||||
}, [player.metaItem, player.selected, streamingServer.statistics, settings.seekTimeDuration, settings.seekShortTimeDuration, routeFocused, menusOpen, nextVideoPopupOpen, video.state.paused, video.state.time, video.state.volume, video.state.audioTracks, video.state.subtitlesTracks, video.state.extraSubtitlesTracks, video.state.playbackSpeed, toggleSubtitlesMenu, toggleInfoMenu, toggleVideosMenu, toggleStatisticsMenu]);
|
||||
}, [player.metaItem, player.selected, streamingServer.statistics, settings.seekTimeDuration, settings.seekShortTimeDuration, routeFocused, menusOpen, nextVideoPopupOpen, video.state.paused, video.state.time, video.state.volume, video.state.audioTracks, video.state.subtitlesTracks, video.state.extraSubtitlesTracks, video.state.playbackSpeed, toggleSubtitlesMenu, toggleStatisticsMenu, toggleSideDrawer]);
|
||||
|
||||
React.useEffect(() => {
|
||||
video.events.on('error', onError);
|
||||
|
|
@ -691,10 +674,9 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
onSeekRequested={onSeekRequested}
|
||||
onToggleOptionsMenu={toggleOptionsMenu}
|
||||
onToggleSubtitlesMenu={toggleSubtitlesMenu}
|
||||
onToggleInfoMenu={toggleInfoMenu}
|
||||
onToggleSpeedMenu={toggleSpeedMenu}
|
||||
onToggleVideosMenu={toggleVideosMenu}
|
||||
onToggleStatisticsMenu={toggleStatisticsMenu}
|
||||
onToggleSideDrawer={toggleSideDrawer}
|
||||
onMouseMove={onBarMouseMove}
|
||||
onMouseOver={onBarMouseMove}
|
||||
/>
|
||||
|
|
@ -719,6 +701,22 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
player.metaItem !== null && player.metaItem.type === 'Ready' ?
|
||||
<>
|
||||
<div className={classnames(styles['layer'], styles['side-drawer-button'], { [styles['open']]: sideDrawerOpen })} onClick={openSideDrawer}>
|
||||
<Icon name={'chevron-back'} className={styles['icon']} />
|
||||
</div>
|
||||
<SideDrawer
|
||||
metaItem={player.metaItem.content}
|
||||
seriesInfo={player.seriesInfo}
|
||||
className={classnames(styles['layer'], styles['side-drawer-layer'], { [styles['open']]: sideDrawerOpen })}
|
||||
closeSideBar={closeSideDrawer}
|
||||
sideDrawerOpen={sideDrawerOpen}
|
||||
/>
|
||||
</>
|
||||
: null
|
||||
}
|
||||
{
|
||||
subtitlesMenuOpen ?
|
||||
<SubtitlesMenu
|
||||
|
|
@ -746,17 +744,6 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
infoMenuOpen ?
|
||||
<InfoMenu
|
||||
className={classnames(styles['layer'], styles['menu-layer'])}
|
||||
stream={player.selected !== null ? player.selected.stream : null}
|
||||
addon={player.addon}
|
||||
metaItem={player.metaItem !== null && player.metaItem.type === 'Ready' ? player.metaItem.content : null}
|
||||
/>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
speedMenuOpen ?
|
||||
<SpeedMenu
|
||||
|
|
@ -767,16 +754,6 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
videosMenuOpen ?
|
||||
<VideosMenu
|
||||
className={classnames(styles['layer'], styles['menu-layer'])}
|
||||
metaItem={player.metaItem !== null && player.metaItem.type === 'Ready' ? player.metaItem.content : null}
|
||||
seriesInfo={player.seriesInfo}
|
||||
/>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
optionsMenuOpen ?
|
||||
<OptionsMenu
|
||||
|
|
|
|||
32
src/routes/Player/SideDrawer/SideDrawer.less
Normal file
32
src/routes/Player/SideDrawer/SideDrawer.less
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (C) 2017-2024 Smart code 203358507
|
||||
|
||||
.overlay {
|
||||
display: none;
|
||||
|
||||
&.open {
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.side-drawer {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
|
||||
.info {
|
||||
overflow: hidden;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: auto;
|
||||
max-height: 58%;
|
||||
}
|
||||
}
|
||||
106
src/routes/Player/SideDrawer/SideDrawer.tsx
Normal file
106
src/routes/Player/SideDrawer/SideDrawer.tsx
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import React from 'react';
|
||||
import MetaPreview from 'stremio/common/MetaPreview/MetaPreview';
|
||||
import Video from '../../MetaDetails/VideosList/Video/Video';
|
||||
import styles from './SideDrawer.less';
|
||||
import classNames from 'classnames';
|
||||
import { CONSTANTS } from 'stremio/common';
|
||||
import SeasonsBar from 'stremio/routes/MetaDetails/VideosList/SeasonsBar';
|
||||
|
||||
type Props = {
|
||||
seriesInfo: any;
|
||||
metaItem: MetaItem;
|
||||
className?: string;
|
||||
closeSideBar: () => void;
|
||||
sideDrawerOpen: boolean;
|
||||
};
|
||||
|
||||
const SideDrawer = ({ seriesInfo, className, closeSideBar, sideDrawerOpen, ...props }: Props) => {
|
||||
const [season, setSeason] = React.useState<number>(seriesInfo?.season);
|
||||
const metaItem = React.useMemo(() => {
|
||||
return props.metaItem !== null && Array.isArray(props.metaItem.videos) && seriesInfo ?
|
||||
{
|
||||
...props.metaItem,
|
||||
links: props.metaItem.links.filter(({ category }) => category === CONSTANTS.SHARE_LINK_CATEGORY)
|
||||
}
|
||||
:
|
||||
props.metaItem;
|
||||
}, [props.metaItem]);
|
||||
const videos = React.useMemo(() => {
|
||||
return props.metaItem && Array.isArray(props.metaItem.videos) ?
|
||||
props.metaItem.videos.filter((video) => video.season === season)
|
||||
:
|
||||
props.metaItem.videos;
|
||||
}, [props.metaItem, season]);
|
||||
const seasons = React.useMemo(() => {
|
||||
return props.metaItem && props.metaItem.videos
|
||||
.map(({ season }) => season)
|
||||
.filter((season, index, seasons) => {
|
||||
return season !== null && season !== undefined &&
|
||||
!isNaN(season) &&
|
||||
typeof season === 'number' &&
|
||||
seasons.indexOf(season) === index;
|
||||
})
|
||||
.sort((a, b) => (a || Number.MAX_SAFE_INTEGER) - (b || Number.MAX_SAFE_INTEGER));
|
||||
}, [props.metaItem.videos]);
|
||||
|
||||
const seasonOnSelect = React.useCallback((event: { value: string }) => {
|
||||
setSeason(parseInt(event.value));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={classNames(styles['overlay'], { [styles['open']]: sideDrawerOpen })} onClick={closeSideBar} />
|
||||
<div className={classNames(styles['side-drawer'], className)}>
|
||||
<div className={styles['info']}>
|
||||
{
|
||||
metaItem !== null ?
|
||||
<MetaPreview
|
||||
compact={true}
|
||||
name={metaItem.name}
|
||||
logo={metaItem.logo}
|
||||
runtime={metaItem.runtime}
|
||||
releaseInfo={metaItem.releaseInfo}
|
||||
released={metaItem.released}
|
||||
description={metaItem.description}
|
||||
links={metaItem.links}
|
||||
/>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
{
|
||||
videos !== null && seriesInfo ?
|
||||
<>
|
||||
<SeasonsBar
|
||||
season={season}
|
||||
seasons={seasons}
|
||||
onSelect={seasonOnSelect}
|
||||
/>
|
||||
<div className={styles['content']}>
|
||||
{videos.map((video, index) => (
|
||||
<Video
|
||||
key={index}
|
||||
className={styles['video']}
|
||||
id={video.id}
|
||||
title={video.title}
|
||||
thumbnail={video.thumbnail}
|
||||
episode={video.episode}
|
||||
released={video.released}
|
||||
upcoming={video.upcoming}
|
||||
watched={video.watched}
|
||||
progress={video.progress}
|
||||
deepLinks={video.deepLinks}
|
||||
scheduled={video.scheduled}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
: null
|
||||
}
|
||||
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SideDrawer;
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
|
||||
@import (reference) '~stremio/common/screen-sizes.less';
|
||||
|
||||
:import('~stremio/common/Slider/styles.less') {
|
||||
active-slider-within: active-slider-within;
|
||||
|
|
@ -112,5 +113,85 @@ html:not(.active-slider-within) {
|
|||
backdrop-filter: blur(15px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&.side-drawer-button {
|
||||
right: -4rem;
|
||||
top: 50%;
|
||||
left: initial;
|
||||
bottom: initial;
|
||||
height: 12.5rem;
|
||||
width: 7.5rem;
|
||||
transform: translateY(-50%);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--modal-background-color);
|
||||
cursor: pointer;
|
||||
border-top-left-radius: 50%;
|
||||
border-bottom-left-radius: 50%;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.icon {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
color: var(--primary-foreground-color);
|
||||
opacity: 0.6;
|
||||
margin-right: 4rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
&.open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.icon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.side-drawer-layer {
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: initial;
|
||||
bottom: initial;
|
||||
max-width: 30%;
|
||||
height: 100vh;
|
||||
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);
|
||||
overflow: visible;
|
||||
padding: 1rem;
|
||||
z-index: 1;
|
||||
transition: transform 0.3s ease-in-out;
|
||||
transform: translateX(100%);
|
||||
|
||||
&.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
@media screen and (max-width: @small) {
|
||||
max-width: 40%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: @xsmall) {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: @xxsmall) {
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: @minimum) {
|
||||
max-width: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
src/types/MetaItem.d.ts
vendored
2
src/types/MetaItem.d.ts
vendored
|
|
@ -15,7 +15,7 @@ type MetaItemPreview = {
|
|||
posterShape: PosterShape,
|
||||
releaseInfo: string | null,
|
||||
runtime: string | null,
|
||||
released: string | null,
|
||||
released: Date | null | undefined,
|
||||
trailerStreams: TrailerStream[],
|
||||
links: Link[],
|
||||
behaviorHints: BehaviorHints,
|
||||
|
|
|
|||
5
src/types/Video.d.ts
vendored
5
src/types/Video.d.ts
vendored
|
|
@ -14,4 +14,9 @@ type Video = {
|
|||
episode?: number,
|
||||
streams: Stream[],
|
||||
trailerStreams: TrailerStream[],
|
||||
watched: boolean,
|
||||
progress: number,
|
||||
upcoming: boolean,
|
||||
deepLinks: VideoDeepLinks,
|
||||
scheduled: boolean,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue