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

Unified Diff: chrome/browser/resources/file_manager/js/file_copy_manager.js

Issue 9652024: Only show progress bar after 500ms (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Merge to trunk. Created 8 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/resources/file_manager/js/file_manager.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/file_manager/js/file_copy_manager.js
diff --git a/chrome/browser/resources/file_manager/js/file_copy_manager.js b/chrome/browser/resources/file_manager/js/file_copy_manager.js
index 8b017cef0cd13820d905239aae4ea8e725b92b9f..296226e2ed8da1199e0d46906868e598b3767b5f 100644
--- a/chrome/browser/resources/file_manager/js/file_copy_manager.js
+++ b/chrome/browser/resources/file_manager/js/file_copy_manager.js
@@ -60,22 +60,38 @@ FileCopyManager.Task.prototype.setEntries = function(entries, callback) {
util.recurseAndResolveEntries(entries, recurse, onEntriesRecursed);
}
-FileCopyManager.Task.prototype.takeNextEntry = function() {
- if (this.pendingDirectories.length)
- return this.pendingDirectories.shift();
+FileCopyManager.Task.prototype.getNextEntry = function() {
+ // We should keep the file in pending list and remove it after complete.
+ // Otherwise, if we try to get status in the middle of copying. The returned
+ // status is wrong (miss count the pasting item in totalItems).
+ if (this.pendingDirectories.length) {
+ this.pendingDirectories[0].inProgress = true;
+ return this.pendingDirectories[0];
+ }
- if (this.pendingFiles.length)
- return this.pendingFiles.shift();
+ if (this.pendingFiles.length) {
+ this.pendingFiles[0].inProgress = true;
+ return this.pendingFiles[0];
+ }
return null;
};
FileCopyManager.Task.prototype.markEntryComplete = function(entry, size) {
- if (entry.isDirectory) {
+ // It is probably not safe to directly remove the first entry in pending list.
+ // We need to check if the removed entry (srcEntry) corresponding to the added
+ // entry (target entry).
+ if (entry.isDirectory && this.pendingDirectories &&
+ this.pendingDirectories[0].inProgress) {
this.completedDirectories.push(entry);
- } else {
+ this.pendingDirectories.shift();
+ } else if (this.pendingFiles && this.pendingFiles[0].inProgress) {
this.completedFiles.push(entry);
this.completedBytes += size;
+ this.pendingFiles.shift();
+ } else {
+ throw new Error('Try to remove a source entry which is not correspond to' +
+ ' the finished target entry');
}
};
@@ -133,14 +149,13 @@ FileCopyManager.prototype.getStatus = function() {
rv.pendingFiles += task.pendingFiles.length;
rv.pendingDirectories += task.pendingDirectories.length;
rv.pendingBytes += task.pendingBytes;
- rv.pendingItems += rv.pendingFiles + rv.pendingDirectories;
rv.completedFiles += task.completedFiles.length;
rv.completedDirectories += task.completedDirectories.length;
rv.completedBytes += task.completedBytes;
- rv.completedItems += rv.completedFiles + rv.completedDirectories;
-
}
+ rv.pendingItems = rv.pendingFiles + rv.pendingDirectories;
+ rv.completedItems = rv.completedFiles + rv.completedDirectories;
rv.totalFiles = rv.pendingFiles + rv.completedFiles;
rv.totalDirectories = rv.pendingDirectories + rv.completedDirectories;
@@ -151,6 +166,40 @@ FileCopyManager.prototype.getStatus = function() {
};
/**
+ * Get the overall progress data of all queued copy tasks.
+ * @return {Object} An object containing the following parameters:
+ * percentage - The percentage (0-1) of finished items.
+ * pendingItems - The number of pending/unfinished items.
+ */
+FileCopyManager.prototype.getProgress = function() {
+ var status = this.getStatus();
+ return {
+ // TODO(bshe): Need to figure out a way to get completed bytes in real
+ // time. We currently use completedItems and totalItems to estimate the
+ // progress. There are completeBytes and totalBytes ready to use.
+ // However, the completedBytes is not in real time. It only updates
+ // itself after each item finished. So if there is a large item to
+ // copy, the progress bar will stop moving until it finishes and jump
+ // a large portion of the bar.
+ // There is case that when user copy a large file, we want to show an
+ // 100% animated progress bar. So we use completedItems + 1 here.
+ percentage: (status.completedItems + 1) / status.totalItems,
+ pendingItems: status.pendingItems
+ };
+};
+
+/**
+ * Dispatch a simple copy-progress event with reason and optional err data.
+ */
+FileCopyManager.prototype.sendProgressEvent_ = function(reason, opt_err) {
+ var event = new cr.Event('copy-progress');
+ event.reason = reason;
+ if (opt_err)
+ event.error = opt_err;
+ this.dispatchEvent(event);
+};
+
+/**
* Completely clear out the copy queue, either because we encountered an error
* or completed successfully.
*/
@@ -176,9 +225,7 @@ FileCopyManager.prototype.requestCancel = function(opt_callback) {
* Perform the bookeeping required to cancel.
*/
FileCopyManager.prototype.doCancel_ = function() {
- var event = new cr.Event('copy-progress');
- event.reason = 'CANCELLED';
- this.dispatchEvent(event);
+ this.sendProgressEvent_('CANCELLED');
this.resetQueue_();
};
@@ -207,10 +254,8 @@ FileCopyManager.prototype.paste = function(clipboard, targetEntry,
};
function onPathError(err) {
- var event = new cr.Event('copy-progress');
- event.reason = 'ERROR';
- event.error = new FileCopyManager.Error('FILESYSTEM_ERROR', err);
- self.dispatchEvent(event);
+ self.sendProgressEvent_('ERROR',
+ new FileCopyManager.Error('FILESYSTEM_ERROR', err));
}
function onSourceEntryFound(dirEntry) {
@@ -279,6 +324,10 @@ FileCopyManager.prototype.queueCopy = function(sourceDirEntry,
if (self.copyTasks_.length == 1) {
// This moved us from 0 to 1 active tasks, let the servicing begin!
self.serviceAllTasks_();
+ } else {
+ // Force to update the progress of butter bar when there are new tasks
+ // coming while servicing current task.
+ self.sendProgressEvent_('PROGRESS');
}
});
@@ -293,28 +342,31 @@ FileCopyManager.prototype.serviceAllTasks_ = function() {
var self = this;
function onTaskError(err) {
- var event = new cr.Event('copy-progress');
- event.reason = 'ERROR';
- event.error = err;
- self.dispatchEvent(event);
+ self.sendProgressEvent_('ERROR', err);
self.resetQueue_();
}
function onTaskSuccess(task) {
- if (task == null) {
+ if (!self.copyTasks_.length) {
// All tasks have been serviced, clean up and exit.
- var event = new cr.Event('copy-progress');
- event.reason = 'SUCCESS';
- self.dispatchEvent(event);
+ self.sendProgressEvent_('SUCCESS');
self.resetQueue_();
return;
}
+ // We want to dispatch a PROGRESS event when there are more tasks to serve
+ // right after one task finished in the queue. We treat all tasks as one
+ // big task logically, so there is only one BEGIN/SUCCESS event pair for
+ // these continuous tasks.
+ self.sendProgressEvent_('PROGRESS');
+
self.serviceNextTask_(onTaskSuccess, onTaskError);
}
// If the queue size is 1 after pushing our task, it was empty before,
- // so we need to kick off queue processing.
+ // so we need to kick off queue processing and dispatch BEGIN event.
+
+ this.sendProgressEvent_('BEGIN');
this.serviceNextTask_(onTaskSuccess, onTaskError);
};
@@ -326,11 +378,6 @@ FileCopyManager.prototype.serviceNextTask_ = function(
if (this.maybeCancel_())
return;
- if (!this.copyTasks_.length) {
- successCallback(null);
- return;
- }
-
var self = this;
var task = this.copyTasks_[0];
@@ -359,7 +406,9 @@ FileCopyManager.prototype.serviceNextTask_ = function(
}
function onEntryServiced(targetEntry, size) {
- if (!targetEntry) {
+ // We should not dispatch a PROGRESS event when there is no pending items
+ // in the task.
+ if (task.pendingDirectories.length + task.pendingFiles.length == 0) {
// All done with the entries in this task.
// If files are moved within GData, FileEntry.moveTo() is used and
// there is no need to delete the original files.
@@ -371,9 +420,7 @@ FileCopyManager.prototype.serviceNextTask_ = function(
return;
}
- var event = new cr.Event('copy-progress');
- event.reason = 'PROGRESS';
- self.dispatchEvent(event);
+ self.sendProgressEvent_('PROGRESS');
// We yield a few ms between copies to give the browser a chance to service
// events (like perhaps the user clicking to cancel the copy, for example).
@@ -382,9 +429,6 @@ FileCopyManager.prototype.serviceNextTask_ = function(
}, 10);
}
- var event = new cr.Event('copy-progress');
- event.reason = 'BEGIN';
- this.dispatchEvent(event);
this.serviceNextTaskEntry_(task, onEntryServiced, errorCallback);
}
@@ -397,7 +441,7 @@ FileCopyManager.prototype.serviceNextTaskEntry_ = function(
return;
var self = this;
- var sourceEntry = task.takeNextEntry();
+ var sourceEntry = task.getNextEntry();
if (!sourceEntry) {
// All entries in this task have been copied.
« no previous file with comments | « no previous file | chrome/browser/resources/file_manager/js/file_manager.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698