'use client'; import { memo, useState, useEffect, useMemo } from 'react'; import type { IDockviewPanelProps } from 'dockview-react'; import { IconRefresh, IconExternalLink } from '@tabler/icons-react'; import { Button } from '@kandev/ui/button'; import { Input } from '@kandev/ui/input'; import { PanelRoot, PanelBody, PanelToolbar } from './panel-primitives'; import { useAppStore } from '@/components/state-provider'; import { detectPreviewUrlFromOutput } from '@/lib/preview-url-detector'; export const BrowserPanel = memo(function BrowserPanel( props: IDockviewPanelProps<{ url?: string }> ) { const initialUrl = props.params.url || ''; const [userUrl, setUserUrl] = useState(initialUrl); const [urlDraft, setUrlDraft] = useState(initialUrl); const [refreshKey, setRefreshKey] = useState(0); const [showIframe, setShowIframe] = useState(false); const activeSessionId = useAppStore((state) => state.tasks.activeSessionId); const devProcessId = useAppStore((state) => activeSessionId ? state.processes.devProcessBySessionId[activeSessionId] : undefined ); const devOutput = useAppStore((state) => devProcessId ? state.processes.outputsByProcessId[devProcessId] ?? '' : '' ); // Auto-detect URL from dev server output const detectedUrl = detectPreviewUrlFromOutput(devOutput); // Use user-set URL if available, otherwise fall back to detected URL const effectiveUrl = useMemo(() => userUrl || detectedUrl || '', [userUrl, detectedUrl]); // Derive iframe visibility: show after a delay when URL is available const showIframeDelayed = effectiveUrl && showIframe; // Delay showing iframe after URL is set useEffect(() => { if (!effectiveUrl) return; const showTimer = setTimeout(() => setShowIframe(true), 1500); return () => { setShowIframe(false); clearTimeout(showTimer); }; }, [effectiveUrl, refreshKey]); // Sync draft with detected URL when user hasn't typed anything const displayDraft = urlDraft || detectedUrl || ''; const handleUrlSubmit = () => { const trimmed = urlDraft.trim(); if (trimmed) { setUserUrl(trimmed); } }; const handleOpenInTab = () => { if (effectiveUrl) { window.open(effectiveUrl, '_blank', 'noopener,noreferrer'); } }; return ( setUrlDraft(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); handleUrlSubmit(); } }} placeholder={detectedUrl || 'http://localhost:3000'} className="h-6 flex-1 min-w-[180px]" /> {showIframeDelayed ? (