import { List, Map, Record } from 'immutable'; import { createSelector } from 'reselect'; import createReducer from '../util/createReducer'; import { messageHeight } from '../util'; import * as actions from '../actions'; import { getSelectedTab } from './tab'; const Message = Record({ id: null, from: null, content: '', time: null, type: null, channel: false, next: false, height: 0, length: 0, breakpoints: null }); export const getMessages = state => state.messages; export const getSelectedMessages = createSelector( getSelectedTab, getMessages, (tab, messages) => messages.getIn([tab.server, tab.name || tab.server], List()) ); export default createReducer(Map(), { [actions.ADD_MESSAGE](state, { server, tab, message }) { return state.updateIn([server, tab], List(), list => list.push(new Message(message))); }, [actions.ADD_MESSAGES](state, { server, tab, messages, prepend }) { return state.withMutations(s => { if (prepend) { for (let i = messages.length - 1; i >= 0; i--) { s.updateIn([server, tab], List(), list => list.unshift(new Message(messages[i]))); } } else { messages.forEach(message => s.updateIn([server, message.tab || tab], List(), list => list.push(new Message(message))) ); } }); }, [actions.DISCONNECT](state, { server }) { return state.delete(server); }, [actions.PART](state, { server, channels }) { return state.withMutations(s => channels.forEach(channel => s.deleteIn([server, channel]) ) ); }, [actions.UPDATE_MESSAGE_HEIGHT](state, { wrapWidth, charWidth }) { return state.withMutations(s => s.forEach((server, serverKey) => server.forEach((target, targetKey) => target.forEach((message, index) => s.setIn([serverKey, targetKey, index, 'height'], messageHeight(message, wrapWidth, charWidth, 6 * charWidth)) ) ) ) ); } });