Kaynağa Gözat

前端:入库 payload 弹窗加「复制 JSON」按钮(带 http 裸IP 降级 + 已复制反馈)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SamLee 3 hafta önce
ebeveyn
işleme
c10895e592
1 değiştirilmiş dosya ile 10 ekleme ve 2 silme
  1. 10 2
      web/index.html

+ 10 - 2
web/index.html

@@ -172,6 +172,11 @@
 <script type="text/x-jsx" id="app-src">
 const {useState,useEffect}=React;
 const j=u=>fetch(u,{cache:"no-store"}).then(r=>r.json());
+// 复制到剪贴板:http/裸IP 下 navigator.clipboard 不可用,降级到 textarea+execCommand
+function copyText(t){
+  if(navigator.clipboard&&window.isSecureContext) return navigator.clipboard.writeText(t);
+  return new Promise(function(res,rej){try{var ta=document.createElement("textarea");ta.value=t;ta.style.position="fixed";ta.style.top="-9999px";ta.style.opacity="0";document.body.appendChild(ta);ta.focus();ta.select();var ok=document.execCommand("copy");document.body.removeChild(ta);ok?res():rej();}catch(e){rej(e);}});
+}
 const SCOPES=[["substance","实质"],["form","形式"],["feeling","感受"],["effect","作用"],["intent","意图"]];
 const SC_CN={substance:"实质",form:"形式",feeling:"感受",effect:"作用",intent:"意图"};
 const TYPECN={how:"How",what:"What",why:"Why"};
@@ -356,6 +361,7 @@ function App(){
   const [run,setRun]=useState(null);     // 选中的 run slug;null=默认样本 frameworks.json
   const [pm,setPm]=useState(null);
   const [json,setJson]=useState(null);
+  const [copied,setCopied]=useState(false);
   const [zoom,setZoom]=useState(null);
   const [src,setSrc]=useState(null);
   const [hl,setHl]=useState(false);
@@ -434,8 +440,10 @@ function App(){
       <div className="body">
         <div className="pmwhy"><b>为什么这么做:</b>{pm.why}</div>
         {pm.text==="加载中…"?<pre>{pm.text}</pre>:<div className="md" dangerouslySetInnerHTML={{__html:mdToHtml(pm.text)}}/>}</div></div></div>}
-    {json&&<div className="modal" onClick={()=>setJson(null)}><div className="mbox" onClick={e=>e.stopPropagation()}>
-      <h2>⚙️ ingest payload(给机器看)<span className="x" onClick={()=>setJson(null)}>×</span></h2>
+    {json&&<div className="modal" onClick={()=>{setJson(null);setCopied(false);}}><div className="mbox" onClick={e=>e.stopPropagation()}>
+      <h2>⚙️ ingest payload(给机器看)
+        <button className="lbtn" style={{marginLeft:"auto",marginRight:8}} onClick={()=>copyText(JSON.stringify(json,null,2)).then(()=>{setCopied(true);setTimeout(()=>setCopied(false),1500);}).catch(()=>{})}>{copied?"✓ 已复制":"📋 复制 JSON"}</button>
+        <span className="x" style={{marginLeft:0}} onClick={()=>{setJson(null);setCopied(false);}}>×</span></h2>
       <div className="body"><pre>{JSON.stringify(json,null,2)}</pre></div></div></div>}
     {src&&<div className="modal" onClick={()=>setSrc(null)}><div className="mbox" onClick={e=>e.stopPropagation()}>
       <h2>🔍 原文出处(① 读到的卡片)<span className="x" onClick={()=>setSrc(null)}>×</span></h2>