🏡 index : quine-global/hyper.git

import Immutable from 'seamless-immutable';
import { decorateSessionsReducer } from '../utils/plugins';
import {
  SESSION_ADD,
  SESSION_PTY_EXIT,
  SESSION_USER_EXIT,
  SESSION_PTY_DATA,
  SESSION_SET_ACTIVE,
  SESSION_CLEAR_ACTIVE,
  SESSION_URL_SET,
  SESSION_URL_UNSET,
  SESSION_SET_XTERM_TITLE,
  SESSION_SET_PROCESS_TITLE
} from '../constants/sessions';

const initialState = Immutable({
  sessions: {},
  write: null,
  activeUid: null
});

function Session (obj) {
  return Immutable({
    uid: '',
    title: '',
    write: null,
    url: null,
    cleared: false
  }).merge(obj);
}

function Write (obj) {
  return Immutable({
    uid: '',
    data: ''
  }).merge(obj);
}

const reducer = (state = initialState, action) => {
  // prune the last write to the terminal
  if (state.write) {
    state = state.set('write', null);
  }

  switch (action.type) {
    case SESSION_ADD:
      return state.setIn(['sessions', action.uid], Session({ uid: action.uid }));

    case SESSION_URL_SET:
      return state.setIn(['sessions', action.uid, 'url'], action.url);

    case SESSION_URL_UNSET:
      return state.setIn(['sessions', action.uid, 'url'], null);

    case SESSION_SET_ACTIVE:
      return state.set('activeUid', action.uid);

    case SESSION_CLEAR_ACTIVE:
      return state.merge({
        sessions: {
          [state.activeUid]: {
            cleared: true
          }
        }
      }, { deep: true });

    case SESSION_PTY_DATA:
      return state.merge({
        write: Write(action),
        sessions: {
          [action.uid]: {
            cleared: false
          }
        }
      }, { deep: true });

    case SESSION_PTY_EXIT:
      if (state.sessions[action.uid]) {
        return deleteSession(state, action.uid);
      } else {
        console.log('ignore pty exit: session removed by user');
        return state;
      }

    case SESSION_USER_EXIT:
      return deleteSession(state, action.uid);

    case SESSION_SET_XTERM_TITLE:
    case SESSION_SET_PROCESS_TITLE:
      return state.setIn(['sessions', action.uid, 'title'], action.title);

    default:
      return state;
  }
};

export default decorateSessionsReducer(reducer);

function deleteSession (state, uid) {
  return state.updateIn(['sessions'], (sessions) => {
    const sessions_ = sessions.asMutable();
    delete sessions_[uid];
    return sessions_;
  });
}