diff --git a/src/react-components/name-entry-panel.js b/src/react-components/name-entry-panel.js new file mode 100644 index 0000000000000000000000000000000000000000..fb0022efc02e8694d11beafdef83198399db94bf --- /dev/null +++ b/src/react-components/name-entry-panel.js @@ -0,0 +1,48 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { SCHEMA } from "../storage/store"; + +export default class NameEntryPanel extends Component { + static propTypes = { + store: PropTypes.object + } + + constructor(props) { + super(props); + window.store = this.props.store; + this.state = {name: this.props.store.state.profile.display_name}; + this.props.store.subscribe(() => { + this.setState({name: this.props.store.state.profile.display_name}); + }); + } + + saveName = (e) => { + e.preventDefault(); + this.props.store.update({ profile: { display_name: this.nameInput.value } }); + } + + componentDidMount() { + // stop propagation so that avatar doesn't move when wasd'ing during text input. + this.nameInput.addEventListener('keydown', e => e.stopPropagation()); + this.nameInput.addEventListener('keypress', e => e.stopPropagation()); + this.nameInput.addEventListener('keyup', e => e.stopPropagation()); + } + + render () { + return ( + <div> + Name Entry + <form onSubmit={this.saveName}> + <label>Name: + <input + value={this.state.name} onChange={(e) => this.setState({name: e.target.value})} + required pattern={SCHEMA.definitions.profile.properties.display_name.pattern} + title="Alphanumerics and hyphens. At least 3 characters, no more than 32" + ref={inp => this.nameInput = inp}/> + </label> + <input type="submit" value="Save" /> + </form> + </div> + ); + } +} diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js index 1d95826d766237291daeb68ee697fc5adca700d1..0fdeb428826e1616884a8d3f62db8353a41e4e9a 100644 --- a/src/react-components/ui-root.js +++ b/src/react-components/ui-root.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { VR_DEVICE_AVAILABILITY } from "../utils/vr-caps-detect.js"; +import NameEntryPanel from './name-entry-panel'; +import { VR_DEVICE_AVAILABILITY } from "../utils/vr-caps-detect"; import queryString from "query-string"; import { SCHEMA } from "../storage/store"; const { detect } = require("detect-browser"); @@ -346,11 +347,6 @@ class UIRoot extends Component { this.setState({ entryStep: ENTRY_STEPS.finished }); } - saveName = (e) => { - e.preventDefault(); - this.props.store.update({ profile: { display_name: this.nameInput.value } }); - } - render() { if (!this.state.sceneLoaded) { return ( @@ -398,22 +394,6 @@ class UIRoot extends Component { </div> ) : null; - const nameEntryPanel = ( - <div> - Name Entry - <form onSubmit={this.saveName}> - <label>Name: - <input - defaultValue={this.props.store.state.profile.display_name} - required pattern={SCHEMA.definitions.profile.properties.display_name.pattern} - title="Alphanumerics and hyphens. At least 3 characters, no more than 32" - ref={inp => this.nameInput = inp}/> - </label> - <input type="submit" value="Save" /> - </form> - </div> - ); - const overlay = this.isWaitingForAutoExit() ? (<AutoExitWarning secondsRemaining={this.state.secondsRemainingBeforeAutoExit} onCancel={this.endAutoExitTimer} />) : ( @@ -422,7 +402,7 @@ class UIRoot extends Component { {micPanel} {audioSetupPanel} - {nameEntryPanel} + <NameEntryPanel store={this.props.store}></NameEntryPanel> </div> );