Skip to content

Commit

Permalink
Android click sound onPress of Touchable component
Browse files Browse the repository at this point in the history
Android's onClick listener will trigger a sound effect by default when a
user has system sounds enabled. Since React implements it's own click
model, we should manually trigger the sound.
  • Loading branch information
mikemonteith committed Apr 9, 2016
1 parent 49fdd99 commit 7cd5ea0
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
23 changes: 23 additions & 0 deletions Libraries/Components/Touchable/Touchable.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

'use strict';

var React = require('React');
var BoundingDimensions = require('BoundingDimensions');
var Position = require('Position');
var TouchEventUtils = require('fbjs/lib/TouchEventUtils');
var UIManager = require('UIManager');

var keyMirror = require('fbjs/lib/keyMirror');
var queryLayoutByID = require('queryLayoutByID');
Expand Down Expand Up @@ -312,6 +314,16 @@ var TouchableMixin = {
this.pressOutDelayTimeout && clearTimeout(this.pressOutDelayTimeout);
},

propTypes: {
/**
* Play sound effects on press events if system sounds are enabled in
* Android settings. Defaults to true
*
* @platform android
*/
soundEffectsEnabled: React.PropTypes.bool,
},

/**
* It's prefer that mixins determine state in this way, having the class
* explicitly mix the state in the one and only `getInitialState` method.
Expand Down Expand Up @@ -702,12 +714,23 @@ var TouchableMixin = {

var shouldInvokePress = !IsLongPressingIn[curState] || pressIsLongButStillCallOnPress;
if (shouldInvokePress && this.touchableHandlePress) {
this._playClickSound();
this.touchableHandlePress(e);
}
}

this.touchableDelayTimeout && clearTimeout(this.touchableDelayTimeout);
this.touchableDelayTimeout = null;
},

_playClickSound: function() {
if (this.props.soundEffectsEnabled !== false) {
UIManager.dispatchViewManagerCommand(
React.findNodeHandle(this),
UIManager.RCTView.Commands.playClickSound,
null
);
}
}

};
Expand Down
8 changes: 8 additions & 0 deletions Libraries/Components/Touchable/TouchableWithoutFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ var TouchableWithoutFeedback = React.createClass({
* views.
*/
hitSlop: EdgeInsetsPropType,

/**
* Play sound effects on press events if system sounds are enabled in
* Android settings. Defaults to true
*
* @platform android
*/
soundEffectsEnabled: React.PropTypes.bool,
},

getInitialState: function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import android.graphics.Rect;
import android.os.Build;
import android.view.SoundEffectConstants;
import android.view.View;

import com.facebook.csslayout.CSSConstants;
Expand Down Expand Up @@ -46,6 +47,7 @@ public class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
};
private static final int CMD_HOTSPOT_UPDATE = 1;
private static final int CMD_SET_PRESSED = 2;
private static final int CMD_PLAY_CLICK_SOUND = 3;

@ReactProp(name = "accessible")
public void setAccessible(ReactViewGroup view, boolean accessible) {
Expand Down Expand Up @@ -158,7 +160,10 @@ public ReactViewGroup createViewInstance(ThemedReactContext context) {

@Override
public Map<String, Integer> getCommandsMap() {
return MapBuilder.of("hotspotUpdate", CMD_HOTSPOT_UPDATE, "setPressed", CMD_SET_PRESSED);
return MapBuilder.of(
"hotspotUpdate", CMD_HOTSPOT_UPDATE,
"setPressed", CMD_SET_PRESSED,
"playClickSound", CMD_PLAY_CLICK_SOUND);
}

@Override
Expand All @@ -184,6 +189,10 @@ public void receiveCommand(ReactViewGroup root, int commandId, @Nullable Readabl
root.setPressed(args.getBoolean(0));
break;
}
case CMD_PLAY_CLICK_SOUND: {
root.playSoundEffect(SoundEffectConstants.CLICK);
break;
}
}
}

Expand Down

0 comments on commit 7cd5ea0

Please sign in to comment.