1 /* TODO |
1 /* TODO |
2 - add callbacks |
2 - add callbacks |
3 */ |
3 */ |
|
4 // EnrichedPlan |
|
5 import Mustache from "mustache"; |
4 |
6 |
5 IriSP.Widgets.EnrichedPlan = function(player, config) { |
7 import enrichedPlanStyles from "./EnrichedPlan.module.css"; |
6 IriSP.Widgets.Widget.call(this, player, config); |
|
7 } |
|
8 |
8 |
9 IriSP.Widgets.EnrichedPlan.prototype = new IriSP.Widgets.Widget(); |
9 const EnrichedPlan = function (ns) { |
|
10 return class extends ns.Widgets.Widget { |
|
11 constructor(player, config) { |
|
12 super(player, config); |
|
13 } |
10 |
14 |
11 IriSP.Widgets.EnrichedPlan.prototype.defaults = { |
15 static defaults = { |
12 // Main type for slide segmentation |
16 // Main type for slide segmentation |
13 annotation_type: "Slides", |
17 annotation_type: "Slides", |
14 // If no annotation type list is specified, use all other types |
18 // If no annotation type list is specified, use all other types |
15 annotation_types: [], |
19 annotation_types: [], |
16 show_controls: true, |
20 show_controls: true, |
17 show_slides: true, |
21 show_slides: true, |
18 show_teacher_notes: true, |
22 show_teacher_notes: true, |
19 show_other_notes: true, |
23 show_other_notes: true, |
20 show_own_notes: true |
24 show_own_notes: true, |
21 } |
|
22 |
|
23 IriSP.Widgets.EnrichedPlan.prototype.template = |
|
24 '<div class="Ldt-EnrichedPlan-Container">' |
|
25 + '{{#show_controls}}<form class="Ldt-EnrichedPlan-Controls">' |
|
26 + ' <input id="{{prefix}}teacher_note_checkbox" class="Ldt-EnrichedPlan-Control-Checkbox Ldt-EnrichedPlan-Note-Teacher" {{#show_teacher_notes}}checked{{/show_teacher_notes}} type="checkbox">' |
|
27 + ' <label for="{{prefix}}teacher_note_checkbox" class="Ldt-EnrichedPlan-Control-Label Ldt-EnrichedPlan-Note-Teacher">Notes Enseignant</label>' |
|
28 + ' <input id="{{prefix}}other_note_checkbox" class="Ldt-EnrichedPlan-Control-Checkbox Ldt-EnrichedPlan-Note-Other" {{#show_other_notes}}checked{{/show_other_notes}} type="checkbox">' |
|
29 + ' <label for="{{prefix}}other_note_checkbox" class="Ldt-EnrichedPlan-Control-Label Ldt-EnrichedPlan-Note-Other">Notes Autres</label>' |
|
30 + ' <input id="{{prefix}}simplified_plan_checkbox" class="Ldt-EnrichedPlan-Control-Checkbox Ldt-EnrichedPlan-Note-Own" {{#show_own_notes}}checked{{/show_own_notes}} type="checkbox">' |
|
31 + ' <label for="{{prefix}}simplified_plan_checkbox" class="Ldt-EnrichedPlan-Control-Label Ldt-EnrichedPlan-Note-Own">Notes perso.</label>' |
|
32 + ' <input id="{{prefix}}slide_display_checkbox" class="Ldt-EnrichedPlan-Control-Checkbox Ldt-EnrichedPlan-Slide-Display" {{#show_slides}}checked{{/show_slides}} type="checkbox">' |
|
33 + ' <label for="{{prefix}}slide_display_checkbox" class="Ldt-EnrichedPlan-Control-Label Ldt-EnrichedPlan-Slide-Display">Diapo<br/> </label>' |
|
34 + ' <input class="Ldt-EnrichedPlan-Search-Input" type="search" incremental placeholder="Recherchez"/>' |
|
35 + '</form>{{/show_controls}}' |
|
36 + '<div class="Ldt-EnrichedPlan-Content"></div>' |
|
37 + '</div>'; |
|
38 |
|
39 IriSP.Widgets.EnrichedPlan.prototype.slideTemplate = |
|
40 '<div data-id="{{ id }}" class="Ldt-EnrichedPlan-Slide">' |
|
41 + ' <div class="Ldt-EnrichedPlan-SlideItem Ldt-EnrichedPlan-SlideTimecode">{{ begin }}</div>' |
|
42 + ' <div data-timecode="{{begintc}}" class="Ldt-EnrichedPlan-SlideItem {{^show_slides}}filtered_out{{/show_slides}} Ldt-EnrichedPlan-SlideThumbnail Ldt-EnrichedPlan-Slide-Display"><img title="{{ begin }} - {{ atitle }}" src="{{ thumbnail }}"></div>' |
|
43 + ' <div class="Ldt-EnrichedPlan-SlideContent">' |
|
44 + ' <div data-timecode="{{begintc}}" class="Ldt-EnrichedPlan-SlideTitle Ldt-EnrichedPlan-SlideTitle{{ level }}">{{ atitle }}</div>' |
|
45 + ' <div class="Ldt-EnrichedPlan-SlideNotes">{{{ notes }}}</div>' |
|
46 + ' </div>' |
|
47 + '</div>'; |
|
48 |
|
49 IriSP.Widgets.EnrichedPlan.prototype.annotationTemplate = '<div title="{{ begin }} - {{ atitle }}" data-id="{{ id }}" data-timecode="{{begintc}}" class="Ldt-EnrichedPlan-SlideItem Ldt-EnrichedPlan-Note {{category}} {{filtered}}"><span class="Ldt-EnrichedPlan-Note-Text">{{{ text }}}</span> <span class="Ldt-EnrichedPlan-Note-Author">{{ author }}</span></div>'; |
|
50 |
|
51 IriSP.Widgets.EnrichedPlan.prototype.draw = function() { |
|
52 var _this = this; |
|
53 // Generate a unique prefix, so that ids of input fields |
|
54 // (necessary for label association) are unique too. |
|
55 _this.prefix = "TODO"; |
|
56 // slides content: title, level (for toc) |
|
57 var _slides = this.getWidgetAnnotations().sortBy(function(_annotation) { |
|
58 return _annotation.begin; |
|
59 }); |
|
60 // All other annotations |
|
61 var _annotations = this.media.getAnnotations().filter( function (a) { |
|
62 return a.getAnnotationType().title != _this.annotation_type; |
|
63 }).sortBy(function(_annotation) { |
|
64 return _annotation.begin; |
|
65 }); |
|
66 |
|
67 // Reference annotations in each slide: assume that end time is |
|
68 // correctly set. |
|
69 _slides.forEach( function (slide) { |
|
70 slide.annotations = _annotations.filter( function (a) { |
|
71 return a.begin >= slide.begin && a.begin <= slide.end; |
|
72 }); |
|
73 }); |
|
74 |
|
75 _this.renderTemplate(); |
|
76 var container = _this.$.find('.Ldt-EnrichedPlan-Container'); |
|
77 var content = _this.$.find('.Ldt-EnrichedPlan-Content'); |
|
78 |
|
79 // Returns the note category: Own, Other, Teacher |
|
80 function note_category(a) { |
|
81 return a.title.indexOf('Anonyme') < 0 ? "Own" : "Other"; |
|
82 }; |
25 }; |
83 |
26 |
84 _slides.forEach(function(slide) { |
27 static template = |
85 var _html = Mustache.to_html(_this.slideTemplate, { |
28 '<div class="Ldt-EnrichedPlan-Container">' + |
86 id : slide.id, |
29 '{{#show_controls}}<form class="Ldt-EnrichedPlan-Controls">' + |
87 atitle : IriSP.textFieldHtml(slide.title), |
30 ' <input id="{{prefix}}teacher_note_checkbox" class="Ldt-EnrichedPlan-Control-Checkbox Ldt-EnrichedPlan-Note-Teacher" {{#show_teacher_notes}}checked{{/show_teacher_notes}} type="checkbox">' + |
88 level: slide.content.level || 1, |
31 ' <label for="{{prefix}}teacher_note_checkbox" class="Ldt-EnrichedPlan-Control-Label Ldt-EnrichedPlan-Note-Teacher">Notes Enseignant</label>' + |
89 begin : slide.begin.toString(), |
32 ' <input id="{{prefix}}other_note_checkbox" class="Ldt-EnrichedPlan-Control-Checkbox Ldt-EnrichedPlan-Note-Other" {{#show_other_notes}}checked{{/show_other_notes}} type="checkbox">' + |
90 begintc: slide.begin.milliseconds, |
33 ' <label for="{{prefix}}other_note_checkbox" class="Ldt-EnrichedPlan-Control-Label Ldt-EnrichedPlan-Note-Other">Notes Autres</label>' + |
91 thumbnail: slide.thumbnail, |
34 ' <input id="{{prefix}}simplified_plan_checkbox" class="Ldt-EnrichedPlan-Control-Checkbox Ldt-EnrichedPlan-Note-Own" {{#show_own_notes}}checked{{/show_own_notes}} type="checkbox">' + |
92 show_slides: _this.show_slides, |
35 ' <label for="{{prefix}}simplified_plan_checkbox" class="Ldt-EnrichedPlan-Control-Label Ldt-EnrichedPlan-Note-Own">Notes perso.</label>' + |
93 notes: slide.annotations.map( function (a) { |
36 ' <input id="{{prefix}}slide_display_checkbox" class="Ldt-EnrichedPlan-Control-Checkbox Ldt-EnrichedPlan-Slide-Display" {{#show_slides}}checked{{/show_slides}} type="checkbox">' + |
94 return Mustache.to_html(_this.annotationTemplate, { |
37 ' <label for="{{prefix}}slide_display_checkbox" class="Ldt-EnrichedPlan-Control-Label Ldt-EnrichedPlan-Slide-Display">Diapo<br/> </label>' + |
95 id: a.id, |
38 ' <input class="Ldt-EnrichedPlan-Search-Input" type="search" incremental placeholder="Recherchez"/>' + |
96 text: IriSP.textFieldHtml(a.description || a.title), |
39 "</form>{{/show_controls}}" + |
97 author: a.creator, |
40 '<div class="Ldt-EnrichedPlan-Content"></div>' + |
98 begin: a.begin.toString(), |
41 "</div>"; |
99 begintc: a.begin.milliseconds, |
42 |
100 atitle: a.title.slice(0, 20), |
43 static slideTemplate = |
101 // FIXME: Temporary hack waiting for a proper metadata definition |
44 '<div data-id="{{ id }}" class="Ldt-EnrichedPlan-Slide">' + |
102 category: "Ldt-EnrichedPlan-Note-" + note_category(a), |
45 ' <div class="Ldt-EnrichedPlan-SlideItem Ldt-EnrichedPlan-SlideTimecode">{{ begin }}</div>' + |
103 filtered: ( (note_category(a) == 'Own' && ! _this.show_own_notes) |
46 ' <div data-timecode="{{begintc}}" class="Ldt-EnrichedPlan-SlideItem {{^show_slides}}filtered_out{{/show_slides}} Ldt-EnrichedPlan-SlideThumbnail Ldt-EnrichedPlan-Slide-Display"><img title="{{ begin }} - {{ atitle }}" src="{{ thumbnail }}"></div>' + |
104 || (note_category(a) == 'Other' && ! _this.show_other_notes) |
47 ' <div class="Ldt-EnrichedPlan-SlideContent">' + |
105 || (note_category(a) == 'Teacher' && ! _this.show_teacher_notes) ) ? 'filtered_out' : '' |
48 ' <div data-timecode="{{begintc}}" class="Ldt-EnrichedPlan-SlideTitle Ldt-EnrichedPlan-SlideTitle{{ level }}">{{ atitle }}</div>' + |
106 }); |
49 ' <div class="Ldt-EnrichedPlan-SlideNotes">{{{ notes }}}</div>' + |
107 }).join("\n") |
50 " </div>" + |
|
51 "</div>"; |
|
52 |
|
53 annotationTemplate = |
|
54 '<div title="{{ begin }} - {{ atitle }}" data-id="{{ id }}" data-timecode="{{begintc}}" class="Ldt-EnrichedPlan-SlideItem Ldt-EnrichedPlan-Note {{category}} {{filtered}}"><span class="Ldt-EnrichedPlan-Note-Text">{{{ text }}}</span> <span class="Ldt-EnrichedPlan-Note-Author">{{ author }}</span></div>'; |
|
55 |
|
56 draw() { |
|
57 var _this = this; |
|
58 // Generate a unique prefix, so that ids of input fields |
|
59 // (necessary for label association) are unique too. |
|
60 _this.prefix = "TODO"; |
|
61 // slides content: title, level (for toc) |
|
62 var _slides = this.getWidgetAnnotations().sortBy(function (_annotation) { |
|
63 return _annotation.begin; |
|
64 }); |
|
65 // All other annotations |
|
66 var _annotations = this.media |
|
67 .getAnnotations() |
|
68 .filter(function (a) { |
|
69 return a.getAnnotationType().title != _this.annotation_type; |
|
70 }) |
|
71 .sortBy(function (_annotation) { |
|
72 return _annotation.begin; |
108 }); |
73 }); |
109 var _el = IriSP.jQuery(_html); |
74 |
|
75 // Reference annotations in each slide: assume that end time is |
|
76 // correctly set. |
|
77 _slides.forEach(function (slide) { |
|
78 slide.annotations = _annotations.filter(function (a) { |
|
79 return a.begin >= slide.begin && a.begin <= slide.end; |
|
80 }); |
|
81 }); |
|
82 |
|
83 _this.renderTemplate(); |
|
84 var container = _this.$.find(".Ldt-EnrichedPlan-Container"); |
|
85 var content = _this.$.find(".Ldt-EnrichedPlan-Content"); |
|
86 |
|
87 // Returns the note category: Own, Other, Teacher |
|
88 function note_category(a) { |
|
89 return a.title.indexOf("Anonyme") < 0 ? "Own" : "Other"; |
|
90 } |
|
91 |
|
92 _slides.forEach(function (slide) { |
|
93 var _html = Mustache.render(_this.slideTemplate, { |
|
94 id: slide.id, |
|
95 atitle: ns.textFieldHtml(slide.title), |
|
96 level: slide.content.level || 1, |
|
97 begin: slide.begin.toString(), |
|
98 begintc: slide.begin.milliseconds, |
|
99 thumbnail: slide.thumbnail, |
|
100 show_slides: _this.show_slides, |
|
101 notes: slide.annotations |
|
102 .map(function (a) { |
|
103 return Mustache.render(_this.annotationTemplate, { |
|
104 id: a.id, |
|
105 text: ns.textFieldHtml(a.description || a.title), |
|
106 author: a.creator, |
|
107 begin: a.begin.toString(), |
|
108 begintc: a.begin.milliseconds, |
|
109 atitle: a.title.slice(0, 20), |
|
110 // FIXME: Temporary hack waiting for a proper metadata definition |
|
111 category: "Ldt-EnrichedPlan-Note-" + note_category(a), |
|
112 filtered: |
|
113 (note_category(a) == "Own" && !_this.show_own_notes) || |
|
114 (note_category(a) == "Other" && !_this.show_other_notes) || |
|
115 (note_category(a) == "Teacher" && !_this.show_teacher_notes) |
|
116 ? "filtered_out" |
|
117 : "", |
|
118 }); |
|
119 }) |
|
120 .join("\n"), |
|
121 }); |
|
122 var _el = ns.jQuery(_html); |
110 content.append(_el); |
123 content.append(_el); |
111 }); |
124 }); |
112 |
125 |
113 container.on("click", "[data-timecode]", function () { |
126 container.on("click", "[data-timecode]", function () { |
114 _this.media.setCurrentTime(Number(this.dataset.timecode)); |
127 _this.media.setCurrentTime(Number(this.dataset.timecode)); |
115 }); |
128 }); |
116 |
129 |
117 container.on("click", ".Ldt-EnrichedPlan-Control-Checkbox", function () { |
130 container.on("click", ".Ldt-EnrichedPlan-Control-Checkbox", function () { |
118 var classname = _.first(_.filter(this.classList, function (s) { return s != "Ldt-EnrichedPlan-Control-Checkbox"; })); |
131 var classname = _.first( |
|
132 _.filter(this.classList, function (s) { |
|
133 return s != "Ldt-EnrichedPlan-Control-Checkbox"; |
|
134 }) |
|
135 ); |
119 if (classname !== undefined) { |
136 if (classname !== undefined) { |
120 if ($(this).is(':checked')) { |
137 if ($(this).is(":checked")) { |
121 content.find(".Ldt-EnrichedPlan-Slide ." + classname).removeClass("filtered_out"); |
138 content |
122 } else { |
139 .find(".Ldt-EnrichedPlan-Slide ." + classname) |
123 content.find(".Ldt-EnrichedPlan-Slide ." + classname).addClass("filtered_out"); |
140 .removeClass("filtered_out"); |
124 } |
141 } else { |
|
142 content |
|
143 .find(".Ldt-EnrichedPlan-Slide ." + classname) |
|
144 .addClass("filtered_out"); |
|
145 } |
125 } |
146 } |
|
147 }); |
126 |
148 |
127 }); |
149 container |
128 |
150 .find(".Ldt-EnrichedPlan-Search-Input") |
129 container.find(".Ldt-EnrichedPlan-Search-Input").on("search", function () { |
151 .on("search", function () { |
130 var q = $(this).val().toLocaleLowerCase(); |
152 var q = $(this).val().toLocaleLowerCase(); |
131 if (q === "") { |
153 if (q === "") { |
132 // Show all |
154 // Show all |
133 content.find(".Ldt-EnrichedPlan-Note").removeClass("non_matching"); |
155 content.find(".Ldt-EnrichedPlan-Note").removeClass("non_matching"); |
134 } else { |
156 } else { |
135 $(".Ldt-EnrichedPlan-Note").each( function () { |
157 $(".Ldt-EnrichedPlan-Note").each(function () { |
136 var node = $(this); |
158 var node = $(this); |
137 if (node.text().toLocaleLowerCase().indexOf(q) > -1) { |
159 if (node.text().toLocaleLowerCase().indexOf(q) > -1) { |
138 node.removeClass("non_matching"); |
160 node.removeClass("non_matching"); |
139 } else { |
161 } else { |
140 node.addClass("non_matching"); |
162 node.addClass("non_matching"); |
141 } |
163 } |
142 }); |
164 }); |
143 } |
165 } |
144 }); |
166 }); |
|
167 } |
|
168 }; |
145 }; |
169 }; |
|
170 |
|
171 export { EnrichedPlan, enrichedPlanStyles }; |