import POGOProtos from 'pogo-protos'; import React from 'react'; import { ContentRect, default as Measure } from 'react-measure'; import { Link } from 'react-router-dom'; import { VariableSizeList } from 'react-window'; import classNames from 'classnames'; import { formatDexNumber, formatForm } from 'app/utils/formatter'; import { appendQueryString } from 'app/utils/navigation'; import { DEFAULT_POKEMON_NAME, IPokemon } from 'app/models/Pokemon'; import * as styles from './styles/PokemonSelectList.scss'; export interface IPokemonSelectListProps { isLoading : boolean; activePokemonId : POGOProtos.Enums.PokemonId | null; activePokemonForm : POGOProtos.Enums.Form | null; pokemonList : Array; filterTerm : string; handleActivatePokemon : (pokemonId : POGOProtos.Enums.PokemonId, form : POGOProtos.Enums.Form) => void; handleChangeFilter : (filterTerm : string) => Promise; } interface IState { dimensions : { width : number; height : number; }; } interface IRowFactory { index : number; style : React.CSSProperties; } export class PokemonSelectList extends React.Component { private listRef : React.RefObject; constructor(props : IPokemonSelectListProps) { super(props); this.state = { dimensions: { width: -1, height: -1, } }; this.listRef = React.createRef(); } public render() { const { width, height } = this.state.dimensions; const listLength = this.props.pokemonList.length; const onResize = (contentRect : ContentRect) => { if (typeof contentRect.bounds !== 'undefined') { this.setState({ dimensions: contentRect.bounds }); } }; const wrapperCss = classNames( styles.leftPanel, { loading: this.props.isLoading, } ); const listWrapperCss = classNames( 'nes-container', styles.listWrapper, { [ styles.emptyList ]: listLength === 0 } ); const inputTextCss = classNames( 'nes-input', styles.filterInput ); return (
{ this.props.filterTerm !== '' && }
{ listLength > 0 && { ({ measureRef }) => (
{ this.rowFactory.bind(this) }
) }
} { listLength === 0 && this.props.filterTerm !== '' &&

{ DEFAULT_POKEMON_NAME }

}
); } private readonly getListItemKey = (index : number) => { const { pokemonList } = this.props; const pokemon = pokemonList[index]; return `${index}-${pokemon.id}-${pokemon.form}`; } private readonly calculateRowHeight = (index : number) => { return this.props.pokemonList[index].form === POGOProtos.Enums.Form.FORM_UNSET ? 25 : 40; } private rowFactory({ index, style } : IRowFactory) { const pokemon = this.props.pokemonList[index]; const dex = formatDexNumber(pokemon.dex); const anchorCss = classNames( 'list-item', { active: this.props.activePokemonId === pokemon.id && this.props.activePokemonForm === pokemon.form } ); // const menuIconCss = classNames( // styles.menuIcon, // 'menu', // `pokemon-${dex}` // ); const dexCss = classNames( 'de-emphasize', styles.dex ); const formCss = classNames( 'de-emphasize', styles.form ); const onClick = () => this.props.handleActivatePokemon(pokemon.id, pokemon.form); const linkTo = { // pathname: '/courses', search: appendQueryString(location, { id: pokemon.id.toString(), form: pokemon.form.toString(), }), // hash: '#the-hash', // state: { fromDashboard: true } }; return ( { pokemon.name } #{ dex } { /* */ } { pokemon.form !== POGOProtos.Enums.Form.FORM_UNSET && { formatForm(pokemon.form) } Form } ); } private readonly handleChangeFilter = (event : React.ChangeEvent) => { this.props.handleChangeFilter(event.currentTarget.value) .then(() => { if (this.listRef.current !== null) { this.listRef.current.resetAfterIndex(0, true); } }); } private readonly handleClickClearFilter = () => { this.props.handleChangeFilter('') .then(() => { if (this.listRef.current !== null) { this.listRef.current.resetAfterIndex(0, true); } }); } }