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

Improve mute button usability #3942

Merged
merged 8 commits into from Jan 31, 2017

Conversation

kevinlitchfield
Copy link
Contributor

Clicking MuteToggle when volume is 0 now has more user-friendly behavior. Previously, clicking MuteToggle when volume was 0 had no user-visible effect (as discussed in #3909, which this PR addresses).

There are three possible scenarios I'm aware of for setting the volume to 0 and then dealing with a click on MuteToggle that need to be taken into account:

  1. User drags VolumeBar to 0 with mouse or finger. In this case, volume should be restored to the level it was at when the user started dragging VolumeBar.
  2. User steps volume to 0 with keyboard. In this case, clicking MuteToggle should restore the volume to its last value before it reached 0.
  3. volume is set directly to 0 with external JS, by a plugin, etc. In this case, it should be up to the programmer to control what level the volume should be set to when the user clicks MuteToggle, but it should never remain at 0.

How this solution works:

  • Clicking MuteToggle when volume is zero sets volume to the value of a new property, lastVolume.
  • lastVolume is updated to match volume when Player#volume sets a new value for volume, unless the new value of volume is 0.
  • When a user starts to drag VolumeBar, volume is saved into another new property, volumeBeforeDrag. When the user finishes dragging VolumeBar, if volume is 0, lastVolume is updated to match volumeBeforeDrag.

Note: This should not be merged until #3918 is fixed. As explained in that bug report:

If clicking MuteToggle when volume is zero sets volume to something greater than zero, then users will be able to accidentally trigger that behavior by mouseuping over MuteToggle after dragging VolumeBar to zero.

@brandonocasey
Copy link
Contributor

brandonocasey commented Jan 20, 2017

Overall this is great! Thanks for the PR!

I think that there may be a way to make this a bit simpler:

  • Remove volumeBeforeDrag and listening for sliderinactive in the VolumeBar constructor
  • Player#lastVolume is updated by VolumeBar:
    1. VolumeBar listens to slideractive on itself (as it does in the current implementation)
    2. The slideractive listener records the starting volume and starts listening for one sliderinactive event on itself
    3. The sliderinactive listener:
      • Sets lastVolume to the current volume unless it is zero or the volume from the slideractive listener if its not zero
      • Does nothing if the volume was changed from 0 to 0

I also think that we should probably make lastVolume on the player a private function prefixed with an _ at the end of it. What does everyone else think? @videojs/contributors

Also note that #3918 should be fixed in the current master. Can you rebase your PR on the current master when you get a chance?

@gkatsev gkatsev moved this from Ready for Review to In Progress in 6.0 Jan 27, 2017
lastVolume(percentAsDecimal) {
if (percentAsDecimal !== undefined) {
this.lastVolume_ = percentAsDecimal;
return this;
Copy link
Member

Choose a reason for hiding this comment

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

This should just return when used as setter.

* a reference to the calling player when setting and the
* current volume as a percent when getting
*/
volumeBeforeDrag(percentAsDecimal) {
Copy link
Member

Choose a reason for hiding this comment

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

this should also be marked as private

@@ -65,7 +65,15 @@ class MuteToggle extends Button {
* @listens click
*/
handleClick(event) {
this.player_.muted(this.player_.muted() ? false : true);
const vol = this.player_.volume();
const lastVolume = this.player_.lastVolume();
Copy link
Member

Choose a reason for hiding this comment

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

is it possible for the lastVolume to end up being 0? Is it worth handling? At that point, I guess would be to set the volume to 0.5?

After the changes to how lastVolume is set, dragging the VolumeBar to 0
and then clicking on the leftmost part of the volumebar would result in
lastVolume being set to 0. This prevents that from happening.
*
* @listens slideractive
*/
updateLastVolume() {
Copy link
Contributor

Choose a reason for hiding this comment

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

we probably want this function to be private (only used internally) just like Player#lastVolume_()

Copy link
Member

Choose a reason for hiding this comment

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

also, @private jsdoc directive

updateLastVolume() {
const volumeBeforeDrag = this.player_.volume();

this.on('sliderinactive', function setLastVolume() {
Copy link
Contributor

Choose a reason for hiding this comment

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

You can actually use this.one('sliderinactive' here that way you don't have to use this.off below. I would also say that you can just use an arrow function here rather than a named one. ex:

this.one('sliderinactive', () => {
// current function goes here
});

* @return {number}
* the current value of lastVolume as a percent when getting
*/
lastVolume_(percentAsDecimal) {
Copy link
Member

Choose a reason for hiding this comment

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

this should have an @private jsdoc directive.

*
* @listens slideractive
*/
updateLastVolume() {
Copy link
Member

Choose a reason for hiding this comment

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

also, @private jsdoc directive

@kevinlitchfield
Copy link
Contributor Author

@brandonocasey @gkatsev Thanks so much for the feedback! Have addressed.

@gkatsev gkatsev merged commit cb42fcf into videojs:master Jan 31, 2017
@gkatsev
Copy link
Member

gkatsev commented Jan 31, 2017

@kevinlitchfield thanks so much for your work!

@gkatsev gkatsev moved this from In Progress to Done in 6.0 Jan 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
6.0
Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants