Skip to content

Commit 19fa797

Browse files
committed
Improve Google Calendar task sync recovery
1 parent 2538f5b commit 19fa797

14 files changed

Lines changed: 1568 additions & 144 deletions

docs/releases/unreleased.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,13 @@ Example:
2323
```
2424
2525
-->
26+
27+
## Fixed
28+
29+
- 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.
30+
- Track exported Google Calendar task events in plugin data so startup can recover cleanup for task files deleted while Obsidian was closed.
31+
- 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.
32+
- 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.
33+
- Prevent duplicate Google Calendar task events when concurrent syncs race before the newly created event ID reaches Obsidian metadata.
34+
- Prevent pending intermediate status updates from overwriting completed Google Calendar task events when users quickly cycle a task to done.
35+
- 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
@@ -301,10 +301,11 @@ export function initializeServicesLazily(plugin: TaskNotesPlugin): void {
301301
plugin.taskCalendarSyncService = new (
302302
await import("../services/TaskCalendarSyncService")
303303
).TaskCalendarSyncService(plugin, plugin.googleCalendarService);
304+
plugin.taskCalendarSyncService.startRecoveryQueueProcessor();
304305

305306
plugin.registerEvent(
306307
plugin.emitter.on("file-deleted", (data: FileDeletedEventData) => {
307-
if (!plugin.taskCalendarSyncService?.isEnabled()) {
308+
if (!plugin.taskCalendarSyncService) {
308309
return;
309310
}
310311

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
@@ -637,6 +637,9 @@ export class GoogleCalendarService extends CalendarProvider {
637637

638638
// Build update payload
639639
const payload: GoogleCalendarEventPayload = { ...currentEvent };
640+
if (payload.status === "cancelled") {
641+
payload.status = "confirmed";
642+
}
640643

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

0 commit comments

Comments
 (0)