src/js/widgets/createAnnotationWidget.js
branchpopcorn-port
changeset 830 18ca612e9ff0
parent 820 7968346b9689
child 831 0dd21c298380
equal deleted inserted replaced
829:ae16691d183d 830:18ca612e9ff0
     1 IriSP.createAnnotationWidget = function(Popcorn, config, Serializer) {
     1 IriSP.createAnnotationWidget = function(Popcorn, config, Serializer) {
     2   IriSP.Widget.call(this, Popcorn, config, Serializer);
     2   IriSP.Widget.call(this, Popcorn, config, Serializer);
     3   this._hidden = true;
     3   this._hidden = true;
     4   this.keywords = IriSP.widgetsDefaults["createAnnotationWidget"].keywords;
     4   
     5   
     5   this.checkOption("keywords");
     6   this.polemic_mode = IriSP.widgetsDefaults["createAnnotationWidget"].polemic_mode;
     6   this.checkOption("polemic_mode", true);
     7   this.polemics = IriSP.widgetsDefaults["createAnnotationWidget"].polemics;
     7   this.checkOption("polemics");
     8   
     8   this.checkOption("cinecast_version", false);
     9   this.cinecast_version = IriSP.widgetsDefaults["createAnnotationWidget"].cinecast_version;
     9   this.checkOption("api_endpoint_template");
    10   this.api_endpoint_template = IriSP.widgetsDefaults["createAnnotationWidget"].api_endpoint_template;
    10   this.checkOption("show_from_field", true);
    11   
    11   this.checkOption("api_method");
    12   this.ids = {}; /* a dictionnary linking buttons ids to keywords */
    12                          
       
    13   if (!IriSP.null_or_undefined(IriSP.user)) {
       
    14       if (!IriSP.null_or_undefined(IriSP.user.avatar)) {
       
    15         this.user_avatar = IriSP.user.avatar;
       
    16       }
       
    17       if (!IriSP.null_or_undefined(IriSP.user.name)) {
       
    18         this.user_name = IriSP.user.name;
       
    19       }
       
    20   }
    13   
    21   
    14   /* variables to save the current position of the slicer */
    22   /* variables to save the current position of the slicer */
    15   if (this.cinecast_version) {
    23   if (this.cinecast_version) {
    16     this.sliceLeft = 0;
    24     this.sliceLeft = 0;
    17     this.sliceWidth = 0;
    25     this.sliceWidth = 0;
    27     this.selector.find(".Ldt-SaKeywordText").text("");
    35     this.selector.find(".Ldt-SaKeywordText").text("");
    28 };
    36 };
    29 
    37 
    30 IriSP.createAnnotationWidget.prototype.draw = function() {
    38 IriSP.createAnnotationWidget.prototype.draw = function() {
    31   var _this = this;
    39   var _this = this;
    32   var template_params = {cinecast_version: this.cinecast_version, 
       
    33                          polemic_mode: this.polemic_mode};
       
    34                          
       
    35   if (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.avatar))
       
    36     template_params["user_avatar"] = IriSP.user.avatar;
       
    37   
    40   
    38   var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_template, 
    41   var annotationMarkup = IriSP.templToHTML(IriSP.createAnnotationWidget_template, 
    39                                            template_params);
    42                                            this);
    40   
    43   
    41 	this.selector.append(annotationMarkup);
    44 	this.selector.append(annotationMarkup);
    42   
    45   
    43   if (!this.cinecast_version)
    46   if (!this.cinecast_version)
    44     this.selector.hide();
    47     this.selector.hide();
    45   else {
    48   else {
    46     this.showStartScreen();
    49     this.showStartScreen();
    47   }
    50   }
    48   
    51 
    49   // add the keywords.
    52   // Add onclick event to both polemic and keywords buttons
    50   for (var i = 0; i < this.keywords.length; i++) {
    53   
    51     var keyword = this.keywords[i];
    54   this.selector.find(".Ldt-createAnnotation-keywords button, .Ldt-createAnnotation-polemics button").click(function() {
    52     var id = IriSP.guid("button_");
    55       _this.addKeyword(IriSP.jQuery(this).text());
    53     var templ = IriSP.templToHTML("<button id={{id}} class='Ldt-createAnnotation-absent-keyword'>{{keyword}}</button>", 
    56   });
    54                                   {keyword: keyword, id: id});
       
    55                                   
       
    56     this.ids[keyword] = id; // save it for the function that handle textarea changes.
       
    57     
       
    58     this.selector.find(".Ldt-createAnnotation-keywords").append(templ);
       
    59     this.selector.find("#" + id).click(function(keyword) { return function() {
       
    60       var contents = _this.selector.find(".Ldt-createAnnotation-Description").val();
       
    61       if (contents.indexOf(keyword) != -1) {
       
    62         var newVal = contents.replace(" " + keyword, "");
       
    63         if (newVal == contents)
       
    64           newVal = contents.replace(keyword, "");
       
    65       } else {
       
    66         if (contents === "")
       
    67           var newVal = keyword;
       
    68         else
       
    69           var newVal = contents + " " + keyword;      
       
    70       }
       
    71       
       
    72       _this.selector.find(".Ldt-createAnnotation-Description").val(newVal);
       
    73       // we use a custom event because there's no simple way to test for a js
       
    74       // change in a textfield.
       
    75       _this.selector.find(".Ldt-createAnnotation-Description").trigger("js_mod");
       
    76       // also call our update function.
       
    77       //_this.handleTextChanges();
       
    78     }
       
    79    }(keyword));
       
    80   }
       
    81 
       
    82   // add the polemic buttons.
       
    83   if(this.polemic_mode)
       
    84     for (var polemic in this.polemics) {
       
    85 
       
    86       var classname = IriSP.templToHTML("Ldt-createAnnotation-polemic-{{classname}}", {classname : this.polemics[polemic]});
       
    87 
       
    88       var templ = IriSP.templToHTML("<button class='{{classname}} Ldt-createAnnotation-polemic-button'>{{polemic}}</button>",
       
    89                   {classname: classname, polemic: polemic});
       
    90                   
       
    91       this.selector.find(".Ldt-createAnnotation-polemics").append(templ);
       
    92       this.selector.find("." + classname).click(function(polemic) { return function() {
       
    93           var contents = _this.selector.find(".Ldt-createAnnotation-Description").val();
       
    94           if (contents.indexOf(polemic) != -1) {
       
    95             var newVal = contents.replace(" " + polemic, "");
       
    96             if (newVal == contents)
       
    97               newVal = contents.replace(polemic, "");
       
    98           } else {
       
    99             if (contents === "")
       
   100               var newVal = polemic;
       
   101             else
       
   102               var newVal = contents + " " + polemic;      
       
   103           }
       
   104           
       
   105           _this.selector.find(".Ldt-createAnnotation-Description").val(newVal);
       
   106           
       
   107           // also call our update function.
       
   108           _this.handleTextChanges();
       
   109         }
       
   110        }(polemic));
       
   111       }    
       
   112   
    57   
   113   // js_mod is a custom event because there's no simple way to test for a js
    58   // js_mod is a custom event because there's no simple way to test for a js
   114   // change in a textfield.                    
    59   // change in a textfield.                    
   115   this.selector.find(".Ldt-createAnnotation-Description")
    60   this.selector.find(".Ldt-createAnnotation-Description")
   116                .bind("propertychange keyup input paste js_mod", IriSP.wrap(this, this.handleTextChanges));
    61                .bind("propertychange keyup input paste js_mod", IriSP.wrap(this, this.handleTextChanges));
   176       }
   121       }
   177     ));
   122     ));
   178   }
   123   }
   179 };
   124 };
   180 
   125 
       
   126 /* Handles adding keywords and polemics */
       
   127 IriSP.createAnnotationWidget.prototype.addKeyword = function(_keyword) {
       
   128     var _field = this.selector.find(".Ldt-createAnnotation-Description"),
       
   129         _rx = IriSP.regexpFromText(_keyword),
       
   130         _contents = _field.val();
       
   131     _contents = ( _rx.test(_contents)
       
   132         ? _contents.replace(_rx,"").replace("  "," ").trim()
       
   133         : _contents.trim() + " " + _keyword
       
   134     );
       
   135     _field.val(_contents);
       
   136     _field.trigger("js_mod");
       
   137 }
       
   138 
   181 /** handles clicks on the annotate button. Works only for the non-cinecast version */
   139 /** handles clicks on the annotate button. Works only for the non-cinecast version */
   182 IriSP.createAnnotationWidget.prototype.handleAnnotateSignal = function() {
   140 IriSP.createAnnotationWidget.prototype.handleAnnotateSignal = function() {
   183   
   141   
   184   if (this._hidden == false && this._state == 'startScreen') {
   142   if (this._hidden == false && this._state == 'startScreen') {
   185     this.selector.hide();
   143     this.selector.hide();
   235 
   193 
   236 /** watch for changes in the textfield and change the buttons accordingly */
   194 /** watch for changes in the textfield and change the buttons accordingly */
   237 IriSP.createAnnotationWidget.prototype.handleTextChanges = function(event) {
   195 IriSP.createAnnotationWidget.prototype.handleTextChanges = function(event) {
   238   var contents = this.selector.find(".Ldt-createAnnotation-Description").val();
   196   var contents = this.selector.find(".Ldt-createAnnotation-Description").val();
   239 
   197 
   240   for(var keyword in this.ids) {
   198   this.selector.find(".Ldt-createAnnotation-keywords button").each(function() {
   241   
   199       var _rx = IriSP.regexpFromText(IriSP.jQuery(this).text());
   242     var id = this.ids[keyword];
   200       if (_rx.test(contents)) {
   243 
   201           IriSP.jQuery(this).removeClass("Ldt-createAnnotation-absent-keyword")
   244     if (contents.indexOf(keyword) != -1) {
   202             .addClass("Ldt-createAnnotation-present-keyword");
   245       /* the word is present in the textarea but the button is not toggled */
   203       } else {
   246       if (this.selector.find("#" + id).hasClass("Ldt-createAnnotation-absent-keyword"))
   204           IriSP.jQuery(this).addClass("Ldt-createAnnotation-absent-keyword")
   247           this.selector.find("#" + id).removeClass("Ldt-createAnnotation-absent-keyword")
   205             .removeClass("Ldt-createAnnotation-present-keyword");
   248                                       .addClass("Ldt-createAnnotation-present-keyword");      
   206       }
   249     } else {
   207   });
   250       /* the word is absent from the textarea but the button is toggled */
   208 
   251       if (this.selector.find("#" + id).hasClass("Ldt-createAnnotation-present-keyword")) {
   209   this.selector.find(".Ldt-createAnnotation-polemics button").each(function() {
   252           this.selector.find("#" + id).removeClass("Ldt-createAnnotation-present-keyword")
   210       var _rx = IriSP.regexpFromText(IriSP.jQuery(this).text());
   253                                       .addClass("Ldt-createAnnotation-absent-keyword");
   211       if (_rx.test(contents)) {
   254       }
   212           IriSP.jQuery(this).addClass("Ldt-createAnnotation-polemic-active");
   255     }
   213       } else {
   256   }
   214           IriSP.jQuery(this).removeClass("Ldt-createAnnotation-polemic-active");
   257   
   215       }
       
   216   });
   258   if (this.polemic_mode) {
   217   if (this.polemic_mode) {
   259     /* Also go through the polemics to highlight the buttons */
   218     /* Also go through the polemics to highlight the buttons */
   260     for (var polemic in this.polemics) {
   219     for (var polemic in this.polemics) {
   261       /* Add the active class to the button */
   220       /* Add the active class to the button */
   262       var classname = "Ldt-createAnnotation-polemic-" + this.polemics[polemic];
   221       var classname = "Ldt-createAnnotation-polemic-" + this.polemics[polemic];
   325 /** handle clicks on "send annotation" button */
   284 /** handle clicks on "send annotation" button */
   326 IriSP.createAnnotationWidget.prototype.handleButtonClick = function(event) {
   285 IriSP.createAnnotationWidget.prototype.handleButtonClick = function(event) {
   327   var _this = this;
   286   var _this = this;
   328   var textfield = this.selector.find(".Ldt-createAnnotation-Description");
   287   var textfield = this.selector.find(".Ldt-createAnnotation-Description");
   329   var contents = textfield.val();
   288   var contents = textfield.val();
   330 
   289   
   331   if (contents === "") {  
   290   if (contents === "") {  
   332     if (this.selector.find(".Ldt-createAnnotation-errorMessage").length === 0) {
   291     if (this.selector.find(".Ldt-createAnnotation-errorMessage").length === 0) {
   333       this.selector.find(".Ldt-createAnnotation-Container")
   292       this.selector.find(".Ldt-createAnnotation-Container")
   334                    .after(IriSP.templToHTML(IriSP.createAnnotation_errorMessage_template));
   293                    .after(IriSP.templToHTML(IriSP.createAnnotation_errorMessage_template));
   335       textfield.css("background-color", "#d93c71");      
   294       textfield.css("background-color", "#d93c71");      
   405   annotation["type_title"] = "Contributions";
   364   annotation["type_title"] = "Contributions";
   406   annotation.content = {};
   365   annotation.content = {};
   407   annotation.content["data"] = contents;
   366   annotation.content["data"] = contents;
   408   
   367   
   409   var meta = apiJson["meta"];
   368   var meta = apiJson["meta"];
   410   if (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.name))
   369   
   411     meta.creator = IriSP.user.name;    
   370   
   412   else 
   371   var _username = this.selector.find(".Ldt-createAnnotation-userName").val();
   413     meta.creator = "An User";
   372   meta.creator = (
       
   373       (_username && _username.length)
       
   374       ? _username
       
   375       : (
       
   376           (!IriSP.null_or_undefined(IriSP.user) && !IriSP.null_or_undefined(IriSP.user.name))
       
   377           ? IriSP.user.name
       
   378           : "Anonymous user"
       
   379       )
       
   380   );
   414   
   381   
   415   meta.created = Date().toString();
   382   meta.created = Date().toString();
   416   
   383   
   417   annotation["tags"] = [];
   384   // All #hashtags are added to tags
   418   
   385   annotation.tags = contents.match(/(#[\S]*)/g);
   419   for (var i = 0; i < this.keywords.length; i++) {
       
   420     var keyword = this.keywords[i];
       
   421     if (contents.indexOf(keyword) != -1)
       
   422       annotation["tags"].push(keyword);
       
   423   }
       
   424   
   386   
   425   var jsonString = JSON.stringify(apiJson);
   387   var jsonString = JSON.stringify(apiJson);
   426   var project_id = this._serializer._data.meta.id;
   388   var project_id = this._serializer._data.meta.id;
   427   
   389   
   428   //TODO: extract magic url
   390   //TODO: extract magic url
   429   var url = Mustache.to_html(this.api_endpoint_template,
   391   var url = Mustache.to_html(this.api_endpoint_template,
   430                               {id: project_id});
   392                               {id: project_id});
   431                           
   393                           
   432   IriSP.jQuery.ajax({
   394   IriSP.jQuery.ajax({
   433       url: url,
   395       url: url,
   434       type: 'PUT',
   396       type: this.api_method,
   435       contentType: 'application/json',
   397       contentType: 'application/json',
   436       data: jsonString,               
   398       data: jsonString,               
   437       //dataType: 'json',
   399       //dataType: 'json',
   438       success: IriSP.wrap(this, function(json, textStatus, XMLHttpRequest) {                   
   400       success: IriSP.wrap(this, function(json, textStatus, XMLHttpRequest) {                   
   439                     /* add the annotation to the annotation and tell the world */
   401                     /* add the annotation to the annotation and tell the world */