dispatch/client/js/components/pages/Connect.js

248 lines
6.4 KiB
JavaScript
Raw Normal View History

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';
2020-05-23 06:05:37 +00:00
import { FiMoreHorizontal } from 'react-icons/fi';
2020-04-30 12:36:30 +00:00
import Navicon from 'components/ui/Navicon';
import Button from 'components/ui/Button';
2018-10-15 06:56:17 +00:00
import Checkbox from 'components/ui/formik/Checkbox';
2018-05-16 03:02:48 +00:00
import TextInput from 'components/ui/TextInput';
2018-10-06 06:46:28 +00:00
import Error from 'components/ui/formik/Error';
2018-05-18 01:39:40 +00:00
import { isValidNick, isValidChannel, isValidUsername, isInt } from 'utils';
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
);
const transformChannels = channels => {
const comma = channels[channels.length - 1] === ',';
channels = channels
.split(',')
.map(channel => {
channel = channel.trim();
if (channel) {
if (isValidChannel(channel, false) && channel[0] !== '#') {
channel = `#${channel}`;
}
}
return channel;
})
.filter(s => s)
.join(',');
return comma ? `${channels},` : channels;
};
2018-05-16 03:02:48 +00:00
class Connect extends Component {
state = {
2018-05-16 03:02:48 +00:00
showOptionals: false
};
2018-05-16 03:02:48 +00:00
handleSSLChange = e => {
const { values, setFieldValue } = this.props;
2020-05-10 00:53:39 +00:00
if (e.target.checked && values.port === '6667') {
setFieldValue('port', '6697', false);
} else if (!e.target.checked && values.port === '6697') {
setFieldValue('port', '6667', false);
}
};
handleShowClick = () => {
this.setState(prevState => ({ showOptionals: !prevState.showOptionals }));
};
renderOptionals = () => {
const { hexIP } = this.props;
return (
2020-05-23 06:05:37 +00:00
<>
<div className="connect-section">
<h2>SASL</h2>
<TextInput name="account" />
<TextInput name="password" type="password" noTrim />
2020-05-23 06:05:37 +00:00
</div>
{!hexIP && <TextInput name="username" />}
2020-05-23 06:05:37 +00:00
<TextInput
name="serverPassword"
label="Server Password"
type="password"
noTrim
/>
2018-12-19 01:55:50 +00:00
<TextInput name="realname" noTrim />
2020-05-23 06:05:37 +00:00
</>
);
};
2018-05-25 02:12:02 +00:00
2018-12-19 01:55:50 +00:00
transformPort = port => {
if (!port) {
2020-05-10 00:53:39 +00:00
return this.props.values.tls ? '6697' : '6667';
2018-12-19 01:55:50 +00:00
}
return port;
};
render() {
2018-05-25 02:12:02 +00:00
const { defaults, values } = this.props;
2018-08-10 19:35:37 +00:00
const { readOnly, showDetails } = defaults;
let form;
2018-08-10 19:35:37 +00:00
if (readOnly) {
form = (
2018-05-16 03:02:48 +00:00
<Form className="connect-form">
<h1>Connect</h1>
2018-05-16 03:02:48 +00:00
{showDetails && (
<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>
))}
</div>
)}
<TextInput name="nick" />
<Button type="submit">Connect</Button>
2018-05-16 03:02:48 +00:00
</Form>
);
} else {
form = (
2018-05-16 03:02:48 +00:00
<Form className="connect-form">
<h1>Connect</h1>
2018-12-19 01:55:50 +00:00
<TextInput name="name" autoCapitalize="words" noTrim />
2018-05-16 03:02:48 +00:00
<div className="connect-form-address">
<TextInput name="host" noError />
2018-12-19 01:55:50 +00:00
<TextInput
name="port"
type="number"
blurTransform={this.transformPort}
noError
/>
2018-10-15 06:56:17 +00:00
<Checkbox
classNameLabel="connect-form-ssl"
2018-10-15 06:56:17 +00:00
name="tls"
label="SSL"
topLabel
onChange={this.handleSSLChange}
/>
2018-05-16 03:02:48 +00:00
</div>
2018-10-06 06:46:28 +00:00
<Error name="host" />
<Error name="port" />
<TextInput name="nick" />
<TextInput name="channels" transform={transformChannels} />
2018-05-16 03:02:48 +00:00
{this.state.showOptionals && this.renderOptionals()}
2020-04-29 01:10:13 +00:00
<Button
className="connect-form-button-optionals"
icon={FiMoreHorizontal}
aria-label="Show more"
2020-04-29 01:10:13 +00:00
onClick={this.handleShowClick}
/>
<Button type="submit">Connect</Button>
2018-05-16 03:02:48 +00:00
</Form>
);
}
return (
<div className="connect">
<Navicon />
{form}
</div>
);
}
}
2018-05-16 03:02:48 +00:00
export default withFormik({
2018-11-06 10:13:32 +00:00
enableReinitialize: true,
mapPropsToValues: ({ defaults, query }) => {
let port = '6667';
if (query.port || defaults.port) {
port = query.port || defaults.port;
} else if (defaults.ssl) {
port = '6697';
}
let { channels } = query;
if (channels) {
channels = transformChannels(channels);
}
let ssl;
if (query.ssl === 'true') {
ssl = true;
} else if (query.ssl === 'false') {
ssl = false;
} else {
ssl = defaults.ssl || false;
}
return {
name: query.name || defaults.name,
host: query.host || defaults.host,
port,
nick: query.nick || localStorage.lastNick || '',
channels: channels || defaults.channels.join(','),
2020-05-23 06:05:37 +00:00
account: '',
password: '',
username: query.username || '',
2020-05-23 06:05:37 +00:00
serverPassword: defaults.serverPassword ? ' ' : '',
realname: query.realname || localStorage.lastRealname || '',
tls: ssl
};
},
2018-05-16 03:02:48 +00:00
validate: values => {
const errors = {};
if (!values.host) {
errors.host = 'Host is required';
} else if (values.host.indexOf('.') < 1) {
errors.host = 'Invalid host';
}
2018-12-19 01:55:50 +00:00
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';
}
2018-12-19 01:55:50 +00:00
const channels = values.channels.split(',');
for (let i = channels.length - 1; i >= 0; i--) {
if (i === channels.length - 1 && channels[i] === '') {
/* eslint-disable-next-line no-continue */
continue;
}
if (!isValidChannel(channels[i])) {
errors.channels = 'Invalid channel(s)';
break;
}
}
2018-05-16 03:02:48 +00:00
return errors;
},
handleSubmit: (values, { props }) => {
const { connect, select, join } = props;
const channels = values.channels ? values.channels.split(',') : [];
2018-05-16 03:02:48 +00:00
delete values.channels;
2018-05-25 02:12:02 +00:00
values.port = `${values.port}`;
2018-05-16 03:02:48 +00:00
connect(values);
select(values.host);
if (channels.length > 0) {
2020-06-21 03:33:02 +00:00
join(channels, values.host, false);
2018-05-16 03:02:48 +00:00
}
localStorage.lastNick = values.nick;
if (values.realname) {
localStorage.lastRealname = values.realname;
}
2018-05-16 03:02:48 +00:00
}
})(Connect);