mediawiki-extensions-Popups/resources/ext.popups/reducers/eventLogging.js
Sam Smith fcfe079d79 Hygiene: Organize reducers
Reducer changes:
* Break the mw.popups.reducers.rootReducer test into @@INIT tests
  for each reducer as there's shouldn't be any need to test that a
  framework works as documented.

Changes:
* Move the mw.popups.reducers#preview, #eventLogging, and #settings
  reducers into their own files in resources/ext.popups/reducers/.
* Make the associated tests mirror the new layout.
* Move the initialization of the mw.popups.reducers namespace into its
  own file.
* Remove the mw.popups.rootReducer property in favour of a simple
  private factory function per the reducer change above.

Change-Id: I94229d9ef1985f3806eec44c2e8234a5bbddc94f
2016-12-13 18:45:10 +00:00

114 lines
3.4 KiB
JavaScript

( function ( popups, nextState ) {
/**
* Reducer for actions that may result in an event being logged via Event
* Logging.
*
* The base data represents data that's shared between all events logged with
* the Popups schema ("Popups events"). Very nearly all of it is initialized
* during the BOOT action and doesn't change between link interactions, e.g.
* the user being an anon or the number of edits they've made.
*
* The user's number of previews, however, does change between link
* interactions and the associated bucket (a computed property) is what is
* logged. This is reflected in the state tree: the `previewCount` property is
* used to store the user's number of previews and the
* `baseData.previewCountBucket` property is used to store the associated
* bucket.
*
* @param {Object} state
* @param {Object} action
* @return {Object} The state as a result of processing the action
*/
popups.reducers.eventLogging = function ( state, action ) {
var nextCount;
if ( state === undefined ) {
state = {
previewCount: undefined,
baseData: {},
interaction: undefined,
event: undefined
};
}
switch ( action.type ) {
case popups.actionTypes.BOOT:
return nextState( state, {
previewCount: action.user.previewCount,
baseData: {
pageTitleSource: action.page.title,
namespaceIdSource: action.page.namespaceID,
pageIdSource: action.page.id,
isAnon: action.user.isAnon,
popupEnabled: action.user.isInCondition,
pageToken: action.pageToken,
sessionToken: action.sessionToken,
editCountBucket: popups.counts.getEditCountBucket( action.user.editCount ),
previewCountBucket: popups.counts.getPreviewCountBucket( action.user.previewCount )
},
event: {
action: 'pageLoaded'
}
} );
case popups.actionTypes.EVENT_LOGGED:
return nextState( state, {
event: undefined
} );
case popups.actionTypes.PREVIEW_SHOW:
nextCount = state.previewCount + 1;
return nextState( state, {
previewCount: nextCount,
baseData: nextState( state.baseData, {
previewCountBucket: popups.counts.getPreviewCountBucket( nextCount )
} ),
interaction: nextState( state.interaction, {
timeToPreviewShow: action.timestamp - state.interaction.started
} )
} );
case popups.actionTypes.LINK_DWELL:
return nextState( state, {
interaction: {
token: action.interactionToken,
started: action.timestamp
}
} );
case popups.actionTypes.LINK_CLICK:
return nextState( state, {
event: {
action: 'opened',
linkInteractionToken: state.interaction.token,
totalInteractionTime: Math.round( action.timestamp - state.interaction.started )
}
} );
case popups.actionTypes.LINK_ABANDON_START:
case popups.actionTypes.PREVIEW_ABANDON_START:
return nextState( state, {
interaction: nextState( state.interaction, {
finished: action.timestamp
} )
} );
case popups.actionTypes.LINK_ABANDON_END:
case popups.actionTypes.PREVIEW_ABANDON_END:
return nextState( state, {
event: {
action: state.interaction.timeToPreviewShow ? 'dismissed' : 'dwelledButAbandoned',
linkInteractionToken: state.interaction.token,
totalInteractionTime: Math.round( state.interaction.finished - state.interaction.started )
}
} );
default:
return state;
}
};
}( mediaWiki.popups, mediaWiki.popups.nextState ) );