# HG changeset patch # User durandn # Date 1441640392 -7200 # Node ID b3cb1d4f07aa721b86e1c0720038b1382e201d99 # Parent 8ecee14c6d816849395db32896d05128f588ba33 Updated Markers Widget to allow Markers to be deleted + reworked the widget code to make it slightly more readable + updated iframe for markers to allow markers to be submitted per-user diff -r 8ecee14c6d81 -r b3cb1d4f07aa server/src/remie/static/remie/metadataplayer/Markers.css --- a/server/src/remie/static/remie/metadataplayer/Markers.css Mon Sep 07 16:36:33 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/Markers.css Mon Sep 07 17:39:52 2015 +0200 @@ -33,7 +33,7 @@ margin-top: 1px; } -.Ldt-Markers-Create{ +.Ldt-Markers-RoundButton{ display: inline-block; background-color: #d93c71; color: #ffffff; @@ -41,7 +41,7 @@ height: 20px; width: 20px; border-radius: 20px; - font-size: 25; + font-size: 25px; font-style: bold; border: 1px solid; border-color: #eca3bc #631e34 #36101c #e16e93; @@ -68,7 +68,8 @@ margin: 0px; } -.Ldt-Markers-ScreenSending, .Ldt-Markers-ScreenFailure, .Ldt-Markers-ScreenSuccess{ +.Ldt-Markers-ScreenSending, .Ldt-Markers-ScreenFailure, .Ldt-Markers-ScreenSuccess, +.Ldt-Markers-ScreenConfirmDelete, .Ldt-Markers-ScreenDeleteSuccess{ text-align: center; vertical-align: middle; line-height: 125px; @@ -90,6 +91,15 @@ background: url(img/widget-control.png); } +a.Ldt-Markers-Screen-SubmitDelete, a.Ldt-Markers-Screen-CancelDelete { + color: #3366BB; + cursor: pointer; +} + +a.Ldt-Markers-Screen-SubmitDelete:hover, a.Ldt-Markers-Screen-CancelDelete:hover { + color: #3a75ff; +} + .Ldt-Markers-MarkerDescription{ height: 45%; width: 90%; @@ -149,7 +159,7 @@ vertical-align: top; } -.Ldt-Markers-Create:hover, .Ldt-Markers-MarkerSend:hover, .Ldt-Markers-MarkerCancel:hover{ +.Ldt-Markers-RoundButton:hover, .Ldt-Markers-MarkerSend:hover, .Ldt-Markers-MarkerCancel:hover{ background-color: #e15581; border-color: #222222 #e87d9f #f0adc3 #68273c; } \ No newline at end of file diff -r 8ecee14c6d81 -r b3cb1d4f07aa server/src/remie/static/remie/metadataplayer/Markers.js --- a/server/src/remie/static/remie/metadataplayer/Markers.js Mon Sep 07 16:36:33 2015 +0200 +++ b/server/src/remie/static/remie/metadataplayer/Markers.js Mon Sep 07 17:39:52 2015 +0200 @@ -15,9 +15,12 @@ ball_radius: 4, pause_on_write: true, api_serializer: "ldt_annotate", - api_endpoint_template: "", + api_endpoint_template_create: "", + api_endpoint_template_edit: "", + api_endpoint_template_delete: "", api_method_create: "POST", - api_method_editing: "PUT", + api_method_edit: "PUT", + api_method_delete: "DELETE", project_id: "", creator_name: "", after_send_timeout: 0, @@ -31,7 +34,8 @@ + '' + '
' + '
' - + '
+
' + + '
+
' + + '
-
' + '
' + '
' + '
' @@ -41,10 +45,22 @@ + '' + '
{{l10n.annotation_saved}}
' + '
' + + '
' + + '' + + '
{{l10n.delete_saved}}
' + + '
' + '
' + '' + '
{{l10n.error_while_contacting}}
' + '
' + + '
' + + '' + + '
' + + '{{l10n.delete_text}} ' + + '{{l10n.submit_delete}} ' + + '{{l10n.cancel}}' + + '
' + + '
' + '
'; @@ -66,18 +82,24 @@ IriSP.Widgets.Markers.prototype.messages = { en : { send : "Send", + submit_delete: "Delete", cancel : "Cancel", wait_while_processing: "Please wait while your annotation is being processed...", + delete_text: "The selected marker will be deleted. Continue?", error_while_contacting: "An error happened while contacting the server. Your annotation has not been saved.", annotation_saved: "Thank you, your annotation has been saved.", + delete_saved: "Thank you, your annotation has been deleted", close_widget: "Close", }, fr : { send : "Envoyer", + submit_delete: "Supprimer", cancel : "Annuler", wait_while_processing: "Veuillez patienter pendant le traitement de votre annotation...", + delete_text: "Le marqueur sélectionné sera supprimé. Continuer?", error_while_contacting: "Une erreur s'est produite en contactant le serveur. Votre annotation n'a pas été enregistrée.", annotation_saved: "Merci, votre annotation a été enregistrée.", + delete_saved: "Merci, votre annotation a été supprimée", close_widget: "Fermer", } } @@ -92,21 +114,13 @@ }); this.drawMarkers(); - this.$.find(".Ldt-Markers-Create").click(function(){ - if (!_this.selectedMarker){ - _this.toggleCreateMarker(); - } - else { - _this.selectedMarker = false; - _this.$.find(".Ldt-Markers-Info").html(""); - _this.$.find(".Ldt-Markers-MarkerBall").css("background-color", _this.marker_color) - _this.$.find(".Ldt-Markers-Create").html("+"); - } - }) - this.$.find(".Ldt-Markers-Info").click(function(){ - if (_this.selectedMarker&&!_this.editing){ - _this.toggleCreateMarker(); - } + this.$.find(".Ldt-Markers-Create").click(this.functionWrapper("onCreateClick")); + this.$.find(".Ldt-Markers-Delete").hide(); + this.$.find(".Ldt-Markers-Delete").click(this.functionWrapper("onDeleteClick")); + this.$.find(".Ldt-Markers-Screen-SubmitDelete").click(this.functionWrapper("sendDelete")); + this.$.find(".Ldt-Markers-Screen-CancelDelete").click(function(){ + _this.showScreen("Main"); + _this.cancelEdit(); }) this.showScreen("Main"); this.$.css({ @@ -117,12 +131,12 @@ this.$.find(".Ldt-Markers-Close").click(function() { _this.showScreen("Main"); + _this.cancelEdit(); }); this.onMediaEvent("timeupdate", "updatePosition"); this.onMdpEvent("Markers.refresh", this.functionWrapper("drawMarkers")); - this.editing = false; this.selectedMarker = false; } @@ -134,47 +148,105 @@ }); }; +IriSP.Widgets.Markers.prototype.onCreateClick = function(){ + this.pauseOnWrite(); + if (!this.selectedMarker){ + this.startEdit(); + } +} -IriSP.Widgets.Markers.prototype.toggleCreateMarker = function(){ - if(!this.editing){ - this.editing = true +IriSP.Widgets.Markers.prototype.onDeleteClick = function(){ + _this = this; + this.pauseOnWrite(); + if(this.selectedMarker){ + this.showScreen("ConfirmDelete"); } else { - this.editing = false + // Clic sur - sans marqueur sélectionné = retour à l'état initial + this.cancelEdit(); } - var _divHtml = ""; - if (this.selectedMarker){ +} + +IriSP.Widgets.Markers.prototype.sendDelete = function(){ + _url = Mustache.to_html(this.api_endpoint_template_delete, {annotation_id: this.selectedMarker ? this.selectedMarker.id : ""}); + IriSP.jQuery.ajax({ + url: _url, + type: this.api_method_delete, + contentType: 'application/json', + success: function(_data) { + _this.showScreen('DeleteSuccess'); /* Si l'appel a fonctionné, on affiche l'écran "Annotation enregistrée" */ + window.setTimeout(function(){ + _this.showScreen("Main"); + _this.cancelEdit(); + }, + (_this.after_send_timeout || 5000)); + if (_this.pause_on_write && _this.media.getPaused()) { + _this.media.play(); + } + _this.markers.removeElement(_this.selectedMarker); + _this.selectedMarker = false + _this.cancelEdit(); + _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */ + _this.player.trigger("Markers.refresh"); + }, + error: function(_xhr, _error, _thrown) { + IriSP.log("Error when sending annotation", _thrown); + _this.showScreen('Failure'); + window.setTimeout(function(){ + _this.showScreen("Main"); + }, + (_this.after_send_timeout || 5000)); + } + }); + this.showScreen("Sending") +} + +IriSP.Widgets.Markers.prototype.startEdit = function(){ + if (this.selectedMarker){ _divHtml = Mustache.to_html(this.infoTemplate, { - edit: this.editing, + edit: true, marker_info: this.selectedMarker.description, send: this.l10n.send, cancel: this.l10n.cancel }) - - this.$.find(".Ldt-Markers-Info").html(_divHtml); - } - else { - if (this.editing) { - _divHtml = Mustache.to_html(this.infoTemplate, { - edit: this.editing, - marker_info: "", - send: this.l10n.send, - cancel: this.l10n.cancel, - }) - } - this.$.find(".Ldt-Markers-Info").html(_divHtml); - } - - if(this.editing){ - this.$.find(".Ldt-Markers-MarkerSend").click(this.functionWrapper("onSubmit")); - this.$.find(".Ldt-Markers-MarkerCancel").click(this.functionWrapper("toggleCreateMarker")); - this.$.find(".Ldt-Markers-MarkerTextArea").bind("change keyup input paste", this.functionWrapper("onDescriptionChange")); - this.$.find(".Ldt-Markers-Create").html("-"); } else { - this.$.find(".Ldt-Markers-Create").html("+"); + _divHtml = Mustache.to_html(this.infoTemplate, { + edit: true, + marker_info: "", + send: this.l10n.send, + cancel: this.l10n.cancel, + }) } -}; + this.$.find(".Ldt-Markers-Info").html(_divHtml); + this.$.find(".Ldt-Markers-MarkerSend").click(this.functionWrapper("onSubmit")); + this.$.find(".Ldt-Markers-MarkerCancel").click(this.functionWrapper("cancelEdit")); + this.$.find(".Ldt-Markers-MarkerTextArea").bind("change keyup input paste", this.functionWrapper("onDescriptionChange")); + this.$.find(".Ldt-Markers-Delete").show(); + this.$.find(".Ldt-Markers-Create").hide(); + this.editing = true; +} + +IriSP.Widgets.Markers.prototype.cancelEdit = function(){ + if (this.selectedMarker){ + // Clic sur "cancel" pendant édition d'un marqueur = retour à l'état visualisation + _divHtml = Mustache.to_html(this.infoTemplate, { + edit: false, + marker_info: this.selectedMarker.description, + send: this.l10n.send, + cancel: this.l10n.cancel, + }) + this.$.find(".Ldt-Markers-Info").html(_divHtml); + this.$.find(".Ldt-Markers-MarkerDescription").click(this.functionWrapper("startEdit")); + } + else { + // Clic sur "cancel" pendant la création d'un marqueur = retour à l'état initial + this.$.find(".Ldt-Markers-Info").html(""); + this.$.find(".Ldt-Markers-Delete").hide(); + this.$.find(".Ldt-Markers-Create").show(); + } + this.editing = false; +} IriSP.Widgets.Markers.prototype.onDescriptionChange = function(){ var _field = this.$.find(".Ldt-Markers-MarkerTextArea"), @@ -198,13 +270,11 @@ IriSP.Widgets.Markers.prototype.showScreen = function(_screenName) { this.$.find('.Ldt-Markers-Screen' + _screenName).show() .siblings().hide(); - if ((_screenName=="Main")&&(this.editing)){ - this.toggleCreateMarker(); - }; } IriSP.Widgets.Markers.prototype.drawMarkers = function(){ this.$.remove("Ldt-Markers-Marker"); + this.$.find(".Ldt-Markers-List").html("") var _this = this, _scale = this.width / this.source.getDuration(), list_$ = this.$.find('.Ldt-Markers-List'); @@ -234,53 +304,38 @@ }) .click(function(){ _this.showScreen("Main"); + _this.cancelEdit(); if (!((_this.selectedMarker)&&(_this.selectedMarker.id == _marker.id))){ + // if there either is no marker selected or we click a different marker list_$.find(".Ldt-Markers-MarkerBall").css("background-color", _this.marker_color) _el.children().css("background-color", _this.selected_color) _this.selectedMarker = _marker; _divHtml = Mustache.to_html(_this.infoTemplate, { - edit: _this.editing, + edit: false, marker_info: _marker.description, send: _this.l10n.send, cancel: _this.l10n.cancel }) _this.$.find(".Ldt-Markers-Info").html(_divHtml); + _this.$.find(".Ldt-Markers-MarkerDescription").click(_this.functionWrapper("startEdit")); + _this.$.find(".Ldt-Markers-Delete").show(); + _this.$.find(".Ldt-Markers-Create").hide(); - if(_this.editing){ - _this.$.find(".Ldt-Markers-MarkerSend").click(_this.functionWrapper("onSubmit")); - _this.$.find(".Ldt-Markers-MarkerCancel").click(_this.functionWrapper("toggleCreateMarker")); - } } else { + // if we click the currently selected marker, we unselect it var _divHtml = "" - if (_this.editing){ - _divHtml = Mustache.to_html(_this.infoTemplate, { - edit: _this.editing, - marker_info: "", - send: _this.l10n.send, - cancel: _this.l10n.cancel - }); - } _el.children().css("background-color", _this.hover_color); _this.selectedMarker = false; _this.$.find(".Ldt-Markers-Info").html(_divHtml); + _this.$.find(".Ldt-Markers-Create").show(); + _this.$.find(".Ldt-Markers-Delete").hide(); - if(_this.editing){ - _this.$.find(".Ldt-Markers-MarkerSend").click(_this.functionWrapper("onSubmit")); - _this.$.find(".Ldt-Markers-MarkerCancel").click(_this.functionWrapper("toggleCreateMarker")); - } - } - - if (_this.selectedMarker){ - _this.$.find(".Ldt-Markers-Create").html("-") - } - else { - _this.$.find(".Ldt-Markers-Create").html("+") } if (_this.selectedMarker) { - // If we unselect a marker we shouldn't trigger pause or time jump + // Only if we select a new marker do we pause video and time jump _this.media.pause(); _marker.trigger("click"); } @@ -289,6 +344,7 @@ }) } + IriSP.Widgets.Markers.prototype.onSubmit = function(){ /* Si les champs obligatoires sont vides, on annule l'envoi */ @@ -302,11 +358,11 @@ } 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 */ - _url = Mustache.to_html(this.api_endpoint_template, {annotation_id: this.selectedMarker ? this.selectedMarker.id : ""}); + _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager); /* Création d'une liste d'annotations contenant une annotation afin de l'envoyer au serveur */ if (this.selectedMarker){ var _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}) - _annotation = this.selectedMarker; + _annotation = this.selectedMarker, + _url = Mustache.to_html(this.api_endpoint_template_edit, {annotation_id: this.selectedMarker ? this.selectedMarker.id : ""}); _annotation.source = _export _annotation.description = this.$.find(".Ldt-Markers-MarkerTextArea").val(), /* Champ description */ _annotationTypes = this.source.getAnnotationTypes().searchByTitle(this.annotation_type, true), /* Récupération du type d'annotation dans lequel l'annotation doit être ajoutée */ @@ -316,7 +372,8 @@ var _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 */ _annotation = new IriSP.Model.Annotation(false, _export); /* Création d'une annotation dans cette source avec un ID généré à la volée (param. false) */ _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 */ + _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_create); /* 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 */ @@ -353,13 +410,14 @@ /* Envoi de l'annotation via AJAX au serveur ! */ IriSP.jQuery.ajax({ url: _url, - type: this.selectedMarker ? this.api_method_editing : this.api_method_create, + type: this.selectedMarker ? this.api_method_edit : this.api_method_create, contentType: 'application/json', data: _export.serialize(), /* L'objet Source est sérialisé */ success: function(_data) { _this.showScreen('Success'); /* Si l'appel a fonctionné, on affiche l'écran "Annotation enregistrée" */ window.setTimeout(function(){ - _this.showScreen("Main") + _this.showScreen("Main"); + _this.cancelEdit(); }, (_this.after_send_timeout || 5000)); _export.getAnnotations().removeElement(_annotation, true); /* Pour éviter les doublons, on supprime l'annotation qui a été envoyée */ @@ -371,9 +429,10 @@ } _this.markers.push(_annotation); _this.selectedMarker = _annotation; + _this.cancelEdit(); + _this.drawMarkers(); _this.player.trigger("AnnotationsList.refresh"); /* On force le rafraîchissement du widget AnnotationsList */ _this.player.trigger("Markers.refresh"); - _this.$.find(".Ldt-Markers-MarkerTextArea").val("") }, error: function(_xhr, _error, _thrown) { IriSP.log("Error when sending annotation", _thrown); diff -r 8ecee14c6d81 -r b3cb1d4f07aa server/src/remie/templates/remie/iframe_markers.html --- a/server/src/remie/templates/remie/iframe_markers.html Mon Sep 07 16:36:33 2015 +0200 +++ b/server/src/remie/templates/remie/iframe_markers.html Mon Sep 07 17:39:52 2015 +0200 @@ -74,9 +74,11 @@ disable_ctrl_f: true },{ type: "Markers", - annotation_type: "markers", + annotation_type: "markers_{{current_user}}", line_height: 24, - api_endpoint_template: "{% url 'api_dispatch_list' resource_name='annotations' api_name='1.0' %}{% templatetag openvariable %}annotation_id{% templatetag closevariable %}", + api_endpoint_template_create: "{% url 'api_dispatch_list' resource_name='annotations' api_name='1.0' %}", + api_endpoint_template_edit: "{% url 'api_dispatch_list' resource_name='annotations' api_name='1.0' %}{% templatetag openvariable %}annotation_id{% templatetag closevariable %}/", + api_endpoint_template_delete: "{% url 'api_dispatch_list' resource_name='annotations' api_name='1.0' %}{% templatetag openvariable %}annotation_id{% templatetag closevariable %}/", creator_name : "{{current_user}}", project_id: "{{project_id}}" }