206 lines
6.2 KiB
JavaScript
206 lines
6.2 KiB
JavaScript
|
/* @flow */
|
||
|
|
||
|
import React from 'react';
|
||
|
import lodash from 'lodash';
|
||
|
import classNames from 'classnames';
|
||
|
import Scroller from './common/Scroller';
|
||
|
import Checkbox from './common/Checkbox';
|
||
|
import GuildStore from '../stores/GuildStore';
|
||
|
import ChannelRecord from '../records/ChannelRecord';
|
||
|
import type {Role} from '../records/GuildRecord';
|
||
|
import SelectedGuildStore from '../stores/SelectedGuildStore';
|
||
|
import CreateChannelModalStore from '../stores/CreateChannelModalStore';
|
||
|
import CreateChannelModalActionCreators from '../actions/CreateChannelModalActionCreators';
|
||
|
import {permissionOverwritesForRoles} from '../utils/ChannelUtils';
|
||
|
import i18n from '../i18n';
|
||
|
import {ChannelTypes} from '../Constants';
|
||
|
import '../styles/create_channel_modal.styl';
|
||
|
|
||
|
const NAME_REF = 'NAME_REF';
|
||
|
|
||
|
type Props = {
|
||
|
channelType: number,
|
||
|
cloneChannel?: ChannelRecord,
|
||
|
errors: {[key: string]: Array<string>},
|
||
|
submitting: boolean,
|
||
|
guildId?: string,
|
||
|
};
|
||
|
|
||
|
const CreateChannelModal = React.createClass({
|
||
|
statics: {
|
||
|
modalConfig: {
|
||
|
store: CreateChannelModalStore,
|
||
|
},
|
||
|
},
|
||
|
|
||
|
propTypes: {
|
||
|
channelType: React.PropTypes.number.isRequired,
|
||
|
cloneChannel: React.PropTypes.instanceOf(ChannelRecord),
|
||
|
errors: React.PropTypes.object.isRequired,
|
||
|
submitting: React.PropTypes.bool.isRequired,
|
||
|
guildId: React.PropTypes.string,
|
||
|
},
|
||
|
|
||
|
getGuildId(props: ?Props): ?string {
|
||
|
props = props || this.props;
|
||
|
return props.guildId || SelectedGuildStore.getGuildId();
|
||
|
},
|
||
|
|
||
|
getRolesForGuild(props: Props): Array<Role> {
|
||
|
const guildId = this.getGuildId(props);
|
||
|
const guild = guildId != null ? GuildStore.getGuild(guildId) : null;
|
||
|
return guild != null ? lodash(guild.roles).sortBy(role => role.position).value() : [];
|
||
|
},
|
||
|
|
||
|
close() {
|
||
|
CreateChannelModalActionCreators.close();
|
||
|
},
|
||
|
|
||
|
getInitialState() {
|
||
|
return {
|
||
|
permissionOverwrites: new Set(),
|
||
|
roles: this.getRolesForGuild(this.props),
|
||
|
};
|
||
|
},
|
||
|
|
||
|
componentWillReceiveProps(nextProps: Props) {
|
||
|
this.setState({
|
||
|
permissionOverwrites: this.getGuildId() !== this.getGuildId(nextProps)
|
||
|
? new Set()
|
||
|
: this.state.permissionOverwrites,
|
||
|
roles: this.getRolesForGuild(nextProps),
|
||
|
});
|
||
|
},
|
||
|
|
||
|
componentDidMount() {
|
||
|
this.refs[NAME_REF].select();
|
||
|
},
|
||
|
|
||
|
renderPermissionOverwrite(role: Role): ReactElement {
|
||
|
const {permissionOverwrites} = this.state;
|
||
|
const disabled = permissionOverwrites.size === 0 && role.id === this.getGuildId();
|
||
|
const checked = permissionOverwrites.has(role.id) || disabled;
|
||
|
return (
|
||
|
<li key={role.id}>
|
||
|
<Checkbox checked={checked} disabled={disabled} onChange={this.handleRoleChange.bind(this, role.id)}>
|
||
|
<span style={{color: role.colorString}}>{role.name}</span>
|
||
|
</Checkbox>
|
||
|
</li>
|
||
|
);
|
||
|
},
|
||
|
|
||
|
render() {
|
||
|
const {errors, cloneChannel, channelType, submitting} = this.props;
|
||
|
|
||
|
const hasError = field => errors[field] != null;
|
||
|
const renderError = field => (hasError(field) ? <span className="error">({errors[field]})</span> : null);
|
||
|
let title;
|
||
|
let cloneHelp;
|
||
|
let defaultValue;
|
||
|
if (cloneChannel != null) {
|
||
|
title = i18n.Messages.CLONE_CHANNEL;
|
||
|
cloneHelp = (
|
||
|
<div className="help-text">
|
||
|
{i18n.Messages.CLONE_CHANNEL_HELP.format({name: cloneChannel.toString(true)})}
|
||
|
</div>
|
||
|
);
|
||
|
defaultValue = cloneChannel.toString();
|
||
|
} else if (channelType === ChannelTypes.GUILD_TEXT) {
|
||
|
title = i18n.Messages.CREATE_TEXT_CHANNEL;
|
||
|
} else {
|
||
|
title = i18n.Messages.CREATE_VOICE_CHANNEL;
|
||
|
}
|
||
|
|
||
|
let permissionOverwrites;
|
||
|
// Don't render if only the @everyone role exists.
|
||
|
if (cloneChannel == null && this.state.roles.length > 1) {
|
||
|
permissionOverwrites = (
|
||
|
<div className="control-group">
|
||
|
<label>{i18n.Messages.FORM_LABEL_CHANNEL_PERMISSIONS}</label>
|
||
|
<ul className="checkbox-group">{this.state.roles.map(this.renderPermissionOverwrite)}</ul>
|
||
|
<div className="help-text">{i18n.Messages.FORM_HELP_CHANNEL_PERMISSIONS}</div>
|
||
|
</div>
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<form id="create-channel-modal" className="form" onSubmit={this.handleSubmit}>
|
||
|
<div className="form-header">
|
||
|
<header>{title}</header>
|
||
|
</div>
|
||
|
<div className="form-inner">
|
||
|
<Scroller>
|
||
|
<div className={classNames({'control-group': true, error: hasError('name')})}>
|
||
|
<label htmlFor="channel-name">{i18n.Messages.FORM_LABEL_CHANNEL_NAME} {renderError('name')}</label>
|
||
|
<input id="channel-name" type="text" defaultValue={defaultValue} ref={NAME_REF} autoFocus />
|
||
|
{cloneHelp}
|
||
|
</div>
|
||
|
{permissionOverwrites}
|
||
|
</Scroller>
|
||
|
</div>
|
||
|
<div className="form-actions">
|
||
|
<button type="button" className="btn btn-default" onClick={this.close}>
|
||
|
{i18n.Messages.CANCEL}
|
||
|
</button>
|
||
|
<button type="submit" className="btn btn-primary" disabled={submitting}>
|
||
|
{i18n.Messages.CREATE}
|
||
|
</button>
|
||
|
</div>
|
||
|
</form>
|
||
|
);
|
||
|
},
|
||
|
|
||
|
// Handlers
|
||
|
|
||
|
handleRoleChange(roleId: string, e: Event) {
|
||
|
const {permissionOverwrites} = this.state;
|
||
|
if (roleId === this.getGuildId()) {
|
||
|
permissionOverwrites.clear();
|
||
|
} else if (e.currentTarget.checked) {
|
||
|
permissionOverwrites.add(roleId);
|
||
|
} else {
|
||
|
permissionOverwrites.delete(roleId);
|
||
|
}
|
||
|
this.forceUpdate();
|
||
|
},
|
||
|
|
||
|
handleSubmit(e: Event) {
|
||
|
e.preventDefault();
|
||
|
|
||
|
const {channelType, cloneChannel} = this.props;
|
||
|
|
||
|
const guildId = this.getGuildId();
|
||
|
if (guildId == null) return;
|
||
|
|
||
|
let permissionOverwrites;
|
||
|
let bitrate;
|
||
|
let userLimit;
|
||
|
if (cloneChannel != null) {
|
||
|
permissionOverwrites = lodash.values(cloneChannel.permissionOverwrites);
|
||
|
bitrate = cloneChannel.bitrate;
|
||
|
userLimit = cloneChannel.userLimit;
|
||
|
} else {
|
||
|
permissionOverwrites = permissionOverwritesForRoles(
|
||
|
guildId,
|
||
|
channelType,
|
||
|
Array.from(this.state.permissionOverwrites)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
CreateChannelModalActionCreators.createChannel(
|
||
|
guildId,
|
||
|
channelType,
|
||
|
this.refs[NAME_REF].value,
|
||
|
permissionOverwrites,
|
||
|
bitrate,
|
||
|
userLimit
|
||
|
);
|
||
|
},
|
||
|
});
|
||
|
|
||
|
export default CreateChannelModal;
|
||
|
|
||
|
|
||
|
|
||
|
// WEBPACK FOOTER //
|
||
|
// ./discord_app/components/CreateChannelModal.js
|