Integrate project classroom with teacher and friend consultations
This commit is contained in:
@@ -40,6 +40,7 @@ export interface AgentBrowserPanelProps {
|
||||
projectId: string | null;
|
||||
open: boolean;
|
||||
onOpenChange(open: boolean): void;
|
||||
embedded?: boolean;
|
||||
}
|
||||
|
||||
const EVENT_METHODS = [
|
||||
@@ -86,10 +87,11 @@ function browserIsActive(snapshot: AgentBrowserSnapshot | null): boolean {
|
||||
|
||||
function modalOccludesBrowser(): boolean {
|
||||
return Array.from(
|
||||
document.querySelectorAll<HTMLElement>('[role="dialog"], [role="alertdialog"]'),
|
||||
document.querySelectorAll<HTMLElement>('[role="dialog"], [role="alertdialog"], #coding-consultation-dock'),
|
||||
).some((element) => {
|
||||
if (element.hidden || element.getAttribute('data-state') === 'closed') return false;
|
||||
const style = window.getComputedStyle(element);
|
||||
if (element.id === 'coding-consultation-dock' && style.position !== 'absolute' && style.position !== 'fixed') return false;
|
||||
return style.display !== 'none' && style.visibility !== 'hidden';
|
||||
});
|
||||
}
|
||||
@@ -118,6 +120,7 @@ export function AgentBrowserPanel({
|
||||
projectId,
|
||||
open,
|
||||
onOpenChange,
|
||||
embedded = false,
|
||||
}: AgentBrowserPanelProps) {
|
||||
const [snapshot, setSnapshot] = useState<AgentBrowserSnapshot | null>(null);
|
||||
const [address, setAddress] = useState('');
|
||||
@@ -214,12 +217,14 @@ export function AgentBrowserPanel({
|
||||
const wasOpen = wasOpenRef.current;
|
||||
wasOpenRef.current = open;
|
||||
if (!wasOpen || open || !projectId) return;
|
||||
// Switching the central workspace tab must preserve the running work page.
|
||||
if (embedded) return;
|
||||
setSnapshot(null);
|
||||
setDiagnosticsOpen(false);
|
||||
setEvents([]);
|
||||
eventCursorRef.current = 0;
|
||||
void closeAgentBrowser(projectId).catch(() => undefined);
|
||||
}, [open, projectId]);
|
||||
}, [embedded, open, projectId]);
|
||||
|
||||
useEffect(() => () => {
|
||||
if (projectId) void closeAgentBrowser(projectId).catch(() => undefined);
|
||||
@@ -237,6 +242,7 @@ export function AgentBrowserPanel({
|
||||
}
|
||||
const update = () => setOccluded(modalOccludesBrowser());
|
||||
update();
|
||||
window.addEventListener('resize', update);
|
||||
const observer = new MutationObserver(update);
|
||||
observer.observe(document.body, {
|
||||
attributes: true,
|
||||
@@ -244,7 +250,10 @@ export function AgentBrowserPanel({
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
return () => observer.disconnect();
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
window.removeEventListener('resize', update);
|
||||
};
|
||||
}, [open]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -390,14 +399,14 @@ export function AgentBrowserPanel({
|
||||
|
||||
return (
|
||||
<aside
|
||||
className="relative flex w-[400px] min-w-[300px] max-w-[48vw] shrink-0 flex-col overflow-hidden border-l border-border/80 bg-background shadow-[-16px_0_32px_hsl(220_20%_16%_/_0.06)] max-[900px]:fixed max-[900px]:inset-y-10 max-[900px]:right-0 max-[900px]:z-40 max-[900px]:max-w-[min(92vw,420px)]"
|
||||
className={cn(embedded ? 'relative flex min-h-0 w-full min-w-0 flex-1 flex-col overflow-hidden bg-background' : 'relative flex w-[400px] min-w-[300px] max-w-[48vw] shrink-0 flex-col overflow-hidden border-l border-border/80 bg-background shadow-[-16px_0_32px_hsl(220_20%_16%_/_0.06)] max-[900px]:fixed max-[900px]:inset-y-10 max-[900px]:right-0 max-[900px]:z-40 max-[900px]:max-w-[min(92vw,420px)]')}
|
||||
data-testid="agent-browser-panel"
|
||||
>
|
||||
<div className="flex h-10 shrink-0 items-center gap-2 border-b border-border/70 px-2.5">
|
||||
<span className="flex h-6 w-6 items-center justify-center rounded-md bg-brand-soft text-brand">
|
||||
<Globe2 className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</span>
|
||||
<h2 className="min-w-0 flex-1 truncate text-xs font-semibold">开发浏览器</h2>
|
||||
<h2 className="min-w-0 flex-1 truncate text-xs font-semibold">{embedded ? '作品预览' : '开发浏览器'}</h2>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
@@ -426,7 +435,7 @@ export function AgentBrowserPanel({
|
||||
onChange={(event) => setAddress(event.target.value)}
|
||||
aria-label="网页地址"
|
||||
className="h-7 min-w-0 flex-1 rounded-lg border border-border/90 bg-surface-input px-2.5 text-[11px] font-medium outline-none focus:border-brand/40 focus:ring-2 focus:ring-brand/15"
|
||||
placeholder="输入 URL"
|
||||
placeholder={embedded ? '作品运行后,在这里打开它的地址' : '输入 URL'}
|
||||
spellCheck={false}
|
||||
/>
|
||||
</form>
|
||||
@@ -448,8 +457,8 @@ export function AgentBrowserPanel({
|
||||
<span className="flex h-12 w-12 items-center justify-center rounded-xl border border-border/70 bg-background shadow-soft">
|
||||
<Globe2 className="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
<p className="text-[13px] font-semibold text-foreground">开始浏览</p>
|
||||
<p className="text-[11px]">输入 URL,或等待智能体打开调试页面</p>
|
||||
<p className="text-[13px] font-semibold text-foreground">{embedded ? '作品会在这里展开' : '开始浏览'}</p>
|
||||
<p className="text-xs leading-6">{embedded ? '先在操作对话里制作作品,再打开它的预览地址。' : '输入 URL,或等待智能体打开调试页面'}</p>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user