// Copyright (C) 2017-2023 Smart code 203358507 const React = require('react'); const { useTranslation } = require('react-i18next'); const PropTypes = require('prop-types'); const classnames = require('classnames'); const { default: Icon } = require('@stremio/stremio-icons/react'); const { useServices } = require('stremio/services'); const { CONSTANTS, useBinaryState, useOnScrollToBottom, withCoreSuspender } = require('stremio/common'); const { AddonDetailsModal, Button, DelayedRenderer, Image, MainNavBars, MetaItem, MetaPreview, Multiselect, ModalDialog } = require('stremio/components'); const useDiscover = require('./useDiscover'); const useSelectableInputs = require('./useSelectableInputs'); const styles = require('./styles'); const SCROLL_TO_BOTTOM_THRESHOLD = 400; const Discover = ({ urlParams, queryParams }) => { const { t } = useTranslation(); const { core } = useServices(); const [discover, loadNextPage] = useDiscover(urlParams, queryParams); const [selectInputs, hasNextPage] = useSelectableInputs(discover); const [inputsModalOpen, openInputsModal, closeInputsModal] = useBinaryState(false); const [addonModalOpen, openAddonModal, closeAddonModal] = useBinaryState(false); const [selectedMetaItemIndex, setSelectedMetaItemIndex] = React.useState(0); const metasContainerRef = React.useRef(); const metaPreviewRef = React.useRef(); React.useEffect(() => { if (discover.catalog?.content.type === 'Loading') { metasContainerRef.current.scrollTop = 0; } }, [discover.catalog]); React.useEffect(() => { if (hasNextPage && metasContainerRef.current) { const containerHeight = metasContainerRef.current.scrollHeight; const viewportHeight = metasContainerRef.current.clientHeight; if (containerHeight <= viewportHeight + SCROLL_TO_BOTTOM_THRESHOLD) { loadNextPage(); } } }, [hasNextPage, loadNextPage]); const selectedMetaItem = React.useMemo(() => { return discover.catalog !== null && discover.catalog.content.type === 'Ready' && discover.catalog.content.content[selectedMetaItemIndex] ? discover.catalog.content.content[selectedMetaItemIndex] : null; }, [discover.catalog, selectedMetaItemIndex]); const addToLibrary = React.useCallback(() => { if (selectedMetaItem === null) { return; } core.transport.dispatch({ action: 'Ctx', args: { action: 'AddToLibrary', args: selectedMetaItem } }); }, [selectedMetaItem]); const removeFromLibrary = React.useCallback(() => { if (selectedMetaItem === null) { return; } core.transport.dispatch({ action: 'Ctx', args: { action: 'RemoveFromLibrary', args: selectedMetaItem.id } }); }, [selectedMetaItem]); const metaItemsOnFocusCapture = React.useCallback((event) => { if (event.target.dataset.index !== null && !isNaN(event.target.dataset.index)) { setSelectedMetaItemIndex(parseInt(event.target.dataset.index, 10)); } }, []); const metaItemOnClick = React.useCallback((event) => { const visible = window.getComputedStyle(metaPreviewRef.current).display !== 'none'; if (event.currentTarget.dataset.index !== selectedMetaItemIndex.toString() && visible) { event.preventDefault(); event.currentTarget.focus(); } }, [selectedMetaItemIndex]); const onScrollToBottom = React.useCallback(() => { if (hasNextPage) { loadNextPage(); } }, [hasNextPage, loadNextPage]); const onScroll = useOnScrollToBottom(onScrollToBottom, SCROLL_TO_BOTTOM_THRESHOLD); React.useEffect(() => { closeInputsModal(); closeAddonModal(); setSelectedMetaItemIndex(0); }, [discover.selected]); return (
{selectInputs.map(({ title, options, selected, renderLabelText, onSelect }, index) => ( ))}
{ discover.catalog !== null && !discover.catalog.installed ?
{t('ERR_ADDON_NOT_INSTALLED')}
: null } { discover.catalog === null ?
{'
{t('NO_CATALOG_SELECTED')}
: discover.catalog.content.type === 'Err' ?
{'
{discover.catalog.content.content}
: discover.catalog.content.type === 'Loading' ?
{Array(CONSTANTS.CATALOG_PAGE_SIZE).fill(null).map((_, index) => (
))}
:
{discover.catalog.content.content.map((metaItem, index) => ( ))}
}
{ selectedMetaItem !== null ? : discover.catalog !== null && discover.catalog.content.type === 'Loading' ?
: null }
{ inputsModalOpen ? {selectInputs.map(({ title, options, selected, renderLabelText, onSelect }, index) => ( ))} : null } { addonModalOpen && discover.selected !== null ? : null } ); }; Discover.propTypes = { urlParams: PropTypes.shape({ transportUrl: PropTypes.string, type: PropTypes.string, catalogId: PropTypes.string }), queryParams: PropTypes.instanceOf(URLSearchParams) }; const DiscoverFallback = () => ( ); module.exports = withCoreSuspender(Discover, DiscoverFallback);