Files
remark42/frontend/app/components/user-info/user-info.tsx
T
b22cd5f76a Add localization (#602)
* #10 add localization

* #10 revert locale from dev page

* #10 add more examples

* #10 localize auth panel

* #10 localize some comment message

* #10 localize some comment form message

* #10 translate vote messages

* #10 translate comment message

* #10 use messages value for translate reference

* #10 fix compile issue

* #10 use messages value for translate reference

* #10 use messages value for translate reference

* #10 use messages value for translate reference

* #10 use messages value for translate reference

* #10 use messages value for translate reference

* #10 translate comment message

* #10 translate comment form

* #10 translate comment form

* #10 translate root component

* #10 translate user info

* #10 translate settings

* #10 translate settings

* #10 translate toolbar

* #10 translate errors messages

* #10 sort dict

* #10 fix after rebase

* #10 localize anonymousLoginForm

* #10 localize emailLoginForm

* #10 update size-limit

* #10 localize subscribe by rss

* #10 localize subscribe by email

* #10 add de locale

* #10 increase limit size

* #10 auto generate loadLocale

* #10 add some documentation

* #10 fix error messages

* fix typo

* don't bundle en locale

* fix message id

* change size limits

* Update extract message pattern

Co-Authored-By: Pavel Mineev <pavel@mineev.me>

Co-authored-by: Pavel Mineev <pavel@mineev.me>
2020-03-04 14:56:00 -06:00

105 lines
3.0 KiB
TypeScript

/** @jsx createElement */
import { createElement, JSX, Component, FunctionComponent } from 'preact';
import b from 'bem-react-helper';
import { useSelector } from 'react-redux';
import { StoreState } from '@app/store';
import { Comment } from '@app/common/types';
import { fetchInfo } from '@app/store/user-info/actions';
import { userInfo } from '@app/common/user-info-settings';
import LastCommentsList from './last-comments-list';
import { AvatarIcon } from '../avatar-icon';
import postMessage from '@app/utils/postMessage';
import { bindActions } from '@app/utils/actionBinder';
import { useActions } from '@app/hooks/useAction';
import { useIntl, defineMessages, FormattedMessage, IntlShape } from 'react-intl';
const boundActions = bindActions({ fetchInfo });
const messages = defineMessages({
unexpectedError: {
id: 'user-info.unexpected-error',
defaultMessage: 'Something went wrong',
},
});
type Props = {
comments: Comment[] | null;
} & typeof boundActions & { intl: IntlShape };
interface State {
isLoading: boolean;
error: string | null;
}
class UserInfo extends Component<Props, State> {
state = { isLoading: true, error: null };
componentWillMount(): void {
if (!this.props.comments && this.state.isLoading) {
this.props
.fetchInfo()
.then(() => {
this.setState({ isLoading: false });
})
.catch(() => {
this.setState({ isLoading: false, error: this.props.intl.formatMessage(messages.unexpectedError) });
});
}
document.addEventListener('keydown', UserInfo.onKeyDown);
}
componentWillUnmount(): void {
document.removeEventListener('keydown', UserInfo.onKeyDown);
}
render(): JSX.Element | null {
const user = userInfo;
const { comments = [] } = this.props;
const { isLoading } = this.state;
// TODO: handle
if (!user) {
return null;
}
return (
<div className={b('user-info', {})}>
<AvatarIcon mix="user-info__avatar" picture={user.picture} />
<p className="user-info__title">
<FormattedMessage
id="user-info.last-comments"
defaultMessage="Last comments by {userName}"
values={{ userName: user.name }}
/>
</p>
<p className="user-info__id">{user.id}</p>
{!!comments && <LastCommentsList isLoading={isLoading} comments={comments} />}
</div>
);
}
/**
* Global on `keydown` handler which is set on component mount.
* Listens for user's `esc` key press
*/
static onKeyDown(e: KeyboardEvent): void {
// ESCAPE key pressed
if (e.keyCode === 27) {
postMessage({ isUserInfoShown: false });
}
}
}
const commentsSelector = (state: StoreState) => state.userComments![userInfo.id!];
export const ConnectedUserInfo: FunctionComponent = () => {
const comments = useSelector(commentsSelector);
const actions = useActions(boundActions);
const intl = useIntl();
return <UserInfo comments={comments} {...actions} intl={intl} />;
};