OLD | NEW |
(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 /** |
| 6 * This Polymer element shows media controls for a route that is currently cast |
| 7 * to a device. |
| 8 * @implements {RouteControlsInterface} |
| 9 */ |
| 10 Polymer({ |
| 11 is: 'route-controls', |
| 12 |
| 13 properties: { |
| 14 /** |
| 15 * The current time displayed in seconds, before formatting. |
| 16 * @private {number} |
| 17 */ |
| 18 displayedCurrentTime_: { |
| 19 type: Number, |
| 20 value: 0, |
| 21 }, |
| 22 |
| 23 /** |
| 24 * The media description to display. Uses route description if none is |
| 25 * provided by the route status object. |
| 26 * @private {string} |
| 27 */ |
| 28 displayedDescription_: { |
| 29 type: String, |
| 30 value: '', |
| 31 }, |
| 32 |
| 33 /** |
| 34 * The volume shown in the volume control, between 0 and 1. |
| 35 * @private {number} |
| 36 */ |
| 37 displayedVolume_: { |
| 38 type: Number, |
| 39 value: 0, |
| 40 }, |
| 41 |
| 42 /** |
| 43 * Set to true when the user is dragging the seek bar. Updates for the |
| 44 * current time from the browser will be ignored when set to true. |
| 45 * @private {boolean} |
| 46 */ |
| 47 isSeeking_: { |
| 48 type: Boolean, |
| 49 value: false, |
| 50 }, |
| 51 |
| 52 /** |
| 53 * Set to true when the user is dragging the volume bar. Volume updates from |
| 54 * the browser will be ignored when set to true. |
| 55 * @private {boolean} |
| 56 */ |
| 57 isVolumeChanging_: { |
| 58 type: Boolean, |
| 59 value: false, |
| 60 }, |
| 61 |
| 62 /** |
| 63 * The status of the media route shown. |
| 64 * @type {!media_router.RouteStatus} |
| 65 */ |
| 66 routeStatus: { |
| 67 type: Object, |
| 68 observer: 'onRouteStatusChange_', |
| 69 value: new media_router.RouteStatus( |
| 70 '', '', false, false, false, false, false, false, 0, 0, 0), |
| 71 }, |
| 72 }, |
| 73 |
| 74 behaviors: [ |
| 75 I18nBehavior, |
| 76 ], |
| 77 |
| 78 /** |
| 79 * Called by Polymer when the element loads. Registers the element to be |
| 80 * notified of route status updates. |
| 81 */ |
| 82 ready: function() { |
| 83 media_router.ui.setRouteControls( |
| 84 /** @type {RouteControlsInterface} */ (this)); |
| 85 }, |
| 86 |
| 87 /** |
| 88 * Converts a number representing an interval of seconds to a string with |
| 89 * HH:MM:SS format. |
| 90 * @param {number} timeInSec Must be non-negative. Intervals longer than 100 |
| 91 * hours get truncated silently. |
| 92 * @return {string} |
| 93 * |
| 94 * @private |
| 95 */ |
| 96 getFormattedTime_: function(timeInSec) { |
| 97 if (timeInSec < 0) { |
| 98 return ''; |
| 99 } |
| 100 var hours = Math.floor(timeInSec / 3600); |
| 101 var minutes = Math.floor(timeInSec / 60) % 60; |
| 102 var seconds = Math.floor(timeInSec) % 60; |
| 103 return ('0' + hours).substr(-2) + ':' + ('0' + minutes).substr(-2) + ':' + |
| 104 ('0' + seconds).substr(-2); |
| 105 }, |
| 106 |
| 107 /** |
| 108 * @param {!media_router.RouteStatus} routeStatus |
| 109 * @return {string} The value for the icon attribute of the mute/unmute |
| 110 * button. |
| 111 * |
| 112 * @private |
| 113 */ |
| 114 getMuteUnmuteIcon_: function(routeStatus) { |
| 115 return routeStatus.isMuted ? 'av:volume-off' : 'av:volume-up'; |
| 116 }, |
| 117 |
| 118 /** |
| 119 * @param {!media_router.RouteStatus} routeStatus |
| 120 * @return {string} Localized title for the mute/unmute button. |
| 121 * |
| 122 * @private |
| 123 */ |
| 124 getMuteUnmuteTitle_: function(routeStatus) { |
| 125 return routeStatus.isMuted ? this.i18n('unmuteTitle') : |
| 126 this.i18n('muteTitle'); |
| 127 }, |
| 128 |
| 129 /** |
| 130 * @param {!media_router.RouteStatus} routeStatus |
| 131 * @return {string}The value for the icon attribute of the play/pause button. |
| 132 * |
| 133 * @private |
| 134 */ |
| 135 getPlayPauseIcon_: function(routeStatus) { |
| 136 return routeStatus.isPaused ? 'av:play-arrow' : 'av:pause'; |
| 137 }, |
| 138 |
| 139 /** |
| 140 * @param {!media_router.RouteStatus} routeStatus |
| 141 * @return {string} Localized title for the play/pause button. |
| 142 * |
| 143 * @private |
| 144 */ |
| 145 getPlayPauseTitle_: function(routeStatus) { |
| 146 return routeStatus.isPaused ? this.i18n('playTitle') : |
| 147 this.i18n('pauseTitle'); |
| 148 }, |
| 149 |
| 150 /** |
| 151 * Called when the user toggles the mute status of the media. Sends a mute or |
| 152 * unmute command to the browser. |
| 153 * |
| 154 * @private |
| 155 */ |
| 156 onMuteUnmute_: function() { |
| 157 media_router.browserApi.setCurrentMediaMute(!this.routeStatus.isMuted); |
| 158 }, |
| 159 |
| 160 /** |
| 161 * Called when the user toggles between playing and pausing the media. Sends a |
| 162 * play or pause command to the browser. |
| 163 * |
| 164 * @private |
| 165 */ |
| 166 onPlayPause_: function() { |
| 167 if (this.routeStatus.isPaused) { |
| 168 media_router.browserApi.playCurrentMedia(); |
| 169 } else { |
| 170 media_router.browserApi.pauseCurrentMedia(); |
| 171 } |
| 172 }, |
| 173 |
| 174 /** |
| 175 * Resets the route controls. Called when the route details view is closed. |
| 176 */ |
| 177 reset: function() { |
| 178 this.routeStatus = new media_router.RouteStatus( |
| 179 '', '', false, false, false, false, false, false, 0, 0, 0); |
| 180 media_router.ui.setRouteControls(null); |
| 181 }, |
| 182 |
| 183 /** |
| 184 * Updates seek and volume bars if the user is not currently dragging on |
| 185 * them. |
| 186 * @param {!media_router.RouteStatus} newRouteStatus |
| 187 * |
| 188 * @private |
| 189 */ |
| 190 onRouteStatusChange_: function(newRouteStatus) { |
| 191 if (!this.isSeeking_) { |
| 192 this.displayedCurrentTime_ = newRouteStatus.currentTime; |
| 193 } |
| 194 if (!this.isVolumeChanging_) { |
| 195 this.displayedVolume_ = newRouteStatus.volume; |
| 196 } |
| 197 if (newRouteStatus.description !== '') { |
| 198 this.displayedDescription_ = newRouteStatus.description; |
| 199 } |
| 200 }, |
| 201 |
| 202 /** |
| 203 * Called when the route is updated. Updates the description shown if it has |
| 204 * not been provided by status updates. |
| 205 * @param {!media_router.Route} route |
| 206 */ |
| 207 onRouteUpdated: function(route) { |
| 208 if (this.routeStatus.description === '') { |
| 209 this.displayedDescription_ = |
| 210 loadTimeData.getStringF('castingActivityStatus', route.description); |
| 211 } |
| 212 }, |
| 213 |
| 214 /** |
| 215 * Called when the user clicks on or stops dragging the seek bar. |
| 216 * @param {!Event} e |
| 217 * |
| 218 * @private |
| 219 */ |
| 220 onSeekComplete_: function(e) { |
| 221 this.isSeeking_ = false; |
| 222 this.displayedCurrentTime_ = e.target.value; |
| 223 media_router.browserApi.seekCurrentMedia(this.displayedCurrentTime_); |
| 224 }, |
| 225 |
| 226 /** |
| 227 * Called when the user starts dragging the seek bar. |
| 228 * @param {!Event} e |
| 229 * |
| 230 * @private |
| 231 */ |
| 232 onSeekStart_: function(e) { |
| 233 this.isSeeking_ = true; |
| 234 var target = /** @type {{immediateValue: number}} */ (e.target); |
| 235 this.displayedCurrentTime_ = target.immediateValue; |
| 236 }, |
| 237 |
| 238 /** |
| 239 * Called when the user clicks on or stops dragging the volume bar. |
| 240 * @param {!Event} e |
| 241 * |
| 242 * @private |
| 243 */ |
| 244 onVolumeChangeComplete_: function(e) { |
| 245 this.isVolumeChanging_ = false; |
| 246 this.volumeSliderValue_ = e.target.value; |
| 247 media_router.browserApi.setCurrentMediaVolume(this.volumeSliderValue_); |
| 248 }, |
| 249 |
| 250 /** |
| 251 * Called when the user starts dragging the volume bar. |
| 252 * @param {!Event} e |
| 253 * |
| 254 * @private |
| 255 */ |
| 256 onVolumeChangeStart_: function(e) { |
| 257 this.isVolumeChanging_ = true; |
| 258 var target = /** @type {{immediateValue: number}} */ (e.target); |
| 259 this.volumeSliderValue_ = target.immediateValue; |
| 260 }, |
| 261 }); |
OLD | NEW |