import { useState, useEffect } from 'react'; import { config as configApi } from '../api'; export default function Output() { const [preview, setPreview] = useState(''); const [loading, setLoading] = useState(false); const [copiedSurge, setCopiedSurge] = useState(false); const [copiedClash, setCopiedClash] = useState(false); const [copiedSsr, setCopiedSsr] = useState(false); const [surgeToken, setSurgeToken] = useState(''); const surgeUrl = surgeToken ? `${window.location.origin}/surge/${surgeToken}` : ''; const clashUrl = surgeToken ? `${window.location.origin}/clash/${surgeToken}` : ''; const ssrUrl = surgeToken ? `${window.location.origin}/ssr/${surgeToken}` : ''; const loadToken = async () => { try { const data = await configApi.getSurgeToken(); setSurgeToken(data.token || ''); } catch {} }; const handleRegenerate = async () => { if (!confirm('重新生成后,旧的订阅链接将失效(Surge / Clash / SSR 三条链接同时更新)。确定继续?')) return; try { const data = await configApi.regenerateSurgeToken(); setSurgeToken(data.token); loadPreview(); } catch {} }; const loadPreview = async () => { setLoading(true); try { const data = await configApi.preview(); setPreview(data.config); } catch (err: any) { setPreview(`# Error: ${err.message}`); } finally { setLoading(false); } }; useEffect(() => { loadToken(); loadPreview(); }, []); const makeCopyHandler = (url: string, setter: (v: boolean) => void) => () => { navigator.clipboard.writeText(url); setter(true); setTimeout(() => setter(false), 2000); }; return (
Surge / Clash / SSR 订阅链接和配置预览
{/* Surge URL */}
{preview || '(empty)'}
{url || '加载中...'}
{onRegenerate && (
)}