@ottocode/web-sdk 0.1.288 → 0.1.289
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/browser/BrowserViewerPanel.d.ts +25 -0
- package/dist/components/browser/BrowserViewerPanel.d.ts.map +1 -1
- package/dist/components/index.js +344 -69
- package/dist/components/index.js.map +4 -4
- package/dist/components/workspace/ViewerTabs.d.ts.map +1 -1
- package/dist/index.js +363 -88
- package/dist/index.js.map +4 -4
- package/package.json +3 -3
package/dist/components/index.js
CHANGED
|
@@ -31392,7 +31392,7 @@ var BrowserPanelToggle = memo49(function BrowserPanelToggle2() {
|
|
|
31392
31392
|
});
|
|
31393
31393
|
});
|
|
31394
31394
|
// src/components/browser/BrowserViewerPanel.tsx
|
|
31395
|
-
import { useEffect as useEffect56, useState as useState52 } from "react";
|
|
31395
|
+
import { useCallback as useCallback37, useEffect as useEffect56, useRef as useRef38, useState as useState52 } from "react";
|
|
31396
31396
|
import {
|
|
31397
31397
|
ChevronLeft as ChevronLeft2,
|
|
31398
31398
|
ChevronRight as ChevronRight18,
|
|
@@ -31400,7 +31400,8 @@ import {
|
|
|
31400
31400
|
Globe2 as Globe23,
|
|
31401
31401
|
Plus as Plus9,
|
|
31402
31402
|
RefreshCw as RefreshCw12,
|
|
31403
|
-
Smartphone
|
|
31403
|
+
Smartphone,
|
|
31404
|
+
X as X23
|
|
31404
31405
|
} from "lucide-react";
|
|
31405
31406
|
|
|
31406
31407
|
// src/hooks/useSimulator.ts
|
|
@@ -31432,13 +31433,17 @@ function useSimulatorStatus() {
|
|
|
31432
31433
|
import { jsx as jsx122, jsxs as jsxs106 } from "react/jsx-runtime";
|
|
31433
31434
|
var DEFAULT_BROWSER_URL = "http://localhost:3000";
|
|
31434
31435
|
var SIMULATOR_URL = "http://localhost:3200";
|
|
31436
|
+
var IFRAME_EMBED_TIMEOUT_MS = 6000;
|
|
31435
31437
|
function normalizeBrowserUrl(value) {
|
|
31436
31438
|
const trimmed = value.trim();
|
|
31437
31439
|
if (!trimmed)
|
|
31438
31440
|
return "";
|
|
31439
31441
|
if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed))
|
|
31440
31442
|
return trimmed;
|
|
31441
|
-
|
|
31443
|
+
if (/^(localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?:\/|$)/i.test(trimmed)) {
|
|
31444
|
+
return `http://${trimmed}`;
|
|
31445
|
+
}
|
|
31446
|
+
return `https://${trimmed}`;
|
|
31442
31447
|
}
|
|
31443
31448
|
function isEmbeddableUrl(value) {
|
|
31444
31449
|
if (!value)
|
|
@@ -31454,11 +31459,100 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31454
31459
|
const updateBrowserTabUrl = useViewerTabsStore((state) => state.updateBrowserTabUrl);
|
|
31455
31460
|
const reloadBrowserTab = useViewerTabsStore((state) => state.reloadBrowserTab);
|
|
31456
31461
|
const openBrowserTab = useViewerTabsStore((state) => state.openBrowserTab);
|
|
31462
|
+
const contentRef = useRef38(null);
|
|
31463
|
+
const iframeRef = useRef38(null);
|
|
31464
|
+
const loadingDoneTimeoutRef = useRef38(null);
|
|
31465
|
+
const iframeEmbedTimeoutRef = useRef38(null);
|
|
31466
|
+
const isLoadingRef = useRef38(false);
|
|
31457
31467
|
const [draftUrl, setDraftUrl] = useState52(tab.url);
|
|
31468
|
+
const [historyEntries, setHistoryEntries] = useState52(() => tab.url ? [normalizeBrowserUrl(tab.url)] : []);
|
|
31469
|
+
const [historyIndex, setHistoryIndex] = useState52(tab.url ? 0 : -1);
|
|
31470
|
+
const [isLoading, setIsLoading] = useState52(() => isEmbeddableUrl(normalizeBrowserUrl(tab.url)));
|
|
31471
|
+
const [loadingProgress, setLoadingProgress] = useState52(() => isEmbeddableUrl(normalizeBrowserUrl(tab.url)) ? 12 : 0);
|
|
31472
|
+
const [embedError, setEmbedError] = useState52(null);
|
|
31458
31473
|
const simulatorStatus = useSimulatorStatus();
|
|
31474
|
+
const nativeBrowser = typeof window !== "undefined" ? window.OTTO_NATIVE_BROWSER : undefined;
|
|
31475
|
+
const normalizedUrl = normalizeBrowserUrl(tab.url);
|
|
31476
|
+
const canRenderUrl = isEmbeddableUrl(normalizedUrl);
|
|
31477
|
+
const useNativeBrowser = Boolean(nativeBrowser?.isAvailable && canRenderUrl);
|
|
31478
|
+
const canGoBack = historyIndex > 0;
|
|
31479
|
+
const canGoForward = historyIndex >= 0 && historyIndex < historyEntries.length - 1;
|
|
31480
|
+
const clearIframeEmbedTimeout = useCallback37(() => {
|
|
31481
|
+
if (iframeEmbedTimeoutRef.current) {
|
|
31482
|
+
clearTimeout(iframeEmbedTimeoutRef.current);
|
|
31483
|
+
iframeEmbedTimeoutRef.current = null;
|
|
31484
|
+
}
|
|
31485
|
+
}, []);
|
|
31486
|
+
const completeLoading = useCallback37(() => {
|
|
31487
|
+
clearIframeEmbedTimeout();
|
|
31488
|
+
setEmbedError(null);
|
|
31489
|
+
setLoadingProgress(100);
|
|
31490
|
+
if (loadingDoneTimeoutRef.current) {
|
|
31491
|
+
clearTimeout(loadingDoneTimeoutRef.current);
|
|
31492
|
+
}
|
|
31493
|
+
loadingDoneTimeoutRef.current = setTimeout(() => {
|
|
31494
|
+
setIsLoading(false);
|
|
31495
|
+
setLoadingProgress(0);
|
|
31496
|
+
loadingDoneTimeoutRef.current = null;
|
|
31497
|
+
}, 180);
|
|
31498
|
+
}, [clearIframeEmbedTimeout]);
|
|
31459
31499
|
useEffect56(() => {
|
|
31460
31500
|
setDraftUrl(tab.url);
|
|
31461
31501
|
}, [tab.url]);
|
|
31502
|
+
useEffect56(() => {
|
|
31503
|
+
isLoadingRef.current = isLoading;
|
|
31504
|
+
}, [isLoading]);
|
|
31505
|
+
useEffect56(() => {
|
|
31506
|
+
if (!isLoading)
|
|
31507
|
+
return;
|
|
31508
|
+
setLoadingProgress((progress) => progress <= 0 || progress >= 100 ? 12 : progress);
|
|
31509
|
+
const interval = setInterval(() => {
|
|
31510
|
+
setLoadingProgress((progress) => {
|
|
31511
|
+
if (progress >= 88)
|
|
31512
|
+
return progress;
|
|
31513
|
+
return Math.min(88, progress + Math.max(2, (90 - progress) * 0.12));
|
|
31514
|
+
});
|
|
31515
|
+
}, 250);
|
|
31516
|
+
return () => clearInterval(interval);
|
|
31517
|
+
}, [isLoading]);
|
|
31518
|
+
useEffect56(() => () => {
|
|
31519
|
+
if (loadingDoneTimeoutRef.current) {
|
|
31520
|
+
clearTimeout(loadingDoneTimeoutRef.current);
|
|
31521
|
+
}
|
|
31522
|
+
clearIframeEmbedTimeout();
|
|
31523
|
+
}, [clearIframeEmbedTimeout]);
|
|
31524
|
+
useEffect56(() => {
|
|
31525
|
+
if (!isLoading || !canRenderUrl || useNativeBrowser) {
|
|
31526
|
+
clearIframeEmbedTimeout();
|
|
31527
|
+
return;
|
|
31528
|
+
}
|
|
31529
|
+
clearIframeEmbedTimeout();
|
|
31530
|
+
iframeEmbedTimeoutRef.current = setTimeout(() => {
|
|
31531
|
+
setEmbedError("This site may block embedding in Otto, or it took too long to load.");
|
|
31532
|
+
setIsLoading(false);
|
|
31533
|
+
setLoadingProgress(0);
|
|
31534
|
+
}, IFRAME_EMBED_TIMEOUT_MS);
|
|
31535
|
+
return clearIframeEmbedTimeout;
|
|
31536
|
+
}, [canRenderUrl, clearIframeEmbedTimeout, isLoading, useNativeBrowser]);
|
|
31537
|
+
useEffect56(() => () => {
|
|
31538
|
+
if (nativeBrowser?.isAvailable) {
|
|
31539
|
+
nativeBrowser.unmount(tab.id);
|
|
31540
|
+
}
|
|
31541
|
+
}, [nativeBrowser, tab.id]);
|
|
31542
|
+
useEffect56(() => {
|
|
31543
|
+
const nextUrl = normalizeBrowserUrl(tab.url);
|
|
31544
|
+
if (!nextUrl)
|
|
31545
|
+
return;
|
|
31546
|
+
setHistoryEntries((entries) => {
|
|
31547
|
+
if (entries[historyIndex] === nextUrl)
|
|
31548
|
+
return entries;
|
|
31549
|
+
const nextEntries = entries.slice(0, historyIndex + 1);
|
|
31550
|
+
nextEntries.push(nextUrl);
|
|
31551
|
+
setHistoryIndex(nextEntries.length - 1);
|
|
31552
|
+
setIsLoading(isEmbeddableUrl(nextUrl));
|
|
31553
|
+
return nextEntries;
|
|
31554
|
+
});
|
|
31555
|
+
}, [tab.url, historyIndex]);
|
|
31462
31556
|
useEffect56(() => {
|
|
31463
31557
|
const url = simulatorStatus.data?.url ?? SIMULATOR_URL;
|
|
31464
31558
|
if (tab.kind === "simulator" && simulatorStatus.data?.status === "connected" && url !== tab.url) {
|
|
@@ -31468,25 +31562,113 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31468
31562
|
});
|
|
31469
31563
|
}
|
|
31470
31564
|
}, [openBrowserTab, simulatorStatus.data, tab.kind, tab.url]);
|
|
31471
|
-
|
|
31472
|
-
|
|
31565
|
+
useEffect56(() => {
|
|
31566
|
+
if (!useNativeBrowser || !nativeBrowser?.isAvailable)
|
|
31567
|
+
return;
|
|
31568
|
+
const content = contentRef.current;
|
|
31569
|
+
if (!content)
|
|
31570
|
+
return;
|
|
31571
|
+
let cancelled = false;
|
|
31572
|
+
const mountNativeBrowser = () => {
|
|
31573
|
+
const rect = content.getBoundingClientRect();
|
|
31574
|
+
const visible = rect.width > 1 && rect.height > 1;
|
|
31575
|
+
if (!visible) {
|
|
31576
|
+
nativeBrowser.setVisible(tab.id, false);
|
|
31577
|
+
return;
|
|
31578
|
+
}
|
|
31579
|
+
nativeBrowser.mount({
|
|
31580
|
+
id: tab.id,
|
|
31581
|
+
url: normalizedUrl,
|
|
31582
|
+
reloadKey: tab.reloadKey,
|
|
31583
|
+
bounds: {
|
|
31584
|
+
x: rect.x,
|
|
31585
|
+
y: rect.y,
|
|
31586
|
+
width: rect.width,
|
|
31587
|
+
height: rect.height
|
|
31588
|
+
},
|
|
31589
|
+
visible
|
|
31590
|
+
}).then(() => {
|
|
31591
|
+
if (!cancelled && isLoadingRef.current)
|
|
31592
|
+
completeLoading();
|
|
31593
|
+
}).catch((error) => {
|
|
31594
|
+
if (cancelled)
|
|
31595
|
+
return;
|
|
31596
|
+
const message = error instanceof Error ? error.message : "Unable to open the native desktop webview.";
|
|
31597
|
+
setEmbedError(message);
|
|
31598
|
+
setIsLoading(false);
|
|
31599
|
+
setLoadingProgress(0);
|
|
31600
|
+
});
|
|
31601
|
+
};
|
|
31602
|
+
mountNativeBrowser();
|
|
31603
|
+
const resizeObserver = new ResizeObserver(mountNativeBrowser);
|
|
31604
|
+
resizeObserver.observe(content);
|
|
31605
|
+
window.addEventListener("resize", mountNativeBrowser);
|
|
31606
|
+
return () => {
|
|
31607
|
+
cancelled = true;
|
|
31608
|
+
resizeObserver.disconnect();
|
|
31609
|
+
window.removeEventListener("resize", mountNativeBrowser);
|
|
31610
|
+
};
|
|
31611
|
+
}, [
|
|
31612
|
+
completeLoading,
|
|
31613
|
+
nativeBrowser,
|
|
31614
|
+
normalizedUrl,
|
|
31615
|
+
tab.id,
|
|
31616
|
+
tab.reloadKey,
|
|
31617
|
+
useNativeBrowser
|
|
31618
|
+
]);
|
|
31473
31619
|
const navigate = (value) => {
|
|
31474
31620
|
const nextUrl = normalizeBrowserUrl(value);
|
|
31621
|
+
if (!nextUrl)
|
|
31622
|
+
return;
|
|
31623
|
+
setEmbedError(null);
|
|
31624
|
+
setIsLoading(isEmbeddableUrl(nextUrl));
|
|
31625
|
+
setLoadingProgress(isEmbeddableUrl(nextUrl) ? 12 : 0);
|
|
31626
|
+
setHistoryEntries((entries) => {
|
|
31627
|
+
const currentUrl = entries[historyIndex];
|
|
31628
|
+
if (currentUrl === nextUrl)
|
|
31629
|
+
return entries;
|
|
31630
|
+
const nextEntries = entries.slice(0, historyIndex + 1);
|
|
31631
|
+
nextEntries.push(nextUrl);
|
|
31632
|
+
setHistoryIndex(nextEntries.length - 1);
|
|
31633
|
+
return nextEntries;
|
|
31634
|
+
});
|
|
31635
|
+
updateBrowserTabUrl(tab.id, nextUrl);
|
|
31636
|
+
};
|
|
31637
|
+
const goToHistoryIndex = (index) => {
|
|
31638
|
+
const nextUrl = historyEntries[index];
|
|
31639
|
+
if (!nextUrl)
|
|
31640
|
+
return;
|
|
31641
|
+
setHistoryIndex(index);
|
|
31642
|
+
setEmbedError(null);
|
|
31643
|
+
setIsLoading(isEmbeddableUrl(nextUrl));
|
|
31644
|
+
setLoadingProgress(isEmbeddableUrl(nextUrl) ? 12 : 0);
|
|
31475
31645
|
updateBrowserTabUrl(tab.id, nextUrl);
|
|
31476
31646
|
};
|
|
31647
|
+
const stopLoading = () => {
|
|
31648
|
+
try {
|
|
31649
|
+
iframeRef.current?.contentWindow?.stop();
|
|
31650
|
+
} catch {}
|
|
31651
|
+
setIsLoading(false);
|
|
31652
|
+
setLoadingProgress(0);
|
|
31653
|
+
clearIframeEmbedTimeout();
|
|
31654
|
+
if (nativeBrowser?.isAvailable) {
|
|
31655
|
+
nativeBrowser.setVisible(tab.id, false);
|
|
31656
|
+
}
|
|
31657
|
+
};
|
|
31477
31658
|
const simulatorError = tab.kind === "simulator" && simulatorStatus.data?.status === "error" ? simulatorStatus.data.error : null;
|
|
31478
31659
|
return /* @__PURE__ */ jsxs106("div", {
|
|
31479
31660
|
className: "h-full w-full min-w-0 bg-background flex flex-col",
|
|
31480
31661
|
children: [
|
|
31481
31662
|
/* @__PURE__ */ jsx122("div", {
|
|
31482
|
-
className: "shrink-0 border-b border-border bg-
|
|
31663
|
+
className: "shrink-0 border-b border-border bg-sidebar text-muted-foreground",
|
|
31483
31664
|
children: /* @__PURE__ */ jsxs106("div", {
|
|
31484
|
-
className: "flex h-11 items-center gap-1 px-3",
|
|
31665
|
+
className: "relative flex h-11 items-center gap-1 px-3",
|
|
31485
31666
|
children: [
|
|
31486
31667
|
/* @__PURE__ */ jsx122("button", {
|
|
31487
31668
|
type: "button",
|
|
31488
|
-
|
|
31489
|
-
|
|
31669
|
+
onClick: () => goToHistoryIndex(historyIndex - 1),
|
|
31670
|
+
disabled: !canGoBack,
|
|
31671
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground/40 disabled:hover:bg-transparent",
|
|
31490
31672
|
title: "Back",
|
|
31491
31673
|
children: /* @__PURE__ */ jsx122(ChevronLeft2, {
|
|
31492
31674
|
className: "h-4 w-4"
|
|
@@ -31494,8 +31676,9 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31494
31676
|
}),
|
|
31495
31677
|
/* @__PURE__ */ jsx122("button", {
|
|
31496
31678
|
type: "button",
|
|
31497
|
-
|
|
31498
|
-
|
|
31679
|
+
onClick: () => goToHistoryIndex(historyIndex + 1),
|
|
31680
|
+
disabled: !canGoForward,
|
|
31681
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground/40 disabled:hover:bg-transparent",
|
|
31499
31682
|
title: "Forward",
|
|
31500
31683
|
children: /* @__PURE__ */ jsx122(ChevronRight18, {
|
|
31501
31684
|
className: "h-4 w-4"
|
|
@@ -31503,25 +31686,45 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31503
31686
|
}),
|
|
31504
31687
|
/* @__PURE__ */ jsx122("button", {
|
|
31505
31688
|
type: "button",
|
|
31506
|
-
onClick: () =>
|
|
31507
|
-
|
|
31508
|
-
|
|
31509
|
-
|
|
31510
|
-
|
|
31689
|
+
onClick: () => {
|
|
31690
|
+
if (isLoading) {
|
|
31691
|
+
stopLoading();
|
|
31692
|
+
return;
|
|
31693
|
+
}
|
|
31694
|
+
setEmbedError(null);
|
|
31695
|
+
setIsLoading(true);
|
|
31696
|
+
setLoadingProgress(12);
|
|
31697
|
+
reloadBrowserTab(tab.id);
|
|
31698
|
+
},
|
|
31699
|
+
disabled: !isLoading && !canRenderUrl,
|
|
31700
|
+
title: isLoading ? "Stop loading" : "Reload",
|
|
31701
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground/40 disabled:hover:bg-transparent",
|
|
31702
|
+
children: isLoading ? /* @__PURE__ */ jsx122(X23, {
|
|
31703
|
+
className: "h-4 w-4"
|
|
31704
|
+
}) : /* @__PURE__ */ jsx122(RefreshCw12, {
|
|
31511
31705
|
className: "h-4 w-4"
|
|
31512
31706
|
})
|
|
31513
31707
|
}),
|
|
31514
31708
|
/* @__PURE__ */ jsx122("form", {
|
|
31515
|
-
className: "mx-2 min-w-48 flex-1",
|
|
31709
|
+
className: "relative mx-2 min-w-48 flex-1",
|
|
31516
31710
|
onSubmit: (event) => {
|
|
31517
31711
|
event.preventDefault();
|
|
31518
31712
|
navigate(draftUrl);
|
|
31519
31713
|
},
|
|
31520
|
-
children: /* @__PURE__ */
|
|
31521
|
-
|
|
31522
|
-
|
|
31523
|
-
|
|
31524
|
-
|
|
31714
|
+
children: /* @__PURE__ */ jsxs106("div", {
|
|
31715
|
+
className: "relative h-8 overflow-hidden rounded-md border border-input bg-muted/30 focus-within:border-ring",
|
|
31716
|
+
children: [
|
|
31717
|
+
loadingProgress > 0 && /* @__PURE__ */ jsx122("div", {
|
|
31718
|
+
className: "absolute inset-y-0 left-0 bg-primary/10 transition-[width] duration-200 ease-out",
|
|
31719
|
+
style: { width: `${loadingProgress}%` }
|
|
31720
|
+
}),
|
|
31721
|
+
/* @__PURE__ */ jsx122("input", {
|
|
31722
|
+
value: draftUrl,
|
|
31723
|
+
onChange: (event) => setDraftUrl(event.target.value),
|
|
31724
|
+
placeholder: "localhost:3000 or https://example.com",
|
|
31725
|
+
className: "relative z-10 h-full w-full bg-transparent px-3 font-mono text-xs text-foreground outline-none placeholder:text-muted-foreground/60"
|
|
31726
|
+
})
|
|
31727
|
+
]
|
|
31525
31728
|
})
|
|
31526
31729
|
}),
|
|
31527
31730
|
/* @__PURE__ */ jsx122("button", {
|
|
@@ -31529,7 +31732,7 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31529
31732
|
onClick: () => window.open(normalizedUrl, "_blank", "noopener,noreferrer"),
|
|
31530
31733
|
disabled: !canRenderUrl,
|
|
31531
31734
|
title: "Open externally",
|
|
31532
|
-
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-
|
|
31735
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground/40 disabled:hover:bg-transparent",
|
|
31533
31736
|
children: /* @__PURE__ */ jsx122(ExternalLink11, {
|
|
31534
31737
|
className: "h-4 w-4"
|
|
31535
31738
|
})
|
|
@@ -31542,7 +31745,7 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31542
31745
|
newTab: true
|
|
31543
31746
|
}),
|
|
31544
31747
|
title: "New browser preview",
|
|
31545
|
-
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-
|
|
31748
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
31546
31749
|
children: /* @__PURE__ */ jsx122(Plus9, {
|
|
31547
31750
|
className: "h-4 w-4"
|
|
31548
31751
|
})
|
|
@@ -31554,7 +31757,7 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31554
31757
|
title: "Simulator"
|
|
31555
31758
|
}),
|
|
31556
31759
|
title: "Simulator preview",
|
|
31557
|
-
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-
|
|
31760
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
31558
31761
|
children: /* @__PURE__ */ jsx122(Smartphone, {
|
|
31559
31762
|
className: "h-4 w-4"
|
|
31560
31763
|
})
|
|
@@ -31567,13 +31770,67 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31567
31770
|
children: simulatorError
|
|
31568
31771
|
}),
|
|
31569
31772
|
/* @__PURE__ */ jsx122("div", {
|
|
31773
|
+
ref: contentRef,
|
|
31570
31774
|
className: "min-h-0 flex-1 bg-muted/20",
|
|
31571
|
-
children: canRenderUrl ? /* @__PURE__ */ jsx122("
|
|
31775
|
+
children: useNativeBrowser && canRenderUrl ? /* @__PURE__ */ jsx122("div", {
|
|
31776
|
+
className: "h-full w-full bg-background"
|
|
31777
|
+
}) : canRenderUrl && !embedError ? /* @__PURE__ */ jsx122("iframe", {
|
|
31778
|
+
ref: iframeRef,
|
|
31572
31779
|
title: tab.title,
|
|
31573
31780
|
src: normalizedUrl,
|
|
31781
|
+
onLoad: completeLoading,
|
|
31574
31782
|
className: "h-full w-full border-0 bg-background",
|
|
31575
31783
|
allow: "clipboard-read; clipboard-write; fullscreen; microphone; camera; geolocation; autoplay"
|
|
31576
|
-
}, `${tab.id}:${tab.reloadKey}`) : /* @__PURE__ */ jsx122("div", {
|
|
31784
|
+
}, `${tab.id}:${tab.reloadKey}`) : embedError ? /* @__PURE__ */ jsx122("div", {
|
|
31785
|
+
className: "h-full w-full flex items-center justify-center p-6 text-center",
|
|
31786
|
+
children: /* @__PURE__ */ jsxs106("div", {
|
|
31787
|
+
className: "max-w-md rounded-lg border border-border bg-background p-6 shadow-sm",
|
|
31788
|
+
children: [
|
|
31789
|
+
/* @__PURE__ */ jsx122(Globe23, {
|
|
31790
|
+
className: "mx-auto mb-3 h-8 w-8 text-muted-foreground"
|
|
31791
|
+
}),
|
|
31792
|
+
/* @__PURE__ */ jsx122("h2", {
|
|
31793
|
+
className: "mb-2 text-sm font-semibold text-foreground",
|
|
31794
|
+
children: "This site can't be embedded"
|
|
31795
|
+
}),
|
|
31796
|
+
/* @__PURE__ */ jsx122("p", {
|
|
31797
|
+
className: "mb-4 text-xs leading-relaxed text-muted-foreground",
|
|
31798
|
+
children: embedError
|
|
31799
|
+
}),
|
|
31800
|
+
/* @__PURE__ */ jsxs106("div", {
|
|
31801
|
+
className: "flex flex-wrap justify-center gap-2",
|
|
31802
|
+
children: [
|
|
31803
|
+
/* @__PURE__ */ jsx122(Button, {
|
|
31804
|
+
type: "button",
|
|
31805
|
+
variant: "secondary",
|
|
31806
|
+
size: "sm",
|
|
31807
|
+
onClick: () => {
|
|
31808
|
+
setEmbedError(null);
|
|
31809
|
+
setIsLoading(true);
|
|
31810
|
+
setLoadingProgress(12);
|
|
31811
|
+
reloadBrowserTab(tab.id);
|
|
31812
|
+
},
|
|
31813
|
+
children: "Try again"
|
|
31814
|
+
}),
|
|
31815
|
+
nativeBrowser?.openWindow && /* @__PURE__ */ jsx122(Button, {
|
|
31816
|
+
type: "button",
|
|
31817
|
+
variant: "secondary",
|
|
31818
|
+
size: "sm",
|
|
31819
|
+
onClick: () => nativeBrowser.openWindow?.(normalizedUrl),
|
|
31820
|
+
children: "Open in desktop window"
|
|
31821
|
+
}),
|
|
31822
|
+
/* @__PURE__ */ jsx122(Button, {
|
|
31823
|
+
type: "button",
|
|
31824
|
+
variant: "secondary",
|
|
31825
|
+
size: "sm",
|
|
31826
|
+
onClick: () => window.open(normalizedUrl, "_blank", "noopener,noreferrer"),
|
|
31827
|
+
children: "Open externally"
|
|
31828
|
+
})
|
|
31829
|
+
]
|
|
31830
|
+
})
|
|
31831
|
+
]
|
|
31832
|
+
})
|
|
31833
|
+
}) : /* @__PURE__ */ jsx122("div", {
|
|
31577
31834
|
className: "h-full w-full flex items-center justify-center p-6 text-center",
|
|
31578
31835
|
children: /* @__PURE__ */ jsxs106("div", {
|
|
31579
31836
|
className: "max-w-md rounded-lg border border-border bg-background p-6 shadow-sm",
|
|
@@ -31608,7 +31865,7 @@ function BrowserViewerPanel({ tab }) {
|
|
|
31608
31865
|
}
|
|
31609
31866
|
// src/components/workspace/ViewerTabs.tsx
|
|
31610
31867
|
import { memo as memo50, useEffect as useEffect57 } from "react";
|
|
31611
|
-
import { Code2, GitCommit as GitCommit5, Globe2 as Globe24, Smartphone as Smartphone2, X as
|
|
31868
|
+
import { Code2, GitCommit as GitCommit5, Globe2 as Globe24, Smartphone as Smartphone2, X as X24 } from "lucide-react";
|
|
31612
31869
|
import { jsx as jsx123, jsxs as jsxs107 } from "react/jsx-runtime";
|
|
31613
31870
|
function tabKindLabel(tab) {
|
|
31614
31871
|
switch (tab.type) {
|
|
@@ -31778,6 +32035,8 @@ function renderTabContent(tab, closeTab, updateSessionFileOperationIndex) {
|
|
|
31778
32035
|
});
|
|
31779
32036
|
}
|
|
31780
32037
|
}
|
|
32038
|
+
var VIEWER_MODE_TAB_BUTTON_BASE = "absolute top-0.5 z-20 h-7 w-9 rounded-full p-0 leading-none transform-none select-none bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-ring active:transform-none";
|
|
32039
|
+
var VIEWER_MODE_ICON_BASE_CLASS = "pointer-events-none absolute top-1/2 z-10 block h-4 w-4 -translate-x-1/2 -translate-y-1/2 shrink-0 transition-colors";
|
|
31781
32040
|
var ViewerTabs = memo50(function ViewerTabs2() {
|
|
31782
32041
|
const tabs = useViewerTabsStore((state) => state.tabs);
|
|
31783
32042
|
const activeTabId = useViewerTabsStore((state) => state.activeTabId);
|
|
@@ -31830,28 +32089,31 @@ var ViewerTabs = memo50(function ViewerTabs2() {
|
|
|
31830
32089
|
children: /* @__PURE__ */ jsxs107("div", {
|
|
31831
32090
|
role: "tablist",
|
|
31832
32091
|
"aria-label": "Viewer mode",
|
|
31833
|
-
className: "relative h-8
|
|
32092
|
+
className: "relative h-8 w-[4.75rem] shrink-0 rounded-full ring-1 ring-inset ring-sidebar-border bg-muted/40 p-0.5",
|
|
31834
32093
|
children: [
|
|
31835
32094
|
/* @__PURE__ */ jsx123("span", {
|
|
31836
32095
|
"aria-hidden": "true",
|
|
31837
32096
|
className: `absolute left-0.5 inset-y-0.5 w-9 rounded-full bg-background shadow-sm ring-1 ring-sidebar-border transition-transform duration-200 ease-out pointer-events-none ${activeMode === "preview" ? "translate-x-9" : "translate-x-0"}`
|
|
31838
32097
|
}),
|
|
31839
|
-
/* @__PURE__ */
|
|
32098
|
+
/* @__PURE__ */ jsx123(Code2, {
|
|
32099
|
+
"aria-hidden": "true",
|
|
32100
|
+
className: `${VIEWER_MODE_ICON_BASE_CLASS} left-5 ${activeMode === "work" ? "text-foreground" : "text-muted-foreground/70"}`
|
|
32101
|
+
}),
|
|
32102
|
+
/* @__PURE__ */ jsx123(Globe24, {
|
|
32103
|
+
"aria-hidden": "true",
|
|
32104
|
+
className: `${VIEWER_MODE_ICON_BASE_CLASS} left-14 ${activeMode === "preview" ? "text-foreground" : "text-muted-foreground/70"}`
|
|
32105
|
+
}),
|
|
32106
|
+
showWorkActivityDot && /* @__PURE__ */ jsx123("span", {
|
|
32107
|
+
className: "pointer-events-none absolute left-[2rem] top-1 z-10 h-1.5 w-1.5 rounded-full bg-primary"
|
|
32108
|
+
}),
|
|
32109
|
+
/* @__PURE__ */ jsx123("button", {
|
|
31840
32110
|
type: "button",
|
|
31841
32111
|
role: "tab",
|
|
31842
32112
|
"aria-selected": activeMode === "work",
|
|
31843
32113
|
onClick: () => setViewerMode("work"),
|
|
31844
32114
|
title: "Work tabs",
|
|
31845
32115
|
"aria-label": "Work tabs",
|
|
31846
|
-
className:
|
|
31847
|
-
children: [
|
|
31848
|
-
/* @__PURE__ */ jsx123(Code2, {
|
|
31849
|
-
className: "h-4 w-4"
|
|
31850
|
-
}),
|
|
31851
|
-
showWorkActivityDot && /* @__PURE__ */ jsx123("span", {
|
|
31852
|
-
className: "absolute right-1 top-1 h-1.5 w-1.5 rounded-full bg-primary"
|
|
31853
|
-
})
|
|
31854
|
-
]
|
|
32116
|
+
className: `${VIEWER_MODE_TAB_BUTTON_BASE} left-0.5`
|
|
31855
32117
|
}),
|
|
31856
32118
|
/* @__PURE__ */ jsx123("button", {
|
|
31857
32119
|
type: "button",
|
|
@@ -31860,10 +32122,7 @@ var ViewerTabs = memo50(function ViewerTabs2() {
|
|
|
31860
32122
|
onClick: handlePreviewMode,
|
|
31861
32123
|
title: "Preview tabs",
|
|
31862
32124
|
"aria-label": "Preview tabs",
|
|
31863
|
-
className:
|
|
31864
|
-
children: /* @__PURE__ */ jsx123(Globe24, {
|
|
31865
|
-
className: "h-4 w-4"
|
|
31866
|
-
})
|
|
32125
|
+
className: `${VIEWER_MODE_TAB_BUTTON_BASE} left-[2.375rem]`
|
|
31867
32126
|
})
|
|
31868
32127
|
]
|
|
31869
32128
|
})
|
|
@@ -31875,7 +32134,7 @@ var ViewerTabs = memo50(function ViewerTabs2() {
|
|
|
31875
32134
|
const isActive = tab.id === activeTab.id;
|
|
31876
32135
|
const activityKind = getTabActivityKind(tab);
|
|
31877
32136
|
return /* @__PURE__ */ jsxs107("div", {
|
|
31878
|
-
className: `group h-12 w-44 max-w-56 shrink-0 px-3 border-r border-sidebar-border flex items-center gap-2 text-left transition-colors ${isActive ? "bg-sidebar text-sidebar-foreground" : "
|
|
32137
|
+
className: `group h-12 w-44 max-w-56 shrink-0 px-3 border-r border-b border-sidebar-border flex items-center gap-2 text-left transition-colors ${isActive ? "border-b-transparent bg-sidebar text-sidebar-foreground" : "bg-background text-muted-foreground/70 hover:text-foreground hover:bg-sidebar-accent/40"}`,
|
|
31879
32138
|
title: `${tab.title}
|
|
31880
32139
|
${tabKindLabel(tab)}`,
|
|
31881
32140
|
children: [
|
|
@@ -31900,7 +32159,7 @@ ${tabKindLabel(tab)}`,
|
|
|
31900
32159
|
},
|
|
31901
32160
|
title: "Close tab",
|
|
31902
32161
|
className: "h-6 w-6 opacity-60 group-hover:opacity-100 shrink-0",
|
|
31903
|
-
children: /* @__PURE__ */ jsx123(
|
|
32162
|
+
children: /* @__PURE__ */ jsx123(X24, {
|
|
31904
32163
|
className: "h-3.5 w-3.5"
|
|
31905
32164
|
})
|
|
31906
32165
|
})
|
|
@@ -31918,7 +32177,7 @@ ${tabKindLabel(tab)}`,
|
|
|
31918
32177
|
title: "Close all tabs and collapse viewer",
|
|
31919
32178
|
"aria-label": "Close all tabs and collapse viewer",
|
|
31920
32179
|
className: "h-8 w-8 inline-flex items-center justify-center rounded-md text-muted-foreground/70 transition-colors hover:bg-destructive/10 hover:text-destructive",
|
|
31921
|
-
children: /* @__PURE__ */ jsx123(
|
|
32180
|
+
children: /* @__PURE__ */ jsx123(X24, {
|
|
31922
32181
|
className: "h-3.5 w-3.5"
|
|
31923
32182
|
})
|
|
31924
32183
|
})
|
|
@@ -31927,12 +32186,28 @@ ${tabKindLabel(tab)}`,
|
|
|
31927
32186
|
})
|
|
31928
32187
|
]
|
|
31929
32188
|
}),
|
|
31930
|
-
/* @__PURE__ */
|
|
31931
|
-
className: "flex-1 min-h-0 overflow-hidden",
|
|
31932
|
-
children:
|
|
31933
|
-
|
|
31934
|
-
|
|
31935
|
-
|
|
32189
|
+
/* @__PURE__ */ jsxs107("div", {
|
|
32190
|
+
className: "relative flex-1 min-h-0 overflow-hidden",
|
|
32191
|
+
children: [
|
|
32192
|
+
previewTabs.map((tab) => {
|
|
32193
|
+
const isActive = activeMode === "preview" && tab.id === activeTab?.id;
|
|
32194
|
+
return /* @__PURE__ */ jsx123("div", {
|
|
32195
|
+
"aria-hidden": !isActive,
|
|
32196
|
+
className: `absolute inset-0 ${isActive ? "block" : "hidden"}`,
|
|
32197
|
+
children: /* @__PURE__ */ jsx123(BrowserViewerPanel, {
|
|
32198
|
+
tab
|
|
32199
|
+
})
|
|
32200
|
+
}, tab.id);
|
|
32201
|
+
}),
|
|
32202
|
+
activeMode === "work" && activeTab && /* @__PURE__ */ jsx123("div", {
|
|
32203
|
+
className: "absolute inset-0",
|
|
32204
|
+
children: renderTabContent(activeTab, closeTab, updateSessionFileOperationIndex)
|
|
32205
|
+
}),
|
|
32206
|
+
!activeTab && /* @__PURE__ */ jsx123("div", {
|
|
32207
|
+
className: "absolute inset-0 flex items-center justify-center bg-sidebar text-muted-foreground/60 text-sm",
|
|
32208
|
+
children: activeMode === "work" ? "No work tabs open" : "No preview tabs open"
|
|
32209
|
+
})
|
|
32210
|
+
]
|
|
31936
32211
|
})
|
|
31937
32212
|
]
|
|
31938
32213
|
});
|
|
@@ -31941,12 +32216,12 @@ ${tabKindLabel(tab)}`,
|
|
|
31941
32216
|
import { memo as memo53, useEffect as useEffect60 } from "react";
|
|
31942
32217
|
|
|
31943
32218
|
// src/components/onboarding/steps/ProviderSetupStep.tsx
|
|
31944
|
-
import { memo as memo51, useEffect as useEffect58, useState as useState53, useRef as
|
|
32219
|
+
import { memo as memo51, useEffect as useEffect58, useState as useState53, useRef as useRef39 } from "react";
|
|
31945
32220
|
import {
|
|
31946
32221
|
Copy as Copy5,
|
|
31947
32222
|
Check as Check16,
|
|
31948
32223
|
CreditCard as CreditCard4,
|
|
31949
|
-
X as
|
|
32224
|
+
X as X25,
|
|
31950
32225
|
Key as Key2,
|
|
31951
32226
|
ExternalLink as ExternalLink12,
|
|
31952
32227
|
ArrowRight as ArrowRight3,
|
|
@@ -32031,20 +32306,20 @@ var ProviderSetupStep = memo51(function ProviderSetupStep2({
|
|
|
32031
32306
|
const [copilotCodeCopied, setCopilotCodeCopied] = useState53(false);
|
|
32032
32307
|
const [copilotModalOpen, setCopilotModalOpen] = useState53(false);
|
|
32033
32308
|
const [copilotLoading, setCopilotLoading] = useState53(false);
|
|
32034
|
-
const copilotPollRef =
|
|
32035
|
-
const copilotCancelledRef =
|
|
32036
|
-
const copilotPollFnRef =
|
|
32309
|
+
const copilotPollRef = useRef39(undefined);
|
|
32310
|
+
const copilotCancelledRef = useRef39(false);
|
|
32311
|
+
const copilotPollFnRef = useRef39(onPollCopilotDeviceFlow);
|
|
32037
32312
|
copilotPollFnRef.current = onPollCopilotDeviceFlow;
|
|
32038
32313
|
const balance = useOttoRouterStore((s) => s.balance);
|
|
32039
32314
|
const usdcBalance = useOttoRouterStore((s) => s.usdcBalance);
|
|
32040
32315
|
const payg = useOttoRouterStore((s) => s.payg);
|
|
32041
32316
|
const subscription = useOttoRouterStore((s) => s.subscription);
|
|
32042
32317
|
const isBalanceLoading = useOttoRouterStore((s) => s.isLoading);
|
|
32043
|
-
const apiKeyInputRef =
|
|
32044
|
-
const oauthCodeInputRef =
|
|
32045
|
-
const importPrivateKeyRef =
|
|
32318
|
+
const apiKeyInputRef = useRef39(null);
|
|
32319
|
+
const oauthCodeInputRef = useRef39(null);
|
|
32320
|
+
const importPrivateKeyRef = useRef39(null);
|
|
32046
32321
|
const isTopupModalOpen = useOttoRouterStore((s) => s.isTopupModalOpen);
|
|
32047
|
-
const prevTopupModalOpen =
|
|
32322
|
+
const prevTopupModalOpen = useRef39(false);
|
|
32048
32323
|
const { fetchBalance } = useOttoRouterBalance("ottorouter");
|
|
32049
32324
|
const effectivePayg = payg?.effectiveSpendableUsd ?? balance ?? 0;
|
|
32050
32325
|
const setuStatusLabel = subscription?.active ? `GO ${(subscription.creditsRemaining ?? 0).toFixed(1)} credits` : `$${effectivePayg.toFixed(2)}`;
|
|
@@ -32743,7 +33018,7 @@ var ProviderSetupStep = memo51(function ProviderSetupStep2({
|
|
|
32743
33018
|
type: "button",
|
|
32744
33019
|
onClick: () => handleRemoveProvider(id),
|
|
32745
33020
|
className: "ml-1 p-1 text-green-600/40 dark:text-green-500/40 hover:text-green-600/80 dark:hover:text-green-500/80 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
32746
|
-
children: /* @__PURE__ */ jsx124(
|
|
33021
|
+
children: /* @__PURE__ */ jsx124(X25, {
|
|
32747
33022
|
className: "w-3 h-3"
|
|
32748
33023
|
})
|
|
32749
33024
|
})
|
|
@@ -32802,7 +33077,7 @@ var ProviderSetupStep = memo51(function ProviderSetupStep2({
|
|
|
32802
33077
|
setApiKeyInput("");
|
|
32803
33078
|
},
|
|
32804
33079
|
className: "shrink-0 p-1.5 text-muted-foreground hover:text-foreground",
|
|
32805
|
-
children: /* @__PURE__ */ jsx124(
|
|
33080
|
+
children: /* @__PURE__ */ jsx124(X25, {
|
|
32806
33081
|
className: "w-4 h-4"
|
|
32807
33082
|
})
|
|
32808
33083
|
})
|
|
@@ -33563,7 +33838,7 @@ var ProviderSetupStep = memo51(function ProviderSetupStep2({
|
|
|
33563
33838
|
});
|
|
33564
33839
|
|
|
33565
33840
|
// src/components/onboarding/steps/DefaultsStep.tsx
|
|
33566
|
-
import { memo as memo52, useState as useState54, useEffect as useEffect59, useId as useId5, useRef as
|
|
33841
|
+
import { memo as memo52, useState as useState54, useEffect as useEffect59, useId as useId5, useRef as useRef40 } from "react";
|
|
33567
33842
|
import { ArrowLeft, Sparkles as Sparkles9, ChevronDown as ChevronDown15 } from "lucide-react";
|
|
33568
33843
|
import { jsx as jsx125, jsxs as jsxs109, Fragment as Fragment48 } from "react/jsx-runtime";
|
|
33569
33844
|
var DefaultsStep = memo52(function DefaultsStep2({
|
|
@@ -33581,7 +33856,7 @@ var DefaultsStep = memo52(function DefaultsStep2({
|
|
|
33581
33856
|
const [selectedAgent, setSelectedAgent] = useState54(authStatus.defaults.agent || "build");
|
|
33582
33857
|
const [selectedApproval, setSelectedApproval] = useState54(authStatus.defaults.toolApproval || "dangerous");
|
|
33583
33858
|
const [guidedMode, setGuidedMode] = useState54(false);
|
|
33584
|
-
const hasUserChangedProvider =
|
|
33859
|
+
const hasUserChangedProvider = useRef40(false);
|
|
33585
33860
|
const providerId = useId5();
|
|
33586
33861
|
const modelId = useId5();
|
|
33587
33862
|
const agentId = useId5();
|
|
@@ -34040,7 +34315,7 @@ var OnboardingModal = memo53(function OnboardingModal2({
|
|
|
34040
34315
|
});
|
|
34041
34316
|
});
|
|
34042
34317
|
// src/components/dashboard/UsageDashboard.tsx
|
|
34043
|
-
import { useCallback as
|
|
34318
|
+
import { useCallback as useCallback38, useEffect as useEffect61, useMemo as useMemo33, useState as useState55 } from "react";
|
|
34044
34319
|
import { AlertTriangle as AlertTriangle3, ArrowLeft as ArrowLeft2, Globe2 as Globe25, RefreshCw as RefreshCw14 } from "lucide-react";
|
|
34045
34320
|
import { jsx as jsx127, jsxs as jsxs111, Fragment as Fragment49 } from "react/jsx-runtime";
|
|
34046
34321
|
function formatNumber(n) {
|
|
@@ -34618,7 +34893,7 @@ function UsageDashboard({ onBack }) {
|
|
|
34618
34893
|
const [loading, setLoading] = useState55(false);
|
|
34619
34894
|
const [error, setError] = useState55(null);
|
|
34620
34895
|
const [scope, setScope] = useState55("project");
|
|
34621
|
-
const fetchStats =
|
|
34896
|
+
const fetchStats = useCallback38(async () => {
|
|
34622
34897
|
setLoading(true);
|
|
34623
34898
|
setError(null);
|
|
34624
34899
|
try {
|
|
@@ -34633,7 +34908,7 @@ function UsageDashboard({ onBack }) {
|
|
|
34633
34908
|
useEffect61(() => {
|
|
34634
34909
|
fetchStats();
|
|
34635
34910
|
}, [fetchStats]);
|
|
34636
|
-
const handleBack =
|
|
34911
|
+
const handleBack = useCallback38(() => {
|
|
34637
34912
|
if (onBack)
|
|
34638
34913
|
return onBack();
|
|
34639
34914
|
if (typeof window === "undefined")
|
|
@@ -35081,4 +35356,4 @@ export {
|
|
|
35081
35356
|
AssistantMessageGroup
|
|
35082
35357
|
};
|
|
35083
35358
|
|
|
35084
|
-
//# debugId=
|
|
35359
|
+
//# debugId=857870757EF1E6EC64756E2164756E21
|