Files
edx-platform/xmodule/js/src/video/05_video_quality_control.js
Syed Ali Abbas Zaidi 8480dbc228 chore: apply amnesty on existing not fixable issues (#32215)
* fix: eslint operator-linebreak issue

* fix: eslint quotes issue

* fix: react jsx indent and props issues

* fix: eslint trailing spaces issues

* fix: eslint line around directives issue

* fix: eslint semi rule

* fix: eslint newline per chain rule

* fix: eslint space infix ops rule

* fix: eslint space-in-parens issue

* fix: eslint space before function paren issue

* fix: eslint space before blocks issue

* fix: eslint arrow body style issue

* fix: eslint dot-location issue

* fix: eslint quotes issue

* fix: eslint quote props issue

* fix: eslint operator assignment issue

* fix: eslint new line after import issue

* fix: indent issues

* fix: operator assignment issue

* fix: all autofixable eslint issues

* fix: all react related fixable issues

* fix: autofixable eslint issues

* chore: remove all template literals

* fix: remaining autofixable issues

* chore: apply amnesty on all existing issues

* fix: failing xss-lint issues

* refactor: apply amnesty on remaining issues

* refactor: apply amnesty on new issues

* fix: remove file level suppressions

* refactor: apply amnesty on new issues
2023-08-07 19:13:19 +05:00

182 lines
7.5 KiB
JavaScript

(function(requirejs, require, define) {
// VideoQualityControl module.
'use strict';
define(
'video/05_video_quality_control.js',
['edx-ui-toolkit/js/utils/html-utils'],
function(HtmlUtils) {
var template = HtmlUtils.interpolateHtml(
HtmlUtils.HTML([
'<button class="control quality-control is-hidden" aria-disabled="false" title="',
'{highDefinition}',
'">',
'<span class="icon icon-hd" aria-hidden="true">HD</span>',
'<span class="sr text-translation">',
'{highDefinition}',
'</span>&nbsp;',
'<span class="sr control-text">',
'{off}',
'</span>',
'</button>'
].join('')),
{
highDefinition: gettext('High Definition'),
off: gettext('off')
}
);
// VideoQualityControl() function - what this module "exports".
return function(state) {
var dfd = $.Deferred();
// Changing quality for now only works for YouTube videos.
if (state.videoType !== 'youtube') {
return;
}
state.videoQualityControl = {};
_makeFunctionsPublic(state);
_renderElements(state);
_bindHandlers(state);
dfd.resolve();
return dfd.promise();
};
// ***************************************************************
// Private functions start here.
// ***************************************************************
// function _makeFunctionsPublic(state)
//
// Functions which will be accessible via 'state' object. When called, these functions will
// get the 'state' object as a context.
function _makeFunctionsPublic(state) {
var methodsDict = {
destroy: destroy,
fetchAvailableQualities: fetchAvailableQualities,
onQualityChange: onQualityChange,
showQualityControl: showQualityControl,
toggleQuality: toggleQuality
};
state.bindTo(methodsDict, state.videoQualityControl, state);
}
function destroy() {
this.videoQualityControl.el.off({
click: this.videoQualityControl.toggleQuality,
destroy: this.videoQualityControl.destroy
});
this.el.off('.quality');
this.videoQualityControl.el.remove();
delete this.videoQualityControl;
}
// function _renderElements(state)
//
// Create any necessary DOM elements, attach them, and set their initial configuration. Also
// make the created DOM elements available via the 'state' object. Much easier to work this
// way - you don't have to do repeated jQuery element selects.
function _renderElements(state) {
// eslint-disable-next-line no-multi-assign
var element = state.videoQualityControl.el = $(template.toString());
state.videoQualityControl.quality = 'large';
HtmlUtils.append(state.el.find('.secondary-controls'), HtmlUtils.HTML(element));
}
// function _bindHandlers(state)
//
// Bind any necessary function callbacks to DOM events (click, mousemove, etc.).
function _bindHandlers(state) {
state.videoQualityControl.el.on('click',
state.videoQualityControl.toggleQuality
);
state.el.on('play.quality', _.once(
state.videoQualityControl.fetchAvailableQualities
));
state.el.on('destroy.quality', state.videoQualityControl.destroy);
}
// ***************************************************************
// Public functions start here.
// These are available via the 'state' object. Their context ('this' keyword) is the 'state' object.
// The magic private function that makes them available and sets up their context is makeFunctionsPublic().
// ***************************************************************
/*
* @desc Shows quality control. This function will only be called if HD
* qualities are available.
*
* @public
*/
function showQualityControl() {
this.videoQualityControl.el.removeClass('is-hidden');
}
// This function can only be called once as _.once has been used.
/*
* @desc Get the available qualities from YouTube API. Possible values are:
['highres', 'hd1080', 'hd720', 'large', 'medium', 'small'].
HD are: ['highres', 'hd1080', 'hd720'].
*
* @public
*/
function fetchAvailableQualities() {
var qualities = this.videoPlayer.player.getAvailableQualityLevels();
this.config.availableHDQualities = _.intersection(
qualities, ['highres', 'hd1080', 'hd720']
);
// HD qualities are available, show video quality control.
if (this.config.availableHDQualities.length > 0) {
this.trigger('videoQualityControl.showQualityControl');
this.trigger('videoQualityControl.onQualityChange', this.videoQualityControl.quality);
}
// On initialization, force the video quality to be 'large' instead of
// 'default'. Otherwise, the player will sometimes switch to HD
// automatically, for example when the iframe resizes itself.
this.trigger('videoPlayer.handlePlaybackQualityChange',
this.videoQualityControl.quality
);
}
function onQualityChange(value) {
var controlStateStr;
this.videoQualityControl.quality = value;
if (_.contains(this.config.availableHDQualities, value)) {
controlStateStr = gettext('on');
this.videoQualityControl.el
.addClass('active')
.find('.control-text')
.text(controlStateStr);
} else {
controlStateStr = gettext('off');
this.videoQualityControl.el
.removeClass('active')
.find('.control-text')
.text(controlStateStr);
}
}
// This function toggles the quality of video only if HD qualities are
// available.
function toggleQuality(event) {
var newQuality,
value = this.videoQualityControl.quality,
isHD = _.contains(this.config.availableHDQualities, value);
event.preventDefault();
newQuality = isHD ? 'large' : 'highres';
this.trigger('videoPlayer.handlePlaybackQualityChange', newQuality);
}
});
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));