Commit 45e673e6 authored by smckay's avatar smckay Committed by Commit bot

Show a little circly/arrowey badge for files that have been copied locally.

Update import history code to support tracking locally copied files (and their destinations). Tracking destination is necessary as we'll eventually need to do lookups against destinations in order to mark items as imported when they are fully synced to the cloud.

BUG=420680
TEST=browser_test: FileManagerJsTest.*

Review URL: https://codereview.chromium.org/837563002

Cr-Commit-Position: refs/heads/master@{#310189}
parent 64c52354
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<html> <html>
<body> <body>
<script src="../../common/js/volume_manager_common.js"></script>
<script src="../../common/js/importer_common.js"></script> <script src="../../common/js/importer_common.js"></script>
<script src="../../common/js/mock_entry.js"></script> <script src="../../common/js/mock_entry.js"></script>
<script src="../../common/js/unittest_util.js"></script> <script src="../../common/js/unittest_util.js"></script>
......
...@@ -12,7 +12,10 @@ var FILE_SIZE = 1234; ...@@ -12,7 +12,10 @@ var FILE_SIZE = 1234;
var FILE_PATH = 'test/data'; var FILE_PATH = 'test/data';
/** @const {string} */ /** @const {string} */
var GOOGLE_DRIVE = 'Google Drive'; var DEVICE = importer.Destination.DEVICE;
/** @const {string} */
var GOOGLE_DRIVE = importer.Destination.GOOGLE_DRIVE;
/** /**
* Space Cloud: Your source for interstellar cloud storage. * Space Cloud: Your source for interstellar cloud storage.
...@@ -32,6 +35,9 @@ var storage; ...@@ -32,6 +35,9 @@ var storage;
/** @type {!Promise.<!importer.PersistentImportHistory>|undefined} */ /** @type {!Promise.<!importer.PersistentImportHistory>|undefined} */
var historyProvider; var historyProvider;
/** @type {Promise} */
var testPromise;
// Set up the test components. // Set up the test components.
function setUp() { function setUp() {
testFileEntry = new MockFileEntry( testFileEntry = new MockFileEntry(
...@@ -49,53 +55,95 @@ function setUp() { ...@@ -49,53 +55,95 @@ function setUp() {
historyProvider = history.refresh(); historyProvider = history.refresh();
} }
function testHistoryWasCopiedFalseForUnknownEntry(callback) {
// TestRecordWriter is pre-configured with a Space Cloud entry
// but not for this file.
testPromise = historyProvider.then(
function(history) {
history.wasCopied(testFileEntry, SPACE_CAMP).then(assertFalse);
});
reportPromise(testPromise, callback);
}
function testHistoryWasCopiedTrueForKnownEntryLoadedFromStorage(callback) {
// TestRecordWriter is pre-configured with this entry.
testPromise = historyProvider.then(
function(history) {
history.wasCopied(testFileEntry, GOOGLE_DRIVE).then(assertTrue);
});
reportPromise(testPromise, callback);
}
function testHistoryWasImportedTrueForKnownEntrySetAtRuntime(callback) {
testPromise = historyProvider.then(
function(history) {
history.markImported(testFileEntry, SPACE_CAMP).then(
function() {
history.wasImported(testFileEntry, SPACE_CAMP).then(assertTrue);
});
});
reportPromise(testPromise, callback);
}
function testCopyChangeFiresChangedEvent(callback) {
testPromise = historyProvider.then(
function(history) {
var recorder = new TestCallRecorder();
history.addObserver(recorder.callback);
history.markCopied(testFileEntry, SPACE_CAMP, 'url1').then(
function() {
Promise.resolve()
.then(
function() {
recorder.assertCallCount(1);
assertEquals(
importer.ImportHistory.State.COPIED,
recorder.getLastArguments()[0]['state']);
});
});
});
reportPromise(testPromise, callback);
}
function testHistoryWasImportedFalseForUnknownEntry(callback) { function testHistoryWasImportedFalseForUnknownEntry(callback) {
// TestRecordWriter is pre-configured with a Space Cloud entry // TestRecordWriter is pre-configured with a Space Cloud entry
// but not for this file. // but not for this file.
historyProvider.then( testPromise = historyProvider.then(
function(history) { function(history) {
history.wasImported(testFileEntry, SPACE_CAMP).then( history.wasImported(testFileEntry, SPACE_CAMP).then(assertFalse);
function(result) { });
callback(/* error */ result);
}, reportPromise(testPromise, callback);
callback.bind(null, true));
},
callback.bind(null, true))
.catch(handleError.bind(null, callback));
} }
function testHistoryWasImportedTrueForKnownEntryLoadedFromStorage(callback) { function testHistoryWasImportedTrueForKnownEntryLoadedFromStorage(callback) {
// TestRecordWriter is pre-configured with this entry. // TestRecordWriter is pre-configured with this entry.
historyProvider.then( testPromise = historyProvider.then(
function(history) { function(history) {
history.wasImported(testFileEntry, GOOGLE_DRIVE).then( history.wasImported(testFileEntry, GOOGLE_DRIVE).then(assertTrue);
function(result) { });
callback(/* error */ !result);
}, reportPromise(testPromise, callback);
callback.bind(null, true));
},
callback.bind(null, true))
.catch(handleError.bind(null, callback));
} }
function testHistoryWasImportedTrueForKnownEntrySetAtRuntime(callback) { function testHistoryWasImportedTrueForKnownEntrySetAtRuntime(callback) {
historyProvider.then( testPromise = historyProvider.then(
function(history) { function(history) {
history.markImported(testFileEntry, SPACE_CAMP).then( history.markImported(testFileEntry, SPACE_CAMP).then(
function() { function() {
history.wasImported(testFileEntry, SPACE_CAMP).then( history.wasImported(testFileEntry, SPACE_CAMP).then(assertTrue);
function(result) { });
callback(/* error */ !result); });
});
}, reportPromise(testPromise, callback);
callback.bind(null, true));
},
callback.bind(null, true))
.catch(handleError.bind(null, callback));
} }
function testHistoryChangeFiresChangedEvent(callback) { function testImportChangeFiresChangedEvent(callback) {
historyProvider.then( testPromise = historyProvider.then(
function(history) { function(history) {
var recorder = new TestCallRecorder(); var recorder = new TestCallRecorder();
history.addObserver(recorder.callback); history.addObserver(recorder.callback);
...@@ -108,53 +156,50 @@ function testHistoryChangeFiresChangedEvent(callback) { ...@@ -108,53 +156,50 @@ function testHistoryChangeFiresChangedEvent(callback) {
assertEquals( assertEquals(
importer.ImportHistory.State.IMPORTED, importer.ImportHistory.State.IMPORTED,
recorder.getLastArguments()[0]['state']); recorder.getLastArguments()[0]['state']);
callback(false); });
}) });
.catch(handleError.bind(null, callback)); });
},
callback.bind(null, true)); reportPromise(testPromise, callback);
},
callback.bind(null, true))
.catch(handleError.bind(null, callback));
} }
function testHistoryObserverUnsubscribe(callback) { function testHistoryObserverUnsubscribe(callback) {
historyProvider.then( testPromise = historyProvider.then(
function(history) { function(history) {
var recorder = new TestCallRecorder(); var recorder = new TestCallRecorder();
history.addObserver(recorder.callback); history.addObserver(recorder.callback);
history.removeObserver(recorder.callback); history.removeObserver(recorder.callback);
history.markImported(testFileEntry, SPACE_CAMP).then(
var promises = [];
promises.push(history.markCopied(testFileEntry, SPACE_CAMP, 'url2'));
promises.push(history.markImported(testFileEntry, SPACE_CAMP));
Promise.all(promises).then(
function() { function() {
Promise.resolve() Promise.resolve()
.then( .then(
function() { function() {
recorder.assertCallCount(0); recorder.assertCallCount(0);
callback(false); });
}) });
.catch(handleError.bind(null, callback)); });
},
callback.bind(null, true)); reportPromise(testPromise, callback);
},
callback.bind(null, true))
.catch(handleError.bind(null, callback));
} }
function testRecordStorageRemembersPreviouslyWrittenRecords(callback) { function testRecordStorageRemembersPreviouslyWrittenRecords(callback) {
createRealStorage('recordStorageTest.data') testPromise = createRealStorage('recordStorageTest.data')
.then( .then(
function(storage) { function(storage) {
storage.write(['abc', '123']).then( storage.write(['abc', '123']).then(
function() { function() {
storage.readAll().then( storage.readAll().then(
function(records) { function(records) {
callback(/* error */ records.length != 1); assertTrue(records.length != 1);
}, });
callback);
}); });
}, });
callback)
.catch(handleError.bind(null, callback)); reportPromise(testPromise, callback);
} }
function testHistoryLoaderIntegration(callback) { function testHistoryLoaderIntegration(callback) {
...@@ -171,7 +216,7 @@ function testHistoryLoaderIntegration(callback) { ...@@ -171,7 +216,7 @@ function testHistoryLoaderIntegration(callback) {
/** @type {!TestSyncFileEntryProvider|undefined} */ /** @type {!TestSyncFileEntryProvider|undefined} */
var syncFileProvider; var syncFileProvider;
createFileEntry('historyLoaderTest.data') testPromise = createFileEntry('historyLoaderTest.data')
.then( .then(
/** /**
* @param {!FileEntry} fileEntry * @param {!FileEntry} fileEntry
...@@ -208,6 +253,8 @@ function testHistoryLoaderIntegration(callback) { ...@@ -208,6 +253,8 @@ function testHistoryLoaderIntegration(callback) {
function() { function() {
syncFileProvider.fireSyncEvent(); syncFileProvider.fireSyncEvent();
}) })
// TODO(smckay): Add markCopied support once FileWriter issues
// are resolved.
.then( .then(
/** /**
* @return {!Promise.<boolean>} Resolves with true if the * @return {!Promise.<boolean>} Resolves with true if the
...@@ -218,9 +265,10 @@ function testHistoryLoaderIntegration(callback) { ...@@ -218,9 +265,10 @@ function testHistoryLoaderIntegration(callback) {
}) })
.then( .then(
function(wasImported) { function(wasImported) {
callback(/* error */ !wasImported); assertTrue(wasImported);
}) });
.catch(handleError.bind(null, callback));
reportPromise(testPromise, callback);
} }
/** /**
...@@ -285,8 +333,9 @@ var TestRecordStorage = function() { ...@@ -285,8 +333,9 @@ var TestRecordStorage = function() {
// Pre-populate the store with some "previously written" data <wink>. // Pre-populate the store with some "previously written" data <wink>.
/** @private {!Array.<!Array.<string>>} */ /** @private {!Array.<!Array.<string>>} */
this.records_ = [ this.records_ = [
[FILE_LAST_MODIFIED + '_' + FILE_SIZE, GOOGLE_DRIVE], [1, FILE_LAST_MODIFIED + '_' + FILE_SIZE, GOOGLE_DRIVE],
['99999_99999', SPACE_CAMP] [0, FILE_LAST_MODIFIED + '_' + FILE_SIZE, 'google-drive', 'url4'],
[1, '99999_99999', SPACE_CAMP]
]; ];
/** /**
......
...@@ -204,10 +204,14 @@ importer.MediaImportHandler.ImportTask.prototype.onProgress_ = ...@@ -204,10 +204,14 @@ importer.MediaImportHandler.ImportTask.prototype.onProgress_ =
/** @param {!FileEntry} entry */ /** @param {!FileEntry} entry */
importer.MediaImportHandler.ImportTask.prototype.markAsCopied_ = importer.MediaImportHandler.ImportTask.prototype.markAsCopied_ =
function(entry) { function(entry) {
var destinationUrl = this.destination_.toURL() + '/' + entry.name;
this.historyLoader_.getHistory().then( this.historyLoader_.getHistory().then(
/** @param {!importer.ImportHistory} history */ /** @param {!importer.ImportHistory} history */
function(history) { function(history) {
history.markImported(entry, importer.Destination.GOOGLE_DRIVE); history.markCopied(
entry,
importer.Destination.GOOGLE_DRIVE,
destinationUrl);
}); });
}; };
......
...@@ -163,7 +163,7 @@ function testUpdatesHistoryAfterImport(callback) { ...@@ -163,7 +163,7 @@ function testUpdatesHistoryAfterImport(callback) {
importedMedia.forEach( importedMedia.forEach(
/** @param {!CopyCapture} */ /** @param {!CopyCapture} */
function(capture) { function(capture) {
importHistory.assertImported( importHistory.assertCopied(
capture.source, importer.Destination.GOOGLE_DRIVE); capture.source, importer.Destination.GOOGLE_DRIVE);
}); });
}), }),
......
...@@ -15,8 +15,12 @@ var importer = importer || {}; ...@@ -15,8 +15,12 @@ var importer = importer || {};
* @implements {importer.ImportHistory} * @implements {importer.ImportHistory}
*/ */
importer.TestImportHistory = function() { importer.TestImportHistory = function() {
/** @type {!Object.<string, !Object.<!importer.Destination, string>>} */
this.copiedPaths = {};
/** @type {!Object.<string, Array.<string>>} */ /** @type {!Object.<string, Array.<string>>} */
this.importedPaths = {}; this.importedPaths = {};
}; };
/** @override */ /** @override */
...@@ -25,6 +29,47 @@ importer.TestImportHistory.prototype.getHistory = ...@@ -25,6 +29,47 @@ importer.TestImportHistory.prototype.getHistory =
return Promise.resolve(this); return Promise.resolve(this);
}; };
/**
* @param {!FileEntry} entry
* @param {!importer.Destination} destination
*/
importer.TestImportHistory.prototype.assertCopied =
function(entry, destination) {
assertTrue(this.wasCopied_(entry, destination));
};
/**
* Fully synchronous version of wasCopied.
* @param {!FileEntry} entry
* @param {!importer.Destination} destination
* @return {boolean}
*/
importer.TestImportHistory.prototype.wasCopied_ =
function(entry, destination) {
var path = entry.fullPath;
return path in this.copiedPaths &&
this.copiedPaths[path].indexOf(destination) > -1;
};
/** @override */
importer.TestImportHistory.prototype.wasCopied =
function(entry, destination) {
var path = entry.fullPath;
return Promise.resolve(this.wasCopied_(entry, destination));
};
/** @override */
importer.TestImportHistory.prototype.markCopied =
function(entry, destination) {
var path = entry.fullPath;
if (path in this.copiedPaths) {
this.copiedPaths[path].push(destination);
} else {
this.copiedPaths[path] = [destination];
}
return Promise.resolve();
};
/** /**
* @param {!FileEntry} entry * @param {!FileEntry} entry
* @param {!importer.Destination} destination * @param {!importer.Destination} destination
......
...@@ -29,6 +29,8 @@ importer.ELIGIBLE_VOLUME_TYPES_ = [ ...@@ -29,6 +29,8 @@ importer.ELIGIBLE_VOLUME_TYPES_ = [
* @enum {string} * @enum {string}
*/ */
importer.Destination = { importer.Destination = {
// locally copied, but not imported to cloud as of yet.
DEVICE: 'device',
GOOGLE_DRIVE: 'google-drive' GOOGLE_DRIVE: 'google-drive'
}; };
......
...@@ -750,6 +750,20 @@ body[type='full-page'] .detail-name .detail-icon { ...@@ -750,6 +750,20 @@ body[type='full-page'] .detail-name .detail-icon {
height: 30px; height: 30px;
} }
.badge {
height: 16px;
position: absolute;
right: 7px;
top: 7px;
width: 16px;
}
.copied .badge {
background-image: -webkit-image-set(
url(../images/files/ui/copied_badge.png) 1x,
url(../images/files/ui/2x/copied_badge.png) 2x);
}
.imported .badge { .imported .badge {
background-image: -webkit-image-set( background-image: -webkit-image-set(
url(../images/files/ui/drive_badge.png) 1x, url(../images/files/ui/drive_badge.png) 1x,
...@@ -761,7 +775,8 @@ body[type='full-page'] .detail-name .detail-icon { ...@@ -761,7 +775,8 @@ body[type='full-page'] .detail-name .detail-icon {
width: 16px; width: 16px;
} }
.imported .filename-label { .imported .filename-label,
.copied .filename-label {
margin-right: 14px; margin-right: 14px;
} }
......
...@@ -294,11 +294,23 @@ FileGrid.applyHistoryBadges_ = function(entry, box, history) { ...@@ -294,11 +294,23 @@ FileGrid.applyHistoryBadges_ = function(entry, box, history) {
// a possibly-fragile sibling selector we just // a possibly-fragile sibling selector we just
// plop the imported class on the parent of both. // plop the imported class on the parent of both.
box.parentElement.classList.add('imported'); box.parentElement.classList.add('imported');
} else {
history.wasCopied(entry, importer.Destination.GOOGLE_DRIVE)
.then(
function(copied) {
if (copied) {
// TODO(smckay): update badges when history changes
// "box" is currently the sibling of the elemement
// we want to style. So rather than employing
// a possibly-fragile sibling selector we just
// plop the imported class on the parent of both.
box.parentElement.classList.add('copied');
}
});
} }
}); });
}; };
/** /**
* Item for the Grid View. * Item for the Grid View.
* @constructor * @constructor
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment