Skip to content

Commit 0e7bd43

Browse files
committed
Improve Google Calendar task sync recovery
1 parent 469b04e commit 0e7bd43

14 files changed

Lines changed: 1565 additions & 144 deletions

docs/releases/unreleased.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,10 @@ Example:
2828

2929
- Made the markdown editor areas in task modals easier to click and focus.
3030
- Reduced false-positive plugin review warnings by making background auto-export and auto-archive schedulers non-overlapping and tightening type/string conversion paths.
31+
- Persist failed Google Calendar task-event deletions in plugin data and retry them after restart or reconnect, preventing orphaned task events when a task file is deleted while Google cleanup fails or sync is not ready.
32+
- Track exported Google Calendar task events in plugin data so startup can recover cleanup for task files deleted while Obsidian was closed.
33+
- Persist Google Calendar task sync requests while Google Calendar is not ready and replay the current task state after reconnect for scheduled, due, or both-date calendar modes.
34+
- Restore cancelled Google Calendar event tombstones when a task is synced to an existing event ID, so deleted-but-still-addressable events become visible again.
35+
- Prevent duplicate Google Calendar task events when concurrent syncs race before the newly created event ID reaches Obsidian metadata.
36+
- Prevent pending intermediate status updates from overwriting completed Google Calendar task events when users quickly cycle a task to done.
37+
- Mark Google Calendar events as completed when tasks were already done before they became calendar-eligible.

src/bootstrap/pluginBootstrap.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,11 @@ export function initializeServicesLazily(plugin: TaskNotesPlugin): void {
313313
plugin.taskCalendarSyncService = new (
314314
await import("../services/TaskCalendarSyncService")
315315
).TaskCalendarSyncService(plugin, plugin.googleCalendarService);
316+
plugin.taskCalendarSyncService.startRecoveryQueueProcessor();
316317

317318
plugin.registerEvent(
318319
plugin.emitter.on("file-deleted", (data: FileDeletedEventData) => {
319-
if (!plugin.taskCalendarSyncService?.isEnabled()) {
320+
if (!plugin.taskCalendarSyncService) {
320321
return;
321322
}
322323

src/components/BatchContextMenu.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ export class BatchContextMenu {
353353
const file = plugin.app.vault.getAbstractFileByPath(path);
354354
if (file) {
355355
// Delete from Google Calendar before trashing file
356-
if (plugin.taskCalendarSyncService?.isEnabled()) {
356+
if (plugin.taskCalendarSyncService) {
357357
const task = await plugin.cacheManager.getTaskInfo(path);
358358
if (task?.googleCalendarEventId) {
359359
try {

src/components/TaskContextMenu.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ export class TaskContextMenu {
497497
if (confirmed) {
498498
// Delete from Google Calendar before trashing file
499499
if (
500-
plugin.taskCalendarSyncService?.isEnabled() &&
500+
plugin.taskCalendarSyncService &&
501501
task.googleCalendarEventId
502502
) {
503503
plugin.taskCalendarSyncService

src/services/GoogleCalendarService.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,9 @@ export class GoogleCalendarService extends CalendarProvider {
645645

646646
// Build update payload
647647
const payload: GoogleCalendarEventPayload = { ...currentEvent };
648+
if (payload.status === "cancelled") {
649+
payload.status = "confirmed";
650+
}
648651

649652
// Support both 'title' and 'summary'
650653
if (updates.title !== undefined || updates.summary !== undefined) {

0 commit comments

Comments
 (0)