fix #163: allow opening same file twice

This commit is contained in:
antelle 2016-06-05 13:25:50 +03:00
parent 5fe2ec0c15
commit c7240edca9
9 changed files with 42 additions and 34 deletions

View File

@ -23,7 +23,7 @@ var FileCollection = Backbone.Collection.extend({
},
getById: function(id) {
return this.find(function(file) { return file.get('id') === id; });
return this.find(function(file) { return file.id === id; });
}
});

View File

@ -263,7 +263,7 @@ var AppModel = Backbone.Model.extend({
createDemoFile: function() {
var that = this;
if (!this.files.getByName('Demo')) {
var demoFile = new FileModel();
var demoFile = new FileModel({ id: IdGenerator.uuid() });
demoFile.openDemo(function() {
that.addFile(demoFile);
});
@ -281,7 +281,7 @@ var AppModel = Backbone.Model.extend({
break;
}
}
var newFile = new FileModel();
var newFile = new FileModel({ id: IdGenerator.uuid() });
newFile.create(name);
this.addFile(newFile);
},
@ -383,6 +383,7 @@ var AppModel = Backbone.Model.extend({
params.keyFileData = FileModel.createKeyFileWithHash(fileInfo.get('keyFileHash'));
}
var file = new FileModel({
id: fileInfo ? fileInfo.id : IdGenerator.uuid(),
name: params.name,
storage: params.storage,
path: params.path,
@ -407,11 +408,9 @@ var AppModel = Backbone.Model.extend({
if (fileInfo) {
file.set('syncDate', fileInfo.get('syncDate'));
}
var cacheId = fileInfo && fileInfo.id || IdGenerator.uuid();
file.set('cacheId', cacheId);
if (updateCacheOnSuccess) {
logger.info('Save loaded file to cache');
Storage.cache.save(cacheId, null, params.fileData);
Storage.cache.save(file.id, null, params.fileData);
}
var rev = params.rev || fileInfo && fileInfo.get('rev');
that.setFileOpts(file, params.opts);
@ -426,6 +425,7 @@ var AppModel = Backbone.Model.extend({
var logger = new Logger('import', params.name);
logger.info('File import request with supplied xml');
var file = new FileModel({
id: IdGenerator.uuid(),
name: params.name,
storage: params.storage,
path: params.path
@ -442,10 +442,10 @@ var AppModel = Backbone.Model.extend({
},
addToLastOpenFiles: function(file, rev) {
this.appLogger.debug('Add last open file', file.get('cacheId'), file.get('name'), file.get('storage'), file.get('path'), rev);
this.appLogger.debug('Add last open file', file.id, file.get('name'), file.get('storage'), file.get('path'), rev);
var dt = new Date();
var fileInfo = new FileInfoModel({
id: file.get('cacheId'),
id: file.id,
name: file.get('name'),
storage: file.get('storage'),
path: file.get('path'),
@ -462,7 +462,7 @@ var AppModel = Backbone.Model.extend({
keyFileHash: file.getKeyFileHash()
});
}
this.fileInfos.remove(file.get('cacheId'));
this.fileInfos.remove(file.id);
this.fileInfos.unshift(fileInfo);
this.fileInfos.save();
},
@ -504,7 +504,7 @@ var AppModel = Backbone.Model.extend({
},
getFileInfo: function(file) {
return file.get('cacheId') ? this.fileInfos.get(file.get('cacheId')) :
return this.fileInfos.get(file.id) ||
this.fileInfos.getMatch(file.get('storage'), file.get('name'), file.get('path'));
},
@ -549,7 +549,6 @@ var AppModel = Backbone.Model.extend({
if (!err) { savedToCache = true; }
logger.info('Sync finished', err || 'no error');
file.setSyncComplete(path, storage, err ? err.toString() : null, savedToCache);
file.set('cacheId', fileInfo.id);
fileInfo.set({
name: file.get('name'),
storage: storage,
@ -557,8 +556,7 @@ var AppModel = Backbone.Model.extend({
opts: that.getStoreOpts(file),
modified: file.get('modified'),
editState: file.getLocalEditState(),
syncDate: file.get('syncDate'),
cacheId: fileInfo.id
syncDate: file.get('syncDate')
});
if (that.settings.get('rememberKeyFiles')) {
fileInfo.set({
@ -573,7 +571,7 @@ var AppModel = Backbone.Model.extend({
if (callback) { callback(err); }
};
if (!storage) {
if (!file.get('modified') && fileInfo.id === file.get('cacheId')) {
if (!file.get('modified') && fileInfo.id === file.id) {
logger.info('Local, not modified');
return complete();
}

View File

@ -21,7 +21,7 @@ var EntryModel = Backbone.Model.extend({
this.entry = entry;
this.group = group;
this.file = file;
if (this.id === entry.uuid.id) {
if (this.get('uuid') === entry.uuid.id) {
this._checkUpdatedEntry();
}
this._fillByEntry();
@ -29,7 +29,7 @@ var EntryModel = Backbone.Model.extend({
_fillByEntry: function() {
var entry = this.entry;
this.set({id: entry.uuid.id}, {silent: true});
this.set({id: this.file.subId(entry.uuid.id), uuid: entry.uuid.id}, {silent: true});
this.fileName = this.file.get('name');
this.groupName = this.group.get('title');
this.title = entry.fields.Title || '';

View File

@ -13,6 +13,7 @@ var logger = new Logger('file');
var FileModel = Backbone.Model.extend({
defaults: {
id: '',
uuid: '',
name: '',
keyFileName: '',
passwordLength: 0,
@ -31,8 +32,7 @@ var FileModel = Backbone.Model.extend({
keyFileChanged: false,
syncing: false,
syncError: null,
syncDate: null,
cacheId: null
syncDate: null
},
db: null,
@ -136,7 +136,7 @@ var FileModel = Backbone.Model.extend({
readModel: function() {
var groups = new GroupCollection();
this.set({
id: this.db.getDefaultGroup().uuid.toString(),
uuid: this.db.getDefaultGroup().uuid.toString(),
groups: groups,
defaultUser: this.db.meta.defaultUser,
recycleBinEnabled: this.db.meta.recycleBinEnabled,
@ -145,18 +145,21 @@ var FileModel = Backbone.Model.extend({
keyEncryptionRounds: this.db.header.keyEncryptionRounds
}, { silent: true });
this.db.groups.forEach(function(group) {
var groupModel = this.getGroup(group.uuid.id);
var groupModel = this.getGroup(this.subId(group.uuid.id));
if (groupModel) {
groupModel.setGroup(group, this);
} else {
groupModel = GroupModel.fromGroup(group, this);
}
groupModel.set({title: this.get('name')});
groups.add(groupModel);
}, this);
this.buildObjectMap();
},
subId: function(id) {
return this.id + ':' + id;
},
buildObjectMap: function() {
var entryMap = {};
var groupMap = {};
@ -257,7 +260,7 @@ var FileModel = Backbone.Model.extend({
forEachEntry: function(filter, callback) {
var top = this;
if (filter.trash) {
top = this.getGroup(this.db.meta.recycleBinUuid ? this.db.meta.recycleBinUuid.id : null);
top = this.getGroup(this.db.meta.recycleBinUuid ? this.subId(this.db.meta.recycleBinUuid.id) : null);
} else if (filter.group) {
top = this.getGroup(filter.group);
}
@ -282,7 +285,7 @@ var FileModel = Backbone.Model.extend({
},
getTrashGroup: function() {
return this.db.meta.recycleBinEnabled ? this.getGroup(this.db.meta.recycleBinUuid.id) : null;
return this.db.meta.recycleBinEnabled ? this.getGroup(this.subId(this.db.meta.recycleBinUuid.id)) : null;
},
setModified: function() {
@ -455,9 +458,9 @@ var FileModel = Backbone.Model.extend({
},
addCustomIcon: function(iconData) {
var id = kdbxweb.KdbxUuid.random();
this.db.meta.customIcons[id] = kdbxweb.ByteUtils.arrayToBuffer(kdbxweb.ByteUtils.base64ToBytes(iconData));
return id.toString();
var uuid = kdbxweb.KdbxUuid.random();
this.db.meta.customIcons[uuid] = kdbxweb.ByteUtils.arrayToBuffer(kdbxweb.ByteUtils.base64ToBytes(iconData));
return uuid.toString();
},
renameTag: function(from, to) {

View File

@ -31,13 +31,15 @@ var GroupModel = MenuItemModel.extend({
setGroup: function(group, file, parentGroup) {
var isRecycleBin = file.db.meta.recycleBinUuid && file.db.meta.recycleBinUuid.id === group.uuid.id;
var id = file.subId(group.uuid.id);
this.set({
id: group.uuid.id,
id: id,
uuid: group.uuid.id,
expanded: group.expanded,
visible: !isRecycleBin,
items: new GroupCollection(),
entries: new EntryCollection(),
filterValue: group.uuid.id,
filterValue: id,
enableSearching: group.enableSearching,
enableAutoType: group.enableAutoType,
autoTypeSeq: group.defaultAutoTypeSeq,
@ -52,7 +54,7 @@ var GroupModel = MenuItemModel.extend({
var items = this.get('items'),
entries = this.get('entries');
group.groups.forEach(function(subGroup) {
var existing = file.getGroup(subGroup.uuid);
var existing = file.getGroup(file.subId(subGroup.uuid.id));
if (existing) {
existing.setGroup(subGroup, file, this);
items.add(existing);
@ -61,7 +63,7 @@ var GroupModel = MenuItemModel.extend({
}
}, this);
group.entries.forEach(function(entry) {
var existing = file.getEntry(entry.uuid);
var existing = file.getEntry(file.subId(entry.uuid.id));
if (existing) {
existing.setEntry(entry, this, file);
entries.add(existing);
@ -73,7 +75,7 @@ var GroupModel = MenuItemModel.extend({
_fillByGroup: function(silent) {
this.set({
title: this.group.name,
title: this.parentGroup ? this.group.name : this.file.get('name'),
iconId: this.group.icon,
icon: this._iconFromId(this.group.icon),
customIcon: this._buildCustomIcon(),

View File

@ -19,7 +19,7 @@ EntryPresenter.prototype = {
}
return this;
},
get id() { return this.entry ? this.entry.id : this.group.get('id'); },
get id() { return this.entry ? this.entry.id : this.group.id; },
get icon() { return this.entry ? this.entry.icon : (this.group.get('icon') || 'folder'); },
get customIcon() { return this.entry ? this.entry.customIcon : undefined; },
get color() { return this.entry ? (this.entry.color || (this.entry.customIcon ? this.noColor : undefined)) : undefined; },

View File

@ -107,7 +107,7 @@ var StorageWebDav = StorageBase.extend({
fileOptsToStoreOpts: function(opts, file) {
var result = {user: opts.user, encpass: opts.encpass};
if (opts.password) {
var fileId = file.get('id');
var fileId = file.get('uuid');
var password = opts.password;
var encpass = '';
for (var i = 0; i < password.length; i++) {
@ -121,7 +121,7 @@ var StorageWebDav = StorageBase.extend({
storeOptsToFileOpts: function(opts, file) {
var result = {user: opts.user, password: opts.password};
if (opts.encpass) {
var fileId = file.get('id');
var fileId = file.get('uuid');
var encpass = atob(opts.encpass);
var password = '';
for (var i = 0; i < encpass.length; i++) {

View File

@ -449,6 +449,10 @@ var OpenView = Backbone.View.extend({
},
openDb: function() {
if (this.params.id && this.model.files.getById(this.params.id)) {
this.trigger('close');
return;
}
if (this.busy || !this.params.name) {
return;
}

View File

@ -16,6 +16,7 @@ Auto-type, ui improvements
`+` logout from remote storages on disable
`*` don't check updates at startup
`*` repos moved to github organization account
`*` allow opening same file twice
`-` prevent second app instance on windows
`-` fix drag-drop in Safari