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

Unified Diff: chrome/browser/resources/media_router/elements/route_details/route_details.js

Issue 2725503002: [Media Router] Custom Controls 4 - Implement details view WebUI (Closed)
Patch Set: . Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
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;
- });
- },
});

Powered by Google App Engine
This is Rietveld 408576698