From 8e5ff83f36c768e1553dd7b24e43cd8f94ef6172 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 27 Jun 2024 16:07:40 +0300 Subject: [PATCH] feature: season episode picker (1) --- src/routes/MetaDetails/MetaDetails.js | 3 ++ .../EpisodePicker/EpisodePicker.tsx | 36 +++++++++++++++++ .../StreamsList/EpisodePicker/index.ts | 4 ++ .../StreamsList/EpisodePicker/styles.less | 40 +++++++++++++++++++ .../MetaDetails/StreamsList/StreamsList.js | 39 +++++++++++++++--- 5 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 src/routes/MetaDetails/StreamsList/EpisodePicker/EpisodePicker.tsx create mode 100644 src/routes/MetaDetails/StreamsList/EpisodePicker/index.ts create mode 100644 src/routes/MetaDetails/StreamsList/EpisodePicker/styles.less diff --git a/src/routes/MetaDetails/MetaDetails.js b/src/routes/MetaDetails/MetaDetails.js index 084ca3f58..ffeb1670b 100644 --- a/src/routes/MetaDetails/MetaDetails.js +++ b/src/routes/MetaDetails/MetaDetails.js @@ -160,7 +160,10 @@ const MetaDetails = ({ urlParams, queryParams }) => { streamPath !== null ? : diff --git a/src/routes/MetaDetails/StreamsList/EpisodePicker/EpisodePicker.tsx b/src/routes/MetaDetails/StreamsList/EpisodePicker/EpisodePicker.tsx new file mode 100644 index 000000000..252b6bec3 --- /dev/null +++ b/src/routes/MetaDetails/StreamsList/EpisodePicker/EpisodePicker.tsx @@ -0,0 +1,36 @@ +// Copyright (C) 2017-2024 Smart code 203358507 + +import { Multiselect } from 'stremio/common'; +import React from 'react'; +import styles from './styles.less'; +import { useTranslation } from 'react-i18next'; + +type Props = { + video: Video; + metaItem: MetaItem; + seasonOnSelect: (season: number) => void, + season: number, +}; + +const EpisodePicker = (props: Props) => { + const { t } = useTranslation(); + + console.log(props.season); + + // const options = props.metaItem;; + + return ( +
+ 0 ? `${t('SEASON')} ${props.season}` : t('SPECIAL')} + direction={'bottom-left'} + // options={options} + // selected={selectedOption} + onSelect={props.seasonOnSelect} + /> +
+ ); +}; + +export default EpisodePicker; \ No newline at end of file diff --git a/src/routes/MetaDetails/StreamsList/EpisodePicker/index.ts b/src/routes/MetaDetails/StreamsList/EpisodePicker/index.ts new file mode 100644 index 000000000..7444a65f7 --- /dev/null +++ b/src/routes/MetaDetails/StreamsList/EpisodePicker/index.ts @@ -0,0 +1,4 @@ +// Copyright (C) 2017-2024 Smart code 203358507 + +import EpisodePicker from './EpisodePicker'; +export default EpisodePicker; \ No newline at end of file diff --git a/src/routes/MetaDetails/StreamsList/EpisodePicker/styles.less b/src/routes/MetaDetails/StreamsList/EpisodePicker/styles.less new file mode 100644 index 000000000..e4331c875 --- /dev/null +++ b/src/routes/MetaDetails/StreamsList/EpisodePicker/styles.less @@ -0,0 +1,40 @@ +// Copyright (C) 2017-2024 Smart code 203358507 + +@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; +@import (reference) '~stremio/common/screen-sizes.less'; + +:import('~stremio/common/Multiselect/styles.less') { + multiselect-menu-container: menu-container; + multiselect-label: label; + multiselect-icon: icon; +} + +.episode-selector-container { + display: flex; + flex-direction: row; + align-items: center; + padding: 1rem; + overflow: visible; + + .label-container { + flex: 0 1 auto; + background: none; + + &:hover, &:focus, &:global(.active) { + background-color: var(--overlay-color); + } + + &>.multiselect-label { + color: var(--primary-foreground-color); + } + + &>.multiselect-icon { + color: var(--primary-foreground-color); + } + + .multiselect-menu-container { + max-height: calc(3.2rem * 7); + overflow: auto; + } + } +} \ No newline at end of file diff --git a/src/routes/MetaDetails/StreamsList/StreamsList.js b/src/routes/MetaDetails/StreamsList/StreamsList.js index ae7d2416e..acf167a8b 100644 --- a/src/routes/MetaDetails/StreamsList/StreamsList.js +++ b/src/routes/MetaDetails/StreamsList/StreamsList.js @@ -9,13 +9,31 @@ const { Button, Image, Multiselect } = require('stremio/common'); const { useServices } = require('stremio/services'); const Stream = require('./Stream'); const styles = require('./styles'); +const { default: EpisodePicker } = require('./EpisodePicker'); const ALL_ADDONS_KEY = 'ALL'; -const StreamsList = ({ className, video, ...props }) => { +const StreamsList = ({ className, video, metaItem, ...props }) => { const { t } = useTranslation(); const { core } = useServices(); const [selectedAddon, setSelectedAddon] = React.useState(ALL_ADDONS_KEY); + const videos = React.useMemo(() => { + return metaItem && metaItem.content.type === 'Ready' ? + metaItem.content.content.videos + : + []; + }, [metaItem]); + const seasons = React.useMemo(() => { + return videos + .map(({ season }) => season) + .filter((season, index, seasons) => { + return season !== null && + !isNaN(season) && + typeof season === 'number' && + seasons.indexOf(season) === index; + }) + .sort((a, b) => (a || Number.MAX_SAFE_INTEGER) - (b || Number.MAX_SAFE_INTEGER)); + }, [videos]); const onAddonSelected = React.useCallback((event) => { setSelectedAddon(event.value); }, []); @@ -86,10 +104,18 @@ const StreamsList = ({ className, video, ...props }) => { : props.streams.every((streams) => streams.content.type === 'Err') ? -
- {' -
{t('NO_STREAM')}
-
+ + +
+ {' +
{t('NO_STREAM')}
+
+
: filteredStreams.length === 0 ?
@@ -162,6 +188,9 @@ const StreamsList = ({ className, video, ...props }) => { StreamsList.propTypes = { className: PropTypes.string, streams: PropTypes.arrayOf(PropTypes.object).isRequired, + metaItem: PropTypes.object, + season: PropTypes.number, + seasonOnSelect: PropTypes.func, video: PropTypes.object };