src/widgets/AnnotationsList.js
changeset 944 8a6c9e3d0158
parent 855 1be5beb4b196
parent 937 eb3c442cec50
child 957 4da0a5740b6c
equal deleted inserted replaced
907:27b248a13355 944:8a6c9e3d0158
       
     1 IriSP.Widgets.AnnotationsList = function(player, config) {
       
     2     IriSP.Widgets.Widget.call(this, player, config);
       
     3     this.searchString = false;
       
     4     this.lastIds = [];
       
     5     var _this = this;
       
     6     this.throttledRefresh = IriSP._.throttle(function() {
       
     7         _this.refresh(false);
       
     8     }, 1500);
       
     9     this.mashupMode = (this.source.currentMedia.elementType === "mashup");
       
    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 : 300000, 
       
    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 : 10,
       
    30     newest_first : false,
       
    31     polemics : [{
       
    32         keyword: "++",
       
    33         background_color: "#c9ecc6"
       
    34     },{
       
    35         keyword: "--",
       
    36         background_color: "#f9c5c6"
       
    37     },{
       
    38         keyword: "??",
       
    39         background_color: "#cec5f9"
       
    40     },{
       
    41         keyword: "==",
       
    42         background_color: "#f9f4c6"
       
    43     }]
       
    44 };
       
    45 
       
    46 IriSP.Widgets.AnnotationsList.prototype.template =
       
    47     '<div class="Ldt-AnnotationsListWidget">'
       
    48     + '<ul class="Ldt-AnnotationsList-ul">'
       
    49     + '</ul>'
       
    50     + '</div>';
       
    51 
       
    52 IriSP.Widgets.AnnotationsList.prototype.annotationTemplate = 
       
    53     '<li class="Ldt-AnnotationsList-li Ldt-TraceMe" trace-info="annotation-id:{{id}}, media-id:{{media_id}}" style="{{specific_style}}">'
       
    54     + '<div class="Ldt-AnnotationsList-ThumbContainer">'
       
    55     + '<a href="{{url}}">'
       
    56     + '<img class="Ldt-AnnotationsList-Thumbnail" src="{{thumbnail}}" />'
       
    57     + '</a>'
       
    58     + '</div>'
       
    59     + '<div class="Ldt-AnnotationsList-Duration">{{begin}} - {{end}}</div>'
       
    60     + '<h3 class="Ldt-AnnotationsList-Title">'
       
    61     + '<a href="{{url}}">{{title}}</a>'
       
    62     + '</h3>'
       
    63     + '<p class="Ldt-AnnotationsList-Description">{{description}}</p>'
       
    64     + '{{#tags.length}}'
       
    65     + '<ul class="Ldt-AnnotationsList-Tags">'
       
    66     + '{{#tags}}'
       
    67     + '{{#.}}'
       
    68     + '<li class="Ldt-AnnotationsList-Tag-Li">'
       
    69     + '<span>{{.}}</span>'
       
    70     + '</li>'
       
    71     + '{{/.}}'
       
    72     + '{{/tags}}'
       
    73     + '</ul>'
       
    74     + '{{/tags.length}}'
       
    75     + '</li>';
       
    76 
       
    77 IriSP.Widgets.AnnotationsList.prototype.onSearch = function(searchString) {
       
    78     this.searchString = typeof searchString !== "undefined" ? searchString : '';
       
    79     var _n = this.refresh(true);
       
    80     if (this.searchString) {
       
    81         if (_n) {
       
    82             this.player.popcorn.trigger("IriSP.search.matchFound");
       
    83         } else {
       
    84             this.player.popcorn.trigger("IriSP.search.noMatchFound");
       
    85         }
       
    86     }
       
    87 }
       
    88 
       
    89 //obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id;
       
    90 
       
    91 IriSP.Widgets.AnnotationsList.prototype.ajaxSource = function() {
       
    92     var _currentTime = this.player.popcorn.currentTime(),
       
    93         _duration = this.source.getDuration();
       
    94     if (typeof _currentTime == "undefined") {
       
    95         _currentTime = 0;
       
    96     }
       
    97     this.lastAjaxQuery = _currentTime;
       
    98     _currentTime = Math.floor(1000 * _currentTime);
       
    99     var _url = Mustache.to_html(this.ajax_url, {
       
   100         media : this.source.currentMedia.id,
       
   101         begin : Math.max(0, _currentTime - this.ajax_granularity),
       
   102         end : Math.min(_duration.milliseconds, _currentTime + this.ajax_granularity)
       
   103     });
       
   104     this.currentSource = this.player.loadMetadata(IriSP._.defaults({
       
   105         "url" : _url
       
   106     }, this.metadata));
       
   107 }
       
   108 
       
   109 IriSP.Widgets.AnnotationsList.prototype.ajaxMashup = function() {
       
   110     var _currentTime = this.player.popcorn.currentTime();
       
   111     if (typeof _currentTime == "undefined") {
       
   112         _currentTime = 0;
       
   113     }
       
   114     var _currentAnnotation = this.source.currentMedia.getAnnotationAtTime(_currentTime * 1000);
       
   115     if (typeof _currentAnnotation !== "undefined" && _currentAnnotation.id !== this.lastMashupAnnotation) {
       
   116         this.lastMashupAnnotation = _currentAnnotation.id;
       
   117         var _currentMedia = _currentAnnotation.getMedia(),
       
   118             _url = Mustache.to_html(this.ajax_url, {
       
   119                 media : _currentMedia.id,
       
   120                 begin : Math.max(0, _currentAnnotation.annotation.begin.milliseconds - this.ajax_granularity),
       
   121                 end : Math.min(_currentMedia.duration.milliseconds, _currentAnnotation.annotation.end.milliseconds + this.ajax_granularity)
       
   122             });
       
   123         this.currentSource = this.player.loadMetadata(IriSP._.defaults({
       
   124             "url" : _url
       
   125         }, this.metadata));
       
   126     }
       
   127 }
       
   128 
       
   129 IriSP.Widgets.AnnotationsList.prototype.refresh = function(_forceRedraw) {
       
   130     _forceRedraw = (typeof _forceRedraw !== "undefined" && _forceRedraw);
       
   131     if (this.currentSource.status !== IriSP.Model._SOURCE_STATUS_READY) {
       
   132         return 0;
       
   133     }
       
   134     var _this = this,
       
   135         _currentTime = this.player.popcorn.currentTime();
       
   136     if (typeof _currentTime == "undefined") {
       
   137         _currentTime = 0;
       
   138     }
       
   139     var _list = this.annotation_type ? this.currentSource.getAnnotationsByTypeTitle(this.annotation_type) : this.currentSource.getAnnotations();
       
   140     if (this.mashupMode) {
       
   141         var _currentAnnotation = this.source.currentMedia.getAnnotationAtTime(_currentTime * 1000);
       
   142         if (typeof _currentAnnotation !== "undefined") {
       
   143             _currentTime = _currentTime - _currentAnnotation.begin.getSeconds() + _currentAnnotation.annotation.begin.getSeconds();
       
   144             var _mediaId = _currentAnnotation.getMedia().id;
       
   145             _list = _list.filter(function(_annotation) {
       
   146                 return _annotation.getMedia().id === _mediaId;
       
   147             });
       
   148         }
       
   149     }
       
   150     if (this.searchString) {
       
   151         _list = _list.searchByTextFields(this.searchString);
       
   152     }
       
   153     if (this.limit_count) {
       
   154         _list = _list.sortBy(function(_annotation) {
       
   155             return Math.abs(_annotation.begin.getSeconds() - _currentTime);
       
   156         }).slice(0, this.limit_count)
       
   157     }
       
   158     if (this.newest_first) {
       
   159         _list = _list.sortBy(function(_annotation) {
       
   160             return -_annotation.created.valueOf();
       
   161         });
       
   162     } else {
       
   163         _list = _list.sortBy(function(_annotation) {
       
   164             return _annotation.begin;
       
   165         });
       
   166     }
       
   167     
       
   168     var _ids = _list.idIndex;
       
   169     
       
   170     if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds)) {
       
   171         /* This part only gets executed if the list needs updating */
       
   172         this.lastIds = _ids;
       
   173         this.list_$.html("");
       
   174         _list.forEach(function(_annotation) {
       
   175             var _url = (
       
   176                 ( typeof _annotation.url !== "undefined" && _annotation.url)
       
   177                 ? _annotation.url
       
   178                 : (
       
   179                     ( typeof _this.source.projectId !== "undefined" && typeof _annotation.project !== "undefined" && _annotation.project && _this.source.projectId !== _annotation.project )
       
   180                     ? Mustache.to_html(
       
   181                         _this.foreign_url,
       
   182                         {
       
   183                             project : _annotation.project,
       
   184                             media : _annotation.media.id,
       
   185                             annotation : _annotation.id,
       
   186                             annotationType : _annotation.annotationType.id
       
   187                         }
       
   188                     )
       
   189                     : '#id=' + _annotation.id
       
   190                     )
       
   191             );
       
   192             var _title = (_annotation.title || "").replace(_annotation.description,''),
       
   193                 _description = _annotation.description;
       
   194             if (!_annotation.title) {
       
   195                 _title = _annotation.creator;
       
   196             }
       
   197             if (!_annotation.description && _annotation.creator) {
       
   198                 _description = _annotation.title;
       
   199                 _title = _annotation.creator;
       
   200             }
       
   201             var _bgcolor;
       
   202             IriSP._(_this.polemics).each(function(_polemic) {
       
   203                 var _rgxp = IriSP.Model.regexpFromTextOrArray(_polemic.keyword, true);
       
   204                 if (_rgxp.test(_title + " " + _description)) {
       
   205                     _bgcolor = _polemic.background_color;
       
   206                 }
       
   207             });
       
   208             var _data = {
       
   209                 id : _annotation.id,
       
   210                 media_id : _annotation.getMedia().id,
       
   211                 title : _title,
       
   212                 description : _description,
       
   213                 begin : _annotation.begin.toString(),
       
   214                 end : _annotation.end.toString(),
       
   215                 thumbnail : typeof _annotation.thumbnail !== "undefined" && _annotation.thumbnail ? _annotation.thumbnail : _this.default_thumbnail,
       
   216                 url : _url,
       
   217                 tags : _annotation.getTagTexts(),
       
   218                 specific_style : (typeof _bgcolor !== "undefined" ? "background-color: " + _bgcolor : "")
       
   219             };
       
   220             var _html = Mustache.to_html(_this.annotationTemplate, _data);
       
   221             var _el = IriSP.jQuery(_html);
       
   222             _el.mouseover(function() {
       
   223                     _annotation.trigger("select");
       
   224                 })
       
   225                 .mouseout(function() {
       
   226                     _annotation.trigger("unselect");
       
   227                 })
       
   228                 .appendTo(_this.list_$);
       
   229             _annotation.on("select", function() {
       
   230                 _this.annotations_$.removeClass("selected");
       
   231                 _el.addClass("selected");
       
   232             });
       
   233             _annotation.on("unselect", function() {
       
   234                 _this.annotations_$.removeClass("selected");
       
   235             });;
       
   236         });
       
   237         
       
   238         this.annotations_$ = this.$.find('.Ldt-AnnotationsList-li');
       
   239         
       
   240         /* Correct the empty tag bug */
       
   241         this.$.find('.Ldt-AnnotationsList-Tag-Li').each(function() {
       
   242             var _el = IriSP.jQuery(this);
       
   243             if (!_el.text().replace(/(^\s+|\s+$)/g,'')) {
       
   244                 _el.detach();
       
   245             }
       
   246         });
       
   247     
       
   248         this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() {
       
   249             _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,''));
       
   250         })
       
   251         
       
   252         if(this.searchString) {
       
   253             var _searchRe = IriSP.Model.regexpFromTextOrArray(this.searchString);
       
   254             this.$.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() {
       
   255                 var _$ = IriSP.jQuery(this);
       
   256                 _$.html(_$.text().replace(/(^\s+|\s+$)/g,'').replace(_searchRe, '<span class="Ldt-AnnotationsList-highlight">$1</span>'))
       
   257             })
       
   258         }
       
   259     }
       
   260     
       
   261     if (this.ajax_url) {
       
   262         if (this.mashupMode) {
       
   263             this.ajaxMashup();
       
   264         } else {
       
   265             if (Math.abs(_currentTime - this.lastAjaxQuery) > (this.ajax_granularity / 2000)) {
       
   266                 this.ajaxSource();
       
   267             }
       
   268         }
       
   269     }
       
   270     return _list.length;
       
   271 }
       
   272 
       
   273 IriSP.Widgets.AnnotationsList.prototype.draw = function() {
       
   274     
       
   275     this.renderTemplate();
       
   276     
       
   277     this.list_$ = this.$.find(".Ldt-AnnotationsList-ul");
       
   278     
       
   279     this.bindPopcorn("IriSP.search", "onSearch");
       
   280     this.bindPopcorn("IriSP.search.closed", "onSearch");
       
   281     this.bindPopcorn("IriSP.search.cleared", "onSearch");
       
   282     this.bindPopcorn("IriSP.AnnotationsList.refresh","refresh");
       
   283     
       
   284     var _this = this;
       
   285     
       
   286     if (this.ajax_url) {
       
   287         if (this.mashupMode) {
       
   288             this.ajaxMashup();
       
   289         } else {
       
   290             this.ajaxSource();
       
   291         }
       
   292     } else {
       
   293         this.currentSource = this.source;
       
   294     }
       
   295     
       
   296     if (this.refresh_interval) {
       
   297         window.setInterval(function() {
       
   298             _this.currentSource.get()
       
   299         }, this.refresh_interval);
       
   300     }
       
   301     
       
   302     var _events = [
       
   303         "IriSP.createAnnotationWidget.addedAnnotation",
       
   304         "timeupdate",
       
   305         "seeked",
       
   306         "loadedmetadata"
       
   307     ];
       
   308     for (var _i = 0; _i < _events.length; _i++) {
       
   309         this.player.popcorn.listen(_events[_i], this.throttledRefresh);
       
   310     }
       
   311     
       
   312     this.throttledRefresh();
       
   313 
       
   314 };