import * as vscode from 'vscode'; import { handleBridgeMessage, type BridgeRequest } from './bridge'; import { getThemeKindName } from './theme'; import type { OpenCodeManager, ConnectionStatus } from './opencode'; export class ChatViewProvider implements vscode.WebviewViewProvider { public static readonly viewType = 'openchamber.chatView'; private _view?: vscode.WebviewView; private _isVisible = false; constructor( private readonly _context: vscode.ExtensionContext, private readonly _extensionUri: vscode.Uri, private readonly _openCodeManager?: OpenCodeManager ) {} public resolveWebviewView( webviewView: vscode.WebviewView ) { this._view = webviewView; this._isVisible = webviewView.visible; webviewView.onDidChangeVisibility(() => { this._isVisible = webviewView.visible; }); const distUri = vscode.Uri.joinPath(this._extensionUri, 'dist'); webviewView.webview.options = { enableScripts: true, localResourceRoots: [this._extensionUri, distUri], }; webviewView.webview.html = this._getHtmlForWebview(webviewView.webview); webviewView.webview.onDidReceiveMessage(async (message: BridgeRequest) => { if (message.type === 'restartApi') { await this._openCodeManager?.restart(); return; } const response = await handleBridgeMessage(message, { manager: this._openCodeManager, context: this._context, }); webviewView.webview.postMessage(response); }); } public newSession() { if (this._view) { this._view.webview.postMessage({ type: 'command', command: 'newSession' }); } } public updateTheme(kind: vscode.ColorThemeKind) { if (this._view) { const themeKind = getThemeKindName(kind); this._view.webview.postMessage({ type: 'themeChange', theme: { kind: themeKind }, }); } } public updateConnectionStatus(status: ConnectionStatus, error?: string) { if (this._view) { this._view.webview.postMessage({ type: 'connectionStatus', status, error, }); } } public isVisible(): boolean { return this._isVisible; } private _getHtmlForWebview(webview: vscode.Webview) { const scriptPath = vscode.Uri.joinPath(this._extensionUri, 'dist', 'webview', 'assets', 'index.js'); const scriptUri = webview.asWebviewUri(scriptPath); const config = vscode.workspace.getConfiguration('openchamber'); const apiUrl = this._openCodeManager?.getApiUrl() || config.get('apiUrl') || 'http://localhost:47339'; const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || ''; const themeKind = getThemeKindName(vscode.window.activeColorTheme.kind); const initialStatus = this._openCodeManager?.getStatus() || 'disconnected'; return ` OpenChamber
`; } }