CreateAnnotations new feature: hide/show functionality on signal trigger (tweaks), added config options to customize what is displayed more accurately
authordurandn
Fri, 03 Jul 2015 16:58:49 +0200
changeset 1038 e78b889a75e1
parent 1037 5c0416e8bba1
child 1039 4fddc765a716
CreateAnnotations new feature: hide/show functionality on signal trigger (tweaks), added config options to customize what is displayed more accurately
src/widgets/CreateAnnotation.css
src/widgets/CreateAnnotation.js
--- a/src/widgets/CreateAnnotation.css	Fri Jul 03 16:57:10 2015 +0200
+++ b/src/widgets/CreateAnnotation.css	Fri Jul 03 16:58:49 2015 +0200
@@ -23,7 +23,7 @@
 }
 
 .Ldt-CreateAnnotation-Main {
-    min-height: 100px;
+    min-height: 150px;
 }
 
 .Ldt-CreateAnnotation-Title, .Ldt-CreateAnnotation-Creator {
@@ -47,7 +47,6 @@
     position: absolute;
     bottom: 7px;
     right: 7px;
-    display: inline;
     color: #ffffff;
     cursor: pointer;
     background: url('img/submit_annotation.png');
@@ -164,18 +163,4 @@
 
 a.Ldt-CreateAnnotation-Close:hover {
     background-position: -17px 0;
-}
-
-.Ldt-CreateAnnotation-Controls {
-    position: absolute;
-    top: 7px;
-    right: 7px;
-}
-
-span[class^='Ldt-CreateAnnotation-Control-'] {
-    background-color: #ddd;
-    padding: 2px;
-    margin: 4px;
-    border-radius: 3px;
-    border: 1px solid #888;
-}
+}
\ No newline at end of file
--- a/src/widgets/CreateAnnotation.js	Fri Jul 03 16:57:10 2015 +0200
+++ b/src/widgets/CreateAnnotation.js	Fri Jul 03 16:58:49 2015 +0200
@@ -1,16 +1,7 @@
 /* TODO: Add Social Network Sharing */
 
 IriSP.Widgets.CreateAnnotation = function(player, config) {
-    var _this = this;
     IriSP.Widgets.Widget.call(this, player, config);
-    if (_this.api_method == 'local' && window.localStorage[_this.api_endpoint_template]) {
-        this.source.onLoad(function () {
-            var _export = _this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[_this.api_serializer]});
-            _export.deSerialize(window.localStorage[_this.api_endpoint_template]);
-            console.log("Loaded personal annotations", _export);
-            _this.source.merge(_export);
-        });
-    };
 };
 
 IriSP.Widgets.CreateAnnotation.prototype = new IriSP.Widgets.Widget();
@@ -18,13 +9,14 @@
 IriSP.Widgets.CreateAnnotation.prototype.defaults = {
     show_title_field : true,
     show_creator_field : true,
+    creator_field_readonly : false,
     start_visible : true,
     always_visible : false,
     show_slice : true,
-    show_controls: false,
     show_arrow : true,
     show_mic_record: false,
     show_mic_play: false,
+    show_time: true,
     minimize_annotation_widget : true,
     creator_name : "",
     creator_avatar : "",
@@ -51,13 +43,15 @@
     }],
     slice_annotation_type: "chap",
     annotation_type: "Contributions",
+    post_at_segment_time: false,
+    segment_annotation_type: "chap",
     api_serializer: "ldt_annotate",
     api_endpoint_template: "",
     api_method: "POST",
+    project_id: "",
     after_send_timeout: 0,
     close_after_send: false,
-    tag_prefix: "#",
-    slice_widget: null
+    tag_prefix: "#"
 };
 
 IriSP.Widgets.CreateAnnotation.prototype.messages = {
@@ -112,16 +106,11 @@
     + '<form class="Ldt-CreateAnnotation-Screen Ldt-CreateAnnotation-Main">'
     + '<h3><span class="Ldt-CreateAnnotation-h3Left">{{l10n.annotate_video}}{{#show_title_field}}</span></h3>'
     + '<h3><span class="Ldt-CreateAnnotation-h3Left"><input class="Ldt-CreateAnnotation-Title empty" placeholder="{{l10n.type_title}}" />{{/show_title_field}}'
-    + '<span class="Ldt-CreateAnnotation-Times"> {{#show_slice}}{{l10n.from_time}} {{/show_slice}}{{^show_slice}}{{l10n.at_time}} {{/show_slice}} <span class="Ldt-CreateAnnotation-Begin">00:00</span>'
+    + '{{#show_time}}<span class="Ldt-CreateAnnotation-Times"> {{#show_slice}}{{l10n.from_time}} {{/show_slice}}{{^show_slice}}{{l10n.at_time}} {{/show_slice}} <span class="Ldt-CreateAnnotation-Begin">00:00</span>{{/show_time}}'
     + '{{#show_slice}} {{l10n.to_time}} <span class="Ldt-CreateAnnotation-End">{{end}}</span>{{/show_slice}}</span></span>'
-    + '{{#show_creator_field}}{{l10n.your_name_}} <input class="Ldt-CreateAnnotation-Creator empty" value="{{creator_name}}" />{{/show_creator_field}}</h3>'
-    + '{{#show_controls}}<div class="Ldt-CreateAnnotation-Controls">'
-    +   '<span class="Ldt-CreateAnnotation-Control-In">IN</span>'
-    +   '<span class="Ldt-CreateAnnotation-Control-Out">OUT</span>'
-    +   '<span class="Ldt-CreateAnnotation-Control-Play">Play</span>'
-    + '</div>{{/show_controls}}'
+    + '{{#show_creator_field}}{{l10n.your_name_}} <input class="Ldt-CreateAnnotation-Creator empty" value="{{creator_name}}" {{#creator_field_readonly}}readonly{{/creator_field_readonly}}/>{{/show_creator_field}}</h3>'
     + '<textarea class="Ldt-CreateAnnotation-Description empty" placeholder="{{l10n.type_description}}"></textarea>'
-    + '{{#show_creator_field}}<div class="Ldt-CreateAnnotation-Avatar"><img src="{{creator_avatar}}" title="{{creator_name}}"></img></div>{{/show_creator_field}}'
+    + '<div class="Ldt-CreateAnnotation-Avatar"><img src="{{creator_avatar}}" title="{{creator_name}}"></img></div>'
     + '<input type="submit" class="Ldt-CreateAnnotation-Submit" value="{{l10n.submit}}" />'
     + '{{#show_mic_record}}<div class="Ldt-CreateAnnotation-RecBlock"><div class="Ldt-CreateAnnotation-RecLabel">Add voice annotation</div>'
     + '    <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="220" height="160">'
@@ -146,7 +135,7 @@
     + '             pluginspage="http://www.macromedia.com/go/getflashplayer">'
     + '        </embed>'
     + '    </object>'
-    + '</div>{{/show_mic_record}}'
+    + '</div>{{/show_mic_record}}' 
     + '{{#tags.length}}<div class="Ldt-CreateAnnotation-Tags"><div class="Ldt-CreateAnnotation-TagTitle">{{l10n.add_keywords_}}</div><ul class="Ldt-CreateAnnotation-TagList">'
     + '{{#tags}}<li class="Ldt-CreateAnnotation-TagLi" tag-id="{{id}}" data-text="{{tag_prefix}}{{title}}"><span class="Ldt-CreateAnnotation-TagButton">{{title}}</span></li>{{/tags}}</ul></div>{{/tags.length}}'
     + '{{#polemics.length}}<div class="Ldt-CreateAnnotation-Polemics"><div class="Ldt-CreateAnnotation-PolemicTitle">{{l10n.add_polemic_keywords_}}</div><ul class="Ldt-CreateAnnotation-PolemicList">'
@@ -156,15 +145,15 @@
     + '<div class="Ldt-CreateAnnotation-Screen Ldt-CreateAnnotation-Error">{{^always_visible}}<a title="{{l10n.close_widget}}" class="Ldt-CreateAnnotation-Close" href="#"></a>{{/always_visible}}<div class="Ldt-CreateAnnotation-InnerBox">{{l10n.error_while_contacting}}</div></div>'
     + '<div class="Ldt-CreateAnnotation-Screen Ldt-CreateAnnotation-Saved">{{^always_visible}}<a title="{{l10n.close_widget}}" class="Ldt-CreateAnnotation-Close" href="#"></a>{{/always_visible}}<div class="Ldt-CreateAnnotation-InnerBox">{{l10n.annotation_saved}}</div></div>'
     + '</div></div>';
-
+    
 IriSP.Widgets.CreateAnnotation.prototype.draw = function() {
     var _this = this;
-
+    
     this.begin = new IriSP.Model.Time();
     this.end = this.source.getDuration();
-
+    
     this.tag_prefix = this.tag_prefix || "";
-
+    
     if (this.tag_titles && !this.tags) {
 		if(!(this.tag_titles.length==1 && this.tag_titles[0]=="")){
 			this.tags = IriSP._(this.tag_titles).map(function(_tag_title) {
@@ -200,13 +189,13 @@
     this.renderTemplate();
     if (this.show_mic_record) {
         this.recorder = this.$.find("embed")[0];
-
+        
         window.setAudioUrl = function(_url) {
             _this.audio_url = _url;
-        };
+        }
     }
     if (this.show_slice) {
-        this.slice_widget = this.insertSubwidget(
+        this.insertSubwidget(
             this.$.find(".Ldt-CreateAnnotation-Slice"),
             {
                 type: "Slice",
@@ -259,35 +248,17 @@
     if (this.show_creator_field) {
         this.$.find(".Ldt-CreateAnnotation-Creator").bind("change keyup input paste", this.functionWrapper("onCreatorChange"));
     }
-    this.$.find("[class^='Ldt-CreateAnnotation-Control-']").click(function() {
-        var action = this.className.replace('Ldt-CreateAnnotation-Control-', '');
-        switch (action) {
-            case "In":
-               // Set In bound to current player time
-               _this.begin = new IriSP.Model.Time(_this.media.getCurrentTime() || 0);
-               _this.$.find(".Ldt-CreateAnnotation-Begin").html(_this.begin.toString());
-               break;
-            case "Out":
-               // Set In bound to current player time
-               _this.end = new IriSP.Model.Time(_this.media.getCurrentTime() || _this.media.duration);
-               _this.$.find(".Ldt-CreateAnnotation-End").html(_this.end.toString());
-               break;
-            case "Play":
-               _this.media.setCurrentTime(_this.begin);
-               _this.media.play()
-               break;
-        }
-        return false;
-    });
-
+    
     if (this.start_visible) {
         this.show();
     } else {
         this.$.hide();
         this.hide();
     }
-
+    
     this.onMdpEvent("CreateAnnotation.toggle","toggle");
+    this.onMdpEvent("CreateAnnotation.hide", "hide");
+    this.onMdpEvent("CreateAnnotation.show", "show");
     this.$.find("form").submit(this.functionWrapper("onSubmit"));
 };
 
@@ -297,51 +268,47 @@
 }
 
 IriSP.Widgets.CreateAnnotation.prototype.show = function() {
-    this.visible = true;
-    this.showScreen('Main');
-    this.$.find(".Ldt-CreateAnnotation-Description").val("").css("border-color", "#666666").addClass("empty");
-    if (this.show_title_field) {
-        this.$.find(".Ldt-CreateAnnotation-Title").val("").css("border-color", "#666666").addClass("empty");
-    }
-    if (this.show_creator_field) {
-        this.$.find(".Ldt-CreateAnnotation-Creator").val(this.creator_name).css("border-color", "#666666");
-        if (!this.creator_name) {
-            this.$.find(".Ldt-CreateAnnotation-Creator").addClass("empty");
+    if (!this.visible){
+        this.visible = true;
+        this.showScreen('Main');
+        this.$.find(".Ldt-CreateAnnotation-Description").val("").css("border-color", "#666666").addClass("empty");
+        if (this.show_title_field) {
+            this.$.find(".Ldt-CreateAnnotation-Title").val("").css("border-color", "#666666").addClass("empty");
         }
-    }
-    this.$.find(".Ldt-CreateAnnotation-TagLi, .Ldt-CreateAnnotation-PolemicLi").removeClass("selected");
-    this.$.slideDown();
-    if (this.minimize_annotation_widget) {
-        this.player.trigger("Annotation.minimize");
+        if (this.show_creator_field) {
+            this.$.find(".Ldt-CreateAnnotation-Creator").val(this.creator_name).css("border-color", "#666666");
+            if (!this.creator_name) {
+                this.$.find(".Ldt-CreateAnnotation-Creator").addClass("empty");
+            }
+        }
+        this.$.find(".Ldt-CreateAnnotation-TagLi, .Ldt-CreateAnnotation-PolemicLi").removeClass("selected");
+        this.$.slideDown();
+        if (this.minimize_annotation_widget) {
+            this.player.trigger("Annotation.minimize");
+        }
     }
 };
 
 IriSP.Widgets.CreateAnnotation.prototype.hide = function() {
-    if (this.recorder) {
-        this.recorder.stopRecord();
-    }
-    if (!this.always_visible) {
-        this.visible = false;
-        this.$.slideUp();
-        if (this.minimize_annotation_widget) {
-            this.player.trigger("Annotation.maximize");
+    if (this.visible){
+        if (this.recorder) {
+            this.recorder.stopRecord();
+        }
+        if (!this.always_visible) {
+            this.visible = false;
+            this.$.slideUp();
+            if (this.minimize_annotation_widget) {
+                this.player.trigger("Annotation.maximize");
+            }
         }
     }
 };
 
 IriSP.Widgets.CreateAnnotation.prototype.toggle = function() {
-    var _this = this;
     if (!this.always_visible) {
         if (this.visible) {
             this.hide();
         } else {
-            _this.begin = new IriSP.Model.Time(_this.media.getCurrentTime() || 0);
-            _this.end = new IriSP.Model.Time(_this.media.getCurrentTime() || 0);
-            _this.$.find(".Ldt-CreateAnnotation-Begin").html(_this.begin.toString());
-            _this.$.find(".Ldt-CreateAnnotation-End").html(_this.end.toString());
-            if (_this.slice_widget) {
-                _this.slice_widget.setBounds(_this.begin, _this.end);
-            }
             this.show();
         }
     }
@@ -419,11 +386,11 @@
     if (!this.onDescriptionChange() || (this.show_title_field && !this.onTitleChange()) || (this.show_creator_field && !this.onCreatorChange())) {
         return false;
     }
-
+    
     if (this.recorder) {
         this.recorder.stopRecord();
     }
-
+    
     var _this = this,
         _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager), /* Création d'une liste d'annotations contenant une annotation afin de l'envoyer au serveur */
         _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}), /* Création d'un objet source utilisant un sérialiseur spécifique pour l'export */
@@ -431,7 +398,7 @@
         _annotationTypes = this.source.getAnnotationTypes().searchByTitle(this.annotation_type, true), /* Récupération du type d'annotation dans lequel l'annotation doit être ajoutée */
         _annotationType = (_annotationTypes.length ? _annotationTypes[0] : new IriSP.Model.AnnotationType(false, _export)), /* Si le Type d'Annotation n'existe pas, il est créé à la volée */
         _url = Mustache.to_html(this.api_endpoint_template, {id: this.source.projectId}); /* Génération de l'URL à laquelle l'annotation doit être envoyée, qui doit inclure l'ID du projet */
-
+    
     /* Si nous avons dû générer un ID d'annotationType à la volée... */
     if (!_annotationTypes.length) {
         /* Il ne faudra pas envoyer l'ID généré au serveur */
@@ -439,30 +406,48 @@
         /* Il faut inclure le titre dans le type d'annotation */
         _annotationType.title = this.annotation_type;
     }
-
+    
     /*
      * Nous remplissons les données de l'annotation générée à la volée
      * ATTENTION: Si nous sommes sur un MASHUP, ces éléments doivent se référer AU MEDIA D'ORIGINE
      * */
     _annotation.setMedia(this.source.currentMedia.id); /* Id du média annoté */
-    _annotation.setBegin(this.begin); /*Timecode de début */
-    _annotation.setEnd(this.end); /* Timecode de fin */
-    _annotation.created = new Date(); /* Date de création de l'annotation */
-
+    
+    if (this.post_at_segment_time){
+        var _currentTime = this.media.getCurrentTime() 
+        var _segmentsAnnotations = this.source.getAnnotationsByTypeTitle(this.segments_annotation_type)
+        var _currentSegments = _segmentsAnnotations.filter(function(_segment){
+            return (_currentTime >= _segment.begin && _currentTime <= _segment.end)
+        });
+        if (_currentSegments.length == 0){
+            _annotation.setBegin(this.begin); /* Timecode de début du widget */
+            _annotation.setEnd(this.end); /* Timecode de fin du widget */
+        }
+        else {
+            _annotation.setBegin(_currentSegments[0].begin); /* Timecode de début du segment */
+            _annotation.setEnd(_currentSegments[0].end); /* Timecode de fin du segment */
+        }
+    }
+    else {
+        _annotation.setBegin(this.begin); /*Timecode de début du widget */
+        _annotation.setEnd(this.end); /* Timecode de fin du widget */
+    }
     _annotation.setAnnotationType(_annotationType.id); /* Id du type d'annotation */
-    _annotation.description = this.$.find(".Ldt-CreateAnnotation-Description").val(); /* Champ description */
     if (this.show_title_field) {
         /* Champ titre, seulement s'il est visible */
         _annotation.title = this.$.find(".Ldt-CreateAnnotation-Title").val();
-    } else {
-        _annotation.title = _annotation.description;
+    }if (this.project_id != ""){
+    	/* Champ id projet, seulement si on l'a renseigné dans la config */
+    	_annotation.project_id = this.project_id;
     }
-
+    _annotation.created = new Date(); /* Date de création de l'annotation */
+    _annotation.description = this.$.find(".Ldt-CreateAnnotation-Description").val(); /* Champ description */
+   
     var tagIds = Array.prototype.map.call(
         this.$.find(".Ldt-CreateAnnotation-TagLi.selected"),
         function(el) { return IriSP.jQuery(el).attr("tag-id")}
     );
-
+        
     IriSP._(_annotation.description.match(/#[^\s#.,;]+/g)).each(function(_tt) {
         var _tag,
             _tag_title = _tt.replace(/^#/,''),
@@ -477,9 +462,9 @@
         if (tagIds.indexOf(_tag.id) === -1) {
             tagIds.push(_tag.id);
         }
-
+        
     })
-
+   
     _annotation.setTags(IriSP._(tagIds).uniq()); /*Liste des ids de tags */
     if (this.audio_url) {
         _annotation.audio = {
@@ -494,65 +479,46 @@
         _annotation.creator = this.creator_name;
     }
     _exportedAnnotations.push(_annotation); /* Ajout de l'annotation à la liste à exporter */
-
-    if (this.api_method == 'local') {
-        // Append to existing localStorage annotations
-        // FIXME: handle movie ids
-        /* Use localStorage */
-        /* Data will be serialized in the localStore property designated by api_endpoint_template */
-        _export.addList("annotation", _exportedAnnotations); /* Ajout de la liste à exporter à l'objet Source */
-        _this.source.merge(_export); /* On ajoute la nouvelle annotation au recueil original */
-        // Import previously saved local annotations
-        if (window.localStorage[_this.api_endpoint_template]) {
-            _export.deSerialize(window.localStorage[_this.api_endpoint_template]);
-        }
-        // Save everything back
-        window.localStorage[_this.api_endpoint_template] = _export.serialize();
-        if (_this.pause_on_write && _this.media.getPaused()) {
-            _this.media.play();
+    _export.addList("annotation",_exportedAnnotations); /* Ajout de la liste à exporter à l'objet Source */
+    var _this = this;
+    /* Envoi de l'annotation via AJAX au serveur ! */
+    IriSP.jQuery.ajax({
+        url: _url,
+        type: this.api_method,
+        contentType: 'application/json',
+        data: _export.serialize(), /* L'objet Source est sérialisé */
+        success: function(_data) {
+            _this.showScreen('Saved'); /* Si l'appel a fonctionné, on affiche l'écran "Annotation enregistrée" */
+            if (_this.after_send_timeout) { /* Selon les options de configuration, on revient à l'écran principal ou on ferme le widget, ou rien */
+                window.setTimeout(
+                    function() {
+                        _this.close_after_send
+                        ? _this.hide()
+                        : _this.show();
+                    },
+                    _this.after_send_timeout
+                );
+            }
+            _export.getAnnotations().removeElement(_annotation, true); /* Pour éviter les doublons, on supprime l'annotation qui a été envoyée */
+            _export.deSerialize(_data); /* On désérialise les données reçues pour les réinjecter */
+            _this.source.merge(_export); /* On récupère les données réimportées dans l'espace global des données */
+            if (_this.pause_on_write && _this.media.getPaused()) {
+                _this.media.play();
+            }
+            _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */
+        },
+        error: function(_xhr, _error, _thrown) {
+            IriSP.log("Error when sending annotation", _thrown);
+            _export.getAnnotations().removeElement(_annotation, true);
+            _this.showScreen('Error');
+            window.setTimeout(function(){
+                _this.showScreen("Main")
+            },
+            (_this.after_send_timeout || 5000));
         }
-        _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */
-        _this.$.find(".Ldt-CreateAnnotation-Description").val("");
-    } else {
-        _export.addList("annotation",_exportedAnnotations); /* Ajout de la liste à exporter à l'objet Source */
-       /* Envoi de l'annotation via AJAX au serveur ! */
-        IriSP.jQuery.ajax({
-            url: _url,
-            type: this.api_method,
-            contentType: 'application/json',
-            data: _export.serialize(), /* L'objet Source est sérialisé */
-            success: function(_data) {
-                _this.showScreen('Saved'); /* Si l'appel a fonctionné, on affiche l'écran "Annotation enregistrée" */
-                if (_this.after_send_timeout) { /* Selon les options de configuration, on revient à l'écran principal ou on ferme le widget, ou rien */
-                    window.setTimeout(
-                        function() {
-                            _this.close_after_send
-                                ? _this.hide()
-                                : _this.show();
-                        },
-                        _this.after_send_timeout
-                    );
-                }
-                _export.getAnnotations().removeElement(_annotation, true); /* Pour éviter les doublons, on supprime l'annotation qui a été envoyée */
-                _export.deSerialize(_data); /* On désérialise les données reçues pour les réinjecter */
-                _this.source.merge(_export); /* On récupère les données réimportées dans l'espace global des données */
-                if (_this.pause_on_write && _this.media.getPaused()) {
-                    _this.media.play();
-                }
-                _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */
-            },
-            error: function(_xhr, _error, _thrown) {
-                IriSP.log("Error when sending annotation", _thrown);
-                _export.getAnnotations().removeElement(_annotation, true);
-                _this.showScreen('Error');
-                window.setTimeout(function(){
-                    _this.showScreen("Main")
-                },
-                                  (_this.after_send_timeout || 5000));
-            }
-        });
-        this.showScreen('Wait');
-    }
-
+    });
+    this.showScreen('Wait');
+    
     return false;
 };
+