You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-06-12 22:57:38 +02:00
* Started revisions support * More rev changes * More rev changes * More revs changes * Fixed deletion algorithm * More tests and moved updated time to separate field * Display info when restoring note * Better handling of existing notes * wip * Further improvements and fixed tests * Better handling of changes created via sync * Enable chokidar again * Testing special case * Further improved logic to handle notes that existed before the revision service * Added tests * Better handling of encrypted revisions * Improved handling of deleted note revisions by moving logic to collectRevision * Improved handling of old notes by moving logic to collectRevision() * Handle case when deleting revisions while one is still encrypted * UI tweaks * Added revision service to mobile app * Fixed config screens on mobile and desktop * Enabled revisions on CLI app
This commit is contained in:
@ -2,6 +2,7 @@ const BaseItem = require('lib/models/BaseItem.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const ItemChange = require('lib/models/ItemChange.js');
|
||||
const ResourceLocalState = require('lib/models/ResourceLocalState.js');
|
||||
const MasterKey = require('lib/models/MasterKey.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
@ -325,7 +326,7 @@ class Synchronizer {
|
||||
if (action == "createRemote" || action == "updateRemote") {
|
||||
let canSync = true;
|
||||
try {
|
||||
if (this.testingHooks_.indexOf("rejectedByTarget") >= 0) throw new JoplinError("Testing rejectedByTarget", "rejectedByTarget");
|
||||
if (this.testingHooks_.indexOf("notesRejectedByTarget") >= 0 && local.type_ === BaseModel.TYPE_NOTE) throw new JoplinError("Testing rejectedByTarget", "rejectedByTarget");
|
||||
const content = await ItemClass.serializeForSync(local);
|
||||
await this.api().put(path, content);
|
||||
} catch (error) {
|
||||
@ -370,9 +371,9 @@ class Synchronizer {
|
||||
local = remoteContent;
|
||||
|
||||
const syncTimeQueries = BaseItem.updateSyncTimeQueries(syncTargetId, local, time.unixMs());
|
||||
await ItemClass.save(local, { autoTimestamp: false, nextQueries: syncTimeQueries });
|
||||
await ItemClass.save(local, { autoTimestamp: false, changeSource: ItemChange.SOURCE_SYNC, nextQueries: syncTimeQueries });
|
||||
} else {
|
||||
await ItemClass.delete(local.id);
|
||||
await ItemClass.delete(local.id, { changeSource: ItemChange.SOURCE_SYNC });
|
||||
}
|
||||
} else if (action == "noteConflict") {
|
||||
// ------------------------------------------------------------------------------
|
||||
@ -395,7 +396,7 @@ class Synchronizer {
|
||||
let conflictedNote = Object.assign({}, local);
|
||||
delete conflictedNote.id;
|
||||
conflictedNote.is_conflict = 1;
|
||||
await Note.save(conflictedNote, { autoTimestamp: false });
|
||||
await Note.save(conflictedNote, { autoTimestamp: false, changeSource: ItemChange.SOURCE_SYNC });
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
@ -406,12 +407,12 @@ class Synchronizer {
|
||||
if (remote) {
|
||||
local = remoteContent;
|
||||
const syncTimeQueries = BaseItem.updateSyncTimeQueries(syncTargetId, local, time.unixMs());
|
||||
await ItemClass.save(local, { autoTimestamp: false, nextQueries: syncTimeQueries });
|
||||
await ItemClass.save(local, { autoTimestamp: false, changeSource: ItemChange.SOURCE_SYNC, nextQueries: syncTimeQueries });
|
||||
|
||||
if (!!local.encryption_applied) this.dispatch({ type: "SYNC_GOT_ENCRYPTED_ITEM" });
|
||||
} else {
|
||||
// Remote no longer exists (note deleted) so delete local one too
|
||||
await ItemClass.delete(local.id);
|
||||
await ItemClass.delete(local.id, { changeSource: ItemChange.SOURCE_SYNC });
|
||||
}
|
||||
}
|
||||
|
||||
@ -535,6 +536,8 @@ class Synchronizer {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.testingHooks_.indexOf('skipRevisions') >= 0 && content && content.type_ === BaseModel.TYPE_REVISION) action = null;
|
||||
|
||||
if (!action) continue;
|
||||
|
||||
this.logSyncOperation(action, local, remote, reason);
|
||||
@ -557,30 +560,13 @@ class Synchronizer {
|
||||
let options = {
|
||||
autoTimestamp: false,
|
||||
nextQueries: BaseItem.updateSyncTimeQueries(syncTargetId, content, time.unixMs()),
|
||||
changeSource: ItemChange.SOURCE_SYNC,
|
||||
};
|
||||
if (action == "createLocal") options.isNew = true;
|
||||
if (action == "updateLocal") options.oldItem = local;
|
||||
|
||||
const creatingNewResource = content.type_ == BaseModel.TYPE_RESOURCE && action == "createLocal";
|
||||
|
||||
// if (content.type_ == BaseModel.TYPE_RESOURCE && action == "createLocal") {
|
||||
// let localResourceContentPath = Resource.fullPath(content);
|
||||
// let remoteResourceContentPath = this.resourceDirName_ + "/" + content.id;
|
||||
// try {
|
||||
// await this.api().get(remoteResourceContentPath, { path: localResourceContentPath, target: "file" });
|
||||
// } catch (error) {
|
||||
// if (error.code === 'rejectedByTarget') {
|
||||
// this.progressReport_.errors.push(error);
|
||||
// this.logger().warn('Rejected by target: ' + path + ': ' + error.message);
|
||||
// continue;
|
||||
// } else {
|
||||
// throw error;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (creatingNewResource) content.fetch_status = Resource.FETCH_STATUS_IDLE;
|
||||
|
||||
if (creatingNewResource) {
|
||||
await ResourceLocalState.save({ resource_id: content.id, fetch_status: Resource.FETCH_STATUS_IDLE });
|
||||
}
|
||||
@ -608,7 +594,7 @@ class Synchronizer {
|
||||
}
|
||||
|
||||
let ItemClass = BaseItem.itemClass(local.type_);
|
||||
await ItemClass.delete(local.id, { trackDeleted: false });
|
||||
await ItemClass.delete(local.id, { trackDeleted: false, changeSource: ItemChange.SOURCE_SYNC });
|
||||
}
|
||||
}
|
||||
|
||||
@ -653,7 +639,7 @@ class Synchronizer {
|
||||
// CONFLICT
|
||||
await Folder.markNotesAsConflict(item.id);
|
||||
}
|
||||
await Folder.delete(item.id, { deleteChildren: false, trackDeleted: false });
|
||||
await Folder.delete(item.id, { deleteChildren: false, changeSource: ItemChange.SOURCE_SYNC, trackDeleted: false });
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user