2017-06-08_509bba0/509bba0_unpacked_with_node_.../discord_app/components/user_settings/UserSettingsAuthedApps.js

263 lines
7.8 KiB
JavaScript
Executable File

/* @flow */
import React from 'react';
import lodash from 'lodash';
import Flux from '../../lib/flux';
import Alert from '../Alert';
import i18n from '../../i18n';
import UserSettingsStore from '../../stores/UserSettingsStore';
import {FormSection, FormTitleTags, FormItem, FormText, FormTextTypes, FormNotice} from '../../uikit/form';
import Flex from '../../uikit/Flex';
import Card, {Types as CardTypes} from '../../uikit/Card';
import Button, {ButtonColors, ButtonSizes, ButtonLooks} from '../../uikit/Button';
import EmptyState, {EmptyStateText, EmptyStateImage} from '../../uikit/EmptyState';
import Spinner from '../../uikit/Spinner';
import AvatarUtils from '../../utils/AvatarUtils';
import StreamerModeEnabled from '../StreamerModeEnabled';
import ModalActionCreators from '../../actions/ModalActionCreators';
import AuthorizedAppsActionCreators from '../../actions/AuthorizedAppsActionCreators';
import AuthorizedAppsStore from '../../stores/AuthorizedAppsStore';
import type {ConnectedApp} from '../../stores/AuthorizedAppsStore';
import StreamerModeStore from '../../stores/StreamerModeStore';
import {OAuth2Scopes} from '../../Constants';
import type {OAuth2Token} from '../../flow/Server';
import '../../styles/user_settings_authorized_apps.styl';
const ThemedEmptyState = Flux.connectStores([UserSettingsStore], () => ({
theme: UserSettingsStore.theme,
}))(EmptyState);
class AuthorizedApp extends React.PureComponent {
renderPermissions = () => {
const permissions = this.props.scopes.map(scope => {
let humanReadableScope;
switch (scope) {
case OAuth2Scopes.IDENTIFY:
humanReadableScope = i18n.Messages.SCOPE_IDENTIFY;
break;
case OAuth2Scopes.EMAIL:
humanReadableScope = i18n.Messages.SCOPE_EMAIL;
break;
case OAuth2Scopes.CONNECTIONS:
humanReadableScope = i18n.Messages.SCOPE_CONNECTIONS;
break;
case OAuth2Scopes.GUILDS:
humanReadableScope = i18n.Messages.SCOPE_GUILDS;
break;
case OAuth2Scopes.GUILDS_JOIN:
humanReadableScope = i18n.Messages.SCOPE_GUILDS_JOIN;
break;
case OAuth2Scopes.GDM_JOIN:
humanReadableScope = i18n.Messages.SCOPE_GDM_JOIN;
break;
case OAuth2Scopes.BOT:
humanReadableScope = i18n.Messages.SCOPE_BOT;
break;
case OAuth2Scopes.RPC:
humanReadableScope = i18n.Messages.SCOPE_RPC;
break;
case OAuth2Scopes.RPC_API:
humanReadableScope = i18n.Messages.SCOPE_RPC_API;
break;
case OAuth2Scopes.RPC_NOTIFICATIONS_READ:
humanReadableScope = i18n.Messages.SCOPE_RPC_NOTIFICATIONS_READ;
break;
case OAuth2Scopes.MESSAGES_READ:
humanReadableScope = i18n.Messages.SCOPE_MESSAGES_READ;
break;
default:
humanReadableScope = scope;
}
return (
<li key={scope} className="permission margin-top-8">
<i className="permission-checkmark" />
<FormText>{humanReadableScope}</FormText>
</li>
);
});
if (permissions.length) {
return (
<FormItem faded title={i18n.Messages.PERMISSIONS} className="margin-top-20">
<ul>
{permissions}
</ul>
</FormItem>
);
}
};
renderDescription() {
const {application} = this.props;
if (application.description) {
return (
<FormItem faded title={i18n.Messages.ABOUT_THIS_APP}>
<FormText>
{application.description}
</FormText>
</FormItem>
);
}
}
renderHeader = () => {
const {application, controlling} = this.props;
const iconSrc = AvatarUtils.getAppIconURL(application);
const icon = iconSrc
? <Flex.Child className="app-avatar no-user-drag" grow={0}>
<img src={iconSrc} />
</Flex.Child>
: null;
return (
<Flex className="header margin-bottom-20">
<Flex className="header-info">
{icon}
<Flex.Child>
<FormText type={FormTextTypes.LABEL_BOLD}>
<span>{application.name}</span>
{controlling ? <span className="controlling">{i18n.Messages.CURRENTLY_CONTROLLING}</span> : null}
</FormText>
</Flex.Child>
</Flex>
<Flex.Child wrap grow={0}>
<Button
className="delete-app"
color={ButtonColors.RED}
look={ButtonLooks.OUTLINED}
size={ButtonSizes.SMALL}
onClick={this.handleDeleteApp}>
{i18n.Messages.DEAUTHORIZE}
</Button>
</Flex.Child>
</Flex>
);
};
render() {
return (
<Card className="authed-app margin-bottom-8" outline>
{this.renderHeader()}
{this.renderDescription()}
{this.renderPermissions()}
</Card>
);
}
// Handlers
handleDeleteApp = () => {
ModalActionCreators.push(props => {
return (
<Alert
title={i18n.Messages.DEAUTHORIZE_APP}
body={i18n.Messages.DELETE_APP_CONFIRM_MSG}
confirmText={i18n.Messages.DEAUTHORIZE}
cancelText={i18n.Messages.CANCEL}
onConfirm={this.props.onDelete}
{...props}
/>
);
});
};
}
class UserSettingsAuthedApps extends React.PureComponent {
props: {
hide: boolean,
applications: ?Array<OAuth2Token>,
connectedApps: Array<ConnectedApp>,
};
constructor(props) {
super(props);
lodash.bindAll(this, ['handleDelete']);
}
isControlling(app) {
return this.props.connectedApps.find(a => a.id === app.id) ? true : false;
}
componentDidMount() {
AuthorizedAppsActionCreators.fetch();
}
handleDelete({id}) {
AuthorizedAppsActionCreators.delete(id);
}
renderEmpty() {
return (
<ThemedEmptyState className="margin-top-20">
<EmptyStateImage
darkSrc={require('../../images/empties/empty_user_settings_authed_apps_dark.svg')}
lightSrc={require('../../images/empties/empty_user_settings_authed_apps_light.svg')}
width={380}
height={282}
/>
<EmptyStateText note={i18n.Messages.NO_AUTHORIZED_APPS_NOTE}>
{i18n.Messages.NO_AUTHORIZED_APPS}
</EmptyStateText>
</ThemedEmptyState>
);
}
renderContent() {
const {applications} = this.props;
if (!applications) {
return <Spinner className="margin-top-20" type={Spinner.Type.SPINNING_CIRCLE} />;
}
if (applications.length === 0) {
return this.renderEmpty();
}
return applications
.map(a => ({
controlling: this.isControlling(a.application),
...a,
}))
.filter(({scopes, controlling}) => !(scopes.includes(OAuth2Scopes.RPC) && !controlling))
.sort((a, b) => +b.controlling - +a.controlling)
.map(app => <AuthorizedApp key={app.id} onDelete={this.handleDelete.bind(this, app)} {...app} />);
}
render() {
if (this.props.hide) {
return <StreamerModeEnabled />;
}
return (
<FormSection
className="user-settings-authorized-apps"
tag={FormTitleTags.H2}
title={i18n.Messages.AUTHORIZED_APPS}>
<FormNotice
className="margin-bottom-40"
type={CardTypes.PRIMARY}
title={i18n.Messages.APPLICATIONS_AND_CONNECTIONS}
body={i18n.Messages.APPLICATIONS_AND_CONNECTIONS_BODY}
/>
{this.renderContent()}
</FormSection>
);
}
}
export default Flux.connectStores([AuthorizedAppsStore, StreamerModeStore], () => {
return {
hide: StreamerModeStore.hidePersonalInformation,
applications: AuthorizedAppsStore.getApps(),
connectedApps: AuthorizedAppsStore.getConnectedApps(),
};
})(UserSettingsAuthedApps);
// WEBPACK FOOTER //
// ./discord_app/components/user_settings/UserSettingsAuthedApps.js