Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/releases/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,10 @@ Example:

- Made the markdown editor areas in task modals easier to click and focus.
- Reduced false-positive plugin review warnings by making background auto-export and auto-archive schedulers non-overlapping and tightening type/string conversion paths.
- 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.
- Track exported Google Calendar task events in plugin data so startup can recover cleanup for task files deleted while Obsidian was closed.
- 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.
- 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.
- Prevent duplicate Google Calendar task events when concurrent syncs race before the newly created event ID reaches Obsidian metadata.
- Prevent pending intermediate status updates from overwriting completed Google Calendar task events when users quickly cycle a task to done.
- Mark Google Calendar events as completed when tasks were already done before they became calendar-eligible.
3 changes: 2 additions & 1 deletion src/bootstrap/pluginBootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,11 @@ export function initializeServicesLazily(plugin: TaskNotesPlugin): void {
plugin.taskCalendarSyncService = new (
await import("../services/TaskCalendarSyncService")
).TaskCalendarSyncService(plugin, plugin.googleCalendarService);
plugin.taskCalendarSyncService.startRecoveryQueueProcessor();

plugin.registerEvent(
plugin.emitter.on("file-deleted", (data: FileDeletedEventData) => {
if (!plugin.taskCalendarSyncService?.isEnabled()) {
if (!plugin.taskCalendarSyncService) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/BatchContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ export class BatchContextMenu {
const file = plugin.app.vault.getAbstractFileByPath(path);
if (file) {
// Delete from Google Calendar before trashing file
if (plugin.taskCalendarSyncService?.isEnabled()) {
if (plugin.taskCalendarSyncService) {
const task = await plugin.cacheManager.getTaskInfo(path);
if (task?.googleCalendarEventId) {
try {
Expand Down
2 changes: 1 addition & 1 deletion src/components/TaskContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ export class TaskContextMenu {
if (confirmed) {
// Delete from Google Calendar before trashing file
if (
plugin.taskCalendarSyncService?.isEnabled() &&
plugin.taskCalendarSyncService &&
task.googleCalendarEventId
) {
plugin.taskCalendarSyncService
Expand Down
3 changes: 3 additions & 0 deletions src/services/GoogleCalendarService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,9 @@ export class GoogleCalendarService extends CalendarProvider {

// Build update payload
const payload: GoogleCalendarEventPayload = { ...currentEvent };
if (payload.status === "cancelled") {
payload.status = "confirmed";
}

// Support both 'title' and 'summary'
if (updates.title !== undefined || updates.summary !== undefined) {
Expand Down
Loading
Loading