# HG changeset patch # User durandn # Date 1441114306 -7200 # Node ID eb77616c245fe0cba0d6b0da3428bd7646b80933 # Parent b06345320ffbf99b201ae8776977d2b7100ab6d4 Updated LatestAnnotation, CurrentSegmentInfobox, AnnotationController and AnnotationList widgets to use timerange to find the current segment when the corresponding option is used + CurrentSegmentInfobox now has an option for editing the current segment + LatestAnnotation now has a "Copy and edit" button that allows to use the text from the currently displayed annotation into the CreateAnnotation widget textarea diff -r b06345320ffb -r eb77616c245f src/widgets/AnnotationsController.js --- a/src/widgets/AnnotationsController.js Tue Sep 01 15:24:26 2015 +0200 +++ b/src/widgets/AnnotationsController.js Tue Sep 01 15:31:46 2015 +0200 @@ -15,7 +15,7 @@ display_or_write: false, starts_hidden: false, hide_without_segment: false, - segments_annotation_type: "chap" + segments_annotation_type: "chap", }; IriSP.Widgets.AnnotationsController.prototype.template = @@ -57,7 +57,17 @@ _this.player.trigger("CreateAnnotation.hide"); } }) - this.onMediaEvent("timeupdate", "onTimeUpdate") + + if(this.hide_without_segment){ + this.onMediaEvent("timeupdate", function(){ + _this.refresh(); + }) + this.onMediaEvent("settimerange", function(_timeRange){ + _this.refresh(_timeRange); + }) + this.segments = this.source.getAnnotationsByTypeTitle(this.segments_annotation_type) + this.currentSegment = false + } if (this.starts_hidden) { this.visible = true @@ -70,25 +80,53 @@ }; -IriSP.Widgets.AnnotationsController.prototype.onTimeUpdate = function(){ +IriSP.Widgets.AnnotationsController.prototype.refresh = function(_timeRange){ + _timeRange = typeof _timeRange !== 'undefined' ? _timeRange : false ; + + if(!_timeRange){ + if (this.media.getTimeRange()){ + _timeRange = this.media.getTimeRange(); + } + } + if (this.hide_without_segment){ - _currentTime = this.media.getCurrentTime() - _segmentsAnnotations = this.source.getAnnotationsByTypeTitle(this.segments_annotation_type) - _currentSegments = _segmentsAnnotations.filter(function(_segment){ - return (_currentTime >= _segment.begin && _currentTime <= _segment.end) - }); - if (_currentSegments.length == 0){ + if (!_timeRange && !this.media.getTimeRange()){ + _currentTime = this.media.getCurrentTime() + _currentSegments = this.segments.filter(function(_segment){ + return (_currentTime >= _segment.begin && _currentTime <= _segment.end) + }); + if(_currentSegments.length > 0){ + currentSegment = true; + } + else { + currentSegment = false; + } + } + else { + var _timeRangeBegin = _timeRange[0], + _timeRangeEnd = _timeRange[1]; + _currentSegments = this.segments.filter(function(_segment){ + return (_timeRangeBegin == _segment.begin && _timeRangeEnd == _segment.end) + }); + if(_currentSegments.length > 0){ + currentSegment = true; + } + else { + currentSegment = false; + } + } + if (!currentSegment && _currentSegments.length == 0){ if (this.visible){ this.hide(); - _this.player.trigger("CreateAnnotation.hide"); - _this.player.trigger("AnnotationsList.hide"); + this.player.trigger("CreateAnnotation.hide"); + this.player.trigger("AnnotationsList.hide"); } } else { if (!this.visible){ this.show(); - _this.player.trigger("CreateAnnotation.hide"); - _this.player.trigger("AnnotationsList.hide"); + this.player.trigger("CreateAnnotation.hide"); + this.player.trigger("AnnotationsList.hide"); } } } diff -r b06345320ffb -r eb77616c245f src/widgets/AnnotationsList.css --- a/src/widgets/AnnotationsList.css Tue Sep 01 15:24:26 2015 +0200 +++ b/src/widgets/AnnotationsList.css Tue Sep 01 15:31:46 2015 +0200 @@ -1,9 +1,14 @@ /* AnnotationsListWidget */ +#ui-datepicker-div +{ + display: none; +} + .Ldt-AnnotationsListWidget { border: none; margin: 0; padding: 0; overflow: auto; - max-height: 480px; + max-height: 380px; } .Ldt-AnnotationsListWidget a { text-decoration: none; diff -r b06345320ffb -r eb77616c245f src/widgets/AnnotationsList.js --- a/src/widgets/AnnotationsList.js Tue Sep 01 15:24:26 2015 +0200 +++ b/src/widgets/AnnotationsList.js Tue Sep 01 15:31:46 2015 +0200 @@ -37,8 +37,10 @@ start_visible: true, show_audio : true, show_filters : false, + show_header : false, + custom_header : false, show_creation_date : false, - show_timecode : true, + show_timecode : true, /* * Only annotation in the current segment will be displayed. Designed to work with the Segments Widget. */ @@ -71,21 +73,30 @@ IriSP.Widgets.AnnotationsList.prototype.messages = { en: { voice_annotation: "Voice Annotation", - now_playing: "Now playing..." + now_playing: "Now playing...", + everyone: "Everyone", + header: "Annotations for this content" }, fr: { voice_annotation: "Annotation Vocale", - now_playing: "Lecture en cours..." + now_playing: "Lecture en cours...", + everyone: "Tous", + header: "Annotations sur ce contenu" } }; IriSP.Widgets.AnnotationsList.prototype.template = - '
' + '{{#show_header}}

' + + '{{#custom_header}}{{custom_header}}{{/custom_header}}' + + '{{^custom_header}}{{l10n.header}}{{/custom_header}}' + + '

{{/show_header}}' + + '
' + '{{#show_filters}}' + '
' - + '' - + '' - + '' + + '' + + '' + + '' + + '' + '
' + '{{/show_filters}}' + '{{#show_audio}}
{{/show_audio}}' @@ -177,15 +188,23 @@ _list = _list.filter(function(_annotation) { return _annotation.found !== false; }); - if (this.filter_by_segments) { + + if ((this.filter_by_segments)&&(!(this.show_filters && this.ignoresegmentcheckbox_$[0].checked))) { /* * A given annotation is considered "in" segment if the middle of it is between the segment beginning and the segment end. * Note this is meant to be used for "markings" annotations (not segments) */ _segmentsAnnotation = this.currentSource.getAnnotationsByTypeTitle(this.segments_annotation_type) - _currentSegments = _segmentsAnnotation.filter(function(_segment){ - return (_currentTime >= _segment.begin && _currentTime <= _segment.end) - }); + if (this.media.getTimeRange()){ + _currentSegments = _segmentsAnnotation.filter(function(_segment){ + return (_this.media.getTimeRange()[0] == _segment.begin && _this.media.getTimeRange()[1] == _segment.end) + }); + } + else { + _currentSegments = _segmentsAnnotation.filter(function(_segment){ + return (_currentTime >= _segment.begin && _currentTime <= _segment.end) + }); + } if (_currentSegments.length == 0) { _list = _list.filter(function(_annotation){ return false; @@ -209,6 +228,7 @@ return Math.abs((_annotation.begin + _annotation.end) / 2 - _currentTime); }).slice(0, this.limit_count); } + if (this.newest_first) { _list = _list.sortBy(function(_annotation) { return -_annotation.created.valueOf(); @@ -219,6 +239,31 @@ }); } + if (this.show_filters){ + _username = this.userselect_$[0].options[this.userselect_$[0].selectedIndex].value; + if (_username != "false") + { + _list = _list.filter(function(_annotation){ + return _annotation.creator == _username + }) + } + _keyword = this.keywordinput_$[0].value; + if (_keyword != ""){ + _list = _list.filter(function(_annotation){ + return _annotation.description.toLowerCase().match(_keyword.toLowerCase()); + }); + } + + + if(this.datefilterinput_$[0].value != ""){ + _date = this.datefilterinput_$.datepicker("getDate"); + _list = _list.filter(function(_annotation){ + return ((_annotation.created.getDate() == _date.getDate())&&(_annotation.created.getMonth() == _date.getMonth())&&(_annotation.created.getFullYear() == _date.getFullYear())) + }); + } + + } + var _ids = _list.idIndex; if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds) || this.searchString !== this.lastSearch) { @@ -246,7 +291,8 @@ ); var _title = "", _description = _annotation.description, - _thumbnail = (typeof _annotation.thumbnail !== "undefined" && _annotation.thumbnail ? _annotation.thumbnail : _this.default_thumbnail); + _thumbnail = (typeof _annotation.thumbnail !== "undefined" && _annotation.thumbnail ? _annotation.thumbnail : _this.default_thumbnail) + // Update : display creator if (_annotation.creator) { _title = _annotation.creator; @@ -334,6 +380,9 @@ .mouseout(function() { _annotation.trigger("unselect"); }) + .click(function() { + _annotation.trigger("click"); + }) .appendTo(_this.list_$); IriSP.attachDndData(_el.find("[draggable]"), { title: _title, @@ -393,16 +442,20 @@ }; IriSP.Widgets.AnnotationsList.prototype.hide = function() { + var _this = this; if (this.visible){ this.visible = false; - this.widget_$.slideUp() + this.widget_$.slideUp(function(){ + _this.$.find('.Ldt-AnnotationsList-header').hide(); + }); } } IriSP.Widgets.AnnotationsList.prototype.show = function() { if(!this.visible){ this.visible = true; - this.widget_$.slideDown() + this.$.find('.Ldt-AnnotationsList-header').show(); + this.widget_$.slideDown(); } } @@ -428,7 +481,23 @@ this.list_$ = this.$.find(".Ldt-AnnotationsList-ul"); this.widget_$ = this.$.find(".Ldt-AnnotationsListWidget"); - + this.userselect_$ = this.$.find("#Ldt-AnnotationsList-userFilter"); + this.userselect_$.change(function(){ + _this.player.trigger("AnnotationsList.refresh"); + }); + this.keywordinput_$ = this.$.find("#Ldt-AnnotationsList-keywordsFilter"); + this.keywordinput_$.keyup(function(){ + _this.player.trigger("AnnotationsList.refresh"); + }); + this.ignoresegmentcheckbox_$ = this.$.find("#Ldt-AnnotationsList-ignoreSegmentsFilter"); + this.ignoresegmentcheckbox_$.click(function(){ + _this.player.trigger("AnnotationsList.refresh"); + }); + this.datefilterinput_$ = this.$.find("#Ldt-AnnotationsList-dateFilter"); + this.datefilterinput_$.datepicker({ dateFormat: 'dd/mm/yy' }); + this.datefilterinput_$.change(function(){ + _this.player.trigger("AnnotationsList.refresh") + }) this.source.getAnnotations().on("search", function(_text) { _this.searchString = _text; @@ -453,6 +522,20 @@ _this.throttledRefresh(); }); + if (this.show_filters){ + _usernames = Array(); + _list = this.getWidgetAnnotations() + _list.forEach(function(_annotation){ + if(_usernames.indexOf(_annotation.creator) == -1){ + _usernames.push(_annotation.creator); + } + }); + this.userselect_$.html(""); + _usernames.forEach(function(_user){ + _this.userselect_$.append(""); + }); + } + this.onMdpEvent("AnnotationsList.refresh", function() { if (_this.ajax_url) { if (_this.mashupMode) { @@ -484,11 +567,12 @@ this.onMdpEvent("AnnotationsList.hide", "hide"); this.onMdpEvent("AnnotationsList.show", "show"); - this.onMdpEvent("createAnnotationWidget.addedAnnotation", "refresh"); + this.onMdpEvent("createAnnotationWidget.addedAnnotation", this.throttledRefresh); var _events = [ "timeupdate", "seeked", - "loadedmetadata" + "loadedmetadata", + "settimerange" ]; for (var _i = 0; _i < _events.length; _i++) { this.onMediaEvent(_events[_i], this.throttledRefresh); diff -r b06345320ffb -r eb77616c245f src/widgets/CurrentSegmentInfobox.css --- a/src/widgets/CurrentSegmentInfobox.css Tue Sep 01 15:24:26 2015 +0200 +++ b/src/widgets/CurrentSegmentInfobox.css Tue Sep 01 15:31:46 2015 +0200 @@ -39,10 +39,90 @@ font-weight: bold; } +textarea.Ldt-CurrentSegmentInfobox-DescriptionInput.Ldt-CurrentSegmentInfobox-Description{ + display: inline-block; + width: 95%; +} + .Ldt-CurrentSegmentInfobox-Tags{ } .Ldt-CurrentSegmentInfobox-NoSegment{ font-size: 15px; font-weight: bold; +} + +.Ldt-CurrentSegmentInfobox-SubmitButton{ + display: inline-block; + background-color: #d93c71; + color: #ffffff; + float: right; + cursor: pointer; + height: 14px; + width: 100px; + margin: 2px; + margin-top: 5px; + padding: 2px; + font-size: 11px; + border: 1px solid; + border-color: #eca3bc #631e34 #36101c #e16e93; + cursor: pointer; + text-align: center; + vertical-align: middle; +} + +.Ldt-CurrentSegmentInfobox-CancelButton{ + display: inline-block; + background-color: #d93c71; + color: #ffffff; + float: right; + cursor: pointer; + height: 14px; + width: 100px; + margin: 2px; + margin-top: 5px; + margin-right: 5px; + padding: 2px; + font-size: 11px; + border: 1px solid; + border-color: #eca3bc #631e34 #36101c #e16e93; + cursor: pointer; + text-align: center; + vertical-align: middle; +} + +.Ldt-CurrentSegmentInfobox-CreateTagButton{ + display: block; + background-color: #d93c71; + color: #ffffff; + cursor: pointer; + height: 14px; + width: 75px; + margin: 2px; + padding: 2px; + font-size: 11px; + border: 1px solid; + border-color: #eca3bc #631e34 #36101c #e16e93; + cursor: pointer; + text-align: center; + vertical-align: middle; +} + +.Ldt-CurrentSegmentInfobox-Tags-Li-Input{ + width: 80px; +} + +.Ldt-CurrentSegmentInfobox-CreateTagButton:hover, .Ldt-CurrentSegmentInfobox-CancelButton:hover, +.Ldt-CurrentSegmentInfobox-SubmitButton:hover{ + background-color: #e15581; + border-color: #222222 #e87d9f #f0adc3 #68273c; +} + +.Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton{ + font-weight: bold; + color: #d93c71 +} + +.Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton:hover{ + color: #e16e93 } \ No newline at end of file diff -r b06345320ffb -r eb77616c245f src/widgets/CurrentSegmentInfobox.js --- a/src/widgets/CurrentSegmentInfobox.js Tue Sep 01 15:24:26 2015 +0200 +++ b/src/widgets/CurrentSegmentInfobox.js Tue Sep 01 15:31:46 2015 +0200 @@ -8,69 +8,263 @@ IriSP.Widgets.CurrentSegmentInfobox.prototype.defaults = { annotation_type: "chap", - readonly: true, - empty_message: false + editable_segments: false, + empty_message: false, + project_id: false, + api_serializer: "ldt_annotate", + api_method: "PUT", + api_endpoint_template: "" }; IriSP.Widgets.CurrentSegmentInfobox.prototype.template = - "
" - + "
{{title}}
" - + "
{{description}}
" - + "
" - + ' {{#tags.length}}' - + '
    ' - + ' {{#tags}}' - + ' {{#.}}' - + '
  • ' - + ' {{.}}' - + '
  • ' - + ' {{/.}}' - + ' {{/tags}}' - + '
' - + ' {{/tags.length}}' - + "
" - + "
" + '
' + + '
{{title}}
' + + '
{{description}}
' + + '
' + + '{{#tags.length}}' + + '
    ' + + '{{#tags}}' + + '{{#.}}' + + '
  • ' + + '{{.}}' + + '
  • ' + + '{{/.}}' + + '{{/tags}}' + + '
' + + '{{/tags.length}}' + + '
' + + '
' +IriSP.Widgets.CurrentSegmentInfobox.prototype.editTemplate = + '
' + + '' + + '
{{cancel}}
' + + '
{{submit}}
' + + '' + + '
' + + '
{{new_tag}}
' + + '{{#tags.length}}' + + '
    ' + + '{{#tags}}' + + '{{#.}}' + + '
  • ' + + '' + + '
    {{delete_tag}}
    ' + + '
  • ' + + '{{/.}}' + + '{{/tags}}' + + '
' + + '{{/tags.length}}' + + '
' + + '
' + IriSP.Widgets.CurrentSegmentInfobox.prototype.messages = { fr : { + submit : "Soumettre", + cancel : "Annuler", + new_tag : "Nouveau tag", + delete_tag : "Supprimer", empty : "Le player vidéo ne lit actuellement aucun segment" }, en: { - empty: "The player currently doesn't read any segment" + submit : "Submit", + cancel : "Cancel", + new_tag : "New tag", + delete_tag : "Delete tag", + empty : "The player currently doesn't read any segment" } } IriSP.Widgets.CurrentSegmentInfobox.prototype.draw = function() { var _this = this; this.segments = this.getWidgetAnnotations(); - this.renderTemplate(); + this.currentSegment = false; + this.clearBox(); this.refresh(); + this.onMediaEvent("timeupdate", "refresh"); + this.onMediaEvent("settimerange", function(_timeRange){ + var _segmentBegin = _timeRange[0], + _segmentEnd = _timeRange[1], + _list = _this.segments.filter(function(_segment){ + return _segment.begin.milliseconds == _segmentBegin.milliseconds && _segment.end.milliseconds == _segmentEnd.milliseconds + }); + if (_list.length >0){ + if (_this.currentSegment.id != _list[0].id){ + _this.currentSegment = _list[0]; + _data = { + title: _this.currentSegment.title, + description : _this.currentSegment.description, + tags : _this.currentSegment.getTagTexts() + } + _this.$.html(Mustache.to_html(_this.template, _data)) + if(_this.editable_segments&&_this.currentSegment){ + _this.$.find(".Ldt-CurrentSegmentInfobox").click(_this.functionWrapper("enableEditMode")); + } + } + } + }); - this.onMediaEvent("timeupdate", "refresh"); + if(this.editable_segments&&this.currentSegment){ + this.$.find(".Ldt-CurrentSegmentInfobox").click(_this.functionWrapper("enableEditMode")); + } +} + +IriSP.Widgets.CurrentSegmentInfobox.prototype.enableEditMode = function() { + if(this.currentSegment){ + _data = { + title: this.currentSegment.title, + description : this.currentSegment.description, + tags : this.currentSegment.getTagTexts(), + submit : this.l10n.submit, + cancel : this.l10n.cancel, + new_tag : this.l10n.new_tag, + delete_tag : this.l10n.delete_tag + } + this.$.html(Mustache.to_html(this.editTemplate, _data)); + this.$.find(".Ldt-CurrentSegmentInfobox-CancelButton").click(this.functionWrapper("disableEditMode")); + this.$.find(".Ldt-CurrentSegmentInfobox-CreateTagButton").click(this.functionWrapper("insertTagInput")); + this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton").click(this.functionWrapper("deleteTagInput")); + this.$.find(".Ldt-CurrentSegmentInfobox-SubmitButton").click(this.functionWrapper("onSubmit")) + } +} + +IriSP.Widgets.CurrentSegmentInfobox.prototype.disableEditMode = function() { + if(this.currentSegment){ + data = { + title: this.currentSegment.title, + description : this.currentSegment.description, + tags : this.currentSegment.getTagTexts() + } + this.$.html(Mustache.to_html(this.template, _data)); + this.$.find(".Ldt-CurrentSegmentInfobox").click(this.functionWrapper("enableEditMode")); + } +} + +IriSP.Widgets.CurrentSegmentInfobox.prototype.insertTagInput = function() { + if((!this.currentSegment.getTagTexts().length)&&(!this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Ul").length)){ + this.$.find(".Ldt-CurrentSegmentInfobox-Tags").prepend('') + } + this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Ul").append( + '
  • ' + +'' + +'
    '+this.l10n.delete_tag+'
    ' + +'
  • '); + this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Li-DeleteTagButton").click(this.functionWrapper("deleteTagInput")); +} + +IriSP.Widgets.CurrentSegmentInfobox.prototype.deleteTagInput = function(clickEvent) { + $(clickEvent.currentTarget).parent().remove(); +} + +IriSP.Widgets.CurrentSegmentInfobox.prototype.onSubmit = function() { + new_tags_titles = this.$.find(".Ldt-CurrentSegmentInfobox-Tags-Li-Input").map(function(){ + if($(this).val()){ + return $(this).val() + } + }); + new_title = this.$.find(".Ldt-CurrentSegmentInfobox-TitleInput").val() + new_description = this.$.find(".Ldt-CurrentSegmentInfobox-DescriptionInput").val() + + 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]}), + _annotation = new IriSP.Model.Annotation(this.currentSegment.id, _export); /* Création d'une annotation dans cette source avec un ID généré à la volée (param. false) */ + + _annotation.setAnnotationType(this.currentSegment.getAnnotationType().id); + _annotation.setMedia(this.currentSegment.getMedia().id); + _annotation.setBegin(this.currentSegment.begin); + _annotation.setEnd(this.currentSegment.end); + _annotation.created = this.currentSegment.created; + _annotation.creator = this.currentSegment.creator; + _annotation.title = new_title /* Champ titre */ + _annotation.description = new_description /* Champ description */ + var _tagIds = IriSP._(new_tags_titles).map(function(_title) { + var _tags = _this.source.getTags(true).searchByTitle(_title, true); + if (_tags.length) { + var _tag = _tags[0]; + } + else { + _tag = new IriSP.Model.Tag(_title.replace(/\W/g,'_'), _this.source); + _tag.title = _title; + _this.source.getTags().push(_tag); + } + return _tag.id; + }); + _annotation.setTags(_tagIds); + _annotation.project_id = this.project_id; + + _exportedAnnotations.push(_annotation); /* Ajout de l'annotation à la liste à exporter */ + _export.addList("annotation",_exportedAnnotations); /* Ajout de la liste à exporter à l'objet Source */ + + _url = Mustache.to_html(this.api_endpoint_template, {annotation_id: this.currentSegment.id}); + + IriSP.jQuery.ajax({ + url: _url, + type: this.api_method, + contentType: 'application/json', + data: _export.serialize(), /* L'objet Source est sérialisé */ + success: function(_data) { + _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 */ + _this.segments.forEach(function(_segment){ + if (_segment.id == _annotation.id){ + _this.segments.removeElement(_segment) + } + }) + _this.segments.push(_annotation) + _this.currentSegment = _annotation + _data = { + title: _this.currentSegment.title, + description : _this.currentSegment.description, + tags : _this.currentSegment.getTagTexts() + } + _this.$.html(Mustache.to_html(_this.template, _data)) + if(_this.editable_segments&&_this.currentSegment){ + _this.$.find(".Ldt-CurrentSegmentInfobox").click(_this.functionWrapper("enableEditMode")); + } + _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); + } + }); } IriSP.Widgets.CurrentSegmentInfobox.prototype.refresh = function() { - var _list = this.segments; - - _currentTime = this.media.getCurrentTime(); - _list = _list.filter(function(_segment){ - return (_segment.begin <= _currentTime && _segment.end >= _currentTime); - }) - if (_list.length > 0){ - _currentSegment = _list[0]; - _data = { - title: _currentSegment.title, - description : _currentSegment.description, - tags : _currentSegment.getTagTexts() + if(!this.media.getTimeRange()){ + var _currentTime = this.media.getCurrentTime(); + var _list = this.segments.filter(function(_segment){ + return (_segment.begin <= _currentTime && _segment.end >= _currentTime); + }) + + if (_list.length > 0){ + if (this.currentSegment.id != _list[0].id){ + this.currentSegment = _list[0]; + _data = { + title: this.currentSegment.title, + description : this.currentSegment.description, + tags : this.currentSegment.getTagTexts() + } + this.$.html(Mustache.to_html(this.template, _data)) + if(this.editable_segments&&this.currentSegment){ + this.$.find(".Ldt-CurrentSegmentInfobox").click(this.functionWrapper("enableEditMode")); + } + } } - this.$.html(Mustache.to_html(this.template, _data)) + else { + this.currentSegment = false; + this.clearBox(); + } } - else { - var _empty_message = this.l10n.empty - if (this.empty_message) { - _empty_message = this.empty_message - } - this.$.find(".Ldt-CurrentSegmentInfobox").html("
    "+_empty_message+"
    "); +} + +IriSP.Widgets.CurrentSegmentInfobox.prototype.clearBox = function(){ + var _empty_message = this.l10n.empty + if (this.empty_message) { + _empty_message = this.empty_message } + this.$.find(".Ldt-CurrentSegmentInfobox").html("
    "+_empty_message+"
    "); } \ No newline at end of file diff -r b06345320ffb -r eb77616c245f src/widgets/LatestAnnotation.css --- a/src/widgets/LatestAnnotation.css Tue Sep 01 15:24:26 2015 +0200 +++ b/src/widgets/LatestAnnotation.css Tue Sep 01 15:31:46 2015 +0200 @@ -25,6 +25,8 @@ } .Ldt-LatestAnnotation-Content{ + max-width: 230px; + text-align: justify; } .Ldt-LatestAnnotation-Title{ @@ -37,3 +39,26 @@ font-size: 14px; font-weight: bold; } + +.Ldt-LatestAnnotation-CopyEditButton{ + display: inline-block; + background-color: #d93c71; + color: #ffffff; + float: right; + cursor: pointer; + height: 14px; + width: 100px; + margin: 2px; + padding: 2px; + font-size: 11px; + border: 1px solid; + border-color: #eca3bc #631e34 #36101c #e16e93; + cursor: pointer; + text-align: center; + vertical-align: middle; +} + +.Ldt-LatestAnnotation-CopyEditButton:hover{ + background-color: #e15581; + border-color: #222222 #e87d9f #f0adc3 #68273c; +} \ No newline at end of file diff -r b06345320ffb -r eb77616c245f src/widgets/LatestAnnotation.js --- a/src/widgets/LatestAnnotation.js Tue Sep 01 15:24:26 2015 +0200 +++ b/src/widgets/LatestAnnotation.js Tue Sep 01 15:31:46 2015 +0200 @@ -16,31 +16,94 @@ * Set to a username if you only want to display annotations from a given user */ show_only_annotation_from_user: false, + /* + * Displays a button that copy currently displayed annotation into CreateAnnotation input field + */ + copy_and_edit_button: false, + /* + * Allows clicks on an annotation from Annotations to display the annotation content into this widget + */ + selectable_annotations: false, empty_message: false, starts_hidden: false, + show_header: false, + custom_header: false, }; +IriSP.Widgets.LatestAnnotation.prototype.messages = { + fr : { + copy_and_edit: "Copier et Editer", + empty : "Aucune annotation à afficher", + header: "Dernière annotation" + }, + en: { + copy_and_edit: "Copy and Edit", + empty: "No annotation to display", + header: "Last annotation" + } +} + IriSP.Widgets.LatestAnnotation.prototype.template = - "
    " + "{{#show_header}}" + + "

    " + + "{{#custom_header}}{{custom_header}}{{/custom_header}}" + + "{{^custom_header}}{{l10n.header}}{{/custom_header}}" + + "

    " + + "{{/show_header}}" + + "
    " + "
    "; IriSP.Widgets.LatestAnnotation.prototype.annotationTemplate = "
    " - + "
    {{{annotation_created}}}
    " - + "
    {{{annotation_creator}}}{{#annotation_title}}: {{{annotation_title}}}{{/annotation_title}}
    " - + "
    " + + "
    {{{annotation_created}}}
    " + + "
    {{{annotation_creator}}}{{#annotation_title}}: {{{annotation_title}}}{{/annotation_title}}
    " + + "
    " + "{{{annotation_content}}}" - + "
    " + + "
    " + + "{{#copy_and_edit_button}}
    {{button_text}}
    {{/copy_and_edit_button}}" + "
    " + IriSP.Widgets.LatestAnnotation.prototype.draw = function(){ var _this = this; - this.renderTemplate(); this.annotationContainer_$ = this.$.find('.Ldt-LatestAnnotation'); - this.onMediaEvent("timeupdate", "refresh"); + if (this.selectable_annotations){ + this.onMdpEvent("AnnotationsList.refresh", function(){ + _this.getWidgetAnnotations().forEach(function(_annotation){ + _annotation.off("click"); + _annotation.on("click", function(){ + _html = Mustache.to_html(_this.annotationTemplate, { + annotation_created: _annotation.created.toLocaleDateString()+", "+_annotation.created.toLocaleTimeString(), + annotation_creator: _annotation.creator, + annotation_title: _annotation.title, + annotation_content: _annotation.description, + copy_and_edit_button: _this.copy_and_edit_button, + button_text: _this.l10n.copy_and_edit, + }); + _this.annotationContainer_$.html(_html); + _this.selectedAnnotation = true; + }); + }); + }); + + this.segments = _this.source.getAnnotationsByTypeTitle(this.segments_annotation_type) + this.segments.forEach(function(_segment){ + _segment.on("click", function(){ + _this.selectedAnnotation = false; + }) + }) + this.currentSegment = false; + } + + this.onMediaEvent("timeupdate", function(){ + _this.refresh(); + }); + this.onMediaEvent("settimerange", function(_timeRange){ + _this.refresh(_timeRange); + }) if (this.starts_hidden){ this.visible = true; @@ -51,40 +114,59 @@ this.show(); } + this.selectedAnnotation = false; // This flag tells the widget if it must display last annotation (false) or clicked annotation (true) + this.player.trigger("AnnotationsList.refresh"); this.refresh(); } -IriSP.Widgets.LatestAnnotation.prototype.messages = { - fr : { - empty : "Aucune annotation à afficher" - }, - en: { - empty: "No annotation to display" - } -} -IriSP.Widgets.LatestAnnotation.prototype.refresh = function(){ - 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) - }); +IriSP.Widgets.LatestAnnotation.prototype.refresh = function(_timeRange){ + _timeRange = typeof _timeRange !== 'undefined' ? _timeRange : false ; + var _this = this; if (this.hide_without_segment){ - if (_currentSegments.length == 0){ + if (!_timeRange && !this.media.getTimeRange()){ + var _currentTime = this.media.getCurrentTime(); + var _currentSegments = this.segments.filter(function(_segment){ + return (_currentTime >= _segment.begin && _currentTime <= _segment.end) + }); + if (_currentSegments.length == 0){ + this.currentSegment = false; + this.selectedAnnotation = false; + } + else { + this.currentSegment = _currentSegments[0] + } + } + else { + var _segmentBegin = _timeRange? _timeRange[0] : this.media.getTimeRange()[0], + _segmentEnd = _timeRange? _timeRange[1] : this.media.getTimeRange()[1]; + if ((!this.currentSegment)||(this.currentSegment.begin != _segmentBegin || this.currentSegment.end != _segmentEnd)) { + var _currentSegments = this.segments.filter(function(_segment){ + return _segment.begin == _segmentBegin && _segment.end == _segmentEnd + }); + if (_currentSegments.length > 0){ + this.selectedAnnotation = false; + this.currentSegment = _currentSegments[0]; + } + } + } + if (!this.currentSegment){ if (this.visible){ - this.hide() + this.hide(); } } else { if (!this.visible){ - this.show() + this.show(); } } } - if (this.visible){ + + if (this.visible && !this.selectedAnnotation){ var _list = this.getWidgetAnnotations(); + if(this.filter_by_segment){ - if (_currentSegments.length == 0) { + if (!this.currentSegment) { _list = _list.filter(function(_annotation){ return false; }); @@ -92,40 +174,56 @@ else { _list = _list.filter(function(_annotation){ _annotationTime = (_annotation.begin+_annotation.end)/2; - return (_currentSegments[0].begin <= _annotationTime && _currentSegments[0].end >= _annotationTime); + return (_this.currentSegment.begin <= _annotationTime && _this.currentSegment.end >= _annotationTime); }); } - _list.sortBy(function(_annotation){ - return _annotation.created; + } + _list = _list.sortBy(function(_annotation){ + return _annotation.created; + }); + + var _latestAnnotation = false; + var _html=""; + if (_list.length != 0){ + _latestAnnotation = _list.pop(); + _html = Mustache.to_html(this.annotationTemplate, { + annotation_created: _latestAnnotation.created.toLocaleDateString()+", "+_latestAnnotation.created.toLocaleTimeString(), + annotation_creator: _latestAnnotation.creator, + annotation_title: _latestAnnotation.title, + annotation_content: _latestAnnotation.description, + copy_and_edit_button: this.copy_and_edit_button, + button_text: this.l10n.copy_and_edit, }); - - var _latestAnnotation = false; - var _html=""; - if (_list.length != 0){ - _latestAnnotation = _list.pop(); - _html = Mustache.to_html(this.annotationTemplate, { - annotation_created: _latestAnnotation.created.toLocaleDateString()+", "+_latestAnnotation.created.toLocaleTimeString(), - annotation_creator: _latestAnnotation.creator, - annotation_title: _latestAnnotation.title, - annotation_content: _latestAnnotation.description, - }); + } + else { + var _empty_message = this.l10n.empty + if (this.empty_message) { + _empty_message = this.empty_message } - else { - var _empty_message = this.l10n.empty - if (this.empty_message) { - _empty_message = this.empty_message - } - _html = "
    "+_empty_message+"
    "; - } - this.annotationContainer_$.html(_html); - + _html = "
    "+_empty_message+"
    "; } + this.annotationContainer_$.html(_html); } + + if(this.copy_and_edit_button){ + this.copyAndEditButton_$ = this.$.find('.Ldt-LatestAnnotation-CopyEditButton'); + this.copyAndEditButton_$.click(this.functionWrapper("copy_and_edit")); + } +} + +IriSP.Widgets.LatestAnnotation.prototype.copy_and_edit = function(){ + this.player.trigger("CreateAnnotation.show"); + this.player.trigger("AnnotationsList.hide"); + annotationText = $('.Ldt-LatestAnnotation-Content').get(0).innerHTML; + + $('.Ldt-CreateAnnotation-Description').removeClass('empty'); + $('.Ldt-CreateAnnotation-Description').val(annotationText); } IriSP.Widgets.LatestAnnotation.prototype.hide = function() { if (this.visible){ this.visible = false; + this.$.find('.Ldt-LatestAnnotation-header').hide(); this.annotationContainer_$.hide() } } @@ -133,6 +231,7 @@ IriSP.Widgets.LatestAnnotation.prototype.show = function() { if(!this.visible){ this.visible = true; + this.$.find('.Ldt-LatestAnnotation-header').show(); this.annotationContainer_$.show() } } diff -r b06345320ffb -r eb77616c245f src/widgets/img/loader.gif Binary file src/widgets/img/loader.gif has changed