mirror of https://github.com/keeweb/keeweb.git
more stable reload after db operations
This commit is contained in:
parent
f11cf25dbe
commit
db062cec27
|
@ -44,9 +44,18 @@ var AppModel = Backbone.Model.extend({
|
|||
file: file
|
||||
});
|
||||
this.refresh();
|
||||
this.listenTo(file, 'reload', this.reloadFile);
|
||||
return true;
|
||||
},
|
||||
|
||||
reloadFile: function(file) {
|
||||
this.menu.groupsSection.removeByFile(file, true);
|
||||
file.get('groups').forEach(function (group) {
|
||||
this.menu.groupsSection.addItem(group);
|
||||
}, this);
|
||||
this.updateTags();
|
||||
},
|
||||
|
||||
_addTags: function(group) {
|
||||
var tagsHash = {};
|
||||
this.tags.forEach(function(tag) {
|
||||
|
|
|
@ -16,15 +16,18 @@ var EntryModel = Backbone.Model.extend({
|
|||
},
|
||||
|
||||
setEntry: function(entry, group, file) {
|
||||
this.set({ id: entry.uuid.id }, {silent: true});
|
||||
this.entry = entry;
|
||||
this.group = group;
|
||||
this.file = file;
|
||||
if (this.id === entry.uuid.id) {
|
||||
this._checkUpdatedEntry();
|
||||
}
|
||||
this._fillByEntry();
|
||||
},
|
||||
|
||||
_fillByEntry: function() {
|
||||
var entry = this.entry;
|
||||
this.set({id: entry.uuid.id}, {silent: true});
|
||||
this.fileName = this.file.db.meta.name;
|
||||
this.title = entry.fields.Title || '';
|
||||
this.password = entry.fields.Password || kdbxweb.ProtectedValue.fromString('');
|
||||
|
@ -48,6 +51,15 @@ var EntryModel = Backbone.Model.extend({
|
|||
this._buildSearchColor();
|
||||
},
|
||||
|
||||
_checkUpdatedEntry: function() {
|
||||
if (this.isJustCreated) {
|
||||
this.isJustCreated = false;
|
||||
}
|
||||
if (this.unsaved && +this.updated !== +this.entry.times.lastModTime) {
|
||||
this.unsaved = false;
|
||||
}
|
||||
},
|
||||
|
||||
_buildSearchText: function() {
|
||||
var text = '';
|
||||
_.forEach(this.entry.fields, function(value) {
|
||||
|
@ -114,7 +126,8 @@ var EntryModel = Backbone.Model.extend({
|
|||
},
|
||||
|
||||
matches: function(filter) {
|
||||
return (!filter.tagLower || this.searchTags.indexOf(filter.tagLower) >= 0) &&
|
||||
return !filter ||
|
||||
(!filter.tagLower || this.searchTags.indexOf(filter.tagLower) >= 0) &&
|
||||
(!filter.textLower || this.searchText.indexOf(filter.textLower) >= 0) &&
|
||||
(!filter.color || filter.color === true && this.searchColor || this.searchColor === filter.color);
|
||||
},
|
||||
|
@ -190,7 +203,7 @@ var EntryModel = Backbone.Model.extend({
|
|||
deleteHistory: function(historyEntry) {
|
||||
var ix = this.entry.history.indexOf(historyEntry);
|
||||
if (ix >= 0) {
|
||||
this.entry.history.splice(ix, 1);
|
||||
this.entry.removeHistory(ix);
|
||||
}
|
||||
this._fillByEntry();
|
||||
},
|
||||
|
@ -211,9 +224,10 @@ var EntryModel = Backbone.Model.extend({
|
|||
},
|
||||
|
||||
discardUnsaved: function() {
|
||||
if (this.unsaved) {
|
||||
if (this.unsaved && this.entry.history.length) {
|
||||
this.unsaved = false;
|
||||
var historyEntry = this.entry.history.pop();
|
||||
var historyEntry = this.entry.history[this.entry.history.length - 1];
|
||||
this.entry.removeHistory(this.entry.history.length - 1);
|
||||
this.entry.fields = {};
|
||||
this.entry.binaries = {};
|
||||
this.entry.copyFrom(historyEntry);
|
||||
|
@ -227,18 +241,13 @@ var EntryModel = Backbone.Model.extend({
|
|||
this.isJustCreated = false;
|
||||
}
|
||||
this.file.db.remove(this.entry);
|
||||
this.group.removeEntry(this);
|
||||
var trashGroup = this.file.getTrashGroup();
|
||||
if (trashGroup) {
|
||||
trashGroup.addEntry(this);
|
||||
this.group = trashGroup;
|
||||
}
|
||||
this.file.reload();
|
||||
},
|
||||
|
||||
deleteFromTrash: function() {
|
||||
this.file.setModified();
|
||||
this.file.db.move(this.entry, null);
|
||||
this.group.removeEntry(this);
|
||||
this.file.reload();
|
||||
},
|
||||
|
||||
removeWithoutHistory: function() {
|
||||
|
@ -246,7 +255,7 @@ var EntryModel = Backbone.Model.extend({
|
|||
if (ix >= 0) {
|
||||
this.group.group.entries.splice(ix, 1);
|
||||
}
|
||||
this.group.removeEntry(this);
|
||||
this.file.reload();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -35,8 +35,12 @@ var FileModel = Backbone.Model.extend({
|
|||
|
||||
db: null,
|
||||
data: null,
|
||||
entryMap: null,
|
||||
groupMap: null,
|
||||
|
||||
initialize: function() {
|
||||
this.entryMap = {};
|
||||
this.groupMap = {};
|
||||
},
|
||||
|
||||
open: function(password, fileData, keyFileData) {
|
||||
|
@ -152,13 +156,38 @@ var FileModel = Backbone.Model.extend({
|
|||
historyMaxSize: this.db.meta.historyMaxSize,
|
||||
keyEncryptionRounds: this.db.header.keyEncryptionRounds
|
||||
}, { silent: true });
|
||||
this.db.groups.forEach(function(group, index) {
|
||||
var groupModel = GroupModel.fromGroup(group, this);
|
||||
if (index === 0 && topGroupTitle) {
|
||||
this.db.groups.forEach(function(group) {
|
||||
var groupModel = this.getGroup(group.uuid.id);
|
||||
if (groupModel) {
|
||||
groupModel.setGroup(group, this);
|
||||
} else {
|
||||
groupModel = GroupModel.fromGroup(group, this);
|
||||
}
|
||||
if (topGroupTitle) {
|
||||
groupModel.set({title: topGroupTitle});
|
||||
}
|
||||
groups.add(groupModel);
|
||||
}, this);
|
||||
this.buildObjectMap();
|
||||
},
|
||||
|
||||
buildObjectMap: function() {
|
||||
var entryMap = {};
|
||||
var groupMap = {};
|
||||
this.forEachGroup(function(group) {
|
||||
groupMap[group.id] = group;
|
||||
group.forEachOwnEntry(null, function(entry) {
|
||||
entryMap[entry.id] = entry;
|
||||
});
|
||||
}, true);
|
||||
this.entryMap = entryMap;
|
||||
this.groupMap = groupMap;
|
||||
},
|
||||
|
||||
reload: function() {
|
||||
this.buildObjectMap();
|
||||
this.readModel(this.get('name'));
|
||||
this.trigger('reload', this);
|
||||
},
|
||||
|
||||
close: function() {
|
||||
|
@ -177,17 +206,12 @@ var FileModel = Backbone.Model.extend({
|
|||
});
|
||||
},
|
||||
|
||||
getEntry: function(id) {
|
||||
return this.entryMap[id];
|
||||
},
|
||||
|
||||
getGroup: function(id) {
|
||||
var found = null;
|
||||
if (id) {
|
||||
this.forEachGroup(function (group) {
|
||||
if (group.get('id') === id) {
|
||||
found = group;
|
||||
return false;
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
return found;
|
||||
return this.groupMap[id];
|
||||
},
|
||||
|
||||
forEachEntry: function(filter, callback) {
|
||||
|
|
|
@ -22,28 +22,43 @@ var GroupModel = MenuItemModel.extend({
|
|||
initialize: function() {
|
||||
if (!GroupCollection) { GroupCollection = require('../collections/group-collection'); }
|
||||
if (!EntryCollection) { EntryCollection = require('../collections/entry-collection'); }
|
||||
this.set('entries', new EntryCollection());
|
||||
},
|
||||
|
||||
setFromGroup: function(group, file) {
|
||||
setGroup: function(group, file, parentGroup) {
|
||||
var isRecycleBin = file.db.meta.recycleBinUuid && file.db.meta.recycleBinUuid.id === group.uuid.id;
|
||||
this.set({
|
||||
id: group.uuid.id,
|
||||
expanded: true,
|
||||
expanded: group.expanded,
|
||||
visible: !isRecycleBin,
|
||||
items: new GroupCollection(),
|
||||
filterValue: group.uuid.id
|
||||
entries: new EntryCollection(),
|
||||
filterValue: group.uuid.id,
|
||||
top: !parentGroup,
|
||||
drag: !!parentGroup
|
||||
}, { silent: true });
|
||||
this.group = group;
|
||||
this.file = file;
|
||||
this.parentGroup = parentGroup;
|
||||
this._fillByGroup(true);
|
||||
var items = this.get('items'),
|
||||
entries = this.get('entries');
|
||||
group.groups.forEach(function(subGroup) {
|
||||
items.add(GroupModel.fromGroup(subGroup, file, this));
|
||||
var existing = file.getGroup(subGroup.uuid);
|
||||
if (existing) {
|
||||
existing.setGroup(subGroup, file, this);
|
||||
items.add(existing);
|
||||
} else {
|
||||
items.add(GroupModel.fromGroup(subGroup, file, this));
|
||||
}
|
||||
}, this);
|
||||
group.entries.forEach(function(entry) {
|
||||
entries.add(EntryModel.fromEntry(entry, this, file));
|
||||
var existing = file.getEntry(entry.uuid);
|
||||
if (existing) {
|
||||
existing.setEntry(entry, this, file);
|
||||
entries.add(existing);
|
||||
} else {
|
||||
entries.add(EntryModel.fromEntry(entry, this, file));
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
|
@ -102,22 +117,12 @@ var GroupModel = MenuItemModel.extend({
|
|||
return this.group.groups;
|
||||
},
|
||||
|
||||
removeEntry: function(entry) {
|
||||
this.get('entries').remove(entry);
|
||||
},
|
||||
|
||||
addEntry: function(entry) {
|
||||
this.get('entries').add(entry);
|
||||
},
|
||||
|
||||
removeGroup: function(group) {
|
||||
this.get('items').remove(group);
|
||||
this.trigger('remove', group);
|
||||
},
|
||||
|
||||
addGroup: function(group) {
|
||||
this.get('items').add(group);
|
||||
this.trigger('insert', group);
|
||||
},
|
||||
|
||||
setName: function(name) {
|
||||
|
@ -139,21 +144,21 @@ var GroupModel = MenuItemModel.extend({
|
|||
this._fillByGroup();
|
||||
},
|
||||
|
||||
setExpanded: function(expanded) {
|
||||
this._groupModified();
|
||||
this.group.expanded = expanded;
|
||||
this.set('expanded', expanded);
|
||||
},
|
||||
|
||||
moveToTrash: function() {
|
||||
this.file.setModified();
|
||||
this.file.db.remove(this.group);
|
||||
this.parentGroup.removeGroup(this);
|
||||
var trashGroup = this.file.getTrashGroup();
|
||||
if (trashGroup) {
|
||||
trashGroup.addGroup(this);
|
||||
this.parentGroup = trashGroup;
|
||||
}
|
||||
this.trigger('delete');
|
||||
this.file.reload();
|
||||
},
|
||||
|
||||
deleteFromTrash: function() {
|
||||
this.file.db.move(this.group, null);
|
||||
this.parentGroup.removeGroup(this);
|
||||
this.file.reload();
|
||||
},
|
||||
|
||||
removeWithoutHistory: function() {
|
||||
|
@ -161,8 +166,7 @@ var GroupModel = MenuItemModel.extend({
|
|||
if (ix >= 0) {
|
||||
this.parentGroup.group.groups.splice(ix, 1);
|
||||
}
|
||||
this.parentGroup.removeGroup(this);
|
||||
this.trigger('delete');
|
||||
this.file.reload();
|
||||
},
|
||||
|
||||
moveHere: function(object) {
|
||||
|
@ -175,42 +179,32 @@ var GroupModel = MenuItemModel.extend({
|
|||
return;
|
||||
}
|
||||
this.file.db.move(object.group, this.group);
|
||||
object.parentGroup.removeGroup(object);
|
||||
object.trigger('delete');
|
||||
this.addGroup(object);
|
||||
this.file.reload();
|
||||
} else if (object instanceof EntryModel) {
|
||||
if (this.group.entries.indexOf(object.entry) >= 0) {
|
||||
return;
|
||||
}
|
||||
this.file.db.move(object.entry, this.group);
|
||||
object.group.removeEntry(object);
|
||||
this.addEntry(object);
|
||||
object.group = this;
|
||||
this.file.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
GroupModel.fromGroup = function(group, file, parentGroup) {
|
||||
var model = new GroupModel();
|
||||
model.setFromGroup(group, file);
|
||||
if (parentGroup) {
|
||||
model.parentGroup = parentGroup;
|
||||
} else {
|
||||
model.set({ top: true, drag: false }, { silent: true });
|
||||
}
|
||||
model.setGroup(group, file, parentGroup);
|
||||
return model;
|
||||
};
|
||||
|
||||
GroupModel.newGroup = function(group, file) {
|
||||
var model = new GroupModel();
|
||||
var grp = file.db.createGroup(group.group);
|
||||
model.setFromGroup(grp, file);
|
||||
model.setGroup(grp, file, group);
|
||||
model.group.times.update();
|
||||
model.parentGroup = group;
|
||||
model.unsaved = true;
|
||||
model.isJustCreated = true;
|
||||
group.addGroup(model);
|
||||
file.setModified();
|
||||
file.reload();
|
||||
return model;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ var MenuItemModel = Backbone.Model.extend({
|
|||
this.trigger('change-items');
|
||||
},
|
||||
|
||||
removeByFile: function(file) {
|
||||
removeByFile: function(file, skipEvent) {
|
||||
var items = this.get('items');
|
||||
var toRemove;
|
||||
items.each(function(item) {
|
||||
|
@ -38,7 +38,9 @@ var MenuItemModel = Backbone.Model.extend({
|
|||
if (toRemove) {
|
||||
items.remove(toRemove);
|
||||
}
|
||||
this.trigger('change-items');
|
||||
if (!skipEvent) {
|
||||
this.trigger('change-items');
|
||||
}
|
||||
},
|
||||
|
||||
setItems: function(items) {
|
||||
|
|
|
@ -96,6 +96,7 @@ var MenuItemView = Backbone.View.extend({
|
|||
|
||||
changeExpanded: function(model, expanded) {
|
||||
this.$el.toggleClass('menu__item--collapsed', !expanded);
|
||||
this.model.setExpanded(expanded);
|
||||
},
|
||||
|
||||
changeCls: function(model, cls) {
|
||||
|
|
Loading…
Reference in New Issue