Skip to content

Commit d3a434f

Browse files
committed
add velocty validation. fix file renaming
1 parent 2771a46 commit d3a434f

File tree

11 files changed

+168
-22
lines changed

11 files changed

+168
-22
lines changed

src/component/Modal.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React from 'react';
33
import { connect } from 'react-redux'
44

55
/* App imports */
6-
import { confirmFileOverwriteAction } from 'redux/actions'
6+
import { confirmFileOverwriteAction, closeFixKitErrors } from 'redux/actions'
77

88
const ModalComponent = (props) => {
99
return (
@@ -31,13 +31,37 @@ const ModalComponent = (props) => {
3131
</div>
3232
</div>
3333
}
34+
35+
{props.showFixKitErrors &&
36+
<div className="modal is-active">
37+
<div className="modal-background"></div>
38+
<div className="modal-content">
39+
<div className="message is-danger">
40+
<div className="message-header">
41+
<p>Cannot Save</p>
42+
</div>
43+
<div className="message-body">
44+
<div className="is-clearfix">Please correct all errors before saving the kit.</div>
45+
46+
<div className="field is-grouped is-pulled-right is-marginless is-padingless">
47+
<div className="buttons control">
48+
<button className="button" onClick={props.closeFixKitErrors}>Ok</button>
49+
</div>
50+
</div>
51+
<div className="is-clearfix" />
52+
</div>
53+
</div>
54+
</div>
55+
</div>
56+
}
3457
</div>
3558
);
3659
}
3760

3861
const mapStateToProps = (state, ownProps) => {
3962
return {
40-
showConfirmOverwrite: state.modals.confirmOverwriteVisible
63+
showConfirmOverwrite: state.modals.confirmOverwriteVisible,
64+
showFixKitErrors: state.modals.fixKitErrorsVisible
4165
}
4266
}
4367

@@ -49,6 +73,9 @@ const mapDispatchToProps = (dispatch, ownProps) => {
4973
dispatchCallbackAndCloseConfirmOverwrite: () => {
5074
dispatch(confirmFileOverwriteAction(true));
5175
},
76+
closeFixKitErrors: () => {
77+
dispatch(closeFixKitErrors());
78+
},
5279
}
5380
}
5481

src/component/Pad/LayerA.js

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React from 'react';
33
import { connect } from 'react-redux'
44

55
/* App imports */
6-
import { MidiMap } from 'util/const'
6+
import { MidiMap, PadErrors, PadErrorStrings } from 'util/const'
77
import { updatePadIntProperty, updatePadProperty, updatePadSensitivity } from 'redux/actions'
88

99
/* Component imports */
@@ -121,7 +121,8 @@ const PadLayerAComponent = (props) => {
121121
<VelocityComponent
122122
min={pad.velocityMin}
123123
max={pad.velocityMax}
124-
tooltip={"Velocity: " + pad.velocityMin + "-" + pad.velocityMax}
124+
tooltip={props.velocityTooltip}
125+
hasError={props.hasVelocityError}
125126
onChangeMin={(value) => props.updatePadIntProperty('velocityMin', value)}
126127
onChangeMax={(value) => props.updatePadIntProperty('velocityMax', value)} />
127128

@@ -132,7 +133,11 @@ const PadLayerAComponent = (props) => {
132133
onChange={(value) => props.updatePadIntProperty('mgrp', value)} />
133134

134135
<div
135-
className={"layerBIcon has-tooltip-left " + ((!props.showLayerB && pad.fileNameB !== "") ? 'has-text-link' : '')}
136+
className={
137+
"layerBIcon has-tooltip-left " +
138+
((!props.showLayerB && pad.fileNameB !== "") ? 'has-text-link ' : ' ') +
139+
((!props.showLayerB && props.hasLayerBError) ? 'has-text-danger ' : ' ')
140+
}
136141
data-tooltip="Toggle Layer B"
137142
onClick={props.toggleLayerB}>
138143
<i className={"glyphicon glyphicon-chevron-" + (props.showLayerB ? 'up' : 'down')} aria-hidden="true" />
@@ -146,9 +151,30 @@ const PadLayerAComponent = (props) => {
146151

147152
const mapStateToProps = (state, ownProps) => {
148153
let pad = state.pads[ownProps.padId];
154+
let velocityTooltip = "Velocity: " + pad.velocityMin + "-" + pad.velocityMax;
155+
156+
let hasVelocityError = false;
157+
if (pad.errors.indexOf(PadErrors.VELOCITY_SWAPPED_A) > -1) {
158+
hasVelocityError = true;
159+
velocityTooltip = "Error: " + PadErrorStrings.VELOCITY_SWAPPED_A;
160+
} else if (pad.errors.indexOf(PadErrors.VELOCITY_TOO_HIGH_A) > -1) {
161+
hasVelocityError = true;
162+
velocityTooltip = "Error: " + PadErrorStrings.VELOCITY_TOO_HIGH_A;
163+
}
164+
165+
let hasLayerBError = false;
166+
if (pad.errors.indexOf(PadErrors.VELOCITY_SWAPPED_B) > -1) {
167+
hasLayerBError = true;
168+
} else if (pad.errors.indexOf(PadErrors.VELOCITY_TOO_HIGH_B) > -1) {
169+
hasLayerBError = true;
170+
}
171+
149172
return {
150173
pad: pad,
151-
padSampleFile: state.drive.rootPath + "/" + pad.fileName
174+
padSampleFile: state.drive.rootPath + "/" + pad.fileName,
175+
hasVelocityError: hasVelocityError,
176+
velocityTooltip: velocityTooltip,
177+
hasLayerBError: hasLayerBError
152178
}
153179
}
154180

src/component/Pad/LayerB.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import { connect } from 'react-redux'
44

55
/* App imports */
6+
import { PadErrors, PadErrorStrings } from 'util/const'
67
import { updatePadIntProperty, updatePadProperty } from 'redux/actions'
78

89
/* Component imports */
@@ -39,7 +40,8 @@ const PadLayerBComponent = (props) => {
3940
<VelocityComponent
4041
min={pad.velocityMinB}
4142
max={pad.velocityMaxB}
42-
tooltip={"Velocity: " + pad.velocityMinB + "-" + pad.velocityMaxB}
43+
tooltip={props.velocityTooltip}
44+
hasError={props.hasVelocityError}
4345
onChangeMin={(value) => props.updatePadIntProperty('velocityMinB', value)}
4446
onChangeMax={(value) => props.updatePadIntProperty('velocityMaxB', value)} />
4547
</div>
@@ -50,9 +52,22 @@ const PadLayerBComponent = (props) => {
5052

5153
const mapStateToProps = (state, ownProps) => {
5254
let pad = state.pads[ownProps.padId];
55+
let velocityTooltip = "Velocity: " + pad.velocityMinB + "-" + pad.velocityMaxB;
56+
57+
let hasVelocityError = false;
58+
if (pad.errors.indexOf(PadErrors.VELOCITY_SWAPPED_B) > -1) {
59+
hasVelocityError = true;
60+
velocityTooltip = "Error: " + PadErrorStrings.VELOCITY_SWAPPED_B;
61+
} else if (pad.errors.indexOf(PadErrors.VELOCITY_TOO_HIGH_B) > -1) {
62+
hasVelocityError = true;
63+
velocityTooltip = "Error: " + PadErrorStrings.VELOCITY_TOO_HIGH_B;
64+
}
65+
5366
return {
5467
pad: pad,
5568
sampleFile: state.drive.rootPath + "/" + pad.fileNameB,
69+
hasVelocityError: hasVelocityError,
70+
velocityTooltip: velocityTooltip
5671
}
5772
}
5873

src/component/Pad/Velocity.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class VelocityComponent extends React.Component {
3333
render() {
3434
return (
3535
<span className="velocityContainer has-tooltip-bottom" data-tooltip={this.props.tooltip}>
36-
<span className="is-small">
36+
<span className={"is-small " + ((this.props.hasError) ? 'has-text-danger' : '')}>
3737
(
3838
{this.state.editingMin &&
3939
<input

src/css/Pad/Velocity.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55
width: 1.8em;
66
padding: .2em 0;
77
height: 1.5em; }
8+
.velocityContainer.has-tooltip-bottom::before {
9+
width: 11em;
10+
white-space: normal !important; }

src/css/Pad/Velocity.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@
77
padding: .2em 0;
88
height: 1.5em;
99
}
10-
}
10+
&.has-tooltip-bottom::before {
11+
width: 11em;
12+
white-space: normal !important;
13+
}
14+
}

src/redux/actions.js

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* App imports */
22
import { KitModel, PadModel } from "redux/models";
3-
import { Actions, MidiMap } from 'util/const'
3+
import { Actions, MidiMap, PadErrors } from 'util/const'
44
import { openKitFileDialog, openDriveDirectoryDialog, openSampleFileDialog} from "util/fileDialog";
55
import { getGlobalStateFromDirectory} from "util/globalState";
66
import { getKitAndPadsFromFile } from "util/kitFile";
@@ -171,8 +171,17 @@ export function saveKit(kitId, asNew=false, confirmedOverwrite=false) {
171171
let state = getState();
172172
let kit = state.kits.models[kitId];
173173

174+
// validate the kit
175+
for (let i = 0; i < kit.pads.length; i++) {
176+
let pad = state.pads[kit.pads[i]];
177+
if (pad.errors.length) {
178+
dispatch({ type: Actions.SHOW_MODAL_KIT_ERRORS });
179+
return;
180+
}
181+
}
182+
183+
// if this kit would overwrite an existing one - confirm first
174184
if (!confirmedOverwrite) {
175-
// if this kit would overwrite an existing one - confirm first
176185
let confirm = kitWillOverwriteExisting(kit, asNew);
177186

178187
if (confirm) {
@@ -266,7 +275,36 @@ export function updatePadSensitivity(padId, value) {
266275
* @param {?} value
267276
*/
268277
export function updatePadProperty(padId, property, value) {
269-
return { type: Actions.UPDATE_PAD_PROPERTY, padId: padId, property: property, value: value }
278+
return (dispatch, getState) => {
279+
dispatch({ type: Actions.UPDATE_PAD_PROPERTY, padId: padId, property: property, value: value });
280+
281+
dispatch(validatePad(padId));
282+
}
283+
}
284+
export function validatePad(padId) {
285+
return (dispatch, getState) => {
286+
let state = getState();
287+
let pad = state.pads[padId];
288+
let prevErrors = pad.errors;
289+
let errors = [];
290+
291+
if (pad.velocityMin > pad.velocityMax) {
292+
errors.push(PadErrors.VELOCITY_SWAPPED_A)
293+
}
294+
if (pad.velocityMin > 127 || pad.velocityMax > 127) {
295+
errors.push(PadErrors.VELOCITY_TOO_HIGH_A);
296+
}
297+
if (pad.velocityMinB > pad.velocityMaxB) {
298+
errors.push(PadErrors.VELOCITY_SWAPPED_B)
299+
}
300+
if (pad.velocityMinB > 127 || pad.velocityMaxB > 127) {
301+
errors.push(PadErrors.VELOCITY_TOO_HIGH_B);
302+
}
303+
304+
if (prevErrors.length || errors.length) {
305+
dispatch({ type: Actions.UPDATE_PAD_PROPERTY, padId: padId, property: 'errors', value: errors });
306+
}
307+
}
270308
}
271309

272310
/** APP ACTION CREATORS */
@@ -300,4 +338,9 @@ export function confirmFileOverwriteAction(result) {
300338
dispatch(callback(result));
301339
}
302340
}
341+
export function closeFixKitErrors() {
342+
return (dispatch, getState) => {
343+
dispatch({ type: Actions.HIDE_MODAL_KIT_ERRORS });
344+
}
345+
}
303346

src/redux/models.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export class PadModel {
4242
fileName: fileName,
4343
velocityMinB: velocityMinB,
4444
velocityMaxB: velocityMaxB,
45-
fileNameB: fileNameB
45+
fileNameB: fileNameB,
46+
errors: []
4647
};
4748
}
4849

src/redux/reducers.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ let lastLoadedDirectory = getLastLoadedDirectory();
1212
let initialState = {
1313
modals: {
1414
confirmOverwriteVisible: false,
15-
confirmOverwriteCallback: null
15+
confirmOverwriteCallback: null,
16+
fixKitErrorsVisible: false
1617
},
1718
drive: {},
1819
kits: {
@@ -74,6 +75,16 @@ function modals(state = initialModalState, action) {
7475
confirmOverwriteVisible: {$set: false}
7576
});
7677

78+
case Actions.SHOW_MODAL_KIT_ERRORS:
79+
return update(state, {
80+
fixKitErrorsVisible: {$set: true}
81+
});
82+
83+
case Actions.HIDE_MODAL_KIT_ERRORS:
84+
return update(state, {
85+
fixKitErrorsVisible: {$set: false}
86+
});
87+
7788
default:
7889
return state;
7990
}

src/util/const.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@ export const Actions = {
2222
/* modal action types */
2323
SHOW_MODAL_CONFIRM_OVERWRITE: 'SHOW_MODAL_CONFIRM_OVERWRITE',
2424
HIDE_MODAL_CONFIRM_OVERWRITE: 'HIDE_MODAL_CONFIRM_OVERWRITE',
25+
26+
SHOW_MODAL_KIT_ERRORS: 'SHOW_MODAL_KIT_ERRORS',
27+
HIDE_MODAL_KIT_ERRORS: 'HIDE_MODAL_KIT_ERRORS'
28+
};
29+
30+
export const PadErrors = {
31+
VELOCITY_SWAPPED_A: 'VELOCITY_SWAPPED_A',
32+
VELOCITY_TOO_HIGH_A: 'VELOCITY_TOO_HIGH_A',
33+
VELOCITY_SWAPPED_B: 'VELOCITY_SWAPPED_B',
34+
VELOCITY_TOO_HIGH_B: 'VELOCITY_TOO_HIGH_B',
35+
DUPLICATE_MIDI_NOTE: 'DUPLICATE_MIDI_NOTE',
36+
};
37+
38+
export const PadErrorStrings = {
39+
VELOCITY_SWAPPED_A: 'Velocity must be in order (min-max)',
40+
VELOCITY_TOO_HIGH_A: 'Velocity values must be 127 or lower',
41+
VELOCITY_SWAPPED_B: 'Velocity must be in order (min-max)',
42+
VELOCITY_TOO_HIGH_B: 'Velocity values must be 127 or lower',
43+
DUPLICATE_MIDI_NOTE: 'Midi Note must be unique'
2544
};
2645

2746
export const DragItemTypes = {

0 commit comments

Comments
 (0)