Stabilize task persistence, OAuth, recurrence and calendar behavior for next release - #2323
Merged
Merged
Conversation
…on + map filter (closes #2043) The default-relationships Subtasks filter generated by formatProjectEntryLinkExpression in defaultBasesFiles.ts emits: file.hasLink(this.file) && list(note.PROP).map(<link-normalizer>).asLink()).contains(this.file.asLink()) The currentFileContainsMatch regex captures the entire conjunction as the property expression. normalizeFilterProperty then sees: file.hasLink(this.file) && list(note.projects).map(...).asLink()) which fails every check (no leading 'list(' since the string starts with 'file.hasLink', no trailing match for the core field set, etc.) and returns null. Net effect: clicking the column '+' button on the default Subtasks tab creates a task with no 'projects' field, which then fails the view filter and disappears. Fix: strip the &&-joined left side and the generated .map(...) wrapper (balanced-paren walk, since .asLink() lives inside the .map argument) before the existing list()/note-prefix recognition runs. Tests: - 3 new regression tests in basesFilterDefaults.test.ts covering the generated core-field case, the user-defined-field case, and the missing-current-file-link fallback. - All 6/6 tests in basesFilterDefaults.test.ts pass. - All 13/13 tests across kanbanCreationDefaults, basesTaskCreation, KanbanView.manualOrderFastPath, and basesCreateFileForView pass. Refs: #2043, #1657, #1902.
…current task edits
…tion cannot delete it Reading mode is virtualised, and every render pass ends with `sizerEl.setChildrenInPlace([pusherEl, ...shownSections])`, which deletes any direct child of `.markdown-preview-sizer` that Obsidian did not put there. The task card was injected between sections, so it was deleted on every pass and re-injected on the next frame. During a scroll that cycle ran continuously and dragged the reader down the note until it hit the bottom (#2255). The scroll quiet period added in b29a29e defers re-injection but cannot stop this, because the problem is where the re-injection lands rather than how often it happens. Once the reader scrolls past the top of the note, Obsidian has detached `.mod-header.mod-ui` too, so `getMetadataOrHeaderInsertionReference` falls through to the preview pusher - whose next sibling is the first section that is *currently rendered*, not the first section of the note. The card is therefore inserted into the middle of the text being read, shoving the page down by its own height. Measured on two notes, each correction was exactly the card's occupied height (579px and 690px), and the corrections arrived every 218-262ms, which is the 200ms quiet period plus a frame. `setChildrenInPlace` only manages *direct* children, so nesting the card one level deeper leaves it untouched by the render pass. It is now placed inside the header, after the properties block. Two supporting changes make that safe: - The observer skips re-injection while the header is not rendered. Obsidian detaches the header with the card inside it when the reader scrolls past the top; that must be left alone rather than fought, and the card is restored when the header comes back. - Injection anchors on the properties block rather than the end of the header. Obsidian builds the header in stages, so appending during an early pass put the card above the properties, which then rendered underneath and shoved it down - a visible jolt on every note open. Nesting also corrects the height accounting noted in the issue: `measureSection` takes a section's height as the gap between its own `offsetTop` and its next sibling's, so a widget between sections is counted in neither. Inside the header it is counted in that section. Spacing is scoped to `.markdown-preview-view .mod-header` so Live Preview and canvas are unchanged. The gap below the card uses `--p-spacing`, the note's own gap between blocks. The `:has()` selector that trims the properties block's bottom margin needs Chromium 105+; where it does not apply the gap is simply larger, never broken. Note that requiring the properties block means a task note rendering with no `.metadata-container` at all would not receive a card.
`observeReadingModeWidgetMutations` is shared: TaskCardNoteDecorations and RelationshipsDecorations both use it. Requiring the header anchor unconditionally would have blocked the relationships widget from injecting whenever the header is detached - which is precisely where that widget lives, since it defaults to the bottom of the note. The guard is now `requireHeaderAnchor`, off by default, set only by the task card, which is the widget that nests inside the header. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SBWuKe71PRSJaN2SM4xUFJ
A Google calendar enabled as `primary` is fetched under that alias, so its events carry `primary` as their calendar id while the calendar list reports the account's real id. Event cards already reconcile the two; three other lookups compared ids directly and missed. The calendar's own color was replaced by the default Google blue, its per-calendar visibility toggle matched nothing and so never hid anything, and mini calendar entries and event-linked notes fell back to the generic provider name. Resolve the alias through one shared helper, and register the account's own calendar under both keys when building visibility toggles. Event and subscription ids are unchanged, so notes already linked to alias-fetched events still match.
# Conflicts: # docs/releases/unreleased.md
# Conflicts: # docs/releases/unreleased.md
# Conflicts: # docs/releases/unreleased.md
# Conflicts: # docs/releases/unreleased.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Integrated candidate for the agreed next-release reliability shortlist. No version bump, tag, release, or issue closeout.
Integrated existing work
20601204).primaryalias handling.b2512e07).04a06108).Existing PR commits are retained through merge commits; contributor credits are consolidated in the release notes.
Follow-up fixes from integration review
Zwithout a device-timezone conversion, following the existing model/editor calendar-anchor convention. Date-only anchors, scheduled-anchor completion and the explicit rule updater contract remain unchanged. This is a bounded instance-completion behavior choice, not a claim that an old DTSTART is an explicit completion datetime under the spec.this.notepredicates must not be treated as writable task defaults.:hasselector from fix(reading-mode): nest the task card inside the header so virtualisation cannot delete it #2300 rather than relaxing the CSS lint rule.Verification
npm run build:testpassed.Dispositions / remaining gates
{message}/{dates}interpolate in every locale.Refs #2291, #2294, #2292, #2322, #2109, #2124, #2300, #2255, #2318, #2319, #2309, #2298, #2299, #2279, #2316, #2055, #2043, #2321, #2284, #2313, #2314.