# HG changeset patch # User veltr # Date 1326736230 -3600 # Node ID 404f876827adb522501e116dc521e0ef3828718d # Parent b1e2dfc7a74077dfcbf38df68ad0a1d63d3f539c# Parent 492d3c8d776ab2ca1b95e7197f6ba7edeb9c4dec Merge with 492d3c8d776ab2ca1b95e7197f6ba7edeb9c4dec diff -r b1e2dfc7a740 -r 404f876827ad src/js/serializers/JSONSerializer.js --- a/src/js/serializers/JSONSerializer.js Mon Jan 16 18:49:45 2012 +0100 +++ b/src/js/serializers/JSONSerializer.js Mon Jan 16 18:50:30 2012 +0100 @@ -274,36 +274,89 @@ /** returns a list of ids of tweet lines (aka: groups in cinelab) */ IriSP.JSONSerializer.prototype.getTweetIds = function() { - if (typeof(this._data.lists) === "undefined" || this._data.lists === null) + if (IriSP.null_or_undefined(this._data.lists) || IriSP.null_or_undefined(this._data.lists) || + IriSP.null_or_undefined(this._data.views) || IriSP.null_or_undefined(this._data.views[0])) return []; - var tweetsId = []; - - /* first get the list containing the tweets */ - var tweets = IriSP.underscore.filter(this._data.lists, function(entry) { return entry.id.indexOf("tweet") !== -1 }); - if (tweets.length === 0) - return []; + /* Get the displayable types + We've got to jump through a few hoops because the json sometimes defines + fields with underscores and sometimes with dashes + */ + var annotation_types = this._data.views[0]["annotation_types"]; + if (IriSP.null_or_undefined(annotation_types)) { + annotation_types = this._data.views[0]["annotation-types"]; + if (IriSP.null_or_undefined(annotation_types)) { + console.log("neither view.annotation_types nor view.annotation-types are defined"); + return; + } + } + + var available_types = this._data["annotation_types"]; + if (IriSP.null_or_undefined(available_types)) { + available_types = this._data["annotation-types"]; + if (IriSP.null_or_undefined(available_types)) { + console.log("neither annotation_types nor annotation-types are defined"); + return; + } + } - // FIXME: collect tweets from multiple sources ? - tweetsId = IriSP.underscore.pluck(tweets[0].items, "id-ref"); - + var potential_types = []; + + // Get the list of types which contain "Tw" in their content + for (var i = 0; i < available_types.length; i++) { + if (/Tw/i.test(available_types[i]["dc:title"])) { + potential_types.push(available_types[i].id); + } + } + + // Get the intersection of both. + var tweetsId = IriSP.underscore.intersection(annotation_types, potential_types); + return tweetsId; }; /** this function returns a list of lines which are not tweet lines */ IriSP.JSONSerializer.prototype.getNonTweetIds = function() { - if (typeof(this._data.lists) === "undefined" || this._data.lists === null) + if (IriSP.null_or_undefined(this._data.lists) || IriSP.null_or_undefined(this._data.lists) || + IriSP.null_or_undefined(this._data.views) || IriSP.null_or_undefined(this._data.views[0])) return []; - - /* complicated : for each list in this._data.lists, get the id-ref. - flatten the returned array because pluck returns a string afterwards. + + /* Get the displayable types + We've got to jump through a few hoops because the json sometimes defines + fields with underscores and sometimes with dashes */ - var ids = IriSP.underscore.flatten(IriSP.underscore.map(this._data.lists, function(entry) { - return IriSP.underscore.pluck(entry.items, "id-ref"); })); - - var illegal_values = this.getTweetIds(); - return IriSP.underscore.difference(ids, illegal_values); + var annotation_types = this._data.views[0]["annotation_types"]; + if (IriSP.null_or_undefined(annotation_types)) { + annotation_types = this._data.views[0]["annotation-types"]; + if (IriSP.null_or_undefined(annotation_types)) { + console.log("neither view.annotation_types nor view.annotation-types are defined"); + return; + } + } + + var available_types = this._data["annotation_types"]; + if (IriSP.null_or_undefined(available_types)) { + available_types = this._data["annotation-types"]; + if (IriSP.null_or_undefined(available_types)) { + console.log("neither annotation_types nor annotation-types are defined"); + return; + } + } + + var potential_types = []; + + // Get the list of types which do not contain "Tw" in their content + for (var i = 0; i < available_types.length; i++) { + if (!(/Tw/i.test(available_types[i]["dc:title"]))) { + potential_types.push(available_types[i].id); + } + } + + // Get the intersection of both. + var nonTweetsId = IriSP.underscore.intersection(annotation_types, potential_types); + + return nonTweetsId; }; diff -r b1e2dfc7a740 -r 404f876827ad src/js/site.js.templ --- a/src/js/site.js.templ Mon Jan 16 18:49:45 2012 +0100 +++ b/src/js/site.js.templ Mon Jan 16 18:50:30 2012 +0100 @@ -44,6 +44,9 @@ keywords: ["#faux-raccord", "#mot-clef"], cinecast_version: true /* put to false to enable the platform version, true for the festival cinecast one. */ }, + "SparkLineWidget" : { + column_width: 10 // the width of a column in pixels. + }, "Main" : { autoplay: true } diff -r b1e2dfc7a740 -r 404f876827ad src/js/utils.js --- a/src/js/utils.js Mon Jan 16 18:49:45 2012 +0100 +++ b/src/js/utils.js Mon Jan 16 18:50:30 2012 +0100 @@ -101,16 +101,14 @@ // conversion de couleur Decimal vers HexaDecimal || 000 si fff IriSP.DEC_HEXA_COLOR = function (dec) { - var hexa='0123456789ABCDEF'; - var hex=''; - var tmp; - while (dec>15){ - tmp = dec-(Math.floor(dec/16))*16; - hex = hexa.charAt(tmp)+hex; - dec = Math.floor(dec/16); - } - hex = hexa.charAt(dec)+hex; - return(hex); + var val = +dec; + var str = val.toString(16); + var zeroes = ""; + if (str.length < 6) { + for (var i = 0; i < 6 - str.length; i++) + zeroes += "0"; + } + return zeroes + str; }; /* shortcut to have global variables in templates */ @@ -148,6 +146,10 @@ return ""; }; +/** test if a value is null or undefined */ +IriSP.null_or_undefined = function(val) { + return (typeof(val) === "undefined" || val === null); +} /* for ie compatibility if (Object.prototype.__defineGetter__&&!Object.defineProperty) { Object.defineProperty=function(obj,prop,desc) { diff -r b1e2dfc7a740 -r 404f876827ad src/js/widgets/annotationsListWidget.js --- a/src/js/widgets/annotationsListWidget.js Mon Jan 16 18:49:45 2012 +0100 +++ b/src/js/widgets/annotationsListWidget.js Mon Jan 16 18:50:30 2012 +0100 @@ -60,7 +60,7 @@ } var idList = IriSP.underscore.pluck(list, "id").sort(); - + if (idList.length !== this.__oldList.length) { this.do_redraw(list); } @@ -91,7 +91,7 @@ IriSP.AnnotationsListWidget.prototype.draw = function() { this.drawList(); - this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, function() { this.redraw(true); })); + this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, function() { this.drawList(true); })); this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.redraw)); }; diff -r b1e2dfc7a740 -r 404f876827ad src/js/widgets/createAnnotationWidget.js --- a/src/js/widgets/createAnnotationWidget.js Mon Jan 16 18:49:45 2012 +0100 +++ b/src/js/widgets/createAnnotationWidget.js Mon Jan 16 18:50:30 2012 +0100 @@ -270,11 +270,11 @@ annotation["end"] = this._currentAnnotation.end; } } else { - var duration = +this._serializer.currentMedia().meta["dc:duration"]; - annotation["begin"] = +((duration * (this.sliceLeft / 100)).toFixed(0)); - annotation["end"] = +((duration * ((this.sliceWidth + this.sliceLeft) / 100)).toFixed(0)); + var duration = +this._serializer.currentMedia().meta["dc:duration"]; + annotation["begin"] = +((duration * (this.sliceLeft / this.selector.width())).toFixed(0)); + annotation["end"] = +((duration * ((this.sliceWidth + this.sliceLeft) / this.selector.width())).toFixed(0)); } - + annotation["type"] = this._serializer.getContributions(); if (typeof(annotation["type"]) === "undefined") annotation["type"] = ""; @@ -318,7 +318,6 @@ console.log(tmp_view); this._serializer._data["annotation-types"].push(tmp_view); } - annotation["type"] = ""; delete annotation.tags; annotation.content.description = annotation.content.data; @@ -327,11 +326,12 @@ annotation.id = json.annotations[0].id; annotation.meta = meta; - annotation.meta["id-ref"] = annotation["type"]; + annotation.meta["id-ref"] = json.annotations[0]["type"]; + // everything is shared so there's no need to propagate the change _this._serializer._data.annotations.push(annotation); console.log(_this._serializer._data); - _this._Popcorn.trigger("IriSP.createAnnotationWidget.addedAnnotation"); + _this._Popcorn.trigger("IriSP.createAnnotationWidget.addedAnnotation", annotation); callback(); }), error: diff -r b1e2dfc7a740 -r 404f876827ad src/js/widgets/segmentsWidget.js --- a/src/js/widgets/segmentsWidget.js Mon Jan 16 18:49:45 2012 +0100 +++ b/src/js/widgets/segmentsWidget.js Mon Jan 16 18:50:30 2012 +0100 @@ -47,9 +47,9 @@ this.selector.append(Mustache.to_html(IriSP.overlay_marker_template)); var view_type = this._serializer.getChapitrage(); - if (typeof(view_type) === "undefined") - view_type = this._serializer.getNonTweetIds()[0]; - + if (typeof(view_type) === "undefined") { + view_type = this._serializer.getNonTweetIds()[0]; + } this.positionMarker = this.selector.children(":first"); this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.positionUpdater)); @@ -101,8 +101,10 @@ var hexa_color = IriSP.DEC_HEXA_COLOR(color); + /* if (hexa_color === "FFCC00") hexa_color = "333"; + */ if (hexa_color.length == 4) hexa_color = hexa_color + '00'; diff -r b1e2dfc7a740 -r 404f876827ad src/js/widgets/sparklineWidget.js --- a/src/js/widgets/sparklineWidget.js Mon Jan 16 18:49:45 2012 +0100 +++ b/src/js/widgets/sparklineWidget.js Mon Jan 16 18:50:30 2012 +0100 @@ -3,7 +3,7 @@ IriSP.Widget.call(this, Popcorn, config, Serializer); this._oldAnnotation = null; - + this._results = []; }; @@ -21,9 +21,8 @@ the second is an overlay div to display the progression in the video, and the third is a div to react to clicks */ - - /* we suppose that a column is 5 pixels wide */ - var num_columns = (this.selector.width()) / 10; + + var num_columns = (this.selector.width()) / IriSP.widgetsDefaults["SparklineWidget"].column_width; var duration = +this._serializer.currentMedia().meta["dc:duration"]; var time_step = duration / num_columns; /* the time interval between two columns */ var results = []; @@ -52,6 +51,9 @@ results.push(count); } + // save the results in an array so that we can re-use them when a new annotation + // is added. + this._results = results; this.selector.append(templ); this.selector.find(".Ldt-sparkLine").css("background", "#c7c8cc"); @@ -59,6 +61,8 @@ spotColor: "#b70056", width: this.width, height: this.height}); this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeUpdateHandler)); + this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, this.handleNewAnnotation)); + IriSP.jQuery(".Ldt-sparkLineClickOverlay").click(IriSP.wrap(this, this.clickHandler)); }; @@ -91,4 +95,18 @@ this._Popcorn.trigger("IriSP.SparklineWidget.clicked", newTime); this._Popcorn.currentTime(newTime); +}; + +/** react when a new annotation is added */ +IriSP.SparklineWidget.prototype.handleNewAnnotation = function(annotation) { + var num_columns = (this.selector.width()) / IriSP.widgetsDefaults["SparklineWidget"].column_width; + var duration = +this._serializer.currentMedia().meta["dc:duration"]; + var time_step = duration / num_columns; /* the time interval between two columns */ + var begin = +annotation.begin; + + var index = Math.floor(begin / time_step); + this._results[index]++; + this.selector.find(".Ldt-sparkLine").sparkline(this._results, {lineColor: "#7492b4", fillColor: "#aeaeb8", + spotColor: "#b70056", + width: this.width, height: this.height}); }; \ No newline at end of file diff -r b1e2dfc7a740 -r 404f876827ad test/integration/polemic-platform.htm --- a/test/integration/polemic-platform.htm Mon Jan 16 18:49:45 2012 +0100 +++ b/test/integration/polemic-platform.htm Mon Jan 16 18:50:30 2012 +0100 @@ -22,7 +22,8 @@