refactor: expose an object of available actions (#520)

Referencing actions as properties of an object is more reliable than
just hardcoding strings everywhere.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
Juan Cruz Viotti 2016-06-23 16:10:22 -04:00 committed by GitHub
parent 5ac5f3a423
commit 78da500816
4 changed files with 66 additions and 46 deletions

View File

@ -22,7 +22,7 @@
const angular = require('angular'); const angular = require('angular');
const _ = require('lodash'); const _ = require('lodash');
const store = require('./store'); const Store = require('./store');
const MODULE_NAME = 'Etcher.Models.Drives'; const MODULE_NAME = 'Etcher.Models.Drives';
const Drives = angular.module(MODULE_NAME, []); const Drives = angular.module(MODULE_NAME, []);
@ -59,8 +59,8 @@ Drives.service('DrivesModel', function() {
* DrivesModel.setDrives([ ... ]); * DrivesModel.setDrives([ ... ]);
*/ */
this.setDrives = function(drives) { this.setDrives = function(drives) {
store.dispatch({ Store.dispatch({
type: 'SET_AVAILABLE_DRIVES', type: Store.Actions.SET_AVAILABLE_DRIVES,
data: drives data: drives
}); });
}; };
@ -98,7 +98,7 @@ Drives.service('DrivesModel', function() {
* const drives = DrivesModel.getDrives(); * const drives = DrivesModel.getDrives();
*/ */
this.getDrives = memoizeImmutableListReference(function() { this.getDrives = memoizeImmutableListReference(function() {
return store.getState().toJS().availableDrives; return Store.getState().toJS().availableDrives;
}); });
}); });

View File

@ -22,7 +22,7 @@
const _ = require('lodash'); const _ = require('lodash');
const angular = require('angular'); const angular = require('angular');
const store = require('./store'); const Store = require('./store');
const MODULE_NAME = 'Etcher.Models.SelectionState'; const MODULE_NAME = 'Etcher.Models.SelectionState';
const SelectionStateModel = angular.module(MODULE_NAME, []); const SelectionStateModel = angular.module(MODULE_NAME, []);
@ -44,8 +44,8 @@ SelectionStateModel.service('SelectionStateModel', function() {
* }); * });
*/ */
this.setDrive = function(drive) { this.setDrive = function(drive) {
store.dispatch({ Store.dispatch({
type: 'SELECT_DRIVE', type: Store.Actions.SELECT_DRIVE,
data: drive data: drive
}); });
}; };
@ -173,8 +173,8 @@ SelectionStateModel.service('SelectionStateModel', function() {
* }); * });
*/ */
this.setImage = function(image) { this.setImage = function(image) {
store.dispatch({ Store.dispatch({
type: 'SELECT_IMAGE', type: Store.Actions.SELECT_IMAGE,
data: image data: image
}); });
}; };
@ -190,7 +190,7 @@ SelectionStateModel.service('SelectionStateModel', function() {
* const drive = SelectionStateModel.getDrive(); * const drive = SelectionStateModel.getDrive();
*/ */
this.getDrive = function() { this.getDrive = function() {
return _.get(store.getState().toJS(), 'selection.drive'); return _.get(Store.getState().toJS(), 'selection.drive');
}; };
/** /**
@ -204,7 +204,7 @@ SelectionStateModel.service('SelectionStateModel', function() {
* const imagePath = SelectionStateModel.getImagePath(); * const imagePath = SelectionStateModel.getImagePath();
*/ */
this.getImagePath = function() { this.getImagePath = function() {
return _.get(store.getState().toJS(), 'selection.image.path'); return _.get(Store.getState().toJS(), 'selection.image.path');
}; };
/** /**
@ -218,7 +218,7 @@ SelectionStateModel.service('SelectionStateModel', function() {
* const imageSize = SelectionStateModel.getImageSize(); * const imageSize = SelectionStateModel.getImageSize();
*/ */
this.getImageSize = function() { this.getImageSize = function() {
return _.get(store.getState().toJS(), 'selection.image.size'); return _.get(Store.getState().toJS(), 'selection.image.size');
}; };
/** /**
@ -262,8 +262,8 @@ SelectionStateModel.service('SelectionStateModel', function() {
* SelectionStateModel.removeDrive(); * SelectionStateModel.removeDrive();
*/ */
this.removeDrive = function() { this.removeDrive = function() {
store.dispatch({ Store.dispatch({
type: 'REMOVE_DRIVE' type: Store.Actions.REMOVE_DRIVE
}); });
}; };
@ -276,8 +276,8 @@ SelectionStateModel.service('SelectionStateModel', function() {
* SelectionStateModel.removeImage(); * SelectionStateModel.removeImage();
*/ */
this.removeImage = function() { this.removeImage = function() {
store.dispatch({ Store.dispatch({
type: 'REMOVE_IMAGE' type: Store.Actions.REMOVE_IMAGE
}); });
}; };
@ -297,13 +297,13 @@ SelectionStateModel.service('SelectionStateModel', function() {
*/ */
this.clear = function(options = {}) { this.clear = function(options = {}) {
if (!options.preserveImage) { if (!options.preserveImage) {
store.dispatch({ Store.dispatch({
type: 'REMOVE_IMAGE' type: Store.Actions.REMOVE_IMAGE
}); });
} }
store.dispatch({ Store.dispatch({
type: 'REMOVE_DRIVE' type: Store.Actions.REMOVE_DRIVE
}); });
}; };

View File

@ -38,12 +38,30 @@ const DEFAULT_STATE = Immutable.fromJS({
} }
}); });
const store = function(state, action) { /**
* @summary Application supported action messages
* @type Object
* @constant
*/
const ACTIONS = _.fromPairs(_.map([
'SET_AVAILABLE_DRIVES',
'SET_FLASH_STATE',
'RESET_FLASH_STATE',
'SET_FLASHING',
'SELECT_DRIVE',
'SELECT_IMAGE',
'REMOVE_DRIVE',
'REMOVE_IMAGE'
], function(message) {
return [ message, message ];
}));
const storeReducer = function(state, action) {
state = state || DEFAULT_STATE; state = state || DEFAULT_STATE;
switch (action.type) { switch (action.type) {
case 'SET_AVAILABLE_DRIVES': { case ACTIONS.SET_AVAILABLE_DRIVES: {
if (!action.data) { if (!action.data) {
throw new Error('Missing drives'); throw new Error('Missing drives');
} }
@ -64,8 +82,8 @@ const store = function(state, action) {
// TODO: Reuse from SelectionStateModel.isDriveValid() // TODO: Reuse from SelectionStateModel.isDriveValid()
if (state.getIn([ 'selection', 'image', 'size' ], 0) <= drive.size && !drive.protected) { if (state.getIn([ 'selection', 'image', 'size' ], 0) <= drive.size && !drive.protected) {
return store(newState, { return storeReducer(newState, {
type: 'SELECT_DRIVE', type: ACTIONS.SELECT_DRIVE,
data: drive data: drive
}); });
} }
@ -77,15 +95,15 @@ const store = function(state, action) {
if (selectedDevice && !_.find(action.data, { if (selectedDevice && !_.find(action.data, {
device: selectedDevice device: selectedDevice
})) { })) {
return store(newState, { return storeReducer(newState, {
type: 'REMOVE_DRIVE' type: ACTIONS.REMOVE_DRIVE
}); });
} }
return newState; return newState;
} }
case 'SET_FLASH_STATE': { case ACTIONS.SET_FLASH_STATE: {
if (!state.getIn([ 'flash', 'flashing' ])) { if (!state.getIn([ 'flash', 'flashing' ])) {
throw new Error('Can\'t set the flashing state when not flashing'); throw new Error('Can\'t set the flashing state when not flashing');
} }
@ -93,24 +111,24 @@ const store = function(state, action) {
return state.setIn([ 'flash', 'state' ], Immutable.fromJS(action.data)); return state.setIn([ 'flash', 'state' ], Immutable.fromJS(action.data));
} }
case 'RESET_FLASH_STATE': { case ACTIONS.RESET_FLASH_STATE: {
return state.setIn([ 'flash', 'state' ], DEFAULT_STATE.getIn([ 'flash', 'state' ])); return state.setIn([ 'flash', 'state' ], DEFAULT_STATE.getIn([ 'flash', 'state' ]));
} }
case 'SET_FLASHING': { case ACTIONS.SET_FLASHING: {
const value = Boolean(action.data); const value = Boolean(action.data);
const newState = state.setIn([ 'flash', 'flashing' ], value); const newState = state.setIn([ 'flash', 'flashing' ], value);
if (!value) { if (!value) {
return store(newState, { return storeReducer(newState, {
type: 'RESET_FLASH_STATE' type: ACTIONS.RESET_FLASH_STATE
}); });
} }
return newState; return newState;
} }
case 'SELECT_DRIVE': { case ACTIONS.SELECT_DRIVE: {
if (!action.data.device) { if (!action.data.device) {
throw new Error('Missing drive device'); throw new Error('Missing drive device');
} }
@ -151,7 +169,7 @@ const store = function(state, action) {
return state.setIn([ 'selection', 'drive' ], Immutable.fromJS(action.data)); return state.setIn([ 'selection', 'drive' ], Immutable.fromJS(action.data));
} }
case 'SELECT_IMAGE': { case ACTIONS.SELECT_IMAGE: {
if (!action.data.path) { if (!action.data.path) {
throw new Error('Missing image path'); throw new Error('Missing image path');
} }
@ -171,11 +189,11 @@ const store = function(state, action) {
return state.setIn([ 'selection', 'image' ], Immutable.fromJS(action.data)); return state.setIn([ 'selection', 'image' ], Immutable.fromJS(action.data));
} }
case 'REMOVE_DRIVE': { case ACTIONS.REMOVE_DRIVE: {
return state.deleteIn([ 'selection', 'drive' ]); return state.deleteIn([ 'selection', 'drive' ]);
} }
case 'REMOVE_IMAGE': { case ACTIONS.REMOVE_IMAGE: {
return state.deleteIn([ 'selection', 'image' ]); return state.deleteIn([ 'selection', 'image' ]);
} }
@ -186,4 +204,6 @@ const store = function(state, action) {
} }
}; };
module.exports = redux.createStore(store); module.exports = _.merge(redux.createStore(storeReducer), {
Actions: ACTIONS
});

View File

@ -21,7 +21,7 @@
*/ */
const angular = require('angular'); const angular = require('angular');
const store = require('../models/store'); const Store = require('../models/store');
const childWriter = require('../../src/child-writer'); const childWriter = require('../../src/child-writer');
const MODULE_NAME = 'Etcher.image-writer'; const MODULE_NAME = 'Etcher.image-writer';
@ -42,8 +42,8 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
* ImageWriterService.resetState(); * ImageWriterService.resetState();
*/ */
this.resetState = function() { this.resetState = function() {
store.dispatch({ Store.dispatch({
type: 'RESET_FLASH_STATE' type: Store.Actions.RESET_FLASH_STATE
}); });
}; };
@ -57,11 +57,11 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
speed: 0 speed: 0
}; };
store.subscribe(function() { Store.subscribe(function() {
// Safely bring the state to the world of Angular // Safely bring the state to the world of Angular
$timeout(function() { $timeout(function() {
self.state = store.getState().toJS().flash.state; self.state = Store.getState().toJS().flash.state;
}); });
}); });
@ -79,7 +79,7 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
* } * }
*/ */
this.isFlashing = function() { this.isFlashing = function() {
return store.getState().toJS().flash.flashing; return Store.getState().toJS().flash.flashing;
}; };
/** /**
@ -96,8 +96,8 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
* ImageWriterService.setFlashing(true); * ImageWriterService.setFlashing(true);
*/ */
this.setFlashing = function(status) { this.setFlashing = function(status) {
store.dispatch({ Store.dispatch({
type: 'SET_FLASHING', type: Store.Actions.SET_FLASHING,
data: status data: status
}); });
}; };
@ -121,8 +121,8 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
* }); * });
*/ */
this.setProgressState = function(state) { this.setProgressState = function(state) {
store.dispatch({ Store.dispatch({
type: 'SET_FLASH_STATE', type: Store.Actions.SET_FLASH_STATE,
data: { data: {
type: state.type, type: state.type,
progress: state.percentage, progress: state.percentage,