# HG changeset patch # User veltr # Date 1338390421 -7200 # Node ID f56199193fad5370c134f7c545c1cd3507c470e2 # Parent 4b6e154ae8de1e5f5cd6b7e6dbdd2aff496173d0 CreateAnnotation widget now posts annotations, Tagcloud can be made segment-dependent diff -r 4b6e154ae8de -r f56199193fad src/js/init.js --- a/src/js/init.js Tue May 22 16:49:48 2012 +0200 +++ b/src/js/init.js Wed May 30 17:07:01 2012 +0200 @@ -19,11 +19,35 @@ this.video_metadata = video_metadata; this.sourceManager = new IriSP.Model.Directory(); this.config = config; + this.callbackQueue = []; + this.isLoaded = false; this.loadLibs(); } IriSP.Metadataplayer.prototype.toString = function() { - return 'A Metadataplayer in DIV #' + this.config.gui.container; + return 'Metadataplayer in #' + this.config.gui.container; +} + +IriSP.Metadataplayer.prototype.deferCallback = function(_callback) { + var _this = this; + IriSP._.defer(function() { + _callback.call(_this); + }); +} + +IriSP.Metadataplayer.prototype.handleCallbacks = function() { + this.isLoaded = true; + while (this.callbackQueue.length) { + this.deferCallback(this.callbackQueue.splice(0,1)[0]); + } +} + +IriSP.Metadataplayer.prototype.onLoad = function(_callback) { + if (this.isLoaded) { + this.deferCallback(_callback); + } else { + this.callbackQueue.push(_callback); + } } IriSP.Metadataplayer.prototype.loadLibs = function() { @@ -121,6 +145,7 @@ }); }; this.$.find('.Ldt-Loader').detach(); + this.handleCallbacks(); } IriSP.Metadataplayer.prototype.loadWidget = function(_widgetConfig, _callback) { diff -r 4b6e154ae8de -r f56199193fad src/js/model.js --- a/src/js/model.js Tue May 22 16:49:48 2012 +0200 +++ b/src/js/model.js Wed May 30 17:07:01 2012 +0200 @@ -210,26 +210,33 @@ }); } -IriSP.Model.List.prototype.removeId = function(_id) { - var _index = (IriSP._(this.idIndex).indexOf(_id)); +IriSP.Model.List.prototype.removeId = function(_id, _deleteFromDirectory) { + var _deleteFromDirectory = _deleteFromDirectory || false, + _index = (IriSP._(this.idIndex).indexOf(_id)); if (_index !== -1) { this.splice(_index,1); } + if (_deleteFromDirectory) { + delete this.directory.elements[_id]; + } } -IriSP.Model.List.prototype.removeElement = function(_el) { +IriSP.Model.List.prototype.removeElement = function(_el, _deleteFromDirectory) { + var _deleteFromDirectory = _deleteFromDirectory || false; this.removeId(_el.id); } -IriSP.Model.List.prototype.removeIds = function(_list) { - var _this = this; +IriSP.Model.List.prototype.removeIds = function(_list, _deleteFromDirectory) { + var _deleteFromDirectory = _deleteFromDirectory || false, + _this = this; IriSP._(_list).forEach(function(_id) { _this.removeId(_id); }); } -IriSP.Model.List.prototype.removeElements = function(_list) { - var _this = this; +IriSP.Model.List.prototype.removeElements = function(_list, _deleteFromDirectory) { + var _deleteFromDirectory = _deleteFromDirectory || false, + _this = this; IriSP._(_list).forEach(function(_el) { _this.removeElement(_el); }); @@ -785,6 +792,13 @@ } } +IriSP.Model.Source.prototype.merge = function(_source) { + var _this = this; + _source.forEach(function(_value, _key) { + _this.getList(_key).addElements(_value); + }); +} + /* */ IriSP.Model.RemoteSource = function(_config) { diff -r 4b6e154ae8de -r f56199193fad src/js/serializers/PlatformAnnotateSerializer.js --- a/src/js/serializers/PlatformAnnotateSerializer.js Tue May 22 16:49:48 2012 +0200 +++ b/src/js/serializers/PlatformAnnotateSerializer.js Wed May 30 17:07:01 2012 +0200 @@ -39,5 +39,47 @@ created: _source.created } return JSON.stringify(_res); + }, + deSerialize : function(_data, _source) { + if (typeof _data == "string") { + _data = JSON.parse(_data); + } + _source.addList('tag', new IriSP.Model.List(_source.directory)); + _source.addList('annotationType', new IriSP.Model.List(_source.directory)); + _source.addList('annotation', new IriSP.Model.List(_source.directory)); + if (typeof _data.annotations == "object" && _data.annotations && _data.annotations.length) { + var _anndata = _data.annotations[0], + _ann = new IriSP.Model.Annotation(_anndata.id, _source); + _ann.title = _anndata.content.title || ""; + _ann.description = _anndata.content.data || ""; + _ann.created = new Date(_data.meta.created); + _ann.setMedia(_anndata.media, _source); + var _anntypes = _source.getAnnotationTypes(true).searchByTitle(_anndata.type_title); + if (_anntypes.length) { + var _anntype = _anntypes[0]; + } else { + var _anntype = new IriSP.Model.AnnotationType(_anndata.type, _source); + _anntype.title = _anndata.type_title; + _source.getAnnotationTypes().push(_anntype); + } + _ann.setAnnotationType(_anntype.id); + var _tagIds = IriSP._(_anndata.tags).map(function(_title) { + var _tags = _source.getTags(true).searchByTitle(_title); + if (_tags.length) { + var _tag = _tags[0]; + } + else { + _tag = new IriSP.Model.Tag(_title.replace(/\W/g,'_'),_source); + _tag.title = _title; + _source.getTags().push(_tag); + } + return _tag.id; + }); + _ann.setTags(_tagIds); + _ann.setBegin(_anndata.begin); + _ann.setEnd(_anndata.end); + _ann.creator = _data.meta.creator; + _source.getAnnotations().push(_ann); + } } } \ No newline at end of file diff -r 4b6e154ae8de -r f56199193fad src/js/serializers/PlatformSerializer.js --- a/src/js/serializers/PlatformSerializer.js Tue May 22 16:49:48 2012 +0200 +++ b/src/js/serializers/PlatformSerializer.js Wed May 30 17:07:01 2012 +0200 @@ -89,7 +89,7 @@ } _res.color = '#' + _c; } - _res.setMedia(_data.media, _source); + _res.setMedia(_data.media); _res.setAnnotationType(_data.meta["id-ref"]); _res.setTags(IriSP._(_data.tags).pluck("id-ref")); _res.setBegin(_data.begin); diff -r 4b6e154ae8de -r f56199193fad src/js/widgets.js --- a/src/js/widgets.js Tue May 22 16:49:48 2012 +0200 +++ b/src/js/widgets.js Wed May 30 17:07:01 2012 +0200 @@ -110,10 +110,4 @@ */ IriSP.Widgets.Widget.prototype.draw = function() { /* implemented by "sub-classes" */ -}; -/** - * Optional method if you want your widget to support redraws. - */ -IriSP.Widgets.Widget.prototype.redraw = function() { - /* implemented by "sub-classes" */ -}; +}; \ No newline at end of file diff -r 4b6e154ae8de -r f56199193fad src/widgets/AnnotationsList.js --- a/src/widgets/AnnotationsList.js Tue May 22 16:49:48 2012 +0200 +++ b/src/widgets/AnnotationsList.js Wed May 30 17:07:01 2012 +0200 @@ -234,6 +234,7 @@ this.bindPopcorn("IriSP.search", "onSearch"); this.bindPopcorn("IriSP.search.closed", "onSearch"); this.bindPopcorn("IriSP.search.cleared", "onSearch"); + this.bindPopcorn("IriSP.AnnotationsList.refresh","refresh"); var _this = this; diff -r 4b6e154ae8de -r f56199193fad src/widgets/CreateAnnotation.css --- a/src/widgets/CreateAnnotation.css Tue May 22 16:49:48 2012 +0200 +++ b/src/widgets/CreateAnnotation.css Wed May 30 17:07:01 2012 +0200 @@ -14,7 +14,6 @@ background: url(img/pinstripe.png); padding: 5px; margin: 0; - min-height: 150px; } .Ldt-CreateAnnotation-Inner h3 { @@ -23,6 +22,10 @@ font-weight: bold; } +.Ldt-CreateAnnotation-Main { + min-height: 150px; +} + .Ldt-CreateAnnotation-Title { margin-right: 2px; font-size: 14px; @@ -133,4 +136,23 @@ li.Ldt-CreateAnnotation-PolemicLi.selected { background-position: 0 -46px; +} + +.Ldt-CreateAnnotation-InnerBox { + margin: 20px 50px; + border: 1px solid #CCCCCC; + padding: 20px; + background: #FFFFFF; + color: #FF3B77; text-align: center; + font-size: 13px; font-weight: bold; +} + +a.Ldt-CreateAnnotation-Close { + position: absolute; top: 2px; right: 2px; + display: inline-block; width: 17px; height: 17px; margin: 2px; + background: url(img/widget-control.png); +} + +a.Ldt-CreateAnnotation-Close:hover { + background-position: -17px 0; } \ No newline at end of file diff -r 4b6e154ae8de -r f56199193fad src/widgets/CreateAnnotation.js --- a/src/widgets/CreateAnnotation.js Tue May 22 16:49:48 2012 +0200 +++ b/src/widgets/CreateAnnotation.js Wed May 30 17:07:01 2012 +0200 @@ -1,3 +1,5 @@ +/* TODO: Add Social Network Sharing and from field */ + IriSP.Widgets.CreateAnnotation = function(player, config) { IriSP.Widgets.Widget.call(this, player, config); this.lastAnnotation = false; @@ -7,7 +9,8 @@ IriSP.Widgets.CreateAnnotation.prototype.defaults = { show_title_field : false, - user_avatar : "https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png", + creator_name : "", + creator_avatar : "https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png", tags : false, max_tags : 8, polemics : [{ @@ -28,35 +31,10 @@ text_color: "#000000" }], annotation_type: "Contributions", - creator_name: "", - api_serializer: "ldt_annotate" -/* - - remote_tags : false, - random_tags : false, - show_from_field : false, - disable_share : false, - polemic_mode : true, // enable polemics - polemics : [{ - className: "positive", - keyword: "++" - }, { - className: "negative", - keyword: "--" - }, { - className: "reference", - keyword: "==" - }, { - className: "question", - keyword: "??" - }], - cinecast_version : false, // put to false to enable the platform version, true for the festival cinecast one. - - // where does the widget PUT the annotations - this is a mustache template. id refers to the id of the media and is filled by the widget. - - api_endpoint_template : "", // platform_url + "/ldtplatform/api/ldt/annotations/{{id}}.json", - api_method : "PUT" - */ + api_serializer: "ldt_annotate", + api_endpoint_template: "", + api_method: "PUT", + close_widget_timeout: 0 } IriSP.Widgets.CreateAnnotation.prototype.messages = { @@ -77,7 +55,8 @@ share_annotation: "Would you like to share it on social networks ?", share_on: "Share on", more_tags: "More tags", - cancel: "Cancel" + cancel: "Cancel", + close_widget: "Cacher la zone de création d'annotations" }, fr: { from_time: "de", @@ -96,7 +75,8 @@ share_annotation: "Souhaitez-vous la partager sur les réseaux sociaux ?", share_on: "Partager sur", more_tags: "Plus de mots-clés", - cancel: "Cancel" + cancel: "Cancel", + close_widget: "Hide the annotation creating block" } } @@ -108,14 +88,17 @@ + ' {{l10n.from_time}} ' + ' {{l10n.to_time}} ' + '' - + '
' + + '
' + '' + '{{#tags.length}}
{{l10n.add_keywords_}}
{{/tags.length}}' + '{{#polemics.length}}
{{l10n.add_polemic_keywords_}}
{{/polemics.length}}' - + '' - + '
'; + + '
' + + '
{{l10n.wait_while_processing}}
' + + '
{{l10n.error_while_contacting}}
' + + '
{{l10n.annotation_saved}}
' + + ''; IriSP.Widgets.CreateAnnotation.prototype.draw = function() { if (!this.tags) { @@ -129,8 +112,12 @@ }); // We have to use the map function because Mustache doesn't like our tags object } + var _this = this; this.renderTemplate(); - var _this = this; + this.$.find(".Ldt-CreateAnnotation-Close").click(function() { + _this.hide(); + return false; + }); this.$.find(".Ldt-CreateAnnotation-TagLi, .Ldt-CreateAnnotation-PolemicLi").click(function() { _this.addKeyword(IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,'')); return false; @@ -149,8 +136,17 @@ this.$.find("form").submit(this.functionWrapper("onSubmit")); } +IriSP.Widgets.CreateAnnotation.prototype.showScreen = function(_screenName) { + this.$.find('.Ldt-CreateAnnotation-' + _screenName).show() + .siblings().hide(); +} + IriSP.Widgets.CreateAnnotation.prototype.show = function() { this.visible = true; + this.showScreen('Main'); + this.$.find(".Ldt-CreateAnnotation-Description").val("").css("border-color", "#666666"); + this.$.find(".Ldt-CreateAnnotation-Title").val("").css("border-color", "#666666"); + this.$.find(".Ldt-CreateAnnotation-TagLi, .Ldt-CreateAnnotation-PolemicLi").removeClass("selected"); this.$.slideDown(); this.player.popcorn.trigger("IriSP.Annotation.minimize"); this.player.popcorn.trigger("IriSP.Slice.show"); @@ -172,8 +168,8 @@ } IriSP.Widgets.CreateAnnotation.prototype.onBoundsChanged = function(_values) { - this.begin = new IriSP.Model.Time(_values[0]); - this.end = new IriSP.Model.Time(_values[1]); + this.begin = new IriSP.Model.Time(_values[0] || 0); + this.end = new IriSP.Model.Time(_values[1] || 0); this.$.find(".Ldt-CreateAnnotation-Begin").html(this.begin.toString()); this.$.find(".Ldt-CreateAnnotation-End").html(this.end.toString()); } @@ -193,7 +189,7 @@ IriSP.Widgets.CreateAnnotation.prototype.onDescriptionChange = function() { var _field = this.$.find(".Ldt-CreateAnnotation-Description"), _contents = _field.val(); - _field.css("border-color", !!_contents ? "#666666" : "#c00000"); + _field.css("border-color", !!_contents ? "#666666" : "#ff0000"); this.$.find(".Ldt-CreateAnnotation-TagLi, .Ldt-CreateAnnotation-PolemicLi").each(function() { var _rx = IriSP.Model.regexpFromTextOrArray(IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,'')); if (_rx.test(_contents)) { @@ -208,7 +204,7 @@ IriSP.Widgets.CreateAnnotation.prototype.onTitleChange = function() { var _field = this.$.find(".Ldt-CreateAnnotation-Title"), _contents = _field.val(); - _field.css("border-color", !!_contents ? "#666666" : "#c00000"); + _field.css("border-color", !!_contents ? "#666666" : "#ff0000"); return !!_contents; } @@ -220,7 +216,8 @@ var _exportedAnnotations = new IriSP.Model.List(this.player.sourceManager); _export = this.player.sourceManager.newLocalSource({serializer: IriSP.serializers[this.api_serializer]}), _annotation = new IriSP.Model.Annotation(false, _export), - _annotationType = new IriSP.Model.AnnotationType(false, _export); + _annotationType = new IriSP.Model.AnnotationType(false, _export), + _url = Mustache.to_html(this.api_endpoint_template, {id: this.source.projectId}); _annotationType.title = this.annotation_type; _annotation.setBegin(this.begin); @@ -234,84 +231,38 @@ _annotation.description = this.$.find(".Ldt-CreateAnnotation-Description").val(); _annotation.setTags(this.$.find(".Ldt-CreateAnnotation-TagLi.selected").map(function() { return IriSP.jQuery(this).attr("tag-id")})); - _export.creator = this.creator; + _export.creator = this.creator_name; _export.created = new Date(); _exportedAnnotations.push(_annotation); _export.addList("annotation",_exportedAnnotations); - console.log(_export.serialize()); + + var _this = this; + IriSP.jQuery.ajax({ + url: _url, + type: this.api_method, + contentType: 'application/json', + data: _export.serialize(), + success: function(_data) { + _this.showScreen('Saved'); + if (_this.close_widget_timeout) { + window.setTimeout(_this.functionWrapper("hide"),_this.close_widget_timeout); + } + _export.getAnnotations().removeElement(_annotation, true); + _export.deSerialize(_data); + _this.source.merge(_export); + _this.player.popcorn.trigger("IriSP.AnnotationsList.refresh"); + }, + error: function(_xhr, _error, _thrown) { + IriSP.log("Error when sending annotation", _thrown); + _this.showScreen('Error'); + window.setTimeout(function(){ + _this.showScreen("Main") + }, + (_this.close_widget_timeout || 5000)); + } + }); + this.showScreen('Wait'); return false; } - -/* - + '
' - + '
' - + '
' - + '
' - + ' {{^cinecast_version}}
' - + ' {{/cinecast_version}}' - + '
' - + '
' - + ' {{#show_from_field}}' - + ' ' - + ' {{/show_from_field}}' - + ' ' - + '
' - + ' {{^user_avatar}} ' - + ' {{/user_avatar}}' - + ' {{#user_avatar}} ' - + ' {{/user_avatar}}' - + '
' - + '
' - + '
' - + ' ' - + ' {{#tags.length}}' - + '
' - + ' ' - + ' ' - + '
' - + ' {{#random_tags}}' - + ' ' - + ' {{/random_tags}}' - + ' {{/tags.length}}' - + ' {{#polemic_mode}}' - + ' {{#polemics.length}}' - + '
' - + ' ' - + ' ' - + '
' - + ' {{/polemics.length}}' - + ' {{/polemic_mode}}' - + '
' - + ' ' - + ' ' - + ' ' - + '
' -*/ diff -r 4b6e154ae8de -r f56199193fad src/widgets/Tagcloud.js --- a/src/widgets/Tagcloud.js Tue May 22 16:49:48 2012 +0200 +++ b/src/widgets/Tagcloud.js Wed May 30 17:07:01 2012 +0200 @@ -13,11 +13,13 @@ IriSP.Widgets.Tagcloud.prototype.defaults = { include_titles: true, include_descriptions: true, + include_tag_texts: true, tag_count: 30, stopword_language: "fr", custom_stopwords: [], exclude_pattern: false, annotation_type: false, + segment_annotation_type: false, min_font_size: 10, max_font_size: 26 } @@ -37,13 +39,51 @@ } IriSP.Widgets.Tagcloud.prototype.draw = function() { + this.bindPopcorn("IriSP.search", "onSearch"); + this.bindPopcorn("IriSP.search.closed", "onSearch"); + this.bindPopcorn("IriSP.search.cleared", "onSearch"); + if (this.segment_annotation_type) { + this.bindPopcorn("timeupdate","onTimeupdate"); + } else { + this.redraw(); + } +} + +IriSP.Widgets.Tagcloud.prototype.onTimeupdate = function() { + var _time = Math.floor(this.player.popcorn.currentTime() * 1000), + _list = this.source.getAnnotationsByTypeTitle(this.segment_annotation_type).filter(function(_annotation) { + return _annotation.begin <= _time && _annotation.end > _time; + }); + if (_list.length) { + if (_list[0].begin !== this.begin_time || _list[0].end !== this.end_time) { + this.begin_time = _list[0].begin; + this.end_time = _list[0].end; + this.redraw(); + } + } +} + +IriSP.Widgets.Tagcloud.prototype.redraw = function() { var _urlRegExp = /https?:\/\/[0-9a-zA-Z\.%\/-_]+/g, _regexpword = /[^\s\.&;,'"!\?\d\(\)\+\[\]\\\…\-«»:\/]{3,}/g, _words = {}, - _this = this; - this.getWidgetAnnotations().forEach(function(_annotation) { - var _txt = (_this.include_titles ? _annotation.title : '') + ' ' + (_this.include_descriptions ? _annotation.description : ''); + _this = this, + _annotations = this.getWidgetAnnotations(); + + if (typeof this.begin_time !== "undefined" && typeof this.end_time !== "undefined") { + _annotations = _annotations.filter(function(_annotation) { + return _annotation.begin >= _this.begin_time && _annotation.end <= _this.end_time; + }) + } + + _annotations.forEach(function(_annotation) { + var _txt = + (_this.include_titles ? _annotation.title : '') + + ' ' + + (_this.include_descriptions ? _annotation.description : '') + + ' ' + + (_this.include_tag_texts ? _annotation.getTagTexts() : ''); IriSP._(_txt.toLowerCase().replace(_urlRegExp, '').match(_regexpword)).each(function(_word) { if (IriSP._(_this.stopwords).indexOf(_word) == -1 && (!_this.exclude_pattern || !_this.exclude_pattern.test(_word))) { _words[_word] = 1 + (_words[_word] || 0); @@ -66,25 +106,20 @@ }) .first(this.tag_count) .value(); - if (!_words.length) { - return; + if (_words.length) { + var _max = _words[0].count, + _min = Math.min(_words[_words.length - 1].count, _max - 1), + _scale = (this.max_font_size - this.min_font_size) / Math.sqrt(_max - _min); + IriSP._(_words).each(function(_word) { + _word.size = Math.floor( _this.min_font_size + _scale * Math.sqrt(_word.count - _min) ); + }); } - var _max = _words[0].count, - _min = Math.min(_words[_words.length - 1].count, _max - 1), - _scale = (this.max_font_size - this.min_font_size) / Math.sqrt(_max - _min); - IriSP._(_words).each(function(_word) { - _word.size = Math.floor( _this.min_font_size + _scale * Math.sqrt(_word.count - _min) ); - }); - this.words = _words; - this.renderTemplate(); - this.$words = this.$.find(".Ldt-Tagcloud-item"); - this.$words.click(function() { + this.$.html(Mustache.to_html(this.template, {words: _words })); + this.$.find(".Ldt-Tagcloud-item").click(function() { var _txt = IriSP.jQuery(this).attr("content"); _this.player.popcorn.trigger("IriSP.search.triggeredSearch", _txt); }); - this.bindPopcorn("IriSP.search", "onSearch"); - this.bindPopcorn("IriSP.search.closed", "onSearch"); - this.bindPopcorn("IriSP.search.cleared", "onSearch"); + } IriSP.Widgets.Tagcloud.prototype.onSearch = function(searchString) { @@ -92,7 +127,7 @@ if (searchString) { var _rgxp = IriSP.Model.regexpFromTextOrArray(searchString); } - this.$words.each(function() { + this.$.find(".Ldt-Tagcloud-item").each(function() { var _el = IriSP.jQuery(this), _txt = _el.attr("content"); if (searchString) { diff -r 4b6e154ae8de -r f56199193fad test/json/return-data.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/json/return-data.json Wed May 30 17:07:01 2012 +0200 @@ -0,0 +1,22 @@ +{ + "meta": { + "creator": "admin", + "created": "Tue May 29 2012 18:05:31 GMT+0200 (Romance Daylight Time)" + }, + "annotations": [ + { + "begin": 0, + "end": 290685, + "tags": [ + "#amateur" + ], + "media": "9a493932-3053-11e0-862b-00145ea49a02", + "content": { + "data": "Test d'annotation #amateur ++" + }, + "type_title": "Contributions", + "type": "c_1e2d0340-a9a8-11e1-9466-08002791f1b7", + "id": "s_1e2e3f4e-a9a8-11e1-9466-08002791f1b7" + } + ] +} \ No newline at end of file diff -r 4b6e154ae8de -r f56199193fad test/jwplayer.htm --- a/test/jwplayer.htm Tue May 22 16:49:48 2012 +0200 +++ b/test/jwplayer.htm Wed May 30 17:07:01 2012 +0200 @@ -14,8 +14,59 @@