web/lib/metadataplayer/AnnotationsList.js
changeset 0 7f8907368bd5
equal deleted inserted replaced
-1:000000000000 0:7f8907368bd5
       
     1 IriSP.Widgets.AnnotationsList = function(player, config) {
       
     2     IriSP.Widgets.Widget.call(this, player, config);
       
     3     this.lastIds = [];
       
     4     var _this = this;
       
     5     this.throttledRefresh = IriSP._.throttle(function() {
       
     6         _this.refresh(false);
       
     7     }, 800);
       
     8     this.searchString = false;
       
     9     this.lastSearch = false;
       
    10 };
       
    11 
       
    12 IriSP.Widgets.AnnotationsList.prototype = new IriSP.Widgets.Widget();
       
    13 
       
    14 IriSP.Widgets.AnnotationsList.prototype.defaults = {
       
    15     /* URL when the annotations are to be reloaded from an LDT-like segment API
       
    16      * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=?
       
    17      */
       
    18     ajax_url : false,
       
    19     /* number of milliseconds before/after the current timecode when calling the segment API
       
    20      */
       
    21     ajax_granularity : 600000, 
       
    22     default_thumbnail : "",
       
    23     /* URL when the annotation is not in the current project,
       
    24      * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}}
       
    25      */
       
    26     foreign_url : "",
       
    27     annotation_type : false,
       
    28     refresh_interval : 0,
       
    29     limit_count : 20,
       
    30     newest_first : false,
       
    31     show_audio: true,
       
    32     polemics : [{
       
    33         keyword: "++",
       
    34         background_color: "#c9ecc6"
       
    35     },{
       
    36         keyword: "--",
       
    37         background_color: "#f9c5c6"
       
    38     },{
       
    39         keyword: "??",
       
    40         background_color: "#cec5f9"
       
    41     },{
       
    42         keyword: "==",
       
    43         background_color: "#f9f4c6"
       
    44     }]
       
    45 };
       
    46 
       
    47 IriSP.Widgets.AnnotationsList.prototype.messages = {
       
    48     en: {
       
    49         voice_annotation: "Voice Annotation",
       
    50         now_playing: "Now playing..."
       
    51     },
       
    52     fr: {
       
    53         voice_annotation: "Annotation Vocale",
       
    54         now_playing: "Lecture en cours..."
       
    55     }
       
    56 };
       
    57 
       
    58 IriSP.Widgets.AnnotationsList.prototype.template =
       
    59     '<div class="Ldt-AnnotationsListWidget">'
       
    60     + '{{#show_audio}}<div class="Ldt-AnnotationsList-Audio"></div>{{/show_audio}}'
       
    61     + '<ul class="Ldt-AnnotationsList-ul">'
       
    62     + '</ul>'
       
    63     + '</div>';
       
    64 
       
    65 IriSP.Widgets.AnnotationsList.prototype.annotationTemplate = 
       
    66     '<li class="Ldt-AnnotationsList-li Ldt-TraceMe" trace-info="annotation-id:{{id}}, media-id:{{media_id}}" style="{{specific_style}}">'
       
    67     + '<div class="Ldt-AnnotationsList-ThumbContainer">'
       
    68     + '<a href="{{url}}" draggable="true">'
       
    69     + '<img class="Ldt-AnnotationsList-Thumbnail" src="{{thumbnail}}" />'
       
    70     + '</a>'
       
    71     + '</div>'
       
    72     + '<div class="Ldt-AnnotationsList-Duration">{{begin}} - {{end}}</div>'
       
    73     + '<h3 class="Ldt-AnnotationsList-Title" draggable="true">'
       
    74     + '<a href="{{url}}">{{{htitle}}}</a>'
       
    75     + '</h3>'
       
    76     + '<p class="Ldt-AnnotationsList-Description">{{{hdescription}}}</p>'
       
    77     + '{{#tags.length}}'
       
    78     + '<ul class="Ldt-AnnotationsList-Tags">'
       
    79     + '{{#tags}}'
       
    80     + '{{#.}}'
       
    81     + '<li class="Ldt-AnnotationsList-Tag-Li">'
       
    82     + '<span>{{.}}</span>'
       
    83     + '</li>'
       
    84     + '{{/.}}'
       
    85     + '{{/tags}}'
       
    86     + '</ul>'
       
    87     + '{{/tags.length}}'
       
    88     + '{{#audio}}<div class="Ldt-AnnotationsList-Play" data-annotation-id="{{id}}">{{l10n.voice_annotation}}</div>{{/audio}}'
       
    89     + '</li>';
       
    90 
       
    91 //obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id;
       
    92 
       
    93 IriSP.Widgets.AnnotationsList.prototype.ajaxSource = function() {
       
    94     var _currentTime = this.media.getCurrentTime(),
       
    95         _duration = this.media.duration;
       
    96     this.lastAjaxQuery = _currentTime;
       
    97     var _url = Mustache.to_html(this.ajax_url, {
       
    98         media : this.source.currentMedia.id,
       
    99         begin : Math.max(0, _currentTime - this.ajax_granularity),
       
   100         end : Math.min(_duration.milliseconds, _currentTime + this.ajax_granularity)
       
   101     });
       
   102     this.currentSource = this.player.loadMetadata(IriSP._.defaults({
       
   103         "url" : _url
       
   104     }, this.metadata));
       
   105 };
       
   106 
       
   107 IriSP.Widgets.AnnotationsList.prototype.ajaxMashup = function() {
       
   108     var _currentTime = this.media.getCurrentTime();
       
   109     var _currentAnnotation = this.source.currentMedia.getAnnotationAtTime(_currentTime);
       
   110     if (typeof _currentAnnotation !== "undefined" && _currentAnnotation.id !== this.lastMashupAnnotation) {
       
   111         this.lastMashupAnnotation = _currentAnnotation.id;
       
   112         var _currentMedia = _currentAnnotation.getMedia(),
       
   113             _url = Mustache.to_html(this.ajax_url, {
       
   114                 media : _currentMedia.id,
       
   115                 begin : Math.max(0, _currentAnnotation.annotation.begin.milliseconds - this.ajax_granularity),
       
   116                 end : Math.min(_currentMedia.duration.milliseconds, _currentAnnotation.annotation.end.milliseconds + this.ajax_granularity)
       
   117             });
       
   118         this.currentSource = this.player.loadMetadata(IriSP._.defaults({
       
   119             "url" : _url
       
   120         }, this.metadata));
       
   121     }
       
   122 };
       
   123 
       
   124 IriSP.Widgets.AnnotationsList.prototype.refresh = function(_forceRedraw) {
       
   125     _forceRedraw = (typeof _forceRedraw !== "undefined" && _forceRedraw);
       
   126     if (this.currentSource.status !== IriSP.Model._SOURCE_STATUS_READY) {
       
   127         return 0;
       
   128     }
       
   129     var _this = this,
       
   130         _currentTime = this.media.getCurrentTime();
       
   131     var _list = this.annotation_type ? this.currentSource.getAnnotationsByTypeTitle(this.annotation_type) : this.currentSource.getAnnotations();
       
   132     if (this.mashupMode) {
       
   133         var _currentAnnotation = this.source.currentMedia.getAnnotationAtTime(_currentTime);
       
   134         if (typeof _currentAnnotation !== "undefined") {
       
   135             _currentTime = _currentTime - _currentAnnotation.begin + _currentAnnotation.annotation.begin;
       
   136             var _mediaId = _currentAnnotation.getMedia().id;
       
   137             _list = _list.filter(function(_annotation) {
       
   138                 return _annotation.getMedia().id === _mediaId;
       
   139             });
       
   140         }
       
   141     }
       
   142     _list = _list.filter(function(_annotation) {
       
   143         return _annotation.found !== false;
       
   144     });
       
   145     if (this.limit_count) {
       
   146         /* Get the n annotations closest to current timecode */
       
   147         _list = _list.sortBy(function(_annotation) {
       
   148             return Math.abs((_annotation.begin + _annotation.end) / 2 - _currentTime);
       
   149         }).slice(0, this.limit_count);
       
   150     }
       
   151     if (this.newest_first) {
       
   152         _list = _list.sortBy(function(_annotation) {
       
   153             return -_annotation.created.valueOf();
       
   154         });
       
   155     } else {
       
   156         _list = _list.sortBy(function(_annotation) {
       
   157             return _annotation.begin;
       
   158         });
       
   159     }
       
   160     
       
   161     var _ids = _list.idIndex;
       
   162     
       
   163     if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds) || this.searchString !== this.lastSearch) {
       
   164         /* This part only gets executed if the list needs updating */
       
   165         this.lastSearch = this.searchString;
       
   166         this.lastIds = _ids;
       
   167         this.list_$.html("");
       
   168         _list.forEach(function(_annotation) {
       
   169             var _url = (
       
   170                 ( typeof _annotation.url !== "undefined" && _annotation.url)
       
   171                 ? _annotation.url
       
   172                 : (
       
   173                     ( typeof _this.source.projectId !== "undefined" && typeof _annotation.project !== "undefined" && _annotation.project && _this.source.projectId !== _annotation.project )
       
   174                     ? Mustache.to_html(
       
   175                         _this.foreign_url,
       
   176                         {
       
   177                             project : _annotation.project,
       
   178                             media : _annotation.media.id,
       
   179                             annotation : _annotation.id,
       
   180                             annotationType : _annotation.annotationType.id
       
   181                         }
       
   182                     )
       
   183                     : document.location.href.replace(/#.*$/,'') + '#id=' + _annotation.id
       
   184                     )
       
   185             );
       
   186             var _title = (_annotation.title || "").replace(_annotation.description,''),
       
   187                 _description = _annotation.description,
       
   188                 _thumbnail = (typeof _annotation.thumbnail !== "undefined" && _annotation.thumbnail ? _annotation.thumbnail : _this.default_thumbnail);
       
   189             if (!_annotation.title) {
       
   190                 _title = _annotation.creator;
       
   191             }
       
   192             if (!_annotation.description && _annotation.creator) {
       
   193                 _description = _annotation.title;
       
   194                 _title = _annotation.creator;
       
   195             }
       
   196             var _bgcolor;
       
   197             IriSP._(_this.polemics).each(function(_polemic) {
       
   198                 var _rgxp = IriSP.Model.regexpFromTextOrArray(_polemic.keyword, true);
       
   199                 if (_rgxp.test(_title + " " + _description)) {
       
   200                     _bgcolor = _polemic.background_color;
       
   201                 }
       
   202             });
       
   203             var _data = {
       
   204                 id : _annotation.id,
       
   205                 media_id : _annotation.getMedia().id,
       
   206                 htitle : IriSP.textFieldHtml(_title),
       
   207                 hdescription : IriSP.textFieldHtml(_description),
       
   208                 begin : _annotation.begin.toString(),
       
   209                 end : _annotation.end.toString(),
       
   210                 thumbnail : _thumbnail,
       
   211                 url : _url,
       
   212                 tags : _annotation.getTagTexts(),
       
   213                 specific_style : (typeof _bgcolor !== "undefined" ? "background-color: " + _bgcolor : ""),
       
   214                 l10n: _this.l10n
       
   215             };
       
   216             if (_this.show_audio && _annotation.audio && _annotation.audio.href && _annotation.audio.href != "null") {
       
   217                 _data.audio = true;
       
   218                 if (!_this.jwplayers[_annotation.id]) {
       
   219                     var _audiofile = _annotation.audio.href;
       
   220                     if (_this.audio_url_transform) {
       
   221                         _audiofile = _this.audio_url_transform(_annotation.audio.href);
       
   222                     }
       
   223                     var _tmpId = "jwplayer-" + IriSP.Model.getUID();
       
   224                     _this.jwplayers[_annotation.id] = _tmpId;
       
   225                     _this.$.find(".Ldt-AnnotationsList-Audio").append(IriSP.jQuery("<div>").attr("id", _tmpId));
       
   226                     jwplayer(_tmpId).setup({
       
   227                         flashplayer: IriSP.getLib("jwPlayerSWF"),
       
   228                         file: _audiofile,
       
   229                         fallback: false,
       
   230                         primary: "flash",
       
   231                         controls: false,
       
   232                         width: 1,
       
   233                         height: 1,
       
   234                         events: {
       
   235                             onPause: function() {
       
   236                                 _this.$.find(".Ldt-AnnotationsList-Play[data-annotation-id=" + _annotation.id + "]").text(_this.l10n.voice_annotation);
       
   237                             },
       
   238                             onPlay: function() {
       
   239                                 _this.$.find(".Ldt-AnnotationsList-Play[data-annotation-id=" + _annotation.id + "]").text(_this.l10n.now_playing);
       
   240                             }
       
   241                         }
       
   242                     });
       
   243                 }
       
   244             }
       
   245             var _html = Mustache.to_html(_this.annotationTemplate, _data),
       
   246                 _el = IriSP.jQuery(_html),
       
   247                 _onselect = function() {
       
   248                     _this.$.find('.Ldt-AnnotationsList-li').removeClass("selected");
       
   249                     _el.addClass("selected");
       
   250                 },
       
   251                 _onunselect = function() {
       
   252                     _this.$.find('.Ldt-AnnotationsList-li').removeClass("selected");
       
   253                 };
       
   254             _el.mouseover(function() {
       
   255                     _annotation.trigger("select");
       
   256                 })
       
   257                 .mouseout(function() {
       
   258                     _annotation.trigger("unselect");
       
   259                 })
       
   260                 .appendTo(_this.list_$);
       
   261             IriSP.attachDndData(_el.find("[draggable]"), {
       
   262             	title: _title,
       
   263             	description: _description,
       
   264             	uri: _url,
       
   265             	image: _annotation.thumbnail
       
   266             });
       
   267             _el.on("remove", function() {
       
   268                 _annotation.off("select", _onselect);
       
   269                 _annotation.off("unselect", _onunselect);
       
   270             });
       
   271             _annotation.on("select", _onselect);
       
   272             _annotation.on("unselect", _onunselect);
       
   273         });
       
   274         
       
   275         /* Correct the empty tag bug */
       
   276         this.$.find('.Ldt-AnnotationsList-Tag-Li').each(function() {
       
   277             var _el = IriSP.jQuery(this);
       
   278             if (!_el.text().replace(/(^\s+|\s+$)/g,'')) {
       
   279                 _el.remove();
       
   280             }
       
   281         });
       
   282     
       
   283         this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() {
       
   284             _this.source.getAnnotations().search(IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,''));
       
   285         });
       
   286         
       
   287         this.$.find(".Ldt-AnnotationsList-Play").click(function() {
       
   288             var _el = IriSP.jQuery(this),
       
   289                 _annid = _el.attr("data-annotation-id");
       
   290             if (_this.jwplayers[_annid]) {
       
   291                 jwplayer(_this.jwplayers[_annid]).play();
       
   292             }
       
   293             _this.media.pause();
       
   294         });
       
   295         
       
   296         if (this.source.getAnnotations().searching) {
       
   297             var rx = _this.source.getAnnotations().regexp || false;
       
   298             this.$.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() {
       
   299                 var _$ = IriSP.jQuery(this);
       
   300                 _$.html(IriSP.textFieldHtml(_$.text(), rx));
       
   301             });
       
   302         }
       
   303     }
       
   304     
       
   305     if (this.ajax_url) {
       
   306         if (this.mashupMode) {
       
   307             this.ajaxMashup();
       
   308         } else {
       
   309             if (Math.abs(_currentTime - this.lastAjaxQuery) > (this.ajax_granularity)) {
       
   310                 this.ajaxSource();
       
   311             }
       
   312         }
       
   313     }
       
   314     return _list.length;
       
   315 };
       
   316 
       
   317 IriSP.Widgets.AnnotationsList.prototype.draw = function() {
       
   318     
       
   319     this.jwplayers = {};
       
   320     this.mashupMode = (this.media.elementType === "mashup");
       
   321     
       
   322     this.renderTemplate();
       
   323     
       
   324     var _this = this;
       
   325         
       
   326     this.list_$ = this.$.find(".Ldt-AnnotationsList-ul");
       
   327     
       
   328     
       
   329     this.source.getAnnotations().on("search", function(_text) {
       
   330         _this.searchString = _text;
       
   331         if (_this.source !== _this.currentSource) {
       
   332             _this.currentSource.getAnnotations().search(_text);
       
   333             _this.throttledRefresh();
       
   334         }
       
   335     });
       
   336     this.source.getAnnotations().on("found", function() {
       
   337         _this.throttledRefresh();
       
   338     });
       
   339     this.source.getAnnotations().on("not-found", function() {
       
   340         _this.throttledRefresh();
       
   341     });
       
   342     this.source.getAnnotations().on("clear-search", function() {
       
   343         _this.searchString = false;
       
   344         if (_this.source !== _this.currentSource) {
       
   345             _this.currentSource.getAnnotations().trigger("clear-search");
       
   346         }
       
   347     });
       
   348     this.source.getAnnotations().on("search-cleared", function() {
       
   349         _this.throttledRefresh();
       
   350     });
       
   351     
       
   352     this.onMdpEvent("AnnotationsList.refresh", function() {
       
   353         if (_this.ajax_url) {
       
   354             if (_this.mashupMode) {
       
   355                 _this.ajaxMashup();
       
   356             } else {
       
   357                 _this.ajaxSource();
       
   358             }
       
   359         }
       
   360         _this.throttledRefresh();
       
   361     });
       
   362     
       
   363     if (this.ajax_url) {
       
   364         if (this.mashupMode) {
       
   365             this.ajaxMashup();
       
   366         } else {
       
   367             this.ajaxSource();
       
   368         }
       
   369     } else {
       
   370         this.currentSource = this.source;
       
   371     }
       
   372     
       
   373     if (this.refresh_interval) {
       
   374         window.setInterval(function() {
       
   375             _this.currentSource.get();
       
   376         }, this.refresh_interval);
       
   377     }
       
   378     
       
   379     this.onMdpEvent("createAnnotationWidget.addedAnnotation");
       
   380     var _events = [
       
   381         "timeupdate",
       
   382         "seeked",
       
   383         "loadedmetadata"
       
   384     ];
       
   385     for (var _i = 0; _i < _events.length; _i++) {
       
   386         this.onMediaEvent(_events[_i], this.throttledRefresh);
       
   387     }
       
   388     
       
   389     this.throttledRefresh();
       
   390 
       
   391 };