Skip to content

Commit 0b5049a

Browse files
committed
release 4.7.2
1 parent da71c84 commit 0b5049a

15 files changed

Lines changed: 78 additions & 154 deletions

docs/releases.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Welcome to the TaskNotes release notes. Here you can find detailed information a
66

77
### Version 4.x (Current)
88

9+
- [4.7.2](releases/4.7.2.md)
910
- [4.7.1](releases/4.7.1.md)
1011
- [4.7.0](releases/4.7.0.md)
1112
- [4.6.0](releases/4.6.0.md)

docs/releases/4.7.2.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# TaskNotes 4.7.2
2+
3+
## Changed
4+
5+
- Improved local lint checks so package and CSS issues reported by Obsidian's online review can be caught before submission.
6+
- Cleaned up stylesheet compatibility issues reported by Obsidian's online review without changing the intended TaskNotes appearance.
7+
- Improved spacing and alignment in task, timeblock, and webhook modals after the stylesheet cleanup.
8+
- Reworked optional calendar and ICS subscription refresh scheduling to avoid interval-based network polling while preserving the same refresh intervals.
9+
- Cleaned up additional source patterns reported by Obsidian's online review, including unsafe default object stringification and redundant external type unions.
10+
- Prevented a console error when plugin listeners are cleaned up after reloads.
11+
- Added a local lint check to prevent interval-based polling in files that also perform network requests.

docs/releases/unreleased.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,3 @@ Example:
2323
```
2424
2525
-->
26-
27-
## Changed
28-
29-
- Improved local lint checks so package and CSS issues reported by Obsidian's online review can be caught before submission.
30-
- Cleaned up stylesheet compatibility issues reported by Obsidian's online review without changing the intended TaskNotes appearance.
31-
- Improved spacing and alignment in task, timeblock, and webhook modals after the stylesheet cleanup.
32-
- Reworked optional calendar and ICS refresh scheduling to avoid `setInterval` around network requests while preserving the same refresh intervals.
33-
- Cleaned up additional source patterns reported by Obsidian's online review, including unsafe default object stringification and redundant external type unions.
34-
- Prevented a console error when plugin listeners are cleaned up after reloads.
35-
- Added a local lint check to prevent `setInterval` from being reintroduced in plugin source.

eslint.config.mjs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,28 @@ const pluginReviewRules = {
124124
};
125125
},
126126
},
127-
"no-set-interval": {
127+
"no-network-interval": {
128128
meta: {
129129
type: "problem",
130130
docs: {
131131
description:
132-
"Disallow setInterval usage so periodic work uses explicit rescheduling and avoids Obsidian review telemetry heuristics.",
132+
"Disallow setInterval in files that perform network calls, matching Obsidian review telemetry heuristics.",
133133
},
134134
messages: {
135135
noSetInterval:
136-
"Use a self-rescheduling setTimeout instead of setInterval.",
137-
noClearInterval:
138-
"Use clearTimeout with the matching self-rescheduling setTimeout.",
136+
"Use a self-rescheduling setTimeout instead of setInterval in files that perform network calls.",
139137
},
140138
schema: [],
141139
},
142140
create(context) {
141+
const sourceCode = context.sourceCode ?? context.getSourceCode();
142+
const hasNetworkCall =
143+
/\b(?:requestUrl|fetch|XMLHttpRequest|sendBeacon)\b/u.test(sourceCode.text);
144+
145+
if (!hasNetworkCall) {
146+
return {};
147+
}
148+
143149
function getCallName(callee) {
144150
if (callee.type === "Identifier") {
145151
return callee.name;
@@ -166,13 +172,6 @@ const pluginReviewRules = {
166172
messageId: "noSetInterval",
167173
});
168174
}
169-
170-
if (callName === "clearInterval") {
171-
context.report({
172-
node: node.callee,
173-
messageId: "noClearInterval",
174-
});
175-
}
176175
},
177176
};
178177
},
@@ -277,7 +276,7 @@ export default [
277276
"no-new-func": "error",
278277
"@microsoft/sdl/no-inner-html": "warn",
279278
"plugin-review/require-eslint-directive-description": "warn",
280-
"plugin-review/no-set-interval": "warn",
279+
"plugin-review/no-network-interval": "warn",
281280
"obsidianmd/no-static-styles-assignment": "warn",
282281
"obsidianmd/rule-custom-message": "warn",
283282
"obsidianmd/ui/sentence-case": "warn",

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "tasknotes",
33
"name": "TaskNotes",
4-
"version": "4.7.1",
4+
"version": "4.7.2",
55
"minAppVersion": "1.12.2",
66
"description": "Note-based task management with calendar, pomodoro and time-tracking integration.",
77
"author": "Callum Alpass",

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tasknotes",
3-
"version": "4.7.1",
3+
"version": "4.7.2",
44
"description": "Note-based task management with calendar, pomodoro and time-tracking integration.",
55
"main": "main.js",
66
"scripts": {

src/bases/KanbanView.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,24 +1915,19 @@ export class KanbanView extends BasesViewBase {
19151915
this.stopAutoScroll();
19161916
this.autoScrollDirection = newDirection;
19171917
if (newDirection !== 0) {
1918-
const scroll = () => {
1918+
this.autoScrollTimer = window.setInterval(() => {
19191919
if (this.boardEl) {
19201920
this.boardEl.scrollLeft +=
19211921
this.autoScrollDirection * this.AUTO_SCROLL_SPEED;
19221922
}
1923-
if (this.autoScrollDirection !== 0) {
1924-
this.autoScrollTimer = window.setTimeout(scroll, 16);
1925-
}
1926-
};
1927-
1928-
this.autoScrollTimer = window.setTimeout(scroll, 16);
1923+
}, 16);
19291924
}
19301925
}
19311926
}
19321927

19331928
private stopAutoScroll(): void {
19341929
if (this.autoScrollTimer) {
1935-
window.clearTimeout(this.autoScrollTimer);
1930+
window.clearInterval(this.autoScrollTimer);
19361931
this.autoScrollTimer = null;
19371932
}
19381933
this.autoScrollDirection = 0;

src/main.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export default class TaskNotesPlugin extends Plugin {
103103

104104
// Date change detection for refreshing task states at midnight
105105
private lastKnownDate: string = new Date().toDateString();
106-
private dateCheckTimer: number | null = null;
106+
private dateCheckInterval: number;
107107
private midnightTimeout: number;
108108

109109
// Ready promise to signal when initialization is complete
@@ -512,20 +512,9 @@ export default class TaskNotesPlugin extends Plugin {
512512
}
513513
};
514514

515-
const scheduleDateCheck = () => {
516-
this.dateCheckTimer = window.setTimeout(() => {
517-
checkDateChange();
518-
scheduleDateCheck();
519-
}, 60000);
520-
};
521-
522-
scheduleDateCheck();
523-
this.register(() => {
524-
if (this.dateCheckTimer) {
525-
window.clearTimeout(this.dateCheckTimer);
526-
this.dateCheckTimer = null;
527-
}
528-
});
515+
// Set up regular interval to check for date changes
516+
this.dateCheckInterval = window.setInterval(checkDateChange, 60000); // Check every minute
517+
this.registerInterval(this.dateCheckInterval);
529518

530519
// Schedule precise check at next midnight for better timing
531520
this.scheduleNextMidnightCheck();

src/modals/DeviceCodeModal.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,16 @@ export class DeviceCodeModal extends Modal {
113113
cls: "tasknotes-device-code-timer-text",
114114
});
115115

116-
const updateCountdown = () => {
116+
// Update countdown every second
117+
this.countdownInterval = window.setInterval(() => {
117118
const remaining = this.getTimeRemaining();
118119
timerText.setText(remaining);
119120

120121
// Close modal if expired
121122
if (this.expiresAt <= Date.now()) {
122123
this.close();
123-
return;
124124
}
125-
126-
this.countdownInterval = window.setTimeout(updateCountdown, 1000);
127-
};
128-
129-
this.countdownInterval = window.setTimeout(updateCountdown, 1000);
125+
}, 1000);
130126

131127
// Status indicator
132128
const statusContainer = contentEl.createDiv({ cls: "tasknotes-device-code-status" });
@@ -362,7 +358,7 @@ export class DeviceCodeModal extends Modal {
362358

363359
onClose(): void {
364360
if (this.countdownInterval) {
365-
window.clearTimeout(this.countdownInterval);
361+
window.clearInterval(this.countdownInterval);
366362
}
367363
const { contentEl } = this;
368364
contentEl.empty();

0 commit comments

Comments
 (0)