v1.0.37: send setSettings and setState simultaneously to avoid flash

Previously setSettings was awaited first (causing blue flash), then
setState was called. Now both are sent in the same Promise.all so
Stream Deck processes setState in the same batch, overriding the
visual reset from setSettings with no visible blue transition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
pdmarf
2026-04-24 09:15:48 +01:00
parent 5cdc77ccf3
commit 35a0bbb867
6 changed files with 13 additions and 18 deletions

View File

@@ -6438,7 +6438,7 @@ async function stopTimer(token, entryId) {
} }
// src/plugin.ts // src/plugin.ts
var CURRENT_VERSION = "1.0.36"; var CURRENT_VERSION = "1.0.37";
var GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/stable-rebuild"; var GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/stable-rebuild";
var SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- var SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4= MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4=
@@ -6623,9 +6623,8 @@ var TimerToggle = class extends SingletonAction {
if (activeEntryId) { if (activeEntryId) {
await stopTimer(global.notionToken, activeEntryId); await stopTimer(global.notionToken, activeEntryId);
const stopped = { ...ev.payload.settings, activeEntryId: null }; const stopped = { ...ev.payload.settings, activeEntryId: null };
await ev.action.setSettings(stopped);
this.settingsCache.set(ev.action.id, stopped); this.settingsCache.set(ev.action.id, stopped);
await Promise.all([ev.action.setState(0), ev.action.setTitle(title)]); await Promise.all([ev.action.setSettings(stopped), ev.action.setState(0), ev.action.setTitle(title)]);
await setRunningEntry(null); await setRunningEntry(null);
} else { } else {
const prevEntryId = await getRunningEntryId(); const prevEntryId = await getRunningEntryId();
@@ -6636,8 +6635,8 @@ var TimerToggle = class extends SingletonAction {
const otherSettings = this.settingsCache.get(other.id); const otherSettings = this.settingsCache.get(other.id);
if (otherSettings?.activeEntryId === prevEntryId) { if (otherSettings?.activeEntryId === prevEntryId) {
const stopped = { ...otherSettings, activeEntryId: null }; const stopped = { ...otherSettings, activeEntryId: null };
await other.setSettings(stopped);
this.settingsCache.set(other.id, stopped); this.settingsCache.set(other.id, stopped);
await Promise.all([other.setSettings(stopped), other.setState(0), other.setTitle(buttonTitle(otherSettings.projectName || ""))]);
} }
} }
} }
@@ -6649,9 +6648,8 @@ var TimerToggle = class extends SingletonAction {
global.userId global.userId
); );
const started = { ...ev.payload.settings, activeEntryId: entryId }; const started = { ...ev.payload.settings, activeEntryId: entryId };
await ev.action.setSettings(started);
this.settingsCache.set(ev.action.id, started); this.settingsCache.set(ev.action.id, started);
await Promise.all([ev.action.setState(1), ev.action.setTitle(`\u23F1 ${title}`)]); await Promise.all([ev.action.setSettings(started), ev.action.setState(1), ev.action.setTitle(`\u23F1 ${title}`)]);
await setRunningEntry(entryId); await setRunningEntry(entryId);
} }
} catch (err) { } catch (err) {

View File

@@ -1,2 +1 @@
Yx<■bМwHW.Eш?сI* ║╘%g╘жЮтр>eШаk╡╒Н┤*иГ╨o <EFBFBD>¹È©Ô<EFBFBD>u1ÀïÖB!ª£½I- bhݵ ä± Gr7L†]x~cá…»d³X Þ¹×9<>B/£ž/
hг@÷╘╚╞=л

View File

@@ -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.36", "Version": "1.0.37",
"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.

View File

@@ -1,4 +1,4 @@
const CURRENT_VERSION = "1.0.36"; const CURRENT_VERSION = "1.0.37";
const GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/stable-rebuild"; const GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/stable-rebuild";
const SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- const SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4= MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4=
@@ -235,10 +235,9 @@ class TimerToggle extends SingletonAction<TimerSettings> {
if (activeEntryId) { if (activeEntryId) {
await stopTimer(global.notionToken, activeEntryId); await stopTimer(global.notionToken, activeEntryId);
const stopped = { ...ev.payload.settings, activeEntryId: null }; const stopped = { ...ev.payload.settings, activeEntryId: null };
await ev.action.setSettings(stopped);
this.settingsCache.set(ev.action.id, stopped); this.settingsCache.set(ev.action.id, stopped);
// Re-assert immediately — before setRunningEntry's async calls // setSettings and setState together so the state reset doesn't flash
await Promise.all([ev.action.setState(0), ev.action.setTitle(title)]); await Promise.all([ev.action.setSettings(stopped), ev.action.setState(0), ev.action.setTitle(title)]);
await setRunningEntry(null); await setRunningEntry(null);
} else { } else {
const prevEntryId = await getRunningEntryId(); const prevEntryId = await getRunningEntryId();
@@ -251,8 +250,8 @@ class TimerToggle extends SingletonAction<TimerSettings> {
const otherSettings = this.settingsCache.get(other.id); const otherSettings = this.settingsCache.get(other.id);
if (otherSettings?.activeEntryId === prevEntryId) { if (otherSettings?.activeEntryId === prevEntryId) {
const stopped = { ...otherSettings, activeEntryId: null }; const stopped = { ...otherSettings, activeEntryId: null };
await other.setSettings(stopped);
this.settingsCache.set(other.id, stopped); this.settingsCache.set(other.id, stopped);
await Promise.all([other.setSettings(stopped), other.setState(0), other.setTitle(buttonTitle(otherSettings.projectName || ""))]);
} }
} }
} }
@@ -265,10 +264,9 @@ class TimerToggle extends SingletonAction<TimerSettings> {
global.userId, global.userId,
); );
const started = { ...ev.payload.settings, activeEntryId: entryId }; const started = { ...ev.payload.settings, activeEntryId: entryId };
await ev.action.setSettings(started);
this.settingsCache.set(ev.action.id, started); this.settingsCache.set(ev.action.id, started);
// Re-assert immediately — before setRunningEntry's async calls // setSettings and setState together so the state reset doesn't flash
await Promise.all([ev.action.setState(1), ev.action.setTitle(`${title}`)]); await Promise.all([ev.action.setSettings(started), ev.action.setState(1), ev.action.setTitle(`${title}`)]);
await setRunningEntry(entryId); await setRunningEntry(entryId);
} }
} catch (err) { } catch (err) {

View File

@@ -1 +1 @@
{ "version": "1.0.36" } { "version": "1.0.37" }