diff --git a/site/src/pages/AgentsPage/AgentsPage.tsx b/site/src/pages/AgentsPage/AgentsPage.tsx index 47c98d2e6a..494ac5da22 100644 --- a/site/src/pages/AgentsPage/AgentsPage.tsx +++ b/site/src/pages/AgentsPage/AgentsPage.tsx @@ -58,6 +58,7 @@ import { hasConfiguredModelsInCatalog, } from "./modelOptions"; import { useAgentsPageKeybindings } from "./useAgentsPageKeybindings"; +import { useAgentsPWA } from "./useAgentsPWA"; import { WebPushButton } from "./WebPushButton"; /** @internal Exported for testing. */ @@ -104,6 +105,7 @@ export interface AgentsOutletContext { } const AgentsPage: FC = () => { + useAgentsPWA(); const queryClient = useQueryClient(); const navigate = useNavigate(); const { agentId } = useParams(); diff --git a/site/src/pages/AgentsPage/useAgentsPWA.ts b/site/src/pages/AgentsPage/useAgentsPWA.ts new file mode 100644 index 0000000000..c0a78a3734 --- /dev/null +++ b/site/src/pages/AgentsPage/useAgentsPWA.ts @@ -0,0 +1,70 @@ +import { useEffect } from "react"; + +/** + * Injects PWA-related
tags while the Agents page is mounted + * (manifest, apple-touch-icon, mobile-web-app metas) and tweaks the + * viewport to prevent zooming. Everything is cleaned up on unmount. + */ +export function useAgentsPWA() { + useEffect(() => { + // -- Injected elements -------------------------------------------------- + const manifest = document.createElement("link"); + manifest.rel = "manifest"; + manifest.href = "/manifest.json"; + + const appleTouchIcon = document.createElement("link"); + appleTouchIcon.rel = "apple-touch-icon"; + appleTouchIcon.href = "/apple-touch-icon.png"; + + const mobileWebAppCapable = document.createElement("meta"); + mobileWebAppCapable.name = "mobile-web-app-capable"; + mobileWebAppCapable.content = "yes"; + + const appleMobileWebAppCapable = document.createElement("meta"); + appleMobileWebAppCapable.name = "apple-mobile-web-app-capable"; + appleMobileWebAppCapable.content = "yes"; + + const appleMobileWebAppStatusBarStyle = document.createElement("meta"); + appleMobileWebAppStatusBarStyle.name = + "apple-mobile-web-app-status-bar-style"; + appleMobileWebAppStatusBarStyle.content = "black-translucent"; + + const appleMobileWebAppTitle = document.createElement("meta"); + appleMobileWebAppTitle.name = "apple-mobile-web-app-title"; + appleMobileWebAppTitle.content = "Agents"; + + const injected = [ + manifest, + appleTouchIcon, + mobileWebAppCapable, + appleMobileWebAppCapable, + appleMobileWebAppStatusBarStyle, + appleMobileWebAppTitle, + ]; + + for (const el of injected) { + document.head.appendChild(el); + } + + // -- Viewport override -------------------------------------------------- + const viewport = document.querySelector