2017-05-27 05:30:22 +00:00
|
|
|
import React, { Component } from 'react';
|
2018-04-25 03:36:27 +00:00
|
|
|
import { createSelector } from 'reselect';
|
2018-05-16 03:02:48 +00:00
|
|
|
import { Form, withFormik } from 'formik';
|
2017-06-21 06:40:28 +00:00
|
|
|
import Navicon from 'containers/Navicon';
|
2018-05-16 03:02:48 +00:00
|
|
|
import Checkbox from 'components/ui/Checkbox';
|
|
|
|
import TextInput from 'components/ui/TextInput';
|
2018-05-18 01:39:40 +00:00
|
|
|
import { isValidNick, isValidChannel, isValidUsername, isInt } from 'utils';
|
2017-05-27 05:30:22 +00:00
|
|
|
|
2018-04-25 03:36:27 +00:00
|
|
|
const getSortedDefaultChannels = createSelector(
|
|
|
|
defaults => defaults.channels,
|
2018-05-16 03:02:48 +00:00
|
|
|
channels => channels.split(',').sort()
|
2018-04-25 03:36:27 +00:00
|
|
|
);
|
|
|
|
|
2018-05-16 03:02:48 +00:00
|
|
|
const Error = ({ children }) =>
|
|
|
|
children ? <div className="form-error">{children}</div> : null;
|
|
|
|
|
|
|
|
class Connect extends Component {
|
2017-05-27 05:30:22 +00:00
|
|
|
state = {
|
2018-05-16 03:02:48 +00:00
|
|
|
showOptionals: false
|
2017-05-27 05:30:22 +00:00
|
|
|
};
|
|
|
|
|
2018-05-16 03:02:48 +00:00
|
|
|
handleSSLChange = e => {
|
|
|
|
const { values, setFieldValue } = this.props;
|
|
|
|
if (e.target.checked && values.port === '6667') {
|
|
|
|
setFieldValue('port', '6697', false);
|
|
|
|
} else if (!e.target.checked && values.port === '6697') {
|
|
|
|
setFieldValue('port', '6667', false);
|
2017-05-27 05:30:22 +00:00
|
|
|
}
|
2018-05-18 03:33:33 +00:00
|
|
|
setFieldValue('tls', e.target.checked);
|
2017-05-27 05:30:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
handleShowClick = () => {
|
|
|
|
this.setState({ showOptionals: !this.state.showOptionals });
|
|
|
|
};
|
|
|
|
|
2018-05-16 03:02:48 +00:00
|
|
|
renderOptionals = () => {
|
|
|
|
const { errors, touched } = this.props;
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<TextInput name="username" placeholder="Username" />
|
|
|
|
{touched.username && <Error>{errors.username}</Error>}
|
|
|
|
<TextInput type="password" name="password" placeholder="Password" />
|
|
|
|
<TextInput name="realname" placeholder="Realname" />
|
|
|
|
</div>
|
|
|
|
);
|
2017-05-27 05:30:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
2018-05-16 03:02:48 +00:00
|
|
|
const { defaults, values, errors, touched } = this.props;
|
|
|
|
const { readonly, showDetails } = defaults;
|
2018-04-14 23:02:28 +00:00
|
|
|
let form;
|
|
|
|
|
2018-05-16 03:02:48 +00:00
|
|
|
if (readonly) {
|
2018-04-14 23:02:28 +00:00
|
|
|
form = (
|
2018-05-16 03:02:48 +00:00
|
|
|
<Form className="connect-form">
|
2018-04-14 23:02:28 +00:00
|
|
|
<h1>Connect</h1>
|
2018-05-16 03:02:48 +00:00
|
|
|
{showDetails && (
|
2018-04-14 23:02:28 +00:00
|
|
|
<div className="connect-details">
|
2018-05-16 03:02:48 +00:00
|
|
|
<h2>
|
|
|
|
{values.host}:{values.port}
|
|
|
|
</h2>
|
|
|
|
{getSortedDefaultChannels(values).map(channel => (
|
2018-04-25 03:36:27 +00:00
|
|
|
<p>{channel}</p>
|
|
|
|
))}
|
2018-04-14 23:02:28 +00:00
|
|
|
</div>
|
|
|
|
)}
|
2018-05-16 03:02:48 +00:00
|
|
|
<TextInput name="nick" placeholder="Nick" />
|
|
|
|
{touched.nick && <Error>{errors.nick}</Error>}
|
2018-04-14 23:02:28 +00:00
|
|
|
<input type="submit" value="Connect" />
|
2018-05-16 03:02:48 +00:00
|
|
|
</Form>
|
2018-04-14 23:02:28 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
form = (
|
2018-05-16 03:02:48 +00:00
|
|
|
<Form className="connect-form">
|
2017-05-27 05:30:22 +00:00
|
|
|
<h1>Connect</h1>
|
2018-05-16 03:02:48 +00:00
|
|
|
<TextInput name="name" placeholder="Name" />
|
|
|
|
<div className="connect-form-address">
|
|
|
|
<TextInput name="host" placeholder="Host" />
|
|
|
|
<TextInput name="port" placeholder="Port" />
|
2018-05-18 03:33:33 +00:00
|
|
|
<Checkbox name="tls" label="SSL" onChange={this.handleSSLChange} />
|
2018-05-16 03:02:48 +00:00
|
|
|
</div>
|
|
|
|
{touched.host && <Error>{errors.host}</Error>}
|
|
|
|
{touched.port && <Error>{errors.port}</Error>}
|
|
|
|
<TextInput name="nick" placeholder="Nick" />
|
|
|
|
{touched.nick && <Error>{errors.nick}</Error>}
|
|
|
|
<TextInput name="channels" placeholder="Channels" />
|
|
|
|
{touched.channels && <Error>{errors.channels}</Error>}
|
|
|
|
{this.state.showOptionals && this.renderOptionals()}
|
|
|
|
<i className="icon-ellipsis" onClick={this.handleShowClick} />
|
2017-05-27 05:30:22 +00:00
|
|
|
<input type="submit" value="Connect" />
|
2018-05-16 03:02:48 +00:00
|
|
|
</Form>
|
2018-04-14 23:02:28 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="connect">
|
|
|
|
<Navicon />
|
|
|
|
{form}
|
2017-05-27 05:30:22 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2018-05-16 03:02:48 +00:00
|
|
|
|
|
|
|
export default withFormik({
|
2018-05-18 03:13:25 +00:00
|
|
|
mapPropsToValues: ({ defaults }) => {
|
|
|
|
let port = '6667';
|
|
|
|
if (defaults.port) {
|
|
|
|
port = `${defaults.port}`;
|
|
|
|
} else if (defaults.ssl) {
|
|
|
|
port = '6697';
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
name: defaults.name,
|
|
|
|
host: defaults.host,
|
|
|
|
port,
|
|
|
|
nick: '',
|
|
|
|
channels: defaults.channels.join(','),
|
|
|
|
username: '',
|
|
|
|
password: defaults.password ? ' ' : '',
|
|
|
|
realname: '',
|
2018-05-18 03:33:33 +00:00
|
|
|
tls: defaults.ssl
|
2018-05-18 03:13:25 +00:00
|
|
|
};
|
|
|
|
},
|
2018-05-16 03:02:48 +00:00
|
|
|
validate: values => {
|
|
|
|
Object.keys(values).forEach(k => {
|
|
|
|
if (typeof values[k] === 'string') {
|
|
|
|
values[k] = values[k].trim();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const errors = {};
|
|
|
|
|
|
|
|
if (!values.host) {
|
|
|
|
errors.host = 'Host is required';
|
|
|
|
} else if (values.host.indexOf('.') < 1) {
|
|
|
|
errors.host = 'Invalid host';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!values.port) {
|
2018-05-18 03:33:33 +00:00
|
|
|
values.port = values.tls ? '6697' : '6667';
|
2018-05-18 01:39:40 +00:00
|
|
|
} else if (!isInt(values.port, 1, 65535)) {
|
2018-05-16 03:02:48 +00:00
|
|
|
errors.port = 'Invalid port';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!values.nick) {
|
|
|
|
errors.nick = 'Nick is required';
|
|
|
|
} else if (!isValidNick(values.nick)) {
|
|
|
|
errors.nick = 'Invalid nick';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (values.username && !isValidUsername(values.username)) {
|
|
|
|
errors.username = 'Invalid username';
|
|
|
|
}
|
|
|
|
|
|
|
|
values.channels = values.channels
|
|
|
|
.split(',')
|
|
|
|
.map(channel => {
|
|
|
|
channel = channel.trim();
|
|
|
|
if (channel) {
|
|
|
|
if (isValidChannel(channel, false)) {
|
|
|
|
if (channel[0] !== '#') {
|
|
|
|
channel = `#${channel}`;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
errors.channels = 'Invalid channel(s)';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return channel;
|
|
|
|
})
|
|
|
|
.filter(s => s)
|
|
|
|
.join(',');
|
|
|
|
|
|
|
|
return errors;
|
|
|
|
},
|
|
|
|
handleSubmit: (values, { props }) => {
|
|
|
|
const { connect, select, join } = props;
|
|
|
|
const channels = values.channels.split(',');
|
|
|
|
delete values.channels;
|
|
|
|
|
|
|
|
connect(values);
|
|
|
|
select(values.host);
|
|
|
|
|
|
|
|
if (channels.length > 0) {
|
|
|
|
join(channels, values.host);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})(Connect);
|