diff --git a/common/static/js/vendor/ova/annotator-full.js b/common/static/js/vendor/ova/annotator-full.js index 156b14e212..0b85c3dc68 100644 --- a/common/static/js/vendor/ova/annotator-full.js +++ b/common/static/js/vendor/ova/annotator-full.js @@ -2506,21 +2506,21 @@ Annotator.Plugin.Store = (function(_super) { Store.prototype._onError = function(xhr) { var action, message; action = xhr._action; - message = Annotator._t("Sorry we could not ") + action + Annotator._t(" this annotation"); + message = Annotator._t("Sorry, our server seems to be down. We could not ") + action + Annotator._t(" this annotation"); if (xhr._action === 'search') { - message = Annotator._t("Sorry we could not search the store for annotations"); + message = Annotator._t("Sorry, the Annotations service is down. Contact your instructor and try again later."); } else if (xhr._action === 'read' && !xhr._id) { - message = Annotator._t("Sorry we could not ") + action + Annotator._t(" the annotations from the store"); + message = Annotator._t("Sorry, our server seems to be down. We could not ") + action + Annotator._t(" the annotation(s)."); } switch (xhr.status) { case 401: - message = Annotator._t("Sorry you are not allowed to ") + action + Annotator._t(" this annotation"); + message = Annotator._t("Sorry, you are not allowed to ") + action + Annotator._t(" this annotation"); break; case 404: - message = Annotator._t("Sorry we could not connect to the annotations store"); + message = Annotator._t("Sorry, we could not connect to the annotations database."); break; case 500: - message = Annotator._t("Sorry something went wrong with the annotation store"); + message = Annotator._t("Sorry, our server is down. Contact your instructor and try again later."); } Annotator.showNotification(message, Annotator.Notification.ERROR); return console.error(Annotator._t("API request failed:") + (" '" + xhr.status + "'")); diff --git a/common/static/js/vendor/ova/catch/css/main.css b/common/static/js/vendor/ova/catch/css/main.css index 5f5406c560..331e171fa2 100644 --- a/common/static/js/vendor/ova/catch/css/main.css +++ b/common/static/js/vendor/ova/catch/css/main.css @@ -530,4 +530,9 @@ #mainCatch .replies .replyItem .deleteReply{ text-decoration: underline; cursor: pointer; -} \ No newline at end of file +} + +#mainCatch div.annotations-loading-gif{ + width:100%; + text-align:center; +} diff --git a/common/static/js/vendor/ova/catch/img/loading_bar.gif b/common/static/js/vendor/ova/catch/img/loading_bar.gif new file mode 100644 index 0000000000..dd936613b1 Binary files /dev/null and b/common/static/js/vendor/ova/catch/img/loading_bar.gif differ diff --git a/common/static/js/vendor/ova/catch/js/catch.js b/common/static/js/vendor/ova/catch/js/catch.js index fdf69c6465..b76b2e67ed 100644 --- a/common/static/js/vendor/ova/catch/js/catch.js +++ b/common/static/js/vendor/ova/catch/js/catch.js @@ -353,14 +353,14 @@ CatchAnnotation.prototype = { // under the instructor's email. Calling changeUserId will update this.options.userId // and most importantly refresh not only the highlights (from Annotator) // but also the table below from the annotations database server (called Catch). - if(this.options.default_tab.toLowerCase() === 'instructor'){ + if(this.options.default_tab.toLowerCase() === 'instructor') { this.changeUserId(this.options.instructor_email); } }, // // GLOBAL UTILITIES // - getTemplate: function(templateName){ + getTemplate: function(templateName) { return this.TEMPLATES[templateName]() || ''; }, refreshCatch: function(newInstance) { @@ -376,7 +376,7 @@ CatchAnnotation.prototype = { var isUser = (typeof self.options.userId !== 'undefined' && self.options.userId !== '' && self.options.userId !== null)? self.options.userId === annotation.user.id:true; var isInList = newInstance?false:self._isInList(annotation); - if (isMedia && isUser && !isInList){ + if (isMedia && isUser && !isInList) { var item = jQuery.extend(true, {}, annotation); self._formatCatch(item); @@ -401,8 +401,8 @@ CatchAnnotation.prototype = { } }); - if (newInstance){ - var videoFormat = (mediaType === "video") ? true:false; + if (newInstance) { + var videoFormat = (mediaType === "video") ? true : false; var publicPrivateTemplate = ''; if (self.options.showPublicPrivate) { var templateName = this.options.instructor_email ? @@ -415,7 +415,7 @@ CatchAnnotation.prototype = { PublicPrivate: this.getTemplate(templateName), MediaSelector: self.options.showMediaSelector?self.TEMPLATES.annotationMediaSelector():'', })); - }else{ + } else { var list = $("#mainCatch .annotationList"); annotationItems.forEach(function(annotation) { list.append($(annotation)); @@ -466,8 +466,8 @@ CatchAnnotation.prototype = { var onClearSearchButtonClick = this.__bind(this._onClearSearchButtonClick, this); var onDeleteReplyButtonClick = this.__bind(this._onDeleteReplyButtonClick, this); var onZoomToImageBoundsButtonClick = this.__bind(this._onZoomToImageBoundsButtonClick, this); - - // Open Button + var openLoadingGIF = this.__bind(this.openLoadingGIF, this); + //Open Button el.on("click", ".annotationItem .annotationRow", openAnnotationItem); // Close Button el.on("click", ".annotationItem .detailHeader", closeAnnotationItem); @@ -511,6 +511,7 @@ CatchAnnotation.prototype = { // Delete Reply Button el.on("click", ".replies .replyItem .deleteReply", onDeleteReplyButtonClick); + el.on("click", ".annotationListButtons .PublicPrivate", openLoadingGIF); }, changeMedia: function(media) { var media = media || 'text'; @@ -544,7 +545,7 @@ CatchAnnotation.prototype = { // if the options.userID (i.e. the value we are searching for) is empty signifying // public or is equal to the person with update access, then we leave it alone, // otherwise we need to clean them up (i.e. disable them). - if(self.options.userId !== '' && self.options.userId !== value.permissions.update[0]){ + if (self.options.userId !== '' && self.options.userId !== value.permissions.update[0]) { $.each(value.highlights, function(key1, value1){ $(value1).removeClass('annotator-hl'); }); @@ -577,7 +578,7 @@ CatchAnnotation.prototype = { }, // check whether is necessary to have a more button or not - checkTotAnnotations: function(){ + checkTotAnnotations: function() { var annotator = this.annotator; var loadFromSearch = annotator.plugins.Store.options.loadFromSearch; var oldLimit = loadFromSearch.limit; @@ -588,7 +589,7 @@ CatchAnnotation.prototype = { loadFromSearch.offset = 0; loadFromSearch.media = this.options.media; loadFromSearch.userid = this.options.userId; - var onSuccess = function(response){ + var onSuccess = function(response) { var totAn = self.element.find('.annotationList .annotationItem').length; var maxAn = response.total; var moreBut = self.element.find('.annotationListButtons .moreButtonCatch'); @@ -620,37 +621,37 @@ CatchAnnotation.prototype = { // // LOCAL UTILITIES // - _subscribeAnnotator: function(){ + _subscribeAnnotator: function() { var self = this; var annotator = this.annotator; // Subscribe to Annotator changes - annotator.subscribe("annotationsLoaded", function (annotations){ + annotator.subscribe("annotationsLoaded", function (annotations) { self.cleanUpAnnotations(); self.refreshCatch(self.clean); // hide or show more button self.checkTotAnnotations(); }); - annotator.subscribe("annotationUpdated", function (annotation){ + annotator.subscribe("annotationUpdated", function (annotation) { self.refreshCatch(true); self.checkTotAnnotations(); }); - annotator.subscribe("annotationDeleted", function (annotation){ + annotator.subscribe("annotationDeleted", function (annotation) { var annotations = annotator.plugins['Store'].annotations; - var tot = typeof annotations !== 'undefined'?annotations.length:0; + var tot = typeof annotations !== 'undefined' ?annotations.length : 0; var attempts = 0; // max 100 - if(annotation.media === "image"){ + if(annotation.media === "image") { self.refreshCatch(true); self.checkTotAnnotations(); } else { // This is to watch the annotations object, to see when is deleted the annotation - var ischanged = function(){ + var ischanged = function() { var new_tot = annotator.plugins['Store'].annotations.length; if (attempts<100) - setTimeout(function(){ - if (new_tot !== tot){ + setTimeout(function() { + if (new_tot !== tot) { self.refreshCatch(true); self.checkTotAnnotations(); - }else{ + } else { attempts++; ischanged(); } @@ -659,7 +660,7 @@ CatchAnnotation.prototype = { ischanged(); } }); - annotator.subscribe("annotationCreated", function (annotation){ + annotator.subscribe("annotationCreated", function (annotation) { var attempts = 0; // max 100 // There is a delay between calls to the backend--especially reading after // writing. This function listens to when a function is created and waits @@ -667,7 +668,7 @@ CatchAnnotation.prototype = { // with it. var ischanged = function(){ if (attempts<100) - setTimeout(function(){ + setTimeout(function() { if (typeof annotation.id !== 'undefined'){ // once it gets the annotation id, the table refreshes to show @@ -686,7 +687,7 @@ CatchAnnotation.prototype = { replies.click(); replies.click(); } - }else{ + } else { attempts++; ischanged(); } @@ -695,7 +696,7 @@ CatchAnnotation.prototype = { ischanged(); }); }, - __bind: function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __bind: function(fn, me) { return function(){ return fn.apply(me, arguments); }; }, _compileTemplates: function() { var self = this; // Change the html tags to functions @@ -703,7 +704,7 @@ CatchAnnotation.prototype = { self.TEMPLATES[templateName] = Handlebars.compile(self.HTMLTEMPLATES[templateName]); }); }, - _isVideoJS: function (an){ + _isVideoJS: function (an) { var annotator = this.annotator; var rt = an.rangeTime; var isOpenVideojs = (typeof annotator.mplayer !== 'undefined'); @@ -724,7 +725,7 @@ CatchAnnotation.prototype = { _formatCatch: function(item) { var item = item || {}; - if(this._isVideoJS(item)){ + if (this._isVideoJS(item)) { // format time item.rangeTime.start= typeof vjs !== 'undefined' ? vjs.formatTime(item.rangeTime.start) : @@ -734,10 +735,10 @@ CatchAnnotation.prototype = { item.rangeTime.end; } // format date - if(typeof item.updated !== 'undefined' && typeof createDateFromISO8601 !== 'undefined') + if (typeof item.updated !== 'undefined' && typeof createDateFromISO8601 !== 'undefined') item.updated = createDateFromISO8601(item.updated); // format geolocation - if(typeof item.geolocation !== 'undefined' && (typeof item.geolocation.latitude==='undefined'||item.geolocation.latitude==='')) + if (typeof item.geolocation !== 'undefined' && (typeof item.geolocation.latitude === 'undefined' || item.geolocation.latitude === '')) delete item.geolocation; /* NEW VARIABLES */ @@ -755,11 +756,10 @@ CatchAnnotation.prototype = { }; // Flags - if(!this.options.flags && typeof item.tags !== 'undefined' && item.tags.length > 0){ - for(var len=item.tags.length, index = len-1; index >= 0; --index){ + if (!this.options.flags && typeof item.tags !== 'undefined' && item.tags.length > 0) { + for (var len = item.tags.length, index = len-1; index >= 0; --index) { var currTag = item.tags[index]; - if(currTag.indexOf("flagged-") !== -1){ - + if (currTag.indexOf("flagged-") !== -1) { item.tags.splice(index); } } @@ -789,60 +789,62 @@ CatchAnnotation.prototype = { }, _closeAnnotationItem: function(evt) { var existEvent = typeof evt.target !== 'undefined' && typeof evt.target.localName !== 'undefined'; - if(existEvent && evt.target.parentNode.className !== 'geolocationIcon'){ + if (existEvent && evt.target.parentNode.className !== 'geolocationIcon') { this._openAnnotationItem(evt); } }, _onGeolocationClick: function(evt) { var latitude = $(evt.target).parent().find('.latitude').html(); var longitude = $(evt.target).parent().find('.longitude').html(); - var imgSrc = ''; + var imgSrc = ''; $(evt.target).parents('.detailHeader:first').find('#myLocationMap .map').html(imgSrc); }, _onPlaySelectionClick: function(evt) { var id = $(evt.target).find('.idAnnotation').html(); var uri = $(evt.target).find('.uri').html(); var container = $(evt.target).find('.container').html(); - if(this.options.externalLink){ - uri += (uri.indexOf('?') >= 0)?'&ovaId='+id:'?ovaId='+id; + if (this.options.externalLink) { + uri += (uri.indexOf('?') >= 0) ? '&ovaId=' + id : '?ovaId=' + id; location.href = uri; - }else{ - var isContainer = typeof this.annotator.an !== 'undefined' && typeof this.annotator.an[container] !== 'undefined', - ovaInstance = isContainer? this.annotator.an[container]:null; - if(ovaInstance !== null){ + } else { + var isContainer = typeof this.annotator.an !== 'undefined' && typeof this.annotator.an[container] !== 'undefined'; + var ovaInstance = isContainer ? this.annotator.an[container] : null; + if (ovaInstance !== null) { var allannotations = this.annotator.plugins['Store'].annotations, ovaId = id, player = ovaInstance.player; for (var item in allannotations) { var an = allannotations[item]; - if (typeof an.id !== 'undefined' && an.id === ovaId) { //this is the annotation - if (this._isVideoJS(an)) { //It is a video - if (player.id_ === an.target.container && player.tech.options_.source.src === an.target.src){ + if (typeof an.id !== 'undefined' && an.id === ovaId) { // this is the annotation + if (this._isVideoJS(an)) { // It is a video + if (player.id_ === an.target.container && player.tech.options_.source.src === an.target.src) { var anFound = an; var playFunction = function(){ // Fix problem with youtube videos in the first play. The plugin don't have this trigger - if (player.techName === 'Youtube'){ - var startAPI = function(){ + if (player.techName === 'Youtube') { + var startAPI = function() { + ovaInstance.showAnnotation(anFound); } if (ovaInstance.loaded) startAPI(); else player.one('loadedRangeSlider', startAPI); // show Annotations once the RangeSlider is loaded - }else{ + } else { + ovaInstance.showAnnotation(anFound); } $('html, body').animate({ - scrollTop: $("#"+player.id_).offset().top}, + scrollTop: $("#" + player.id_).offset().top}, 'slow'); }; if (player.paused()) { player.play(); player.one('playing', playFunction); - }else{ + } else { playFunction(); } @@ -862,11 +864,11 @@ CatchAnnotation.prototype = { var allannotations = this.annotator.plugins['Store'].annotations; var osda = this.annotator.osda; - if(this.options.externalLink){ - uri += (uri.indexOf('?') >= 0)?'&osdaId='+osdaId:'?osdaId='+osdaId; + if (this.options.externalLink) { + uri += (uri.indexOf('?') >= 0) ?'&osdaId=' + osdaId : '?osdaId=' + osdaId; location.href = uri; } - for(var item in allannotations){ + for(var item in allannotations) { var an = allannotations[item]; // Makes sure that all images are set to transparent in case one was // previously selected. @@ -883,7 +885,7 @@ CatchAnnotation.prototype = { } } }, - _onQuoteMediaButton: function(evt){ + _onQuoteMediaButton: function(evt) { var quote = $(evt.target).hasClass('quote')?$(evt.target):$(evt.target).parents('.quote:first'); var id = quote.find('.idAnnotation').html(); var uri = quote.find('.uri').html(); @@ -893,22 +895,22 @@ CatchAnnotation.prototype = { id = quote.find('.idAnnotation').html(); // clickPlaySelection(evt); } - if(this.options.externalLink){ + if (this.options.externalLink) { uri += (uri.indexOf('?') >= 0)?'&ovaId='+id:'?ovaId='+id; location.href = uri; - }else{ + } else { var allannotations = this.annotator.plugins['Store'].annotations; var ovaId = id; for (var item in allannotations) { var an = allannotations[item]; - if (typeof an.id !== 'undefined' && an.id === ovaId){ // this is the annotation - if(!this._isVideoJS(an)){ + if (typeof an.id !== 'undefined' && an.id === ovaId) { // this is the annotation + if(!this._isVideoJS(an)) { var hasRanges = typeof an.ranges !== 'undefined' && typeof an.ranges[0] !== 'undefined', startOffset = hasRanges?an.ranges[0].startOffset:'', endOffset = hasRanges?an.ranges[0].endOffset:''; - if(typeof startOffset !== 'undefined' && typeof endOffset !== 'undefined'){ + if (typeof startOffset !== 'undefined' && typeof endOffset !== 'undefined') { $(an.highlights).parent().find('.annotator-hl').removeClass('api'); // change the color @@ -923,7 +925,7 @@ CatchAnnotation.prototype = { } } }, - _refreshReplies: function(evt){ + _refreshReplies: function(evt) { var item = $(evt.target).parents('.annotationItem:first'); var anId = item.attr('annotationId'); @@ -937,7 +939,7 @@ CatchAnnotation.prototype = { parentid:anId, uri:loadFromSearchURI, }; - var onSuccess=function(data){ + var onSuccess=function(data) { if (data === null) data = {}; annotations = data.rows || []; var _i, _len; @@ -949,17 +951,16 @@ CatchAnnotation.prototype = { annotations: annotations })); var replyItems = $('.replies .replyItem'); - if(typeof replyItems !== 'undefined' && replyItems.length > 0){ - annotations.forEach(function(ann){ - replyItems.each(function(item){ + if (typeof replyItems !== 'undefined' && replyItems.length > 0) { + annotations.forEach(function(ann) { + replyItems.each(function(item) { var id = $(replyItems[item]).attr('annotationid'); - if(id === ann.id){ + if (id === ann.id) { var perm = self.annotator.plugins.Permissions; - if(!perm.options.userAuthorize('delete', ann, perm.user)){ + if (!perm.options.userAuthorize('delete', ann, perm.user)) { $(replyItems[item]).find('.deleteReply').remove(); - }else{ + } else { $(replyItems[item]).data('annotation', ann); - } } }); @@ -975,10 +976,10 @@ CatchAnnotation.prototype = { request._id = id; request._action = action; }, - _onControlRepliesClick: function(evt){ + _onControlRepliesClick: function(evt) { var action = $(evt.target)[0].className; - if(action === 'newReply'){ + if (action === 'newReply') { var item = $(evt.target).parents('.annotationItem:first'); var id = item.attr('annotationId'); // Pre-show Adder @@ -1012,12 +1013,12 @@ CatchAnnotation.prototype = { parentValue.html(id); var self = this; - }else if(action === 'hideReplies'){ + } else if (action === 'hideReplies') { var oldAction = $(evt.target).html(); if (oldAction === 'Show Replies'){ $(evt.target).html('Hide Replies'); - }else{ + } else { $(evt.target).html('Show Replies'); var replyElem = $(evt.target).parents('.annotationItem:first').find('.replies'); replyElem.html(''); @@ -1026,8 +1027,8 @@ CatchAnnotation.prototype = { // search this._refreshReplies(evt); - }else if(action === 'deleteAnnotation'){ - if(confirm("Would you like to delete the annotation?")){ + } else if (action === 'deleteAnnotation') { + if (confirm("Would you like to delete the annotation?")) { var annotator = this.annotator; var item = $(evt.target).parents('.annotationItem:first'); var id = item.attr('annotationId'); @@ -1035,15 +1036,15 @@ CatchAnnotation.prototype = { var annotations = store.annotations; var permissions = annotator.plugins.Permissions; var annotation; - annotations.forEach(function(ann){ - if(ann.id === id) + annotations.forEach(function(ann) { + if (ann.id === id) annotation = ann; }); var authorized = permissions.options.userAuthorize('delete', annotation, permissions.user); - if(authorized) + if (authorized) annotator.deleteAnnotation(annotation); } - }else if(action === 'editAnnotation'){ + } else if (action === 'editAnnotation') { var annotator = this.annotator; var item = $(evt.target).parents('.annotationItem:first'); @@ -1052,12 +1053,12 @@ CatchAnnotation.prototype = { var annotations = store.annotations; var permissions = annotator.plugins.Permissions; var annotation; - annotations.forEach(function(ann){ - if(ann.id === id) + annotations.forEach(function(ann) { + if (ann.id === id) annotation = ann; }); var authorized = permissions.options.userAuthorize('update', annotation, permissions.user); - if(authorized){ + if (authorized){ // Get elements var wrapper = $('.annotator-wrapper'); // Calculate Editor position @@ -1087,19 +1088,18 @@ CatchAnnotation.prototype = { }, _onShareControlsClick: function(evt) { var action = $(evt.target)[0].className; - if(action === 'privacy_button'){ + if (action === 'privacy_button') { - }else if(action === 'groups_button'){ + } else if (action === 'groups_button') { alert("Coming soon..."); - }else if(action === 'reply_button'){ + } else if (action === 'reply_button') { var item = $(evt.target).parents('.annotationItem:first'), id = item.attr('annotationId'); // New annotation var an = this.annotator.setupAnnotation(this.annotator.createAnnotation()); an.text="010"; an.parent = id; - }else if(action === 'share_button'){ - + } else if (action === 'share_button') { } }, @@ -1133,7 +1133,7 @@ CatchAnnotation.prototype = { // Change userid and refresh this.changeUserId(userId); }, - _onSelectionButtonClick: function(evt){ + _onSelectionButtonClick: function(evt) { var but = $(evt.target); var action = but.attr('media'); @@ -1144,7 +1144,7 @@ CatchAnnotation.prototype = { // Change media and refresh this.changeMedia(action); }, - _onMoreButtonClick: function(evt){ + _onMoreButtonClick: function(evt) { this.clean = false; var moreBut = this.element.find('.annotationListButtons .moreButtonCatch'); var isLoading = moreBut.html() === 'More'?false:true; @@ -1152,7 +1152,7 @@ CatchAnnotation.prototype = { this.loadAnnotations(); }, - _refresh:function(searchtype, searchInput){ + _refresh:function(searchtype, searchInput) { var searchtype = searchtype || ""; var searchInput = searchInput || ""; this.clean = true; @@ -1170,26 +1170,26 @@ CatchAnnotation.prototype = { loadFromSearch.tag = ""; loadFromSearch.text = ""; - if (searchtype === "Users"){ + if (searchtype === "Users") { loadFromSearch.username = searchInput; - } else if(searchtype === "Tags"){ + } else if(searchtype === "Tags") { loadFromSearch.tag = searchInput; - } else{ + } else { loadFromSearch.text = searchInput; } annotator.plugins['Store'].loadAnnotationsFromSearch(loadFromSearch); }, - _onSearchButtonClick: function(evt){ + _onSearchButtonClick: function(evt) { var searchtype = this.element.find('.searchbox .dropdown-list').val(); var searchInput = this.element.find('.searchbox input').val(); this._refresh(searchtype, searchInput); }, - _onClearSearchButtonClick: function(evt){ + _onClearSearchButtonClick: function(evt) { this._refresh('', ''); }, - _clearAnnotator: function(){ + _clearAnnotator: function() { var annotator = this.annotator; var store = annotator.plugins.Store; var annotations = store.annotations.slice(); @@ -1210,7 +1210,7 @@ CatchAnnotation.prototype = { store.unregisterAnnotation(ann); }); }, - _onDeleteReplyButtonClick : function(evt){ + _onDeleteReplyButtonClick : function(evt) { var annotator = this.annotator; var item = $(evt.target).parents('.replyItem:first'); var id = item.attr('annotationid'); @@ -1223,5 +1223,8 @@ CatchAnnotation.prototype = { item.remove(); } } - } + }, + openLoadingGIF: function() { + $('#mainCatch').append('

Annotations Data Loading... Please Wait.
'); + }, }