OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Overrided metadata worker's path. | 6 * Overrided metadata worker's path. |
7 * @type {string} | 7 * @type {string} |
8 * @const | |
9 */ | 8 */ |
10 ContentMetadataProvider.WORKER_SCRIPT = '/js/metadata_worker.js'; | 9 ContentMetadataProvider.WORKER_SCRIPT = '/js/metadata_worker.js'; |
11 | 10 |
12 /** | 11 /** |
13 * @param {HTMLElement} container Container element. | 12 * @param {Element} container Container element. |
14 * @constructor | 13 * @constructor |
15 */ | 14 */ |
16 function AudioPlayer(container) { | 15 function AudioPlayer(container) { |
17 this.container_ = container; | 16 this.container_ = container; |
18 this.volumeManager_ = new VolumeManagerWrapper( | 17 this.volumeManager_ = new VolumeManagerWrapper( |
19 VolumeManagerWrapper.NonNativeVolumeStatus.ENABLED); | 18 VolumeManagerWrapper.NonNativeVolumeStatus.ENABLED); |
20 this.metadataModel_ = new MetadataModel.create(this.volumeManager_); | 19 this.metadataModel_ = MetadataModel.create(this.volumeManager_); |
21 this.selectedEntry_ = null; | 20 this.selectedEntry_ = null; |
| 21 this.invalidTracks_ = {}; |
22 | 22 |
23 this.model_ = new AudioPlayerModel(); | 23 this.model_ = new AudioPlayerModel(); |
24 Object.observe(this.model_, function(changes) { | 24 Object.observe(this.model_, function(changes) { |
25 for (var i = 0; i < changes.lenfth; i++) { | 25 for (var i = 0; i < changes.length; i++) { |
26 var change = changes[i]; | 26 var change = changes[i]; |
27 if (change.name == 'expanded' && change.type == 'update') { | 27 if (change.name == 'expanded' && change.type == 'update') { |
28 this.onModelExpandedChanged(change.oldValue, change.object.expanded); | 28 this.onModelExpandedChanged(change.oldValue, change.object.expanded); |
29 break; | 29 break; |
30 } | 30 } |
31 } | 31 } |
32 }.bind(this)); | 32 }.bind(this)); |
33 | 33 |
34 this.entries_ = []; | 34 this.entries_ = []; |
35 this.currentTrackIndex_ = -1; | 35 this.currentTrackIndex_ = -1; |
36 this.playlistGeneration_ = 0; | 36 this.playlistGeneration_ = 0; |
37 | 37 |
38 /** | 38 /** |
39 * Whether if the playlist is expanded or not. This value is changed by | 39 * Whether if the playlist is expanded or not. This value is changed by |
40 * this.syncExpanded(). | 40 * this.syncExpanded(). |
41 * True: expanded, false: collapsed, null: unset. | 41 * True: expanded, false: collapsed, null: unset. |
42 * | 42 * |
43 * @type {?boolean} | 43 * @type {?boolean} |
44 * @private | 44 * @private |
45 */ | 45 */ |
46 this.isExpanded_ = null; // Initial value is null. It'll be set in load(). | 46 this.isExpanded_ = null; // Initial value is null. It'll be set in load(). |
47 | 47 |
48 this.player_ = document.querySelector('audio-player'); | 48 this.player_ = |
| 49 /** @type {AudioPlayerElement} */ (document.querySelector('audio-player')); |
49 // TODO(yoshiki): Move tracks into the model. | 50 // TODO(yoshiki): Move tracks into the model. |
50 this.player_.tracks = []; | 51 this.player_.tracks = []; |
51 this.player_.model = this.model_; | 52 this.player_.model = this.model_; |
52 | 53 |
53 // Run asynchronously after an event of model change is delivered. | 54 // Run asynchronously after an event of model change is delivered. |
54 setTimeout(function() { | 55 setTimeout(function() { |
55 this.errorString_ = ''; | 56 this.errorString_ = ''; |
56 this.offlineString_ = ''; | 57 this.offlineString_ = ''; |
57 chrome.fileManagerPrivate.getStrings(function(strings) { | 58 chrome.fileManagerPrivate.getStrings(function(strings) { |
58 container.ownerDocument.title = strings['AUDIO_PLAYER_TITLE']; | 59 container.ownerDocument.title = strings['AUDIO_PLAYER_TITLE']; |
59 this.errorString_ = strings['AUDIO_ERROR']; | 60 this.errorString_ = strings['AUDIO_ERROR']; |
60 this.offlineString_ = strings['AUDIO_OFFLINE']; | 61 this.offlineString_ = strings['AUDIO_OFFLINE']; |
61 AudioPlayer.TrackInfo.DEFAULT_ARTIST = | 62 AudioPlayer.TrackInfo.DEFAULT_ARTIST = |
62 strings['AUDIO_PLAYER_DEFAULT_ARTIST']; | 63 strings['AUDIO_PLAYER_DEFAULT_ARTIST']; |
63 }.bind(this)); | 64 }.bind(this)); |
64 | 65 |
65 this.volumeManager_.addEventListener('externally-unmounted', | 66 this.volumeManager_.addEventListener('externally-unmounted', |
66 this.onExternallyUnmounted_.bind(this)); | 67 this.onExternallyUnmounted_.bind(this)); |
67 | 68 |
68 window.addEventListener('resize', this.onResize_.bind(this)); | 69 window.addEventListener('resize', this.onResize_.bind(this)); |
69 | 70 |
70 // Show the window after DOM is processed. | 71 // Show the window after DOM is processed. |
71 var currentWindow = chrome.app.window.current(); | 72 var currentWindow = chrome.app.window.current(); |
72 if (currentWindow) | 73 if (currentWindow) |
73 setTimeout(currentWindow.show.bind(currentWindow), 0); | 74 setTimeout(currentWindow.show.bind(currentWindow), 0); |
74 }.bind(this)); | 75 }.bind(this), 0); |
75 } | 76 } |
76 | 77 |
77 /** | 78 /** |
78 * Initial load method (static). | 79 * Initial load method (static). |
79 */ | 80 */ |
80 AudioPlayer.load = function() { | 81 AudioPlayer.load = function() { |
81 document.ondragstart = function(e) { e.preventDefault(); }; | 82 document.ondragstart = function(e) { e.preventDefault(); }; |
82 | 83 |
83 AudioPlayer.instance = | 84 AudioPlayer.instance = |
84 new AudioPlayer(document.querySelector('.audio-player')); | 85 new AudioPlayer(document.querySelector('.audio-player')); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 // is called, before the handler of the track index. | 148 // is called, before the handler of the track index. |
148 setTimeout(function() { | 149 setTimeout(function() { |
149 this.select_(position, !!time); | 150 this.select_(position, !!time); |
150 | 151 |
151 // Load the selected track metadata first, then load the rest. | 152 // Load the selected track metadata first, then load the rest. |
152 this.loadMetadata_(position); | 153 this.loadMetadata_(position); |
153 for (i = 0; i != this.entries_.length; i++) { | 154 for (i = 0; i != this.entries_.length; i++) { |
154 if (i != position) | 155 if (i != position) |
155 this.loadMetadata_(i); | 156 this.loadMetadata_(i); |
156 } | 157 } |
157 }.bind(this)); | 158 }.bind(this), 0); |
158 }.bind(this)); | 159 }.bind(this)); |
159 }.bind(this)); | 160 }.bind(this)); |
160 }; | 161 }; |
161 | 162 |
162 /** | 163 /** |
163 * Loads metadata for a track. | 164 * Loads metadata for a track. |
164 * @param {number} track Track number. | 165 * @param {number} track Track number. |
165 * @private | 166 * @private |
166 */ | 167 */ |
167 AudioPlayer.prototype.loadMetadata_ = function(track) { | 168 AudioPlayer.prototype.loadMetadata_ = function(track) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 util.saveAppState(); | 229 util.saveAppState(); |
229 | 230 |
230 var entry = this.entries_[this.currentTrackIndex_]; | 231 var entry = this.entries_[this.currentTrackIndex_]; |
231 | 232 |
232 this.fetchMetadata_(entry, function(metadata) { | 233 this.fetchMetadata_(entry, function(metadata) { |
233 if (this.currentTrackIndex_ != newTrack) | 234 if (this.currentTrackIndex_ != newTrack) |
234 return; | 235 return; |
235 | 236 |
236 this.selectedEntry_ = entry; | 237 this.selectedEntry_ = entry; |
237 }.bind(this)); | 238 }.bind(this)); |
238 }.bind(this)); | 239 }.bind(this), 0); |
239 }; | 240 }; |
240 | 241 |
241 /** | 242 /** |
242 * @param {FileEntry} entry Track file entry. | 243 * @param {FileEntry} entry Track file entry. |
243 * @param {function(object)} callback Callback. | 244 * @param {function(Object)} callback Callback. |
244 * @private | 245 * @private |
245 */ | 246 */ |
246 AudioPlayer.prototype.fetchMetadata_ = function(entry, callback) { | 247 AudioPlayer.prototype.fetchMetadata_ = function(entry, callback) { |
247 this.metadataModel_.get( | 248 this.metadataModel_.get( |
248 [entry], ['mediaTitle', 'mediaArtist', 'present']).then( | 249 [entry], ['mediaTitle', 'mediaArtist', 'present']).then( |
249 function(generation, metadata) { | 250 function(generation, metadata) { |
250 // Do nothing if another load happened since the metadata request. | 251 // Do nothing if another load happened since the metadata request. |
251 if (this.playlistGeneration_ == generation) | 252 if (this.playlistGeneration_ == generation) |
252 callback(metadata[0]); | 253 callback(metadata[0]); |
253 }.bind(this, this.playlistGeneration_)); | 254 }.bind(this, this.playlistGeneration_)); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 // Not expanded. | 374 // Not expanded. |
374 targetHeight = AudioPlayer.CONTROLS_HEIGHT + AudioPlayer.TRACK_HEIGHT; | 375 targetHeight = AudioPlayer.CONTROLS_HEIGHT + AudioPlayer.TRACK_HEIGHT; |
375 } | 376 } |
376 | 377 |
377 window.resizeTo(window.innerWidth, targetHeight + AudioPlayer.HEADER_HEIGHT); | 378 window.resizeTo(window.innerWidth, targetHeight + AudioPlayer.HEADER_HEIGHT); |
378 }; | 379 }; |
379 | 380 |
380 /** | 381 /** |
381 * Create a TrackInfo object encapsulating the information about one track. | 382 * Create a TrackInfo object encapsulating the information about one track. |
382 * | 383 * |
383 * @param {fileEntry} entry FileEntry to be retrieved the track info from. | 384 * @param {FileEntry} entry FileEntry to be retrieved the track info from. |
384 * @param {function} onClick Click handler. | 385 * @param {function(MouseEvent)} onClick Click handler. |
385 * @constructor | 386 * @constructor |
386 */ | 387 */ |
387 AudioPlayer.TrackInfo = function(entry, onClick) { | 388 AudioPlayer.TrackInfo = function(entry, onClick) { |
388 this.url = entry.toURL(); | 389 this.url = entry.toURL(); |
389 this.title = this.getDefaultTitle(); | 390 this.title = this.getDefaultTitle(); |
390 this.artist = this.getDefaultArtist(); | 391 this.artist = this.getDefaultArtist(); |
391 | 392 |
392 // TODO(yoshiki): implement artwork. | 393 // TODO(yoshiki): implement artwork. |
393 this.artwork = null; | 394 this.artwork = null; |
394 this.active = false; | 395 this.active = false; |
395 }; | 396 }; |
396 | 397 |
397 /** | 398 /** |
398 * @return {HTMLDivElement} The wrapper element for the track. | |
399 */ | |
400 AudioPlayer.TrackInfo.prototype.getBox = function() { return this.box_; }; | |
401 | |
402 /** | |
403 * @return {string} Default track title (file name extracted from the url). | 399 * @return {string} Default track title (file name extracted from the url). |
404 */ | 400 */ |
405 AudioPlayer.TrackInfo.prototype.getDefaultTitle = function() { | 401 AudioPlayer.TrackInfo.prototype.getDefaultTitle = function() { |
406 var title = this.url.split('/').pop(); | 402 var title = this.url.split('/').pop(); |
407 var dotIndex = title.lastIndexOf('.'); | 403 var dotIndex = title.lastIndexOf('.'); |
408 if (dotIndex >= 0) title = title.substr(0, dotIndex); | 404 if (dotIndex >= 0) title = title.substr(0, dotIndex); |
409 title = decodeURIComponent(title); | 405 title = decodeURIComponent(title); |
410 return title; | 406 return title; |
411 }; | 407 }; |
412 | 408 |
(...skipping 18 matching lines...) Expand all Loading... |
431 // TODO(yoshiki): Handle error in better way. | 427 // TODO(yoshiki): Handle error in better way. |
432 // TODO(yoshiki): implement artwork (metadata.thumbnail) | 428 // TODO(yoshiki): implement artwork (metadata.thumbnail) |
433 this.title = metadata.mediaTitle || this.getDefaultTitle(); | 429 this.title = metadata.mediaTitle || this.getDefaultTitle(); |
434 this.artist = error || metadata.mediaArtist || this.getDefaultArtist(); | 430 this.artist = error || metadata.mediaArtist || this.getDefaultArtist(); |
435 }; | 431 }; |
436 | 432 |
437 // Starts loading the audio player. | 433 // Starts loading the audio player. |
438 window.addEventListener('polymer-ready', function(e) { | 434 window.addEventListener('polymer-ready', function(e) { |
439 AudioPlayer.load(); | 435 AudioPlayer.load(); |
440 }); | 436 }); |
OLD | NEW |