v1.0.33: instant button feedback on key press
Visual state change now happens before any async work (getGlobal, getRunningEntryId, API calls). Previously the button waited for getGlobal() to resolve before going green, causing a 1-2s delay. Also reverts optimistic state on API error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
const CURRENT_VERSION = "1.0.32";
|
||||
const CURRENT_VERSION = "1.0.33";
|
||||
const GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/stable-rebuild";
|
||||
const SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
||||
MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4=
|
||||
@@ -198,11 +198,22 @@ class TimerToggle extends SingletonAction<TimerSettings> {
|
||||
|
||||
async onKeyDown(ev: KeyDownEvent<TimerSettings>): Promise<void> {
|
||||
this.settingsCache.set(ev.action.id, ev.payload.settings);
|
||||
const global = await getGlobal();
|
||||
const { projectId, projectName, activeEntryId } = ev.payload.settings;
|
||||
const title = buttonTitle(projectName || "");
|
||||
|
||||
// Instant visual feedback before any async work
|
||||
if (projectId) {
|
||||
if (activeEntryId) {
|
||||
await Promise.all([ev.action.setState(0), ev.action.setTitle(title)]);
|
||||
} else {
|
||||
await Promise.all([ev.action.setState(1), ev.action.setTitle(`⏱ ${title}`)]);
|
||||
}
|
||||
}
|
||||
|
||||
const global = await getGlobal();
|
||||
|
||||
if (!isConfigured(global)) {
|
||||
await Promise.all([ev.action.setState(activeEntryId ? 1 : 0), ev.action.setTitle(activeEntryId ? `⏱ ${title}` : title)]);
|
||||
await ev.action.showAlert();
|
||||
return;
|
||||
}
|
||||
@@ -218,13 +229,11 @@ class TimerToggle extends SingletonAction<TimerSettings> {
|
||||
const stopped = { ...ev.payload.settings, activeEntryId: null };
|
||||
await ev.action.setSettings(stopped);
|
||||
this.settingsCache.set(ev.action.id, stopped);
|
||||
await ev.action.setState(0);
|
||||
await ev.action.setTitle(title);
|
||||
await setRunningEntry(null);
|
||||
} else {
|
||||
const prevEntryId = await getRunningEntryId();
|
||||
|
||||
// Optimistically update visuals immediately — no waiting for API
|
||||
// Turn off the previously running button immediately
|
||||
if (prevEntryId) {
|
||||
for (const other of this.actions) {
|
||||
if (other.id === ev.action.id) continue;
|
||||
@@ -233,11 +242,6 @@ class TimerToggle extends SingletonAction<TimerSettings> {
|
||||
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) {
|
||||
await stopTimer(global.notionToken, prevEntryId);
|
||||
for (const other of this.actions) {
|
||||
if (other.id === ev.action.id) continue;
|
||||
@@ -261,10 +265,12 @@ class TimerToggle extends SingletonAction<TimerSettings> {
|
||||
await ev.action.setSettings(started);
|
||||
this.settingsCache.set(ev.action.id, started);
|
||||
await setRunningEntry(entryId);
|
||||
// Re-assert state after setSettings, which can reset visual state
|
||||
// Re-assert after setSettings resets visual state
|
||||
await Promise.all([ev.action.setState(1), ev.action.setTitle(`⏱ ${title}`)]);
|
||||
}
|
||||
} catch (err) {
|
||||
// Revert optimistic visual on error
|
||||
await Promise.all([ev.action.setState(activeEntryId ? 1 : 0), ev.action.setTitle(activeEntryId ? `⏱ ${title}` : title)]);
|
||||
streamDeck.logger.error("Timer toggle failed:", err);
|
||||
await ev.action.showAlert();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user