fix(ui): open external toast links via system browser

This commit is contained in:
Shantur Rathore
2026-01-28 19:24:33 +00:00
parent 1bb5aedfdb
commit 2961d41be3
3 changed files with 51 additions and 5 deletions

20
package-lock.json generated
View File

@@ -1419,6 +1419,16 @@
"node": ">=10"
}
},
"node_modules/@tauri-apps/api": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.9.1.tgz",
"integrity": "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw==",
"license": "Apache-2.0 OR MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.9.4",
"dev": true,
@@ -1462,6 +1472,15 @@
"node": ">= 10"
}
},
"node_modules/@tauri-apps/plugin-opener": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz",
"integrity": "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==",
"license": "MIT OR Apache-2.0",
"dependencies": {
"@tauri-apps/api": "^2.8.0"
}
},
"node_modules/@tootallnate/once": {
"version": "2.0.0",
"dev": true,
@@ -7471,6 +7490,7 @@
"@suid/icons-material": "^0.9.0",
"@suid/material": "^0.19.0",
"@suid/system": "^0.14.0",
"@tauri-apps/plugin-opener": "^2.5.3",
"ansi-sequence-parser": "^1.1.3",
"debug": "^4.4.3",
"github-markdown-css": "^5.8.1",

View File

@@ -17,6 +17,7 @@
"@suid/icons-material": "^0.9.0",
"@suid/material": "^0.19.0",
"@suid/system": "^0.14.0",
"@tauri-apps/plugin-opener": "^2.5.3",
"ansi-sequence-parser": "^1.1.3",
"debug": "^4.4.3",
"github-markdown-css": "^5.8.1",

View File

@@ -1,4 +1,5 @@
import toast from "solid-toast"
import { isTauriHost } from "./runtime-env"
export type ToastVariant = "info" | "success" | "warning" | "error"
@@ -21,6 +22,31 @@ export type ToastPayload = {
}
}
async function openExternalUrl(url: string): Promise<void> {
if (typeof window === "undefined") {
return
}
try {
if (isTauriHost()) {
const { openUrl } = await import("@tauri-apps/plugin-opener")
await openUrl(url)
return
}
} catch (error) {
// Fall through to browser handling.
// Note: on Linux, system opener failures can throw here.
console.warn("[notifications] unable to open via system opener", error)
}
try {
window.open(url, "_blank", "noopener,noreferrer")
} catch (error) {
console.warn("[notifications] unable to open external url", error)
toast.error("Unable to open link")
}
}
const variantAccent: Record<
ToastVariant,
{
@@ -80,14 +106,13 @@ export function showToastNotification(payload: ToastPayload): ToastHandle {
{payload.title && <p class={`font-semibold ${accent.headline}`}>{payload.title}</p>}
<p class={`${accent.body} ${payload.title ? "mt-1" : ""}`}>{payload.message}</p>
{payload.action && (
<a
<button
type="button"
class="mt-3 inline-flex items-center text-xs font-semibold uppercase tracking-wide text-sky-300 hover:text-sky-200"
href={payload.action.href}
target="_blank"
rel="noreferrer noopener"
onClick={() => void openExternalUrl(payload.action!.href)}
>
{payload.action.label}
</a>
</button>
)}
</div>
</div>