Show last IRC connection error in status tab, log IRC connection errors
This commit is contained in:
parent
786d8013b9
commit
18aff3ded6
19 changed files with 294 additions and 189 deletions
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue