From 4cfe58cde3b771da1b5130add1213aa289c58e07 Mon Sep 17 00:00:00 2001 From: pdmarf <135653545+pdmarf@users.noreply.github.com> Date: Tue, 21 Apr 2026 18:32:11 +0100 Subject: [PATCH] v1.0.16: manual update button in property inspector Co-Authored-By: Claude Sonnet 4.6 --- com.pdma.notion-timer.sdPlugin/bin/plugin.js | 30 ++++++++++++++---- .../bin/plugin.js.sig | Bin 64 -> 64 bytes .../ui/property-inspector.html | 29 +++++++++++++++++ notion-timer.streamDeckPlugin | Bin 99324 -> 99608 bytes src/plugin.ts | 24 ++++++++++---- version.json | 2 +- 6 files changed, 72 insertions(+), 13 deletions(-) diff --git a/com.pdma.notion-timer.sdPlugin/bin/plugin.js b/com.pdma.notion-timer.sdPlugin/bin/plugin.js index ec3f8d8..e543330 100644 --- a/com.pdma.notion-timer.sdPlugin/bin/plugin.js +++ b/com.pdma.notion-timer.sdPlugin/bin/plugin.js @@ -6438,7 +6438,7 @@ async function stopTimer(token, entryId) { } // src/plugin.ts -var CURRENT_VERSION = "1.0.15"; +var CURRENT_VERSION = "1.0.16"; var GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/master"; var SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4= @@ -6456,24 +6456,35 @@ function fetchWithTimeout2(url) { const timer = setTimeout(() => controller.abort(), 1e4); return fetch(url, { signal: controller.signal }).finally(() => clearTimeout(timer)); } -async function checkForUpdates() { +async function checkForUpdates(sendStatus) { try { const resp = await fetchWithTimeout2(`${GITEA_BASE}/version.json`); - if (!resp.ok) return; + if (!resp.ok) { + sendStatus?.("Update check failed"); + return; + } const { version } = await resp.json(); if (!/^\d+\.\d+\.\d+$/.test(version)) return; - if (!isNewerVersion(version, CURRENT_VERSION)) return; + if (!isNewerVersion(version, CURRENT_VERSION)) { + sendStatus?.(`Already up to date (v${CURRENT_VERSION})`); + return; + } + sendStatus?.(`Updating to v${version}\u2026`); const [pluginResp, sigResp] = await Promise.all([ fetchWithTimeout2(`${GITEA_BASE}/com.pdma.notion-timer.sdPlugin/bin/plugin.js`), fetchWithTimeout2(`${GITEA_BASE}/com.pdma.notion-timer.sdPlugin/bin/plugin.js.sig`) ]); - if (!pluginResp.ok || !sigResp.ok) return; + if (!pluginResp.ok || !sigResp.ok) { + sendStatus?.("Download failed"); + return; + } const newCode = await pluginResp.text(); const sigBytes = Buffer.from(await sigResp.arrayBuffer()); const { verify } = await import("node:crypto"); const valid = verify(null, Buffer.from(newCode), SIGNING_PUBLIC_KEY, sigBytes); if (!valid) { plugin_default.logger.error("Update rejected: signature verification failed"); + sendStatus?.("Update rejected: invalid signature"); return; } const fs3 = await import("fs"); @@ -6481,7 +6492,9 @@ async function checkForUpdates() { plugin_default.logger.info(`Updated to ${version}, restarting\u2026`); process.exit(0); } catch (err) { - plugin_default.logger.error(`Update check failed: ${err instanceof Error ? err.message : String(err)}`); + const msg = err instanceof Error ? err.message : String(err); + plugin_default.logger.error(`Update check failed: ${msg}`); + sendStatus?.(`Error: ${msg}`); } } var HARDCODED = { @@ -6621,6 +6634,11 @@ plugin_default.ui.onSendToPlugin(async (ev) => { const title = buttonTitle(ev.payload.settings.projectName || ""); if (title) await ev.action.setTitle(title); } + if (ev.payload.event === "checkForUpdates") { + const send = (msg) => plugin_default.ui.sendToPropertyInspector({ event: "updateStatus", message: msg }); + send("Checking\u2026"); + await checkForUpdates(send); + } }); plugin_default.connect(); setTimeout(() => checkForUpdates(), 1e4); diff --git a/com.pdma.notion-timer.sdPlugin/bin/plugin.js.sig b/com.pdma.notion-timer.sdPlugin/bin/plugin.js.sig index 99f1a519923ecd446c3774e86b637c4b7b7048db..21650639818fec9fb4b44ded8b28e61ec0d4e72b 100644 GIT binary patch literal 64 zcmV-G0KflaD?(Ie#Z!Ou>Q8K64n6SQWYOv8CHIHw4Q0hQ*zHfH*{HoxldhRnpC;^w W;bted%lqqy?>0~@pD0>a!vPIv&LSxQ literal 64 zcmV-G0KfkfqgHgOv4T^PdxX9n^B>X{J5S^%)JhG;y4ae}YlXc6p@s_;Y1~*S3DZx` WBvjtDY%2iRbFvU+Q*~@!rb`dg*c|Zy diff --git a/com.pdma.notion-timer.sdPlugin/ui/property-inspector.html b/com.pdma.notion-timer.sdPlugin/ui/property-inspector.html index 355496b..3d5de35 100644 --- a/com.pdma.notion-timer.sdPlugin/ui/property-inspector.html +++ b/com.pdma.notion-timer.sdPlugin/ui/property-inspector.html @@ -88,6 +88,26 @@ } #credStatus.ok { color: #4caf50; } #credStatus.error { color: #e57373; } + #updateBtn { + display: block; + width: 100%; + margin-top: 10px; + padding: 6px; + background: #2a2a2a; + border: 1px solid #444; + border-radius: 4px; + color: #ccc; + font-size: 12px; + cursor: pointer; + } + #updateBtn:hover { background: #333; } + #updateStatus { + font-size: 11px; + color: #888; + text-align: center; + margin-top: 4px; + min-height: 14px; + } @@ -125,6 +145,8 @@

+ +

@@ -229,6 +251,10 @@ document.getElementById("projectSelect").addEventListener("change", save); document.getElementById("notionToken").addEventListener("input", scheduleCredSave); document.getElementById("userId").addEventListener("change", saveCredentials); + document.getElementById("updateBtn").addEventListener("click", function() { + document.getElementById("updateStatus").textContent = ""; + $PI.sendToPlugin({ event: "checkForUpdates" }); + }); }); $PI.onDidReceiveGlobalSettings(function(jsn) { @@ -268,6 +294,9 @@ $PI.onSendToPropertyInspector(ACTION_UUID, function(jsn) { var payload = jsn.payload; + if (payload.event === "updateStatus") { + document.getElementById("updateStatus").textContent = payload.message; + } if (payload.event === "projects") { if (payload.version) { document.getElementById("versionText").textContent = "v" + payload.version; diff --git a/notion-timer.streamDeckPlugin b/notion-timer.streamDeckPlugin index 36aadc827d709b63e31008fa66b32fe4f6092faf..17e3a2b72a2ea0449e8ab81e542f84d107608f8f 100644 GIT binary patch delta 4977 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 dtc2(SRrnctt5{|B3W%9#KF diff --git a/src/plugin.ts b/src/plugin.ts index 4c0599b..2ea2919 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,4 +1,4 @@ -const CURRENT_VERSION = "1.0.15"; +const CURRENT_VERSION = "1.0.16"; const GITEA_BASE = "https://gitea.pdmarf.co.uk/pdm/stream_deck_notion_timer/raw/branch/master"; const SIGNING_PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEAN7ko8TUpuPzPAJuKAZCRjV0c4ZSlou5d9pUAF6o12b4= @@ -19,19 +19,23 @@ function fetchWithTimeout(url: string): Promise { return fetch(url, { signal: controller.signal }).finally(() => clearTimeout(timer)); } -async function checkForUpdates(): Promise { +async function checkForUpdates(sendStatus?: (msg: string) => void): Promise { try { const resp = await fetchWithTimeout(`${GITEA_BASE}/version.json`); - if (!resp.ok) return; + if (!resp.ok) { sendStatus?.("Update check failed"); return; } const { version } = await resp.json() as { version: string }; if (!/^\d+\.\d+\.\d+$/.test(version)) return; - if (!isNewerVersion(version, CURRENT_VERSION)) return; + if (!isNewerVersion(version, CURRENT_VERSION)) { + sendStatus?.(`Already up to date (v${CURRENT_VERSION})`); + return; + } + sendStatus?.(`Updating to v${version}…`); const [pluginResp, sigResp] = await Promise.all([ fetchWithTimeout(`${GITEA_BASE}/com.pdma.notion-timer.sdPlugin/bin/plugin.js`), fetchWithTimeout(`${GITEA_BASE}/com.pdma.notion-timer.sdPlugin/bin/plugin.js.sig`), ]); - if (!pluginResp.ok || !sigResp.ok) return; + if (!pluginResp.ok || !sigResp.ok) { sendStatus?.("Download failed"); return; } const newCode = await pluginResp.text(); const sigBytes = Buffer.from(await sigResp.arrayBuffer()); @@ -40,6 +44,7 @@ async function checkForUpdates(): Promise { const valid = verify(null, Buffer.from(newCode), SIGNING_PUBLIC_KEY, sigBytes); if (!valid) { streamDeck.logger.error("Update rejected: signature verification failed"); + sendStatus?.("Update rejected: invalid signature"); return; } @@ -48,7 +53,9 @@ async function checkForUpdates(): Promise { streamDeck.logger.info(`Updated to ${version}, restarting…`); process.exit(0); } catch (err) { - streamDeck.logger.error(`Update check failed: ${err instanceof Error ? err.message : String(err)}`); + const msg = err instanceof Error ? err.message : String(err); + streamDeck.logger.error(`Update check failed: ${msg}`); + sendStatus?.(`Error: ${msg}`); } } @@ -235,6 +242,11 @@ streamDeck.ui.onSendToPlugin<{ event: string; settings?: TimerSettings }>(async const title = buttonTitle(ev.payload.settings.projectName || ""); if (title) await ev.action.setTitle(title); } + if (ev.payload.event === "checkForUpdates") { + const send = (msg: string) => streamDeck.ui.sendToPropertyInspector({ event: "updateStatus", message: msg }); + send("Checking…"); + await checkForUpdates(send); + } }); streamDeck.connect(); diff --git a/version.json b/version.json index b0b51e1..8c7047a 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "version": "1.0.15" } +{ "version": "1.0.16" }