Refactored WikiTreeLoginMenuComponent from class-based to functional

This commit is contained in:
Przemek Wiech
2021-11-03 14:19:26 +01:00
parent b6c96ae336
commit a1a4b0d35e

View File

@@ -2,11 +2,11 @@ import * as queryString from 'query-string';
import wikitreeLogo from './wikitree.png'; import wikitreeLogo from './wikitree.png';
import {analyticsEvent} from '../util/analytics'; import {analyticsEvent} from '../util/analytics';
import {Button, Form, Header, Input, Modal} from 'semantic-ui-react'; import {Button, Form, Header, Input, Modal} from 'semantic-ui-react';
import {Component, createRef, useEffect, useRef, useState} from 'react';
import {FormattedMessage, injectIntl, WrappedComponentProps} from 'react-intl'; import {FormattedMessage, injectIntl, WrappedComponentProps} from 'react-intl';
import {getLoggedInUserName} from '../datasource/wikitree'; import {getLoggedInUserName} from '../datasource/wikitree';
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';
enum WikiTreeLoginState { enum WikiTreeLoginState {
UNKNOWN, UNKNOWN,
@@ -152,74 +152,31 @@ export function WikiTreeMenu(props: RouteComponentProps & Props) {
); );
} }
interface LoginState {
wikiTreeLoginState: WikiTreeLoginState;
wikiTreeLoginUsername?: string;
}
/** Displays and handles the "Log in to WikiTree" menu. */ /** Displays and handles the "Log in to WikiTree" menu. */
class WikiTreeLoginMenuComponent extends Component< function WikiTreeLoginMenuComponent(props: WrappedComponentProps & Props) {
RouteComponentProps & WrappedComponentProps & Props, const formRef = useRef<HTMLFormElement>(null);
LoginState const returnUrlRef = useRef<HTMLInputElement>(null);
> {
state: LoginState = {
wikiTreeLoginState: WikiTreeLoginState.UNKNOWN,
};
wikiTreeLoginFormRef: React.RefObject<HTMLFormElement> = createRef();
wikiTreeReturnUrlRef: React.RefObject<HTMLInputElement> = createRef();
/** /**
* Redirect to the WikiTree Apps login page with a return URL pointing to * Redirect to the WikiTree Apps login page with a return URL pointing to
* Topola Viewer hosted on apps.wikitree.com. * Topola Viewer hosted on apps.wikitree.com.
*/ */
private wikiTreeLogin() { function login() {
const wikiTreeTopolaUrl = const wikiTreeTopolaUrl =
'https://apps.wikitree.com/apps/wiech13/topola-viewer'; 'https://apps.wikitree.com/apps/wiech13/topola-viewer';
// Append '&' because the login page appends '?authcode=...' to this URL. // Append '&' because the login page appends '?authcode=...' to this URL.
// TODO: remove ?authcode if it is in the current URL. // TODO: remove ?authcode if it is in the current URL.
const returnUrl = `${wikiTreeTopolaUrl}${window.location.hash}&`; const returnUrl = `${wikiTreeTopolaUrl}${window.location.hash}&`;
this.wikiTreeReturnUrlRef.current!.value = returnUrl; returnUrlRef.current!.value = returnUrl;
this.wikiTreeLoginFormRef.current!.submit(); formRef.current!.submit();
} }
private checkWikiTreeLoginState() { const username = getLoggedInUserName();
const wikiTreeLoginUsername = getLoggedInUserName(); if (!username) {
const wikiTreeLoginState = wikiTreeLoginUsername
? WikiTreeLoginState.LOGGED_IN
: WikiTreeLoginState.NOT_LOGGED_IN;
if (this.state.wikiTreeLoginState !== wikiTreeLoginState) {
this.setState(
Object.assign({}, this.state, {
wikiTreeLoginState,
wikiTreeLoginUsername,
}),
);
}
}
componentDidMount() {
this.checkWikiTreeLoginState();
}
componentDidUpdate() {
this.checkWikiTreeLoginState();
}
render() {
switch (this.state.wikiTreeLoginState) {
case WikiTreeLoginState.NOT_LOGGED_IN:
return ( return (
<> <>
<MenuItem <MenuItem menuType={props.menuType} onClick={login}>
menuType={this.props.menuType} <img src={wikitreeLogo} alt="WikiTree logo" className="menu-icon" />
onClick={() => this.wikiTreeLogin()}
>
<img
src={wikitreeLogo}
alt="WikiTree logo"
className="menu-icon"
/>
<FormattedMessage <FormattedMessage
id="menu.wikitree_login" id="menu.wikitree_login"
defaultMessage="Log in to WikiTree" defaultMessage="Log in to WikiTree"
@@ -229,33 +186,23 @@ class WikiTreeLoginMenuComponent extends Component<
action="https://api.wikitree.com/api.php" action="https://api.wikitree.com/api.php"
method="POST" method="POST"
style={{display: 'hidden'}} style={{display: 'hidden'}}
ref={this.wikiTreeLoginFormRef} ref={formRef}
> >
<input type="hidden" name="action" value="clientLogin" /> <input type="hidden" name="action" value="clientLogin" />
<input <input type="hidden" name="returnURL" ref={returnUrlRef} />
type="hidden"
name="returnURL"
ref={this.wikiTreeReturnUrlRef}
/>
</form> </form>
</> </>
); );
}
case WikiTreeLoginState.LOGGED_IN: const tooltip = props.intl.formatMessage(
const tooltip = this.state.wikiTreeLoginUsername
? this.props.intl.formatMessage(
{ {
id: 'menu.wikitree_popup_username', id: 'menu.wikitree_popup_username',
defaultMessage: 'Logged in to WikiTree as {username}', defaultMessage: 'Logged in to WikiTree as {username}',
}, },
{username: this.state.wikiTreeLoginUsername}, {username},
) );
: this.props.intl.formatMessage({
id: 'menu.wikitree_popup',
defaultMessage: 'Logged in to WikiTree',
});
return ( return (
<MenuItem menuType={this.props.menuType} title={tooltip}> <MenuItem menuType={props.menuType} title={tooltip}>
<img src={wikitreeLogo} alt="WikiTree logo" className="menu-icon" /> <img src={wikitreeLogo} alt="WikiTree logo" className="menu-icon" />
<FormattedMessage <FormattedMessage
id="menu.wikitree_logged_in" id="menu.wikitree_logged_in"
@@ -263,8 +210,5 @@ class WikiTreeLoginMenuComponent extends Component<
/> />
</MenuItem> </MenuItem>
); );
}
return null;
}
} }
export const WikiTreeLoginMenu = injectIntl(WikiTreeLoginMenuComponent); export const WikiTreeLoginMenu = injectIntl(WikiTreeLoginMenuComponent);