diff --git a/package-lock.json b/package-lock.json index 22ee4ee2b..404cca9a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nuzlocke-generator", - "version": "1.3.1", + "version": "1.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -5672,6 +5672,19 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" }, + "@react-hook/debounce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@react-hook/debounce/-/debounce-3.0.0.tgz", + "integrity": "sha512-ir/kPrSfAzY12Gre0sOHkZ2rkEmM4fS5M5zFxCi4BnCeXh2nvx9Ujd+U4IGpKCuPA+EQD0pg1eK2NGLvfWejag==", + "requires": { + "@react-hook/latest": "^1.0.2" + } + }, + "@react-hook/latest": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz", + "integrity": "sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==" + }, "@rollup/plugin-node-resolve": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", diff --git a/package.json b/package.json index 650349b9f..47b844906 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nuzlocke-generator", - "version": "1.4.0", + "version": "1.4.1", "description": "A tool for generating nuzlocke team pics from data", "main": "dist/bundle.js", "scripts": { @@ -33,6 +33,7 @@ "license": "MIT", "dependencies": { "@emmaramirez/dom-to-image": "^3.0.2", + "@react-hook/debounce": "^3.0.0", "@types/chalk": "^2.2.0", "@types/color": "^3.0.0", "@types/cypress": "^1.1.3", diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx index 643acced9..775c0dac2 100644 --- a/src/components/App/App.tsx +++ b/src/components/App/App.tsx @@ -52,8 +52,10 @@ export class UpdaterBase extends React.Component<{ this.props.present != null && !isEqual(this.props.present, prev.present) ) { - console.log(this.props.lrt, prev.lrt); + const t0 = performance.now(); this.props.updateEditorHistory(prev.present); + const t1 = performance.now(); + console.log(`Updated history in ${t1 - t0}ms`); } } diff --git a/src/components/PokemonEditor/CurrentPokemonEdit.tsx b/src/components/PokemonEditor/CurrentPokemonEdit.tsx index 5ee909ec9..b0ebc2617 100644 --- a/src/components/PokemonEditor/CurrentPokemonEdit.tsx +++ b/src/components/PokemonEditor/CurrentPokemonEdit.tsx @@ -423,6 +423,15 @@ CurrentPokemonEditState + {/**/} string; disabled?: boolean; options?: string[] | { key: string; value: string | null }[]; - editPokemon: editPokemon; - selectedId: string; - selectPokemon: selectPokemon; pokemon?: Pokemon; - customMoveMap: State['customMoveMap']; usesKeyValue?: boolean; - customTypes: State['customTypes']; + className?: string; + items?: string[]; } -export class CurrentPokemonInputBase extends React.Component< -CurrentPokemonInputProps> { - public constructor(props: CurrentPokemonInputProps) { - super(props); +// selectedId: state.selectedId, +// customMoveMap: state.customMoveMap, +// customTypes: state.customTypes, +// }), +// { editPokemon, selectPokemon }, + +interface ChangeArgs { + inputName: CurrentPokemonInputProps['inputName']; + position?: number; + value?: any; + pokemon?: Pokemon; + edit: { [x: string]: any }; +} + +const createEdit = ({ inputName, value, pokemon, edit }: ChangeArgs) => { + if (inputName === 'species') { + return { + ...edit, + types: matchSpeciesToTypes(edit['species']) + }; + } else if (inputName === 'nature' && pokemon?.species === 'Toxtricity') { + return { + ...edit, + forme: matchNatureToToxtricityForme(value), + }; + } else if (inputName === 'forme') { + return { + ...edit, + types: pokemon && matchSpeciesToTypes(pokemon?.species, value) + }; } - public static defaultProps = { - disabled: false, - }; + return edit; +}; - public onChange = ( - inputName, - { position, value, pokemon }: { position?: number; value?: any; pokemon?: Pokemon } = {}, - ) => (e: React.ChangeEvent & { target: { value: any; checked?: boolean } }) => { - e.persist(); - let edit; +export type InputTypesFromState = Partial< +Pick +>; +export type InputTypesFromActions = {}; +export type InputTypesFromInternalState = { + setEdit: React.Dispatch< + React.SetStateAction<{ + [x: string]: any; + }> + >; + edit: { [x: string]: any }; + onChange: (event: React.ChangeEvent) => void; +}; +export type PokemonInputProps = CurrentPokemonInputProps & +InputTypesFromState & +InputTypesFromInternalState; - if (inputName === 'types' && position != null) { - edit = { - [inputName]: value, - }; - edit[inputName][position] = e.target.value; - } else if (inputName === 'species') { - edit = { - [inputName]: e.target.value, - types: matchSpeciesToTypes(e.target.value), - }; - } else if (inputName === 'nature' && pokemon?.species === 'Toxtricity') { - edit = { - [inputName]: e.target.value, - forme: matchNatureToToxtricityForme(e.target.value), - }; - } else if (inputName === 'moves') { - edit = { - [inputName]: e.target.value, - }; - } else if ( - inputName === 'champion' || - inputName === 'shiny' || - inputName === 'hidden' || - inputName === 'mvp' - ) { - edit = { - [inputName]: e.target.checked, - }; - } else if (inputName === 'egg') { - edit = { - [inputName]: e.target.checked, - }; - } else if (inputName === 'forme') { - edit = { - forme: e.target.value, - types: pokemon && matchSpeciesToTypes(pokemon?.species, e.target.value), - }; - } else { - edit = { - [inputName]: e.target.value, - }; - } +export const renderItems = (visibleItems, setSelectedItem) => ( + visibleItems.map((v, i) => { + return ( +
  • setSelectedItem(v)} + style={v === this.state.currentValue ? { color: 'lightblue' } : {}}> + {v} +
  • + ); + }) +); - this.props.editPokemon(edit, this.props.selectedId); - }; +export function PokemonAutocompleteInput({ + className, + placeholder, + inputName, + edit, + disabled, + onChange, + setEdit, + items, +}: PokemonInputProps) { + const [isOpen, setIsOpen] = React.useState(false); + const [visibleItems, setVisibleItems] = React.useState(items); + const [selectedItem, setSelectedItem] = React.useState(); + const handleKeyDown = () => {}; + const updateItems = () => {}; + const closeList = () => {}; + const openList = () => {}; - public getInput({ - labelName, - usesKeyValue, - disabled, - inputName, - type, - value, - placeholder, - options, - pokemon, - }: { - labelName?: CurrentPokemonInputProps['labelName']; - usesKeyValue?: boolean; - disabled?: boolean; - inputName?: CurrentPokemonInputProps['inputName']; - type: string; - value: any; - placeholder?: string; - options?: any[]; - pokemon?: Pokemon; - }) { - const { customMoveMap, customTypes } = this.props; - value = value ?? ''; - if (type === 'moves') { - return ( - - { - // @TODO: Fix inconsitencies with bad parameter types - const background = - typeToColor( - // @ts-ignore - customMoveMap.find((m) => m?.move === v)?.type || - getMoveType(v?.toString()?.trim() || ''), - customTypes, - ) || 'transparent'; - const color = getContrastColor(background); - return { - style: { - background, - color, - }, - }; - }} - onChange={(values) => { - const edit = { - moves: values, - }; - this.props.editPokemon(edit, this.props.selectedId); - }} - values={value || []} - /> - - ); - } - if (type === 'text') { - return ( - - ); - } - if (type === 'textArea') { - return ( -