@@ -5,7 +5,9 @@ import Link from "@mui/material/Link";
5
5
import Tooltip from "@mui/material/Tooltip" ;
6
6
import { API } from "api/api" ;
7
7
import type * as TypesGen from "api/typesGenerated" ;
8
+ import { displayError } from "components/GlobalSnackbar/utils" ;
8
9
import { useProxy } from "contexts/ProxyContext" ;
10
+ import { useEffect } from "react" ;
9
11
import { type FC , type MouseEvent , useState } from "react" ;
10
12
import { createAppLinkHref } from "utils/apps" ;
11
13
import { generateRandomString } from "utils/random" ;
@@ -152,6 +154,20 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
152
154
url = href . replaceAll ( magicTokenString , key . key ) ;
153
155
setFetchingSessionToken ( false ) ;
154
156
}
157
+
158
+ // When browser recognizes the protocol and is able to navigate to the app,
159
+ // it will blur away, and will stop the timer. Otherwise,
160
+ // an error message will be displayed.
161
+ const openAppExternallyFailedTimeout = 500 ;
162
+ const openAppExternallyFailed = setTimeout ( ( ) => {
163
+ displayError (
164
+ `${ app . display_name !== "" ? app . display_name : app . slug } must be installed first.` ,
165
+ ) ;
166
+ } , openAppExternallyFailedTimeout ) ;
167
+ window . addEventListener ( "blur" , ( ) => {
168
+ clearTimeout ( openAppExternallyFailed ) ;
169
+ } ) ;
170
+
155
171
window . location . href = url ;
156
172
return ;
157
173
}
0 commit comments