fix: 添加拷贝按钮
This commit is contained in:
parent
604cb31114
commit
988b4d10c8
|
|
@ -105,7 +105,6 @@ async fn execute_python_command(_app: tauri::AppHandle, args: &[String]) -> Resu
|
||||||
}
|
}
|
||||||
} else if line.trim().starts_with('{') && line.trim().ends_with('}') {
|
} else if line.trim().starts_with('{') && line.trim().ends_with('}') {
|
||||||
// Fallback: try to parse as direct JSON result
|
// Fallback: try to parse as direct JSON result
|
||||||
println!("Python json rpc: {}", line);
|
|
||||||
if let Ok(json_value) = serde_json::from_str::<serde_json::Value>(line.trim()) {
|
if let Ok(json_value) = serde_json::from_str::<serde_json::Value>(line.trim()) {
|
||||||
// Check if this looks like a final result (has status field)
|
// Check if this looks like a final result (has status field)
|
||||||
if json_value.get("status").is_some() {
|
if json_value.get("status").is_some() {
|
||||||
|
|
@ -113,8 +112,6 @@ async fn execute_python_command(_app: tauri::AppHandle, args: &[String]) -> Resu
|
||||||
println!("Direct JSON result: {}", line.trim());
|
println!("Direct JSON result: {}", line.trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
println!("Python other: {}", line);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
import { Play, Trash2 } from 'lucide-react'
|
import { Play, Trash2, Copy, Check } from 'lucide-react'
|
||||||
|
|
||||||
interface VideoJob {
|
interface VideoJob {
|
||||||
id: string
|
id: string
|
||||||
|
|
@ -22,6 +22,8 @@ interface VideoJobListProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const VideoJobList: React.FC<VideoJobListProps> = ({ jobs, onPreview, onDelete }) => {
|
const VideoJobList: React.FC<VideoJobListProps> = ({ jobs, onPreview, onDelete }) => {
|
||||||
|
const [copiedJobId, setCopiedJobId] = useState<string | null>(null)
|
||||||
|
|
||||||
const formatTime = (timestamp: number): string => {
|
const formatTime = (timestamp: number): string => {
|
||||||
return new Date(timestamp).toLocaleTimeString()
|
return new Date(timestamp).toLocaleTimeString()
|
||||||
}
|
}
|
||||||
|
|
@ -45,6 +47,24 @@ const VideoJobList: React.FC<VideoJobListProps> = ({ jobs, onPreview, onDelete }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const copyErrorToClipboard = (job: VideoJob) => {
|
||||||
|
const errorInfo = {
|
||||||
|
error: job.error,
|
||||||
|
request: job.request,
|
||||||
|
id: job.id,
|
||||||
|
status: job.status,
|
||||||
|
startTime: new Date(job.startTime).toLocaleString(),
|
||||||
|
endTime: job.endTime ? new Date(job.endTime).toLocaleString() : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.clipboard.writeText(JSON.stringify(errorInfo, null, 2))
|
||||||
|
.then(() => {
|
||||||
|
setCopiedJobId(job.id)
|
||||||
|
setTimeout(() => setCopiedJobId(null), 2000)
|
||||||
|
})
|
||||||
|
.catch(err => console.error('Failed to copy error info:', err))
|
||||||
|
}
|
||||||
|
|
||||||
if (jobs.length === 0) {
|
if (jobs.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div className="text-center py-8 text-gray-500">
|
<div className="text-center py-8 text-gray-500">
|
||||||
|
|
@ -141,8 +161,37 @@ const VideoJobList: React.FC<VideoJobListProps> = ({ jobs, onPreview, onDelete }
|
||||||
{/* Error Result */}
|
{/* Error Result */}
|
||||||
{job.error && job.status === 'failed' && (
|
{job.error && job.status === 'failed' && (
|
||||||
<div className="text-sm text-red-600 bg-red-50 p-3 rounded">
|
<div className="text-sm text-red-600 bg-red-50 p-3 rounded">
|
||||||
<div className="font-medium mb-1">❌ 生成失败</div>
|
<div className="flex items-center justify-between mb-2">
|
||||||
<div className="text-xs">{JSON.stringify(job)}</div>
|
<div className="font-medium">❌ 生成失败</div>
|
||||||
|
<button
|
||||||
|
onClick={() => copyErrorToClipboard(job)}
|
||||||
|
className="flex items-center gap-1 px-2 py-1 bg-red-600 text-white text-xs rounded hover:bg-red-700 transition-colors"
|
||||||
|
title="复制错误信息"
|
||||||
|
>
|
||||||
|
{copiedJobId === job.id ? (
|
||||||
|
<>
|
||||||
|
<Check size={12} />
|
||||||
|
已复制
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Copy size={12} />
|
||||||
|
复制
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-red-700 mb-2">
|
||||||
|
错误信息: {job.error}
|
||||||
|
</div>
|
||||||
|
<details className="text-xs">
|
||||||
|
<summary className="cursor-pointer text-red-600 hover:text-red-800">
|
||||||
|
查看详细信息
|
||||||
|
</summary>
|
||||||
|
<pre className="mt-2 p-2 bg-red-100 rounded text-xs overflow-auto max-h-32">
|
||||||
|
{JSON.stringify(job, null, 2)}
|
||||||
|
</pre>
|
||||||
|
</details>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue