Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:raccoongang/xblock-video into featur…
Browse files Browse the repository at this point in the history
…e/interactive_transcripts_display

Fix conflicts
  • Loading branch information
sendr committed Jan 3, 2017
2 parents ac6f434 + 7d67dc6 commit 8de712f
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 69 deletions.
12 changes: 11 additions & 1 deletion video_xblock/static/css/videojs-contextmenu-ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@
background-color: #2B333F;
background-color: rgba(43, 51, 63, 0.9);
border-radius: 0.3em;
padding: 0.25em; }
padding: 0.25em;
}


.vjs-contextmenu-ui-submenu {
left: 100%;
top: 7em;
width: 50%;
display : none;
}
.vjs-contextmenu-ui-submenu:hover{
display : block;
}

.vjs-menu-item:last-of-type:hover .vjs-contextmenu-ui-submenu{
display : block;
}

.vjs-contextmenu-ui-menu .vjs-menu-item,
Expand Down
25 changes: 25 additions & 0 deletions video_xblock/static/html/student_view.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,29 @@ <h3 class="hd hd-2">{{display_name}}</h3>
<a href="{{ handout }}" class="download-handout" download="{{ handout_file_name }}">{% trans 'Download Handout' %}</a>
</li>
{% endif %}
{% if download_transcript_allowed and transcripts %}
<li class="video-transcript video-download-button-custom">
<a class="download-transcript" id="download-transcript-link" href="#">{% trans 'Download transcript' %}</a>
<script>
var transcripts = {
{% for transcript in transcripts %}
'{{transcript.lang}}': {
'label': '{{transcript.label}}',
'url': '{{transcript.url}}',
},
{% endfor %}
};

/** Change download link consider selected transcript's language */
function chooseTransciptForDownload(language){
language = language || 'en';
var currentTranscript = transcripts[language] || transcripts[Object.keys(transcripts)[0]]
document.getElementById('download-transcript-link').href=currentTranscript.url;
}
// TODO Load current transcript from state and send it as paramenter of function below
chooseTransciptForDownload();
</script>
</li>
{% endif %}
</ul>

147 changes: 81 additions & 66 deletions video_xblock/static/js/player-context-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,90 +8,105 @@
*
*/

/**
* Initialise player context menu with nested elements.
*/
domReady(function() {

var videoPlayer = document.getElementById("{{ video_player_id }}");
var dataSetup = JSON.parse(videoPlayer.getAttribute('data-setup'));
var playbackRates = dataSetup.playbackRates;
var docfrag = document.createDocumentFragment();
// VideoJS Player() object necessary for context menu creation
var player = videojs('{{ video_player_id }}');

/**
* Create elements of nested context submenu.
*/
function createNestedContextSubMenu(e) {
var target = e.target;

// Generate nested submenu elements as document fragment
var ulSubMenu = document.createElement('ul');
ulSubMenu.className = 'vjs-contextmenu-ui-submenu';
playbackRates.forEach(function(rate) {
var liSubMenu = document.createElement('li');
liSubMenu.className = 'vjs-submenu-item';
liSubMenu.innerHTML = rate + 'x';
ulSubMenu.appendChild(liSubMenu);
liSubMenu.onclick = function() {
player.playbackRate(parseFloat(rate));
};
});
docfrag.appendChild(ulSubMenu);

// Create nested submenu
if (target.matches("li.vjs-menu-item")
&& target.innerText == player.contextmenuUI.content[3].label
&& target.innerText == getItem('speed').label
&& !target.querySelector('.vjs-contextmenu-ui-submenu') ) {

// Create nested submenu
var ulSubMenu = document.createElement('ul');
ulSubMenu.className = 'vjs-contextmenu-ui-submenu';
target.appendChild(ulSubMenu);
for (var i = 0; i < playbackRates.length; i++) {
var liSubMenu = document.createElement('li');
liSubMenu.className = 'vjs-submenu-item';
liSubMenu.innerHTML = playbackRates[i] + 'x';
ulSubMenu.appendChild(liSubMenu);
liSubMenu.onclick = function(){
player.playbackRate(parseFloat(this.innerHTML));
}
}

// Hide nested submenu
var els = [target, ulSubMenu];
els.forEach(function(item){
item.onmouseout = function() { ulSubMenu.style.visibility = 'hidden' };
});

var liSpeedMenuItem = document.querySelectorAll('.vjs-contextmenu-ui-menu .vjs-menu-item')[3];
target.appendChild(docfrag);
}

// Show nested submenu
if (liSpeedMenuItem) {
liSpeedMenuItem.addEventListener('mouseover', function(){
document.querySelector('.vjs-contextmenu-ui-submenu').style.visibility = 'visible';
})}
}

// Delegate creation of a nested submenu for a context menu
videoPlayer.addEventListener('mouseover', createNestedContextSubMenu);

// Fire up vjs-contextmenu-ui plugin, add context menu options
player.contextmenuUI({
content: [{
label: 'Play',
listener: function () {
if (player.paused()) {
player.play();
player.contextmenuUI.content[0]['label'] = 'Pause';
} else {
player.pause();
player.contextmenuUI.content[0]['label'] = 'Play';
}
}}, {
label: 'Mute',
listener: function () {
if (player.muted()) {
player.muted(false);
player.contextmenuUI.content[1]['label'] = 'Mute';
} else {
player.muted(true);
player.contextmenuUI.content[1]['label'] = 'Unmute';
}
}}, {
label: 'Fill browser',
listener: function () {
if (player.isFullscreen()) {
player.exitFullscreen();
player.contextmenuUI.content[2]['label'] = 'Fill browser';
} else {
player.requestFullscreen();
player.contextmenuUI.content[2]['label'] = 'Unfill browser';
}
}}, {
// Nested submenu creation is delegated to the player
label: 'Speed'}
]
});
// Create context menu options
var content = [{
id: "play",
label: 'Play',
listener: function () {
var item = getItem('play');
if (player.paused()) {
player.play();
item['label'] = 'Pause';
} else {
player.pause();
item['label'] = 'Play';
}
}}, {
id: "mute",
label: 'Mute',
listener: function () {
var item = getItem('mute');
if (player.muted()){
player.muted(false);
item['label'] = 'Mute';
} else {
player.muted(true);
item['label'] = 'Unmute';
}
}}, {
id: "fullscreen",
label: 'Fill browser',
listener: function () {
var item = getItem('fullscreen');
if (player.isFullscreen()){
player.exitFullscreen();
item['label'] = 'Fill browser';
} else {
player.requestFullscreen();
item['label'] = 'Unfill browser';
}
}}, {
// Nested submenu creation is delegated to the player
id: "speed",
label: 'Speed'
}
];

// Fire up vjs-contextmenu-ui plugin
player.contextmenuUI({content: content});

// Update context menu labels
var getItem = (function(contextmenuUI) {
var hash = {};
contextmenuUI.content.forEach(function(item) {
hash[item.id] = item;
});
return function(id) {
return hash[id];
};
}(player.contextmenuUI));

});
17 changes: 15 additions & 2 deletions video_xblock/video_xblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,21 @@ class VideoXBlock(StudioEditableXBlockMixin, XBlock):
default='',
scope=Scope.content,
display_name=_('Upload transcript'),
help=_('Add transcripts in different languages. Click below to specify a language and upload an .srt transcript file for that language.')
help=_('Add transcripts in different languages. Click below to specify a language and upload an .srt transcript'
' file for that language.')
)

editable_fields = ('display_name', 'href', 'start_time', 'end_time', 'account_id', 'handout', 'transcripts', 'player_id')
download_transcript_allowed = Boolean(
default=False,
scope=Scope.content,
display_name=_('Download Transcript Allowed'),
help=_("Allow students to download the timed transcript. A link to download the file appears below the video."
" By default, the transcript is an .srt or .txt file. If you want to provide the transcript for download"
" in a different format, upload a file by using the Upload Handout field.")
)

editable_fields = ('display_name', 'href', 'start_time', 'end_time', 'account_id', 'player_id', 'handout',
'transcripts', 'download_transcript_allowed')
player_state_fields = ('current_time', 'muted', 'playback_rate', 'volume', 'transcripts_enabled')

@property
Expand Down Expand Up @@ -236,6 +247,8 @@ def student_view(self, context=None):
display_name=self.display_name,
usage_id=self.location.to_deprecated_string(),
handout=self.handout,
transcripts=json.loads(self.transcripts) if self.transcripts else [],
download_transcript_allowed=self.download_transcript_allowed,
handout_file_name=self.get_handout_file_name()
)
)
Expand Down

0 comments on commit 8de712f

Please sign in to comment.