sync bugfixes

This commit is contained in:
Antelle 2015-12-11 23:51:16 +03:00
parent 56b7feea9f
commit 5bd6cf88b4
10 changed files with 63 additions and 24 deletions

6
.idea/encodings.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@ -121,6 +121,7 @@ DropboxChooser.prototype.readFile = function(url) {
};
var DropboxLink = {
ERROR_CONFLICT: Dropbox.ApiError.CONFLICT,
_getClient: function(complete) {
if (this._dropboxClient && this._dropboxClient.isAuthenticated()) {
complete(null, this._dropboxClient);
@ -199,6 +200,8 @@ var DropboxLink = {
body: 'Something went wrong during Dropbox sync. Please, try again later. Error code: ' + err.status
});
break;
case Dropbox.ApiError.CONFLICT:
break;
default:
alertCallback({
header: 'Dropbox Sync Error',
@ -241,7 +244,7 @@ var DropboxLink = {
saveFile: function(fileName, data, rev, complete) {
if (rev) {
var opts = typeof rev === 'string' ? { lastVersionTag: rev } : undefined;
var opts = typeof rev === 'string' ? { lastVersionTag: rev, noOverwrite: true, noAutoRename: true } : undefined;
this._callAndHandleError('writeFile', [fileName, data, opts], complete);
} else {
this.getFileList((function(err, files) {

View File

@ -322,7 +322,10 @@ var AppModel = Backbone.Model.extend({
file.setLocalEditState(fileInfo.get('editState'));
}
file.set('modified', true);
setTimeout(this.syncFile.bind(this, file), 0);
setTimeout(that.syncFile.bind(that, file), 0);
}
if (fileInfo) {
file.set('syncDate', fileInfo.get('syncDate'));
}
var cacheId = fileInfo && fileInfo.id || IdGenerator.uuid();
if (updateCacheOnSuccess && params.storage !== 'file') {
@ -350,7 +353,7 @@ var AppModel = Backbone.Model.extend({
modified: file.get('modified'),
editState: file.getLocalEditState(),
rev: rev,
pullDate: dt,
syncDate: file.get('syncDate') || dt,
openDate: dt
});
this.fileInfos.remove(id);
@ -365,6 +368,10 @@ var AppModel = Backbone.Model.extend({
},
syncFile: function(file, options, callback) {
var that = this;
if (file.get('demo')) {
return callback && callback();
}
if (file.get('syncing')) {
return callback && callback('Sync in progress');
}
@ -382,12 +389,13 @@ var AppModel = Backbone.Model.extend({
modified: file.get('modified'),
editState: null,
rev: null,
pullDate: dt,
syncDate: dt,
openDate: dt
});
}
var storage = Storage[options.storage || file.get('storage')];
var storage = options.storage || file.get('storage');
var path = options.path || file.get('path');
file.setSyncProgress();
var complete = function(err, savedToCache) {
if (!err) { savedToCache = true; }
file.setSyncComplete(path, storage, err ? err.toString() : null, savedToCache);
@ -395,12 +403,13 @@ var AppModel = Backbone.Model.extend({
storage: storage,
path: path,
modified: file.get('modified'),
editState: file.getLocalEditState()
editState: file.getLocalEditState(),
syncDate: file.get('syncDate')
});
if (!this.fileInfos.get(id)) {
this.fileInfos.unshift(fileInfo);
if (!that.fileInfos.get(fileInfo.id)) {
that.fileInfos.unshift(fileInfo);
}
this.fileInfos.save();
that.fileInfos.save();
if (callback) { callback(err); }
};
if (!storage) {
@ -419,16 +428,22 @@ var AppModel = Backbone.Model.extend({
if (++loadLoops === maxLoadLoops) {
return complete('Too many load attempts, please try again later');
}
storage.load(path, function(err, data, stat) {
Storage[storage].load(path, function(err, data, stat) {
if (err) { return complete(err); }
file.mergeOrUpdate(data, function(err) {
if (err) { return complete(err); }
if (stat && stat.rev) {
fileInfo.set('rev', stat.rev);
}
fileInfo.set('pullDate', new Date());
file.set('syncDate', new Date());
if (file.get('modified')) {
saveToCacheAndStorage();
} else if (file.get('dirty') && storage !== 'file') {
Storage.cache.save(fileInfo.id, data, function (err) {
if (err) { return complete(err); }
file.set('dirty', false);
complete();
});
} else {
complete();
}
@ -438,7 +453,7 @@ var AppModel = Backbone.Model.extend({
var saveToCacheAndStorage = function() {
file.getData(function(data, err) {
if (err) { return complete(err); }
if (!file.get('dirty') || storage === Storage.file) {
if (!file.get('dirty') || storage === 'file') {
saveToStorage(data);
} else {
Storage.cache.save(fileInfo.id, data, function (err) {
@ -450,31 +465,40 @@ var AppModel = Backbone.Model.extend({
});
};
var saveToStorage = function(data) {
storage.save(path, data, function(err) {
Storage[storage].save(path, data, function(err) {
if (err && err.revConflict) {
loadFromStorageAndMerge();
} else if (err) {
complete(err);
} else {
if (storage === Storage.file) {
if (storage === 'file') {
Storage.cache.remove(fileInfo.id);
}
file.set('syncDate', new Date());
complete();
}
}, fileInfo.get('rev'));
};
if (options.reload) {
loadFromStorageAndMerge();
} else if (storage === Storage.file) {
} else if (storage === 'file') {
if (file.get('modified')) {
saveToCacheAndStorage();
} else {
complete();
}
} else {
storage.stat(path, function (err, stat) {
Storage[storage].stat(path, function (err, stat) {
if (err) {
// TODO: save to cache if storage save failed
return complete(err);
}
if (stat.rev === fileInfo.get('rev')) {
saveToCacheAndStorage();
if (file.get('modified')) {
saveToCacheAndStorage();
} else {
complete();
}
} else {
loadFromStorageAndMerge();
}

View File

@ -11,7 +11,7 @@ var FileInfoModel = Backbone.Model.extend({
modified: false,
editState: null,
rev: null,
pullDate: null,
syncDate: null,
openDate: null
},

View File

@ -26,7 +26,8 @@ var FileModel = Backbone.Model.extend({
passwordChanged: false,
keyFileChanged: false,
syncing: false,
syncError: null
syncError: null,
syncDate: null
},
db: null,

View File

@ -19,7 +19,13 @@ var StorageDropbox = {
},
save: function(path, data, callback, rev) {
DropboxLink.saveFile(path, data, rev, callback || _.noop);
DropboxLink.saveFile(path, data, rev, function(err) {
if (!callback) { return; }
if (err && err.status === DropboxLink.ERROR_CONFLICT) {
err = { revConflict: true };
}
callback(err);
});
}
};

View File

@ -323,7 +323,7 @@ var AppView = Backbone.View.extend({
}
},
saveAndLock: function(autoInit) {
saveAndLock: function(/*autoInit*/) {
var pendingCallbacks = 0,
errorFiles = [],
that = this;

View File

@ -183,7 +183,7 @@ var SettingsAboutView = Backbone.View.extend({
that.render();
return;
}
this.save({ storage: 'dropbox' });
that.save({ storage: 'dropbox' });
});
},

View File

@ -26,7 +26,7 @@
"backbone": "~1.2.3",
"baron": "~1.0.1",
"bourbon": "~4.2.5",
"dropbox": "antelle/dropbox-js#0.10.5",
"dropbox": "antelle/dropbox-js#0.10.6",
"font-awesome": "~4.4.0",
"install": "~1.0.4",
"kdbxweb": "~0.3.1",

View File

@ -10,6 +10,5 @@
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="keeweb node_modules" level="project" />
</component>
</module>