From 0972ae879e52fc852898d9bdcdac1a887f3f5ea4 Mon Sep 17 00:00:00 2001 From: hirono Date: Tue, 11 Nov 2014 23:51:24 -0800 Subject: [PATCH] Files.app: Cache thumbnail DOM of GridView. The CL adds a cache to GridView's thumbnail to enable the view to create the items' DOM synchronously. The unused cache is removed just after updating the view's DOM in overriden the mergeItems method. BUG=316050 TEST=copy files on Download directory and observe thumbnails. Review URL: https://codereview.chromium.org/712313002 Cr-Commit-Position: refs/heads/master@{#303803} --- .../file_manager/foreground/js/ui/file_grid.js | 66 ++++++++++++++++++++-- .../file_manager/foreground/js/ui/preview_panel.js | 1 + 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js index 123d5ad3f9e9..ebb82262d4cc 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js @@ -45,9 +45,42 @@ FileGrid.decorate = function(self, metadataCache, volumeManager) { self.scrollBar_.initialize(self.parentElement, self); self.setBottomMarginForPanel(0); + /** + * Map of URL and ListItem generated at the previous update time. + * This is used for updating existing item synchronously. + * @type {Object.} + * @private + * @const + */ + self.previousItems_ = {}; + self.itemConstructor = function(entry) { - var item = self.ownerDocument.createElement('LI'); + var item = self.previousItems_[entry.toURL()]; + if (item) { + // At this point, previous items that are needed to be replaced have been + // removed. + assert(item.parentElement == null); + + // If the thumbnail has already been loaded, mark it cached to prevent + // playing fadein animation. Then update the thumbnail. + var img = item.querySelector('img'); + if (img) { + img.classList.add('cached'); + FileGrid.decorateThumbnailBox( + item.querySelector('.thumbnail-frame div'), + entry, + self.metadataCache_, + self.volumeManager_, + ThumbnailLoader.FillMode.AUTO, + FileGrid.ThumbnailQuality.LOW, + /* animation */ false); + } + return item; + } + item = self.ownerDocument.createElement('LI'); FileGrid.Item.decorate(item, entry, /** @type {FileGrid} */ (self)); + self.previousItems_[entry.toURL()] = + /** @type {!FileGrid.Item} */ (item); return item; }; @@ -56,6 +89,19 @@ FileGrid.decorate = function(self, metadataCache, volumeManager) { }; /** + * @override + */ +FileGrid.prototype.mergeItems = function() { + cr.ui.Grid.prototype.mergeItems.apply(this, arguments); + + // Update item cache. + for (var url in this.previousItems_) { + if (this.getIndexOfListItem(this.previousItems_[url]) === -1) + delete this.previousItems_[url]; + } +}; + +/** * Updates items to reflect metadata changes. * @param {string} type Type of metadata changed. * @param {Array.} entries Entries whose metadata changed. @@ -74,8 +120,9 @@ FileGrid.prototype.updateListItemsMetadata = function(type, entries) { entry, this.metadataCache_, this.volumeManager_, - ThumbnailLoader.FillMode.FIT, - FileGrid.ThumbnailQuality.LOW); + ThumbnailLoader.FillMode.AUTO, + FileGrid.ThumbnailQuality.LOW, + /* animation */ false); } }; @@ -121,7 +168,8 @@ FileGrid.decorateThumbnail = function(li, entry, metadataCache, volumeManager) { metadataCache, volumeManager, ThumbnailLoader.FillMode.AUTO, - FileGrid.ThumbnailQuality.LOW); + FileGrid.ThumbnailQuality.LOW, + /* animation */ true); } frame.appendChild(box); @@ -140,12 +188,13 @@ FileGrid.decorateThumbnail = function(li, entry, metadataCache, volumeManager) { * @param {VolumeManagerWrapper} volumeManager Volume manager instance. * @param {ThumbnailLoader.FillMode} fillMode Fill mode. * @param {FileGrid.ThumbnailQuality} quality Thumbnail quality. + * @param {boolean} animation Whther to use fadein animation or not. * @param {function(HTMLImageElement)=} opt_imageLoadCallback Callback called * when the image has been loaded before inserting it into the DOM. */ FileGrid.decorateThumbnailBox = function( box, entry, metadataCache, volumeManager, fillMode, quality, - opt_imageLoadCallback) { + animation, opt_imageLoadCallback) { var locationInfo = volumeManager.getLocationInfo(entry); box.className = 'img-container'; @@ -190,7 +239,12 @@ FileGrid.decorateThumbnailBox = function( load(box, fillMode, ThumbnailLoader.OptimizationMode.DISCARD_DETACHED, - opt_imageLoadCallback); + function(image, transform) { + if (animation == false) + image.classList.add('cached'); + if (opt_imageLoadCallback) + opt_imageLoadCallback(image); + }); }); }; diff --git a/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js b/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js index c93b59bce3b2..eb15c77c9a9e 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js +++ b/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js @@ -454,6 +454,7 @@ PreviewPanel.Thumbnails.prototype.loadThumbnails_ = function(selection) { this.volumeManager_, ThumbnailLoader.FillMode.FILL, FileGrid.ThumbnailQuality.LOW, + /* animation */ false, i == 0 && length == 1 ? this.setZoomedImage_.bind(this) : undefined); } -- 2.11.4.GIT