authorgravatar for 159104116+whoisaldo@users.noreply.github.comAli Younes <159104116+whoisaldo@users.noreply.github.com> 2026-10-11 21:29:01-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-12 01:29:01+00:00
logd45d1a1ede45cc4daa88843c2e4bffba938df367
tree2ba2da1b95c14234698f46bbdf9f0dfc9011c0e8
parentee2763e9b20f937de0c2adffff8dddfe2d5af3b3
signature Signed by PGP key B5690EEEBB952194

fix(desktop): Option-click on a chat link opens the system browser (#18238)


1 files changed, 17 insertions(+), 1 deletions(-)

apps/web/src/components/ChatMarkdown.tsx+17-1
...@@ -173,6 +173,7 @@ import {...@@ -173,6 +173,7 @@ import {
173 type MarkdownFileLinkMeta,173 type MarkdownFileLinkMeta,
174} from "../markdown-links";174} from "../markdown-links";
175import { isMarkdownFileLinkLabel } from "@t3tools/shared/markdownLinks";175import { isMarkdownFileLinkLabel } from "@t3tools/shared/markdownLinks";
176import { isElectron } from "../env";
176import { readLocalApi } from "../localApi";177import { readLocalApi } from "../localApi";
177import { useAssetUrlRefresh, useAssetUrlState } from "../assets/assetUrls";178import { useAssetUrlRefresh, useAssetUrlState } from "../assets/assetUrls";
178import { cn } from "../lib/utils";179import { cn } from "../lib/utils";
...@@ -3035,8 +3036,8 @@ const CHAT_MARKDOWN_COMPONENTS = {...@@ -3035,8 +3036,8 @@ const CHAT_MARKDOWN_COMPONENTS = {
3035 // keeps the `_blank` the shell already handles; the in-app browser needs3036 // keeps the `_blank` the shell already handles; the in-app browser needs
3036 // the click intercepted here. A modifier click is the way out of the3037 // the click intercepted here. A modifier click is the way out of the
3037 // in-app default, so it is left to the shell too.3038 // in-app default, so it is left to the shell too.
3039 if (event.defaultPrevented) return;
3038 if (3040 if (
3039 event.defaultPrevented ||
3040 resolveLinkTarget({3041 resolveLinkTarget({
3041 url: href,3042 url: href,
3042 event,3043 event,
...@@ -3044,6 +3045,21 @@ const CHAT_MARKDOWN_COMPONENTS = {...@@ -3044,6 +3045,21 @@ const CHAT_MARKDOWN_COMPONENTS = {
3044 canOpenInApp: canOpenInPreview,3045 canOpenInApp: canOpenInPreview,
3045 }) !== "app"3046 }) !== "app"
3046 ) {3047 ) {
3048 // Chromium turns an Option/Alt-click into a download that never reaches the
3049 // shell. On desktop, open the link here while the key is still down, so link
3050 // routers such as Finicky can still read it.
3051 if (isElectron && event.altKey) {
3052 event.preventDefault();
3053 event.stopPropagation();
3054 void readLocalApi()
3055 ?.shell.openExternal(href)
3056 .catch((cause) =>
3057 reportMarkdownActionFailure(
3058 { operation: "open-link-external", target: href },
3059 cause,
3060 ),
3061 );
3062 }
3047 return;3063 return;
3048 }3064 }
3049 event.preventDefault();3065 event.preventDefault();