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

feat: Improve SmartTV scrubbing behavior #8988

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 12 additions & 4 deletions src/js/control-bar/progress-control/play-progress-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,25 @@ class PlayProgressBar extends Component {
* @param {number} seekBarPoint
* A number from 0 to 1, representing a horizontal reference point
* from the left edge of the {@link SeekBar}
*
* @param {Event} [event]
* The `timeupdate` event that caused this function to run.
*/
update(seekBarRect, seekBarPoint) {
update(seekBarRect, seekBarPoint, event) {
const timeTooltip = this.getChild('timeTooltip');

if (!timeTooltip) {
return;
}

const time = (this.player_.scrubbing()) ?
this.player_.getCache().currentTime :
this.player_.currentTime();
// Combined logic: if an event with a valid pendingSeekTime getter exists, use it.
const time = (event &&
event.target &&
typeof event.target.pendingSeekTime === 'function') ?
event.target.pendingSeekTime() :
(this.player_.scrubbing() ?
this.player_.getCache().currentTime :
this.player_.currentTime());

timeTooltip.updateTime(seekBarRect, seekBarPoint, time);
}
Expand Down
72 changes: 58 additions & 14 deletions src/js/control-bar/progress-control/seek-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@ class SeekBar extends Slider {
// Avoid mutating the prototype's `children` array by creating a copy
options.children = [...options.children];

const shouldDisableSeekWhileScrubbingOnMobile = player.options_.disableSeekWhileScrubbingOnMobile && (IS_IOS || IS_ANDROID);
const shouldDisableSeekWhileScrubbing = (player.options_.disableSeekWhileScrubbingOnMobile && (IS_IOS || IS_ANDROID)) || (player.options_.disableSeekWhileScrubbingOnSTV);

// Add the TimeTooltip as a child if we are on desktop, or on mobile with `disableSeekWhileScrubbingOnMobile: true`
if ((!IS_IOS && !IS_ANDROID) || shouldDisableSeekWhileScrubbingOnMobile) {
if ((!IS_IOS && !IS_ANDROID) || shouldDisableSeekWhileScrubbing) {
options.children.splice(1, 0, 'mouseTimeDisplay');
}

super(player, options);

this.shouldDisableSeekWhileScrubbingOnMobile_ = shouldDisableSeekWhileScrubbingOnMobile;
this.shouldDisableSeekWhileScrubbing_ = shouldDisableSeekWhileScrubbing;
this.pendingSeekTime_ = null;

this.setEventHandlers_();
Expand Down Expand Up @@ -196,7 +196,7 @@ class SeekBar extends Slider {

// update the progress bar time tooltip with the current time
if (this.bar) {
this.bar.update(Dom.getBoundingClientRect(this.el()), this.getProgress());
this.bar.update(Dom.getBoundingClientRect(this.el()), this.getProgress(), event);
}
});

Expand Down Expand Up @@ -233,6 +233,20 @@ class SeekBar extends Slider {
this.player_.currentTime();
}

/**
* Getter and setter for pendingSeekTime.
* Acts as a setter if a value is provided, or as a getter if no argument is given.
*
* @param {number|null} [time] - Optional. The new pending seek time, can be a number or null.
* @return {number|null} - The current pending seek time.
*/
pendingSeekTime(time) {
if (time !== undefined) {
this.pendingSeekTime_ = time;
}
return this.pendingSeekTime_;
}

/**
* Get the percentage of media played so far.
*
Expand All @@ -242,8 +256,8 @@ class SeekBar extends Slider {
getPercent() {
// If we have a pending seek time, we are scrubbing on mobile and should set the slider percent
// to reflect the current scrub location.
if (this.pendingSeekTime_) {
return this.pendingSeekTime_ / this.player_.duration();
if (this.pendingSeekTime() !== null) {
return this.pendingSeekTime() / this.player_.duration();
}

const currentTime = this.getCurrentTime_();
Expand Down Expand Up @@ -284,7 +298,7 @@ class SeekBar extends Slider {

// Don't pause if we are on mobile and `disableSeekWhileScrubbingOnMobile: true`.
// In that case, playback should continue while the player scrubs to a new location.
if (!this.shouldDisableSeekWhileScrubbingOnMobile_) {
if (!this.shouldDisableSeekWhileScrubbing_) {
this.player_.pause();
}

Expand Down Expand Up @@ -351,8 +365,8 @@ class SeekBar extends Slider {
}

// if on mobile and `disableSeekWhileScrubbingOnMobile: true`, keep track of the desired seek point but we won't initiate the seek until 'touchend'
if (this.shouldDisableSeekWhileScrubbingOnMobile_) {
this.pendingSeekTime_ = newTime;
if (this.shouldDisableSeekWhileScrubbing_) {
this.pendingSeekTime(newTime);
} else {
this.userSeek_(newTime);
}
Expand Down Expand Up @@ -402,10 +416,10 @@ class SeekBar extends Slider {
this.player_.scrubbing(false);

// If we have a pending seek time, then we have finished scrubbing on mobile and should initiate a seek.
if (this.pendingSeekTime_) {
this.userSeek_(this.pendingSeekTime_);
if (this.pendingSeekTime() !== null) {
this.userSeek_(this.pendingSeekTime());

this.pendingSeekTime_ = null;
this.pendingSeekTime(null);
}

/**
Expand All @@ -429,14 +443,40 @@ class SeekBar extends Slider {
* Move more quickly fast forward for keyboard-only users
*/
stepForward() {
this.userSeek_(this.player_.currentTime() + this.options().stepSeconds);
// if `disableSeekWhileScrubbingOnSTV: true`, keep track of the desired seek point but we won't initiate the seek
if (this.shouldDisableSeekWhileScrubbing_) {
if (!this.player_.paused()) {
this.player_.pause();
}
const currentPos = this.pendingSeekTime() !== null ?
this.pendingSeekTime() :
this.player_.currentTime();

this.pendingSeekTime(currentPos + this.options().stepSeconds);
this.player_.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
} else {
this.userSeek_(this.player_.currentTime() + this.options().stepSeconds);
}
}

/**
* Move more quickly rewind for keyboard-only users
*/
stepBack() {
this.userSeek_(this.player_.currentTime() - this.options().stepSeconds);
// if `disableSeekWhileScrubbingOnSTV: true`, keep track of the desired seek point but we won't initiate the seek
if (this.shouldDisableSeekWhileScrubbing_) {
if (!this.player_.paused()) {
this.player_.pause();
}
const currentPos = this.pendingSeekTime() !== null ?
this.pendingSeekTime() :
this.player_.currentTime();

this.pendingSeekTime(currentPos - this.options().stepSeconds);
this.player_.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
} else {
this.userSeek_(this.player_.currentTime() - this.options().stepSeconds);
}
}

/**
Expand All @@ -448,6 +488,10 @@ class SeekBar extends Slider {
*
*/
handleAction(event) {
if (this.pendingSeekTime() !== null) {
this.userSeek_(this.pendingSeekTime());
this.pendingSeekTime(null);
}
if (this.player_.paused()) {
this.player_.play();
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/js/control-bar/time-controls/current-time-display.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class CurrentTimeDisplay extends TimeDisplay {

if (this.player_.ended()) {
time = this.player_.duration();
} else if (event && event.target && typeof event.target.pendingSeekTime === 'function') {
time = event.target.pendingSeekTime();
} else {
time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
}
Expand Down
3 changes: 2 additions & 1 deletion src/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -5577,7 +5577,8 @@ Player.prototype.options_ = {
},
// Default smooth seeking to false
enableSmoothSeeking: false,
disableSeekWhileScrubbingOnMobile: false
disableSeekWhileScrubbingOnMobile: false,
disableSeekWhileScrubbingOnSTV: false
};

TECH_EVENTS_RETRIGGER.forEach(function(event) {
Expand Down
4 changes: 4 additions & 0 deletions src/js/slider/slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,10 @@ class Slider extends Component {
event.stopPropagation();
this.stepForward();
} else {
if (this.pendingSeekTime()) {
this.pendingSeekTime(null);
this.userSeek_(this.player_.currentTime());
}
super.handleKeyDown(event);
}

Expand Down
Loading
Loading