mirror of https://github.com/keeweb/keeweb.git
fix #163: allow opening same file twice
This commit is contained in:
parent
5fe2ec0c15
commit
c7240edca9
|
@ -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; });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 || '';
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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; },
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue