diff --git a/com.pdma.notion-timer.sdPlugin/bin/plugin.js b/com.pdma.notion-timer.sdPlugin/bin/plugin.js index a59bd84..022e76d 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.23"; +var CURRENT_VERSION = "1.0.25"; 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 9289204..d1817a8 100644 --- a/com.pdma.notion-timer.sdPlugin/bin/plugin.js.sig +++ b/com.pdma.notion-timer.sdPlugin/bin/plugin.js.sig @@ -1 +1,3 @@ -(=uIXpTD0tQ εFr!(\${ EHR05q \ No newline at end of file +Һ +HJ{l >0^t @@ -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 c3273a2..e30bf4c 100644 Binary files a/notion-timer.streamDeckPlugin and b/notion-timer.streamDeckPlugin differ diff --git a/src/plugin.ts b/src/plugin.ts index d59075a..0b40fcb 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,4 +1,4 @@ -const CURRENT_VERSION = "1.0.23"; +const CURRENT_VERSION = "1.0.25"; 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();