Commit eabfba48 by Mushtaq Ali

Change video image requirements text hover - EDUCATOR-577

parent 9750cd2a
......@@ -717,7 +717,9 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
'width': 16, # 16x9
'height': 9
},
'The minimum allowed image resolution is {image_file_min_width}x{image_file_min_height}.'.format(
'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format(
image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
)
......@@ -727,7 +729,9 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
'width': settings.VIDEO_IMAGE_MIN_WIDTH - 10,
'height': settings.VIDEO_IMAGE_MIN_HEIGHT
},
'The minimum allowed image resolution is {image_file_min_width}x{image_file_min_height}.'.format(
'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format(
image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
)
......@@ -737,7 +741,9 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
'width': settings.VIDEO_IMAGE_MIN_WIDTH,
'height': settings.VIDEO_IMAGE_MIN_HEIGHT - 10
},
'The minimum allowed image resolution is {image_file_min_width}x{image_file_min_height}.'.format(
'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format(
image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
)
......@@ -747,7 +753,9 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
'width': 1200, # not 16:9, but width/height check first.
'height': 100
},
'The minimum allowed image resolution is {image_file_min_width}x{image_file_min_height}.'.format(
'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format(
image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
)
......
......@@ -187,7 +187,10 @@ def validate_video_image(image_file):
return _('This image file is corrupted.')
image_file_aspect_ratio = abs(image_file_width / float(image_file_height) - settings.VIDEO_IMAGE_ASPECT_RATIO)
if image_file_width < settings.VIDEO_IMAGE_MIN_WIDTH or image_file_height < settings.VIDEO_IMAGE_MIN_HEIGHT:
error = _('The minimum allowed image resolution is {image_file_min_width}x{image_file_min_height}.').format(
error = _('Recommended image resolution is {image_file_max_width}x{image_file_max_height}. '
'The minimum resolution is {image_file_min_width}x{image_file_min_height}.').format(
image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
)
......
......@@ -201,12 +201,12 @@ define(
AjaxHelpers.respondWithError(requests, 400);
verifyStateInfo($thumbnail, 'error');
verifyStateInfo($thumbnail, 'edit');
});
it('calls readMessage with correct message', function() {
var errorMessage = 'This image file type is not supported. Supported file types are ' +
videoThumbnailView.getVideoImageSupportedFileFormats().humanize + '.',
var errorMessage = 'Image upload failed. This image file type is not supported. Supported file ' +
'types are ' + videoThumbnailView.getVideoImageSupportedFileFormats().humanize + '.',
successData = {
files: [createFakeImageFile()],
submit: function() {}
......@@ -255,7 +255,7 @@ define(
// Verify error message
expect($videoListEl.find('.thumbnail-error-wrapper').find('.action-text').html()
.trim()).toEqual(
'The selected image must be larger than ' +
'Image upload failed. The selected image must be larger than ' +
videoThumbnailView.getVideoImageMinSize().humanize + '.'
);
});
......@@ -270,7 +270,7 @@ define(
// Verify error message
expect($videoListEl.find('.thumbnail-error-wrapper').find('.action-text').html()
.trim()).toEqual(
'The selected image must be smaller than ' +
'Image upload failed. The selected image must be smaller than ' +
videoThumbnailView.getVideoImageMaxSize().humanize + '.'
);
});
......@@ -307,7 +307,7 @@ define(
// Verify error message
expect($videoListEl.find('.thumbnail-error-wrapper').find('.action-text').html()
.trim()).toEqual(
'This image file type is not supported. Supported file types are ' +
'Image upload failed. This image file type is not supported. Supported file types are ' +
videoThumbnailView.getVideoImageSupportedFileFormats().humanize + '.'
);
});
......
......@@ -26,26 +26,42 @@ define(
this.videoImageSettings = options.videoImageSettings;
this.actionsInfo = {
upload: {
name: 'upload',
icon: '',
text: gettext('Add Thumbnail')
},
edit: {
name: 'edit',
actionText: gettext('Edit Thumbnail'),
icon: '<span class="icon fa fa-pencil" aria-hidden="true"></span>',
text: gettext('Edit Thumbnail')
text: HtmlUtils.interpolateHtml(
// Translators: This is a 2 part text which tells the image requirements.
gettext('{InstructionsSpanStart}{videoImageResoultion}{lineBreak} {videoImageSupportedFileFormats}{spanEnd}'), // eslint-disable-line max-len
{
videoImageResoultion: this.getVideoImageResolution(),
videoImageSupportedFileFormats: this.getVideoImageSupportedFileFormats().humanize,
lineBreak: HtmlUtils.HTML('<br>'),
InstructionsSpanStart: HtmlUtils.HTML('<span class="requirements-instructions">'),
spanEnd: HtmlUtils.HTML('</span>')
}
).toString()
},
error: {
name: 'error',
icon: '',
text: gettext('Image upload failed')
},
progress: {
name: 'progress-action',
icon: '<span class="icon fa fa-spinner fa-pulse fa-spin" aria-hidden="true"></span>',
text: gettext('Uploading')
},
requirements: {
name: 'requirements',
icon: '',
text: HtmlUtils.interpolateHtml(
// Translators: This is a 3 part text which tells the image requirements.
gettext('{ReqTextSpanStart}Image requirements{spanEnd}{lineBreak}{InstructionsSpanStart}{videoImageResoultion}{lineBreak} {videoImageSupportedFileFormats}{spanEnd}'), // eslint-disable-line max-len
gettext('{ReqTextSpanStart}Requirements{spanEnd}{lineBreak}{InstructionsSpanStart}{videoImageResoultion}{lineBreak} {videoImageSupportedFileFormats}{spanEnd}'), // eslint-disable-line max-len
{
videoImageResoultion: this.getVideoImageResolution(),
videoImageSupportedFileFormats: this.getVideoImageSupportedFileFormats().humanize,
......@@ -259,26 +275,40 @@ define(
},
setActionInfo: function(action, showText, additionalSRText) {
var hasError = this.$('.thumbnail-wrapper').hasClass('error');
this.$('.thumbnail-action').toggle(showText);
// In case of error, we don't want to show any icon on the image.
if (action === 'error') {
HtmlUtils.setHtml(
this.$('.thumbnail-action .action-icon'),
HtmlUtils.HTML('')
);
} else {
HtmlUtils.setHtml(
this.$('.thumbnail-action .action-icon'),
HtmlUtils.HTML(this.actionsInfo[action].icon)
);
}
HtmlUtils.setHtml(
this.$('.thumbnail-action .action-text'),
HtmlUtils.HTML(this.actionsInfo[action].text)
);
this.$('.thumbnail-action .action-text-sr').text(additionalSRText || '');
this.$('.thumbnail-wrapper').attr('class', 'thumbnail-wrapper {action}'.replace('{action}', action));
this.$('.thumbnail-action .action-icon')
.attr('class', 'action-icon {action}'.replace('{action}', action));
// Add error class if it was already present.
if (hasError) {
this.$('.thumbnail-wrapper').addClass('error');
}
// Don't show edit-container layout on progress action.
if (action === 'progress') {
this.$('.thumbnail-action .edit-container').toggle(false);
} else if (action === 'edit') {
this.$('.thumbnail-action .edit-container').toggle(true);
HtmlUtils.setHtml(
this.$('.thumbnail-action .edit-container .action-icon'),
HtmlUtils.HTML(this.actionsInfo[action].icon)
);
HtmlUtils.setHtml(
this.$('.thumbnail-action .edit-container .edit-action-text'),
HtmlUtils.HTML(this.actionsInfo[action].actionText)
);
}
},
validateImageFile: function(imageFile) {
......@@ -320,22 +350,29 @@ define(
if ($thumbnailWrapperEl.length) {
$thumbnailWrapperEl.remove();
}
// Remove error class from thumbnail wrapper as well.
$('.thumbnail-wrapper').removeClass('error');
},
showErrorMessage: function(errorText) {
var videoId = this.model.get('edx_video_id'),
$parentRowEl = $(this.$el.parent());
this.action = 'error';
// If image url is not this.defaultVideoImageURL then it means image is uploaded
// so we should treat it as edit action otherwise default upload action.
this.action = this.$('.thumbnail-wrapper img').attr('src') !== this.defaultVideoImageURL
? 'edit' : 'upload';
this.setActionInfo(this.action, true);
this.readMessages([gettext('Could not upload the video image file'), errorText]);
errorText = gettext('Image upload failed. ') + errorText; // eslint-disable-line no-param-reassign
// Add error wrapper html to current video element row.
$parentRowEl.before( // safe-lint: disable=javascript-jquery-insertion
$parentRowEl.before( // xss-lint: disable=javascript-jquery-insertion
HtmlUtils.ensureHtml(
this.thumbnailErrorTemplate({videoId: videoId, errorText: errorText})
).toString()
);
this.$el.find('.thumbnail-wrapper').addClass('error');
},
readMessages: function(messages) {
......
......@@ -179,23 +179,15 @@
display: table-cell;
}
.thumbnail-col {
width: 15%;
}
.name-col {
width: 25%;
}
.date-col {
width: 10%;
}
.video-id-col {
.thumbnail-col, .video-id-col {
width: 15%;
}
.status-col {
.date-col, .status-col {
width: 10%;
}
......@@ -203,20 +195,18 @@
width: 5%;
}
.video-head-col.thumbnail-col {
width: 17% !important;
}
}
}
.thumbnail-error-wrapper {
display: table-row;
white-space: nowrap;
.thumbnail-error-text {
color: $red;
padding: 10px 10px 0;
.action-text {
margin-left: 5px;
}
.icon {
margin: ($baseline*0.75) ($baseline/4) 0 ($baseline/2);
}
}
......@@ -250,7 +240,7 @@
font-size: 15px;
font-family: "Open Sans";
text-align: left;
color: #4c4c4c;
color: $gray-d2;
line-height: 1.5;
}
.video-duration {
......@@ -271,7 +261,6 @@
}
}
&.error,
&.progress {
background: white;
......@@ -285,10 +274,6 @@
}
}
&.error .thumbnail-action {
color: $red;
}
&.upload .thumbnail-action {
color: $blue;
}
......@@ -299,10 +284,24 @@
}
}
&.edit .thumbnail-action {
background-color: white;
&.edit {
background-color: #4e4e4e;
}
&.edit .thumbnail-action .action-icon.edit {
display: none;
}
&.edit .thumbnail-action .edit-container {
background-color: $white;
padding: ($baseline/4);
border-radius: ($baseline/5);
margin-top: ($baseline/2);
display: none;
}
&.edit .action-text {
color: $white;
}
.thumbnail-action {
......@@ -316,6 +315,7 @@
left: 5px;;
right: 5px;
@include transform(translateY(-50%));
z-index: 1;
}
.upload-image-input {
......@@ -344,5 +344,9 @@
&.focused {
box-shadow: 0 0 ($baseline/5) 1px $blue;
}
&.error {
box-shadow: 0 0 ($baseline/5) 1px $red;
}
}
}
<div class="thumbnail-error-wrapper thumbnail-error" data-video-id="<%- videoId %>">
<div class="thumbnail-error-text">
<span class="action-icon" aria-hidden="true">
<span class="icon fa fa-exclamation-triangle" aria-hidden="true"></span>
</span>
<span class="action-text"><%- errorText %></span>
</div>
</div>
......@@ -3,9 +3,13 @@
<div class="thumbnail-overlay">
<input id="thumb-<%- videoId %>" class="upload-image-input" type="file" name="file" accept=".bmp, .jpg, .jpeg, .png, .gif"/>
<label for="thumb-<%- videoId %>" class="thumbnail-action">
<span class="action-icon" aria-hidden="true"><%- actionInfo.icon %></span>
<span class="main-icon action-icon <%- actionInfo.name %>" aria-hidden="true"><%- actionInfo.icon %></span>
<span class="action-text-sr sr"></span>
<span class="action-text"><%- actionInfo.text %></span>
<div class="edit-container">
<span class="action-icon" aria-hidden="true"><%- actionInfo.icon %></span>
<span class="edit-action-text"><%- actionInfo.actionText %></span>
</div>
</label>
<span class="requirements-text-sr sr">
......
......@@ -77,7 +77,7 @@ git+https://github.com/edx/lettuce.git@0.2.20.002#egg=lettuce==0.2.20.002
git+https://github.com/edx/edx-ora2.git@1.4.3#egg=ora2==1.4.3
-e git+https://github.com/edx/edx-submissions.git@2.0.0#egg=edx-submissions==2.0.0
git+https://github.com/edx/ease.git@release-2015-07-14#egg=ease==0.1.3
git+https://github.com/edx/edx-val.git@0.0.15#egg=edxval==0.0.15
git+https://github.com/edx/edx-val.git@ammar/auto-generated-images-fixes
git+https://github.com/pmitros/RecommenderXBlock.git@v1.2#egg=recommender-xblock==1.2
git+https://github.com/solashirai/crowdsourcehinter.git@518605f0a95190949fe77bd39158450639e2e1dc#egg=crowdsourcehinter-xblock==0.1
-e git+https://github.com/pmitros/RateXBlock.git@367e19c0f6eac8a5f002fd0f1559555f8e74bfff#egg=rate-xblock
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment