<commit_before>import { createTrackObj } from './utils'

const addTrack = (state, action) => {
  let { name, segments, locations, transModes } = action
  let track = createTrackObj(name, segments, locations, transModes, state.get('segments').count())
  const ctrack = track.track
  const csegments = track.segments
  state = state.setIn(['tracks', ctrack.get('id')], ctrack)
  csegments.forEach((cs) => {
    state = state.setIn(['segments', cs.get('id')], cs)
  })

  return state
}

const updateTrackName = (state, action) => {
  return state.setIn(['tracks', action.trackId, 'name'], action.name)
}

const toggleTrackRenaming = (state, action) => {
  let id = action.trackId
  return state.setIn(['tracks', action.trackId, 'renaming'], !state.get('tracks').get(id).get('renaming'))
}

import { addTrack as addTrackAction } from '../actions/tracks'

const removeTracksFor = (state, action) => {
  state = state
    .updateIn(['tracks'], (tracks) => {
      return tracks.clear()
    })
    .updateIn(['segments'], (segments) => {
      return segments.clear()
    })
  return addTrack(state, addTrackAction(action.segments.map((s) => s.points), action.name, action.locations, action.segments.map((s) => s.transportationModes)))
}

const undo = (state, action) => {
  let toPut = state.get('history').get('past').get(-1)
  if (toPut) {
    return toPut.undo(toPut, state)
    .updateIn(['history', 'past'], (past) => past.pop())
    .updateIn(['history', 'future'], (future) => future.push(toPut))
  } else {
    return state
  }
}

const redo = (state, action) => {
  return state
  .updateIn(['history', 'future'], (future) => future.pop())
}

const ACTION_REACTION = {
  'ADD_TRACK': addTrack,
  'TOGGLE_TRACK_RENAMING': toggleTrackRenaming,
  'UPDATE_TRACK_NAME': updateTrackName,
  'REMOVE_TRACKS_FOR': removeTracksFor,
  'UNDO': undo,
  'REDO': redo
}

import segments from './segments'
import { fromJS } from 'immutable'

const initalState = fromJS({
  tracks: {},
  segments: {},
  history: {
    past: [],
    future: []
  }
})

const tracks = (state = initalState, action) => {
  let result
  if (ACTION_REACTION[action.type]) {
    result = ACTION_REACTION[action.type](state, action)
  } else {
    result = segments(state, action)
  }
  // TODO: false is temporary
  if (result !== state && action.undo) {
    return result.updateIn(['history', 'past'], (past) => {
      return past.push(action)
    })
  } else {
    return result
  }
}
<commit_msg>Add undo/redo limit<commit_after>import { createTrackObj } from './utils'

const addTrack = (state, action) => {
  let { name, segments, locations, transModes } = action
  let track = createTrackObj(name, segments, locations, transModes, state.get('segments').count())
  const ctrack = track.track
  const csegments = track.segments
  state = state.setIn(['tracks', ctrack.get('id')], ctrack)
  csegments.forEach((cs) => {
    state = state.setIn(['segments', cs.get('id')], cs)
  })

  return state
}

const updateTrackName = (state, action) => {
  return state.setIn(['tracks', action.trackId, 'name'], action.name)
}

const toggleTrackRenaming = (state, action) => {
  let id = action.trackId
  return state.setIn(['tracks', action.trackId, 'renaming'], !state.get('tracks').get(id).get('renaming'))
}

import { addTrack as addTrackAction } from '../actions/tracks'

const removeTracksFor = (state, action) => {
  state = state
    .updateIn(['tracks'], (tracks) => {
      return tracks.clear()
    })
    .updateIn(['segments'], (segments) => {
      return segments.clear()
    })
  return addTrack(state, addTrackAction(action.segments.map((s) => s.points), action.name, action.locations, action.segments.map((s) => s.transportationModes)))
}

const undo = (state, action) => {
  let toPut = state.get('history').get('past').get(-1)
  if (toPut) {
    return toPut.undo(toPut, state)
    .updateIn(['history', 'past'], (past) => past.pop())
    .updateIn(['history', 'future'], (future) => {
      future = future.push(toPut)
      if (UNDO_LIMIT !== Infinity) {
        return future.slice(future.count() - UNDO_LIMIT)
      } else {
        return future
      }
    })
  } else {
    return state
  }
}

const redo = (state, action) => {
  return state
  .updateIn(['history', 'future'], (future) => future.pop())
}

const ACTION_REACTION = {
  'ADD_TRACK': addTrack,
  'TOGGLE_TRACK_RENAMING': toggleTrackRenaming,
  'UPDATE_TRACK_NAME': updateTrackName,
  'REMOVE_TRACKS_FOR': removeTracksFor,
  'UNDO': undo,
  'REDO': redo
}

import segments from './segments'
import { fromJS } from 'immutable'

const initalState = fromJS({
  tracks: {},
  segments: {},
  history: {
    past: [],
    future: []
  }
})

// Number or Infinity
const UNDO_LIMIT = 50

const tracks = (state = initalState, action) => {
  let result
  if (ACTION_REACTION[action.type]) {
    result = ACTION_REACTION[action.type](state, action)
  } else {
    result = segments(state, action)
  }
  // TODO: false is temporary
  if (result !== state && action.undo) {
    return result.updateIn(['history', 'past'], (past) => {
      past = past.push(action)
      if (UNDO_LIMIT !== Infinity) {
        return past.slice(past.count() - UNDO_LIMIT)
      } else {
        return past
      }
    })
  } else {
    return result
  }
}

{'fraction_non_alphanumeric': 0.17247915087187263, 'fraction_numerical': 0.000758150113722517, 'mean_word_length': 3.6699115044247788, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 35, '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': '4974521', 'n_tokens_mistral': 1806, 'n_tokens_neox': 1772, 'n_words': 393}