// Copyright (C) 2017-2023 Smart code 203358507 const React = require('react'); const PropTypes = require('prop-types'); const classnames = require('classnames'); const { useTranslation } = require('react-i18next'); const { default: Icon } = require('@stremio/stremio-icons/react'); const { Button, Image, MultiselectMenu } = require('stremio/components'); const { useServices } = require('stremio/services'); const Stream = require('./Stream'); const styles = require('./styles'); const { usePlatform, useProfile } = require('stremio/common'); const { default: SeasonEpisodePicker } = require('../EpisodePicker'); const ALL_ADDONS_KEY = 'ALL'; const StreamsList = ({ className, video, type, onEpisodeSearch, ...props }) => { const { t } = useTranslation(); const { core } = useServices(); const platform = usePlatform(); const profile = useProfile(); const streamsContainerRef = React.useRef(null); const [selectedAddon, setSelectedAddon] = React.useState(ALL_ADDONS_KEY); const onAddonSelected = React.useCallback((value) => { streamsContainerRef.current.scrollTo({ top: 0, left: 0, behavior: platform.name === 'ios' ? 'smooth' : 'instant' }); setSelectedAddon(value); }, [platform]); const showInstallAddonsButton = React.useMemo(() => { return !profile || profile.auth === null || profile.auth?.user?.isNewUser === true && !video?.upcoming; }, [profile, video]); const backButtonOnClick = React.useCallback(() => { if (video.deepLinks && typeof video.deepLinks.metaDetailsVideos === 'string') { window.location.replace(video.deepLinks.metaDetailsVideos + ( typeof video.season === 'number' ? `?${new URLSearchParams({ 'season': video.season })}` : null )); } else { window.history.back(); } }, [video]); const countLoadingAddons = React.useMemo(() => { return props.streams.filter((stream) => stream.content.type === 'Loading').length; }, [props.streams]); const streamsByAddon = React.useMemo(() => { return props.streams .filter((streams) => streams.content.type === 'Ready') .reduce((streamsByAddon, streams) => { streamsByAddon[streams.addon.transportUrl] = { addon: streams.addon, streams: streams.content.content.map((stream) => ({ ...stream, onClick: () => { core.transport.analytics({ event: 'StreamClicked', args: { stream } }); }, addonName: streams.addon.manifest.name })) }; return streamsByAddon; }, {}); }, [props.streams]); const filteredStreams = React.useMemo(() => { return selectedAddon === ALL_ADDONS_KEY ? Object.values(streamsByAddon).map(({ streams }) => streams).flat(1) : streamsByAddon[selectedAddon] ? streamsByAddon[selectedAddon].streams : []; }, [streamsByAddon, selectedAddon]); const selectableOptions = React.useMemo(() => { return { options: [ { value: ALL_ADDONS_KEY, label: t('ALL_ADDONS'), title: t('ALL_ADDONS') }, ...Object.keys(streamsByAddon).map((transportUrl) => ({ value: transportUrl, label: streamsByAddon[transportUrl].addon.manifest.name, title: streamsByAddon[transportUrl].addon.manifest.name, })) ], value: selectedAddon, onSelect: onAddonSelected }; }, [streamsByAddon, selectedAddon]); const handleEpisodePicker = React.useCallback((season, episode) => { onEpisodeSearch(season, episode); }, [onEpisodeSearch]); return (
{ video ?
{typeof video.season === 'number' && typeof video.episode === 'number' ? `S${video.season}E${video.episode}${video.title ? ` ${video.title}` : ''}` : (video.title ?? '')}
: null } { Object.keys(streamsByAddon).length > 1 ? : null }
{ props.streams.length === 0 ?
{ type === 'series' ? : null } {'
{t('ERR_NO_ADDONS_FOR_STREAMS')}
: props.streams.every((streams) => streams.content.type === 'Err') ?
{ type === 'series' ? : null } { video?.upcoming ?
{t('UPCOMING')}...
: null } {'
{t('NO_STREAM')}
{ showInstallAddonsButton ? : null }
: filteredStreams.length === 0 ?
:
{filteredStreams.map((stream, index) => ( ))} { showInstallAddonsButton ? : null }
{ countLoadingAddons > 0 ?
{countLoadingAddons} {t('MOBILE_ADDONS_LOADING')}
: null }
}
); }; StreamsList.propTypes = { className: PropTypes.string, streams: PropTypes.arrayOf(PropTypes.object).isRequired, video: PropTypes.object, type: PropTypes.string, onEpisodeSearch: PropTypes.func }; module.exports = StreamsList;