Refactored UrlMenu component from class-based to functional

This commit is contained in:
Przemek Wiech
2021-11-03 09:34:36 +01:00
parent 60aa526e62
commit be3592f51b

View File

@@ -1,75 +1,45 @@
import * as queryString from 'query-string'; import * as queryString from 'query-string';
import * as React from 'react';
import {analyticsEvent} from '../util/analytics'; import {analyticsEvent} from '../util/analytics';
import {Button, Form, Header, Icon, Input, Modal} from 'semantic-ui-react'; import {Button, Form, Header, Icon, Input, Modal} from 'semantic-ui-react';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import {MenuItem, MenuType} from './menu_item'; import {MenuItem, MenuType} from './menu_item';
import {RouteComponentProps} from 'react-router-dom'; import {RouteComponentProps} from 'react-router-dom';
import {useEffect, useRef, useState} from 'react';
interface Props { interface Props {
menuType: MenuType; menuType: MenuType;
} }
interface State {
dialogOpen: boolean;
url?: string;
}
/** Displays and handles the "Open URL" menu. */ /** Displays and handles the "Open URL" menu. */
export class UrlMenu extends React.Component< export function UrlMenu(props: RouteComponentProps & Props) {
RouteComponentProps & Props, const [dialogOpen, setDialogOpen] = useState(false);
State const [url, setUrl] = useState('');
> { const inputRef = useRef<Input>(null);
state: State = {dialogOpen: false};
inputRef: React.RefObject<Input> = React.createRef(); useEffect(() => {
if (dialogOpen) {
/** Opens the "Load from URL" dialog. */ setUrl('');
private openDialog() { inputRef.current!.focus();
this.setState(Object.assign({}, this.state, {dialogOpen: true}), () =>
this.inputRef.current!.focus(),
);
}
/** Cancels any of the open dialogs. */
private handleClose() {
this.setState(
Object.assign({}, this.state, {
dialogOpen: false,
}),
);
} }
}, [dialogOpen]);
/** Load button clicked in the "Load from URL" dialog. */ /** Load button clicked in the "Load from URL" dialog. */
private handleLoad() { function handleLoad() {
this.setState( setDialogOpen(false);
Object.assign({}, this.state, { if (url) {
dialogOpen: false,
}),
);
if (this.state.url) {
analyticsEvent('url_selected'); analyticsEvent('url_selected');
this.props.history.push({ props.history.push({
pathname: '/view', pathname: '/view',
search: queryString.stringify({url: this.state.url}), search: queryString.stringify({url}),
}); });
} }
} }
/** Called when the URL input is typed into. */ function loadFromUrlModal() {
private handleUrlChange(value: string) {
this.setState(
Object.assign({}, this.state, {
url: value,
}),
);
}
private loadFromUrlModal() {
return ( return (
<Modal <Modal
open={this.state.dialogOpen} open={dialogOpen}
onClose={() => this.handleClose()} onClose={() => setDialogOpen(false)}
centered={false} centered={false}
> >
<Header> <Header>
@@ -80,12 +50,13 @@ export class UrlMenu extends React.Component<
/> />
</Header> </Header>
<Modal.Content> <Modal.Content>
<Form onSubmit={() => this.handleLoad()}> <Form onSubmit={handleLoad}>
<Input <Input
placeholder="https://" placeholder="https://"
fluid fluid
onChange={(e, data) => this.handleUrlChange(data.value)} value={url}
ref={this.inputRef} onChange={(_, data) => setUrl(data.value)}
ref={inputRef}
/> />
<p> <p>
<FormattedMessage <FormattedMessage
@@ -105,13 +76,13 @@ export class UrlMenu extends React.Component<
</Form> </Form>
</Modal.Content> </Modal.Content>
<Modal.Actions> <Modal.Actions>
<Button secondary onClick={() => this.handleClose()}> <Button secondary onClick={() => setDialogOpen(false)}>
<FormattedMessage <FormattedMessage
id="load_from_url.cancel" id="load_from_url.cancel"
defaultMessage="Cancel" defaultMessage="Cancel"
/> />
</Button> </Button>
<Button primary onClick={() => this.handleLoad()}> <Button primary onClick={handleLoad}>
<FormattedMessage id="load_from_url.load" defaultMessage="Load" /> <FormattedMessage id="load_from_url.load" defaultMessage="Load" />
</Button> </Button>
</Modal.Actions> </Modal.Actions>
@@ -119,21 +90,16 @@ export class UrlMenu extends React.Component<
); );
} }
render() {
return ( return (
<> <>
<MenuItem <MenuItem onClick={() => setDialogOpen(true)} menuType={props.menuType}>
onClick={() => this.openDialog()}
menuType={this.props.menuType}
>
<Icon name="cloud download" /> <Icon name="cloud download" />
<FormattedMessage <FormattedMessage
id="menu.load_from_url" id="menu.load_from_url"
defaultMessage="Load from URL" defaultMessage="Load from URL"
/> />
</MenuItem> </MenuItem>
{this.loadFromUrlModal()} {loadFromUrlModal()}
</> </>
); );
}
} }