@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/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")
|
|
@@ -34998,7 +35273,7 @@ function UsageDashboard({ onBack }) {
|
|
|
34998
35273
|
});
|
|
34999
35274
|
}
|
|
35000
35275
|
// src/hooks/useClientEvents.ts
|
|
35001
|
-
import { useEffect as useEffect62, useRef as
|
|
35276
|
+
import { useEffect as useEffect62, useRef as useRef41 } from "react";
|
|
35002
35277
|
import { useQueryClient as useQueryClient23 } from "@tanstack/react-query";
|
|
35003
35278
|
import {
|
|
35004
35279
|
buildClientEventsStreamUrl,
|
|
@@ -35185,7 +35460,7 @@ async function maybeShowLocalAccessToast(baseUrl) {
|
|
|
35185
35460
|
}
|
|
35186
35461
|
function useClientEvents(activeSessionId) {
|
|
35187
35462
|
const queryClient = useQueryClient23();
|
|
35188
|
-
const activeSessionIdRef =
|
|
35463
|
+
const activeSessionIdRef = useRef41(activeSessionId);
|
|
35189
35464
|
useEffect62(() => {
|
|
35190
35465
|
activeSessionIdRef.current = activeSessionId;
|
|
35191
35466
|
}, [activeSessionId]);
|
|
@@ -35268,7 +35543,7 @@ function useClientEvents(activeSessionId) {
|
|
|
35268
35543
|
return buildClientEventsStreamUrl({ baseUrl: getBaseUrl() });
|
|
35269
35544
|
}
|
|
35270
35545
|
// src/hooks/useTheme.ts
|
|
35271
|
-
import { useEffect as useEffect63, useState as useState56, useCallback as
|
|
35546
|
+
import { useEffect as useEffect63, useState as useState56, useCallback as useCallback39, useMemo as useMemo34 } from "react";
|
|
35272
35547
|
var STORAGE_KEY3 = "otto-theme";
|
|
35273
35548
|
function resolveInitialTheme() {
|
|
35274
35549
|
if (typeof window === "undefined") {
|
|
@@ -35314,7 +35589,7 @@ function useTheme() {
|
|
|
35314
35589
|
window.addEventListener("message", handler);
|
|
35315
35590
|
return () => window.removeEventListener("message", handler);
|
|
35316
35591
|
}, []);
|
|
35317
|
-
const toggleTheme =
|
|
35592
|
+
const toggleTheme = useCallback39(() => {
|
|
35318
35593
|
setTheme((prev) => prev === "dark" ? "light" : "dark");
|
|
35319
35594
|
}, []);
|
|
35320
35595
|
return useMemo34(() => ({ theme, setTheme, toggleTheme }), [theme, toggleTheme]);
|
|
@@ -35348,7 +35623,7 @@ function useWorkingDirectory() {
|
|
|
35348
35623
|
return dirName;
|
|
35349
35624
|
}
|
|
35350
35625
|
// src/hooks/useKeyboardShortcuts.ts
|
|
35351
|
-
import { useEffect as useEffect65, useCallback as
|
|
35626
|
+
import { useEffect as useEffect65, useCallback as useCallback40 } from "react";
|
|
35352
35627
|
|
|
35353
35628
|
// src/stores/sidebarStore.ts
|
|
35354
35629
|
import { create as create24 } from "zustand";
|
|
@@ -35402,7 +35677,7 @@ function useKeyboardShortcuts({
|
|
|
35402
35677
|
const toggleResearch = useResearchStore((state) => state.toggleSidebar);
|
|
35403
35678
|
const toggleTerminalPanel = useTerminalStore((state) => state.togglePanel);
|
|
35404
35679
|
const currentSessionIndex = sessionIds.indexOf(activeSessionId || "");
|
|
35405
|
-
const handleKeyDown =
|
|
35680
|
+
const handleKeyDown = useCallback40((e) => {
|
|
35406
35681
|
const target = e.target;
|
|
35407
35682
|
const isInInput = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
|
|
35408
35683
|
const isInTerminal = !!target.closest("[data-terminal-viewer]");
|
|
@@ -35667,7 +35942,7 @@ function useKeyboardShortcuts({
|
|
|
35667
35942
|
// src/hooks/useImageUpload.ts
|
|
35668
35943
|
import {
|
|
35669
35944
|
useState as useState58,
|
|
35670
|
-
useCallback as
|
|
35945
|
+
useCallback as useCallback41,
|
|
35671
35946
|
useEffect as useEffect66
|
|
35672
35947
|
} from "react";
|
|
35673
35948
|
var SUPPORTED_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
|
|
@@ -35700,7 +35975,7 @@ function useImageUpload(options = {}) {
|
|
|
35700
35975
|
const [isDragging, setIsDragging] = useState58(false);
|
|
35701
35976
|
const [error, setError] = useState58(null);
|
|
35702
35977
|
const maxSizeBytes = maxSizeMB * 1024 * 1024;
|
|
35703
|
-
const validateFile =
|
|
35978
|
+
const validateFile = useCallback41((file) => {
|
|
35704
35979
|
if (!SUPPORTED_TYPES.includes(file.type)) {
|
|
35705
35980
|
return `Unsupported file type: ${file.type}. Supported: PNG, JPEG, GIF, WebP`;
|
|
35706
35981
|
}
|
|
@@ -35709,7 +35984,7 @@ function useImageUpload(options = {}) {
|
|
|
35709
35984
|
}
|
|
35710
35985
|
return null;
|
|
35711
35986
|
}, [maxSizeBytes, maxSizeMB]);
|
|
35712
|
-
const addImages =
|
|
35987
|
+
const addImages = useCallback41(async (files) => {
|
|
35713
35988
|
setError(null);
|
|
35714
35989
|
const fileArray = Array.from(files);
|
|
35715
35990
|
const remaining = maxImages - images.length;
|
|
@@ -35745,22 +36020,22 @@ function useImageUpload(options = {}) {
|
|
|
35745
36020
|
setImages((prev) => [...prev, ...newImages]);
|
|
35746
36021
|
}
|
|
35747
36022
|
}, [images.length, maxImages, validateFile]);
|
|
35748
|
-
const removeImage =
|
|
36023
|
+
const removeImage = useCallback41((id) => {
|
|
35749
36024
|
setImages((prev) => prev.filter((img) => img.id !== id));
|
|
35750
36025
|
setError(null);
|
|
35751
36026
|
}, []);
|
|
35752
|
-
const clearImages =
|
|
36027
|
+
const clearImages = useCallback41(() => {
|
|
35753
36028
|
setImages([]);
|
|
35754
36029
|
setError(null);
|
|
35755
36030
|
}, []);
|
|
35756
|
-
const handleDragEnter =
|
|
36031
|
+
const handleDragEnter = useCallback41((e) => {
|
|
35757
36032
|
e.preventDefault();
|
|
35758
36033
|
e.stopPropagation();
|
|
35759
36034
|
if (e.dataTransfer.types.includes("Files")) {
|
|
35760
36035
|
setIsDragging(true);
|
|
35761
36036
|
}
|
|
35762
36037
|
}, []);
|
|
35763
|
-
const handleDragLeave =
|
|
36038
|
+
const handleDragLeave = useCallback41((e) => {
|
|
35764
36039
|
e.preventDefault();
|
|
35765
36040
|
e.stopPropagation();
|
|
35766
36041
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -35770,11 +36045,11 @@ function useImageUpload(options = {}) {
|
|
|
35770
36045
|
setIsDragging(false);
|
|
35771
36046
|
}
|
|
35772
36047
|
}, []);
|
|
35773
|
-
const handleDragOver =
|
|
36048
|
+
const handleDragOver = useCallback41((e) => {
|
|
35774
36049
|
e.preventDefault();
|
|
35775
36050
|
e.stopPropagation();
|
|
35776
36051
|
}, []);
|
|
35777
|
-
const handleDrop =
|
|
36052
|
+
const handleDrop = useCallback41((e) => {
|
|
35778
36053
|
e.preventDefault();
|
|
35779
36054
|
e.stopPropagation();
|
|
35780
36055
|
setIsDragging(false);
|
|
@@ -35786,7 +36061,7 @@ function useImageUpload(options = {}) {
|
|
|
35786
36061
|
}
|
|
35787
36062
|
}
|
|
35788
36063
|
}, [addImages]);
|
|
35789
|
-
const handlePaste =
|
|
36064
|
+
const handlePaste = useCallback41((e) => {
|
|
35790
36065
|
const items = e.clipboardData?.items;
|
|
35791
36066
|
if (!items)
|
|
35792
36067
|
return;
|
|
@@ -35865,10 +36140,10 @@ function useImageUpload(options = {}) {
|
|
|
35865
36140
|
};
|
|
35866
36141
|
}
|
|
35867
36142
|
// src/hooks/useSetuPayments.ts
|
|
35868
|
-
import { useEffect as useEffect67, useRef as
|
|
36143
|
+
import { useEffect as useEffect67, useRef as useRef42 } from "react";
|
|
35869
36144
|
function useSetuPayments(sessionId) {
|
|
35870
|
-
const clientRef =
|
|
35871
|
-
const loadingToastIdRef =
|
|
36145
|
+
const clientRef = useRef42(null);
|
|
36146
|
+
const loadingToastIdRef = useRef42(null);
|
|
35872
36147
|
const setBalance = useOttoRouterStore((s) => s.setBalance);
|
|
35873
36148
|
const setPaymentPending = useOttoRouterStore((s) => s.setPaymentPending);
|
|
35874
36149
|
const removeToast = useToastStore((s) => s.removeToast);
|
|
@@ -36223,4 +36498,4 @@ export {
|
|
|
36223
36498
|
API_BASE_URL
|
|
36224
36499
|
};
|
|
36225
36500
|
|
|
36226
|
-
//# debugId=
|
|
36501
|
+
//# debugId=66B25A0616A3472664756E2164756E21
|