// @flow import { FieldTextStateless } from '@atlaskit/field-text'; import React, { Component } from 'react'; import { connect } from 'react-redux'; import type { Dispatch } from 'redux'; import config from '../../config'; import { getExternalApiURL } from '../../utils'; import { setServerURL } from '../actions'; type Props = { /** * Redux dispatch. */ dispatch: Dispatch<*>; /** * Default Jitsi Meet Server URL in (redux) store. */ _serverURL: string; }; type State = { /** * Whether the url of the Jitsi Meet Server valid. */ isValid: boolean; /** * Default Jitsi Meet Server URL in (local) state. */ serverURL: string; }; /** * Default Server URL field text placed in the Settings drawer. */ class ServerURLField extends Component<Props, State> { /** * Initializes a new {@code ServerURLField} instance. * * @inheritdoc */ constructor(props) { super(props); this.state = { isValid: true, serverURL: '' }; this._onServerURLChange = this._onServerURLChange.bind(this); this._onServerURLSubmit = this._onServerURLSubmit.bind(this); } /** * This updates the Server URL in (local) state when there is a change * in redux store. * * @param {Props} props - New props of the component. * @returns {State} - New state of the component. */ static getDerivedStateFromProps(props) { return { serverURL: props._serverURL }; } /** * Render function of component. * * @returns {ReactElement} */ render() { return ( <form onSubmit = { this._onServerURLSubmit }> <FieldTextStateless invalidMessage = { 'Invalid Server URL' } isInvalid = { !this.state.isValid } isValidationHidden = { this.state.isValid } label = 'Server URL' onBlur = { this._onServerURLSubmit } onChange = { this._onServerURLChange } placeholder = { config.defaultServerURL } shouldFitContainer = { true } type = 'text' value = { this.state.serverURL } /> </form> ); } _onServerURLChange: (*) => void; /** * Updates Server URL in (redux) state when it is updated. * * @param {SyntheticInputEvent<HTMLInputElement>} event - Event by which * this function is called. * @returns {void} */ _onServerURLChange(event: SyntheticInputEvent<HTMLInputElement>) { this.setState({ serverURL: event.currentTarget.value }, this._validateServerURL); } _onServerURLSubmit: (*) => void; /** * Updates Server URL in (redux) store when it is updated. * * @param {Event} event - Event by which this function is called. * @returns {void} */ _onServerURLSubmit(event: Event) { event.preventDefault(); if (this.state.isValid) { this.props.dispatch(setServerURL(this.state.serverURL)); } } /** * Validates the Server URL by fetching external_api.js using the HEAD * method. * * @returns {void} */ _validateServerURL() { fetch(getExternalApiURL(this.state.serverURL), { method: 'HEAD' }) .then((response: Object) => { this.setState({ isValid: response.ok }); }) .catch(() => { this.setState({ isValid: false }); }); } } /** * Maps (parts of) the redux store to the React props. * * @param {Object} state - The redux state. * @returns {{ * _serverURL: string * }} */ function _mapStateToProps(state: Object) { return { _serverURL: state.settings.serverURL }; } export default connect(_mapStateToProps)(ServerURLField);