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 10, 2021
1 parent 322e1dd commit a4539d6
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 9 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: 4 additions & 1 deletion 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 @@ -512,7 +515,7 @@ function(HTML5Video, HTML5HLSVideo, Resizer, HLS, _, Time) {
function onEnded() {
var time = this.videoPlayer.duration();


this.trigger('videoProgressSlider.notifyThroughHandleEnd', {
end: true
});
Expand Down
4 changes: 4 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 @@ -132,6 +132,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 +145,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
22 changes: 20 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,6 @@ 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 +210,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 +278,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 +2261,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 +2345,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 +2366,6 @@ 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 a4539d6

Please sign in to comment.