181 lines
5.8 KiB
TypeScript
181 lines
5.8 KiB
TypeScript
import { h, Component } from 'preact';
|
|
import { FormattedMessage, IntlShape, useIntl } from 'react-intl';
|
|
import b from 'bem-react-helper';
|
|
import clsx from 'clsx';
|
|
|
|
import { User, Theme, PostInfo } from 'common/types';
|
|
import { IS_STORAGE_AVAILABLE, IS_THIRD_PARTY } from 'common/constants';
|
|
import { postMessageToParent } from 'utils/post-message';
|
|
import { getHandleClickProps } from 'common/accessibility';
|
|
import { StoreState } from 'store';
|
|
import { useTheme } from 'hooks/useTheme';
|
|
import { Button } from 'components/button';
|
|
import { Auth } from 'components/auth';
|
|
import { Avatar } from 'components/avatar';
|
|
import { SignOutIcon } from 'components/icons/signout';
|
|
import { IconButton } from 'components/icon-button/icon-button';
|
|
import { messages } from 'components/auth/auth.messsages';
|
|
|
|
import styles from './auth-panel.module.css';
|
|
|
|
interface OwnProps {
|
|
user: User | null;
|
|
hiddenUsers: StoreState['hiddenUsers'];
|
|
isCommentsDisabled: boolean;
|
|
postInfo: PostInfo;
|
|
|
|
signout(): Promise<void>;
|
|
onCommentsChangeReadOnlyMode(readOnly: boolean): Promise<void>;
|
|
onBlockedUsersShow(): void;
|
|
onBlockedUsersHide(): void;
|
|
}
|
|
|
|
export interface Props extends OwnProps {
|
|
intl: IntlShape;
|
|
theme: Theme;
|
|
}
|
|
|
|
interface State {
|
|
isBlockedVisible: boolean;
|
|
anonymousUsernameInputValue: string;
|
|
}
|
|
|
|
class AuthPanelComponent extends Component<Props, State> {
|
|
state = {
|
|
isBlockedVisible: false,
|
|
anonymousUsernameInputValue: 'anon',
|
|
};
|
|
|
|
toggleBlockedVisibility = () => {
|
|
if (!this.state.isBlockedVisible) {
|
|
if (this.props.onBlockedUsersShow) this.props.onBlockedUsersShow();
|
|
} else if (this.props.onBlockedUsersHide) this.props.onBlockedUsersHide();
|
|
|
|
this.setState({ isBlockedVisible: !this.state.isBlockedVisible });
|
|
};
|
|
|
|
toggleCommentsAvailability = () => {
|
|
this.props.onCommentsChangeReadOnlyMode(!this.props.isCommentsDisabled);
|
|
};
|
|
|
|
renderAuthorized = (user: User) => {
|
|
return (
|
|
<div className={clsx('user', styles.user)}>
|
|
<button
|
|
className={clsx('user-profile-button', styles.userButton)}
|
|
onClick={() => postMessageToParent({ profile: { ...user, current: '1' } })}
|
|
title={this.props.intl.formatMessage(messages.openProfile)}
|
|
>
|
|
<div className={clsx('user-avatar', styles.userAvatar)}>
|
|
<Avatar url={user.picture} />
|
|
</div>
|
|
{user.name}
|
|
</button>{' '}
|
|
<div className={clsx('user-logout-button', styles.userLogoutButton)}>
|
|
<IconButton title={this.props.intl.formatMessage(messages.signout)} onClick={this.props.signout}>
|
|
<SignOutIcon size="14" />
|
|
</IconButton>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
renderThirdPartyWarning = () => {
|
|
if (IS_STORAGE_AVAILABLE || !IS_THIRD_PARTY) return null;
|
|
return (
|
|
<div className="auth-panel__column">
|
|
<FormattedMessage
|
|
id="authPanel.disabled-cookies"
|
|
defaultMessage="Disable third-party cookies blocking to login or open comments in"
|
|
/>{' '}
|
|
<a
|
|
className="auth-panel__pseudo-link"
|
|
href={`${window.location.origin}/web/comments.html${window.location.search}`}
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
>
|
|
<FormattedMessage id="authPanel.new-page" defaultMessage="new page" />
|
|
</a>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
renderCookiesWarning = () => {
|
|
if (IS_STORAGE_AVAILABLE || IS_THIRD_PARTY) {
|
|
return null;
|
|
}
|
|
return (
|
|
<div className="auth-panel__column">
|
|
<FormattedMessage id="authPanel.enable-cookies" defaultMessage="Allow cookies to login and comment" />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
renderSettingsLabel = () => {
|
|
return (
|
|
<Button
|
|
kind="link"
|
|
mix="auth-panel__admin-action"
|
|
{...getHandleClickProps(this.toggleBlockedVisibility)}
|
|
role="link"
|
|
>
|
|
{this.state.isBlockedVisible ? (
|
|
<FormattedMessage id="authPanel.hide-settings" defaultMessage="Hide settings" />
|
|
) : (
|
|
<FormattedMessage id="authPanel.show-settings" defaultMessage="Show settings" />
|
|
)}
|
|
</Button>
|
|
);
|
|
};
|
|
|
|
renderReadOnlySwitch = () => {
|
|
const { isCommentsDisabled } = this.props;
|
|
return (
|
|
<Button
|
|
kind="link"
|
|
mix="auth-panel__admin-action"
|
|
{...getHandleClickProps(this.toggleCommentsAvailability)}
|
|
role="link"
|
|
>
|
|
{isCommentsDisabled ? (
|
|
<FormattedMessage id="authPanel.enable-comments" defaultMessage="Enable comments" />
|
|
) : (
|
|
<FormattedMessage id="authPanel.disable-comments" defaultMessage="Disable comments" />
|
|
)}
|
|
</Button>
|
|
);
|
|
};
|
|
|
|
render({ user, postInfo, theme }: Props, { isBlockedVisible }: State) {
|
|
const { read_only } = postInfo;
|
|
const isAdmin = user && user.admin;
|
|
const isSettingsLabelVisible = Object.keys(this.props.hiddenUsers).length > 0 || isAdmin || isBlockedVisible;
|
|
|
|
return (
|
|
<div className={b('auth-panel', {}, { theme, loggedIn: !!user })}>
|
|
<div className="auth-panel__column">{user ? this.renderAuthorized(user) : read_only && <Auth />}</div>
|
|
{this.renderThirdPartyWarning()}
|
|
{this.renderCookiesWarning()}
|
|
<div className="auth-panel__column">
|
|
{isSettingsLabelVisible && this.renderSettingsLabel()}
|
|
{isSettingsLabelVisible && ' • '}
|
|
{isAdmin && this.renderReadOnlySwitch()}
|
|
{isAdmin && read_only && ' • '}
|
|
{!isAdmin && read_only && (
|
|
<span className="auth-panel__readonly-label">
|
|
<FormattedMessage id="authPanel.read-only" defaultMessage="Read-only" />
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export function AuthPanel(props: OwnProps) {
|
|
const intl = useIntl();
|
|
const theme = useTheme();
|
|
|
|
return <AuthPanelComponent intl={intl} theme={theme} {...props} />;
|
|
}
|