Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable listening for touch events above the player #992

Merged
merged 10 commits into from
Feb 7, 2014
34 changes: 33 additions & 1 deletion src/js/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ vjs.Component = vjs.CoreObject.extend({
this.ready(ready);
// Don't want to trigger ready here or it will before init is actually
// finished for all children that run this constructor

if (options.reportUserActivity) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want enableUserActivity to be the default for components, I think we want this to be if (options.reportUserActivity !== false)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Done.

this.enableUserActivity();
}
}
});

Expand Down Expand Up @@ -851,7 +855,7 @@ vjs.Component.prototype.emitTapEvents = function(){

// When the touch ends, measure how long it took and trigger the appropriate
// event
this.on('touchend', function() {
this.on('touchend', function(event) {
// Proceed only if the touchmove/leave/cancel event didn't happen
if (couldBeTap === true) {
// Measure how long the touch lasted
Expand All @@ -866,3 +870,31 @@ vjs.Component.prototype.emitTapEvents = function(){
}
});
};

vjs.Component.prototype.enableUserActivity = function() {
var touchmove = false;

this.enableUserActivity.touchstart = function() {
touchmove = false;
};
this.enableUserActivity.touchmove = vjs.bind(this, function() {
this.player_.reportUserActivity();
touchmove = true;
});
this.enableUserActivity.touchend = vjs.bind(this, function() {
if (!touchmove) {
this.player_.reportUserActivity();
}
});

this.on('touchstart', this.enableUserActivity.touchstart);
this.on('touchmove', this.enableUserActivity.touchmove);
this.on('touchend', this.enableUserActivity.touchend);
};

vjs.Component.prototype.disableUserActivity = function() {
this.off('touchstart', this.enableUserActivity.touchstart);
this.off('touchmove', this.enableUserActivity.touchmove);
this.off('touchend', this.enableUserActivity.touchend);
};

22 changes: 8 additions & 14 deletions src/js/media/media.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
vjs.MediaTechController = vjs.Component.extend({
/** @constructor */
init: function(player, options, ready){
// we don't want the tech to report user activity automatically.
// This is done manually in addControlsListeners
options.reportUserActivity = false;
vjs.Component.call(this, player, options, ready);

this.initControlsListeners();
Expand Down Expand Up @@ -60,7 +63,7 @@ vjs.MediaTechController.prototype.initControlsListeners = function(){
};

vjs.MediaTechController.prototype.addControlsListeners = function(){
var preventBubble, userWasActive;
var userWasActive;

// Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
// trigger mousedown/up.
Expand All @@ -82,23 +85,14 @@ vjs.MediaTechController.prototype.addControlsListeners = function(){
this.on('touchstart', function(event) {
// Stop the mouse events from also happening
event.preventDefault();
event.stopPropagation();
// Record if the user was active now so we don't have to keep polling it
userWasActive = this.player_.userActive();
});

preventBubble = function(event){
event.stopPropagation();
if (userWasActive) {
this.player_.reportUserActivity();
this.on('touchmove', function(event) {
if (userWasActive){
this.player().reportUserActivity();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if (userWasActive) reportUserActivity() check is no longer going to happen on touch move. Do the controls keep showing for you while you're moving your finger around the video?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not seeing it appear if I was moving my finger on the video.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok if the controls don't appear if they're already hidden when you do a touchmove (no tap), but if the controls are showing, we want the controls to keep showing for as long as the user is moving their finger around. Does that makes sense? I believe I was just trying mimic iOS.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think they keep showing and don't disappear. I'll double check.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like they don't.

}
};

// Treat all touch events the same for consistency
this.on('touchmove', preventBubble);
this.on('touchleave', preventBubble);
this.on('touchcancel', preventBubble);
this.on('touchend', preventBubble);
});

// Turn on component tap events
this.emitTapEvents();
Expand Down
11 changes: 3 additions & 8 deletions src/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ vjs.Player = vjs.Component.extend({
// May be turned back on by HTML5 tech if nativeControlsForTouch is true
tag.controls = false;

// we don't want the player to report user activity
options.reportUserActivity = false;

// Run base component initializing with new options.
// Builds the element through createEl()
// Inits and embeds any child components in opts
Expand Down Expand Up @@ -1316,14 +1319,6 @@ vjs.Player.prototype.listenForUserActivity = function(){
this.on('keydown', onMouseActivity);
this.on('keyup', onMouseActivity);

// Consider any touch events that bubble up to be activity
// Certain touches on the tech will be blocked from bubbling because they
// toggle controls
this.on('touchstart', onMouseDown);
this.on('touchmove', onMouseActivity);
this.on('touchend', onMouseUp);
this.on('touchcancel', onMouseUp);

// Run an interval every 250 milliseconds instead of stuffing everything into
// the mousemove/touchmove function itself, to prevent performance degradation.
// `this.reportUserActivity` simply sets this.userActivity_ to true, which
Expand Down
2 changes: 1 addition & 1 deletion test/unit/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ test('should emit a tap event', function(){
var origTouch = vjs.TOUCH_ENABLED;
vjs.TOUCH_ENABLED = true;

var comp = new vjs.Component(getFakePlayer(), {});
var comp = new vjs.Component(getFakePlayer(), {reportUserActivity: false});

comp.emitTapEvents();
comp.on('tap', function(){
Expand Down