/** * Live Preview Manager * Manages application preview in an iframe */ class PreviewManager { constructor() { this.previewUrl = null; this.previewServer = null; this.previewPort = null; this.isPreviewRunning = false; } /** * Start preview server */ async startPreview(sessionId, workingDir) { console.log('Starting preview for session:', sessionId); try { const res = await fetch(`/claude/api/claude/sessions/${sessionId}/preview/start`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ workingDir }) }); const data = await res.json(); if (!res.ok) { throw new Error(data.error || 'Failed to start preview'); } this.previewUrl = data.url; this.previewPort = data.port; this.previewServer = data.processId; this.isPreviewRunning = true; console.log('Preview started:', this.previewUrl); // Show preview panel this.showPreviewPanel(this.previewUrl); return data; } catch (error) { console.error('Error starting preview:', error); this.showError(error.message); throw error; } } /** * Stop preview server */ async stopPreview(sessionId) { console.log('Stopping preview for session:', sessionId); try { const res = await fetch(`/claude/api/claude/sessions/${sessionId}/preview/stop`, { method: 'POST' }); const data = await res.json(); if (!res.ok) { throw new Error(data.error || 'Failed to stop preview'); } this.isPreviewRunning = false; this.previewUrl = null; this.previewServer = null; // Hide preview panel this.hidePreviewPanel(); console.log('Preview stopped'); return data; } catch (error) { console.error('Error stopping preview:', error); throw error; } } /** * Refresh preview */ refreshPreview() { if (!this.previewUrl || !this.isPreviewRunning) { console.warn('No preview to refresh'); return; } const iframe = document.getElementById('preview-iframe'); if (iframe) { iframe.src = iframe.src; // Reload iframe console.log('Preview refreshed'); } } /** * Show preview panel */ showPreviewPanel(url) { // Remove existing panel const existing = document.querySelector('.preview-panel'); if (existing) { existing.remove(); } // Create preview panel const previewPanel = document.createElement('div'); previewPanel.className = 'preview-panel'; previewPanel.innerHTML = `