[parseFootprintResult]: (state, result)=>{ if (state.has('result_takeaction_pounds')) { if (state.hasIn(['result_takeaction_pounds', 'more_efficient_vehicle'])) { if(Map.isMap(result)) result = result.toJS(); result = Object.keys(result).reduce((hash, api_key)=>{ if (!/^(result|input)_takeaction/.test(api_key)){ hash[api_key] = result[api_key] } return hash; }, {}); let merged_data = state.get('data') .merge(result); setLocalStorageItem('user_footprint', merged_data); let updated = state.set('data', merged_data) .set('loading', false); return loop( fromJS(updated), Effects.constant(updateRemoteUserAnswers()) ); } } state = state.set('data', state.get('data').merge(result)); return loop( fromJS(state), Effects.constant(parseTakeactionResult(result)) ); },
export default (state = initialState, action) => { if (action.type === TOGGLE_SIDEBAR) { return loop({ ...state, isCollapsed: !state.isCollapsed, }, Effects.none() ); }; return loop(state, Effects.none()); }
[Actions.incrementBothStart]: (state, amount) => loop( state, Effects.batch([ Effects.constant(Actions.shortIncrementStart(amount)), Effects.constant(Actions.longIncrementStart(amount)) ]) )
export default (isCollapsed) => { return loop({ isCollapsed, }, Effects.none() ); }
const devicesReducer = (state = initialState, action) => { switch (action.type) { case SET_CONFIG: { if (state.initialized) return state const nextState = state.set('initialized', true) return loop( nextState, Cmd.run(watchSerialPorts, { args: [Cmd.getState, Cmd.dispatch], }), ) } case DEVICE_CONNECTED: { const { device } = action.payload return state.setIn(['byID', device.id], device) } case DEVICE_DISCONNECTED: { const { device } = action.payload // console.log('DISCONNECT', device.id) return state.removeIn(['byID', device.id]) } default: { return state } } }
export default () => { return loop( JSON.parse(localStorage.me) , Effects.none() ); }
it('FETCH_THREADS', () => { const action = fetchThreads('test'); const state = Map(); assert.deepEqual( ThreadsStateReducer(state, action), loop( state.set('fetching', true), Effects.promise(fetchThreadsFromAPI, action.payload) ) ); });
[login]: (current_session)=>{ return loop( current_session.set('loading', true), Effects.promise(()=>{ let api = new SessionApi(); return api.login() .then(loggedIn) .catch(sessionError); }) ) },
export default (tasks) => (state = {}, action) => { if (action.type === TRANSITION) { return loop( state , Effects.call(tasks.transition, action.method, action.args) ); } if (action.type === UPDATE_LOCATION) { return loop({ ...state, location: action.location, }, Effects.none() ); } return loop(state, Effects.none()); }
const handleLoad = state => ( loop({ ...state, loaded: false, loading: true }, Effects.batch([ Effects.promise(fetchTasks), ]) ) );
[updateTakeactionResult]: (state)=>{ return loop( state, Effects.promise(()=>{ return CalculatorApi.computeTakeactionResults(state.get('data').toJS()) .then(parseTakeactionResult) .catch(userFootprintError) }) ) },
const handleFetch = (state, payload) => { const { country, year } = payload return loop({ ...state, isLoaded: false, isLoading: true, error: undefined }, Effects.promise(request(country, year)) ) }
[LOAD]: (state) => { return loop( { ...state, loaded: false, loading: true }, Effects.batch([ Effects.promise(fetchSettings), ]) ); },
[ensureDefaults]: (state, default_inputs)=>{ state = state.set('loading', true) .set('reset', false); return loop( state, Effects.promise(()=>{ return CalculatorApi.getDefaultsAndResults(default_inputs) .then(defaultsRetrieved) .catch(defaultsRetrievalError) }) ) },
[logout]: (current_session)=>{ return loop( current_session .set('loading', true) .set('token', null), Effects.promise(()=>{ let api = new SessionApi(); return api.logout() .then(loggedOut) .catch(sessionError); }) ) },
[footprintRetrieved]: (state, api_data)=>{ let merged_data = state.get('data') .merge(api_data); setLocalStorageItem('user_footprint', merged_data.toJS()); let updated = state.set('data', merged_data) return loop( fromJS(updated), Effects.constant(parseFootprintResult(merged_data)) ) },
[ensureFootprintComputed]: (state, payload)=>{ let updated = state.set('data', payload) .set('loading', true); return loop( updated, Effects.promise(()=>{ return CalculatorApi.computeFootprint(payload.toJS()) .then(footprintRetrieved) .catch(userFootprintError) }) ) },
[averageFootprintUpdated]: (state, api_data)=>{ let merged_data = state.get('data').merge(api_data); setLocalStorageItem('average_footprint', merged_data); let updated = state.set('data', merged_data) .set('loading', false) .set('reset', false); return loop( fromJS(updated), Effects.constant(footprintRetrieved(merged_data.toJS())) ) },
const configReducer = (state = initialState, action) => { switch (action.type) { case SET_CONFIG: { const { config } = action.payload // If the config is being changed by a user then save it to disk. if (state != null) { return loop( config, Cmd.run(saveConfig, { args: [{ config }], }), ) } return config } case CREATE_INVITE: { const { invite } = action.payload const nextConfig = state .updateIn(['auth', 'invites'], invites => invites.push(invite)) const nextAction = requestSetConfig({ config: nextConfig, }) return loop( state, Cmd.action(nextAction), ) } default: { return state } } }
const reducer: Reducer<State, Action> = (state: State, action) => { switch(action.type) { case 'FIRST': return loop( { ...state, first: true }, Effects.constant({ type: 'SECOND' }) ); case 'SECOND': return { ...state, second: true }; default: // $ExpectError return {} } }
[defaultsRetrieved]: (state, api_data)=>{ setLocalStorageItem('average_footprint', api_data); if (!api_data.failed) { state = state.set('data', state.get('data').merge(api_data)) .set('reset', false); return loop( state, Effects.promise(()=>{ return CalculatorApi.computeFootprint(api_data) .then(averageFootprintUpdated) .catch(defaultsRetrievalError) }) ) } else { return Effects.constant(defaultsRetrievalError(api_data)) } },
const delayReducer = (state, action) => { switch (action.type) { case DESPOOL_TASK: { const { macro, args } = action.payload if (macro === DELAY) { return loop(state, Cmd.run(Promise.delay, { args: [args.period], successActionCreator: despoolCompleted, })) } return state } default: { return state } } }
[updatedFootprintComputed]: (state, payload)=>{ let params = payload; if(Map.isMap(payload)) params = payload.toJS(); let merged_data = state.get('data') .merge(payload); setLocalStorageItem('user_footprint', merged_data); let updated = state.set('data', merged_data); return loop( fromJS(updated), Effects.promise(()=>{ return CalculatorApi.computeFootprint(params) .then(parseFootprintResult) .catch(userFootprintError) }) ) },
// Reducer export default function ProgressStateReducer(state = initialState, action = {}) { switch (action.type) { case CHANGE_SEARCH_PROPERTIES: return state.set('searchProperties',action.payload); case OPEN_SEARCH: return state.set('searchOpen',true); case REQUEST_GEONODES: return loop( state.set('loading',true), Effects.promise(receiveGeonodes,action.payload) ); case RECEIVE_GEONODES: return state.set('geonodesList', action.payload); default: return state; } }
const counter = (state = 0, action) => { switch (action.type) { case INCREMENT_ASYNC: return loop( state, Effect.promise(Api.incrementAsync, action.payload) ); case INCREMENT_COUNTER: return state + 1; case DECREMENT_COUNTER: return state - 1; case INCREMENT_IF_ODD: return state % 2 ? state + 1 : state; default: return state; } };
export default function ThreadsStateReducer(state = initialState, action = {}) { switch (action.type) { case ACTION_TYPES.FETCH_THREADS: { return loop( state.set('fetching', true), Effects.promise(fetchThreadsFromAPI, action.payload) ); } case ACTION_TYPES.THREADS_UPDATED: { return state .set('fetching', false) .set('threadsFetched', true) .set('threads', fromJS(action.payload)) .update('threads', threads => threads.map(thread => thread.set('lastMessage', thread.get('messages').last()) ) ); } case ACTION_TYPES.FETCHING_ERROR: { return state .set('fetching', false) .set('fetchingError', fromJS(action.payload)); } case ACTION_TYPES.NEW_MESSAGE: { return state.update('threads', threads => threads .map(thread => ThreadStateReducer(thread, action)) .map(thread => thread.set('lastMessage', thread.get('messages').last()) ) ); } default: { return state; } } }
[parseTakeactionResult]: (state, result)=>{ let merged = state.get('data') .merge(result); if(!Map.isMap(result)) result = new Map(result); let updated = state.set('data', merged) .set('result_takeaction_pounds', fromJS(JSON.parse(result.get('result_takeaction_pounds')))) .set('result_takeaction_dollars', fromJS(JSON.parse(result.get('result_takeaction_dollars')))) .set('result_takeaction_net10yr', fromJS(JSON.parse(result.get('result_takeaction_net10yr')))) .set('loading', false); setLocalStorageItem('result_takeaction_pounds', fromJS(result.get('result_takeaction_pounds'))); setLocalStorageItem('result_takeaction_dollars', fromJS(result.get('result_takeaction_dollars'))); setLocalStorageItem('result_takeaction_net10yr', fromJS(result.get('result_takeaction_net10yr'))); setLocalStorageItem('user_footprint', merged); return loop( fromJS(updated), Effects.constant(updateRemoteUserAnswers()) ); },
export default function friendListReducer(state = initialState, action) { switch (action.type) { case types.FETCH_FRIENDS: return loop( Object.assign({}, state, { loading: true }), Effects.promise(searchFriends, action.query) ); case types.SET_QUERY: return Object.assign({}, state, { query: action.query }); case types.SET_FRIENDS: return Object.assign({}, state, { friends: action.friends, loading: false }); default: return state; } }
) => (state = initialState, action) => { switch (action.type) { case SET_CONFIG: { const { config } = action.payload const enabled = isMacroEnabled({ config, meta }) return state.merge({ config, enabled, }) } case DESPOOL_TASK: { const { macro, args } = action.payload if (macro === meta.macro && state.enabled) { // expand the macro into it's expanded gcode (an array of strings) const data = macroFn(args, state) /* * 1. insert the expanded gcode lines in a task before everything else * effectively swapping the host macro for the expanded gcode lines * 2. despool the first line of that expanded gcode */ const actions = [ Cmd.action(spoolMacroExpansion({ action, data })), Cmd.action(despoolCompleted()), ] return loop(state, Cmd.list(actions)) } return state } default: { return state } } }
const autodropJobStatusReducer = (state = initialState, action) => { switch (action.type) { case SET_CONFIG: { const { config } = action.payload const autodropConfig = getPluginModels(config).get(PACKAGE).toJS() const nextState = initialState.merge({ config: autodropConfig, }) return nextState } case JOB_DOWNLOAD_COMPLETE: { const content = action.payload const lines = content.split('\n') const autodropIsEmpty = lines[0].indexOf(';START') === -1 if (autodropIsEmpty) { debug(`got nothing: ${lines.slice(0, 5).join('\n')}`) return state } debug(`got a job:\n${lines.slice(0, 5).join('\n')}`) const autodropJobID = lines[2].replace(';', '').trim() const name = `AUTODROP JOB #${autodropJobID}` const nextAction = requestCreateJob({ name, meta: { autodropJobID }, files: [{ name, content, }], }) const nextState = state.merge({ teghJobID: nextAction.payload.job.id, autodropJobID, }) // bug: returning an action without a list here fails due to an // unknown issue with redux-loop. It is something to do with the // Cmd.list we return from the autodropJobDownloadReducer.js // simultaneously. return loop( nextState, Cmd.list([ Cmd.action(nextAction), ]), ) } case DESPOOL_TASK: { const { config, lastUpdate, autodropJobID, teghJobID, } = state const { task, isLastLineInTask, } = action.payload if (task.jobID == null || task.jobID !== teghJobID) { return state } if (isLastLineInTask) { return loop(state, Cmd.action(markAutodropJobAsDone())) } if (Date.now() > lastUpdate + UPDATE_INTERVAL) { const percentComplete = getTaskPercentComplete({ task, despooling: true, }) const url = getAutodropURL({ config, params: { jobID: autodropJobID, stat: 'update', jobStatus: percentComplete, }, }) updateDebug(`updating job ${url}`) const nextState = state.set('lastUpdate', Date.now()) return loop( nextState, Cmd.run( fetchFromAutodrop, { args: [{ url }], failActionCreator: autodropUpdateFail, }, ), ) } return state } case MARK_AUTODROP_JOB_AS_DONE: { const { config, autodropJobID, } = state if (autodropJobID == null) { throw new Error('AutoDrop Job ID cannot be Null') } const url = getAutodropURL({ config, params: { jobID: autodropJobID, stat: 'Done', }, }) debug(`marking job as done ${url}`) return loop( state, Cmd.run( fetchFromAutodrop, { args: [{ url }], successActionCreator: autodropJobDone, failActionCreator: autodropJobDoneFail, }, ), ) } case AUTODROP_JOB_DONE: { return state.merge({ autodropJobID: null, teghJobID: null, }) } case AUTODROP_JOB_DONE_FAIL: { return loop( state, Cmd.run(Promise.delay, { args: [RETRY_DELAY_AFTER_ERROR], successActionCreator: markAutodropJobAsDone, }), ) } default: { return state } } }