Skip to content
Merged
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
1 change: 1 addition & 0 deletions docs/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Welcome to the TaskNotes release notes. Here you can find detailed information a

### Version 4.x (Current)

- [4.13.0](releases/4.13.0.md)
- [4.12.5](releases/4.12.5.md)
- [4.12.4](releases/4.12.4.md)
- [4.12.3](releases/4.12.3.md)
Expand Down
38 changes: 38 additions & 0 deletions docs/releases/4.13.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# TaskNotes 4.13.0

## Before updating

**HTTP API and MCP clients now require authentication.** If you previously connected without a token, copy the API token from **Settings → TaskNotes → Integrations** into your client's authentication settings. Requests must include `Authorization: Bearer <token>`. If the token is empty when the server starts, TaskNotes generates and saves one; leaving it empty no longer disables authentication. See [HTTP API](https://tasknotes.dev/HTTP_API/).

## Security

- (#2292) Required authentication for local API/MCP listeners. OAuth callbacks now use an OS-assigned loopback port, accept each authorization state only once, and return fixed pages without reflecting callback text. Thanks to @martin-forge for the hardening.

## Added

- Added a dedicated TaskNotes v5 and app beta section to the plugin's release notes, including instructions for joining the Android test. The announcement appears once rather than repeating inside individual versions.
- (#2147) Added context-menu actions for recording task completion today, on the scheduled date, on the due date, or on a chosen date. The actions can be grouped in a submenu from Appearance settings. See [Completing Tasks](https://tasknotes.dev/features/task-management/#completing-tasks).
- Rescheduling a recurring task can reactivate affected completed or skipped instances after confirmation. See [Recurring Tasks](https://tasknotes.dev/features/recurring-tasks/).
- Completion-date actions, submenu settings, and rescheduling confirmations are translated into all supported languages.
- Thanks to @renatomen for the contribution.

## Fixed

- (#2291) Preserved background task updates when saving an older task edit window, including recurring completion history and properties changed or removed elsewhere. Thanks to @martin-forge for the fix.
- (#2294) Stopped plugin startup when an existing settings file cannot be read, preserving it for recovery instead of starting services with default settings. Thanks to @GGlider for reporting settings loss in #1591 and @martin-forge for the fix.
- (#2322) Fixed metadata edits deleting the saved title when a filename cannot represent it, such as for long titles. Existing title properties are preserved on unrelated edits; this does not recover previously deleted titles. Thanks to @1dezer1 for reporting.
- (#2255, #2300) Fixed task cards repeatedly disappearing and being restored while scrolling in Reading mode, which could pull the note down to the bottom. Thanks to @logicelf for the diagnosis and @nelsonlove for the fix.
- (#2318) Kept calendar events chronological when a Base sort is configured, using Base order for tasks at the same time. Thanks to @ky1ejs for reporting #1411 and @martin-forge for the fix.
- (#2319) Avoided duplicate recurring-task projections when TaskNotes has recorded the original occurrence date of a calendar move. Completion and skip history remain visible when requested. Other move cases are unchanged. Thanks to @martin-forge for the fix.
- (#2309) Fixed Google calendars enabled through the `primary` alias using the wrong color, ignoring visibility toggles, or losing their calendar name on event cards and linked notes. Thanks to @martin-forge for the fix.
- (#2279) Fixed Google Calendar authorization stalling when the system browser opens but does not report back that it launched. Authorization now completes or times out independently, and overlapping attempts cannot stop the active connection attempt. Thanks to @DamienDLR for the diagnosis.
- (#2298, #2299) Kept timed recurrence anchors when saving custom recurrence or completing a completion-anchored instance. Timed anchors are written with `Z` and retain their time, including seconds, without a device-timezone conversion. Date-only rules and scheduled-anchor completion are unchanged. See [Recurring Tasks](https://tasknotes.dev/features/recurring-tasks/). Thanks to @wellsbk1 for reporting.
- (#2043, #2055) Fixed tasks created with the default Subtasks view's **+** button missing their project and immediately disappearing from the view. Thanks to @kudrmax for reporting and @ther12k for the initial fix.
- (#2284) Prevented repeated activation of instant checkbox conversion from creating duplicate TaskNotes while the first conversion is still in progress. Thanks to @doyoonear for reporting.
- (#2314) Fixed rescheduled ICS recurring events appearing at their original time and cancelled occurrences remaining visible. Thanks to @benschifman for reporting.
- (#1849) Fixed context menus stacking on top of each other. Only one menu stays open at a time, and clicking the same indicator again closes its menu. This previously applied to date fields only, and now covers priority, status, recurrence, reminders, task, ICS event, and batch menus. Thanks to @3zra47 for reporting and @YBKF for the contribution.
- (#2303) Removed the extra space after inline task links on desktop while retaining the task menu on touch devices. Thanks to @nelsonlove for the fix.

## Changed

- (#2316) Clarified the Google OAuth Desktop app setup and redirect-mismatch troubleshooting, including why fixed Web application redirect URLs are not reliable with dynamic callback ports. See [Calendar Setup](https://tasknotes.dev/calendar-setup/). Thanks to @TomaszGaweda for reporting and following up.
34 changes: 0 additions & 34 deletions docs/releases/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,3 @@ When a change has user-facing documentation, include a canonical tasknotes.dev l
```

-->

## Added

- (#2147) Added context-menu actions for recording task completion today, on the scheduled date, on the due date, or on a chosen date. The actions can be grouped in a submenu from Appearance settings. See [Completing Tasks](https://tasknotes.dev/features/task-management/#completing-tasks).
- Rescheduling a recurring task can reactivate affected completed or skipped instances after confirmation. See [Recurring Tasks](https://tasknotes.dev/features/recurring-tasks/).
- Completion-date actions, submenu settings, and rescheduling confirmations are translated into all supported languages.
- Thanks to @renatomen for the contribution.

## Fixed

- (#2291) Preserved background task updates when saving an older task edit window, including recurring completion history and fields removed by another writer. Thanks to @martin-forge for the fix.
- (#2294) Stopped plugin startup when an existing settings file cannot be read, preserving it for recovery instead of starting services with default settings. Thanks to @GGlider for reporting settings loss in #1591 and @martin-forge for the fix.
- (#2322) Fixed metadata edits deleting the saved title when a filename cannot represent it, such as for long titles. Existing title properties are preserved on unrelated edits; this does not recover previously deleted titles. Thanks to @1dezer1 for reporting.
- (#2255, #2300) Fixed task cards repeatedly disappearing and being restored while scrolling in Reading mode, which could pull the note down to the bottom. Thanks to @logicelf for the diagnosis and @nelsonlove for the fix.
- (#2318) Kept calendar events chronological when a Base sort is configured, using Base order for tasks at the same time. Thanks to @ky1ejs for reporting #1411 and @martin-forge for the fix.
- (#2319) Avoided duplicate recurring-task projections when an original occurrence date is already recorded by a calendar move. Completion and skip history remain visible when requested. Moves without recorded original-date metadata are not covered by this fix. Thanks to @martin-forge for the fix.
- (#2309) Fixed Google calendars enabled through the `primary` alias using the wrong color, ignoring visibility toggles, or losing their calendar name on event cards and linked notes. Thanks to @martin-forge for the fix.
- (#2279) Fixed Google Calendar authorization stalling when the system browser opens but does not report back that it launched. Authorization now completes or times out independently, and overlapping attempts cannot stop the active connection attempt. Thanks to @DamienDLR for the diagnosis.
- (#2298, #2299) Kept timed recurrence anchors when saving custom recurrence or completing a completion-anchored instance. Timed anchors are written with `Z`; their clock components, including seconds, are preserved without a device-timezone conversion. Date-only rules and scheduled-anchor completion are unchanged. See [Recurring Tasks](https://tasknotes.dev/features/recurring-tasks/). Thanks to @wellsbk1 for reporting.
- (#2043, #2055) Fixed tasks created with the default Subtasks view's **+** button missing their project and immediately disappearing from the view. Thanks to @kudrmax for reporting and @ther12k for the initial fix.
- (#2284) Prevented repeated activation of instant checkbox conversion from creating duplicate TaskNotes while the first conversion is still in progress. Thanks to @doyoonear for reporting.
- (#2314) Fixed rescheduled ICS recurring events appearing at their original time and cancelled occurrences remaining visible. Thanks to @benschifman for reporting.
- (#1849) Fixed context menus stacking on top of each other. Only one menu stays open at a time, and clicking the same indicator again closes its menu. This previously applied to date fields only, and now covers priority, status, recurrence, reminders, task, ICS event, and batch menus.
- Thanks to @3zra47 for reporting and @YBKF for the contribution.
- (#2303) Removed the extra space after inline task links on desktop while retaining the task menu on touch devices.
- Thanks to @nelsonlove for the fix.

## Changed

- (#2316) Clarified the Google OAuth Desktop app setup and redirect-mismatch troubleshooting, including why fixed Web application redirect URLs are not reliable with dynamic callback ports. See [Calendar Setup](https://tasknotes.dev/calendar-setup/). Thanks to @TomaszGaweda for reporting and following up.

## Security

- (#2292) Required authentication for local API/MCP listeners. When no token is configured, TaskNotes generates and saves one before listening. Clients that previously omitted authentication must supply the token from Integrations settings. OAuth callbacks now use an OS-assigned loopback port, accept each authorization state only once, and return fixed pages without reflecting callback text. Thanks to @martin-forge for the hardening.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "tasknotes",
"name": "TaskNotes",
"version": "4.12.5",
"version": "4.13.0",
"minAppVersion": "1.12.2",
"description": "Note-based task management with calendar, pomodoro and time-tracking integration.",
"author": "Callum Alpass",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tasknotes",
"version": "4.12.5",
"version": "4.13.0",
"description": "Note-based task management with calendar, pomodoro and time-tracking integration.",
"main": "main.js",
"scripts": {
Expand Down
22 changes: 22 additions & 0 deletions src/releaseNotesAnnouncement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## TaskNotes v5 and the TaskNotes app — join the beta

**TaskNotes v5** introduces portable collections that you can use in both Obsidian and the new **TaskNotes app**. Your tasks remain ordinary Markdown files in your vault, with [mdbase Connect](https://mdbase.dev/connect/) providing access from the app.

Available to try now:
- **[Try the TaskNotes v5 plugin beta](https://github.com/callumalpass/tasknotes/releases/tag/5.0.0-beta.2)**
- **[Try the TaskNotes web app](https://app.tasknotes.dev/)**
- **[Download TaskNotes for iOS](https://apps.apple.com/app/tasknotes/id6797168033)**

These are early releases under active development. Please back up your vault before trying them and [report any problems](https://github.com/callumalpass/tasknotes/issues). TaskNotes 4.13 remains the recommended stable plugin release.

### Help bring TaskNotes to Android

**We need at least 12 testers for the TaskNotes Android app before we can apply for a public Google Play release.**

If you have an Android device and would like to help:

1. **[Join the tester Google Group](https://groups.google.com/g/tasknotes-android-testers)** using the Google account you use for Google Play.
2. **[Opt in to the Google Play test](https://play.google.com/apps/testing/dev.tasknotes.app)** with that same account and install TaskNotes.
3. Stay opted in for **at least 14 consecutive days**, use the app regularly during that time, and let us know how it goes.

You don’t need to be a developer—using TaskNotes for your everyday tasks and sharing anything confusing or broken is valuable feedback. Your participation will help make the Android release possible.
15 changes: 14 additions & 1 deletion src/views/ReleaseNotesView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ItemView, WorkspaceLeaf, MarkdownRenderer } from "obsidian";
import { format, parseISO } from "date-fns";
import TaskNotesPlugin from "../main";
import type { ReleaseNoteVersion } from "../releaseNotes";
import releaseNotesAnnouncement from "../releaseNotesAnnouncement.md";

export const RELEASE_NOTES_VIEW_TYPE = "tasknotes-release-notes";

Expand Down Expand Up @@ -85,7 +86,13 @@ export class ReleaseNotesView extends ItemView {
versionData: ReleaseNoteVersion
): Promise<void> {
// Transform issue references into clickable links and render the markdown
const transformedNotes = this.transformIssueLinks(versionData.content);
// The beta invitation now appears once above the version list. Preserve
// historical source files (also used by GitHub), but omit their old callout.
const notes = versionData.content.replace(
/^> \[!info\] TaskNotes v5 beta\r?\n(?:>[^\n]*(?:\n|$))*/gm,
""
);
const transformedNotes = this.transformIssueLinks(notes);
const releaseContent = versionData.isCurrent
? `${this.plugin.i18n.translate("views.releaseNotes.baseFilesNotice")}\n\n${transformedNotes}`
: transformedNotes;
Expand Down Expand Up @@ -536,6 +543,12 @@ export class ReleaseNotesView extends ItemView {
starMessage.appendText(messageText);
}

// One shared announcement, independent of the bundled release versions.
const announcement = container.createEl("section", {
cls: "release-notes-announcement",
});
await MarkdownRenderer.render(this.plugin.app, releaseNotesAnnouncement, announcement, "", this);

// Create all version sections
const versionsContainer = container.createDiv({ cls: "release-notes-versions" });
for (let i = 0; i < this.releaseNotesBundle.length; i++) {
Expand Down
17 changes: 17 additions & 0 deletions styles/release-notes-view.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
.tasknotes-release-notes-view .release-notes-announcement,
.tasknotes-release-notes-view .release-notes-version-content {
font-family: var(--font-text);
font-size: var(--font-text-size);
line-height: var(--line-height-normal);
}

.tasknotes-release-notes-view .release-notes-announcement {
margin-bottom: var(--size-4-5);
padding: var(--size-4-4);
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-m);
background: var(--background-secondary);
}

.tasknotes-release-notes-view .release-notes-announcement > :first-child {
margin-top: 0;
}

.tasknotes-release-notes-view .release-notes-announcement > :last-child {
margin-bottom: 0;
}
27 changes: 27 additions & 0 deletions tests/unit/views/ReleaseNotesView.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MarkdownRenderer } from "obsidian";
import { ReleaseNotesView, transformReleaseNoteIssueLinks } from "../../../src/views/ReleaseNotesView";
import type { ReleaseNoteVersion } from "../../../src/releaseNotes";
import releaseNotesAnnouncement from "../../../src/releaseNotesAnnouncement.md";

describe("transformReleaseNoteIssueLinks", () => {
it("links a single parenthesized issue reference", () => {
Expand Down Expand Up @@ -74,6 +75,32 @@ describe("ReleaseNotesView", () => {
jest.mocked(MarkdownRenderer.render).mockClear();
});

it("renders one shared announcement before the version list", async () => {
const view = createView();
await view.onOpen();

expect(view.contentEl.querySelectorAll(".release-notes-announcement")).toHaveLength(1);
const announcement = view.contentEl.querySelector(".release-notes-announcement");
expect(announcement?.nextElementSibling?.className).toBe("release-notes-versions");
const calls = jest.mocked(MarkdownRenderer.render).mock.calls;
expect(calls).toHaveLength(1);
expect(calls[0][1]).toBe(releaseNotesAnnouncement);
expect(calls[0][2]).toBe(announcement);
expect(calls[0][4]).toBe(view);
});

it("omits legacy beta callouts without changing other release content", async () => {
const content = "# TaskNotes 4.12.4\n\n> [!info] TaskNotes v5 beta\n>\n> Old announcement\n\n## Fixed\n\n- A fix\n\n> [!info] Another notice\n> Keep this\n";
await createSection(releaseNote({ content }), true);

const rendered = jest.mocked(MarkdownRenderer.render).mock.calls[0][1];
expect(rendered).not.toContain("Old announcement");
expect(rendered).not.toContain("[!info] TaskNotes v5 beta");
expect(rendered).toContain("## Fixed\n\n- A fix");
expect(rendered).toContain("> [!info] Another notice\n> Keep this");
expect(content).toContain("Old announcement");
});

it("renders initially expanded release notes immediately", async () => {
const container = await createSection(releaseNote(), true);

Expand Down
3 changes: 2 additions & 1 deletion versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@
"4.12.2": "1.12.2",
"4.12.3": "1.12.2",
"4.12.4": "1.12.2",
"4.12.5": "1.12.2"
"4.12.5": "1.12.2",
"4.13.0": "1.12.2"
}
Loading