182 lines
4.9 KiB
TypeScript
182 lines
4.9 KiB
TypeScript
import { IIRCLine, IRCConnectionEvents, NickListEvents } from '@icynet/irclib';
|
|
import { useEffect, useReducer } from 'react';
|
|
import { IRCConnectionWrapper, IRCManager } from '../../lib/irc-manager';
|
|
import { BufferActionKind, BufferType } from '../../lib/client-view.types';
|
|
import { ClientViewReducer, getBuffer } from '../../lib/client.reducer';
|
|
import { MessageBufferWrapper } from '../MessageBufferWrapper/MessageBufferWrapper';
|
|
import { ViewTabs } from '../ViewTabs/ViewTabs';
|
|
|
|
export const ClientView = ({ manager }: { manager: IRCManager }) => {
|
|
const [state, dispatch] = useReducer(ClientViewReducer, {
|
|
buffers: [],
|
|
activeIndex: 0,
|
|
});
|
|
|
|
useEffect(() => {
|
|
const firstConnection = manager.connections[0];
|
|
dispatch({
|
|
type: BufferActionKind.AddBuffer,
|
|
payload: {
|
|
connection: firstConnection,
|
|
toBuffer: {
|
|
type: 'server',
|
|
name: firstConnection.connection.options.host,
|
|
},
|
|
},
|
|
});
|
|
}, [manager.connections]);
|
|
|
|
useEffect(() => {
|
|
const handlers: [
|
|
IRCConnectionWrapper,
|
|
keyof IRCConnectionEvents,
|
|
(...args: any) => void,
|
|
][] = [];
|
|
|
|
manager.connections.forEach((conn) => {
|
|
const lineHandler = (line: IIRCLine, processed: boolean) => {
|
|
if (processed) return;
|
|
let target: BufferType = 'server';
|
|
let targetName: string | undefined;
|
|
|
|
if (line.arguments[1] || (!line.arguments[1] && line.arguments[0])) {
|
|
const targetTest = line.arguments[line.arguments.length - 1];
|
|
const exists = getBuffer(state, {
|
|
connection: conn,
|
|
toBuffer: {
|
|
name: targetTest,
|
|
},
|
|
});
|
|
if (exists) {
|
|
target = exists.type;
|
|
targetName = exists.name;
|
|
}
|
|
}
|
|
|
|
if (
|
|
(line.command === 'NOTICE' || line.command === 'PRIVMSG') &&
|
|
line.arguments[0] === conn.connection.options.nick &&
|
|
line.user.nickname
|
|
) {
|
|
dispatch({
|
|
type: BufferActionKind.AddBuffer,
|
|
payload: {
|
|
connection: conn,
|
|
toBuffer: {
|
|
type: 'user',
|
|
name: line.user.nickname,
|
|
},
|
|
},
|
|
});
|
|
target = 'user';
|
|
targetName = line.user.nickname;
|
|
}
|
|
|
|
dispatch({
|
|
type: BufferActionKind.AddBufferLine,
|
|
payload: {
|
|
connection: conn,
|
|
toBuffer: {
|
|
type: target,
|
|
name: targetName,
|
|
},
|
|
message: {
|
|
type: 'privmsg',
|
|
time: new Date(),
|
|
sender: line.user
|
|
? line.user.nickname || line.user.hostname
|
|
: '--',
|
|
message: line.trailing,
|
|
},
|
|
},
|
|
});
|
|
|
|
if (
|
|
line.command === 'JOIN' &&
|
|
line.user.nickname === conn.connection.options.nick
|
|
) {
|
|
dispatch({
|
|
type: BufferActionKind.AddBuffer,
|
|
payload: {
|
|
connection: conn,
|
|
toBuffer: {
|
|
type: 'channel',
|
|
name: line.trailing,
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
if (line.command === '332' || line.command === 'TOPIC') {
|
|
dispatch({
|
|
type: BufferActionKind.SetTopic,
|
|
payload: {
|
|
connection: conn,
|
|
toBuffer: {
|
|
type: 'channel',
|
|
name: line.arguments[line.arguments.length - 1],
|
|
},
|
|
topic: line.trailing,
|
|
},
|
|
});
|
|
}
|
|
};
|
|
|
|
conn.connection.on('line', lineHandler);
|
|
handlers.push([conn, 'line', lineHandler]);
|
|
});
|
|
|
|
return () =>
|
|
handlers.forEach(([main, evt, handler]) =>
|
|
main.connection.removeEventListener(evt, handler),
|
|
);
|
|
}, [manager.connections, state]);
|
|
|
|
useEffect(() => {
|
|
const handlers: [
|
|
IRCConnectionWrapper,
|
|
keyof NickListEvents,
|
|
(...args: any) => void,
|
|
][] = [];
|
|
|
|
manager.connections.forEach((conn) => {
|
|
const handler = (channels?: string[]) => {
|
|
dispatch({
|
|
type: BufferActionKind.UpdateNicklist,
|
|
payload: {
|
|
connection: conn,
|
|
channels,
|
|
},
|
|
});
|
|
};
|
|
|
|
conn.nicklist.on('update', handler);
|
|
handlers.push([conn, 'update', handler]);
|
|
});
|
|
|
|
return () =>
|
|
handlers.forEach(([main, evt, handler]) =>
|
|
main.nicklist.removeEventListener(evt, handler),
|
|
);
|
|
}, [manager.connections]);
|
|
|
|
return (
|
|
<>
|
|
<ViewTabs
|
|
buffers={state.buffers}
|
|
activeIndex={state.activeIndex}
|
|
setActive={(index) => {
|
|
dispatch({
|
|
type: BufferActionKind.SetActiveBuffer,
|
|
payload: {
|
|
activeIndex: index,
|
|
},
|
|
});
|
|
}}
|
|
/>
|
|
|
|
<MessageBufferWrapper state={state} dispatch={dispatch} />
|
|
</>
|
|
);
|
|
};
|