| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * Controller of metadata box. |
| * This should be initialized with |init| method. |
| * |
| * @param{!MetadataModel} metadataModel |
| * @param{!QuickViewModel} quickViewModel |
| * @param{!FileMetadataFormatter} fileMetadataFormatter |
| * |
| * @constructor |
| */ |
| function MetadataBoxController( |
| metadataModel, quickViewModel, fileMetadataFormatter) { |
| /** |
| * @type {!MetadataModel} |
| * @private |
| */ |
| this.metadataModel_ = metadataModel; |
| |
| /** |
| * @type {!QuickViewModel} |
| * @private |
| */ |
| this.quickViewModel_ = quickViewModel; |
| |
| /** |
| * @type {FilesMetadataBox} metadataBox |
| * @private |
| */ |
| this.metadataBox_ = null; |
| |
| /** |
| * @type {FilesQuickView} quickView |
| * @private |
| */ |
| this.quickView_ = null; |
| |
| /** |
| * @type {!FileMetadataFormatter} |
| * @private |
| */ |
| this.fileMetadataFormatter_ = fileMetadataFormatter; |
| |
| /** |
| * @type {Entry} |
| * @private |
| */ |
| this.previousEntry_ = null; |
| |
| /** |
| * @type {boolean} |
| * @private |
| */ |
| this.isDirectorySizeLoading_ = false; |
| |
| /** |
| * @type {?function(!DirectoryEntry)} |
| * @private |
| */ |
| this.onDirectorySizeLoaded_ = null; |
| } |
| |
| /** |
| * Initialize the controller with quick view which will be lazily loaded. |
| * @param{!FilesQuickView} quickView |
| */ |
| MetadataBoxController.prototype.init = function(quickView) { |
| // TODO(oka): Add storage to persist the value of |
| // quickViewModel_.metadataBoxActive. |
| this.fileMetadataFormatter_.addEventListener( |
| 'date-time-format-changed', this.updateView_.bind(this)); |
| |
| quickView.addEventListener( |
| 'metadata-box-active-changed', this.updateView_.bind(this)); |
| |
| this.quickViewModel_.addEventListener( |
| 'selected-entry-changed', this.updateView_.bind(this)); |
| |
| this.metadataBox_ = quickView.getFilesMetadataBox(); |
| this.quickView_ = quickView; |
| }; |
| |
| /** |
| * @const {!Array<string>} |
| */ |
| MetadataBoxController.GENERAL_METADATA_NAME = [ |
| 'size', |
| 'modificationTime', |
| ]; |
| |
| /** |
| * Update the view of metadata box. |
| * |
| * @private |
| */ |
| MetadataBoxController.prototype.updateView_ = function() { |
| if (!this.quickView_.metadataBoxActive) { |
| return; |
| } |
| const entry = this.quickViewModel_.getSelectedEntry(); |
| const isSameEntry = util.isSameEntry(entry, this.previousEntry_); |
| this.previousEntry_ = entry; |
| // Do not clear isSizeLoading and size fields when the entry is not changed. |
| this.metadataBox_.clear(isSameEntry); |
| if (!entry) { |
| return; |
| } |
| this.metadataModel_ |
| .get([entry], MetadataBoxController.GENERAL_METADATA_NAME.concat([ |
| 'alternateUrl', 'externalFileUrl', 'hosted' |
| ])) |
| .then(this.onGeneralMetadataLoaded_.bind(this, entry, isSameEntry)); |
| }; |
| |
| /** |
| * Update metadata box with general file information. |
| * Then retrieve file specific metadata if any. |
| * |
| * @param {!Entry} entry |
| * @param {boolean} isSameEntry if the entry is not changed from the last time. |
| * @param {!Array<!MetadataItem>} items |
| * |
| * @private |
| */ |
| MetadataBoxController.prototype.onGeneralMetadataLoaded_ = function( |
| entry, isSameEntry, items) { |
| const type = FileType.getType(entry).type; |
| const item = items[0]; |
| |
| this.metadataBox_.type = type; |
| // For directory, item.size is always -1. |
| if (item.size && !entry.isDirectory) { |
| this.metadataBox_.size = |
| this.fileMetadataFormatter_.formatSize(item.size, item.hosted); |
| } |
| if (entry.isDirectory) { |
| this.setDirectorySize_( |
| /** @type {!DirectoryEntry} */ (entry), isSameEntry); |
| } |
| |
| if (item.modificationTime) { |
| this.metadataBox_.modificationTime = |
| this.fileMetadataFormatter_.formatModDate(item.modificationTime); |
| } |
| |
| if (item.externalFileUrl || item.alternateUrl) { |
| this.metadataModel_.get([entry], ['contentMimeType']).then(items => { |
| const item = items[0]; |
| this.metadataBox_.mediaMimeType = item.contentMimeType || ''; |
| }); |
| } else { |
| this.metadataModel_.get([entry], ['mediaMimeType']).then(items => { |
| const item = items[0]; |
| this.metadataBox_.mediaMimeType = item.mediaMimeType || ''; |
| }); |
| } |
| |
| if (['image', 'video', 'audio'].includes(type)) { |
| if (item.externalFileUrl || item.alternateUrl) { |
| this.metadataModel_.get([entry], ['imageHeight', 'imageWidth']) |
| .then(items => { |
| const item = items[0]; |
| this.metadataBox_.imageHeight = |
| /** @type {number} */ (item.imageHeight); |
| this.metadataBox_.imageWidth = |
| /** @type {number} */ (item.imageWidth); |
| }); |
| } else { |
| this.metadataModel_ |
| .get( |
| [entry], |
| [ |
| 'ifd', |
| 'imageHeight', |
| 'imageWidth', |
| 'mediaAlbum', |
| 'mediaArtist', |
| 'mediaDuration', |
| 'mediaGenre', |
| 'mediaTitle', |
| 'mediaTrack', |
| 'mediaYearRecorded', |
| ]) |
| .then(items => { |
| const item = items[0]; |
| this.metadataBox_.ifd = item.ifd || null; |
| this.metadataBox_.imageHeight = item.imageHeight || 0; |
| this.metadataBox_.imageWidth = item.imageWidth || 0; |
| this.metadataBox_.mediaAlbum = item.mediaAlbum || ''; |
| this.metadataBox_.mediaArtist = item.mediaArtist || ''; |
| this.metadataBox_.mediaDuration = item.mediaDuration || 0; |
| this.metadataBox_.mediaGenre = item.mediaGenre || ''; |
| this.metadataBox_.mediaTitle = item.mediaTitle || ''; |
| this.metadataBox_.mediaTrack = item.mediaTrack || ''; |
| this.metadataBox_.mediaYearRecorded = item.mediaYearRecorded || ''; |
| }); |
| } |
| } |
| }; |
| |
| /** |
| * Set a current directory's size in metadata box. |
| * If previous getDirectorySize is still running, next getDirectorySize is not |
| * called at the time. After the previous callback is finished, getDirectorySize |
| * that corresponds to the last setDirectorySize_ is called. |
| * |
| * @param {!DirectoryEntry} entry |
| * @param {boolean} isSameEntry |
| * if the entry is not changed from the last time. |
| * |
| * @private |
| */ |
| MetadataBoxController.prototype.setDirectorySize_ = function( |
| entry, isSameEntry) { |
| if (!entry.isDirectory) { |
| return; |
| } |
| |
| if (this.isDirectorySizeLoading_) { |
| if (!isSameEntry) { |
| this.metadataBox_.isSizeLoading = true; |
| } |
| |
| // Only retain the last setDirectorySize_ request. |
| this.onDirectorySizeLoaded_ = lastEntry => { |
| this.setDirectorySize_(entry, util.isSameEntry(entry, lastEntry)); |
| }; |
| return; |
| } |
| |
| // false if the entry is same. true if the entry is changed. |
| this.metadataBox_.isSizeLoading = !isSameEntry; |
| this.isDirectorySizeLoading_ = true; |
| chrome.fileManagerPrivate.getDirectorySize(entry, size => { |
| this.isDirectorySizeLoading_ = false; |
| if (this.onDirectorySizeLoaded_) { |
| setTimeout(this.onDirectorySizeLoaded_.bind(null, entry)); |
| this.onDirectorySizeLoaded_ = null; |
| } |
| |
| if (this.quickViewModel_.getSelectedEntry() != entry) { |
| return; |
| } |
| |
| if (chrome.runtime.lastError) { |
| this.metadataBox_.isSizeLoading = false; |
| return; |
| } |
| |
| this.metadataBox_.isSizeLoading = false; |
| this.metadataBox_.size = this.fileMetadataFormatter_.formatSize(size, true); |
| }); |
| }; |