Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: chrome/browser/resources/media_router/elements/route_controls/route_controls.js

Issue 2725503002: [Media Router] Custom Controls 4 - Implement details view WebUI (Closed)
Patch Set: Fix a test Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // This Polymer element shows media controls for a route that is currently cast
6 // to a device.
7 Polymer({
8 is: 'route-controls',
9
10 properties: {
11 /**
12 * The current time displayed in seconds.
13 * @type {number}
14 */
15 displayedCurrentTime_: {
16 type: Number,
17 value: 0
18 },
19
20 /**
21 * Whether updates for the current time from the browser should be ignored.
22 * Set to true when the user is dragging the time slider.
23 * @private {boolean}
24 */
25 ignoreExternalTimeUpdates_: {
mark a. foltz 2017/05/03 21:27:00 This might be clearer as isSeeking_, but I don't f
takumif 2017/05/05 18:57:39 Done.
26 type: Boolean,
27 value: false
28 },
29
30 /**
31 * Whether volume updates from the browser should be ignored. Set to true
32 * when the user is dragging the volume slider.
33 * @private {boolean}
34 */
35 ignoreExternalVolumeUpdates_: {
mark a. foltz 2017/05/03 21:27:00 isVolumeChanging_
takumif 2017/05/05 18:57:40 Done.
36 type: Boolean,
37 value: false
38 },
39
40 /**
41 * Whether we have received status updates from the browser for the current
42 * route. When this is false, we allow updating the media title based on the
43 * route name.
mark a. foltz 2017/05/03 21:26:59 I don't follow how a media status update is relate
takumif 2017/05/05 18:57:39 Removed this variable. I wanted to use route descr
44 * @private {boolean}
45 */
46 receivedStatusUpdates_: {
47 type: Boolean,
48 value: false
49 },
50
51 /**
52 * The route to show.
53 * @type {?media_router.Route}
mark a. foltz 2017/05/03 21:26:59 Must this be null on construction?
takumif 2017/05/05 18:57:39 Removed.
54 */
55 route: {
56 type: Object,
57 observer: 'onRouteChange_',
58 value: null
59 },
60
61 /**
62 * The status of the media route shown. External updates are done using
63 * updateRouteStatus() to discern from internal updates.
mark a. foltz 2017/05/03 21:27:00 s/status/media status/ Can you explain "internal"
takumif 2017/05/05 18:57:40 Removed. This was to discern updates by status obj
64 * @private {?media_router.RouteStatus}
65 */
66 routeStatus_: {
67 type: Object,
68 observer: 'onRouteStatusChange_',
69 value: null
70 },
71
72 /**
73 * The value of the time slider, between 0 and 1.
mark a. foltz 2017/05/03 21:26:59 s/time slider/seek bar/ Shouldn't this be in secon
takumif 2017/05/05 18:57:40 Switched to seconds. Also merged with displayedCur
74 * @type {number}
75 */
76 timeSliderValue_: {
mark a. foltz 2017/05/03 21:26:59 currentTimeFraction_ ?
takumif 2017/05/05 18:57:39 Merged with displayedCurrentTime_
77 type: Number,
78 value: 0
79 },
80
81 /**
82 * The value of the volume slider, between 0 and 1.
mark a. foltz 2017/05/03 21:27:00 s/slider/control/
takumif 2017/05/05 18:57:40 Done.
83 * @type {number}
84 */
85 volumeSliderValue_: {
86 type: Number,
87 value: 0
88 },
89 },
90
91 behaviors: [
92 I18nBehavior,
93 ],
94
95 /**
96 * Gets the duration formatted in HH:MM:SS format.
97 * @param {?media_router.RouteStatus} routeStatus
98 * @return {string}
99 *
100 * @private
101 */
102 getDuration_: function(routeStatus) {
103 return routeStatus ? this.getFormattedTime_(routeStatus.duration) : '';
104 },
105
106 /**
107 * Converts a number representing an interval of seconds to a string with
108 * HH:MM:SS format.
109 * @param {number} timeInSec Must be non-negative. Intervals longer than 100
110 * hours get truncated silently.
111 * @return {string}
112 *
113 * @private
114 */
115 getFormattedTime_: function(timeInSec) {
116 if (timeInSec < 0) {
117 return '';
118 }
119 var hours = Math.floor(timeInSec / 3600);
mark a. foltz 2017/05/03 21:27:00 s/var/const/
takumif 2017/05/05 18:57:39 The presubmit check tells us to use var instead of
120 var minutes = Math.floor(timeInSec / 60) % 60;
121 var seconds = Math.floor(timeInSec) % 60;
122 var timeParts = [
123 ('0' + hours).substr(-2), ('0' + minutes).substr(-2),
124 ('0' + seconds).substr(-2)
125 ];
126 return timeParts.join(':');
mark a. foltz 2017/05/03 21:27:00 This can be combined with the previous line.
takumif 2017/05/05 18:57:39 Done.
127 },
128
129 /**
130 * @param {?media_router.RouteStatus} routeStatus
131 * @return {string} The value for the icon attribute of the mute/unmute
132 * button.
133 *
134 * @private
135 */
136 getMuteUnmuteIcon_: function(routeStatus) {
137 return (routeStatus && routeStatus.isMuted) ? 'av:volume-off' :
mark a. foltz 2017/05/03 21:27:00 Can we initialize the element with a routeStatus t
takumif 2017/05/05 18:57:39 Done.
138 'av:volume-up';
139 },
140
141 /**
142 * @param {?media_router.RouteStatus} routeStatus
143 * @return {string} Localized title for the mute/unmute button.
144 *
145 * @private
146 */
147 getMuteUnmuteTitle_: function(routeStatus) {
148 return (routeStatus && routeStatus.isMuted) ? this.i18n('unmuteTitle') :
149 this.i18n('muteTitle');
150 },
151
152 /**
153 * @param {?media_router.RouteStatus} routeStatus
154 * @return {string}The value for the icon attribute of the play/pause button.
155 *
156 * @private
157 */
158 getPlayPauseIcon_: function(routeStatus) {
159 return (routeStatus && routeStatus.isPaused) ? 'av:play-arrow' : 'av:pause';
160 },
161
162 /**
163 * @param {?media_router.RouteStatus} routeStatus
164 * @return {string} Localized title for the play/pause button.
165 *
166 * @private
167 */
168 getPlayPauseTitle_: function(routeStatus) {
169 return (routeStatus && routeStatus.isPaused) ? this.i18n('playTitle') :
170 this.i18n('pauseTitle');
171 },
172
173 /**
174 * @param {number} seekPositionRatio The ratio with the duration, which must
175 * be between 0 and 1.
176 * @param {number} duration The duration in seconds.
177 * @return {number} The seek position in seconds.
178 *
179 * @private
180 */
181 getSeekPosition_: function(seekPositionRatio, duration) {
mark a. foltz 2017/05/03 21:27:00 getSeekTime_(seekPosition, duration) ?
takumif 2017/05/05 18:57:40 Using seconds in the slider, and removing this fun
182 return duration ? Math.floor(seekPositionRatio * duration) : 0;
mark a. foltz 2017/05/03 21:27:00 I don't think this extra check is necessary; Math.
takumif 2017/05/05 18:57:39 Removing.
183 },
184
185 /**
186 * @param {number} seekPosition The seek position in seconds.
187 * @param {number} duration The duration in seconds.
188 * @return {number} The seek position as a ratio with the duration, between 0
189 * and 1.
190 *
191 * @private
192 */
193 getSeekPositionRatio_: function(seekPosition, duration) {
mark a. foltz 2017/05/03 21:27:00 getSeekPosition_(seekTime, duration) ?
takumif 2017/05/05 18:57:39 Removing.
194 return duration ? (seekPosition / duration) : 0;
195 },
196
197 /**
198 * Called when the user starts dragging the current-time slider.
199 * @param {!Event} e
200 *
201 * @private
202 */
203 onImmediateTimeSliderChange_: function(e) {
mark a. foltz 2017/05/03 21:26:59 onSeekStart_ ?
takumif 2017/05/05 18:57:39 Done.
204 this.ignoreExternalTimeUpdates_ = true;
205 /** @type {{immediateValue: number}} */
206 var target = e.target;
207 this.timeSliderValue_ = target.immediateValue;
208 this.displayedCurrentTime_ = this.getSeekPosition_(
209 this.timeSliderValue_, this.routeStatus_.duration);
210 },
211
212 /**
213 * Called when the user starts dragging the volume slider.
214 * @param {!Event} e
215 *
216 * @private
217 */
218 onImmediateVolumeSliderChange_: function(e) {
mark a. foltz 2017/05/03 21:27:00 onVolumeChangeStart_?
takumif 2017/05/05 18:57:40 Done.
219 this.ignoreExternalVolumeUpdates_ = true;
220 /** @type {{immediateValue: number}} */
221 var target = e.target;
222 this.volumeSliderValue_ = target.immediateValue;
223 },
224
225 /**
226 * Sends a mute or unmute command to the browser.
mark a. foltz 2017/05/03 21:27:00 Called when the user toggles the mute status of th
takumif 2017/05/05 18:57:39 Done.
227 *
228 * @private
229 */
230 onMuteUnmute_: function() {
231 media_router.browserApi.setCurrentMediaMute(!this.routeStatus_.isMuted);
232 },
233
234 /**
235 * Sends a play or pause command to the browser.
mark a. foltz 2017/05/03 21:27:00 Called when the user toggles between playing and p
takumif 2017/05/05 18:57:39 Done.
236 *
237 * @private
238 */
239 onPlayPause_: function() {
240 if (this.routeStatus_.isPaused) {
241 media_router.browserApi.playCurrentMedia();
242 } else {
243 media_router.browserApi.pauseCurrentMedia();
244 }
245 },
246
247 /**
248 * Updates the route title shown, if no status updates have been received.
249 *
250 * @private
251 */
252 onRouteChange_: function(newRoute) {
253 if (!newRoute || this.receivedStatusUpdates_)
254 return;
255
256 // Hide all the elements except for the title showing the route description.
257 this.routeStatus_ = new media_router.RouteStatus(
mark a. foltz 2017/05/03 21:27:00 Would this be simpler as just a <div> with text co
takumif 2017/05/05 18:57:39 Creating a displayedDescription_ property to set i
258 loadTimeData.getStringF('castingActivityStatus', newRoute.description),
259 '', false, false, false, false, false, false, 0, 0, 0);
260 },
261
262 /**
263 * Called when the route details view is closed.
264 */
265 onRouteDetailsClosed: function() {
266 this.receivedStatusUpdates_ = false;
267 this.routeStatus_ = null;
268 media_router.ui.setRouteControls(null);
269 },
270
271 /**
272 * Updates seek and volume sliders if the user is not currently dragging on
273 * them.
274 * @param {?media_router.RouteStatus} newRouteStatus
275 *
276 * @private
277 */
278 onRouteStatusChange_: function(newRouteStatus) {
279 if (!newRouteStatus)
280 return;
281
282 if (!this.ignoreExternalTimeUpdates_) {
283 this.displayedCurrentTime_ = newRouteStatus.currentTime;
284 this.timeSliderValue_ = this.getSeekPositionRatio_(
285 newRouteStatus.currentTime, newRouteStatus.duration);
286 }
287
288 if (!this.ignoreExternalVolumeUpdates_) {
289 this.volumeSliderValue_ = newRouteStatus.volume;
290 }
291 },
292
293 /**
294 * Called when the user clicks on or stops dragging the current-time slider.
295 * @param {!Event} e
296 *
297 * @private
298 */
299 onTimeSliderChange_: function(e) {
mark a. foltz 2017/05/03 21:27:00 onSeekComplete_
takumif 2017/05/05 18:57:40 Done.
300 if (!this.routeStatus_)
301 return;
302
303 this.ignoreExternalTimeUpdates_ = false;
304 /** @type {{value: number}} */
305 var target = e.target;
306 this.timeSliderValue_ = target.value;
307 this.displayedCurrentTime_ = this.getSeekPosition_(
308 this.timeSliderValue_, this.routeStatus_.duration);
309 media_router.browserApi.seekCurrentMedia(this.displayedCurrentTime_);
310 },
311
312 /**
313 * Called when the user clicks on or stops dragging the volume slider.
314 * @param {!Event} e
315 *
316 * @private
317 */
318 onVolumeSliderChange_: function(e) {
mark a. foltz 2017/05/03 21:27:00 onVolumeChangeComplete_
takumif 2017/05/05 18:57:39 Done.
319 if (!this.routeStatus_)
320 return;
321
322 this.ignoreExternalVolumeUpdates_ = false;
323 /** @type {{value: number}} */
324 var target = e.target;
325 this.volumeSliderValue_ = target.value;
326 media_router.browserApi.setCurrentMediaVolume(this.volumeSliderValue_);
327 },
328
329 /**
330 * Called by Polymer on ready.
331 */
332 ready: function() {
333 media_router.ui.setRouteControls(this);
334 },
335
336 /**
337 * Updates the route status that is displayed on the controls.
338 *
339 * @param {!media_router.RouteStatus} status
340 */
341 updateRouteStatus: function(status) {
342 this.receivedStatusUpdates_ = true;
mark a. foltz 2017/05/03 21:27:00 Is this the same as testing this.routeStatus_ ?
takumif 2017/05/05 18:57:39 Removed.
343 this.routeStatus_ = status;
344 },
345 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698