mirror of
https://github.com/heroblackink/ultimate-todoist-sync-for-obsidian.git
synced 2026-07-22 07:40:27 +00:00
fix(sync): await persistence calls and enforce update-before-save ordering
This commit is contained in:
parent
49e8c94b43
commit
e4c481c9a8
4 changed files with 74 additions and 52 deletions
|
|
@ -368,9 +368,12 @@ export class CacheOperation {
|
|||
this.plugin.debugLog(`new file path is`)
|
||||
this.plugin.debugLog(searchResult)
|
||||
|
||||
//update metadata
|
||||
await this.updateRenamedFilePath(filepath,searchResult)
|
||||
this.plugin.saveSettings()
|
||||
//update metadata
|
||||
await this.updateRenamedFilePath(filepath,searchResult)
|
||||
const saved = await this.plugin.saveSettings();
|
||||
if (!saved) {
|
||||
console.warn('[checkFileMetadata] saveSettings skipped or failed');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -457,16 +460,16 @@ export class CacheOperation {
|
|||
* @param filepath - 文件路径
|
||||
* @param defaultProjectId - 项目 ID
|
||||
*/
|
||||
setDefaultProjectIdForFilepath(filepath:string, defaultProjectId:string){
|
||||
const metadatas = { ...this.plugin.settings.fileMetadata }
|
||||
if (!metadatas[filepath]) {
|
||||
metadatas[filepath] = {}
|
||||
}
|
||||
metadatas[filepath].defaultProjectId = defaultProjectId
|
||||
|
||||
this.plugin.safeSettings?.update({ fileMetadata: metadatas })
|
||||
async setDefaultProjectIdForFilepath(filepath:string, defaultProjectId:string): Promise<void> {
|
||||
const metadatas = { ...this.plugin.settings.fileMetadata }
|
||||
if (!metadatas[filepath]) {
|
||||
metadatas[filepath] = {}
|
||||
}
|
||||
metadatas[filepath].defaultProjectId = defaultProjectId
|
||||
|
||||
}
|
||||
await this.plugin.safeSettings?.update({ fileMetadata: metadatas }, true)
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ==========================================================================================
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ export class EventHandlers {
|
|||
if (!await this.plugin.checkModuleClass()) return;
|
||||
|
||||
await this.plugin.cacheOperation!.updateRenamedFilePath(oldpath, file.path);
|
||||
this.plugin.saveSettings();
|
||||
this.plugin.logOperation?.log('FILE_RENAMED', `File renamed from ${oldpath} to ${file.path}`, file.path);
|
||||
|
||||
if (!await this.plugin.syncLockManager.acquire('obsidianToTodoist')) return;
|
||||
|
|
@ -103,6 +102,8 @@ export class EventHandlers {
|
|||
if (!this.plugin.settings.apiInitialized) return;
|
||||
if (this.plugin.isSyncingFromTodoist) return;
|
||||
if (this.plugin.isProcessingModify) return;
|
||||
if (!file.path.endsWith('.md')) return;
|
||||
if (file.path.startsWith('.obsidian/')) return;
|
||||
this.plugin.isProcessingModify = true;
|
||||
|
||||
const filepath = file.path;
|
||||
|
|
|
|||
|
|
@ -60,12 +60,15 @@ export class ObsidianToTodoistSync {
|
|||
}
|
||||
}
|
||||
|
||||
if (deletedCount > 0) {
|
||||
this.plugin.saveSettings();
|
||||
try {
|
||||
await this.plugin.todoistSyncAPI.incrementalSync();
|
||||
} catch (syncErr) {
|
||||
console.error('[deletedTaskCheck] Post-push incremental sync failed:', syncErr);
|
||||
if (deletedCount > 0) {
|
||||
const saved = await this.plugin.saveSettings();
|
||||
if (!saved) {
|
||||
console.warn('[deletedTaskCheck] saveSettings skipped or failed');
|
||||
}
|
||||
try {
|
||||
await this.plugin.todoistSyncAPI.incrementalSync();
|
||||
} catch (syncErr) {
|
||||
console.error('[deletedTaskCheck] Post-push incremental sync failed:', syncErr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +109,7 @@ export class ObsidianToTodoistSync {
|
|||
this.plugin.logOperation?.log('OBSIDIAN_TASK_CREATED', `Created task in Obsidian: ${newTask.content}`, filepath, todoist_id, 'obsidian→todoist');
|
||||
this.plugin.logOperation?.log('TODOIST_TASK_CREATED', `Created task in Todoist: ${newTask.content}`, filepath, todoist_id, 'obsidian→todoist');
|
||||
|
||||
this.plugin.cacheOperation.setTaskFileMapping(todoist_id, filepath || '');
|
||||
await this.plugin.cacheOperation.setTaskFileMapping(todoist_id, filepath || '');
|
||||
|
||||
// Immediately sync so syncData contains the new task before any
|
||||
// subsequent lineModifiedTaskCheck fires on the same line.
|
||||
|
|
@ -148,11 +151,14 @@ export class ObsidianToTodoistSync {
|
|||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.plugin.saveSettings();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
try {
|
||||
const saved = await this.plugin.saveSettings();
|
||||
if (!saved) {
|
||||
console.warn('[lineContentNewTaskCheck] saveSettings skipped or failed');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error adding task:', error);
|
||||
|
|
@ -210,7 +216,7 @@ export class ObsidianToTodoistSync {
|
|||
this.plugin.logOperation?.log('OBSIDIAN_TASK_CREATED', `Created task in Obsidian: ${newTask.content}`, filepath, todoist_id, 'obsidian\u2192todoist');
|
||||
this.plugin.logOperation?.log('TODOIST_TASK_CREATED', `Created task in Todoist: ${newTask.content}`, filepath, todoist_id, 'obsidian\u2192todoist');
|
||||
|
||||
this.plugin.cacheOperation.setTaskFileMapping(todoist_id, filepath || '');
|
||||
await this.plugin.cacheOperation.setTaskFileMapping(todoist_id, filepath || '');
|
||||
if (currentTask.isCompleted === true) {
|
||||
await this.plugin.todoistSyncAPI.CloseTask(newTask.id);
|
||||
this.plugin.logOperation?.log('OBSIDIAN_TASK_COMPLETED', `Completed task in Obsidian: ${newTask.content}`, filepath, todoist_id, 'obsidian\u2192todoist');
|
||||
|
|
@ -224,7 +230,10 @@ export class ObsidianToTodoistSync {
|
|||
const newContent = lines.join('\n');
|
||||
await this.plugin.backupOperation?.backupFile(filepath);
|
||||
await this.app.vault.modify(file, newContent);
|
||||
this.plugin.saveSettings();
|
||||
const saved = await this.plugin.saveSettings();
|
||||
if (!saved) {
|
||||
console.warn('[fullTextNewTaskCheck] saveSettings skipped or failed');
|
||||
}
|
||||
try {
|
||||
await this.plugin.todoistSyncAPI.incrementalSync();
|
||||
const updatedTask = await this.plugin.todoistSyncAPI.GetTaskById(todoist_id);
|
||||
|
|
@ -397,7 +406,10 @@ export class ObsidianToTodoistSync {
|
|||
if (contentChanged || statusChanged || dueDateChanged || tagsChanged || priorityChanged) {
|
||||
this.plugin.debugLog(lineTask);
|
||||
this.plugin.debugLog(savedTask);
|
||||
this.plugin.saveSettings();
|
||||
const saved = await this.plugin.saveSettings();
|
||||
if (!saved) {
|
||||
console.warn('[lineModifiedTaskCheck] saveSettings skipped or failed');
|
||||
}
|
||||
try {
|
||||
await this.plugin.todoistSyncAPI.incrementalSync();
|
||||
const refreshedTask = await this.plugin.todoistSyncAPI.GetTaskById(lineTask_todoist_id);
|
||||
|
|
@ -504,8 +516,11 @@ export class ObsidianToTodoistSync {
|
|||
}
|
||||
|
||||
await this.plugin.todoistSyncAPI.CloseTask(taskId);
|
||||
await this.plugin.fileOperation.completeTaskInTheFile(taskId);
|
||||
this.plugin.saveSettings();
|
||||
await this.plugin.fileOperation.completeTaskInTheFile(taskId);
|
||||
const saved = await this.plugin.saveSettings();
|
||||
if (!saved) {
|
||||
console.warn('[closeTask] saveSettings skipped or failed');
|
||||
}
|
||||
try {
|
||||
await this.plugin.todoistSyncAPI.incrementalSync();
|
||||
const refreshedTask = await this.plugin.todoistSyncAPI.GetTaskById(taskId);
|
||||
|
|
@ -555,8 +570,11 @@ export class ObsidianToTodoistSync {
|
|||
}
|
||||
|
||||
await this.plugin.todoistSyncAPI.OpenTask(taskId);
|
||||
await this.plugin.fileOperation.uncompleteTaskInTheFile(taskId);
|
||||
this.plugin.saveSettings();
|
||||
await this.plugin.fileOperation.uncompleteTaskInTheFile(taskId);
|
||||
const saved = await this.plugin.saveSettings();
|
||||
if (!saved) {
|
||||
console.warn('[repoenTask] saveSettings skipped or failed');
|
||||
}
|
||||
try {
|
||||
await this.plugin.todoistSyncAPI.incrementalSync();
|
||||
const refreshedTask = await this.plugin.todoistSyncAPI.GetTaskById(taskId);
|
||||
|
|
|
|||
|
|
@ -44,20 +44,20 @@ export class SetDefalutProjectInTheFilepathModal extends Modal {
|
|||
|
||||
|
||||
|
||||
new Setting(contentEl)
|
||||
.setName('Default project')
|
||||
//.setDesc('Set default project for todoist tasks in the current file')
|
||||
.addDropdown(component =>
|
||||
component
|
||||
.addOption(this.defaultProjectId,this.defaultProjectName)
|
||||
.addOptions(myProjectsOptions)
|
||||
.onChange((value)=>{
|
||||
this.plugin.debugLog(`project id is ${value}`)
|
||||
this.plugin.cacheOperation.setDefaultProjectIdForFilepath(this.filepath,value)
|
||||
this.plugin.setStatusBarText()
|
||||
this.close();
|
||||
|
||||
})
|
||||
new Setting(contentEl)
|
||||
.setName('Default project')
|
||||
//.setDesc('Set default project for todoist tasks in the current file')
|
||||
.addDropdown(component =>
|
||||
component
|
||||
.addOption(this.defaultProjectId,this.defaultProjectName)
|
||||
.addOptions(myProjectsOptions)
|
||||
.onChange(async (value)=>{
|
||||
this.plugin.debugLog(`project id is ${value}`)
|
||||
await this.plugin.cacheOperation.setDefaultProjectIdForFilepath(this.filepath,value)
|
||||
this.plugin.setStatusBarText()
|
||||
this.close();
|
||||
|
||||
})
|
||||
|
||||
)
|
||||
|
||||
|
|
@ -749,7 +749,7 @@ export class TaskManagerModal extends Modal {
|
|||
if (refreshed?.updated_at) {
|
||||
await this.plugin.cacheOperation.updateTaskMappingSyncMeta(taskId, { updated_at: refreshed.updated_at });
|
||||
}
|
||||
this.plugin.safeSettings?.update({}, true);
|
||||
await this.plugin.safeSettings?.update({}, true);
|
||||
new Notice(`Conflict resolved: kept Obsidian version`);
|
||||
} else {
|
||||
const task = this.plugin.todoistSyncAPI.getTaskByIdLocal(taskId);
|
||||
|
|
@ -840,7 +840,7 @@ export class TaskManagerModal extends Modal {
|
|||
if (this._closed) return;
|
||||
await this.plugin.cacheOperation.setTaskFileMapping(taskId, filePath, 'active', true);
|
||||
await this.plugin.cacheOperation.updateTaskMappingSyncMeta(taskId, { updated_at: task.updated_at });
|
||||
this.plugin.safeSettings?.update({}, true);
|
||||
await this.plugin.safeSettings?.update({}, true);
|
||||
new Notice(`Conflict resolved: kept Todoist version`);
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
@ -868,8 +868,8 @@ export class TaskManagerModal extends Modal {
|
|||
if (this._closed) return;
|
||||
await this.plugin.fileOperation.unbindTaskInFile(taskId);
|
||||
await this.plugin.cacheOperation.deleteTaskFileMapping(taskId);
|
||||
this.plugin.safeSettings?.update({}, true);
|
||||
new Notice(`Issue task deleted`);
|
||||
await this.plugin.safeSettings?.update({}, true);
|
||||
new Notice(`Issue task deleted`);
|
||||
} catch (e) {
|
||||
console.error(`[TaskManagerModal] deleteIssueTask error:`, e);
|
||||
new Notice(`Error deleting task: ${e}`);
|
||||
|
|
@ -882,8 +882,8 @@ export class TaskManagerModal extends Modal {
|
|||
private async reEnableTask(taskId: string, filePath: string, skipRerender = false) {
|
||||
try {
|
||||
await this.plugin.cacheOperation.setTaskFileMapping(taskId, filePath, 'active', true);
|
||||
this.plugin.safeSettings?.update({}, true);
|
||||
new Notice(`Task re-enabled`);
|
||||
await this.plugin.safeSettings?.update({}, true);
|
||||
new Notice(`Task re-enabled`);
|
||||
} catch (e) {
|
||||
console.error(`[TaskManagerModal] reEnableTask error:`, e);
|
||||
new Notice(`Error re-enabling task: ${e}`);
|
||||
|
|
|
|||
Loading…
Reference in a new issue