v1.0.26: eliminate double-green flash when switching timers
Both buttons now flip to their final visual state immediately on key press, before any API calls. Previously the old button stayed green throughout the stopTimer network round-trip (~0.5–2s), causing a window where both buttons appeared green simultaneously. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
47d8c7d98d
commit
d6d695e6c0
@@ -6438,7 +6438,7 @@ async function stopTimer(token, entryId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// src/plugin.ts
|
// src/plugin.ts
|
||||||
var CURRENT_VERSION = "1.0.25";
|
var CURRENT_VERSION = "1.0.26";
|
||||||
var GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/master";
|
var GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/master";
|
||||||
var SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
var SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
||||||
MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4=
|
MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4=
|
||||||
@@ -6589,6 +6589,16 @@ var TimerToggle = class extends SingletonAction {
|
|||||||
await setRunningEntry(null);
|
await setRunningEntry(null);
|
||||||
} else {
|
} else {
|
||||||
const prevEntryId = await getRunningEntryId();
|
const prevEntryId = await getRunningEntryId();
|
||||||
|
if (prevEntryId) {
|
||||||
|
for (const other of this.actions) {
|
||||||
|
if (other.id === ev.action.id) continue;
|
||||||
|
const otherSettings = this.settingsCache.get(other.id);
|
||||||
|
if (otherSettings?.activeEntryId === prevEntryId) {
|
||||||
|
await Promise.all([other.setState(0), other.setTitle(buttonTitle(otherSettings.projectName || ""))]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Promise.all([ev.action.setState(1), ev.action.setTitle(`\u23F1 ${title}`)]);
|
||||||
if (prevEntryId) {
|
if (prevEntryId) {
|
||||||
await stopTimer(global.notionToken, prevEntryId);
|
await stopTimer(global.notionToken, prevEntryId);
|
||||||
for (const other of this.actions) {
|
for (const other of this.actions) {
|
||||||
@@ -6598,8 +6608,6 @@ var TimerToggle = class extends SingletonAction {
|
|||||||
const stopped = { ...otherSettings, activeEntryId: null };
|
const stopped = { ...otherSettings, activeEntryId: null };
|
||||||
await other.setSettings(stopped);
|
await other.setSettings(stopped);
|
||||||
this.settingsCache.set(other.id, stopped);
|
this.settingsCache.set(other.id, stopped);
|
||||||
await other.setState(0);
|
|
||||||
await other.setTitle(buttonTitle(otherSettings.projectName || ""));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6614,8 +6622,6 @@ var TimerToggle = class extends SingletonAction {
|
|||||||
await ev.action.setSettings(started);
|
await ev.action.setSettings(started);
|
||||||
this.settingsCache.set(ev.action.id, started);
|
this.settingsCache.set(ev.action.id, started);
|
||||||
await setRunningEntry(entryId);
|
await setRunningEntry(entryId);
|
||||||
await ev.action.setState(1);
|
|
||||||
await ev.action.setTitle(`\u23F1 ${title}`);
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
plugin_default.logger.error("Timer toggle failed:", err);
|
plugin_default.logger.error("Timer toggle failed:", err);
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
чжр╨╞
|
KH›YƢRK>q2lĚűZ
|
||||||
HJК{lн И▐>ь┘0^Уt<fх▄╦┼Ь╢\ME
/куCБ╡ЗsW
|
e>ÓřťőüW%"YŔ8gĆe�€Ý8BÓŻ$>ŤWĎ=kIÜÇÄŹ¸Mîe2K
|
||||||
тЪ╛─'╙▀1и█╚
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"Author": "Pete Marfleet",
|
"Author": "Pete Marfleet",
|
||||||
"Description": "Toggle Notion time tracking for a project with a single button press.",
|
"Description": "Toggle Notion time tracking for a project with a single button press.",
|
||||||
"Name": "Notion Timer",
|
"Name": "Notion Timer",
|
||||||
"Version": "1.0.25",
|
"Version": "1.0.26",
|
||||||
"SDKVersion": 2,
|
"SDKVersion": 2,
|
||||||
"Software": { "MinimumVersion": "5.0" },
|
"Software": { "MinimumVersion": "5.0" },
|
||||||
"OS": [{ "Platform": "mac", "MinimumVersion": "10.11" }],
|
"OS": [{ "Platform": "mac", "MinimumVersion": "10.11" }],
|
||||||
|
|||||||
Binary file not shown.
+14
-6
@@ -1,4 +1,4 @@
|
|||||||
const CURRENT_VERSION = "1.0.25";
|
const CURRENT_VERSION = "1.0.26";
|
||||||
const GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/master";
|
const GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/master";
|
||||||
const SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
const SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
||||||
MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4=
|
MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4=
|
||||||
@@ -195,7 +195,19 @@ class TimerToggle extends SingletonAction<TimerSettings> {
|
|||||||
} else {
|
} else {
|
||||||
const prevEntryId = await getRunningEntryId();
|
const prevEntryId = await getRunningEntryId();
|
||||||
|
|
||||||
// Stop previous timer
|
// Optimistically update visuals immediately — no waiting for API
|
||||||
|
if (prevEntryId) {
|
||||||
|
for (const other of this.actions) {
|
||||||
|
if (other.id === ev.action.id) continue;
|
||||||
|
const otherSettings = this.settingsCache.get(other.id);
|
||||||
|
if (otherSettings?.activeEntryId === prevEntryId) {
|
||||||
|
await Promise.all([other.setState(0), other.setTitle(buttonTitle(otherSettings.projectName || ""))]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Promise.all([ev.action.setState(1), ev.action.setTitle(`⏱ ${title}`)]);
|
||||||
|
|
||||||
|
// Now do the API calls
|
||||||
if (prevEntryId) {
|
if (prevEntryId) {
|
||||||
await stopTimer(global.notionToken, prevEntryId);
|
await stopTimer(global.notionToken, prevEntryId);
|
||||||
for (const other of this.actions) {
|
for (const other of this.actions) {
|
||||||
@@ -205,8 +217,6 @@ class TimerToggle extends SingletonAction<TimerSettings> {
|
|||||||
const stopped = { ...otherSettings, activeEntryId: null };
|
const stopped = { ...otherSettings, activeEntryId: null };
|
||||||
await other.setSettings(stopped);
|
await other.setSettings(stopped);
|
||||||
this.settingsCache.set(other.id, stopped);
|
this.settingsCache.set(other.id, stopped);
|
||||||
await other.setState(0);
|
|
||||||
await other.setTitle(buttonTitle(otherSettings.projectName || ""));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,8 +232,6 @@ class TimerToggle extends SingletonAction<TimerSettings> {
|
|||||||
await ev.action.setSettings(started);
|
await ev.action.setSettings(started);
|
||||||
this.settingsCache.set(ev.action.id, started);
|
this.settingsCache.set(ev.action.id, started);
|
||||||
await setRunningEntry(entryId);
|
await setRunningEntry(entryId);
|
||||||
await ev.action.setState(1);
|
|
||||||
await ev.action.setTitle(`⏱ ${title}`);
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
streamDeck.logger.error("Timer toggle failed:", err);
|
streamDeck.logger.error("Timer toggle failed:", err);
|
||||||
|
|||||||
Reference in New Issue
Block a user