2017-06-08_509bba0/509bba0_unpacked_with_node_modules/discord_app/components/guild_settings/GuildSettingsBans.js
2022-07-26 10:06:20 -07:00

249 lines
8 KiB
JavaScript
Executable file

import React from 'react';
import lodash from 'lodash';
import Flux from '../../lib/flux';
import i18n from '../../i18n';
import RegexUtils from '../../utils/RegexUtils';
import StreamerModeStore from '../../stores/StreamerModeStore';
import UserStore from '../../stores/UserStore';
import UserSettingsStore from '../../stores/UserSettingsStore';
import GuildSettingsStore from '../../stores/GuildSettingsStore';
import GuildSettingsActionCreators from '../../actions/GuildSettingsActionCreators';
import GuildActionCreators from '../../actions/GuildActionCreators';
import ModalActionCreators from '../../actions/ModalActionCreators';
import {LazyContentScroller} from '../common/StandardSidebarView';
import ContextMenu from '../common/ContextMenu';
import UserContextMenu from '../contextmenus/UserContextMenu';
import {Tags as FormTitleTags} from '../../uikit/form/FormTitle';
import Avatar from '../../uikit/Avatar';
import Button from '../../uikit/Button';
import FormText, {Types as FormTextTypes} from '../../uikit/form/FormText';
import EmptyState, {EmptyStateText, EmptyStateImage} from '../../uikit/EmptyState';
import Flex from '../../uikit/Flex';
import FormSection from '../../uikit/form/FormSection';
import FormDivider from '../../uikit/form/FormDivider';
import Modal from '../../uikit/Modal';
import SearchBar from '../../uikit/SearchBar';
import Spinner from '../../uikit/Spinner';
import Text from '../../uikit/Text';
import {GuildSettingsSections, ContextMenuTypes} from '../../Constants';
import './GuildSettingsBans.styl';
import '../../styles/shared/hover_card.styl';
class BannedUserModal extends React.PureComponent {
render() {
const {user, ban, theme, onRevoke, onClose} = this.props;
return (
<Modal className="guild-settings-banned-user-modal" theme={theme}>
<Modal.Content className="content user-select-text">
<div>
<Flex justify={Flex.Justify.CENTER}>
<Text color={Text.Colors.PRIMARY} className="user-username">{user.toString()}</Text>
<Text className="user-discrim">#{user.discriminator}</Text>
</Flex>
<Text className="reason-header margin-top-40" size={Text.Sizes.SMALL}>
{i18n.Messages.BAN_REASON}
</Text>
<Text className="reason">
{ban.reason || i18n.Messages.NO_BAN_REASON}
</Text>
</div>
</Modal.Content>
<Modal.Footer className="footer">
<Flex justify={Flex.Justify.BETWEEN}>
<Button className="revoke-btn" onClick={onRevoke} look={Button.Looks.LINK} color={Button.Colors.RED}>
{i18n.Messages.REVOKE_BAN}
</Button>
<Button onClick={onClose}>{i18n.Messages.DONE}</Button>
</Flex>
</Modal.Footer>
</Modal>
);
}
}
const BannedUserModalConnected = Flux.connectStores([UserSettingsStore], () => ({
theme: UserSettingsStore.theme,
}))(BannedUserModal);
class BannedUser extends React.PureComponent {
constructor(props) {
super(props);
(this: any).handleRevokeBan = this.handleRevokeBan.bind(this);
(this: any).handleShowModal = this.handleShowModal.bind(this);
(this: any).handleCloseModal = this.handleCloseModal.bind(this);
(this: any).handleContextMenu = this.handleContextMenu.bind(this);
}
render() {
const {user, hideDiscriminator} = this.props;
return (
<Flex
className="guild-settings-banned-user ui-hover-card"
align={Flex.Align.CENTER}
onClick={this.handleShowModal}
onContextMenu={this.handleContextMenu}>
<Avatar className="banned-user-avatar" src={user.getAvatarURL()} />
<Flex.Child basis={100} className="margin-reset">
<div className="username">
{user.toString()}
{!hideDiscriminator && <span className="discrim">#{user.discriminator}</span>}
</div>
</Flex.Child>
</Flex>
);
}
handleShowModal() {
const {user, hideDiscriminator, ban} = this.props;
ModalActionCreators.push(props =>
<BannedUserModalConnected
{...props}
ban={ban}
user={user}
hideDiscriminator={hideDiscriminator}
onRevoke={this.handleRevokeBan}
onClose={this.handleCloseModal}
/>
);
}
handleCloseModal() {
ModalActionCreators.pop();
}
handleRevokeBan() {
const {guildId, user} = this.props;
GuildActionCreators.unbanUser(guildId, user.id).then(ModalActionCreators.pop);
}
handleContextMenu(e: Event) {
ContextMenu.openContextMenu(e, props =>
<UserContextMenu {...props} type={ContextMenuTypes.USER_BANS} user={this.props.user} />
);
}
}
class GuildSettingsBans extends React.PureComponent {
makeFilter() {
const {searchQuery} = this.props;
if (searchQuery == null || searchQuery.length === 0) {
return () => true;
} else {
const regex = new RegExp(`^${RegexUtils.escape(searchQuery)}`, 'i');
return user => user != null && regex.test(user.username);
}
}
renderHeader() {
const {bans, theme, searchQuery} = this.props;
let emptyState;
if (bans == null) {
emptyState = null;
} else if (lodash.isEmpty(bans)) {
emptyState = (
<EmptyState theme={theme} className="margin-top-40">
<EmptyStateImage
darkSrc={require('../../images/empties/empty_server_settings_bans_dark.svg')}
lightSrc={require('../../images/empties/empty_server_settings_bans_light.svg')}
width={256}
height={212}
/>
<EmptyStateText note={i18n.Messages.BANS_NO_USERS_BANNED} style={{maxWidth: 300}}>
{i18n.Messages.NO_BANS}
</EmptyStateText>
</EmptyState>
);
}
const totalBans = lodash(bans || {}).keys().value().length;
return (
<FormSection tag={FormTitleTags.H2} title={i18n.Messages.BANS_HEADER.format({bans: totalBans})}>
<Flex justify={Flex.Justify.BETWEEN}>
<FormText type={FormTextTypes.DESCRIPTION} className="margin-bottom-20">
{i18n.Messages.BANS_HINT.format({onModerationClick: this.handleModerationClick})}
</FormText>
{emptyState == null &&
<SearchBar
query={searchQuery}
placeholder={i18n.Messages.BANS_SEARCH_PLACEHOLDER}
onChange={this.handleQueryChange}
onClear={this.handleQueryClear}
/>}
</Flex>
<FormDivider style={{marginBottom: -1}} />
{emptyState}
</FormSection>
);
}
render() {
const {bans, guildId, streamerMode, theme} = this.props;
let bansInner;
if (bans == null) {
bansInner = [<Spinner key="spinner" className="margin-top-20" type={Spinner.Type.SPINNING_CIRCLE} />];
} else {
bansInner = lodash(bans)
.keys()
.map(UserStore.getUser)
.filter(this.makeFilter())
.sortBy(user => user.username.toLowerCase())
.map(user =>
<BannedUser
user={user}
ban={bans[user.id]}
hideDiscriminator={streamerMode}
guildId={guildId}
key={user.id}
/>
)
.value();
}
return (
<LazyContentScroller theme={theme} header={this.renderHeader()} elementHeight={56}>
{bansInner}
</LazyContentScroller>
);
}
// Handlers
handleModerationClick() {
GuildSettingsActionCreators.setSection(GuildSettingsSections.MODERATION);
}
handleQueryChange(query) {
GuildSettingsActionCreators.setSearchQuery(query);
}
handleQueryClear() {
GuildSettingsActionCreators.setSearchQuery('');
}
}
const WrappedGuildSettingsBans = Flux.connectStores([GuildSettingsStore, UserSettingsStore], () => {
const {bans, guild, searchQuery} = GuildSettingsStore.getProps();
return {
searchQuery: searchQuery || '',
bans,
guildId: guild.id,
theme: UserSettingsStore.theme,
streamerMode: StreamerModeStore.enabled,
};
})(GuildSettingsBans);
export default WrappedGuildSettingsBans;
// WEBPACK FOOTER //
// ./discord_app/components/guild_settings/GuildSettingsBans.js