mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
[eric] browser/apps: drop the iframe fallback for a 'run in the desktop app' message (keeps srcdoc + Windows-crash iframe)
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
interface Props {
|
||||
kind?: 'browser' | 'app';
|
||||
}
|
||||
|
||||
// Shown when a browser/app card is rendered OUTSIDE Electron (the dev URL opened directly in a web browser). The real <webview> only exists in the desktop app; rather than a crippled <iframe> the agent can't drive, tell the user to launch correctly.
|
||||
const RunInDesktopMessage: React.FC<Props> = ({ kind = 'browser' }) => {
|
||||
const noun = kind === 'app' ? 'Apps' : 'Browsers';
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 1,
|
||||
px: 3,
|
||||
textAlign: 'center',
|
||||
color: '#888',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
<Typography sx={{ fontSize: '0.95rem', fontWeight: 600, color: '#bbb' }}>
|
||||
Open this in the OpenSwarm desktop app
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: '0.82rem', lineHeight: 1.5, maxWidth: 360 }}>
|
||||
{noun} run inside the OpenSwarm desktop window, not a regular web browser. It looks like you opened the dev URL directly in a browser; launch OpenSwarm (the Electron window from <code>bash run.sh</code>) and use it there instead.
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default RunInDesktopMessage;
|
||||
@@ -21,6 +21,7 @@ import AddIcon from '@mui/icons-material/Add';
|
||||
import LockIcon from '@mui/icons-material/Lock';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import SmartToyOutlinedIcon from '@mui/icons-material/SmartToyOutlined';
|
||||
import RunInDesktopMessage from '@/app/components/RunInDesktopMessage';
|
||||
import {
|
||||
setBrowserCardPosition,
|
||||
setBrowserCardSize,
|
||||
@@ -120,7 +121,8 @@ function markWindowsWebviewSurvived(): void {
|
||||
}
|
||||
|
||||
const isWindows = navigator.userAgent.includes('Windows');
|
||||
const isElectron = navigator.userAgent.includes('Electron') && (!isWindows || windowsWebviewEnabled());
|
||||
const inElectron = navigator.userAgent.includes('Electron');
|
||||
const isElectron = inElectron && (!isWindows || windowsWebviewEnabled());
|
||||
|
||||
// Keep the openswarm/<ver> product token: Google's sign-in flags a BARE Chrome UA as not-genuine-Chrome and blocks it ("browser may not be secure"), but tolerates a UA carrying a product token. Only the Electron token must go (that one Google hard-blocks).
|
||||
const chromeUserAgent = navigator.userAgent
|
||||
@@ -1325,11 +1327,11 @@ const BrowserCard: React.FC<Props> = ({
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
{!isElectron && (
|
||||
{!isElectron && (inElectron ? (
|
||||
// inElectron but !isElectron = Windows after the webview crashed (windowsWebviewEnabled() false); keep the iframe as the crash safety net. No sandbox so sites render; the renderer's already isolated by Electron + the main.js XFO/CSP strip.
|
||||
<Box sx={{ width: '100%', height: '100%', position: 'relative' }}>
|
||||
<iframe
|
||||
src={activeUrl}
|
||||
// No sandbox: a restrictive sandbox blocks some sites from rendering, and our renderer is already isolated by Electron's contextIsolation + sub_frame XFO/CSP frame-ancestors strip in main.js. onLoad/onError add definitive instrumentation so we can tell whether the iframe loaded successfully (with empty body from anti-iframe JS) or genuinely failed (network error, CSP block, etc.).
|
||||
style={{ width: '100%', height: '100%', border: 'none', pointerEvents: isElementSelectMode ? 'none' : 'auto' }}
|
||||
title="Browser"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
@@ -1339,7 +1341,9 @@ const BrowserCard: React.FC<Props> = ({
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
) : (
|
||||
<RunInDesktopMessage kind="browser" />
|
||||
))}
|
||||
|
||||
{/* Camera flash: screenshot */}
|
||||
{(agentAction === 'screenshot' || lastAction === 'screenshot') && (
|
||||
|
||||
@@ -7,8 +7,9 @@ import { useIframeElementSelector } from './useIframeElementSelector';
|
||||
import { getAuthToken, ensureAuthToken } from '@/shared/config';
|
||||
import { useClaudeTokens } from '@/shared/styles/ThemeContext';
|
||||
import { registerViewWebview, unregisterViewWebview, type ViewWebview } from '@/shared/viewWebviewRegistry';
|
||||
import RunInDesktopMessage from '@/app/components/RunInDesktopMessage';
|
||||
|
||||
// In Electron use <webview> to escape iframe restrictions (popups, mic/camera, WebAuthn, cookied fetch); outside Electron fall back to iframe.
|
||||
// In Electron use <webview> to escape iframe restrictions (popups, mic/camera, WebAuthn, cookied fetch); a srcdoc app still uses an iframe (data:text/html breaks webview same-origin); outside Electron we show a launch-correctly message.
|
||||
const isElectron = navigator.userAgent.includes('Electron');
|
||||
|
||||
// Card previews render small; downscale + JPEG so thumbnails don't bloat the output JSON or every list fetch.
|
||||
@@ -411,7 +412,8 @@ const ViewPreview = forwardRef<ViewPreviewHandle, Props>(({
|
||||
...style,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
) : isElectron ? (
|
||||
// In Electron but not useWebview = a srcdoc app (no serveUrl); the iframe is REQUIRED here (data:text/html breaks webview same-origin), not a fallback. Non-Electron falls through to the launch-correctly message.
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
// Key only changes on mode switch (URL vs srcdoc); reloadKey updates the src attribute in place to avoid blank-flash on reload.
|
||||
@@ -429,6 +431,8 @@ const ViewPreview = forwardRef<ViewPreviewHandle, Props>(({
|
||||
}}
|
||||
title="App Preview"
|
||||
/>
|
||||
) : (
|
||||
<RunInDesktopMessage kind="app" />
|
||||
)}
|
||||
{restoring && (
|
||||
<Box
|
||||
|
||||
Reference in New Issue
Block a user