|
1 /* Internationalization for this widget */ |
|
2 |
|
3 IriSP.i18n.addMessages( |
|
4 { |
|
5 "en": { |
|
6 "play_pause": "Play/Pause", |
|
7 "mute_unmute": "Mute/Unmute", |
|
8 "play": "Play", |
|
9 "pause": "Pause", |
|
10 "mute": "Mute", |
|
11 "unmute": "Unmute", |
|
12 "annotate": "Annotate", |
|
13 "search": "Search", |
|
14 "elapsed_time": "Elapsed time", |
|
15 "total_time": "Total time", |
|
16 "volume": "Volume", |
|
17 "volume_control": "Volume control" |
|
18 }, |
|
19 "fr": { |
|
20 "play_pause": "Lecture/Pause", |
|
21 "mute_unmute": "Couper/Activer le son", |
|
22 "play": "Lecture", |
|
23 "pause": "Pause", |
|
24 "mute": "Couper le son", |
|
25 "unmute": "Activer le son", |
|
26 "annotate": "Annoter", |
|
27 "search": "Rechercher", |
|
28 "elapsed_time": "Durée écoulée", |
|
29 "total_time": "Durée totale", |
|
30 "volume": "Niveau sonore", |
|
31 "volume_control": "Réglage du niveau sonore" |
|
32 } |
|
33 } |
|
34 ); |
|
35 |
|
36 |
|
37 IriSP.PlayerWidget = function(Popcorn, config, Serializer) { |
|
38 IriSP.Widget.call(this, Popcorn, config, Serializer); |
|
39 |
|
40 this._searchBlockOpen = false; |
|
41 this._searchLastValue = ""; |
|
42 }; |
|
43 |
|
44 IriSP.PlayerWidget.prototype = new IriSP.Widget(); |
|
45 |
|
46 IriSP.PlayerWidget.prototype.draw = function() { |
|
47 var self = this; |
|
48 var width = this.width; |
|
49 var height = this.height; |
|
50 var heightS = this.height-20; |
|
51 |
|
52 var playerTempl = IriSP.templToHTML(IriSP.player_template, this._config); |
|
53 this.selector.append(playerTempl); |
|
54 |
|
55 this.selector.children(".Ldt-controler").show(); |
|
56 |
|
57 // handle clicks by the user on the video. |
|
58 this._Popcorn.listen("play", IriSP.wrap(this, this.playButtonUpdater)); |
|
59 this._Popcorn.listen("pause", IriSP.wrap(this, this.playButtonUpdater)); |
|
60 |
|
61 this._Popcorn.listen("volumechange", IriSP.wrap(this, this.volumeUpdater)); |
|
62 |
|
63 this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeDisplayUpdater)); |
|
64 // update the time display for the first time. |
|
65 this._Popcorn.listen("loadedmetadata", IriSP.wrap(this, this.timeDisplayUpdater)); |
|
66 |
|
67 this._Popcorn.listen("IriSP.search.matchFound", IriSP.wrap(this, this.searchMatch)); |
|
68 this._Popcorn.listen("IriSP.search.noMatchFound", IriSP.wrap(this, this.searchNoMatch)); |
|
69 this._Popcorn.listen("IriSP.search.triggeredSearch", IriSP.wrap(this, this.triggeredSearch)); |
|
70 |
|
71 |
|
72 this.selector.find(".Ldt-CtrlPlay").click(function() { self.playHandler.call(self); }); |
|
73 this.selector.find(".Ldt-CtrlAnnotate").click(function() |
|
74 { self._Popcorn.trigger("IriSP.PlayerWidget.AnnotateButton.clicked"); }); |
|
75 this.selector.find(".Ldt-CtrlSearch").click(function() { self.searchButtonHandler.call(self); }); |
|
76 |
|
77 var _volctrl = this.selector.find(".Ldt-Ctrl-Volume-Control"); |
|
78 this.selector.find('.Ldt-CtrlSound') |
|
79 .click(function() { self.muteHandler.call(self); } ) |
|
80 .mouseover(function() { |
|
81 _volctrl.show(); |
|
82 }) |
|
83 .mouseout(function() { |
|
84 _volctrl.hide(); |
|
85 }); |
|
86 _volctrl.mouseover(function() { |
|
87 _volctrl.show(); |
|
88 }).mouseout(function() { |
|
89 _volctrl.hide(); |
|
90 }); |
|
91 |
|
92 /* |
|
93 var searchButtonPos = this.selector.find(".Ldt-CtrlSearch").position(); |
|
94 var searchBox = Mustache.to_html(IriSP.search_template, {margin_left : searchButtonPos.left + "px"}); |
|
95 this.selector.find(".Ldt-CtrlSearch").after(searchBox); |
|
96 */ |
|
97 |
|
98 // trigger an IriSP.PlayerWidget.MouseOver to the widgets that are interested (i.e : sliderWidget) |
|
99 this.selector.hover(function() { self._Popcorn.trigger("IriSP.PlayerWidget.MouseOver"); }, |
|
100 function() { self._Popcorn.trigger("IriSP.PlayerWidget.MouseOut"); }); |
|
101 this.selector.find(".Ldt-Ctrl-Volume-Cursor").draggable({ |
|
102 axis: "x", |
|
103 drag: function(event, ui) { |
|
104 var _vol = Math.max(0, Math.min( 1, ui.position.left / (ui.helper.parent().width() - ui.helper.outerWidth()))); |
|
105 ui.helper.attr("title",IriSP.i18n.getMessage('volume')+': ' + Math.floor(100*_vol) + '%'); |
|
106 self._Popcorn.volume(_vol); |
|
107 }, |
|
108 containment: "parent" |
|
109 }); |
|
110 |
|
111 setTimeout(function() { |
|
112 self.volumeUpdater(); |
|
113 }, 1000); /* some player - jwplayer notable - save the state of the mute button between sessions */ |
|
114 }; |
|
115 |
|
116 /* Update the elasped time div */ |
|
117 IriSP.PlayerWidget.prototype.timeDisplayUpdater = function() { |
|
118 |
|
119 if (this._previousSecond === undefined) { |
|
120 this._previousSecond = this._Popcorn.roundTime(); |
|
121 } |
|
122 else { |
|
123 /* we're still in the same second, so it's not necessary to update time */ |
|
124 if (this._Popcorn.roundTime() == this._previousSecond) |
|
125 return; |
|
126 |
|
127 } |
|
128 |
|
129 // we get it at each call because it may change. |
|
130 var duration = this.getDuration() / 1000; |
|
131 var totalTime = IriSP.secondsToTime(duration); |
|
132 var elapsedTime = IriSP.secondsToTime(this._Popcorn.currentTime()); |
|
133 |
|
134 this.selector.find(".Ldt-ElapsedTime").html(elapsedTime.toString()); |
|
135 this.selector.find(".Ldt-TotalTime").html(totalTime.toString()); |
|
136 this._previousSecond = this._Popcorn.roundTime(); |
|
137 }; |
|
138 |
|
139 /* update the icon of the button - separate function from playHandler |
|
140 because in some cases (for instance, when the user directly clicks on |
|
141 the jwplayer window) we have to change the icon without playing/pausing |
|
142 */ |
|
143 IriSP.PlayerWidget.prototype.playButtonUpdater = function() { |
|
144 var status = this._Popcorn.media.paused; |
|
145 |
|
146 if ( status == true ){ |
|
147 /* the background sprite is changed by adding/removing the correct classes */ |
|
148 this.selector.find(".Ldt-CtrlPlay").attr("title", IriSP.i18n.getMessage('play')); |
|
149 this.selector.find(".Ldt-CtrlPlay").removeClass("Ldt-CtrlPlay-PauseState").addClass("Ldt-CtrlPlay-PlayState"); |
|
150 } else { |
|
151 this.selector.find(".Ldt-CtrlPlay").attr("title", IriSP.i18n.getMessage('pause')); |
|
152 this.selector.find(".Ldt-CtrlPlay").removeClass("Ldt-CtrlPlay-PlayState").addClass("Ldt-CtrlPlay-PauseState"); |
|
153 } |
|
154 |
|
155 return; |
|
156 }; |
|
157 |
|
158 |
|
159 IriSP.PlayerWidget.prototype.playHandler = function() { |
|
160 var status = this._Popcorn.media.paused; |
|
161 |
|
162 if ( status == true ){ |
|
163 this._Popcorn.play(); |
|
164 } else { |
|
165 this._Popcorn.pause(); |
|
166 } |
|
167 }; |
|
168 |
|
169 IriSP.PlayerWidget.prototype.muteHandler = function() { |
|
170 this._Popcorn.mute(!this._Popcorn.muted()); |
|
171 }; |
|
172 |
|
173 IriSP.PlayerWidget.prototype.volumeUpdater = function() { |
|
174 var _muted = this._Popcorn.muted(), |
|
175 _vol = this._Popcorn.volume(); |
|
176 if (_vol === false) { |
|
177 _vol = .5; |
|
178 } |
|
179 var _soundCtl = this.selector.find(".Ldt-CtrlSound"); |
|
180 _soundCtl.removeClass("Ldt-CtrlSound-Mute Ldt-CtrlSound-Half Ldt-CtrlSound-Full"); |
|
181 if (_muted) { |
|
182 _soundCtl.attr("title", IriSP.i18n.getMessage('unmute')) |
|
183 .addClass("Ldt-CtrlSound-Mute"); |
|
184 } else { |
|
185 _soundCtl.attr("title", IriSP.i18n.getMessage('mute')) |
|
186 .addClass(_vol < .5 ? "Ldt-CtrlSound-Half" : "Ldt-CtrlSound-Full" ) |
|
187 } |
|
188 var _cursor = this.selector.find(".Ldt-Ctrl-Volume-Cursor"); |
|
189 _cursor.css({ |
|
190 "left": ( _muted ? 0 : Math.floor(_vol * (_cursor.parent().width() - _cursor.outerWidth())) ) + "px" |
|
191 }) |
|
192 }; |
|
193 |
|
194 IriSP.PlayerWidget.prototype.showSearchBlock = function() { |
|
195 var self = this; |
|
196 |
|
197 if (this._searchBlockOpen == false) { |
|
198 this.selector.find(".LdtSearch").show("blind", { direction: "horizontal"}, 100); |
|
199 this.selector.find(".LdtSearchInput").css('background-color','#fff'); |
|
200 |
|
201 this._searchBlockOpen = true; |
|
202 this.selector.find(".LdtSearchInput").bind('keyup', null, function() { self.searchHandler.call(self); } ); |
|
203 this.selector.find(".LdtSearchInput").focus(); |
|
204 |
|
205 // we need this variable because some widget can find a match in |
|
206 // their data while at the same time other's don't. As we want the |
|
207 // search field to become green when there's a match, we need a |
|
208 // variable to remember that we had one. |
|
209 this._positiveMatch = false; |
|
210 |
|
211 // tell the world the field is open |
|
212 this._Popcorn.trigger("IriSP.search.open"); |
|
213 } |
|
214 }; |
|
215 |
|
216 IriSP.PlayerWidget.prototype.hideSearchBlock = function() { |
|
217 if (this._searchBlockOpen == true) { |
|
218 this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value'); |
|
219 this.selector.find(".LdtSearchInput").attr('value',''); |
|
220 this.selector.find(".LdtSearch").hide("blind", { direction: "horizontal"}, 75); |
|
221 |
|
222 // unbind the watcher event. |
|
223 this.selector.find(".LdtSearchInput").unbind('keypress set'); |
|
224 this._searchBlockOpen = false; |
|
225 |
|
226 this._positiveMatch = false; |
|
227 |
|
228 this._Popcorn.trigger("IriSP.search.closed"); |
|
229 } |
|
230 }; |
|
231 |
|
232 /** react to clicks on the search button */ |
|
233 IriSP.PlayerWidget.prototype.searchButtonHandler = function() { |
|
234 var self = this; |
|
235 |
|
236 /* show the search field if it is not shown */ |
|
237 if ( this._searchBlockOpen == false ) { |
|
238 this.showSearchBlock(); |
|
239 this.selector.find(".LdtSearchInput").attr('value', this._searchLastValue); |
|
240 this._Popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural. |
|
241 } else { |
|
242 this.hideSearchBlock(); |
|
243 } |
|
244 }; |
|
245 |
|
246 /** this handler is called whenever the content of the search |
|
247 field changes */ |
|
248 IriSP.PlayerWidget.prototype.searchHandler = function() { |
|
249 this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value'); |
|
250 this._positiveMatch = false; |
|
251 |
|
252 // do nothing if the search field is empty, instead of highlighting everything. |
|
253 if (this._searchLastValue == "") { |
|
254 this._Popcorn.trigger("IriSP.search.cleared"); |
|
255 this.selector.find(".LdtSearchInput").css('background-color',''); |
|
256 } else { |
|
257 this._Popcorn.trigger("IriSP.search", this._searchLastValue); |
|
258 } |
|
259 }; |
|
260 |
|
261 /** |
|
262 handler for the IriSP.search.found message, which is sent by some views when they |
|
263 highlight a match. |
|
264 */ |
|
265 IriSP.PlayerWidget.prototype.searchMatch = function() { |
|
266 this._positiveMatch = true; |
|
267 this.selector.find(".LdtSearchInput").css('background-color','#e1ffe1'); |
|
268 }; |
|
269 |
|
270 /** the same, except that no value could be found */ |
|
271 IriSP.PlayerWidget.prototype.searchNoMatch = function() { |
|
272 if (this._positiveMatch !== true) |
|
273 this.selector.find(".LdtSearchInput").css('background-color', "#d62e3a"); |
|
274 }; |
|
275 |
|
276 /** react to an IriSP.Player.triggeredSearch - that is, when |
|
277 a widget ask the PlayerWidget to do a search on his behalf */ |
|
278 IriSP.PlayerWidget.prototype.triggeredSearch = function(searchString) { |
|
279 this.showSearchBlock(); |
|
280 this.selector.find(".LdtSearchInput").attr('value', searchString); |
|
281 this._Popcorn.trigger("IriSP.search", searchString); // trigger the search to make it more natural. |
|
282 }; |
|
283 |
|
284 |