Show last IRC connection error in status tab, log IRC connection errors

This commit is contained in:
Ken-Håvard Lieng 2017-07-02 03:31:00 +02:00
parent 786d8013b9
commit 18aff3ded6
19 changed files with 294 additions and 189 deletions

View file

@ -39,6 +39,14 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
margin: 0;
}
.success {
color: #6BB758 !important;
}
.error {
color: #F6546A !important;
}
.wrap {
position: fixed;
top: 0;

View file

@ -12,13 +12,14 @@ export default class TabList extends PureComponent {
const tabs = [];
channels.forEach((server, address) => {
const srv = servers.get(address);
tabs.push(
<TabListItem
key={address}
server={address}
content={servers.getIn([address, 'name'])}
content={srv.name}
selected={tab.server === address && tab.name === null}
connected={servers.getIn([address, 'connected'])}
connected={srv.status.connected}
onClick={this.handleTabClick}
/>
);

View file

@ -15,9 +15,9 @@ export default class TabListItem extends PureComponent {
classes.push('tab-server');
if (connected) {
style.color = '#6BB758';
classes.push('success');
} else {
style.color = '#F6546A';
classes.push('error');
}
}

View file

@ -55,6 +55,7 @@ export default class Chat extends Component {
nick,
search,
showUserList,
status,
tab,
title,
users,
@ -81,6 +82,7 @@ export default class Chat extends Component {
<div className={chatClass}>
<ChatTitle
channel={channel}
status={status}
tab={tab}
title={title}
onCloseClick={this.handleCloseClick}

View file

@ -7,7 +7,7 @@ import { linkify } from 'util';
export default class ChatTitle extends PureComponent {
render() {
const { title, tab, channel, onTitleChange,
const { status, title, tab, channel, onTitleChange,
onToggleSearch, onToggleUserList, onCloseClick } = this.props;
let closeTitle;
@ -19,6 +19,11 @@ export default class ChatTitle extends PureComponent {
closeTitle = 'Disconnect';
}
let serverError = null;
if (!tab.name && status.error) {
serverError = <span className="error">Error! {status.error}</span>;
}
return (
<div>
<div className="chat-title-bar">
@ -34,6 +39,7 @@ export default class ChatTitle extends PureComponent {
</Editable>
<div className="chat-topic-wrap">
<span className="chat-topic">{linkify(channel.get('topic')) || null}</span>
{serverError}
</div>
<i className="icon-search" title="Search" onClick={onToggleSearch} />
<i

View file

@ -10,7 +10,7 @@ import { getSelectedMessages, getHasMoreMessages,
runCommand, sendMessage, fetchMessages, addFetchedMessages } from 'state/messages';
import { openPrivateChat, closePrivateChat } from 'state/privateChats';
import { getSearch, searchMessages, toggleSearch } from 'state/search';
import { getCurrentNick, disconnect, setNick, setServerName } from 'state/servers';
import { getCurrentNick, getCurrentServerStatus, disconnect, setNick, setServerName } from 'state/servers';
import { getSelectedTab, select } from 'state/tab';
import { getShowUserList, toggleUserList } from 'state/ui';
@ -22,6 +22,7 @@ const mapState = createStructuredSelector({
nick: getCurrentNick,
search: getSearch,
showUserList: getShowUserList,
status: getCurrentServerStatus,
tab: getSelectedTab,
title: getSelectedTabTitle,
users: getSelectedChannelUsers

View file

@ -1,4 +1,26 @@
import { setServerName } from '../servers';
import { connect, setServerName } from '../servers';
describe('connect()', () => {
it('sets host and port correctly', () => {
expect(connect('cake.com:1881', '', {})).toMatchObject({
socket: {
data: {
host: 'cake.com',
port: '1881'
}
}
});
expect(connect('cake.com', '', {})).toMatchObject({
socket: {
data: {
host: 'cake.com',
port: undefined
}
}
});
});
});
describe('setServerName()', () => {
it('passes valid names to the server', () => {

View file

@ -8,10 +8,13 @@ describe('server reducer', () => {
expect(state.toJS()).toEqual({
'127.0.0.1': {
connected: false,
name: '127.0.0.1',
nick: 'nick',
editedNick: null
editedNick: null,
status: {
connected: false,
error: null
}
}
});
@ -19,10 +22,13 @@ describe('server reducer', () => {
expect(state.toJS()).toEqual({
'127.0.0.1': {
connected: false,
name: '127.0.0.1',
nick: 'nick',
editedNick: null
editedNick: null,
status: {
connected: false,
error: null
}
}
});
@ -32,16 +38,22 @@ describe('server reducer', () => {
expect(state.toJS()).toEqual({
'127.0.0.1': {
connected: false,
name: '127.0.0.1',
nick: 'nick',
editedNick: null
editedNick: null,
status: {
connected: false,
error: null
}
},
'127.0.0.2': {
connected: false,
name: 'srv',
nick: 'nick',
editedNick: null
editedNick: null,
status: {
connected: false,
error: null
}
}
});
});
@ -87,9 +99,8 @@ describe('server reducer', () => {
editing: true
});
expect(state.toJS()).toEqual({
expect(state.toJS()).toMatchObject({
'127.0.0.1': {
connected: false,
name: '127.0.0.1',
nick: 'nick',
editedNick: 'nick2'
@ -111,9 +122,8 @@ describe('server reducer', () => {
nick: ''
});
expect(state.toJS()).toEqual({
expect(state.toJS()).toMatchObject({
'127.0.0.1': {
connected: false,
name: '127.0.0.1',
nick: 'nick',
editedNick: null
@ -130,9 +140,8 @@ describe('server reducer', () => {
newNick: 'nick2'
});
expect(state.toJS()).toEqual({
expect(state.toJS()).toMatchObject({
'127.0.0.1': {
connected: false,
name: '127.0.0.1',
nick: 'nick2',
editedNick: null
@ -153,9 +162,8 @@ describe('server reducer', () => {
server: '127.0.0.1'
});
expect(state.toJS()).toEqual({
expect(state.toJS()).toMatchObject({
'127.0.0.1': {
connected: false,
name: '127.0.0.1',
nick: 'nick',
editedNick: null
@ -171,13 +179,17 @@ describe('server reducer', () => {
host: '127.0.0.1',
name: 'stuff',
nick: 'nick',
connected: true
status: {
connected: true
}
},
{
host: '127.0.0.2',
name: 'stuffz',
nick: 'nick2',
connected: false
status: {
connected: false
}
},
]
});
@ -187,13 +199,19 @@ describe('server reducer', () => {
name: 'stuff',
nick: 'nick',
editedNick: null,
connected: true
status: {
connected: true,
error: null
}
},
'127.0.0.2': {
name: 'stuffz',
nick: 'nick2',
editedNick: null,
connected: false
status: {
connected: false,
error: null
}
}
});
});
@ -202,7 +220,8 @@ describe('server reducer', () => {
let state = reducer(undefined, connect('127.0.0.1:1337', 'nick', {}));
state = reducer(state, {
type: actions.socket.CONNECTION_UPDATE,
'127.0.0.1': true
server: '127.0.0.1',
connected: true
});
expect(state.toJS()).toEqual({
@ -210,7 +229,29 @@ describe('server reducer', () => {
name: '127.0.0.1',
nick: 'nick',
editedNick: null,
connected: true
status: {
connected: true,
error: null
}
}
});
state = reducer(state, {
type: actions.socket.CONNECTION_UPDATE,
server: '127.0.0.1',
connected: false,
error: 'Bad stuff happened'
});
expect(state.toJS()).toEqual({
'127.0.0.1': {
name: '127.0.0.1',
nick: 'nick',
editedNick: null,
status: {
connected: false,
error: 'Bad stuff happened'
}
}
});
});

View file

@ -4,11 +4,16 @@ import createReducer from 'util/createReducer';
import { getSelectedTab, updateSelection } from './tab';
import * as actions from './actions';
const Status = Record({
connected: false,
error: null
});
const Server = Record({
nick: '',
editedNick: null,
name: '',
connected: false
status: new Status()
});
export const getServers = state => state.servers;
@ -31,6 +36,12 @@ export const getCurrentServerName = createSelector(
(servers, tab) => servers.getIn([tab.server, 'name'])
);
export const getCurrentServerStatus = createSelector(
getServers,
getSelectedTab,
(servers, tab) => servers.getIn([tab.server, 'status'])
);
export default createReducer(Map(), {
[actions.CONNECT](state, { host, nick, options }) {
if (!state.has(host)) {
@ -81,27 +92,27 @@ export default createReducer(Map(), {
return state.withMutations(s => {
data.forEach(server => {
server.status = new Status(server.status);
s.set(server.host, new Server(server));
});
});
},
[actions.socket.CONNECTION_UPDATE](state, action) {
return state.withMutations(s =>
Object.keys(action).forEach(server => {
if (s.has(server)) {
s.setIn([server, 'connected'], action[server]);
}
})
);
if (state.has(action.server)) {
return state.setIn([action.server, 'status'], new Status(action));
}
return state;
}
});
export function connect(server, nick, options) {
let host = server;
let port;
const i = server.indexOf(':');
if (i > 0) {
host = server.slice(0, i);
port = server.slice(i + 1);
}
return {
@ -112,7 +123,8 @@ export function connect(server, nick, options) {
socket: {
type: 'connect',
data: {
server,
host,
port,
nick,
username: options.username || nick,
password: options.password,