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 |