Skip to content

Commit

Permalink
Add speed controls, progress bar and next button feature
Browse files Browse the repository at this point in the history
  • Loading branch information
NomanShafi authored and naumanshafi committed Jun 9, 2021
1 parent 322e1dd commit 7b6216d
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,20 @@ import * as Time from 'time.js';
});
});

it('data contains video completely watched flag, async is true', function() {
itSpec({
asyncVal: true,
speedVal: undefined,
positionVal: undefined,
data: {
is_complete: true
},
ajaxData: {
is_complete: true
}
});
});

function itSpec(value) {
state.config.saveStateEnabled = true;
var asyncVal = value.asyncVal,
Expand Down
5 changes: 3 additions & 2 deletions common/lib/xmodule/xmodule/js/src/video/03_video_player.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ function(HTML5Video, HTML5HLSVideo, Resizer, HLS, _, Time) {
if (state.isTouch) {
dfd.resolve();
}
if (state.config.enableNextOnCompletion === true && state.config.isComplete === false) {
$('.sequence-nav-button.button-next').prop('disabled', true);
}
}

function _updateVcrAndRegion(state, isYoutube) {
Expand Down Expand Up @@ -511,8 +514,6 @@ function(HTML5Video, HTML5HLSVideo, Resizer, HLS, _, Time) {

function onEnded() {
var time = this.videoPlayer.duration();


this.trigger('videoProgressSlider.notifyThroughHandleEnd', {
end: true
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ function() {
// have to do repeated jQuery element selects.
function _renderElements(state) {
state.videoProgressSlider.el = $(template);

state.el.find('.video-controls').prepend(state.videoProgressSlider.el);
state.videoProgressSlider.buildSlider();
_buildHandle(state);
Expand Down
5 changes: 5 additions & 0 deletions common/lib/xmodule/xmodule/js/src/video/09_completion.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@

/** Handler to call when a timeupdate event is triggered */
handleTimeUpdate: function(currentTime) {

var duration;
if (this.isComplete) {
return;
Expand Down Expand Up @@ -132,6 +133,9 @@
var errmsg;
this.isComplete = true;
this.lastSentTime = currentTime;
if (self.state.config.enableNextOnCompletion === true && self.state.config.isComplete === false) {
$('.sequence-nav-button.button-next').prop('disabled', false);
}
if (this.state.config.publishCompletionUrl) {
$.ajax({
type: 'POST',
Expand All @@ -142,6 +146,7 @@
success: function() {
self.state.el.off('timeupdate.completion');
self.state.el.off('ended.completion');
self.state.videoSaveStatePlugin.onVideoComplete();
},
error: function(xhr) {
/* eslint-disable no-console */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
}

_.bindAll(this, 'onSpeedChange', 'onAutoAdvanceChange', 'saveStateHandler', 'bindUnloadHandler', 'onUnload',
'onYoutubeAvailability', 'onLanguageChange', 'destroy');
'onYoutubeAvailability', 'onLanguageChange', 'destroy','onVideoComplete');
this.state = state;
this.options = _.extend({events: []}, options);
this.state.videoSaveStatePlugin = this;
Expand Down Expand Up @@ -72,6 +72,10 @@
this.state.storage.setItem('general_speed', newSpeed);
},

onVideoComplete: function(event) {
this.saveState(true, { is_complete: true });
},

onAutoAdvanceChange: function(event, enabled) {
this.saveState(true, {auto_advance: enabled});
this.state.storage.setItem('auto_advance', enabled);
Expand Down
7 changes: 5 additions & 2 deletions common/lib/xmodule/xmodule/js/src/video/10_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,15 @@
storage = VideoStorage('VideoState', id),
bumperMetadata = el.data('bumper-metadata'),
autoAdvanceEnabled = el.data('autoadvance-enabled') === 'True',
metadata = el.data('metadata'),
mainVideoModules = [
FocusGrabber, VideoControl, VideoPlayPlaceholder,
VideoPlayPauseControl, VideoProgressSlider, VideoSpeedControl,
VideoPlayPauseControl,
VideoVolumeControl, VideoQualityControl, VideoFullScreen, VideoCaption, VideoCommands,
VideoContextMenu, VideoSaveStatePlugin, VideoEventsPlugin, VideoCompletionHandler
].concat(autoAdvanceEnabled ? [VideoAutoAdvanceControl] : []),
].concat(autoAdvanceEnabled ? [VideoAutoAdvanceControl] : [],
metadata.enableProgressSlider ? [VideoProgressSlider] : [],
metadata.enableSpeedControl ? [VideoSpeedControl] : []),
bumperVideoModules = [VideoControl, VideoPlaySkipControl, VideoSkipControl,
VideoVolumeControl, VideoCaption, VideoCommands, VideoSaveStatePlugin,
VideoEventsBumperPlugin, VideoCompletionHandler],
Expand Down
3 changes: 2 additions & 1 deletion common/lib/xmodule/xmodule/video_module/video_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def handle_ajax(self, dispatch, data):
accepted_keys = [
'speed', 'auto_advance', 'saved_video_position', 'transcript_language',
'transcript_download_format', 'youtube_is_available',
'bumper_last_view_date', 'bumper_do_not_show_again'
'bumper_last_view_date', 'bumper_do_not_show_again','is_complete'
]

conversions = {
Expand All @@ -77,6 +77,7 @@ def handle_ajax(self, dispatch, data):
'youtube_is_available': json.loads,
'bumper_last_view_date': to_boolean,
'bumper_do_not_show_again': to_boolean,
'is_complete': to_boolean,
}

if dispatch == 'save_user_state':
Expand Down
6 changes: 5 additions & 1 deletion common/lib/xmodule/xmodule/video_module/video_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,12 @@ def get_html(self, view=STUDENT_VIEW):
if getattr(self.runtime, 'suppports_state_for_anonymous_users', False) else ''
),
'ytTestTimeout': settings.YOUTUBE['TEST_TIMEOUT'],
}

'enableProgressSlider': self.enable_progress_slider,
'enableSpeedControl': self.enable_speed_control,
'enableNextOnCompletion': self.enable_next_on_completion,
'isComplete': self.is_complete,
}
bumperize(self)

context = {
Expand Down
29 changes: 29 additions & 0 deletions common/lib/xmodule/xmodule/video_module/video_xfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,32 @@ class VideoFields(object):
scope=Scope.preferences,
default=False,
)
enable_progress_slider = Boolean(
help=_(
"Specify whether progress bar is enabled or disabled"
),
display_name=_("Enable Progress Slider"),
scope=Scope.settings,
default=True
)
enable_speed_control = Boolean(
help=_(
"Specify whether Speed Controls are enabled or disabled"
),
display_name=_("Enable Speed Controls"),
scope=Scope.settings,
default=True
)
enable_next_on_completion = Boolean(
help=_(
"Enable Next Button on completion"
),
display_name=_("Enable Next Button on Completion"),
scope=Scope.settings,
default=False
)
is_complete = Boolean(
help=_("Is video completely watched?"),
scope=Scope.user_state,
default=False
)
6 changes: 5 additions & 1 deletion lms/djangoapps/courseware/tests/test_video_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,13 @@ def test_handle_ajax_for_speed_with_nan(self):
self.assertEqual(self.item_descriptor.global_speed, 1.0)

def test_handle_ajax(self):

data = [
{u'speed': 2.0},
{u'saved_video_position': "00:00:10"},
{u'transcript_language': 'uk'},
{u'bumper_do_not_show_again': True},
{u'bumper_last_view_date': True},
{u'is_complete': False},
{u'demoo�': 'sample'}
]
for sample in data:
Expand All @@ -222,6 +222,10 @@ def test_handle_ajax(self):
self.item_descriptor.handle_ajax('save_user_state', {'bumper_do_not_show_again': True})
self.assertEqual(self.item_descriptor.bumper_do_not_show_again, True)

self.assertEqual(self.item_descriptor.is_complete, False)
self.item_descriptor.handle_ajax('save_user_state', {'is_complete': True})
self.assertEqual(self.item_descriptor.is_complete, True)

with freezegun.freeze_time(now()):
self.assertEqual(self.item_descriptor.bumper_last_view_date, None)
self.item_descriptor.handle_ajax('save_user_state', {'bumper_last_view_date': True})
Expand Down
24 changes: 22 additions & 2 deletions lms/djangoapps/courseware/tests/test_video_mongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ def test_video_constructor(self):
'completionPercentage': 0.95,
'publishCompletionUrl': self.get_handler_url('publish_completion', ''),
'prioritizeHls': False,
'enableProgressSlider': True,
'enableSpeedControl': True,
'enableNextOnCompletion': False,
'isComplete': False,
})),
'track': None,
'transcript_download_format': u'srt',
Expand All @@ -132,7 +136,7 @@ def test_video_constructor(self):
],
'poster': 'null',
}

self.assertEqual(
get_context_dict_from_string(context),
get_context_dict_from_string(
Expand Down Expand Up @@ -207,6 +211,10 @@ def test_video_constructor(self):
'completionPercentage': 0.95,
'publishCompletionUrl': self.get_handler_url('publish_completion', ''),
'prioritizeHls': False,
'enableProgressSlider': True,
'enableSpeedControl': True,
'enableNextOnCompletion': False,
'isComplete': False,
})),
'track': None,
'transcript_download_format': u'srt',
Expand Down Expand Up @@ -271,6 +279,10 @@ def setUp(self):
'completionPercentage': 0.95,
'publishCompletionUrl': self.get_handler_url('publish_completion', ''),
'prioritizeHls': False,
'enableProgressSlider': True,
'enableSpeedControl': True,
'enableNextOnCompletion': False,
'isComplete': False,
})

def get_handler_url(self, handler, suffix):
Expand Down Expand Up @@ -2250,6 +2262,10 @@ def test_bumper_metadata(self, get_url_for_profiles, get_bumper_settings, is_bum
'completionPercentage': 0.95,
'publishCompletionUrl': self.get_handler_url('publish_completion', ''),
'prioritizeHls': False,
'enableProgressSlider': True,
'enableSpeedControl': True,
'enableNextOnCompletion': False,
'isComplete': False,
})),
'track': None,
'transcript_download_format': u'srt',
Expand Down Expand Up @@ -2330,6 +2346,10 @@ def prepare_expected_context(self, autoadvanceenabled_flag, autoadvance_flag):
'completionPercentage': 0.95,
'publishCompletionUrl': self.get_handler_url('publish_completion', ''),
'prioritizeHls': False,
'enableProgressSlider': True,
'enableSpeedControl': True,
'enableNextOnCompletion': False,
'isComplete': False,
})),
'track': None,
'transcript_download_format': u'srt',
Expand All @@ -2347,7 +2367,7 @@ def assert_content_matches_expectations(self, autoadvanceenabled_must_be, autoad
to the passed context.
Helper function to avoid code repetition.
"""

with override_settings(FEATURES=self.FEATURES):
content = self.item_descriptor.render(STUDENT_VIEW).content

Expand Down

0 comments on commit 7b6216d

Please sign in to comment.