| Index: chrome/browser/resources/media_router/elements/route_details/route_details.js
|
| diff --git a/chrome/browser/resources/media_router/elements/route_details/route_details.js b/chrome/browser/resources/media_router/elements/route_details/route_details.js
|
| index ae7ebcca5e1d63a66b704f13ce420e12c896879c..e343d6aa72b9f826c9ebf0c94e2b01e51ec01641 100644
|
| --- a/chrome/browser/resources/media_router/elements/route_details/route_details.js
|
| +++ b/chrome/browser/resources/media_router/elements/route_details/route_details.js
|
| @@ -24,7 +24,36 @@ Polymer({
|
| changeRouteSourceAvailable_: {
|
| type: Boolean,
|
| computed: 'computeChangeRouteSourceAvailable_(route, sink,' +
|
| - 'isAnySinkCurrentlyLaunching, shownCastModeValue)',
|
| + 'isAnySinkCurrentlyLaunching, shownCastModeValue)',
|
| + },
|
| +
|
| + /**
|
| + * The current time displayed in milliseconds.
|
| + * @type {number}
|
| + */
|
| + displayedCurrentTime_: {
|
| + type: Number,
|
| + value: 0
|
| + },
|
| +
|
| + /**
|
| + * Whether updates for the current time from the browser should be ignored.
|
| + * Set to true when the user is dragging the time slider.
|
| + * @private {boolean}
|
| + */
|
| + ignoreExternalTimeUpdates_: {
|
| + type: Boolean,
|
| + value: false
|
| + },
|
| +
|
| + /**
|
| + * Whether volume updates from the browser should be ignored. Set to true
|
| + * when the user is dragging the volume slider.
|
| + * @private {boolean}
|
| + */
|
| + ignoreExternalVolumeUpdates_: {
|
| + type: Boolean,
|
| + value: false
|
| },
|
|
|
| /**
|
| @@ -42,7 +71,17 @@ Polymer({
|
| */
|
| route: {
|
| type: Object,
|
| - observer: 'maybeLoadCustomController_',
|
| + },
|
| +
|
| +
|
| + /**
|
| + * The status of the media route shown.
|
| + * @type {?media_router.RouteStatus}
|
| + */
|
| + routeStatus: {
|
| + type: Object,
|
| + observer: 'onRouteStatusChange_',
|
| + value: null
|
| },
|
|
|
| /**
|
| @@ -65,14 +104,21 @@ Polymer({
|
| },
|
|
|
| /**
|
| - * Whether the custom controller should be hidden.
|
| - * A custom controller is shown iff |route| specifies customControllerPath
|
| - * and the view can be loaded.
|
| - * @private {boolean}
|
| + * The value of the time slider, between 0 and 100.
|
| + * @type {number}
|
| */
|
| - isCustomControllerHidden_: {
|
| - type: Boolean,
|
| - value: true,
|
| + timeSliderValue_: {
|
| + type: Number,
|
| + value: 0
|
| + },
|
| +
|
| + /**
|
| + * The value of the volume slider, between 0 and 100.
|
| + * @type {number}
|
| + */
|
| + volumeSliderValue_: {
|
| + type: Number,
|
| + value: 0
|
| },
|
| },
|
|
|
| @@ -155,6 +201,209 @@ Polymer({
|
| },
|
|
|
| /**
|
| + * @param {number} seekPosition The seek position in milliseconds.
|
| + * @param {number} duration The duration in milliseconds.
|
| + * @return {number} The seek position as a percentage between 0 and 100.
|
| + *
|
| + * @private
|
| + */
|
| + getSeekPositionPercentage_: function(seekPosition, duration) {
|
| + return duration ? (seekPosition / duration * 100) : 0;
|
| + },
|
| +
|
| + /**
|
| + * @param {number} seekPositionPercentage Must be between 0 and 100.
|
| + * @param {number} duration The duration in milliseconds.
|
| + * @return {number} The seek position in milliseconds.
|
| + *
|
| + * @private
|
| + */
|
| + getSeekPosition_: function(seekPositionPercentage, duration) {
|
| + return duration ? (seekPositionPercentage * duration / 100) : 0;
|
| + },
|
| +
|
| + /**
|
| + * Gets the duration formatted in HH:MM:SS format.
|
| + * @param {?media_router.RouteStatus} routeStatus
|
| + * @return {string}
|
| + *
|
| + * @private
|
| + */
|
| + getDuration_: function(routeStatus) {
|
| + return routeStatus ? this.getFormattedTime_(routeStatus.duration) : '';
|
| + },
|
| +
|
| + /**
|
| + * Converts a number representing an interval of milliseconds to a string with
|
| + * HH:MM:SS format.
|
| + * @param {number} timeInMilliSec Must be positive. Intervals longer than 100
|
| + * hours get truncated silently.
|
| + * @return {string}
|
| + *
|
| + * @private
|
| + */
|
| + getFormattedTime_: function(timeInMilliSec) {
|
| + if (timeInMilliSec < 0) {
|
| + return '';
|
| + }
|
| + var hours = Math.floor(timeInMilliSec / 3600 / 1000);
|
| + var minutes = Math.floor(timeInMilliSec / 60 / 1000) % 60;
|
| + var seconds = Math.floor(timeInMilliSec / 1000) % 60;
|
| + var timeParts = [
|
| + ('0' + hours).substr(-2), ('0' + minutes).substr(-2),
|
| + ('0' + seconds).substr(-2)
|
| + ];
|
| + return timeParts.join(':');
|
| + },
|
| +
|
| + /**
|
| + * @param {?media_router.RouteStatus} routeStatus
|
| + * @return {string} The value for the icon attribute of the mute/unmute
|
| + * button.
|
| + *
|
| + * @private
|
| + */
|
| + getMuteUnmuteIcon_: function(routeStatus) {
|
| + return (routeStatus && routeStatus.isMuted) ? 'av:volume-off' :
|
| + 'av:volume-up';
|
| + },
|
| +
|
| + /**
|
| + * @param {?media_router.RouteStatus} routeStatus
|
| + * @return {string} Localized title for the mute/unmute button.
|
| + *
|
| + * @private
|
| + */
|
| + getMuteUnmuteTitle_: function(routeStatus) {
|
| + return (routeStatus && routeStatus.isMuted) ? this.i18n('unmuteTitle') :
|
| + this.i18n('muteTitle');
|
| + },
|
| +
|
| + /**
|
| + * @param {?media_router.RouteStatus} routeStatus
|
| + * @return {string}The value for the icon attribute of the play/pause button.
|
| + *
|
| + * @private
|
| + */
|
| + getPlayPauseIcon_: function(routeStatus) {
|
| + return (routeStatus && routeStatus.isPaused) ? 'av:play-arrow' : 'av:pause';
|
| + },
|
| +
|
| + /**
|
| + * @param {?media_router.RouteStatus} routeStatus
|
| + * @return {string} Localized title for the play/pause button.
|
| + *
|
| + * @private
|
| + */
|
| + getPlayPauseTitle_: function(routeStatus) {
|
| + return (routeStatus && routeStatus.isPaused) ? this.i18n('playTitle') :
|
| + this.i18n('pauseTitle');
|
| + },
|
| +
|
| + /**
|
| + * Sends a play or pause command to the browser.
|
| + *
|
| + * @private
|
| + */
|
| + onPlayPause_: function() {
|
| + if (this.routeStatus.isPaused) {
|
| + this.fire('play-route');
|
| + } else {
|
| + this.fire('pause-route');
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Sends a mute or unmute command to the browser.
|
| + *
|
| + * @private
|
| + */
|
| + onMuteUnmute_: function() {
|
| + this.fire('set-route-mute', {mute: !this.routeStatus.isMuted});
|
| + },
|
| +
|
| + /**
|
| + * Updates seek and volume sliders if the user is not currently dragging on
|
| + * them.
|
| + * @param {?media_router.RouteStatus} newRouteStatus
|
| + * @param {?media_router.RouteStatus} oldRouteStatus
|
| + *
|
| + * @private
|
| + */
|
| + onRouteStatusChange_: function(newRouteStatus, oldRouteStatus) {
|
| + if (!newRouteStatus)
|
| + return;
|
| +
|
| + if (!this.ignoreExternalTimeUpdates_) {
|
| + this.displayedCurrentTime_ = newRouteStatus.currentTime;
|
| + this.timeSliderValue_ = this.getSeekPositionPercentage_(
|
| + newRouteStatus.currentTime, newRouteStatus.duration);
|
| + }
|
| +
|
| + if (!this.ignoreExternalVolumeUpdates_) {
|
| + this.volumeSliderValue_ = newRouteStatus.volume;
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Called when the user starts dragging the current-time slider.
|
| + * @param {!Event} e
|
| + *
|
| + * @private
|
| + */
|
| + onImmediateTimeSliderChange_: function(e) {
|
| + this.ignoreExternalTimeUpdates_ = true;
|
| + /** @type {{immediateValue: number}} */
|
| + var target = e.target;
|
| + this.timeSliderValue_ = target.immediateValue;
|
| + this.displayedCurrentTime_ = this.getSeekPosition_(
|
| + this.timeSliderValue_, this.routeStatus.duration);
|
| + },
|
| +
|
| + /**
|
| + * Called when the user clicks on or stops dragging the current-time slider.
|
| + * @param {!Event} e
|
| + *
|
| + * @private
|
| + */
|
| + onTimeSliderChange_: function(e) {
|
| + this.ignoreExternalTimeUpdates_ = false;
|
| + /** @type {{value: number}} */
|
| + var target = e.target;
|
| + this.timeSliderValue_ = target.value;
|
| + this.displayedCurrentTime_ = this.getSeekPosition_(
|
| + this.timeSliderValue_, this.routeStatus.duration);
|
| + this.fire('seek-route', {time: this.displayedCurrentTime_});
|
| + },
|
| +
|
| + /**
|
| + * Called when the user starts dragging the volume slider.
|
| + * @param {!Event} e
|
| + *
|
| + * @private
|
| + */
|
| + onImmediateVolumeSliderChange_: function(e) {
|
| + this.ignoreExternalVolumeUpdates_ = true;
|
| + /** @type {{immediateValue: number}} */
|
| + var target = e.target;
|
| + this.volumeSliderValue_ = target.immediateValue;
|
| + },
|
| +
|
| + /**
|
| + * Called when the user clicks on or stops dragging the volume slider.
|
| + * @param {!Event} e
|
| + *
|
| + * @private
|
| + */
|
| + onVolumeSliderChange_: function(e) {
|
| + this.ignoreExternalVolumeUpdates_ = false;
|
| + /** @type {{value: number}} */
|
| + var target = e.target;
|
| + this.volumeSliderValue_ = target.value;
|
| + this.fire('set-route-volume', {volume: this.volumeSliderValue_});
|
| + },
|
| +
|
| + /**
|
| * Fires a join-route-click event if the current route is joinable, otherwise
|
| * it fires a change-route-source-click event, which changes the source of the
|
| * current route. This may cause the current route to be closed and a new
|
| @@ -174,41 +423,4 @@ Polymer({
|
| });
|
| }
|
| },
|
| -
|
| - /**
|
| - * Loads the custom controller if |route.customControllerPath| exists.
|
| - * Falls back to the default route details view otherwise, or if load fails.
|
| - * Updates |activityStatus_| for the default view.
|
| - *
|
| - * @private
|
| - */
|
| - maybeLoadCustomController_: function() {
|
| - this.activityStatus_ = this.route ?
|
| - loadTimeData.getStringF('castingActivityStatus',
|
| - this.route.description) :
|
| - '';
|
| -
|
| - if (!this.route || !this.route.customControllerPath) {
|
| - this.isCustomControllerHidden_ = true;
|
| - return;
|
| - }
|
| -
|
| - // Show custom controller
|
| - var extensionview = this.$['custom-controller'];
|
| -
|
| - // Do nothing if the url is the same and the view is not hidden.
|
| - if (this.route.customControllerPath == extensionview.src &&
|
| - !this.isCustomControllerHidden_)
|
| - return;
|
| -
|
| - var that = this;
|
| - extensionview.load(this.route.customControllerPath)
|
| - .then(function() {
|
| - // Load was successful; show the custom controller.
|
| - that.isCustomControllerHidden_ = false;
|
| - }, function() {
|
| - // Load was unsuccessful; fall back to default view.
|
| - that.isCustomControllerHidden_ = true;
|
| - });
|
| - },
|
| });
|
|
|