Handle channel forwarding and errors better

This commit is contained in:
Ken-Håvard Lieng 2019-01-25 11:02:31 +01:00
parent 497934888c
commit f8e12f5938
15 changed files with 481 additions and 213 deletions

View file

@ -149,6 +149,10 @@ i[class*=' icon-']:before {
color: #f6546a !important;
}
.disabled {
color: #999 !important;
}
.textinput {
display: block;
position: relative;

View file

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react';
import classnames from 'classnames';
import Button from 'components/ui/Button';
import TabListItem from './TabListItem';
import TabListItem from 'containers/TabListItem';
export default class TabList extends PureComponent {
handleTabClick = (server, target) => this.props.select(server, target);

View file

@ -1,4 +1,4 @@
import React, { memo } from 'react';
import React from 'react';
import classnames from 'classnames';
const TabListItem = ({
@ -7,12 +7,15 @@ const TabListItem = ({
server,
selected,
connected,
joined,
error,
onClick
}) => {
const className = classnames({
'tab-server': !target,
success: !target && connected,
error: !target && !connected,
error: (!target && !connected) || (!joined && error),
disabled: !!target && !error && joined === false,
selected
});
@ -23,4 +26,4 @@ const TabListItem = ({
);
};
export default memo(TabListItem);
export default TabListItem;

View file

@ -0,0 +1,20 @@
import { createStructuredSelector } from 'reselect';
import get from 'lodash/get';
import TabListItem from 'components/TabListItem';
import connect from 'utils/connect';
const mapState = createStructuredSelector({
joined: (state, { server, target }) =>
get(state, ['channels', server, target, 'joined']),
error: (state, { server, target }) => {
const messages = get(state, ['messages', server, target]);
if (messages && messages.length > 0) {
return messages[messages.length - 1].type === 'error';
}
return false;
}
});
export default connect(mapState)(TabListItem);

View file

@ -10,7 +10,7 @@ import {
import { openModal } from 'state/modals';
import { reconnect } from 'state/servers';
import { select } from 'state/tab';
import { find, normalizeChannel } from 'utils';
import { find } from 'utils';
function withReason(message, reason) {
return message + (reason ? ` (${reason})` : '');
@ -46,22 +46,7 @@ export default function handleSocket({
},
join({ user, server, channels }) {
const state = getState();
const tab = state.tab.selected;
const [joinedChannel] = channels;
if (tab.server && tab.name) {
const { nick } = state.servers[tab.server];
if (
tab.server === server &&
nick === user &&
tab.name !== joinedChannel &&
normalizeChannel(tab.name) === normalizeChannel(joinedChannel)
) {
dispatch(select(server, joinedChannel));
}
}
dispatch(inform(`${user} joined the channel`, server, joinedChannel));
dispatch(inform(`${user} joined the channel`, server, channels[0]));
},
part({ user, server, channel, reason }) {
@ -123,6 +108,10 @@ export default function handleSocket({
dispatch(addMessage(message, tab.server, tab.name));
},
error({ server, target, message }) {
dispatch(addMessage({ content: message, type: 'error' }, server, target));
},
connection_update({ server, errorType }) {
if (errorType === 'verify') {
dispatch(
@ -145,6 +134,16 @@ export default function handleSocket({
}
};
const afterHandlers = {
channel_forward(forward) {
const { selected } = getState().tab;
if (selected.server === forward.server && selected.name === forward.old) {
dispatch(select(forward.server, forward.new, true));
}
}
};
socket.onMessage((type, data) => {
let action;
if (Array.isArray(data)) {
@ -162,5 +161,9 @@ export default function handleSocket({
}
dispatch(action);
if (type in afterHandlers) {
afterHandlers[type](data);
}
});
}

View file

@ -66,8 +66,10 @@ export const socket = createSocketActions([
'cert_fail',
'cert_success',
'channels',
'channel_forward',
'channel_search',
'connection_update',
'error',
'join',
'message',
'mode',

View file

@ -140,6 +140,11 @@ export default createReducer(
state[server][channel].users.push(createUser(user));
},
[actions.socket.CHANNEL_FORWARD](state, action) {
init(state, action.server, action.new);
delete state[action.server][action.old];
},
[actions.socket.PART](state, { server, channel, user }) {
if (state[server][channel]) {
removeUser(state[server][channel].users, user);
@ -230,16 +235,27 @@ export function join(channels, server) {
}
export function part(channels, server) {
return dispatch => {
dispatch({
return (dispatch, getState) => {
const action = {
type: actions.PART,
channels,
server,
socket: {
server
};
const state = getState().channels[server];
const joined = channels.filter(c => state[c] && state[c].joined);
if (joined.length > 0) {
action.socket = {
type: 'part',
data: { channels, server }
}
});
data: {
channels: joined,
server
}
};
}
dispatch(action);
dispatch(updateSelection());
};
}

View file

@ -140,6 +140,12 @@ export default createReducer(
channels.forEach(channel => delete state[server][channel]);
},
[actions.socket.CHANNEL_FORWARD](state, { server, old }) {
if (state[server]) {
delete state[server][old];
}
},
[actions.UPDATE_MESSAGE_HEIGHT](
state,
{ wrapWidth, charWidth, windowWidth }