<commit_before>import _ from 'lodash'
import { autorun, extendObservable } from 'mobx'
import { handleActions } from 'utils/actions'
import config from 'config'
import state, { Node } from './state'
import {
  loadNodeData,
  toggleNodeFold,
  selectNode,
  highlightDirNode,
  removeNode,
  openContextMenu,
  closeContextMenu,
} from './actions'

const ROOT_PATH = ''

handleActions({
  [loadNodeData]: (state, payload) => {
    payload.forEach(nodeInfo => {
      let nextNodeInfo = { ...nodeInfo, path: ROOT_PATH + nodeInfo.path }
      const curNodeInfo = state.nodes.get(nextNodeInfo.path)
      if (curNodeInfo) nextNodeInfo = {...curNodeInfo, ...nextNodeInfo}
      state.nodes.set(nextNodeInfo.path, new Node(nextNodeInfo))
    })
  },

  [selectNode]: (state, payload) => {
    const { node: nodeOrOffset, multiSelect } = payload
    let offset, node
    if (typeof nodeOrOffset === 'number') {
      offset = nodeOrOffset
    } else {
      node = nodeOrOffset
    }

    if (offset === 1) {
      node = state.focusedNodes[0].next(true)
    } else if (offset === -1) {
      node = state.focusedNodes[0].prev(true)
    }

    if (!multiSelect) {
      state.root.unfocus()
      state.root.forEachDescendant(childNode => childNode.unfocus())
    }

    node.focus()
  },

  [highlightDirNode]: (state, payload) => {
    node = payload
    if (node.isDir) node.highlight()
  },

  [toggleNodeFold]: (state, payload) => {
    let { node, shouldBeFolded, deep } = payload
    if (!node.isDir) return state
    let isFolded
    if (typeof shouldBeFolded === 'boolean') {
      isFolded = shouldBeFolded
    } else {
      isFolded = !node.isFolded
    }
    node.toggleFold(isFolded)
    if (deep) {
      node.forEachDescendant(childNode => {
        childNode.toggleFold(isFolded)
      })
    }
  },

  [removeNode]: (state, payload) => {
    let node = payload
    state.nodes.delete(node.path)
  },

  [openContextMenu]: (state, payload) => {
    extendObservable(state.contextMenuState, payload)
  },

  [closeContextMenu]: (state, payload) => {
    contextMenuState.isActive = false
  },
}, state)


let reduxState
autorun(() => {
  reduxState = state.toJS()
})

function reducer (prevState, action) {
  return reduxState
}

export default reducer
<commit_msg>:bug: fix 181<commit_after>import _ from 'lodash'
import { autorun, extendObservable } from 'mobx'
import { handleActions } from 'utils/actions'
import config from 'config'
import state, { Node } from './state'
import {
  loadNodeData,
  toggleNodeFold,
  selectNode,
  highlightDirNode,
  removeNode,
  openContextMenu,
  closeContextMenu,
} from './actions'

const ROOT_PATH = ''

handleActions({
  [loadNodeData]: (state, payload) => {
    payload.forEach(nodeInfo => {
      let nextNodeInfo = { ...nodeInfo, path: ROOT_PATH + nodeInfo.path }
      const curNodeInfo = state.nodes.get(nextNodeInfo.path)
      if (curNodeInfo) nextNodeInfo = {...curNodeInfo, ...nextNodeInfo}
      state.nodes.set(nextNodeInfo.path, new Node(nextNodeInfo))
    })
  },

  [selectNode]: (state, payload) => {
    const { node: nodeOrOffset, multiSelect } = payload
    let offset, node
    if (typeof nodeOrOffset === 'number') {
      offset = nodeOrOffset
    } else {
      node = nodeOrOffset
    }

    if (offset === 1) {
      node = state.focusedNodes[0].next(true)
    } else if (offset === -1) {
      node = state.focusedNodes[0].prev(true)
    }

    if (!multiSelect) {
      state.root.unfocus()
      state.root.forEachDescendant(childNode => childNode.unfocus())
    }

    node.focus()
  },

  [highlightDirNode]: (state, payload) => {
    node = payload
    if (node.isDir) node.highlight()
  },

  [toggleNodeFold]: (state, payload) => {
    let { node, shouldBeFolded, deep } = payload
    if (!node.isDir) return state
    let isFolded
    if (typeof shouldBeFolded === 'boolean') {
      isFolded = shouldBeFolded
    } else {
      isFolded = !node.isFolded
    }
    node.toggleFold(isFolded)
    if (deep) {
      node.forEachDescendant(childNode => {
        childNode.toggleFold(isFolded)
      })
    }
  },

  [removeNode]: (state, payload) => {
    let node = payload
    state.nodes.delete(node.path)
  },

  [openContextMenu]: (state, payload) => {
    extendObservable(state.contextMenuState, payload)
  },

  [closeContextMenu]: (state, payload) => {
    state.contextMenuState.isActive = false
  },
}, state)


let reduxState
autorun(() => {
  reduxState = state.toJS()
})

function reducer (prevState, action) {
  return reduxState
}

export default reducer

{'fraction_non_alphanumeric': 0.13718173836698858, 'fraction_numerical': 0.002414398595258999, 'mean_word_length': 3.06875, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6626322', 'n_tokens_mistral': 1537, 'n_tokens_neox': 1485, 'n_words': 322}