2026-03-13 20:55:34 +08:00
|
|
|
import React, { useEffect, useState } from 'react'
|
|
|
|
|
|
|
|
|
|
const XCOPENCODEWEB_PORT = 3002
|
2026-03-13 18:39:58 +08:00
|
|
|
|
|
|
|
|
export const OpenCodePage: React.FC = () => {
|
2026-03-13 20:55:34 +08:00
|
|
|
const [isRunning, setIsRunning] = useState(false)
|
|
|
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
let mounted = true
|
|
|
|
|
|
|
|
|
|
const startService = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const result = await window.electronAPI.xcOpenCodeWebStart()
|
|
|
|
|
if (mounted) {
|
|
|
|
|
if (result.success) {
|
|
|
|
|
setIsRunning(true)
|
|
|
|
|
setError(null)
|
|
|
|
|
} else {
|
|
|
|
|
setError(result.error || '启动失败')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
if (mounted) {
|
|
|
|
|
setError(err instanceof Error ? err.message : '启动失败')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startService()
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
mounted = false
|
|
|
|
|
window.electronAPI.xcOpenCodeWebStop()
|
|
|
|
|
setIsRunning(false)
|
|
|
|
|
}
|
|
|
|
|
}, [])
|
|
|
|
|
|
2026-03-13 18:39:58 +08:00
|
|
|
return (
|
2026-03-13 20:55:34 +08:00
|
|
|
<div className="h-full w-full flex flex-col">
|
|
|
|
|
<div className="max-w-4xl mx-auto w-full px-14 py-4 flex items-center gap-4">
|
|
|
|
|
<h1 className="text-2xl font-bold text-gray-800 dark:text-gray-200">
|
|
|
|
|
OpenCode
|
|
|
|
|
</h1>
|
|
|
|
|
<span className={`px-2 py-1 text-xs rounded ${isRunning ? 'bg-green-100 text-green-700' : 'bg-yellow-100 text-yellow-700'}`}>
|
|
|
|
|
{isRunning ? '运行中' : '启动中...'}
|
|
|
|
|
</span>
|
|
|
|
|
{error && (
|
|
|
|
|
<span className="text-red-500 text-sm">{error}</span>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
{isRunning && (
|
|
|
|
|
<iframe
|
|
|
|
|
src={`http://localhost:${XCOPENCODEWEB_PORT}`}
|
|
|
|
|
className="flex-1 w-full border-0"
|
|
|
|
|
title="XCOpenCodeWeb"
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2026-03-13 18:39:58 +08:00
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|