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

Unified Diff: chrome/browser/resources/file_manager/audio_player/elements/track_list.js

Issue 144713008: [AudioPlayer] Implement shuffle mode (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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/file_manager/audio_player/elements/track_list.js
diff --git a/chrome/browser/resources/file_manager/audio_player/elements/track_list.js b/chrome/browser/resources/file_manager/audio_player/elements/track_list.js
index 5faee2daac83b046a3f0ee69522b277a1c183b1b..be5263b632c69654e34143a8851737441680a513 100644
--- a/chrome/browser/resources/file_manager/audio_player/elements/track_list.js
+++ b/chrome/browser/resources/file_manager/audio_player/elements/track_list.js
@@ -23,6 +23,12 @@
tracks: [],
/**
+ * Play order of the tracks. Each value is the index of 'this.tracks'.
+ * @type {Array.<number>}
+ */
+ playOrder: [],
+
+ /**
* Track index of the current track.
* If the tracks propertye is empty, it should be -1. Otherwise, be a valid
* track number.
@@ -32,6 +38,21 @@
currentTrackIndex: -1,
/**
+ * Flag whether the shuffle mode is enabled.
+ * @type {boolean}
+ */
+ shuffle: false,
+
+ /**
+ * Invoked when 'shuffle' property is changed.
+ * @param {boolean} oldValue Old value.
+ * @param {boolean} newValue New value.
+ */
+ shuffleChanged: function(oldValue, newValue) {
+ this.generatePlayOrder(true /* keep the current track */);
+ },
+
+ /**
* Invoked when the current track index is changed.
* @param {number} oldValue old value.
* @param {number} newValue new value.
@@ -40,17 +61,23 @@
if (oldValue === newValue)
return;
- if (oldValue !== -1)
+ if (!isNaN(oldValue) && oldValue !== -1)
this.tracks[oldValue].active = false;
- if (newValue < 0 || this.tracks.length <= newValue) {
- if (this.tracks.length === 0)
- this.currentTrackIndex = -1;
- else
- this.currentTrackIndex = 0;
- } else {
- this.tracks[newValue].active = true;
+ if (0 <= newValue && newValue < this.tracks.length) {
+ var currentPlayOrder = this.playOrder.indexOf(newValue);
+ if (currentPlayOrder !== -1) {
+ // Success
+ this.tracks[newValue].active = true;
+ return;
+ }
}
+
+ // Invalid index
+ if (this.tracks.length === 0)
+ this.currentTrackIndex = -1;
+ else
+ this.generatePlayOrder(false /* no need to keep the current track */);
},
/**
@@ -59,16 +86,21 @@
*/
tracksChanged: function(oldValue, newValue) {
if (oldValue !== newValue) {
+ // Re-register the observer of 'this.tracks'.
this.tracksObserver_.close();
this.tracksObserver_ = new ArrayObserver(
this.tracks,
this.tracksValueChanged_.bind(this));
+
+ // Reset play order and current index.
if (this.tracks.length !== 0)
- this.currentTrackIndex = 0;
+ this.generatePlayOrder(false /* no need to keep the current track */);
}
- if (this.tracks.length === 0)
+ if (this.tracks.length === 0) {
+ this.playOrder = [];
this.currentTrackIndex = -1;
+ }
},
/**
@@ -92,6 +124,45 @@
},
/**
+ * Invoked when the track element is clicked.
+ * @param {Event} event Click event.
hirono 2014/02/03 08:09:52 nit: @param {boolean} keepCurrentTrack ... ?
yoshiki 2014/02/03 09:38:41 Yes, Thanks!
+ */
+ generatePlayOrder: function(keepCurrentTrack) {
+ if (this.tracks.length === 0) {
+ this.playOrder = [];
+ return;
+ }
+
+ // Creates sequenced array.
+ this.playOrder =
hirono 2014/02/03 08:09:52 How about: this.tracks.map(function(unused, index)
yoshiki 2014/02/03 09:38:41 Done.
+ Array.apply(null, Array(this.tracks.length)).
+ map(function(unused, index) { return index; });
+
+ if (this.shuffle) {
+ // Randomizes the play order array (Schwarzian-transform algorithm).
+ this.playOrder =
+ this.playOrder.
+ map(function(a) {
+ return {weight: Math.random(), index: a};
+ }).
+ sort(function(a, b) { return a.weight - b.weight }).
+ map(function(a) { return a.index });
+
+ if (keepCurrentTrack) {
+ // Puts the current track at the beginning of the play order.
+ this.playOrder =
+ this.playOrder.filter(function(value) {
+ return this.currentTrackIndex !== value;
+ }, this);
+ this.playOrder.splice(0, 0, this.currentTrackIndex);
+ }
+ }
+
+ if (!keepCurrentTrack)
+ this.currentTrackIndex = this.playOrder[0];
+ },
+
+ /**
* Sets the current track.
* @param {AudioPlayer.TrackInfo} track TrackInfo to be set as the current
* track.
@@ -127,23 +198,23 @@
* @return {AudioPlayer.TrackInfo} TrackInfo of the next track. If there is
hirono 2014/02/03 08:09:52 nit: @return {number} ... ?
yoshiki 2014/02/03 09:38:41 Done.
* no track, the return value is null.
*/
- getNextTrackIndex: function(forward) {
- var defaultTrack = forward ? 0 : (this.tracks.length - 1);
- var tentativeNewTrackIndex = this.currentTrackIndex + (forward ? +1 : -1);
- var newTrackIndex;
+ getNextTrackIndex: function(forward) {
+ if (this.tracks.length === 0)
+ return -1;
- if (this.tracks.length === 0) {
- newTrackIndex = -1;
- } else {
- if (this.currentTrackIndex === -1) {
- newTrackIndex = defaultTrack;
- } else if (0 <= tentativeNewTrackIndex &&
- tentativeNewTrackIndex < this.tracks.length) {
- newTrackIndex = tentativeNewTrackIndex;
- } else {
- newTrackIndex = defaultTrack;
- }
- }
+ var defaultTrack =
hirono 2014/02/03 08:09:52 Please rename it with defaultTrackIndex.
yoshiki 2014/02/03 09:38:41 Done.
+ forward ? this.playOrder[0] : this.playOrder[this.tracks.length - 1];
+
+ var currentPlayOrder = this.playOrder.indexOf(this.currentTrackIndex);
+ var newPlayOrder = currentPlayOrder + (forward ? +1 : -1);
+ // The below "if (!(...))" is intentional, to catch undefined and NaN.
+ if (!(0 <= newPlayOrder && newPlayOrder < this.tracks.length))
+ return defaultTrack;
+
+ var newTrackIndex = this.playOrder[newPlayOrder];
+ console.assert(
+ (0 <= newTrackIndex && newTrackIndex < this.tracks.length),
+ 'Insufficient TrackList.playOrder. New Play Order: ' + newPlayOrder);
return newTrackIndex;
},
@@ -157,21 +228,21 @@
* otherwise.
*/
isNextTrackAvailable: function(forward) {
- if (this.tracks.length === 0) {
+ if (this.tracks.length === 0)
return false;
- } else {
- var tentativeNewTrackIndex =
- this.currentTrackIndex + (forward ? +1 : -1);
-
- if (this.currentTrackIndex === -1) {
- return false;
- } else if (0 <= tentativeNewTrackIndex &&
- tentativeNewTrackIndex < this.tracks.length) {
- return true;
- } else {
- return false;
- }
- }
- }
+
+ var currentPlayOrder = this.playOrder.indexOf(this.currentTrackIndex);
+ var newPlayOrder = currentPlayOrder + (forward ? +1 : -1);
+ // The below "if (!(...))" is intentional, to catch undefined and NaN.
+ if (!(0 <= newPlayOrder && newPlayOrder < this.tracks.length))
hirono 2014/02/03 08:09:52 If currentPlayOrder is -1, it would return true. I
yoshiki 2014/02/03 09:38:41 It's ok. Added the comment to explain this.
hirono 2014/02/03 09:57:48 Maybe I lost the point. Can we ensure currentPlay
yoshiki 2014/02/03 10:46:14 That's good point. It shouldn't be occurred, but a
+ return false;
+
+ var newTrackIndex = this.playOrder[newPlayOrder];
+ console.assert(
+ (0 <= newTrackIndex && newTrackIndex < this.tracks.length),
+ 'Insufficient TrackList.playOrder. New Play Order: ' + newPlayOrder);
+
+ return true;
+ },
}); // Polymer('track-list') block
})(); // Anonymous closure

Powered by Google App Engine
This is Rietveld 408576698