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

Side by Side Diff: ui/file_manager/gallery/js/gallery.js

Issue 470983002: Gallery: Load gallery items by chunk on startup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove unused method. Created 6 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | ui/file_manager/gallery/js/mosaic_mode.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 'use strict'; 5 'use strict';
6 6
7 /** 7 /**
8 * Called from the main frame when unloading. 8 * Called from the main frame when unloading.
9 * @param {boolean=} opt_exiting True if the app is exiting. 9 * @param {boolean=} opt_exiting True if the app is exiting.
10 */ 10 */
11 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting); } 11 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting); }
12 12
13 /** 13 /**
14 * Overrided metadata worker's path. 14 * Overrided metadata worker's path.
15 * @type {string} 15 * @type {string}
16 * @const 16 * @const
17 */ 17 */
18 ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js'; 18 ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js';
19 19
20 /** 20 /**
21 * Data model for gallery. 21 * Data model for gallery.
22 * 22 *
23 * @param {MetadataCache} metadataCache Metadata cache.
23 * @constructor 24 * @constructor
24 * @extends {cr.ui.ArrayDataModel} 25 * @extends {cr.ui.ArrayDataModel}
25 */ 26 */
26 function GalleryDataModel() { 27 function GalleryDataModel(metadataCache) {
27 cr.ui.ArrayDataModel.call(this, []); 28 cr.ui.ArrayDataModel.call(this, []);
28 this.metadataCache_ = null; 29 this.metadataCache_ = metadataCache;
29 } 30 }
30 31
31 /** 32 /**
32 * Maximum number of full size image cache. 33 * Maximum number of full size image cache.
33 * @type {number} 34 * @type {number}
34 * @const 35 * @const
35 * @private 36 * @private
36 */ 37 */
37 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3; 38 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3;
38 39
39 /** 40 /**
40 * Maximum number of screen size image cache. 41 * Maximum number of screen size image cache.
41 * @type {number} 42 * @type {number}
42 * @const 43 * @const
43 * @private 44 * @private
44 */ 45 */
45 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5; 46 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5;
46 47
47 GalleryDataModel.prototype = { 48 GalleryDataModel.prototype = {
48 __proto__: cr.ui.ArrayDataModel.prototype 49 __proto__: cr.ui.ArrayDataModel.prototype
49 }; 50 };
50 51
51 /** 52 /**
52 * Initializes the data model.
53 *
54 * @param {MetadataCache} metadataCache Metadata cache.
55 * @param {Array.<FileEntry>} entries Image entries.
56 * @return {Promise} Promise to be fulfilled with after initialization.
57 */
58 GalleryDataModel.prototype.initialize = function(metadataCache, entries) {
59 // Store metadata cache.
60 this.metadataCache_ = metadataCache;
61
62 // Obtain metadata.
63 var metadataPromise = new Promise(function(fulfill) {
64 this.metadataCache_.get(entries, Gallery.METADATA_TYPE, fulfill);
65 }.bind(this));
66
67 // Initialize the gallery by using the metadata.
68 return metadataPromise.then(function(metadata) {
69 // Check the length of metadata.
70 if (entries.length !== metadata.length)
71 return Promise.reject('Failed to obtain metadata for the entries.');
72
73 // Obtains items.
74 var items = entries.map(function(entry, i) {
75 var clonedMetadata = MetadataCache.cloneMetadata(metadata[i]);
76 return new Gallery.Item(
77 entry, clonedMetadata, metadataCache, /* original */ true);
78 });
79
80 // Update the models.
81 this.push.apply(this, items);
82 }.bind(this));
83 };
84
85 /**
86 * Saves new image. 53 * Saves new image.
87 * 54 *
88 * @param {Gallery.Item} item Original gallery item. 55 * @param {Gallery.Item} item Original gallery item.
89 * @param {Canvas} canvas Canvas containing new image. 56 * @param {Canvas} canvas Canvas containing new image.
90 * @param {boolean} overwrite Whether to overwrite the image to the item or not. 57 * @param {boolean} overwrite Whether to overwrite the image to the item or not.
91 * @return {Promise} Promise to be fulfilled with when the operation completes. 58 * @return {Promise} Promise to be fulfilled with when the operation completes.
92 */ 59 */
93 GalleryDataModel.prototype.saveItem = function(item, canvas, overwrite) { 60 GalleryDataModel.prototype.saveItem = function(item, canvas, overwrite) {
94 var oldEntry = item.getEntry(); 61 var oldEntry = item.getEntry();
95 var oldMetadata = item.getMetadata(); 62 var oldMetadata = item.getMetadata();
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 loadTimeData: {} 183 loadTimeData: {}
217 }; 184 };
218 this.container_ = document.querySelector('.gallery'); 185 this.container_ = document.querySelector('.gallery');
219 this.document_ = document; 186 this.document_ = document;
220 this.metadataCache_ = this.context_.metadataCache; 187 this.metadataCache_ = this.context_.metadataCache;
221 this.volumeManager_ = volumeManager; 188 this.volumeManager_ = volumeManager;
222 this.selectedEntry_ = null; 189 this.selectedEntry_ = null;
223 this.metadataCacheObserverId_ = null; 190 this.metadataCacheObserverId_ = null;
224 this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this); 191 this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this);
225 192
226 this.dataModel_ = new GalleryDataModel(); 193 this.dataModel_ = new GalleryDataModel(this.context_.metadataCache);
227 this.selectionModel_ = new cr.ui.ListSelectionModel(); 194 this.selectionModel_ = new cr.ui.ListSelectionModel();
228 195
229 this.initDom_(); 196 this.initDom_();
230 this.initListeners_(); 197 this.initListeners_();
231 } 198 }
232 199
233 /** 200 /**
234 * Gallery extends cr.EventTarget. 201 * Gallery extends cr.EventTarget.
235 */ 202 */
236 Gallery.prototype.__proto__ = cr.EventTarget.prototype; 203 Gallery.prototype.__proto__ = cr.EventTarget.prototype;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 return button; 396 return button;
430 }; 397 };
431 398
432 /** 399 /**
433 * Loads the content. 400 * Loads the content.
434 * 401 *
435 * @param {!Array.<Entry>} entries Array of entries. 402 * @param {!Array.<Entry>} entries Array of entries.
436 * @param {!Array.<Entry>} selectedEntries Array of selected entries. 403 * @param {!Array.<Entry>} selectedEntries Array of selected entries.
437 */ 404 */
438 Gallery.prototype.load = function(entries, selectedEntries) { 405 Gallery.prototype.load = function(entries, selectedEntries) {
439 this.dataModel_.initialize(this.metadataCache_, entries).then(function() { 406 // Obtains max chank size.
440 // Apply selection. 407 var maxChunkSize = 20;
441 this.selectionModel_.adjustLength(this.dataModel_.length); 408 var volumeInfo = this.volumeManager_.getVolumeInfo(entries[0]);
442 var entryIndexesByURLs = {}; 409 if (volumeInfo &&
443 for (var index = 0; index < entries.length; index++) { 410 volumeInfo.volumeType === VolumeManagerCommon.VolumeType.MTP) {
444 entryIndexesByURLs[entries[index].toURL()] = index; 411 maxChunkSize = 1;
445 } 412 }
446 for (var i = 0; i !== selectedEntries.length; i++) {
447 var selectedIndex = entryIndexesByURLs[selectedEntries[i].toURL()];
448 if (selectedIndex !== undefined)
449 this.selectionModel_.setIndexSelected(selectedIndex, true);
450 else
451 console.error('Cannot select ' + selectedEntries[i]);
452 }
453 if (this.selectionModel_.selectedIndexes.length === 0)
454 this.onSelection_();
455 413
456 // Determine the initial mode. 414 // Make loading list.
457 var shouldShowMosaic = selectedEntries.length > 1 || 415 var entrySet = {};
458 (this.context_.pageState && 416 for (var i = 0; i < entries.length; i++) {
459 this.context_.pageState.gallery === 'mosaic'); 417 var entry = entries[i];
460 this.setCurrentMode_(shouldShowMosaic ? this.mosaicMode_ : this.slideMode_); 418 entrySet[entry.toURL()] = {
419 entry: entry,
420 selected: false,
421 index: i
422 };
423 }
424 for (var i = 0; i < selectedEntries.length; i++) {
425 var entry = selectedEntries[i];
426 entrySet[entry.toURL()] = {
427 entry: entry,
428 selected: true,
429 index: i
430 };
431 }
432 var loadingList = [];
433 for (var url in entrySet) {
434 loadingList.push(entrySet[url]);
435 }
436 loadingList = loadingList.sort(function(a, b) {
437 if (a.selected && !b.selected)
438 return -1;
439 else if (!a.selected && b.selected)
440 return 1;
441 else
442 return a.index - b.index;
443 });
461 444
462 // Init mosaic mode. 445 // Load entries.
463 var mosaic = this.mosaicMode_.getMosaic(); 446 var loadChunk = function(firstChunk) {
yoshiki 2014/08/15 05:47:39 loadChunk is called many times. Function.bind() is
hirono 2014/08/15 07:05:25 Done.
464 mosaic.init(); 447 // Extract chunk.
448 var chunk = loadingList.splice(0, maxChunkSize);
449 if (!chunk.length)
450 return;
465 451
466 // Do the initialization for each mode. 452 return new Promise(function(fulfill) {
467 if (shouldShowMosaic) { 453 // Obtains metadata for chunk.
468 mosaic.show(); 454 var entries = chunk.map(function(chunkItem) {
469 this.inactivityWatcher_.check(); // Show the toolbar. 455 return chunkItem.entry;
470 cr.dispatchSimpleEvent(this, 'loaded'); 456 });
471 } else { 457 this.metadataCache_.get(entries, Gallery.METADATA_TYPE, fulfill);
472 this.slideMode_.enter( 458 }.bind(this)).then(function(metadataList) {
473 null, 459 if (chunk.length !== metadataList.length)
474 function() { 460 return Promise.reject('Failed to load metadata.');
475 // Flash the toolbar briefly to show it is there. 461
476 this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT); 462 // Add items to the model.
477 }.bind(this), 463 var items = chunk.map(function(chunkItem, index) {
478 function() { 464 var clonedMetadata = MetadataCache.cloneMetadata(metadataList[index]);
479 cr.dispatchSimpleEvent(this, 'loaded'); 465 return new Gallery.Item(
480 }.bind(this)); 466 chunkItem.entry,
481 } 467 clonedMetadata,
482 }.bind(this)).catch(function(error) { 468 this.metadataCache_,
469 /* original */ true);
470 }.bind(this));
471 this.dataModel_.push.apply(this.dataModel_, items);
472
473 // Apply the selection.
474 var selectionUpdated = false;
475 for (var i = 0; i < chunk.length; i++) {
476 if (!chunk[i].selected)
477 continue;
478 var index = this.dataModel_.indexOf(items[i]);
479 if (index < 0)
480 continue;
481 this.selectionModel_.setIndexSelected(index);
482 selectionUpdated = true;
483 }
484 if (selectionUpdated)
485 this.onSelection_();
486
487 // Init modes after the first chunk is loaded.
488 if (firstChunk) {
489 // Determine the initial mode.
490 var shouldShowMosaic = selectedEntries.length > 1 ||
491 (this.context_.pageState &&
492 this.context_.pageState.gallery === 'mosaic');
493 this.setCurrentMode_(
494 shouldShowMosaic ? this.mosaicMode_ : this.slideMode_);
495
496 // Init mosaic mode.
497 var mosaic = this.mosaicMode_.getMosaic();
498 mosaic.init();
499
500 // Do the initialization for each mode.
501 if (shouldShowMosaic) {
502 mosaic.show();
503 this.inactivityWatcher_.check(); // Show the toolbar.
504 cr.dispatchSimpleEvent(this, 'loaded');
505 } else {
506 this.slideMode_.enter(
507 null,
508 function() {
509 // Flash the toolbar briefly to show it is there.
510 this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT);
511 }.bind(this),
512 function() {
513 cr.dispatchSimpleEvent(this, 'loaded');
514 }.bind(this));
515 }
516 }
517
518 // Continue to load chunks.
519 return loadChunk(/* firstChunk */ false);
520 }.bind(this));
521 }.bind(this);
522 loadChunk(/* firstChunk */ true).catch(function(error) {
483 console.error(error.stack || error); 523 console.error(error.stack || error);
484 }); 524 });
485 }; 525 };
486 526
487 /** 527 /**
488 * Handles user's 'Close' action. 528 * Handles user's 'Close' action.
489 * @private 529 * @private
490 */ 530 */
491 Gallery.prototype.onClose_ = function() { 531 Gallery.prototype.onClose_ = function() {
492 this.executeWhenReady(this.context_.onClose); 532 this.executeWhenReady(this.context_.onClose);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 window.loadTimeData.data = backgroundComponents.stringData; 981 window.loadTimeData.data = backgroundComponents.stringData;
942 gallery = new Gallery(backgroundComponents.volumeManager); 982 gallery = new Gallery(backgroundComponents.volumeManager);
943 }; 983 };
944 984
945 /** 985 /**
946 * Loads entries. 986 * Loads entries.
947 */ 987 */
948 window.loadEntries = function(entries, selectedEntries) { 988 window.loadEntries = function(entries, selectedEntries) {
949 gallery.load(entries, selectedEntries); 989 gallery.load(entries, selectedEntries);
950 }; 990 };
OLDNEW
« no previous file with comments | « no previous file | ui/file_manager/gallery/js/mosaic_mode.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698