/* globals window document */ /* eslint-disable no-invalid-this */ import React from 'react'; import ListItem from './ListItem.jsx'; import ListItemSkeleton from './ListItemSkeleton.jsx'; export default class List extends React.Component { constructor() { super(); this.state = { servers: [], pageCount: 1, pageLimit: 10, activePage: 0, isLoading: true, hasMoreContent: true, }; this.changePage = this.changePage.bind(this); this.buildPages = this.buildPages.bind(this); } async componentWillReceiveProps(nextProps) { if (this.props.isShowcase) { this.setState({ servers: nextProps.servers, }); } if ((this.props.category !== nextProps.category) || (this.props.sort !== nextProps.sort) || (nextProps.search !== undefined) || (nextProps.searchQuery !== undefined)) { await this.reloadServers(); } } async reloadServers() { this.setState({ isLoading: true }); const serversInfo = await this.props.getPage(0, this.type); this.setState({ servers: serversInfo.servers || [], pageCount: serversInfo.pageCount, activePage: 0, isLoading: false, hasMoreContent: true, }); } async componentWillMount() { if (this.props.isShowcase) { this.setState({ servers: this.props.servers, isLoading: false, }); return; } if (this.props.featured) { this.type = 'featured'; } else if (this.props.premium) { this.type = 'premium'; } else if (this.props.search) { this.type = 'search'; window.onscroll = this.handleScroll; } else { this.type = 'regular'; } try { const serversInfo = await this.props.getPage(0, this.type); this.setState({ servers: serversInfo.servers || [], pageCount: serversInfo.pageCount, activePage: 0, isLoading: false, // We return at most 20 entires from the backend. Less than that means end of the list hasMoreContent: serversInfo.servers.length === 12, }); } catch (e) { this.setState({ error: 'Failed to load servers, try again later' }); } } handleScroll = () => { if (this.state.isLoading || !this.state.hasMoreContent || !this.props.pagination || !this.props.paginationInfiniteScroll) return; // Checks that the page has scrolled to the bottom if (window.innerHeight + document.documentElement.scrollTop >= document.documentElement.offsetHeight - 1) { this.changePage(this.state.activePage + 1); } }; async changePage(page) { this.setState({ isLoading: true, activePage: page }); if (this.type !== 'search' && !this.props.premium && !this.props.featured) { const elem = document.getElementsByClassName('server-list-wrapper premium')[0]; if (elem) { window.scrollBy({ top: elem.getBoundingClientRect().top + 50, behavior: 'smooth' }); } } const serversInfo = await this.props.getPage(page, this.type); let servers; serversInfo.servers = serversInfo.servers || []; if (this.type === 'search') { servers = this.state.servers.slice(0); servers.push(...serversInfo.servers); } else { servers = serversInfo.servers; } this.setState({ servers: servers, isLoading: false, // We return at most 20 entires from the backend. Less than that means end of the list hasMoreContent: serversInfo.servers.length === 12, }); } buildHeader() { return false; if (!this.props.search || this.props.isMainPage) return false; const premiumList = this.props.getPage(page, type, new Date().getTime())} pagination paginationCircles />; return (
{premiumList}
); } buildFooter() { if (!this.props.search) return false; if (this.state.hasMoreContent) return false; return (
); } buildPages() { let pages = [...Array(this.state.pageCount).keys()]; if (!this.props.paginationCircles && !this.props.paginationInfiniteScroll) { let { activePage, pageLimit, pageCount } = this.state; if (pageCount < pageLimit) { return ; } // Places the active page around the middle if possible let startPage = activePage - (pageLimit / 2); if (startPage < 0) { startPage = 0; } pages = []; let i = 0; if (activePage > (pageLimit / 2)) { pages.push((
  • 1
  • )); pages.push((
  • ...
  • )); } for (let i = 1; i <= pageLimit; i++) { let p = startPage + i; if (p > pageCount) { break; } pages.push((
  • {p}
  • )); } if (activePage < pageCount - (pageLimit / 2)) { pages.push((
  • ...
  • )); pages.push((
  • {pageCount}
  • )); } return ; } else if (this.props.paginationCircles) { return ( ); } else if (this.props.paginationInfiniteScroll) { if (this.state.isLoading) { return (
    ); } return false; } } render() { if (this.state.error) { return

    {this.state.error}

    ; } let title; let subTitle; let skeletonSize = 12; let additionalClasses = ''; if (this.props.featured) { additionalClasses += 'vertical '; skeletonSize = 4; title = 'Featured'; subTitle = 'Selected Dyno Server'; } else if (this.props.premium) { additionalClasses += 'premium '; skeletonSize = 3; title = 'Sponsored'; subTitle = 'Our recommended servers'; } else { additionalClasses += 'regular '; title = (this.props.isMainPage) ? 'Discord Servers' : 'All Servers'; subTitle = 'List of all discord servers'; } subTitle = ''; if (this.props.search) { skeletonSize = 0; title = 'Search Results'; } if (this.props.isShowcase) { title = ''; additionalClasses += 'showcase '; } let listNodes; if (this.state.isLoading && this.type !== 'search') { listNodes = []; for (let i = 0; i < skeletonSize; i++) { listNodes.push(()); } } else { listNodes = this.state.servers.map((server, index) => ); } return (
    {this.buildHeader()} { title &&

    {title}

    { !this.props.isShowcase &&

    {subTitle}

    }
    } {this.props.sortSelect}
    {listNodes}
    {this.props.pagination && } {this.buildFooter()}
    ); } }