Files
edx-platform/cms/static/js/views/video_transcripts.js
2023-05-09 13:53:54 +05:00

365 lines
17 KiB
JavaScript

define(
['underscore', 'gettext', 'js/views/baseview', 'common/js/components/views/feedback_prompt',
'edx-ui-toolkit/js/utils/html-utils', 'edx-ui-toolkit/js/utils/string-utils',
'common/js/components/utils/view_utils', 'text!templates/video-transcripts.underscore',
'text!templates/video-transcript-upload-status.underscore'],
function(_, gettext, BaseView, PromptView, HtmlUtils, StringUtils, ViewUtils, videoTranscriptsTemplate,
videoTranscriptUploadStatusTemplate) {
'use strict';
var VideoTranscriptsView = BaseView.extend({
tagName: 'div',
events: {
'click .toggle-show-transcripts-button': 'toggleShowTranscripts',
'click .upload-transcript-button': 'chooseFile',
'click .delete-transcript-button': 'deleteTranscript',
'click .more-details-action': 'showUploadFailureMessage'
},
initialize: function(options) {
this.isCollapsed = true;
this.transcripts = options.transcripts;
this.edxVideoID = options.edxVideoID;
this.clientVideoID = options.clientVideoID;
this.transcriptionStatus = options.transcriptionStatus;
this.errorDescription = options.errorDescription;
this.transcriptAvailableLanguages = options.transcriptAvailableLanguages;
this.videoSupportedFileFormats = options.videoSupportedFileFormats;
this.videoTranscriptSettings = options.videoTranscriptSettings;
this.template = HtmlUtils.template(videoTranscriptsTemplate);
this.transcriptUploadStatusTemplate = HtmlUtils.template(videoTranscriptUploadStatusTemplate);
this.defaultFailureTitle = gettext('The file could not be uploaded.');
this.defaultFailureMessage = gettext('This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.'); // eslint-disable-line max-len
this.transcriptUploadStatuses = {
uploaded: {
statusClass: 'success',
iconClasses: 'fa-check',
shortMessage: 'Transcript uploaded.',
hiddenClass: 'hidden'
},
uploading: {
statusClass: '',
iconClasses: 'fa-spinner fa-pulse',
shortMessage: 'Uploading transcript.',
hiddenClass: 'hidden'
},
failed: {
statusClass: 'error',
iconClasses: 'fa-warning',
shortMessage: 'Upload failed.',
hiddenClass: ''
},
validationFailed: {
statusClass: 'error',
iconClasses: 'fa-warning',
shortMessage: 'Validation failed.',
hiddenClass: ''
}
};
// This is needed to attach transcript methods to this object while uploading.
_.bindAll(
this, 'render', 'chooseFile', 'transcriptSelected', 'transcriptUploadSucceeded',
'transcriptUploadFailed'
);
},
/*
Returns transcript title.
*/
getTranscriptClientTitle: function() {
var clientTitle = this.clientVideoID;
// Remove video file extension for transcript title.
_.each(this.videoSupportedFileFormats, function(videoFormat) {
clientTitle = clientTitle.replace(videoFormat, '');
});
return clientTitle.substring(0, 20);
},
/*
Returns transcript download link.
*/
getTranscriptDownloadLink: function(edxVideoID, transcriptLanguageCode, transcriptDownloadHandlerUrl) {
return StringUtils.interpolate(
'{transcriptDownloadHandlerUrl}?edx_video_id={edxVideoID}&language_code={transcriptLanguageCode}',
{
transcriptDownloadHandlerUrl: transcriptDownloadHandlerUrl,
edxVideoID: edxVideoID,
transcriptLanguageCode: transcriptLanguageCode
}
);
},
/*
Returns transcript delete handler url.
*/
getTranscriptDeleteUrl: function(edxVideoID, transcriptLanguageCode, transcriptDeleteHandlerUrl) {
return StringUtils.interpolate(
'{transcriptDeleteHandlerUrl}/{edxVideoID}/{transcriptLanguageCode}',
{
transcriptDeleteHandlerUrl: transcriptDeleteHandlerUrl,
edxVideoID: edxVideoID,
transcriptLanguageCode: transcriptLanguageCode
}
);
},
/*
Toggles Show/Hide transcript button and transcripts container.
*/
toggleShowTranscripts: function() {
var $transcriptsWrapperEl = this.$el.find('.video-transcripts-wrapper');
if ($transcriptsWrapperEl.hasClass('hidden')) {
this.showTranscripts();
this.isCollapsed = false;
} else {
this.hideTranscripts();
this.isCollapsed = true;
}
},
showTranscripts: function() {
// Show transcript wrapper
this.$el.find('.video-transcripts-wrapper').removeClass('hidden');
// Update button text.
HtmlUtils.setHtml(
this.$el.find('.toggle-show-transcripts-button-text'),
StringUtils.interpolate(
gettext('Hide transcripts ({transcriptCount})'),
{
transcriptCount: this.transcripts.length
}
)
);
this.$el.find('.toggle-show-transcripts-icon')
.removeClass('fa-caret-right')
.addClass('fa-caret-down');
},
hideTranscripts: function() {
// Hide transcript wrapper
this.$el.find('.video-transcripts-wrapper').addClass('hidden');
// Update button text.
HtmlUtils.setHtml(
this.$el.find('.toggle-show-transcripts-button-text'),
StringUtils.interpolate(
gettext('Show transcripts ({transcriptCount})'),
{
transcriptCount: this.transcripts.length
}
)
);
this.$el.find('.toggle-show-transcripts-icon')
.removeClass('fa-caret-down')
.addClass('fa-caret-right');
},
validateTranscriptUpload: function(file) {
var errorMessage = '',
fileName = file.name,
fileType = fileName.substr(fileName.lastIndexOf('.') + 1);
if (fileType !== this.videoTranscriptSettings.trancript_download_file_format) {
errorMessage = gettext(
'This file type is not supported. Supported file type is {supportedFileFormat}.'
)
.replace('{supportedFileFormat}', this.videoTranscriptSettings.trancript_download_file_format);
}
return errorMessage;
},
chooseFile: function(event) {
var $transcriptContainer = $(event.target).parents('.video-transcript-content'),
$transcriptUploadEl = $transcriptContainer.find('.upload-transcript-input');
$transcriptUploadEl.fileupload({
url: this.videoTranscriptSettings.transcript_upload_handler_url,
add: this.transcriptSelected,
done: this.transcriptUploadSucceeded,
fail: this.transcriptUploadFailed,
formData: {
edx_video_id: this.edxVideoID,
language_code: $transcriptContainer.attr('data-language-code'),
new_language_code: $transcriptContainer.find('.transcript-language-menu').val()
}
});
$transcriptUploadEl.click();
},
transcriptSelected: function(event, data) {
var errorMessage,
$transcriptContainer = $(event.target).parents('.video-transcript-content');
errorMessage = this.validateTranscriptUpload(data.files[0]);
if (!errorMessage) {
// Do not trigger global AJAX error handler
data.global = false; // eslint-disable-line no-param-reassign
data.submit();
this.renderMessage($transcriptContainer, 'uploading');
} else {
// Reset transcript language back to original.
$transcriptContainer.find('.transcript-language-menu').val($transcriptContainer.attr('data-language-code')); // eslint-disable-line max-len
this.renderMessage($transcriptContainer, 'validationFailed', errorMessage);
}
},
transcriptUploadSucceeded: function(event, data) {
var languageCode = data.formData.language_code,
newLanguageCode = data.formData.new_language_code,
$transcriptContainer = this.$el.find('.video-transcript-content[data-language-code="' + languageCode + '"]'); // eslint-disable-line max-len
$transcriptContainer.attr('data-language-code', newLanguageCode);
$transcriptContainer.find('.download-transcript-button').attr(
'href',
this.getTranscriptDownloadLink(
this.edxVideoID,
newLanguageCode,
this.videoTranscriptSettings.transcript_download_handler_url
)
);
HtmlUtils.setHtml(
$transcriptContainer.find('.transcript-title'),
StringUtils.interpolate(gettext('{transcriptClientTitle}_{transcriptLanguageCode}.{fileExtension}'),
{
transcriptClientTitle: this.getTranscriptClientTitle(),
transcriptLanguageCode: newLanguageCode,
fileExtension: this.videoTranscriptSettings.trancript_download_file_format
}
)
);
this.renderMessage($transcriptContainer, 'uploaded');
},
transcriptUploadFailed: function(event, data) {
var errorMessage,
languageCode = data.formData.language_code,
$transcriptContainer = this.$el.find('.video-transcript-content[data-language-code="' + languageCode + '"]'); // eslint-disable-line max-len
try {
errorMessage = JSON.parse(data.jqXHR.responseText).error;
errorMessage = errorMessage || this.defaultFailureMessage;
} catch (error) {
errorMessage = this.defaultFailureMessage;
}
// Reset transcript language back to original.
$transcriptContainer.find('.transcript-language-menu').val(languageCode);
this.renderMessage($transcriptContainer, 'failed', errorMessage);
},
deleteTranscript: function(event) {
var self = this,
$transcriptEl = $(event.target).parents('.video-transcript-content'),
languageCode = $transcriptEl.attr('data-language-code'),
transcriptDeleteUrl = self.getTranscriptDeleteUrl(
self.edxVideoID,
languageCode,
self.videoTranscriptSettings.transcript_delete_handler_url
);
ViewUtils.confirmThenRunOperation(
gettext('Are you sure you want to remove this transcript?'),
gettext('If you remove this transcript, the transcript will not be available for any components that use this video.'), // eslint-disable-line max-len
gettext('Remove'),
function() {
ViewUtils.runOperationShowingMessage(
gettext('Removing'),
function() {
return $.ajax({
url: transcriptDeleteUrl,
type: 'DELETE'
}).done(function() {
// Update transcripts.
self.transcripts = _.without(self.transcripts, languageCode);
// re-render transcripts.
self.render();
});
}
);
}
);
},
clearMessage: function() {
var $transcriptStatusesEl = this.$el.find('.transcript-upload-status-container');
// Clear all message containers
HtmlUtils.setHtml($transcriptStatusesEl, '');
$transcriptStatusesEl.removeClass('success error');
},
renderMessage: function($transcriptContainer, status, errorMessage) {
var statusData = this.transcriptUploadStatuses[status],
$transcriptStatusEl = $transcriptContainer.find('.transcript-upload-status-container');
// If a messge is already present above the video transcript element, remove it.
this.clearMessage();
HtmlUtils.setHtml(
$transcriptStatusEl,
this.transcriptUploadStatusTemplate({
status: statusData.statusClass,
iconClasses: statusData.iconClasses,
shortMessage: gettext(statusData.shortMessage),
errorMessage: errorMessage || '',
hiddenClass: statusData.hiddenClass
})
);
$transcriptStatusEl.addClass(statusData.statusClass);
},
showUploadFailureMessage: function(event) {
var errorMessage = $(event.target).data('error-message');
return new PromptView.Warning({
title: this.defaultFailureTitle,
message: errorMessage,
actions: {
primary: {
text: gettext('Close'),
click: function(prompt) {
return prompt.hide();
}
}
}
}).show();
},
/*
Renders transcripts view.
*/
render: function() {
HtmlUtils.setHtml(
this.$el,
this.template({
transcripts: this.transcripts,
error_description: this.errorDescription,
transcription_status: this.transcriptionStatus,
transcriptAvailableLanguages: this.transcriptAvailableLanguages,
edxVideoID: this.edxVideoID,
transcriptClientTitle: this.getTranscriptClientTitle(),
transcriptFileFormat: this.videoTranscriptSettings.trancript_download_file_format,
getTranscriptDownloadLink: this.getTranscriptDownloadLink,
transcriptDownloadHandlerUrl: this.videoTranscriptSettings.transcript_download_handler_url
})
);
if (this.isCollapsed) {
this.hideTranscripts();
} else {
this.showTranscripts();
}
return this;
}
});
return VideoTranscriptsView;
}
);