import React from "react"; import ReactDOM from "react-dom"; import lbryuri from "lbryuri"; import FileCard from "component/fileCard"; import { Icon, BusyMessage } from "component/common.js"; import ToolTip from "component/tooltip.js"; class FeaturedCategory extends React.PureComponent { componentWillMount() { this.setState({ numItems: this.props.names.length, canScrollPrevious: false, canScrollNext: true, }); } handleScrollPrevious() { const cardRow = ReactDOM.findDOMNode(this.refs.rowitems); if (cardRow.scrollLeft > 0) { // check the visible cards const cards = cardRow.getElementsByTagName("section"); let firstVisibleCard = null; let firstVisibleIdx = -1; for (var i = 0; i < cards.length; i++) { if (this.isCardVisible(cards[i], cardRow, false)) { firstVisibleCard = cards[i]; firstVisibleIdx = i; break; } } const numDisplayed = this.numDisplayedCards(cardRow); const scrollToIdx = firstVisibleIdx - numDisplayed; const animationCallback = () => { this.setState({ canScrollPrevious: cardRow.scrollLeft !== 0, canScrollNext: true, }); }; this.scrollCardItemsLeftAnimated( cardRow, scrollToIdx < 0 ? 0 : cards[scrollToIdx].offsetLeft, 100, animationCallback ); } } handleScrollNext() { const cardRow = ReactDOM.findDOMNode(this.refs.rowitems); // check the visible cards const cards = cardRow.getElementsByTagName("section"); let lastVisibleCard = null; let lastVisibleIdx = -1; for (var i = 0; i < cards.length; i++) { if (this.isCardVisible(cards[i], cardRow, true)) { lastVisibleCard = cards[i]; lastVisibleIdx = i; } } if (lastVisibleCard) { const numDisplayed = this.numDisplayedCards(cardRow); const animationCallback = () => { // update last visible index after scroll for (var i = 0; i < cards.length; i++) { if (this.isCardVisible(cards[i], cardRow, true)) { lastVisibleIdx = i; } } this.setState({ canScrollPrevious: true }); if (lastVisibleIdx === cards.length - 1) { this.setState({ canScrollNext: false }); } }; this.scrollCardItemsLeftAnimated( cardRow, Math.min( lastVisibleCard.offsetLeft, cardRow.scrollWidth - cardRow.clientWidth ), 100, animationCallback ); } } scrollCardItemsLeftAnimated(cardRow, target, duration, callback) { if (!duration || duration <= diff) { cardRow.scrollLeft = target; if (callback) { callback(); } return; } const component = this; const diff = target - cardRow.scrollLeft; const tick = diff / duration * 10; setTimeout(() => { cardRow.scrollLeft = cardRow.scrollLeft + tick; if (cardRow.scrollLeft === target) { if (callback) { callback(); } return; } component.scrollCardItemsLeftAnimated( cardRow, target, duration - 10, callback ); }, 10); } isCardVisible(section, cardRow, partialVisibility) { // check if a card is fully or partialy visible in its parent const cardRowWidth = cardRow.offsetWidth; const cardRowLeft = cardRow.scrollLeft; const cardRowEnd = cardRowLeft + cardRow.offsetWidth; const sectionLeft = section.offsetLeft - cardRowLeft; const sectionEnd = sectionLeft + section.offsetWidth; return ( (sectionLeft >= 0 && sectionEnd <= cardRowWidth) || (((sectionLeft < 0 && sectionEnd > 0) || (sectionLeft > 0 && sectionLeft <= cardRowWidth)) && partialVisibility) ); } numDisplayedCards(cardRow) { const cards = cardRow.getElementsByTagName("section"); const cardRowWidth = cardRow.offsetWidth; // get the width of the first card and then calculate const cardWidth = cards.length > 0 ? cards[0].offsetWidth : 0; if (cardWidth > 0) { return Math.ceil(cardRowWidth / cardWidth); } // return a default value of 1 card displayed if the card width couldn't be determined return 1; } render() { const { category, names } = this.props; return (