koishi-plugin-chat-patch 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/vue/chat-logic.ts +3159 -0
- package/client/vue/index.vue +114 -3045
- package/dist/index.js +8 -8
- package/dist/style.css +1 -1
- package/lib/api-handlers.d.ts +19 -0
- package/lib/config.d.ts +13 -0
- package/lib/file-manager.d.ts +18 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +40 -13
- package/lib/message-handler.d.ts +19 -0
- package/lib/types.d.ts +55 -0
- package/lib/utils.d.ts +9 -0
- package/package.json +1 -1
- package/src/api-handlers.ts +6 -1
- package/src/index.ts +1 -1
- package/src/message-handler.ts +48 -13
- package/src/types.ts +3 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{defineComponent as ee,ref as f,onMounted as Pe,h as d,computed as O,watch as ht,nextTick as Q,onUnmounted as ua,createElementBlock as y,openBlock as m,normalizeStyle as Me,normalizeClass as V,createElementVNode as i,createCommentVNode as E,Fragment as R,renderList as ce,createBlock as ve,unref as ge,toDisplayString as C,withDirectives as mt,createTextVNode as Fe,vShow as da,withModifiers as vt,withKeys as fa,vModelText as ha,resolveComponent as ma}from"vue";import{receive as He,send as B,icons as va}from"@koishijs/client";const ga={class:"bot-list"},ya={class:"bot-items"},pa=["onClick","onContextmenu"],wa={class:"bot-avatar"},Ia={key:1,class:"avatar-placeholder"},xa={class:"bot-info"},Ca={class:"bot-name"},ka={class:"bot-platform"},ba={class:"channel-list"},_a={key:0,class:"empty-state"},$a={key:1,class:"channel-items"},Sa=["data-channel-id","onClick","onContextmenu"],Ba={class:"channel-info"},Da={class:"channel-name"},La={class:"channel-type"},Ta=["onMousedown","onTouchstart","title"],qa={class:"message-area"},Ua={class:"panel-header"},Ka={key:0,class:"empty-state"},Aa={key:1,class:"message-content"},ja={class:"message-avatar"},Na={key:1,class:"avatar-placeholder"},za={class:"message-content-wrapper"},Oa={class:"message-header"},Ra={class:"message-username"},Pa={class:"message-time"},Ma={key:0,class:"message-quote"},Fa={class:"quote-header"},Ha={class:"quote-avatar"},Xa={key:1,class:"avatar-placeholder"},Ya={class:"quote-username"},Va={class:"quote-time"},Wa={class:"quote-content"},Ja={class:"message-text"},Ga={class:"message-input"},Za={key:0,class:"image-preview-container"},Qa=["src","alt"],Ea=["onClick"],en={class:"input-row"},tn={class:"input-actions"},an=["placeholder","disabled"],nn=["disabled"],sn=100*1024*1024,Xe=50,gt="ChatImageCache",rn=2,D="images",ie=50*1024*1024,yt=100,ue=500,Ye=2*1024*1024,pt=.8,ln=60*1e3,P=80,on=ee({__name:"index",setup(te){function ae(e){try{return new URL(e).protocol==="file:"}catch{return false}}const ne=ee({props:{src:{type:String,required:true},alt:{type:String,default:"头像"},channelKey:{type:String,required:true}},setup(e){const a=f("loading"),t=f(e.src),n=f(""),r=async()=>{try{a.value="loading";const o=await Oe(e.channelKey,e.src);if(o){t.value=o,a.value="loaded";return}const l=new Image;l.crossOrigin="anonymous",l.referrerPolicy="no-referrer",l.draggable=false;const c=new Promise((p,g)=>{l.onload=()=>p(),l.onerror=()=>g(new Error("Direct load failed")),l.src=e.src}),v=new Promise((p,g)=>{setTimeout(()=>g(new Error("Timeout")),3e3)});try{await Promise.race([c,v]),t.value=e.src,a.value="loaded",oe(e.channelKey,e.src).catch(p=>{console.warn("异步缓存头像失败:",p)})}catch{await s()}}catch(o){console.error("头像加载失败:",o),a.value="error",n.value="头像加载失败"}},s=async()=>{try{a.value="caching";const o=await oe(e.channelKey,e.src);if(o)t.value=o,a.value="loaded";else throw new Error("缓存系统加载失败")}catch(o){console.error("缓存系统加载头像失败:",o),a.value="error",n.value=(o==null?void 0:o.message)||"缓存加载失败"}};return Pe(()=>{r()}),()=>{switch(a.value){case"loading":case"caching":return d("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase());case"loaded":return d("img",{src:t.value,alt:e.alt,draggable:false,style:{width:"100%",height:"100%","object-fit":"cover"}});case"error":return d("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase());default:return d("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase())}}}}),de=ee({props:{src:{type:String,required:true},alt:{type:String,default:"图片"},filename:{type:String,default:""},channelKey:{type:String,required:true}},setup(e){const a=f("loading"),t=f(e.src),n=f(""),r=f(null),s=async()=>{try{a.value="loading";const l=await Oe(e.channelKey,e.src);if(l){t.value=l,a.value="loaded";return}if(ae(e.src)){console.log("ImageComponent: 检测到本地文件,使用代理请求:",e.src),await o();return}const c=new Image;c.crossOrigin="anonymous",c.referrerPolicy="no-referrer",c.draggable=false;const v=new Promise((g,L)=>{c.onload=()=>g(),c.onerror=()=>L(new Error("Direct load failed")),c.src=e.src}),p=new Promise((g,L)=>{setTimeout(()=>L(new Error("Timeout")),3e3)});try{await Promise.race([v,p]),t.value=e.src,a.value="loaded",oe(e.channelKey,e.src).catch(g=>{console.warn("异步缓存图片失败:",g)})}catch{await o()}}catch(l){console.error("图片加载失败:",l),a.value="error",n.value="图片加载失败"}},o=async()=>{try{a.value="caching";const l=await oe(e.channelKey,e.src);if(l)t.value=l,a.value="loaded";else throw new Error("缓存系统加载失败")}catch(l){console.error("缓存系统加载图片失败:",l),a.value="error",n.value=(l==null?void 0:l.message)||"缓存加载失败"}};return Pe(()=>{s()}),()=>{switch(a.value){case"loading":return d("div",{class:"message-image-loading"},"加载中...");case"caching":return d("div",{class:"message-image-loading"},"[图片加载缓存中...]");case"loaded":return d("img",{src:t.value,alt:e.alt,class:"message-image",loading:"lazy",ref:r,draggable:false,style:{"max-width":"min(400px, 66.67vw)","max-height":"200px",width:"auto",height:"auto","object-fit":"contain"}});case"error":return d("div",{class:"message-image-error"},["图片加载失败",d("br"),d("small",e.filename||e.alt||"未知图片"),d("br"),d("small",{style:"color: #ff9800;"},n.value)]);default:return d("div",{class:"message-image-error"},"未知状态")}}}}),Be=ee({props:{data:{type:String,required:true},channelKey:{type:String,required:true}},setup(e){const t=(()=>{try{const r=JSON.parse(e.data);if(r.meta&&r.meta.detail_1){const s=r.meta.detail_1;return{type:"share_card",title:s.title||r.prompt||"分享内容",desc:s.desc||"",preview:s.preview?s.preview.replace(/\\\//g,"/"):"",icon:s.icon?s.icon.replace(/\\\//g,"/"):"",url:s.qqdocurl?s.qqdocurl.replace(/\\\//g,"/"):s.url?s.url.replace(/\\\//g,"/"):"",appName:s.title||"应用"}}return{type:"raw",data:r}}catch(r){return console.error("解析JSON数据失败:",r),{type:"error",error:"无法解析的JSON数据"}}})(),n=()=>{t.type==="share_card"&&t.url&&window.open(t.url,"_blank","noopener,noreferrer")};return()=>t.type==="share_card"&&t.preview?d("img",{src:t.preview,alt:t.title||"[分享小程序]",class:"message-image",loading:"lazy",draggable:false,onClick:n,style:{"max-width":"400px","max-height":"200px",width:"auto",height:"auto","object-fit":"contain",cursor:t.url?"pointer":"default"},title:t.url?`点击打开: ${t.title||"链接"}`:t.title,onError:r=>{const o=r.target.parentElement;o&&(o.style.display="none")}}):t.type==="error"?d("div",{class:"message-json-error"},[d("span",{class:"json-error-text"},t.error),d("details",{class:"json-raw-data"},[d("summary","查看原始数据"),d("pre",{class:"json-raw-content"},e.data)])]):d("div",{class:"message-json-raw"},[d("div",{class:"json-label"},"[JSON数据]"),d("details",{class:"json-raw-data"},[d("summary","查看详情"),d("pre",{class:"json-raw-content"},JSON.stringify(t.data,null,2))])])}}),It=ee({props:{element:{type:Object,required:true},channelKey:{type:String,required:true}},setup(e){const a=f(false),t=()=>{a.value=!a.value},n=()=>{if(!e.element.children||e.element.children.length===0)return{previews:[],messageCount:0};const s=e.element.children.filter(c=>c.type==="message"),o=s.length;return{previews:s.slice(0,3).map(c=>{var g,L;const v=((g=c.attrs)==null?void 0:g.nickname)||"用户";let p="";if(c.children&&c.children.length>0){const S=c.children[0];S.type==="text"?(p=(((L=S.attrs)==null?void 0:L.content)||"").substring(0,20),p.length>15&&(p+="...")):S.type==="img"?p="[图片]":S.type==="video"?p="[视频]":p=`[${S.type}]`}return`${v}:${p}`}),messageCount:o}},r=(s,o)=>{var v,p,g;const l=((v=s.attrs)==null?void 0:v.nickname)||"用户",c=((p=s.attrs)==null?void 0:p.userId)||"unknown";return d("div",{key:o,class:"forwarded-message-item"},[d("div",{class:"forwarded-message-header"},[d("span",{class:"forwarded-message-nickname"},l),d("span",{class:"forwarded-message-userid"},`(${c})`)]),d("div",{class:"forwarded-message-content"},((g=s.children)==null?void 0:g.map((L,S)=>d(ye,{key:S,element:L,channelKey:e.channelKey})))||[])])};return()=>{var l;const{previews:s,messageCount:o}=n();return d("div",{class:"forward-message-container"},[d("div",{class:"forward-message-preview",onClick:t},[d("div",{class:"forward-message-title"},"聊天记录"),...s.map((c,v)=>d("div",{key:v,class:"forward-message-preview-item"},c)),d("div",{class:"forward-message-footer"},[d("span",{class:"forward-message-count"},`查看${o}条转发消息`),d("span",{class:"forward-message-toggle"},a.value?"▲":"▼")])]),a.value&&d("div",{class:"forward-message-expanded"},((l=e.element.children)==null?void 0:l.filter(c=>c.type==="message").map((c,v)=>r(c,v)))||[])])}}}),ye=ee({props:{element:{type:Object,required:true},channelKey:{type:String,required:true}},setup(e){const a=t=>{var n,r,s,o,l,c;switch(t.type){case"text":return d("span",{class:"message-text-content"},t.attrs.content||"");case"forward":return d("span",{class:"message-text-content"},`[转发消息 ${t.attrs.id}]`||"[转发消息]");case"img":case"image":const v=t.attrs.src||t.attrs.url||t.attrs.file;return d("div",{class:"message-image-container"},[d(de,{src:v,alt:t.attrs.summary||"图片",filename:t.attrs.filename||t.attrs.summary||"",channelKey:e.channelKey})]);case"mface":const p=t.attrs.src||t.attrs.url||t.attrs.file;return d("div",{class:"message-image-container"},[d(de,{src:p,alt:t.attrs.summary||"表情",filename:t.attrs.emojiId||t.attrs.summary||"",channelKey:e.channelKey})]);case"face":if((r=(n=t.children[0])==null?void 0:n.attrs)!=null&&r.src){const g=((o=(s=t.children[0])==null?void 0:s.attrs)==null?void 0:o.src)||((c=(l=t.children[0])==null?void 0:l.attrs)==null?void 0:c.url);return d("div",{class:"message-image-container"},[d(de,{src:g,alt:t.attrs.name||t.attrs.id||"[表情]",filename:t.attrs.name||t.attrs.id||"[表情]",channelKey:e.channelKey})])}else return d("span",{class:"message-text-content"},`[${t.attrs.name||t.attrs.id}]`||"[表情]");case"at":return d("span",{class:"message-at",title:t.attrs.name},`${t.attrs.name||t.attrs.id}`);case"json":return d("div",{class:"message-image-container"},[d(Be,{data:t.attrs.data||"",channelKey:e.channelKey})]);case"p":if(t.children&&t.children.length>0){const g=t.children.map((L,S)=>d(ye,{key:S,element:L,channelKey:e.channelKey}));return d("div",{class:"message-paragraph"},g)}else return d("div",{class:"message-paragraph"},"");case"figure":return d(It,{element:t,channelKey:e.channelKey});default:return d("span",{class:"message-unknown",title:`未知消息类型: ${t.type}`},t.attrs.content||`[${t.type}]`)}};return()=>a(e.element)}}),u=f({bots:{},channels:{},messages:{}}),U=f({}),pe=f({maxMessagesPerChannel:1e3,keepMessagesOnClear:50,loggerinfo:false,blockedPlatforms:[],chatContainerHeight:80}),b=f({});let De=0,w=null,K=0,M=0,Ve=0;const h=f(""),k=f(""),fe=f("");function We(e){return e.size||0}function we(e){De+=e,pe.value.loggerinfo&&console.log(`内存使用量变化: ${e>0?"+":""}${(e/1024/1024).toFixed(2)}MB, 总计: ${(De/1024/1024).toFixed(2)}MB`)}function Je(e=10){const a=Object.entries(b.value);if(a.length<=e)return;const t=a.slice(0,a.length-e);let n=0;t.forEach(([r,s])=>{URL.revokeObjectURL(s),delete b.value[r],n+=500*1024,pe.value.loggerinfo&&console.log("清理旧blob URL:",r)}),we(-n)}function Le(){Object.keys(b.value).length>Xe&&Je(Math.floor(Xe*.7)),De>sn&&Je(Math.floor(Xe*.5))}const A=f([]),G=f(false),Te=f(),T=f(false),W=f("bots"),F=f(null),se=f(null),qe=f(false),Z=f({show:false,text:""}),$=f(),he=f(),Ue=f(false),me=f(false),re=f(false),H=f(""),j=f({x:0,y:0}),q=f({x:0,y:0}),Ge=f({x:0,y:0}),Ke=f({x:0,y:0}),Ae=f(0),N=f(null),le=f(false),I=f(null),x=f({show:false,x:0,y:0,type:null,targetId:"",isSecondClick:false}),X=f(new Set),Y=f(new Set),xt=O(()=>Object.values(u.value.bots).sort((a,t)=>{const n=X.value.has(a.selfId),r=X.value.has(t.selfId);return n&&!r?-1:!n&&r?1:0})),Ct=O(()=>!h.value||!u.value.channels[h.value]?[]:Object.values(u.value.channels[h.value]).sort((a,t)=>{const n=Y.value.has(`${h.value}:${a.id}`),r=Y.value.has(`${h.value}:${t.id}`);return n&&!r?-1:!n&&r?1:0})),Ze=O(()=>{if(!h.value||!k.value)return[];const e=`${h.value}:${k.value}`,a=u.value.messages[e]||[];return a.filter(t=>t.quote),a}),kt=O(()=>{var a;if(!h.value||!k.value)return"";const e=u.value.channels[h.value];return((a=e==null?void 0:e[k.value])==null?void 0:a.name)||""}),Ie=O(()=>!h.value||!k.value?"":`${h.value}:${k.value}`),Qe=O(()=>h.value&&k.value&&(fe.value.trim()||A.value.length>0)&&!re.value),bt=O(()=>h.value&&k.value&&!re.value),_t=O(()=>{if(!T.value)return"";switch(W.value){case"channels":return"show-channels";case"messages":return"show-messages";default:return""}}),$t=O(()=>T.value?"输入消息...(屏幕左滑返回)":"输入消息..."),St=O(()=>({}));function Bt(e){h.value=e,k.value="",T.value&&(W.value="channels")}function Dt(e,a){if(e.preventDefault(),e.stopPropagation(),x.value.show&&x.value.type==="bot"&&x.value.targetId===a){z();return}Ee(e,"bot",a)}function Lt(e,a){if(e.preventDefault(),e.stopPropagation(),x.value.show&&x.value.type==="channel"&&x.value.targetId===a){z();return}Ee(e,"channel",a)}function Ee(e,a,t){let s=e.clientX,o=e.clientY;s+180>window.innerWidth&&(s=window.innerWidth-180-10),o+80>window.innerHeight&&(o=window.innerHeight-80-10),x.value={show:true,x:s,y:o,type:a,targetId:t,isSecondClick:false},document.addEventListener("click",z,{once:true}),document.addEventListener("keydown",et)}function z(){x.value.show=false,document.removeEventListener("click",z),document.removeEventListener("keydown",et)}function et(e){e.key==="Escape"&&x.value.show&&z()}async function Tt(e){X.value.has(e)?X.value.delete(e):X.value.add(e),await B("set-pinned-bots",{pinnedBots:Array.from(X.value)}),z()}async function qt(e){const a=`${h.value}:${e}`;Y.value.has(a)?Y.value.delete(a):Y.value.add(a),await B("set-pinned-channels",{pinnedChannels:Array.from(Y.value)}),z()}async function Ut(e){try{const a=await B("delete-bot-data",{selfId:e});if(a.success){const t=Object.keys(u.value.messages).filter(n=>n.startsWith(`${e}:`));for(const n of t)delete u.value.messages[n],delete U.value[n],await Se(n);delete u.value.bots[e],delete u.value.channels[e],h.value===e&&(h.value="",k.value=""),_(a.message||"已删除该机器人的所有数据","success")}else throw new Error(a.error||"删除失败")}catch(a){console.error("删除机器人数据失败:",a),_("删除失败: "+((a==null?void 0:a.message)||String(a)),"error")}z()}async function Kt(e){try{const a=await B("delete-channel-data",{selfId:h.value,channelId:e});if(a.success){const t=`${h.value}:${e}`;delete u.value.messages[t],delete U.value[t],u.value.channels[h.value]&&delete u.value.channels[h.value][e],await Se(t),k.value===e&&(k.value=""),_(a.message||"已删除该频道的所有数据","success")}else throw new Error(a.error||"删除失败")}catch(a){console.error("删除频道数据失败:",a),_("删除失败: "+((a==null?void 0:a.message)||String(a)),"error")}z()}async function At(e){k.value=e,me.value=false,T.value&&(W.value="messages"),h.value&&await sa(h.value,e),Q(()=>{J(),!T.value&&he.value&&he.value.focus()})}async function tt(){if(!Qe.value)return;const e=fe.value.trim();if(!e&&A.value.length===0)return;re.value=true;const a=[...A.value];try{const t=await B("send-message",{selfId:h.value,channelId:k.value,content:e,images:a.map(n=>({tempId:n.tempId,filename:n.filename}))});if(t.success){if(fe.value="",a.forEach(n=>{URL.revokeObjectURL(n.preview)}),A.value=[],G.value=false,t.tempImageIds&&t.tempImageIds.length>0)try{await B("cleanup-temp-images",{tempImageIds:t.tempImageIds}),console.log("临时图片清理完成:",t.tempImageIds)}catch(n){console.warn("清理临时图片失败:",n)}}else console.error("消息发送失败:",t.error),_("发送失败: "+t.error,"error")}catch(t){console.error("发送消息时出错:",t),_("发送失败: "+((t==null?void 0:t.message)||String(t)),"error")}finally{re.value=false}}function jt(){G.value=!G.value}function Nt(){Te.value&&Te.value.click(),G.value=false}async function zt(e){const a=e.target,t=a.files;if(!(!t||t.length===0)){for(const n of Array.from(t))await at(n);a.value=""}}async function Ot(e){var t;const a=(t=e.clipboardData)==null?void 0:t.items;if(a){for(const n of Array.from(a))if(n.type.startsWith("image/")){e.preventDefault();const r=n.getAsFile();r&&await at(r)}}}async function at(e){try{if(e.size>10*1024*1024){_("图片文件过大,请选择小于10MB的图片","error");return}if(!e.type.startsWith("image/")){_("请选择图片文件","error");return}const a=await Pt(e),t=URL.createObjectURL(e),n=await B("upload-image",{file:a,filename:e.name,mimeType:e.type});n.success?A.value.push({tempId:n.tempId,filename:e.name,preview:t,size:e.size}):(URL.revokeObjectURL(t),_("图片上传失败: "+n.error,"error"))}catch(a){console.error("上传图片失败:",a),_("图片上传失败: "+((a==null?void 0:a.message)||String(a)),"error")}}async function Rt(e){try{const a=A.value.findIndex(t=>t.tempId===e);if(a!==-1){const t=A.value[a];URL.revokeObjectURL(t.preview),A.value.splice(a,1)}await B("delete-temp-image",{tempId:e})}catch(a){console.error("删除图片失败:",a)}}function Pt(e){return new Promise((a,t)=>{const n=new FileReader;n.onload=()=>a(n.result),n.onerror=t,n.readAsDataURL(e)})}function nt(e){const a=e.target;a.closest(".input-actions")||(G.value=false),a.closest(".context-menu")||z()}function st(e){return new Date(e).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit"})}function Mt(e){if(typeof e=="number")switch(e){case 0:return"文本";case 1:return"私聊";default:return"未知"}return String(e)}function J(){$.value&&($.value.scrollTop=$.value.scrollHeight,Ue.value=false,me.value=false)}function xe(){if($.value){const{scrollTop:e,scrollHeight:a,clientHeight:t}=$.value,r=a-(e+t)<=50,s=!r;Ue.value=s,r?me.value=false:me.value=true}}function Ce(){if(!$.value)return true;const{scrollTop:e,scrollHeight:a,clientHeight:t}=$.value;return a-(e+t)<=200}function je(e){var n;if(!h.value)return 0;const a=`${h.value}:${e}`,t=U.value[a];return t!==void 0?t:((n=u.value.messages[a])==null?void 0:n.length)||0}function rt(e,a){e.preventDefault(),e.stopPropagation();const t="touches"in e?e.touches[0].clientX:e.clientX,n="touches"in e?e.touches[0].clientY:e.clientY;Ae.value=Date.now(),j.value={x:t,y:n},q.value={x:t,y:n},le.value=false;const s=e.target.getBoundingClientRect();Ge.value={x:s.left,y:s.top},Ke.value={x:t-s.left,y:n-s.top},N.value=window.setTimeout(()=>{if(Ae.value>0){le.value=true,H.value=a;const o=e.target,l=o.cloneNode(true);l.classList.add("dragging-clone"),l.style.position="fixed",l.style.zIndex="1000",l.style.pointerEvents="none";const c=o.getBoundingClientRect();l.style.left=`${c.left}px`,l.style.top=`${c.top}px`,l.style.width=`${c.width}px`,l.style.height=`${c.height}px`,document.body.appendChild(l),I.value=l,document.body.style.userSelect="none",document.body.style.cursor="grabbing",document.body.classList.add("dragging-bubble-global"),Xt(j.value.x,j.value.y)}},60),document.addEventListener("mousemove",ke),document.addEventListener("mouseup",be),document.addEventListener("touchmove",ke),document.addEventListener("touchend",be)}function ke(e){if(!le.value||!I.value)return;e.preventDefault();const a="touches"in e?e.touches[0].clientX:e.clientX,t="touches"in e?e.touches[0].clientY:e.clientY;q.value={x:a,y:t};const n=q.value.x-j.value.x,r=q.value.y-j.value.y,s=Math.sqrt(n*n+r*r),o=Math.max(.3,1-s/(P*2)),l=Math.max(.8,1-s/(P*3)),c=s>P,v=q.value.x-Ke.value.x,p=q.value.y-Ke.value.y;I.value.style.left=`${v}px`,I.value.style.top=`${p}px`,I.value.style.transform=`scale(${l})`,I.value.style.opacity=`${o}`,I.value.style.backgroundColor=c?"#f44336":"#2196f3",I.value.style.boxShadow=c?"0 4px 12px rgba(244, 67, 54, 0.4)":"0 4px 12px rgba(33, 150, 243, 0.4)",c?I.value.classList.add("will-delete"):I.value.classList.remove("will-delete")}function be(e){if(N.value&&(clearTimeout(N.value),N.value=null),N.value&&(clearTimeout(N.value),N.value=null),!le.value||!H.value){_e();return}const a=H.value;if(Math.sqrt(Math.pow(q.value.x-j.value.x,2)+Math.pow(q.value.y-j.value.y,2))>P)Ht(a),_e();else if(I.value){I.value.style.transition="all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)";const n=document.querySelector(`[data-channel-id="${a}"] .channel-message-count`);if(n){const r=n.getBoundingClientRect();I.value.style.left=`${r.left}px`,I.value.style.top=`${r.top}px`,I.value.style.transform="scale(1)",I.value.style.opacity="1",I.value.style.backgroundColor="#2196f3",I.value.style.boxShadow="0 4px 12px rgba(33, 150, 243, 0.4)"}setTimeout(()=>{_e()},300)}else _e()}function _e(){N.value&&(clearTimeout(N.value),N.value=null),H.value="",j.value={x:0,y:0},q.value={x:0,y:0},Ge.value={x:0,y:0},Ae.value=0,le.value=false,document.removeEventListener("mousemove",ke),document.removeEventListener("mouseup",be),document.removeEventListener("touchmove",ke),document.removeEventListener("touchend",be),document.body.style.userSelect="",document.body.style.cursor="",document.body.classList.remove("dragging-bubble-global"),I.value&&I.value.parentNode&&(I.value.parentNode.removeChild(I.value),I.value=null),Yt()}function Ft(e){return H.value===e&&le.value?{visibility:"hidden",pointerEvents:"none",transition:"none"}:{}}function lt(e){if(H.value!==e)return 0;const a=q.value.x-j.value.x,t=q.value.y-j.value.y;return Math.sqrt(a*a+t*t)}async function Ht(e){if(h.value)try{const a=`${h.value}:${e}`,t=je(e),n=pe.value.keepMessagesOnClear;if(n>0&&t<=n){_("当前消息还很少诶~ 无需清理","success");return}const r=await B("clear-channel-history",{selfId:h.value,channelId:e});if(r.success)if(r.clearedCount&&r.clearedCount>0){if(u.value.messages[a]){const o=[...u.value.messages[a]].sort((l,c)=>l.timestamp-c.timestamp);u.value.messages[a]=o.slice(-r.keptCount)}U.value[a]=r.keptCount,await Se(a),_(`历史记录已清理,清理了 ${r.clearedCount} 条消息,保留最新 ${r.keptCount} 条`,"success")}else n===0?(u.value.messages[a]&&(u.value.messages[a]=[]),U.value[a]=0,await Se(a),_("历史记录已清理,所有消息已删除","success")):_("当前消息还很少诶~ 无需清理","success");else console.error("清理历史记录失败:",r.error),_("清理失败: "+r.error,"error")}catch(a){console.error("清理历史记录时出错:",a),_("清理失败: "+((a==null?void 0:a.message)||String(a)),"error")}}function _(e,a="success"){const t=document.createElement("div");t.className=`notification ${a}`,t.textContent=e;let n="#4caf50";switch(a){case"info":n="#2196f3";break;case"warn":n="#ff9800";break;case"error":n="#f44336";break;case"success":n="#4caf50";break}t.style.cssText=`
|
|
1
|
+
import{defineComponent as Ce,ref as v,onMounted as nt,h,computed as E,watch as kt,nextTick as xe,onUnmounted as ma,createElementBlock as x,openBlock as y,unref as r,normalizeStyle as st,normalizeClass as le,createCommentVNode as S,createElementVNode as f,Fragment as ee,renderList as De,createBlock as Ne,toDisplayString as D,withDirectives as bt,createTextVNode as ot,vShow as va,withModifiers as St,withKeys as ga,isRef as ya,vModelText as pa,resolveComponent as wa}from"vue";import{receive as rt,send as j,icons as Ia}from"@koishijs/client";function xa(){function te(e){try{return new URL(e).protocol==="file:"}catch{return false}}const ce=Ce({props:{src:{type:String,required:true},alt:{type:String,default:"头像"},channelKey:{type:String,required:true}},setup(e){const t=v("loading"),a=v(e.src),n=v(""),o=async()=>{try{t.value="loading";const i=await Ve(e.channelKey,e.src);if(i){a.value=i,t.value="loaded";return}const c=new Image;c.crossOrigin="anonymous",c.referrerPolicy="no-referrer",c.draggable=false;const d=new Promise((k,w)=>{c.onload=()=>k(),c.onerror=()=>w(new Error("Direct load failed")),c.src=e.src}),p=new Promise((k,w)=>{setTimeout(()=>w(new Error("Timeout")),3e3)});try{await Promise.race([d,p]),a.value=e.src,t.value="loaded",Ie(e.channelKey,e.src).catch(k=>{console.warn("异步缓存头像失败:",k)})}catch{await s()}}catch(i){console.error("头像加载失败:",i),t.value="error",n.value="头像加载失败"}},s=async()=>{try{t.value="caching";const i=await Ie(e.channelKey,e.src);if(i)a.value=i,t.value="loaded";else throw new Error("缓存系统加载失败")}catch(i){console.error("缓存系统加载头像失败:",i),t.value="error",n.value=(i==null?void 0:i.message)||"缓存加载失败"}};return nt(()=>{o()}),()=>{switch(t.value){case"loading":case"caching":return h("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase());case"loaded":return h("img",{src:a.value,alt:e.alt,draggable:false,style:{width:"100%",height:"100%","object-fit":"cover"}});case"error":return h("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase());default:return h("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase())}}}}),Y=Ce({props:{src:{type:String,required:true},alt:{type:String,default:"图片"},filename:{type:String,default:""},channelKey:{type:String,required:true}},setup(e){const t=v("loading"),a=v(e.src),n=v(""),o=v(null),s=async()=>{try{t.value="loading";const c=await Ve(e.channelKey,e.src);if(c){a.value=c,t.value="loaded";return}if(te(e.src)){console.log("ImageComponent: 检测到本地文件,使用代理请求:",e.src),await i();return}const d=new Image;d.crossOrigin="anonymous",d.referrerPolicy="no-referrer",d.draggable=false;const p=new Promise((w,O)=>{d.onload=()=>w(),d.onerror=()=>O(new Error("Direct load failed")),d.src=e.src}),k=new Promise((w,O)=>{setTimeout(()=>O(new Error("Timeout")),3e3)});try{await Promise.race([p,k]),a.value=e.src,t.value="loaded",Ie(e.channelKey,e.src).catch(w=>{console.warn("异步缓存图片失败:",w)})}catch{await i()}}catch(c){console.error("图片加载失败:",c),t.value="error",n.value="图片加载失败"}},i=async()=>{try{t.value="caching";const c=await Ie(e.channelKey,e.src);if(c)a.value=c,t.value="loaded";else throw new Error("缓存系统加载失败")}catch(c){console.error("缓存系统加载图片失败:",c),t.value="error",n.value=(c==null?void 0:c.message)||"缓存加载失败"}};return nt(()=>{s()}),()=>{switch(t.value){case"loading":return h("div",{class:"message-image-loading"},"加载中...");case"caching":return h("div",{class:"message-image-loading"},"[图片加载缓存中...]");case"loaded":return h("img",{src:a.value,alt:e.alt,class:"message-image",loading:"lazy",ref:o,draggable:false,style:{"max-width":"min(400px, 66.67vw)","max-height":"200px",width:"auto",height:"auto","object-fit":"contain"}});case"error":return h("div",{class:"message-image-error"},["图片加载失败",h("br"),h("small",e.filename||e.alt||"未知图片"),h("br"),h("small",{style:"color: #ff9800;"},n.value)]);default:return h("div",{class:"message-image-error"},"未知状态")}}}}),ye=Ce({props:{data:{type:String,required:true},channelKey:{type:String,required:true}},setup(e){const a=(()=>{try{const o=JSON.parse(e.data);if(o.meta&&o.meta.detail_1){const s=o.meta.detail_1;return{type:"share_card",title:s.title||o.prompt||"分享内容",desc:s.desc||"",preview:s.preview?s.preview.replace(/\\\//g,"/"):"",icon:s.icon?s.icon.replace(/\\\//g,"/"):"",url:s.qqdocurl?s.qqdocurl.replace(/\\\//g,"/"):s.url?s.url.replace(/\\\//g,"/"):"",appName:s.title||"应用"}}return{type:"raw",data:o}}catch(o){return console.error("解析JSON数据失败:",o),{type:"error",error:"无法解析的JSON数据"}}})(),n=()=>{a.type==="share_card"&&a.url&&window.open(a.url,"_blank","noopener,noreferrer")};return()=>a.type==="share_card"&&a.preview?h("img",{src:a.preview,alt:a.title||"[分享小程序]",class:"message-image",loading:"lazy",draggable:false,onClick:n,style:{"max-width":"400px","max-height":"200px",width:"auto",height:"auto","object-fit":"contain",cursor:a.url?"pointer":"default"},title:a.url?`点击打开: ${a.title||"链接"}`:a.title,onError:o=>{const i=o.target.parentElement;i&&(i.style.display="none")}}):a.type==="error"?h("div",{class:"message-json-error"},[h("span",{class:"json-error-text"},a.error),h("details",{class:"json-raw-data"},[h("summary","查看原始数据"),h("pre",{class:"json-raw-content"},e.data)])]):h("div",{class:"message-json-raw"},[h("div",{class:"json-label"},"[JSON数据]"),h("details",{class:"json-raw-data"},[h("summary","查看详情"),h("pre",{class:"json-raw-content"},JSON.stringify(a.data,null,2))])])}}),Z=Ce({props:{element:{type:Object,required:true},channelKey:{type:String,required:true}},setup(e){const t=v(false),a=()=>{t.value=!t.value},n=()=>{if(!e.element.children||e.element.children.length===0)return{previews:[],messageCount:0};const s=e.element.children.filter(d=>d.type==="message"),i=s.length;return{previews:s.slice(0,3).map(d=>{var w,O;const p=((w=d.attrs)==null?void 0:w.nickname)||"用户";let k="";if(d.children&&d.children.length>0){const P=d.children[0];P.type==="text"?(k=(((O=P.attrs)==null?void 0:O.content)||"").substring(0,20),k.length>15&&(k+="...")):P.type==="img"?k="[图片]":P.type==="video"?k="[视频]":k=`[${P.type}]`}return`${p}:${k}`}),messageCount:i}},o=(s,i)=>{var p,k,w;const c=((p=s.attrs)==null?void 0:p.nickname)||"用户",d=((k=s.attrs)==null?void 0:k.userId)||"unknown";return h("div",{key:i,class:"forwarded-message-item"},[h("div",{class:"forwarded-message-header"},[h("span",{class:"forwarded-message-nickname"},c),h("span",{class:"forwarded-message-userid"},`(${d})`)]),h("div",{class:"forwarded-message-content"},((w=s.children)==null?void 0:w.map((O,P)=>h(ke,{key:P,element:O,channelKey:e.channelKey})))||[])])};return()=>{var c;const{previews:s,messageCount:i}=n();return h("div",{class:"forward-message-container"},[h("div",{class:"forward-message-preview",onClick:a},[h("div",{class:"forward-message-title"},"聊天记录"),...s.map((d,p)=>h("div",{key:p,class:"forward-message-preview-item"},d)),h("div",{class:"forward-message-footer"},[h("span",{class:"forward-message-count"},`查看${i}条转发消息`),h("span",{class:"forward-message-toggle"},t.value?"▲":"▼")])]),t.value&&h("div",{class:"forward-message-expanded"},((c=e.element.children)==null?void 0:c.filter(d=>d.type==="message").map((d,p)=>o(d,p)))||[])])}}}),ke=Ce({props:{element:{type:Object,required:true},channelKey:{type:String,required:true}},setup(e){const t=a=>{var n,o,s,i,c,d;switch(a.type){case"text":return h("span",{class:"message-text-content"},a.attrs.content||"");case"forward":return h("span",{class:"message-text-content"},`[转发消息 ${a.attrs.id}]`||"[转发消息]");case"img":case"image":const p=a.attrs.src||a.attrs.url||a.attrs.file;return h("div",{class:"message-image-container"},[h(Y,{src:p,alt:a.attrs.summary||"图片",filename:a.attrs.filename||a.attrs.summary||"",channelKey:e.channelKey})]);case"mface":const k=a.attrs.src||a.attrs.url||a.attrs.file;return h("div",{class:"message-image-container"},[h(Y,{src:k,alt:a.attrs.summary||"表情",filename:a.attrs.emojiId||a.attrs.summary||"",channelKey:e.channelKey})]);case"face":if((o=(n=a.children[0])==null?void 0:n.attrs)!=null&&o.src){const w=((i=(s=a.children[0])==null?void 0:s.attrs)==null?void 0:i.src)||((d=(c=a.children[0])==null?void 0:c.attrs)==null?void 0:d.url);return h("div",{class:"message-image-container"},[h(Y,{src:w,alt:a.attrs.name||a.attrs.id||"[表情]",filename:a.attrs.name||a.attrs.id||"[表情]",channelKey:e.channelKey})])}else return h("span",{class:"message-text-content"},`[${a.attrs.name||a.attrs.id}]`||"[表情]");case"at":return h("span",{class:"message-at",title:a.attrs.name},`${a.attrs.name||a.attrs.id}`);case"json":return h("div",{class:"message-image-container"},[h(ye,{data:a.attrs.data||"",channelKey:e.channelKey})]);case"p":if(a.children&&a.children.length>0){const w=a.children.map((O,P)=>h(ke,{key:P,element:O,channelKey:e.channelKey}));return h("div",{class:"message-paragraph"},w)}else return h("div",{class:"message-paragraph"},"");case"figure":return h(Z,{element:a,channelKey:e.channelKey});default:return h("span",{class:"message-unknown",title:`未知消息类型: ${a.type}`},a.attrs.content||`[${a.type}]`)}};return()=>t(e.element)}}),u=v({bots:{},channels:{},messages:{}}),U=v({}),ie=v({maxMessagesPerChannel:1e3,keepMessagesOnClear:50,loggerinfo:false,blockedPlatforms:[],chatContainerHeight:80}),b=v({}),be=100*1024*1024,ue=50;let pe=0,I=null;const Re="ChatImageCache",Oe=2,B="images",ae=50*1024*1024,K=100,de=500,Te=2*1024*1024,Fe=.8,We=60*1e3;let F=0,M=0,He=0;const g=v(""),_=v(""),Se=v(""),V=v([]),fe=v(false),Le=v(),q=v(false),W=v("bots"),H=v(null),ne=v(null),Be=v(false),he=v({show:false,text:""}),$=v(),me=v(),$e=v(false),se=v(false),ve=v(false),oe=v(""),A=v({x:0,y:0}),z=v({x:0,y:0}),_e=v({x:0,y:0}),we=v({x:0,y:0}),X=80,qe=v(0),N=v(null),Q=v(false),C=v(null),R=v({show:false,x:0,y:0,type:null,targetId:"",isSecondClick:false}),J=v(new Set),re=v(new Set),m=E(()=>Object.values(u.value.bots).sort((t,a)=>{const n=J.value.has(t.selfId),o=J.value.has(a.selfId);return n&&!o?-1:!n&&o?1:0})),l=E(()=>!g.value||!u.value.channels[g.value]?[]:Object.values(u.value.channels[g.value]).sort((t,a)=>{const n=re.value.has(`${g.value}:${t.id}`),o=re.value.has(`${g.value}:${a.id}`);return n&&!o?-1:!n&&o?1:0})),T=E(()=>{if(!g.value||!_.value)return[];const e=`${g.value}:${_.value}`,t=u.value.messages[e]||[];return t.filter(a=>a.quote),t}),Ue=E(()=>{var t;if(!g.value||!_.value)return"";const e=u.value.channels[g.value];return((t=e==null?void 0:e[_.value])==null?void 0:t.name)||""}),$t=E(()=>!g.value||!_.value?"":`${g.value}:${_.value}`),lt=E(()=>g.value&&_.value&&(Se.value.trim()||V.value.length>0)&&!ve.value),_t=E(()=>g.value&&_.value&&!ve.value),Dt=E(()=>{if(!q.value)return"";switch(W.value){case"channels":return"show-channels";case"messages":return"show-messages";default:return""}}),Tt=E(()=>q.value?"输入消息...(屏幕左滑返回)":"输入消息..."),Lt=E(()=>({}));function ct(e){return e.size||0}function Xe(e){pe+=e,ie.value.loggerinfo&&console.log(`内存使用量变化: ${e>0?"+":""}${(e/1024/1024).toFixed(2)}MB, 总计: ${(pe/1024/1024).toFixed(2)}MB`)}function it(e=10){const t=Object.entries(b.value);if(t.length<=e)return;const a=t.slice(0,t.length-e);let n=0;a.forEach(([o,s])=>{URL.revokeObjectURL(s),delete b.value[o],n+=500*1024,ie.value.loggerinfo&&console.log("清理旧blob URL:",o)}),Xe(-n)}function Je(){Object.keys(b.value).length>ue&&it(Math.floor(ue*.7)),pe>be&&it(Math.floor(ue*.5))}function qt(e){g.value=e,_.value="",q.value&&(W.value="channels")}function Ut(e,t){if(e.preventDefault(),e.stopPropagation(),R.value.show&&R.value.type==="bot"&&R.value.targetId===t){G();return}Ge(e,"bot",t)}function Kt(e,t){if(e.preventDefault(),e.stopPropagation(),R.value.show&&R.value.type==="channel"&&R.value.targetId===t){G();return}Ge(e,"channel",t)}function Ge(e,t,a){let s=e.clientX,i=e.clientY;s+180>window.innerWidth&&(s=window.innerWidth-180-10),i+80>window.innerHeight&&(i=window.innerHeight-80-10),R.value={show:true,x:s,y:i,type:t,targetId:a,isSecondClick:false},document.addEventListener("click",G,{once:true}),document.addEventListener("keydown",Ze)}function G(){R.value.show=false,document.removeEventListener("click",G),document.removeEventListener("keydown",Ze)}function Ze(e){e.key==="Escape"&&R.value.show&&G()}async function Mt(e){J.value.has(e)?J.value.delete(e):J.value.add(e),await j("set-pinned-bots",{pinnedBots:Array.from(J.value)}),G()}async function At(e){const t=`${g.value}:${e}`;re.value.has(t)?re.value.delete(t):re.value.add(t),await j("set-pinned-channels",{pinnedChannels:Array.from(re.value)}),G()}async function zt(e){try{const t=await j("delete-bot-data",{selfId:e});if(t.success){const a=Object.keys(u.value.messages).filter(n=>n.startsWith(`${e}:`));for(const n of a)delete u.value.messages[n],delete U.value[n],await je(n);delete u.value.bots[e],delete u.value.channels[e],g.value===e&&(g.value="",_.value=""),L(t.message||"已删除该机器人的所有数据","success")}else throw new Error(t.error||"删除失败")}catch(t){console.error("删除机器人数据失败:",t),L("删除失败: "+((t==null?void 0:t.message)||String(t)),"error")}G()}async function Pt(e){try{const t=await j("delete-channel-data",{selfId:g.value,channelId:e});if(t.success){const a=`${g.value}:${e}`;delete u.value.messages[a],delete U.value[a],u.value.channels[g.value]&&delete u.value.channels[g.value][e],await je(a),_.value===e&&(_.value=""),L(t.message||"已删除该频道的所有数据","success")}else throw new Error(t.error||"删除失败")}catch(t){console.error("删除频道数据失败:",t),L("删除失败: "+((t==null?void 0:t.message)||String(t)),"error")}G()}async function jt(e){_.value=e,se.value=false,q.value&&(W.value="messages"),g.value&&await It(g.value,e),xe(()=>{ge(),!q.value&&me.value&&me.value.focus()})}async function Nt(){if(!lt.value)return;const e=Se.value.trim();if(!e&&V.value.length===0)return;ve.value=true;const t=[...V.value];try{const a=await j("send-message",{selfId:g.value,channelId:_.value,content:e,images:t.map(n=>({tempId:n.tempId,filename:n.filename}))});if(a.success){if(Se.value="",t.forEach(n=>{URL.revokeObjectURL(n.preview)}),V.value=[],fe.value=false,a.tempImageIds&&a.tempImageIds.length>0)try{await j("cleanup-temp-images",{tempImageIds:a.tempImageIds}),console.log("临时图片清理完成:",a.tempImageIds)}catch(n){console.warn("清理临时图片失败:",n)}}else console.error("消息发送失败:",a.error),L("发送失败: "+a.error,"error")}catch(a){console.error("发送消息时出错:",a),L("发送失败: "+((a==null?void 0:a.message)||String(a)),"error")}finally{ve.value=false}}function Rt(){fe.value=!fe.value}function Ot(){Le.value&&Le.value.click(),fe.value=false}async function Ft(e){const t=e.target,a=t.files;if(!(!a||a.length===0)){for(const n of Array.from(a))await Qe(n);t.value=""}}async function Ht(e){var a;const t=(a=e.clipboardData)==null?void 0:a.items;if(t){for(const n of Array.from(t))if(n.type.startsWith("image/")){e.preventDefault();const o=n.getAsFile();o&&await Qe(o)}}}async function Qe(e){try{if(e.size>10*1024*1024){L("图片文件过大,请选择小于10MB的图片","error");return}if(!e.type.startsWith("image/")){L("请选择图片文件","error");return}const t=await ut(e),a=URL.createObjectURL(e),n=await j("upload-image",{file:t,filename:e.name,mimeType:e.type});n.success?V.value.push({tempId:n.tempId,filename:e.name,preview:a,size:e.size}):(URL.revokeObjectURL(a),L("图片上传失败: "+n.error,"error"))}catch(t){console.error("上传图片失败:",t),L("图片上传失败: "+((t==null?void 0:t.message)||String(t)),"error")}}async function Xt(e){try{const t=V.value.findIndex(a=>a.tempId===e);if(t!==-1){const a=V.value[t];URL.revokeObjectURL(a.preview),V.value.splice(t,1)}await j("delete-temp-image",{tempId:e})}catch(t){console.error("删除图片失败:",t)}}function ut(e){return new Promise((t,a)=>{const n=new FileReader;n.onload=()=>t(n.result),n.onerror=a,n.readAsDataURL(e)})}function Ee(e){const t=e.target;t.closest(".input-actions")||(fe.value=false),t.closest(".context-menu")||G()}function Yt(e){return new Date(e).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit"})}function Vt(e){if(typeof e=="number")switch(e){case 0:return"文本";case 1:return"私聊";default:return"未知"}return String(e)}function ge(){$.value&&($.value.scrollTop=$.value.scrollHeight,$e.value=false,se.value=false)}function Ke(){if($.value){const{scrollTop:e,scrollHeight:t,clientHeight:a}=$.value,o=t-(e+a)<=50,s=!o;$e.value=s,o?se.value=false:se.value=true}}function Me(){if(!$.value)return true;const{scrollTop:e,scrollHeight:t,clientHeight:a}=$.value;return t-(e+a)<=200}function dt(e){var n;if(!g.value)return 0;const t=`${g.value}:${e}`,a=U.value[t];return a!==void 0?a:((n=u.value.messages[t])==null?void 0:n.length)||0}function Wt(e,t){e.preventDefault(),e.stopPropagation();const a="touches"in e?e.touches[0].clientX:e.clientX,n="touches"in e?e.touches[0].clientY:e.clientY;qe.value=Date.now(),A.value={x:a,y:n},z.value={x:a,y:n},Q.value=false;const s=e.target.getBoundingClientRect();_e.value={x:s.left,y:s.top},we.value={x:a-s.left,y:n-s.top},N.value=window.setTimeout(()=>{if(qe.value>0){Q.value=true,oe.value=t;const i=e.target,c=i.cloneNode(true);c.classList.add("dragging-clone"),c.style.position="fixed",c.style.zIndex="1000",c.style.pointerEvents="none";const d=i.getBoundingClientRect();c.style.left=`${d.left}px`,c.style.top=`${d.top}px`,c.style.width=`${d.width}px`,c.style.height=`${d.height}px`,document.body.appendChild(c),C.value=c,document.body.style.userSelect="none",document.body.style.cursor="grabbing",document.body.classList.add("dragging-bubble-global"),ht(A.value.x,A.value.y)}},60),document.addEventListener("mousemove",Ae),document.addEventListener("mouseup",ze),document.addEventListener("touchmove",Ae),document.addEventListener("touchend",ze)}function Ae(e){if(!Q.value||!C.value)return;e.preventDefault();const t="touches"in e?e.touches[0].clientX:e.clientX,a="touches"in e?e.touches[0].clientY:e.clientY;z.value={x:t,y:a};const n=z.value.x-A.value.x,o=z.value.y-A.value.y,s=Math.sqrt(n*n+o*o),i=Math.max(.3,1-s/(X*2)),c=Math.max(.8,1-s/(X*3)),d=s>X,p=z.value.x-we.value.x,k=z.value.y-we.value.y;C.value.style.left=`${p}px`,C.value.style.top=`${k}px`,C.value.style.transform=`scale(${c})`,C.value.style.opacity=`${i}`,C.value.style.backgroundColor=d?"#f44336":"#2196f3",C.value.style.boxShadow=d?"0 4px 12px rgba(244, 67, 54, 0.4)":"0 4px 12px rgba(33, 150, 243, 0.4)",d?C.value.classList.add("will-delete"):C.value.classList.remove("will-delete")}function ze(e){if(N.value&&(clearTimeout(N.value),N.value=null),N.value&&(clearTimeout(N.value),N.value=null),!Q.value||!oe.value){Pe();return}const t=oe.value;if(Math.sqrt(Math.pow(z.value.x-A.value.x,2)+Math.pow(z.value.y-A.value.y,2))>X)ft(t),Pe();else if(C.value){C.value.style.transition="all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)";const n=document.querySelector(`[data-channel-id="${t}"] .channel-message-count`);if(n){const o=n.getBoundingClientRect();C.value.style.left=`${o.left}px`,C.value.style.top=`${o.top}px`,C.value.style.transform="scale(1)",C.value.style.opacity="1",C.value.style.backgroundColor="#2196f3",C.value.style.boxShadow="0 4px 12px rgba(33, 150, 243, 0.4)"}setTimeout(()=>{Pe()},300)}else Pe()}function Pe(){N.value&&(clearTimeout(N.value),N.value=null),oe.value="",A.value={x:0,y:0},z.value={x:0,y:0},_e.value={x:0,y:0},qe.value=0,Q.value=false,document.removeEventListener("mousemove",Ae),document.removeEventListener("mouseup",ze),document.removeEventListener("touchmove",Ae),document.removeEventListener("touchend",ze),document.body.style.userSelect="",document.body.style.cursor="",document.body.classList.remove("dragging-bubble-global"),C.value&&C.value.parentNode&&(C.value.parentNode.removeChild(C.value),C.value=null),mt()}function Jt(e){return oe.value===e&&Q.value?{visibility:"hidden",pointerEvents:"none",transition:"none"}:{}}function Gt(e){if(oe.value!==e)return 0;const t=z.value.x-A.value.x,a=z.value.y-A.value.y;return Math.sqrt(t*t+a*a)}async function ft(e){if(g.value)try{const t=`${g.value}:${e}`,a=dt(e),n=ie.value.keepMessagesOnClear;if(n>0&&a<=n){L("当前消息还很少诶~ 无需清理","success");return}const o=await j("clear-channel-history",{selfId:g.value,channelId:e});if(o.success)if(o.clearedCount&&o.clearedCount>0){if(u.value.messages[t]){const i=[...u.value.messages[t]].sort((c,d)=>c.timestamp-d.timestamp);u.value.messages[t]=i.slice(-o.keptCount)}U.value[t]=o.keptCount,await je(t),L(`历史记录已清理,清理了 ${o.clearedCount} 条消息,保留最新 ${o.keptCount} 条`,"success")}else n===0?(u.value.messages[t]&&(u.value.messages[t]=[]),U.value[t]=0,await je(t),L("历史记录已清理,所有消息已删除","success")):L("当前消息还很少诶~ 无需清理","success");else console.error("清理历史记录失败:",o.error),L("清理失败: "+o.error,"error")}catch(t){console.error("清理历史记录时出错:",t),L("清理失败: "+((t==null?void 0:t.message)||String(t)),"error")}}function L(e,t="success"){const a=document.createElement("div");a.className=`notification ${t}`,a.textContent=e;let n="#4caf50";switch(t){case"info":n="#2196f3";break;case"warn":n="#ff9800";break;case"error":n="#f44336";break;case"success":n="#4caf50";break}a.style.cssText=`
|
|
2
2
|
position: fixed;
|
|
3
3
|
top: 20px;
|
|
4
4
|
right: 20px;
|
|
@@ -10,7 +10,7 @@ import{defineComponent as ee,ref as f,onMounted as Pe,h as d,computed as O,watch
|
|
|
10
10
|
animation: slideIn 0.3s ease-out;
|
|
11
11
|
background: ${n};
|
|
12
12
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
13
|
-
`;const
|
|
13
|
+
`;const o=document.createElement("style");o.textContent=`
|
|
14
14
|
@keyframes slideIn {
|
|
15
15
|
from { transform: translateX(100%); opacity: 0; }
|
|
16
16
|
to { transform: translateX(0); opacity: 1; }
|
|
@@ -19,9 +19,9 @@ import{defineComponent as ee,ref as f,onMounted as Pe,h as d,computed as O,watch
|
|
|
19
19
|
from { transform: translateX(0); opacity: 1; }
|
|
20
20
|
to { transform: translateX(100%); opacity: 0; }
|
|
21
21
|
}
|
|
22
|
-
`,document.head.appendChild(
|
|
23
|
-
left: ${e-
|
|
24
|
-
top: ${
|
|
25
|
-
width: ${
|
|
26
|
-
height: ${
|
|
27
|
-
`,document.body.appendChild(t),window.dragThresholdCircle=t}function Yt(){const e=window.dragThresholdCircle;e&&e.parentNode&&(e.parentNode.removeChild(e),window.dragThresholdCircle=null)}async function Ne(){try{if(!w)return false;const e=Date.now();if(e-Ve<ln)return true;Ve=e;const a=await ot();K=a.totalSize,M=a.totalImages,console.log("数据库健康检查:",{大小:`${(K/1024/1024).toFixed(2)}MB / ${(ie/1024/1024).toFixed(2)}MB`,图片数量:`${M} / ${ue}`,使用率:`${(K/ie*100).toFixed(1)}%`});const t=K/ie,n=M/ue;return(t>pt||n>pt)&&(console.warn("数据库使用率过高,开始自动清理"),await $e()),(t>.95||n>.95)&&(console.error("数据库接近极限,执行紧急清理"),await Vt()),true}catch(e){return console.error("数据库健康检查失败:",e),false}}async function ot(){return w?new Promise(e=>{const n=w.transaction([D],"readonly").objectStore(D).getAll();n.onsuccess=()=>{const r=n.result||[];let s=0;const o={};r.forEach(l=>{s+=l.size||0,o[l.channelKey]=(o[l.channelKey]||0)+1}),e({totalSize:s,totalImages:r.length,channelStats:o})},n.onerror=()=>{console.error("获取数据库统计失败:",n.error),e({totalSize:0,totalImages:0,channelStats:{}})}}):{totalSize:0,totalImages:0,channelStats:{}}}async function $e(){try{console.log("开始自动清理...");const e=await ct();if(e.length===0)return;const a={};e.forEach(r=>{a[r.channelKey]||(a[r.channelKey]=[]),a[r.channelKey].push(r)});let t=0,n=0;for(const[r,s]of Object.entries(a))if(s.length>yt){s.sort((l,c)=>l.timestamp-c.timestamp);const o=s.slice(0,s.length-yt);for(const l of o)await ze(l.url),t++,n+=l.size||0,b.value[l.url]&&(URL.revokeObjectURL(b.value[l.url]),delete b.value[l.url])}console.log(`自动清理完成: 清理了 ${t} 张图片,释放了 ${(n/1024/1024).toFixed(2)}MB`),M-=t,K-=n}catch(e){console.error("自动清理失败:",e)}}async function Vt(){try{console.log("开始紧急清理...");const e=await ct();if(e.length===0)return;e.sort((s,o)=>o.timestamp-s.timestamp);const a=Math.floor(ue*.3),t=e.slice(a);let n=0,r=0;for(const s of t)await ze(s.url),n++,r+=s.size||0,b.value[s.url]&&(URL.revokeObjectURL(b.value[s.url]),delete b.value[s.url]);console.log(`紧急清理完成: 清理了 ${n} 张图片,释放了 ${(r/1024/1024).toFixed(2)}MB`),M=a,K-=r}catch(e){console.error("紧急清理失败:",e)}}async function ct(){return w?new Promise(e=>{const n=w.transaction([D],"readonly").objectStore(D).getAll();n.onsuccess=()=>{e(n.result||[])},n.onerror=()=>{console.error("获取所有图片失败:",n.error),e([])}}):[]}async function Wt(){return new Promise(e=>{try{w&&(w.close(),w=null);const a=indexedDB.deleteDatabase(gt);a.onsuccess=()=>{console.log("IndexedDB数据库已完全清理"),K=0,M=0,e(true)},a.onerror=()=>{console.error("清理IndexedDB数据库失败:",a.error),e(false)},a.onblocked=()=>{console.warn("IndexedDB数据库删除被阻塞,可能有其他连接正在使用"),setTimeout(()=>{e(false)},5e3)}}catch(a){console.error("清理数据库时出错:",a),e(false)}})}async function Jt(){try{return await it()?(setTimeout(async()=>{const a=await ot();console.log("数据库初始状态:",{大小:`${(a.totalSize/1024/1024).toFixed(2)}MB`,图片数量:a.totalImages,频道分布:a.channelStats}),(a.totalSize>ie*.9||a.totalImages>ue*.9)&&(console.warn("数据库初始状态接近限制,执行清理"),await $e())},1e3),true):(console.warn("数据库打开失败,尝试清理后重新初始化"),await Wt(),await it())}catch(e){return console.error("IndexedDB初始化出错:",e),false}}async function it(){return new Promise(e=>{try{const a=indexedDB.open(gt,rn);a.onerror=()=>{console.error("IndexedDB打开失败:",a.error),e(false)},a.onsuccess=()=>{w=a.result,w.onerror=t=>{console.error("IndexedDB运行时错误:",t)},w.onversionchange=()=>{console.warn("IndexedDB版本变更,关闭连接"),w==null||w.close(),w=null},e(true)},a.onupgradeneeded=t=>{const n=t.target.result;if(!n.objectStoreNames.contains(D)){const r=n.createObjectStore(D,{keyPath:"url"});r.createIndex("channelKey","channelKey",{unique:false}),r.createIndex("timestamp","timestamp",{unique:false}),r.createIndex("size","size",{unique:false}),console.log("IndexedDB对象存储创建完成")}},a.onblocked=()=>{console.warn("IndexedDB打开被阻塞"),e(false)}}catch(a){console.error("打开数据库时出错:",a),e(false)}})}async function Gt(e){return w?new Promise((a,t)=>{const s=w.transaction([D],"readonly").objectStore(D).get(e);s.onsuccess=()=>{a(s.result||null)},s.onerror=()=>{console.error("从IndexedDB获取图片失败:",s.error),a(null)}}):null}async function ut(e){if(!w)return false;try{return e.size>Ye?(console.warn(`图片过大,跳过缓存: ${(e.size/1024/1024).toFixed(2)}MB > ${(Ye/1024/1024).toFixed(2)}MB`),false):(await Ne(),K+e.size>ie&&(console.warn("添加图片会超过数据库大小限制,执行清理"),await $e(),K+e.size>ie)?(console.warn("清理后仍会超过限制,跳过此图片"),false):M>=ue&&(console.warn("图片数量已达上限,执行清理"),await $e(),M>=ue)?(console.warn("清理后仍达上限,跳过此图片"),false):new Promise(a=>{const r=w.transaction([D],"readwrite").objectStore(D).put(e);r.onsuccess=()=>{K+=e.size,M+=1,a(true)},r.onerror=()=>{console.error("保存图片到IndexedDB失败:",r.error),a(false)}}))}catch(a){return console.error("保存图片时出错:",a),false}}async function ze(e){return w?new Promise(a=>{const r=w.transaction([D],"readwrite").objectStore(D).delete(e);r.onsuccess=()=>{a(true)},r.onerror=()=>{console.error("从IndexedDB删除图片失败:",r.error),a(false)}}):false}async function Zt(e){return w?new Promise(a=>{const s=w.transaction([D],"readonly").objectStore(D).index("channelKey").getAll(e);s.onsuccess=()=>{a(s.result||[])},s.onerror=()=>{console.error("获取频道图片失败:",s.error),a([])}}):[]}async function Oe(e,a){const t=b.value[a];if(t)return t;const n=await Gt(a);if(!n)return null;Le();const r=URL.createObjectURL(n.blob);return b.value[a]=r,we(We(n.blob)),n.timestamp=Date.now(),await ut(n),r}async function oe(e,a){try{const t=await Oe(e,a);if(t)return t;const n=await B("fetch-image",{url:a});if(!n.success)return console.error("获取图片失败:",n.error),null;const r=n.base64,s=n.contentType||"image/jpeg",o=atob(r),l=new Array(o.length);for(let S=0;S<o.length;S++)l[S]=o.charCodeAt(S);const c=new Uint8Array(l),v=new Blob([c],{type:s});if(v.size>Ye)return console.warn(`图片过大,跳过缓存: ${(v.size/1024/1024).toFixed(2)}MB`),null;const p={url:a,blob:v,timestamp:Date.now(),size:v.size,channelKey:e};if(!await ut(p))return console.error("保存图片到IndexedDB失败"),null;Le();const L=URL.createObjectURL(v);return b.value[a]=L,we(We(v)),L}catch(t){return console.error("缓存图片失败:",t),null}}async function Se(e){try{const a=await Zt(e);let t=0;for(const n of a)await ze(n.url),b.value[n.url]&&(URL.revokeObjectURL(b.value[n.url]),delete b.value[n.url],t+=n.size||0);t>0&&we(-t)}catch(a){console.error("清理频道图片缓存失败:",a)}}function Qt(e){var a,t,n,r;if(!u.value.bots[e.selfId])u.value.bots[e.selfId]={selfId:e.selfId,platform:e.platform,username:((a=e.bot)==null?void 0:a.name)||`Bot-${e.selfId}`,avatar:(t=e.bot)==null?void 0:t.avatar,status:"online"};else{const s=u.value.bots[e.selfId];s.status="online",(n=e.bot)!=null&&n.name&&s.username!==e.bot.name&&(s.username=e.bot.name),(r=e.bot)!=null&&r.avatar&&s.avatar!==e.bot.avatar&&(s.avatar=e.bot.avatar)}if(u.value.channels[e.selfId]||(u.value.channels[e.selfId]={}),e.channelId&&!u.value.channels[e.selfId][e.channelId]){const s=e.guildId?`${e.guildName||e.guildId} (${e.channelId})`:`私信 ${e.channelId}`;u.value.channels[e.selfId][e.channelId]={id:e.channelId,name:s,type:e.channelType||0,guildId:e.guildId,guildName:e.guildName||e.guildId||"私聊"}}if(e.messageId&&e.content&&e.channelId){const s=`${e.selfId}:${e.channelId}`;if(u.value.messages[s]||(u.value.messages[s]=[]),!u.value.messages[s].find(l=>l.id===e.messageId)){const l={id:e.messageId,content:e.content,userId:e.userId,username:e.username,avatar:e.avatar,timestamp:e.timestamp,channelId:e.channelId,selfId:e.selfId,elements:e.elements,isBot:false,quote:e.quote},c=u.value.messages[s];let v=c.length;for(let g=c.length-1;g>=0;g--){if(c[g].timestamp<=e.timestamp){v=g+1;break}g===0&&(v=0)}c.splice(v,0,l),c.length>100&&(u.value.messages[s]=c.slice(-100)),U.value[s]=c.length;const p=Ce();Q(()=>{setTimeout(()=>{p&&J()},10)})}}if(e.elements&&e.elements.length>0){const s=`${e.selfId}:${e.channelId}`;e.elements.forEach(o=>{if((o.type==="img"||o.type==="image"||o.type==="mface")&&o.attrs){const l=o.attrs.src||o.attrs.url||o.attrs.file;l&&oe(s,l).catch(c=>{console.warn("预缓存图片失败:",l,c)})}})}u.value={...u.value}}function Et(e){const a=`${e.selfId}:${e.channelId}`;if(u.value.messages[a]||(u.value.messages[a]=[]),!u.value.messages[a].find(n=>n.id===e.messageId)){const n={id:e.messageId,content:e.content,userId:e.selfId,username:e.botUsername,avatar:e.botAvatar,timestamp:e.timestamp,channelId:e.channelId,selfId:e.selfId,elements:e.elements,isBot:true,quote:e.quote},r=u.value.messages[a];let s=r.length;for(let l=r.length-1;l>=0;l--){if(r[l].timestamp<=e.timestamp){s=l+1;break}l===0&&(s=0)}r.splice(s,0,n),r.length>100&&(u.value.messages[a]=r.slice(-100)),U.value[a]=r.length;const o=Ce();Q(()=>{setTimeout(()=>{o&&J()},10)})}u.value={...u.value}}function ea(e){var a,t,n,r;if(!u.value.bots[e.selfId])u.value.bots[e.selfId]={selfId:e.selfId,platform:e.platform,username:((a=e.bot)==null?void 0:a.name)||`Bot-${e.selfId}`,avatar:(t=e.bot)==null?void 0:t.avatar,status:"online"};else{const s=u.value.bots[e.selfId];s.status="online",(n=e.bot)!=null&&n.name&&s.username!==e.bot.name&&(s.username=e.bot.name),(r=e.bot)!=null&&r.avatar&&s.avatar!==e.bot.avatar&&(s.avatar=e.bot.avatar)}if(u.value.channels[e.selfId]||(u.value.channels[e.selfId]={}),e.channelId&&!u.value.channels[e.selfId][e.channelId]){const s=e.guildId?`${e.guildName||e.guildId} (${e.channelId})`:`私信 ${e.channelId}`;u.value.channels[e.selfId][e.channelId]={id:e.channelId,name:s,type:e.channelType||0,guildId:e.guildId,guildName:e.guildName||e.guildId||"私聊"}}if(e.messageId&&e.content&&e.channelId){const s=`${e.selfId}:${e.channelId}`;if(u.value.messages[s]||(u.value.messages[s]=[]),!u.value.messages[s].find(l=>l.id===e.messageId)){const l={id:e.messageId,content:e.content,userId:e.userId,username:e.username,avatar:e.avatar,timestamp:e.timestamp,channelId:e.channelId,selfId:e.selfId,elements:e.elements,isBot:true,quote:e.quote},c=u.value.messages[s];let v=c.length;for(let g=c.length-1;g>=0;g--){if(c[g].timestamp<=e.timestamp){v=g+1;break}g===0&&(v=0)}c.splice(v,0,l),c.length>100&&(u.value.messages[s]=c.slice(-100)),U.value[s]=c.length;const p=Ce();Q(()=>{setTimeout(()=>{p&&J()},10)})}}if(e.elements&&e.elements.length>0){const s=`${e.selfId}:${e.channelId}`;e.elements.forEach(o=>{if((o.type==="img"||o.type==="image"||o.type==="mface")&&o.attrs){const l=o.attrs.src||o.attrs.url||o.attrs.file;l&&oe(s,l).catch(c=>{console.warn("预缓存图片失败:",l,c)})}})}u.value={...u.value}}ht(Ze,(e,a)=>{a.length===0&&e.length>0&&Q(()=>{J()})});async function ta(){try{const e=await B("get-chat-data");if(e.success&&e.data){const a={};X.value=new Set(e.data.pinnedBots||[]),Y.value=new Set(e.data.pinnedChannels||[]);for(const[t,n]of Object.entries(e.data.messages||{})){const r=n.map(s=>({id:s.id,content:s.content,userId:s.userId,username:s.username,avatar:s.avatar,timestamp:s.timestamp,channelId:s.channelId,selfId:s.selfId,elements:s.elements,isBot:s.type==="bot",quote:s.quote}));r.sort((s,o)=>s.timestamp-o.timestamp),a[t]=r}return u.value={bots:e.data.bots||{},channels:e.data.channels||{},messages:a},await aa(),true}else return console.warn("获取聊天数据失败:",e.error),false}catch(e){return console.error("获取聊天数据时出错:",e),false}}async function aa(){try{const e=await B("get-all-channel-message-counts");if(e.success&&e.counts){const a={};for(const[t,n]of Object.entries(e.counts))a[t]=n;U.value=a}else console.warn("获取频道消息数量失败:",e.error)}catch(e){console.error("获取频道消息数量时出错:",e)}}async function na(){try{const e=await B("get-plugin-config");e.success&&e.config?pe.value=e.config:console.warn("获取插件配置失败:",e.error)}catch(e){console.error("获取插件配置时出错:",e)}}async function sa(e,a){try{const t=await B("get-history-messages",{selfId:e,channelId:a});if(t.success&&t.messages){const n=`${e}:${a}`,r=t.messages.map(s=>({id:s.id,content:s.content,userId:s.userId,username:s.username,avatar:s.avatar,timestamp:s.timestamp,channelId:s.channelId,selfId:s.selfId,elements:s.elements,isBot:s.type==="bot",quote:s.quote}));return r.sort((s,o)=>s.timestamp-o.timestamp),u.value.messages[n]=r,U.value[n]=r.length,u.value={...u.value},true}else return console.warn("获取历史消息失败:",t.error),false}catch(t){return console.error("获取历史消息时出错:",t),false}}function ra(e){if(!T.value||e.touches.length!==1)return;const a=e.touches[0];F.value={x:a.clientX,y:a.clientY,time:Date.now()},se.value={x:a.clientX,y:a.clientY},qe.value=false}function la(e){if(!T.value||!F.value||e.touches.length!==1)return;const a=e.touches[0];se.value={x:a.clientX,y:a.clientY};const t=a.clientX-F.value.x,n=a.clientY-F.value.y;if(Math.abs(t)>Math.abs(n)&&Math.abs(t)>30){const r=t>0,s=W.value==="messages"||W.value==="channels";if(r&&s){qe.value=true;const o=Math.min(t,200),l=150;o>l?Z.value={show:true,text:"松开返回"}:Z.value={show:true,text:`滑动返回 ${Math.round(o/l*100)}%`},e.preventDefault()}else Z.value={show:false,text:""}}else Z.value={show:false,text:""}}function oa(e){if(!T.value||!F.value)return;const t=Date.now()-F.value.time;if(se.value){const n=se.value.x-F.value.x,r=se.value.y-F.value.y,s=n>150,o=Math.abs(n)>Math.abs(r),l=t<300&&n>80;(s&&o||l)&&ca()}F.value=null,se.value=null,qe.value=false,Z.value={show:false,text:""}}function ca(){switch(W.value){case"messages":W.value="channels";break;case"channels":W.value="bots",h.value="",k.value="";break}}function Re(){T.value=window.innerWidth<=768}function dt(){return!me.value||Ce()}const ft=()=>{T.value&&$.value&&Q(()=>{dt()&&J()})},ia=()=>{T.value&&setTimeout(()=>{$.value&&dt()&&J()},300)};return Pe(async()=>{Re(),window.addEventListener("resize",Re),window.visualViewport&&window.visualViewport.addEventListener("resize",ft),document.addEventListener("click",nt),await Jt()?(console.log("IndexedDB初始化成功"),setTimeout(async()=>{await Ne()},2e3),setInterval(async()=>{await Ne()},5*60*1e3)):console.warn("IndexedDB初始化失败,图片缓存功能将不可用"),await na(),await ta();const a=He("chat-message-event",Qt),t=He("bot-message-sent-event",Et),n=He("chat-bot-message-event",ea);ht(k,r=>{r&&Q(()=>{$.value&&($.value.removeEventListener("scroll",xe),$.value.addEventListener("scroll",xe),xe()),!T.value&&he.value&&he.value.focus()})},{immediate:true}),setInterval(()=>{Le()},2*60*1e3),ua(()=>{window.removeEventListener("resize",Re),window.visualViewport&&window.visualViewport.removeEventListener("resize",ft),document.removeEventListener("click",nt),a&&typeof a=="function"&&a(),t&&typeof t=="function"&&t(),n&&typeof n=="function"&&n(),$.value&&$.value.removeEventListener("scroll",xe),Object.values(b.value).forEach(r=>{URL.revokeObjectURL(r)}),b.value={},w&&(w.close(),w=null)})}),(e,a)=>(m(),y("div",{class:V(["chat-container",_t.value]),style:Me(St.value),onTouchstart:ra,onTouchmove:la,onTouchend:oa},[i("div",ga,[a[7]||(a[7]=i("div",{class:"panel-header"},[i("h3",null,"机器人")],-1)),i("div",ya,[(m(true),y(R,null,ce(xt.value,t=>(m(),y("div",{key:t.selfId,class:V(["bot-item",{active:h.value===t.selfId,pinned:X.value.has(t.selfId)}]),onClick:n=>Bt(t.selfId),onContextmenu:n=>Dt(n,t.selfId)},[i("div",wa,[t.avatar?(m(),ve(ge(ne),{key:0,src:t.avatar,alt:t.username,"channel-key":"bot-list"},null,8,["src","alt"])):(m(),y("div",Ia,C(t.username.charAt(0).toUpperCase()),1))]),i("div",xa,[i("div",Ca,C(t.username),1),i("div",ka,C(t.platform),1)]),i("div",{class:V(["bot-status",t.status])},null,2)],42,pa))),128))])]),i("div",ba,[a[8]||(a[8]=i("div",{class:"panel-header"},[i("h3",null,"频道")],-1)),h.value?(m(),y("div",$a,[(m(true),y(R,null,ce(Ct.value,t=>(m(),y("div",{key:t.id,class:V(["channel-item",{active:k.value===t.id,pinned:Y.value.has(`${h.value}:${t.id}`)}]),"data-channel-id":t.id,onClick:n=>At(t.id),onContextmenu:n=>Lt(n,t.id)},[i("div",Ba,[i("div",Da,C(t.name),1),i("div",La,C(Mt(t.type)),1)]),je(t.id)>0?(m(),y("div",{key:0,class:V(["channel-message-count draggable-bubble",{dragging:H.value===t.id,"will-delete":H.value===t.id&<(t.id)>P}]),onMousedown:n=>rt(n,t.id),onTouchstart:n=>rt(n,t.id),style:Me(Ft(t.id)),title:H.value===t.id?lt(t.id)>P?"松开清理历史记录":"拖拽更远以清理历史记录":"拖拽清理历史记录"},C(je(t.id)),47,Ta)):E("",true)],42,Sa))),128))])):(m(),y("div",_a," 请选择一个机器人 "))]),i("div",qa,[i("div",Ua,[i("h3",null,C(kt.value||"选择频道"),1)]),!h.value||!k.value?(m(),y("div",Ka," 请选择机器人和频道 ")):(m(),y("div",Aa,[i("div",{class:"message-history",ref_key:"messageHistory",ref:$},[(m(true),y(R,null,ce(Ze.value,t=>(m(),y("div",{key:t.id,class:V(["message-item",{"bot-message":t.isBot}])},[i("div",ja,[t.avatar?(m(),ve(ge(ne),{key:0,src:t.avatar,alt:t.username,"channel-key":Ie.value},null,8,["src","alt","channel-key"])):(m(),y("div",Na,C(t.username.charAt(0).toUpperCase()),1))]),i("div",za,[i("div",Oa,[i("span",Ra,C(t.username),1),i("span",Pa,C(st(t.timestamp)),1)]),t.quote?(m(),y("div",Ma,[i("div",Fa,[i("div",Ha,[t.quote.user.avatar?(m(),ve(ge(ne),{key:0,src:t.quote.user.avatar,alt:t.quote.user.username,"channel-key":Ie.value},null,8,["src","alt","channel-key"])):(m(),y("div",Xa,C(t.quote.user.username.charAt(0).toUpperCase()),1))]),i("span",Ya,C(t.quote.user.username),1),i("span",Va,C(st(t.quote.timestamp)),1)]),i("div",Wa,[t.quote.elements&&t.quote.elements.length>0?(m(true),y(R,{key:0},ce(t.quote.elements,(n,r)=>(m(),ve(ge(ye),{key:`quote-${r}`,element:n,"channel-key":Ie.value},null,8,["element","channel-key"]))),128)):(m(),y(R,{key:1},[Fe(C(t.quote.content),1)],64))])])):E("",true),i("div",Ja,[t.elements&&t.elements.length>0?(m(true),y(R,{key:0},ce(t.elements,(n,r)=>(m(),ve(ge(ye),{key:r,element:n,"channel-key":Ie.value},null,8,["element","channel-key"]))),128)):(m(),y(R,{key:1},[Fe(C(t.content),1)],64))])])],2))),128))],512),mt(i("div",{class:"floating-scroll-button",onClick:J},a[9]||(a[9]=[i("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor"},[i("path",{d:"M7 10l5 5 5-5z"})],-1)]),512),[[da,Ue.value]]),i("div",Ga,[A.value.length>0?(m(),y("div",Za,[(m(true),y(R,null,ce(A.value,t=>(m(),y("div",{key:t.tempId,class:"image-preview-item"},[i("img",{src:t.preview,alt:t.filename,class:"preview-image"},null,8,Qa),i("button",{class:"remove-image-btn",onClick:n=>Rt(t.tempId),title:"删除图片"},a[10]||(a[10]=[i("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"currentColor"},[i("path",{d:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"})],-1)]),8,Ea)]))),128))])):E("",true),i("div",en,[i("div",tn,[i("button",{class:V(["add-button",{active:G.value}]),onClick:jt,title:"更多操作"},a[11]||(a[11]=[i("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2.5","stroke-linecap":"round","stroke-linejoin":"round"},[i("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),i("line",{x1:"5",y1:"12",x2:"19",y2:"12"})],-1)]),2),G.value?(m(),y("div",{key:0,class:"action-menu",onClick:a[0]||(a[0]=vt(()=>{},["stop"]))},[i("button",{class:"action-menu-item",onClick:Nt},a[12]||(a[12]=[i("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[i("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),i("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),i("polyline",{points:"21,15 16,10 5,21"})],-1),Fe(" 上传图片 ",-1)]))])):E("",true)]),mt(i("input",{"onUpdate:modelValue":a[1]||(a[1]=t=>fe.value=t),type:"text",placeholder:$t.value,onKeyup:fa(tt,["enter"]),disabled:!bt.value,ref_key:"messageInput",ref:he,onPaste:Ot,onFocus:ia},null,40,an),[[ha,fe.value]]),i("button",{onClick:tt,disabled:!Qe.value,class:V({"is-sending":re.value})},C(re.value?"发送中...":"发送"),11,nn)]),i("input",{type:"file",ref_key:"fileInput",ref:Te,onChange:zt,accept:"image/*",multiple:"",style:{display:"none"}},null,544)])]))]),x.value.show?(m(),y("div",{key:0,class:"context-menu",style:Me({left:x.value.x+"px",top:x.value.y+"px"}),onClick:a[6]||(a[6]=vt(()=>{},["stop"]))},[x.value.type==="bot"?(m(),y(R,{key:0},[i("div",{class:"context-menu-item",onClick:a[2]||(a[2]=t=>Tt(x.value.targetId))},C(X.value.has(x.value.targetId)?"取消置顶":"置顶"),1),i("div",{class:"context-menu-item danger",onClick:a[3]||(a[3]=t=>Ut(x.value.targetId))}," 彻底删除此机器人所有数据 ")],64)):E("",true),x.value.type==="channel"?(m(),y(R,{key:1},[i("div",{class:"context-menu-item",onClick:a[4]||(a[4]=t=>qt(x.value.targetId))},C(Y.value.has(`${h.value}:${x.value.targetId}`)?"取消置顶":"置顶"),1),i("div",{class:"context-menu-item danger",onClick:a[5]||(a[5]=t=>Kt(x.value.targetId))}," 彻底删除此频道所有数据 ")],64)):E("",true)],4)):E("",true),i("div",{class:V(["swipe-indicator",{show:Z.value.show}])},C(Z.value.text),3)],38))}}),wt=(te,ae)=>{const ne=te.__vccOpts||te;for(const[de,Be]of ae)ne[de]=Be;return ne},cn=wt(on,[["__scopeId","data-v-95736198"]]),un={},dn={class:"k-icon",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none"};function fn(te,ae){return m(),y("svg",dn,ae[0]||(ae[0]=[i("path",{d:"M8 10.5H16",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),i("path",{d:"M8 14H13.5",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),i("path",{d:"M17 3.33782C15.5291 2.48697 13.8214 2 12 2C6.47715 2 2 6.47715 2 12C2 13.5997 2.37562 15.1116 3.04346 16.4525C3.22094 16.8088 3.28001 17.2161 3.17712 17.6006L2.58151 19.8267C2.32295 20.793 3.20701 21.677 4.17335 21.4185L6.39939 20.8229C6.78393 20.72 7.19121 20.7791 7.54753 20.9565C8.88837 21.6244 10.4003 22 12 22C17.5228 22 22 17.5228 22 12C22 10.1786 21.513 8.47087 20.6622 7",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1)]))}const hn=wt(un,[["render",fn]]);va.register("activity:chat",hn);const gn=te=>{te.page({name:"聊天室",path:"/chat-patch",desc:"",authority:4,icon:"activity:chat",component:ee({setup(){return()=>d(ma("k-layout"),{},{default:()=>d(cn)})}})})};export{gn as default};
|
|
22
|
+
`,document.head.appendChild(o),document.body.appendChild(a),setTimeout(()=>{a.style.animation="slideOut 0.3s ease-in",setTimeout(()=>{a.parentNode&&a.parentNode.removeChild(a),o.parentNode&&o.parentNode.removeChild(o)},300)},3e3)}function ht(e,t){const a=document.createElement("div");a.className="drag-threshold-circle",a.style.cssText=`
|
|
23
|
+
left: ${e-X}px;
|
|
24
|
+
top: ${t-X}px;
|
|
25
|
+
width: ${X*2}px;
|
|
26
|
+
height: ${X*2}px;
|
|
27
|
+
`,document.body.appendChild(a),window.dragThresholdCircle=a}function mt(){const e=window.dragThresholdCircle;e&&e.parentNode&&(e.parentNode.removeChild(e),window.dragThresholdCircle=null)}async function et(){try{if(!I)return false;const e=Date.now();if(e-He<We)return true;He=e;const t=await vt();F=t.totalSize,M=t.totalImages,console.log("数据库健康检查:",{大小:`${(F/1024/1024).toFixed(2)}MB / ${(ae/1024/1024).toFixed(2)}MB`,图片数量:`${M} / ${de}`,使用率:`${(F/ae*100).toFixed(1)}%`});const a=F/ae,n=M/de;return(a>Fe||n>Fe)&&(console.warn("数据库使用率过高,开始自动清理"),await Ye()),(a>.95||n>.95)&&(console.error("数据库接近极限,执行紧急清理"),await Zt()),true}catch(e){return console.error("数据库健康检查失败:",e),false}}async function vt(){return I?new Promise(e=>{const n=I.transaction([B],"readonly").objectStore(B).getAll();n.onsuccess=()=>{const o=n.result||[];let s=0;const i={};o.forEach(c=>{s+=c.size||0,i[c.channelKey]=(i[c.channelKey]||0)+1}),e({totalSize:s,totalImages:o.length,channelStats:i})},n.onerror=()=>{console.error("获取数据库统计失败:",n.error),e({totalSize:0,totalImages:0,channelStats:{}})}}):{totalSize:0,totalImages:0,channelStats:{}}}async function Ye(){try{console.log("开始自动清理...");const e=await gt();if(e.length===0)return;const t={};e.forEach(o=>{t[o.channelKey]||(t[o.channelKey]=[]),t[o.channelKey].push(o)});let a=0,n=0;for(const[o,s]of Object.entries(t))if(s.length>K){s.sort((c,d)=>c.timestamp-d.timestamp);const i=s.slice(0,s.length-K);for(const c of i)await tt(c.url),a++,n+=c.size||0,b.value[c.url]&&(URL.revokeObjectURL(b.value[c.url]),delete b.value[c.url])}console.log(`自动清理完成: 清理了 ${a} 张图片,释放了 ${(n/1024/1024).toFixed(2)}MB`),M-=a,F-=n}catch(e){console.error("自动清理失败:",e)}}async function Zt(){try{console.log("开始紧急清理...");const e=await gt();if(e.length===0)return;e.sort((s,i)=>i.timestamp-s.timestamp);const t=Math.floor(de*.3),a=e.slice(t);let n=0,o=0;for(const s of a)await tt(s.url),n++,o+=s.size||0,b.value[s.url]&&(URL.revokeObjectURL(b.value[s.url]),delete b.value[s.url]);console.log(`紧急清理完成: 清理了 ${n} 张图片,释放了 ${(o/1024/1024).toFixed(2)}MB`),M=t,F-=o}catch(e){console.error("紧急清理失败:",e)}}async function gt(){return I?new Promise(e=>{const n=I.transaction([B],"readonly").objectStore(B).getAll();n.onsuccess=()=>{e(n.result||[])},n.onerror=()=>{console.error("获取所有图片失败:",n.error),e([])}}):[]}async function Qt(){return new Promise(e=>{try{I&&(I.close(),I=null);const t=indexedDB.deleteDatabase(Re);t.onsuccess=()=>{console.log("IndexedDB数据库已完全清理"),F=0,M=0,e(true)},t.onerror=()=>{console.error("清理IndexedDB数据库失败:",t.error),e(false)},t.onblocked=()=>{console.warn("IndexedDB数据库删除被阻塞,可能有其他连接正在使用"),setTimeout(()=>{e(false)},5e3)}}catch(t){console.error("清理数据库时出错:",t),e(false)}})}async function Et(){try{return await yt()?(setTimeout(async()=>{const t=await vt();console.log("数据库初始状态:",{大小:`${(t.totalSize/1024/1024).toFixed(2)}MB`,图片数量:t.totalImages,频道分布:t.channelStats}),(t.totalSize>ae*.9||t.totalImages>de*.9)&&(console.warn("数据库初始状态接近限制,执行清理"),await Ye())},1e3),true):(console.warn("数据库打开失败,尝试清理后重新初始化"),await Qt(),await yt())}catch(e){return console.error("IndexedDB初始化出错:",e),false}}async function yt(){return new Promise(e=>{try{const t=indexedDB.open(Re,Oe);t.onerror=()=>{console.error("IndexedDB打开失败:",t.error),e(false)},t.onsuccess=()=>{I=t.result,I.onerror=a=>{console.error("IndexedDB运行时错误:",a)},I.onversionchange=()=>{console.warn("IndexedDB版本变更,关闭连接"),I==null||I.close(),I=null},e(true)},t.onupgradeneeded=a=>{const n=a.target.result;if(!n.objectStoreNames.contains(B)){const o=n.createObjectStore(B,{keyPath:"url"});o.createIndex("channelKey","channelKey",{unique:false}),o.createIndex("timestamp","timestamp",{unique:false}),o.createIndex("size","size",{unique:false}),console.log("IndexedDB对象存储创建完成")}},t.onblocked=()=>{console.warn("IndexedDB打开被阻塞"),e(false)}}catch(t){console.error("打开数据库时出错:",t),e(false)}})}async function ea(e){return I?new Promise((t,a)=>{const s=I.transaction([B],"readonly").objectStore(B).get(e);s.onsuccess=()=>{t(s.result||null)},s.onerror=()=>{console.error("从IndexedDB获取图片失败:",s.error),t(null)}}):null}async function pt(e){if(!I)return false;try{return e.size>Te?(console.warn(`图片过大,跳过缓存: ${(e.size/1024/1024).toFixed(2)}MB > ${(Te/1024/1024).toFixed(2)}MB`),false):(await et(),F+e.size>ae&&(console.warn("添加图片会超过数据库大小限制,执行清理"),await Ye(),F+e.size>ae)?(console.warn("清理后仍会超过限制,跳过此图片"),false):M>=de&&(console.warn("图片数量已达上限,执行清理"),await Ye(),M>=de)?(console.warn("清理后仍达上限,跳过此图片"),false):new Promise(t=>{const o=I.transaction([B],"readwrite").objectStore(B).put(e);o.onsuccess=()=>{F+=e.size,M+=1,t(true)},o.onerror=()=>{console.error("保存图片到IndexedDB失败:",o.error),t(false)}}))}catch(t){return console.error("保存图片时出错:",t),false}}async function tt(e){return I?new Promise(t=>{const o=I.transaction([B],"readwrite").objectStore(B).delete(e);o.onsuccess=()=>{t(true)},o.onerror=()=>{console.error("从IndexedDB删除图片失败:",o.error),t(false)}}):false}async function ta(e){return I?new Promise(t=>{const s=I.transaction([B],"readonly").objectStore(B).index("channelKey").getAll(e);s.onsuccess=()=>{t(s.result||[])},s.onerror=()=>{console.error("获取频道图片失败:",s.error),t([])}}):[]}async function Ve(e,t){const a=b.value[t];if(a)return a;const n=await ea(t);if(!n)return null;Je();const o=URL.createObjectURL(n.blob);return b.value[t]=o,Xe(ct(n.blob)),n.timestamp=Date.now(),await pt(n),o}async function Ie(e,t){try{const a=await Ve(e,t);if(a)return a;const n=await j("fetch-image",{url:t});if(!n.success)return console.error("获取图片失败:",n.error),null;const o=n.base64,s=n.contentType||"image/jpeg",i=atob(o),c=new Array(i.length);for(let P=0;P<i.length;P++)c[P]=i.charCodeAt(P);const d=new Uint8Array(c),p=new Blob([d],{type:s});if(p.size>Te)return console.warn(`图片过大,跳过缓存: ${(p.size/1024/1024).toFixed(2)}MB`),null;const k={url:t,blob:p,timestamp:Date.now(),size:p.size,channelKey:e};if(!await pt(k))return console.error("保存图片到IndexedDB失败"),null;Je();const O=URL.createObjectURL(p);return b.value[t]=O,Xe(ct(p)),O}catch(a){return console.error("缓存图片失败:",a),null}}async function je(e){try{const t=await ta(e);let a=0;for(const n of t)await tt(n.url),b.value[n.url]&&(URL.revokeObjectURL(b.value[n.url]),delete b.value[n.url],a+=n.size||0);a>0&&Xe(-a)}catch(t){console.error("清理频道图片缓存失败:",t)}}function aa(){const e=Object.keys(b.value).length;return{blobCount:e,estimatedMemoryUsage:pe,maxMemoryLimit:be,maxBlobLimit:ue,memoryUsagePercent:(pe/be*100).toFixed(1),blobUsagePercent:(e/ue*100).toFixed(1)}}async function na(){return I?new Promise(e=>{const n=I.transaction([B],"readonly").objectStore(B).getAll();n.onsuccess=()=>{const o=n.result||[],s=new Set;let i=0;o.forEach(c=>{s.add(c.channelKey),i+=c.size}),e({totalImages:o.length,totalSize:i,channels:s.size})},n.onerror=()=>{console.error("获取缓存统计失败:",n.error),e({totalImages:0,totalSize:0,channels:0})}}):{totalImages:0,totalSize:0,channels:0}}function wt(e){var t,a,n,o;if(!u.value.bots[e.selfId])u.value.bots[e.selfId]={selfId:e.selfId,platform:e.platform,username:((t=e.bot)==null?void 0:t.name)||`Bot-${e.selfId}`,avatar:(a=e.bot)==null?void 0:a.avatar,status:"online"};else{const s=u.value.bots[e.selfId];s.status="online",(n=e.bot)!=null&&n.name&&s.username!==e.bot.name&&(s.username=e.bot.name),(o=e.bot)!=null&&o.avatar&&s.avatar!==e.bot.avatar&&(s.avatar=e.bot.avatar)}if(u.value.channels[e.selfId]||(u.value.channels[e.selfId]={}),e.channelId&&!u.value.channels[e.selfId][e.channelId]){const s=e.isDirect?`私信 ${e.channelId}`:`${e.guildName||e.channelId} (${e.channelId})`;u.value.channels[e.selfId][e.channelId]={id:e.channelId,name:s,type:e.channelType||0,channelId:e.channelId,guildName:e.guildName||"群聊",isDirect:e.isDirect}}if(e.messageId&&e.content&&e.channelId){const s=`${e.selfId}:${e.channelId}`;if(u.value.messages[s]||(u.value.messages[s]=[]),!u.value.messages[s].find(c=>c.id===e.messageId)){const c={id:e.messageId,content:e.content,userId:e.userId,username:e.username,avatar:e.avatar,timestamp:e.timestamp,channelId:e.channelId,selfId:e.selfId,elements:e.elements,isBot:false,quote:e.quote},d=u.value.messages[s];let p=d.length;for(let w=d.length-1;w>=0;w--){if(d[w].timestamp<=e.timestamp){p=w+1;break}w===0&&(p=0)}d.splice(p,0,c),d.length>100&&(u.value.messages[s]=d.slice(-100)),U.value[s]=d.length;const k=Me();xe(()=>{setTimeout(()=>{k&&ge()},10)})}}if(e.elements&&e.elements.length>0){const s=`${e.selfId}:${e.channelId}`;e.elements.forEach(i=>{if((i.type==="img"||i.type==="image"||i.type==="mface")&&i.attrs){const c=i.attrs.src||i.attrs.url||i.attrs.file;c&&Ie(s,c).catch(d=>{console.warn("预缓存图片失败:",c,d)})}})}u.value={...u.value}}function sa(e){const t=`${e.selfId}:${e.channelId}`;if(u.value.messages[t]||(u.value.messages[t]=[]),!u.value.messages[t].find(n=>n.id===e.messageId)){const n={id:e.messageId,content:e.content,userId:e.selfId,username:e.botUsername,avatar:e.botAvatar,timestamp:e.timestamp,channelId:e.channelId,selfId:e.selfId,elements:e.elements,isBot:true,quote:e.quote},o=u.value.messages[t];let s=o.length;for(let c=o.length-1;c>=0;c--){if(o[c].timestamp<=e.timestamp){s=c+1;break}c===0&&(s=0)}o.splice(s,0,n),o.length>100&&(u.value.messages[t]=o.slice(-100)),U.value[t]=o.length;const i=Me();xe(()=>{setTimeout(()=>{i&&ge()},10)})}u.value={...u.value}}function oa(e){var t,a,n,o;if(!u.value.bots[e.selfId])u.value.bots[e.selfId]={selfId:e.selfId,platform:e.platform,username:((t=e.bot)==null?void 0:t.name)||`Bot-${e.selfId}`,avatar:(a=e.bot)==null?void 0:a.avatar,status:"online"};else{const s=u.value.bots[e.selfId];s.status="online",(n=e.bot)!=null&&n.name&&s.username!==e.bot.name&&(s.username=e.bot.name),(o=e.bot)!=null&&o.avatar&&s.avatar!==e.bot.avatar&&(s.avatar=e.bot.avatar)}if(u.value.channels[e.selfId]||(u.value.channels[e.selfId]={}),e.channelId&&!u.value.channels[e.selfId][e.channelId]){const s=e.isDirect?`私信 ${e.channelId}`:`${e.guildName||e.channelId} (${e.channelId})`;u.value.channels[e.selfId][e.channelId]={id:e.channelId,name:s,type:e.channelType||0,channelId:e.channelId,guildName:e.guildName||"群聊",isDirect:e.isDirect}}if(e.messageId&&e.content&&e.channelId){const s=`${e.selfId}:${e.channelId}`;if(u.value.messages[s]||(u.value.messages[s]=[]),!u.value.messages[s].find(c=>c.id===e.messageId)){const c={id:e.messageId,content:e.content,userId:e.userId,username:e.username,avatar:e.avatar,timestamp:e.timestamp,channelId:e.channelId,selfId:e.selfId,elements:e.elements,isBot:true,quote:e.quote},d=u.value.messages[s];let p=d.length;for(let w=d.length-1;w>=0;w--){if(d[w].timestamp<=e.timestamp){p=w+1;break}w===0&&(p=0)}d.splice(p,0,c),d.length>100&&(u.value.messages[s]=d.slice(-100)),U.value[s]=d.length;const k=Me();xe(()=>{setTimeout(()=>{k&&ge()},10)})}}if(e.elements&&e.elements.length>0){const s=`${e.selfId}:${e.channelId}`;e.elements.forEach(i=>{if((i.type==="img"||i.type==="image"||i.type==="mface")&&i.attrs){const c=i.attrs.src||i.attrs.url||i.attrs.file;c&&Ie(s,c).catch(d=>{console.warn("预缓存图片失败:",c,d)})}})}u.value={...u.value}}async function ra(){try{const e=await j("get-chat-data");if(e.success&&e.data){const t={};J.value=new Set(e.data.pinnedBots||[]),re.value=new Set(e.data.pinnedChannels||[]);for(const[a,n]of Object.entries(e.data.messages||{})){const o=n.map(s=>({id:s.id,content:s.content,userId:s.userId,username:s.username,avatar:s.avatar,timestamp:s.timestamp,channelId:s.channelId,selfId:s.selfId,elements:s.elements,isBot:s.type==="bot",quote:s.quote}));o.sort((s,i)=>s.timestamp-i.timestamp),t[a]=o}return u.value={bots:e.data.bots||{},channels:e.data.channels||{},messages:t},await la(),true}else return console.warn("获取聊天数据失败:",e.error),false}catch(e){return console.error("获取聊天数据时出错:",e),false}}async function la(){try{const e=await j("get-all-channel-message-counts");if(e.success&&e.counts){const t={};for(const[a,n]of Object.entries(e.counts))t[a]=n;U.value=t}else console.warn("获取频道消息数量失败:",e.error)}catch(e){console.error("获取频道消息数量时出错:",e)}}async function ca(){try{const e=await j("get-plugin-config");e.success&&e.config?ie.value=e.config:console.warn("获取插件配置失败:",e.error)}catch(e){console.error("获取插件配置时出错:",e)}}async function It(e,t){try{const a=await j("get-history-messages",{selfId:e,channelId:t});if(a.success&&a.messages){const n=`${e}:${t}`,o=a.messages.map(s=>({id:s.id,content:s.content,userId:s.userId,username:s.username,avatar:s.avatar,timestamp:s.timestamp,channelId:s.channelId,selfId:s.selfId,elements:s.elements,isBot:s.type==="bot",quote:s.quote}));return o.sort((s,i)=>s.timestamp-i.timestamp),u.value.messages[n]=o,U.value[n]=o.length,u.value={...u.value},true}else return console.warn("获取历史消息失败:",a.error),false}catch(a){return console.error("获取历史消息时出错:",a),false}}function ia(e){if(!q.value||e.touches.length!==1)return;const t=e.touches[0];H.value={x:t.clientX,y:t.clientY,time:Date.now()},ne.value={x:t.clientX,y:t.clientY},Be.value=false}function ua(e){if(!q.value||!H.value||e.touches.length!==1)return;const t=e.touches[0];ne.value={x:t.clientX,y:t.clientY};const a=t.clientX-H.value.x,n=t.clientY-H.value.y;if(Math.abs(a)>Math.abs(n)&&Math.abs(a)>30){const o=a>0,s=W.value==="messages"||W.value==="channels";if(o&&s){Be.value=true;const i=Math.min(a,200),c=150;i>c?he.value={show:true,text:"松开返回"}:he.value={show:true,text:`滑动返回 ${Math.round(i/c*100)}%`},e.preventDefault()}else he.value={show:false,text:""}}else he.value={show:false,text:""}}function da(e){if(!q.value||!H.value)return;const a=Date.now()-H.value.time;if(ne.value){const n=ne.value.x-H.value.x,o=ne.value.y-H.value.y,s=n>150,i=Math.abs(n)>Math.abs(o),c=a<300&&n>80;(s&&i||c)&&fa()}H.value=null,ne.value=null,Be.value=false,he.value={show:false,text:""}}function fa(){switch(W.value){case"messages":W.value="channels";break;case"channels":W.value="bots",g.value="",_.value="";break}}function at(){q.value=window.innerWidth<=768}function xt(){return!se.value||Me()}const Ct=()=>{q.value&&$.value&&xe(()=>{xt()&&ge()})},ha=()=>{q.value&&setTimeout(()=>{$.value&&xt()&&ge()},300)};return kt(T,(e,t)=>{t.length===0&&e.length>0&&xe(()=>{ge()})}),nt(async()=>{at(),window.addEventListener("resize",at),window.visualViewport&&window.visualViewport.addEventListener("resize",Ct),document.addEventListener("click",Ee),await Et()?(console.log("IndexedDB初始化成功"),setTimeout(async()=>{await et()},2e3),setInterval(async()=>{await et()},5*60*1e3)):console.warn("IndexedDB初始化失败,图片缓存功能将不可用"),await ca(),await ra();const t=rt("chat-message-event",wt),a=rt("bot-message-sent-event",sa),n=rt("chat-bot-message-event",oa);kt(_,o=>{o&&xe(()=>{$.value&&($.value.removeEventListener("scroll",Ke),$.value.addEventListener("scroll",Ke),Ke()),!q.value&&me.value&&me.value.focus()})},{immediate:true}),setInterval(()=>{Je()},2*60*1e3),ma(()=>{window.removeEventListener("resize",at),window.visualViewport&&window.visualViewport.removeEventListener("resize",Ct),document.removeEventListener("click",Ee),t&&typeof t=="function"&&t(),a&&typeof a=="function"&&a(),n&&typeof n=="function"&&n(),$.value&&$.value.removeEventListener("scroll",Ke),Object.values(b.value).forEach(o=>{URL.revokeObjectURL(o)}),b.value={},I&&(I.close(),I=null)})}),{AvatarComponent:ce,ImageComponent:Y,JsonCardComponent:ye,ForwardMessageComponent:Z,MessageElement:ke,chatData:u,channelMessageCounts:U,pluginConfig:ie,selectedBot:g,selectedChannel:_,inputMessage:Se,imageBlobUrls:b,pinnedBots:J,pinnedChannels:re,uploadedImages:V,showActionMenu:fe,isMobile:q,mobileView:W,touchStart:H,touchCurrent:ne,isSwipeActive:Be,swipeIndicator:he,messageHistory:$,messageInput:me,showScrollButton:$e,isUserScrolling:se,isSending:ve,draggingChannel:oe,dragStartPos:A,dragCurrentPos:z,dragElementInitialPos:_e,dragOffset:we,dragThreshold:X,isDragReady:Q,draggedBubbleElement:C,contextMenu:R,fileInput:Le,bots:m,currentChannels:l,currentMessages:T,currentChannelName:Ue,currentChannelKey:$t,canSendMessage:lt,canInputMessage:_t,mobileViewClass:Dt,inputPlaceholder:Tt,chatContainerStyle:Lt,selectBot:qt,selectChannel:jt,handleBotRightClick:Ut,handleChannelRightClick:Kt,showContextMenu:Ge,hideContextMenu:G,handleKeyDown:Ze,toggleBotPin:Mt,toggleChannelPin:At,deleteBotMessages:zt,deleteChannelMessages:Pt,sendMessage:Nt,toggleActionMenu:Rt,triggerImageUpload:Ot,handleFileSelect:Ft,handlePaste:Ht,uploadImage:Qe,removeImage:Xt,fileToBase64:ut,handleClickOutside:Ee,formatTime:Yt,getChannelTypeText:Vt,scrollToBottom:ge,checkScrollPosition:Ke,isNearBottom:Me,getChannelMessageCount:dt,startDrag:Wt,handleDragMove:Ae,handleDragEnd:ze,resetDragState:Pe,getDragStyle:Jt,getDragDistance:Gt,clearChannelHistory:ft,showNotification:L,createThresholdCircle:ht,removeThresholdCircle:mt,handleTouchStart:ia,handleTouchMove:ua,handleTouchEnd:da,handleInputFocus:ha,getCachedImageUrl:Ve,cacheImage:Ie,clearChannelImageCache:je,getMemoryStats:aa,getCacheStats:na,isFileUrl:te,loadHistoryMessages:It,handleMessageEvent:wt}}const Ca={class:"bot-list"},ka={class:"bot-items"},ba=["onClick","onContextmenu"],Sa={class:"bot-avatar"},Ba={key:1,class:"avatar-placeholder"},$a={class:"bot-info"},_a={class:"bot-name"},Da={class:"bot-platform"},Ta={class:"channel-list"},La={key:0,class:"empty-state"},qa={key:1,class:"channel-items"},Ua=["data-channel-id","onClick","onContextmenu"],Ka={class:"channel-info"},Ma={class:"channel-name"},Aa={class:"channel-type"},za=["onMousedown","onTouchstart","title"],Pa={class:"message-area"},ja={class:"panel-header"},Na={key:0,class:"empty-state"},Ra={key:1,class:"message-content"},Oa={class:"message-avatar"},Fa={key:1,class:"avatar-placeholder"},Ha={class:"message-content-wrapper"},Xa={class:"message-header"},Ya={class:"message-username"},Va={class:"message-time"},Wa={key:0,class:"message-quote"},Ja={class:"quote-header"},Ga={class:"quote-avatar"},Za={key:1,class:"avatar-placeholder"},Qa={class:"quote-username"},Ea={class:"quote-time"},en={class:"quote-content"},tn={class:"message-text"},an={class:"message-input"},nn={key:0,class:"image-preview-container"},sn=["src","alt"],on=["onClick"],rn={class:"input-row"},ln={class:"input-actions"},cn=["placeholder","disabled"],un=["disabled"],dn=Ce({__name:"index",setup(te){const ce=xa(),{AvatarComponent:Y,MessageElement:ye,selectedBot:Z,selectedChannel:ke,inputMessage:u,pinnedBots:U,pinnedChannels:ie,uploadedImages:b,showActionMenu:be,swipeIndicator:ue,messageHistory:pe,messageInput:I,showScrollButton:Re,isSending:Oe,draggingChannel:B,dragThreshold:ae,contextMenu:K,fileInput:de,bots:Te,currentChannels:Fe,currentMessages:We,currentChannelName:F,currentChannelKey:M,canSendMessage:He,canInputMessage:g,mobileViewClass:_,inputPlaceholder:Se,chatContainerStyle:V,selectBot:fe,selectChannel:Le,handleBotRightClick:q,handleChannelRightClick:W,toggleBotPin:H,toggleChannelPin:ne,deleteBotMessages:Be,deleteChannelMessages:he,sendMessage:$,toggleActionMenu:me,triggerImageUpload:$e,handleFileSelect:se,handlePaste:ve,removeImage:oe,formatTime:A,getChannelTypeText:z,scrollToBottom:_e,getChannelMessageCount:we,startDrag:X,getDragStyle:qe,getDragDistance:N,handleTouchStart:Q,handleTouchMove:C,handleTouchEnd:R,handleInputFocus:J}=ce;return(re,m)=>(y(),x("div",{class:le(["chat-container",r(_)]),style:st(r(V)),onTouchstart:m[15]||(m[15]=(...l)=>r(Q)&&r(Q)(...l)),onTouchmove:m[16]||(m[16]=(...l)=>r(C)&&r(C)(...l)),onTouchend:m[17]||(m[17]=(...l)=>r(R)&&r(R)(...l))},[S(" 左侧机器人列表 "),f("div",Ca,[m[18]||(m[18]=f("div",{class:"panel-header"},[f("h3",null,"机器人")],-1)),f("div",ka,[(y(true),x(ee,null,De(r(Te),l=>(y(),x("div",{key:l.selfId,class:le(["bot-item",{active:r(Z)===l.selfId,pinned:r(U).has(l.selfId)}]),onClick:T=>r(fe)(l.selfId),onContextmenu:T=>r(q)(T,l.selfId)},[f("div",Sa,[l.avatar?(y(),Ne(r(Y),{key:0,src:l.avatar,alt:l.username,"channel-key":"bot-list"},null,8,["src","alt"])):(y(),x("div",Ba,D(l.username.charAt(0).toUpperCase()),1))]),f("div",$a,[f("div",_a,D(l.username),1),f("div",Da,D(l.platform),1)]),f("div",{class:le(["bot-status",l.status])},null,2)],42,ba))),128))])]),S(" 中间频道列表 "),f("div",Ta,[m[19]||(m[19]=f("div",{class:"panel-header"},[f("h3",null,"频道")],-1)),r(Z)?(y(),x("div",qa,[(y(true),x(ee,null,De(r(Fe),l=>(y(),x("div",{key:l.id,class:le(["channel-item",{active:r(ke)===l.id,pinned:r(ie).has(`${r(Z)}:${l.id}`)}]),"data-channel-id":l.id,onClick:T=>r(Le)(l.id),onContextmenu:T=>r(W)(T,l.id)},[f("div",Ka,[f("div",Ma,D(l.name),1),f("div",Aa,D(r(z)(l.type)),1)]),r(we)(l.id)>0?(y(),x("div",{key:0,class:le(["channel-message-count draggable-bubble",{dragging:r(B)===l.id,"will-delete":r(B)===l.id&&r(N)(l.id)>r(ae)}]),onMousedown:T=>r(X)(T,l.id),onTouchstart:T=>r(X)(T,l.id),style:st(r(qe)(l.id)),title:r(B)===l.id?r(N)(l.id)>r(ae)?"松开清理历史记录":"拖拽更远以清理历史记录":"拖拽清理历史记录"},D(r(we)(l.id)),47,za)):S("v-if",true)],42,Ua))),128))])):(y(),x("div",La," 请选择一个机器人 "))]),S(" 右侧消息区域 "),f("div",Pa,[f("div",ja,[f("h3",null,D(r(F)||"选择频道"),1)]),!r(Z)||!r(ke)?(y(),x("div",Na," 请选择机器人和频道 ")):(y(),x("div",Ra,[S(" 消息历史 "),f("div",{class:"message-history",ref_key:"messageHistory",ref:pe},[(y(true),x(ee,null,De(r(We),l=>(y(),x("div",{key:l.id,class:le(["message-item",{"bot-message":l.isBot}])},[f("div",Oa,[l.avatar?(y(),Ne(r(Y),{key:0,src:l.avatar,alt:l.username,"channel-key":r(M)},null,8,["src","alt","channel-key"])):(y(),x("div",Fa,D(l.username.charAt(0).toUpperCase()),1))]),f("div",Ha,[f("div",Xa,[f("span",Ya,D(l.username),1),f("span",Va,D(r(A)(l.timestamp)),1)]),S(" 引用消息显示 "),l.quote?(y(),x("div",Wa,[f("div",Ja,[f("div",Ga,[l.quote.user.avatar?(y(),Ne(r(Y),{key:0,src:l.quote.user.avatar,alt:l.quote.user.username,"channel-key":r(M)},null,8,["src","alt","channel-key"])):(y(),x("div",Za,D(l.quote.user.username.charAt(0).toUpperCase()),1))]),f("span",Qa,D(l.quote.user.username),1),f("span",Ea,D(r(A)(l.quote.timestamp)),1)]),f("div",en,[l.quote.elements&&l.quote.elements.length>0?(y(true),x(ee,{key:0},De(l.quote.elements,(T,Ue)=>(y(),Ne(r(ye),{key:`quote-${Ue}`,element:T,"channel-key":r(M)},null,8,["element","channel-key"]))),128)):(y(),x(ee,{key:1},[ot(D(l.quote.content),1)],64))])])):S("v-if",true),f("div",tn,[l.elements&&l.elements.length>0?(y(true),x(ee,{key:0},De(l.elements,(T,Ue)=>(y(),Ne(r(ye),{key:Ue,element:T,"channel-key":r(M)},null,8,["element","channel-key"]))),128)):(y(),x(ee,{key:1},[ot(D(l.content),1)],64))])])],2))),128))],512),S(" 悬浮的滚动到底部按钮 "),bt(f("div",{class:"floating-scroll-button",onClick:m[0]||(m[0]=(...l)=>r(_e)&&r(_e)(...l))},m[20]||(m[20]=[f("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor"},[f("path",{d:"M7 10l5 5 5-5z"})],-1)]),512),[[va,r(Re)]]),S(" 输入框 "),f("div",an,[S(" 图片预览区域 "),r(b).length>0?(y(),x("div",nn,[(y(true),x(ee,null,De(r(b),l=>(y(),x("div",{key:l.tempId,class:"image-preview-item"},[f("img",{src:l.preview,alt:l.filename,class:"preview-image"},null,8,sn),f("button",{class:"remove-image-btn",onClick:T=>r(oe)(l.tempId),title:"删除图片"},m[21]||(m[21]=[f("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"currentColor"},[f("path",{d:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"})],-1)]),8,on)]))),128))])):S("v-if",true),f("div",rn,[S(" 加号按钮 "),f("div",ln,[f("button",{class:le(["add-button",{active:r(be)}]),onClick:m[1]||(m[1]=(...l)=>r(me)&&r(me)(...l)),title:"更多操作"},m[22]||(m[22]=[f("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2.5","stroke-linecap":"round","stroke-linejoin":"round"},[f("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),f("line",{x1:"5",y1:"12",x2:"19",y2:"12"})],-1)]),2),S(" 操作菜单 "),r(be)?(y(),x("div",{key:0,class:"action-menu",onClick:m[3]||(m[3]=St(()=>{},["stop"]))},[f("button",{class:"action-menu-item",onClick:m[2]||(m[2]=(...l)=>r($e)&&r($e)(...l))},m[23]||(m[23]=[f("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[f("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),f("circle",{cx:"8.5",cy:"8.5",r:"1.5"}),f("polyline",{points:"21,15 16,10 5,21"})],-1),ot(" 上传图片 ",-1)]))])):S("v-if",true)]),bt(f("input",{"onUpdate:modelValue":m[4]||(m[4]=l=>ya(u)?u.value=l:null),type:"text",placeholder:r(Se),onKeyup:m[5]||(m[5]=ga((...l)=>r($)&&r($)(...l),["enter"])),disabled:!r(g),ref_key:"messageInput",ref:I,onPaste:m[6]||(m[6]=(...l)=>r(ve)&&r(ve)(...l)),onFocus:m[7]||(m[7]=(...l)=>r(J)&&r(J)(...l))},null,40,cn),[[pa,r(u)]]),f("button",{onClick:m[8]||(m[8]=(...l)=>r($)&&r($)(...l)),disabled:!r(He),class:le({"is-sending":r(Oe)})},D(r(Oe)?"发送中...":"发送"),11,un)]),S(" 隐藏的文件输入 "),f("input",{type:"file",ref_key:"fileInput",ref:de,onChange:m[9]||(m[9]=(...l)=>r(se)&&r(se)(...l)),accept:"image/*",multiple:"",style:{display:"none"}},null,544)])]))]),S(" 右键菜单 "),r(K).show?(y(),x("div",{key:0,class:"context-menu",style:st({left:r(K).x+"px",top:r(K).y+"px"}),onClick:m[14]||(m[14]=St(()=>{},["stop"]))},[S(" 机器人右键菜单 "),r(K).type==="bot"?(y(),x(ee,{key:0},[f("div",{class:"context-menu-item",onClick:m[10]||(m[10]=l=>r(H)(r(K).targetId))},D(r(U).has(r(K).targetId)?"取消置顶":"置顶"),1),f("div",{class:"context-menu-item danger",onClick:m[11]||(m[11]=l=>r(Be)(r(K).targetId))}," 彻底删除此机器人所有数据 ")],64)):S("v-if",true),S(" 频道右键菜单 "),r(K).type==="channel"?(y(),x(ee,{key:1},[f("div",{class:"context-menu-item",onClick:m[12]||(m[12]=l=>r(ne)(r(K).targetId))},D(r(ie).has(`${r(Z)}:${r(K).targetId}`)?"取消置顶":"置顶"),1),f("div",{class:"context-menu-item danger",onClick:m[13]||(m[13]=l=>r(he)(r(K).targetId))}," 彻底删除此频道所有数据 ")],64)):S("v-if",true)],4)):S("v-if",true),S(" 滑动指示器 "),f("div",{class:le(["swipe-indicator",{show:r(ue).show}])},D(r(ue).text),3)],38))}}),Bt=(te,ce)=>{const Y=te.__vccOpts||te;for(const[ye,Z]of ce)Y[ye]=Z;return Y},fn=Bt(dn,[["__scopeId","data-v-de93bb69"]]),hn={},mn={class:"k-icon",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none"};function vn(te,ce){return y(),x("svg",mn,ce[0]||(ce[0]=[f("path",{d:"M8 10.5H16",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),f("path",{d:"M8 14H13.5",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),f("path",{d:"M17 3.33782C15.5291 2.48697 13.8214 2 12 2C6.47715 2 2 6.47715 2 12C2 13.5997 2.37562 15.1116 3.04346 16.4525C3.22094 16.8088 3.28001 17.2161 3.17712 17.6006L2.58151 19.8267C2.32295 20.793 3.20701 21.677 4.17335 21.4185L6.39939 20.8229C6.78393 20.72 7.19121 20.7791 7.54753 20.9565C8.88837 21.6244 10.4003 22 12 22C17.5228 22 22 17.5228 22 12C22 10.1786 21.513 8.47087 20.6622 7",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1)]))}const gn=Bt(hn,[["render",vn]]);Ia.register("activity:chat",gn);const wn=te=>{te.page({name:"聊天室",path:"/chat-patch",desc:"",authority:4,icon:"activity:chat",component:Ce({setup(){return()=>h(wa("k-layout"),{},{default:()=>h(fn)})}})})};export{wn as default};
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.message-quote[data-v-95736198]{margin:8px 0;padding:8px 12px;background-color:#bebebe1a;border-left:4px solid rgba(151,152,152,.45);border-radius:6px;font-size:.9em;position:relative}.quote-indicator[data-v-95736198]{font-size:.75em;color:#007bff;font-weight:600;margin-bottom:4px;text-transform:uppercase}.quote-header[data-v-95736198]{display:flex;align-items:center;margin-bottom:4px;gap:6px}.quote-avatar[data-v-95736198]{width:20px;height:20px;border-radius:50%;overflow:hidden;flex-shrink:0}.quote-avatar img[data-v-95736198]{width:100%;height:100%;object-fit:cover}.quote-avatar .avatar-placeholder[data-v-95736198]{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background-color:#6c757d;color:#fff;font-size:10px;font-weight:700}.quote-username[data-v-95736198]{font-weight:600;color:#007bff;font-size:.85em}.quote-time[data-v-95736198]{color:#6c757d;font-size:.75em;margin-left:auto}.quote-content[data-v-95736198]{color:#7276b7;line-height:1.3;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere;-webkit-hyphens:auto;hyphens:auto}.quote-content .message-image[data-v-95736198]{max-width:min(200px,50vw);max-height:100px}.quote-content .message-image-container[data-v-95736198]{margin:2px 0}@media (prefers-color-scheme:dark){.message-quote[data-v-95736198]{background-color:#ffffff14;border-left-color:#0d6efd}.quote-content[data-v-95736198]{color:#adb5bd}.quote-username[data-v-95736198]{color:#0d6efd}}.chat-container[data-v-95736198]{display:flex;height:100vh;background:0 0;margin-left:0;width:100%;overflow:hidden;color:inherit;position:relative}.bot-list[data-v-95736198],.channel-list[data-v-95736198],.message-area[data-v-95736198]{display:flex;flex-direction:column;background:0 0;border-right:1px solid rgba(128,128,128,.2)}.bot-list[data-v-95736198]{width:250px;min-width:250px;max-width:250px;flex-shrink:0}.channel-list[data-v-95736198]{width:300px;min-width:300px;max-width:300px;flex-shrink:0}.message-area[data-v-95736198]{flex:1;border-right:none}.panel-header[data-v-95736198]{padding:16px;border-bottom:1px solid rgba(128,128,128,.2);background:0 0;display:flex;align-items:center;justify-content:space-between}.panel-header h3[data-v-95736198]{margin:0;font-size:16px;font-weight:600;color:currentColor}.back-button[data-v-95736198]{display:none;background:0 0;border:none;color:currentColor;font-size:18px;cursor:pointer;padding:4px 8px;border-radius:4px;transition:background-color .2s}.back-button[data-v-95736198]:hover{background:#8080801a}.bot-items[data-v-95736198],.channel-items[data-v-95736198]{flex:1;overflow-y:auto;max-height:calc(100vh - 60px)}.bot-item[data-v-95736198],.channel-item[data-v-95736198]{display:flex;align-items:center;padding:12px 16px;cursor:pointer;border-bottom:1px solid rgba(128,128,128,.1);transition:background-color .2s}.bot-item[data-v-95736198]:hover,.channel-item[data-v-95736198]:hover{background:#8080801a}.bot-item.active[data-v-95736198],.channel-item.active[data-v-95736198]{background:#2196f31a;border-right:3px solid #2196f3}.bot-avatar[data-v-95736198]{width:40px;height:40px;margin-right:12px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;background:#e0e0e0}.bot-avatar img[data-v-95736198]{width:100%;height:100%;object-fit:cover}.avatar-placeholder[data-v-95736198]{font-size:16px;font-weight:700;color:currentColor;opacity:.7}.bot-info[data-v-95736198]{flex:1}.bot-name[data-v-95736198]{font-weight:500;color:currentColor;margin-bottom:2px}.bot-platform[data-v-95736198]{font-size:12px;color:currentColor;opacity:.7}.bot-status[data-v-95736198]{width:8px;height:8px;border-radius:50%;margin-left:8px}.bot-status.online[data-v-95736198]{background:#4caf50}.bot-status.offline[data-v-95736198]{background:#f44336}.channel-info[data-v-95736198]{flex:1}.channel-name[data-v-95736198]{font-weight:500;color:currentColor;margin-bottom:2px}.channel-type[data-v-95736198]{font-size:12px;color:currentColor;opacity:.7}.channel-message-count[data-v-95736198]{background:#2196f3;color:#fff;font-size:12px;padding:2px 6px;border-radius:10px;min-width:18px;text-align:center;position:relative;transition:all .2s ease}.channel-message-count.draggable-bubble[data-v-95736198]{cursor:grab;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.channel-message-count.draggable-bubble[data-v-95736198]:hover{background:#1976d2;transform:scale(1.1);box-shadow:0 2px 8px #2196f34d}.channel-message-count.draggable-bubble.dragging[data-v-95736198],.channel-message-count.draggable-bubble[data-v-95736198]:active{cursor:grabbing;background:#1565c0;box-shadow:0 4px 12px #2196f366}.dragging-clone[data-v-95736198]{position:fixed;z-index:1000;pointer-events:none;transition:none;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#2196f3;color:#fff;font-size:12px;padding:2px 6px;border-radius:10px;min-width:18px;text-align:center;box-shadow:0 4px 12px #2196f366}.dragging-clone.will-delete[data-v-95736198]{background:#f44336!important;animation:shake-95736198 .3s ease-in-out infinite}@keyframes pulseThreshold-95736198{0%,to{opacity:.4;transform:scale(.9);border-color:#f4433699;box-shadow:0 0 15px #f4433633}50%{opacity:.8;transform:scale(1.1);border-color:#f44336;box-shadow:0 0 25px #f4433666}}@keyframes menuSlideIn-95736198{0%{transform:translateY(8px);opacity:0}to{transform:translateY(0);opacity:1}}.message-content[data-v-95736198]{display:flex;flex-direction:column;height:calc(100vh - 60px);overflow:hidden;position:relative}.message-history[data-v-95736198]{flex:1;overflow-y:auto;padding:16px 16px 8px;max-height:calc(100vh - 200px)}.message-item[data-v-95736198]{display:flex;margin-bottom:16px;padding:8px;border-radius:8px;transition:background-color .3s ease}.message-item[data-v-95736198]:hover{background-color:#8080801a}.message-item.new-message[data-v-95736198]{background-color:#4caf5033;animation:highlight-95736198 2s ease-out}.message-item.bot-message[data-v-95736198]{flex-direction:row-reverse;justify-content:flex-start}.message-item.bot-message .message-avatar[data-v-95736198]{margin-right:0;margin-left:12px}.message-item.bot-message .message-content-wrapper[data-v-95736198]{display:flex;flex-direction:column;align-items:flex-end}.message-item.bot-message .message-header[data-v-95736198]{display:flex;align-items:center;justify-content:flex-end;margin-bottom:4px}.message-item.bot-message .message-username[data-v-95736198]{margin-right:0;margin-left:8px;order:2}.message-item.bot-message .message-time[data-v-95736198]{order:1}.message-item.bot-message .message-text[data-v-95736198]{background-color:#2196f31a;padding:8px 12px;border-radius:12px 12px 4px;display:inline-block;max-width:80%;text-align:left;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}@keyframes highlight-95736198{0%{background-color:#4caf504d}to{background-color:transparent}}.message-avatar[data-v-95736198]{width:32px;height:32px;margin-right:12px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;background:#e0e0e0;flex-shrink:0}.message-avatar img[data-v-95736198]{width:100%;height:100%;object-fit:cover}.message-avatar .avatar-placeholder[data-v-95736198]{font-size:12px;font-weight:700;color:currentColor;opacity:.7}.message-content-wrapper[data-v-95736198]{flex:1}.message-header[data-v-95736198]{display:flex;align-items:center;margin-bottom:4px}.message-username[data-v-95736198]{font-weight:500;color:currentColor;margin-right:8px}.message-time[data-v-95736198]{font-size:12px;color:currentColor;opacity:.5}.message-text[data-v-95736198]{color:currentColor;line-height:1.4;word-wrap:break-word;word-break:break-all;white-space:pre-wrap;max-width:100%;overflow-wrap:anywhere;-webkit-hyphens:auto;hyphens:auto}.message-item:not(.bot-message) .message-text[data-v-95736198]{background-color:#8080801a;padding:8px 12px;border-radius:12px 12px 12px 4px;display:inline-block;max-width:80%;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}.message-input[data-v-95736198]{display:flex;flex-direction:column;padding:12px 16px 16px;border-top:1px solid rgba(128,128,128,.2);background:0 0;flex-shrink:0;position:sticky;bottom:0;margin-top:-10px}.input-row[data-v-95736198]{display:flex;gap:8px;align-items:center}.floating-scroll-button[data-v-95736198]{position:absolute;right:24px;bottom:18%;width:48px;height:48px;background:#2196f3;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 12px #2196f34d;color:#fff;transition:all .3s ease;z-index:100;border:2px solid rgba(255,255,255,.2)}.floating-scroll-button[data-v-95736198]:hover{background:#1976d2;transform:scale(1.1);box-shadow:0 6px 16px #2196f366}.floating-scroll-button[data-v-95736198]:active{transform:scale(.95)}.input-row button[data-v-95736198]{padding:8px 16px;background:#2196f3;color:#fff;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s}.message-image-container[data-v-95736198]{margin:8px 0;max-width:100%;display:block}.message-image[data-v-95736198]{border-radius:8px;object-fit:contain;display:block;cursor:pointer;transition:transform .2s ease;max-width:min(400px,66.67vw);max-height:200px;width:auto;height:auto}.message-image-loading[data-v-95736198]{display:inline-block;padding:8px 12px;background:#8080801a;border-radius:4px;color:currentColor;opacity:.7;font-size:12px}.message-image-error[data-v-95736198]{display:inline-block;padding:8px 12px;background:#f443361a;border:1px solid rgba(244,67,54,.3);border-radius:4px;color:#f44336;font-size:12px;max-width:300px;word-break:break-word}.message-paragraph[data-v-95736198]{display:block;margin-bottom:4px}.message-paragraph[data-v-95736198]:last-child{margin-bottom:0}.forward-message-container[data-v-95736198]{border:1px solid #fff;border-radius:8px;margin:4px 0;overflow:hidden;background:#f9f9f900}.forward-message-preview[data-v-95736198]{padding:12px;cursor:pointer;transition:background-color .2s}.forward-message-preview[data-v-95736198]:hover{background:#f0f0f0}.forward-message-title[data-v-95736198]{font-weight:600;color:#333;margin-bottom:8px;font-size:14px}.forward-message-preview-item[data-v-95736198]{color:#666;font-size:13px;margin:2px 0;line-height:1.4;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}.forward-message-footer[data-v-95736198]{display:flex;justify-content:space-between;align-items:center;margin-top:8px;padding-top:8px;border-top:1px solid #e8e8e8}.forward-message-count[data-v-95736198]{color:#2196f3;font-size:12px}.forward-message-toggle[data-v-95736198]{color:#666;font-size:12px}.forward-message-expanded[data-v-95736198]{border-top:1px solid #e0e0e0;background:#fff;max-height:400px;overflow-y:auto}.forwarded-message-item[data-v-95736198]{padding:12px;border-bottom:1px solid #f0f0f0}.forwarded-message-item[data-v-95736198]:last-child{border-bottom:none}.forwarded-message-header[data-v-95736198]{display:flex;align-items:center;margin-bottom:6px}.forwarded-message-nickname[data-v-95736198]{font-weight:600;color:#333;font-size:13px}.forwarded-message-userid[data-v-95736198]{color:#999;font-size:11px;margin-left:6px}.forwarded-message-content[data-v-95736198]{color:#555;font-size:13px;line-height:1.4;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}.message-at[data-v-95736198]{background:#2196f31a;color:#2196f3;padding:2px 4px;border-radius:3px;font-weight:500;cursor:pointer}.message-unknown[data-v-95736198]{background:#ff98001a;color:#ff9800;padding:2px 4px;border-radius:3px;font-style:italic;cursor:help}.input-row input[data-v-95736198]{flex:1;min-width:0;padding:8px 12px;border:1px solid rgba(128,128,128,.3);border-radius:4px;outline:0;background:0 0;color:currentColor}.input-row input[data-v-95736198]:focus{border-color:#2196f3;box-shadow:0 0 0 2px #2196f333}.input-row input[data-v-95736198]::placeholder{color:currentColor;opacity:.5}.input-row button[data-v-95736198]{padding:8px 16px;background:#2196f3;color:#fff;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;flex-shrink:0;white-space:nowrap}.input-row button[data-v-95736198]:hover:not(:disabled){background:#1976d2}.input-row button[data-v-95736198]:disabled{background:#8080804d;cursor:not-allowed}.input-row button.is-sending[data-v-95736198]{background:#ffc107!important;color:#333!important;cursor:default!important}.message-input .input-row button.is-sending[data-v-95736198]{background:#ffc107!important;color:#333!important;cursor:default!important;border-color:#ffc107!important}.empty-state[data-v-95736198]{display:flex;align-items:center;justify-content:center;height:100%;color:currentColor;opacity:.5;font-size:14px}.message-text-content[data-v-95736198]{display:inline;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere;-webkit-hyphens:auto;hyphens:auto}.message-image-container[data-v-95736198]{display:block;margin:4px 0}.message-image[data-v-95736198]{border-radius:8px;margin:4px 0;display:block;cursor:pointer;transition:transform .2s ease;object-fit:contain;background:#8080801a}.message-image[data-v-95736198]:hover{transform:scale(1.02)}.message-image-loading[data-v-95736198]{height:60px;width:200px;border-radius:8px;margin:4px 0;display:flex;align-items:center;justify-content:center;background:#8080801a;color:currentColor;opacity:.7;font-size:14px;border:1px dashed rgba(128,128,128,.3)}.message-image-error[data-v-95736198]{min-height:60px;width:200px;border-radius:8px;margin:4px 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#8080801a;color:currentColor;opacity:.7;font-size:14px;border:1px dashed rgba(128,128,128,.3);padding:8px;text-align:center}.message-at[data-v-95736198]{background:#2196f31a;color:#2196f3;padding:2px 6px;border-radius:4px;font-weight:500;cursor:pointer;display:inline-block;margin:0 2px}.message-at[data-v-95736198]:hover{background:#2196f333}.message-unknown[data-v-95736198]{background:#ff98001a;color:#ff9800;padding:2px 6px;border-radius:4px;font-size:12px;display:inline-block;margin:0 2px;cursor:help}@keyframes pulse-95736198{0%,to{transform:translate(-50%,-50%) scale(1)}50%{transform:translate(-50%,-50%) scale(1.1)}}.channel-message-count.will-delete[data-v-95736198]{background:#f44336!important;animation:shake-95736198 .3s ease-in-out infinite}@keyframes shake-95736198{0%,to{transform:translate(0)}25%{transform:translate(-2px)}75%{transform:translate(2px)}}body.dragging-bubble-global[data-v-95736198]{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:grabbing}.drag-threshold-circle[data-v-95736198]{position:fixed;pointer-events:none;border:3px dashed rgba(244,67,54,.8);border-radius:50%;z-index:999;background:#f443361a;box-shadow:0 0 20px #f443364d;animation:pulseThreshold-95736198 1.5s ease-in-out infinite}.context-menu[data-v-95736198]{position:fixed;background:#ffffffa6;border:1px solid rgba(0,0,0,.1);border-radius:8px;box-shadow:0 8px 32px #00000026;z-index:10000;min-width:180px;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);overflow:hidden}.context-menu-item[data-v-95736198]{padding:12px 16px;cursor:pointer;color:#333;font-size:14px;font-weight:500;transition:all .2s ease;border-bottom:1px solid rgba(0,0,0,.08);position:relative}.context-menu-item[data-v-95736198]:last-child{border-bottom:none}.context-menu-item[data-v-95736198]:hover{background:#2196f31a;color:#1976d2;transform:translate(2px)}.context-menu-item.danger[data-v-95736198]{color:#d32f2f}.context-menu-item.danger[data-v-95736198]:hover{background:#f443361a;color:#c62828}.bot-item.pinned[data-v-95736198],.channel-item.pinned[data-v-95736198]{background:#ffc1071a;border-left:3px solid #ffc107}.bot-item.pinned[data-v-95736198]:before,.channel-item.pinned[data-v-95736198]:before{content:"📌";position:absolute;left:4px;top:50%;transform:translateY(-50%);font-size:12px;opacity:.7}.bot-item.pinned[data-v-95736198],.channel-item.pinned[data-v-95736198]{position:relative;padding-left:24px}@media (prefers-color-scheme:dark){.context-menu[data-v-95736198]{background:#ffffff26;border-color:#fff3;box-shadow:0 8px 32px #0006}.context-menu-item[data-v-95736198]{color:#fff;border-bottom-color:#ffffff1a}.context-menu-item[data-v-95736198]:hover{background:#2196f333;color:#64b5f6}.context-menu-item.danger[data-v-95736198]{color:#ff8a80}.context-menu-item.danger[data-v-95736198]:hover{background:#f4433633;color:#ffab91}.bot-item.pinned[data-v-95736198],.channel-item.pinned[data-v-95736198]{background:#ffc10726}}.message-share-card[data-v-95736198]{display:inline-block;width:75px;margin:8px 0;border:1px solid rgba(128,128,128,.2);border-radius:12px;background:#ffffff0d;transition:all .3s ease;cursor:pointer;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.message-share-card[data-v-95736198]:hover{transform:translateY(-2px);box-shadow:0 8px 24px #00000026;border-color:#2196f34d}.share-card-preview[data-v-95736198]{width:100%;position:relative;display:flex;align-items:center;justify-content:center;padding:4px;border-radius:12px 12px 0 0}.share-card-image[data-v-95736198]{max-width:calc(100% - 8px);width:auto;height:auto;object-fit:contain;transition:transform .3s ease;display:block;border-radius:4px}.message-share-card:hover .share-card-image[data-v-95736198]{transform:scale(1.05)}.share-card-content[data-v-95736198]{padding:8px}.share-card-header[data-v-95736198]{display:flex;align-items:center;margin-bottom:12px;gap:12px}.share-card-icon[data-v-95736198]{width:32px;height:32px;border-radius:8px;object-fit:cover;flex-shrink:0}.share-card-app-info[data-v-95736198]{flex:1;min-width:0}.share-card-app-name[data-v-95736198]{font-size:12px;color:currentColor;opacity:.7;margin-bottom:2px;font-weight:500}.share-card-title[data-v-95736198]{font-size:10px;font-weight:600;color:currentColor;line-height:1.2;word-wrap:break-word;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden}.share-card-desc[data-v-95736198]{font-size:14px;color:currentColor;opacity:.8;line-height:1.4;margin-bottom:12px;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;word-wrap:break-word}.share-card-link-hint[data-v-95736198]{font-size:12px;color:#2196f3;font-weight:500;display:flex;align-items:center;gap:4px}.share-card-link-hint[data-v-95736198]:after{content:"→";transition:transform .2s ease}.message-share-card:hover .share-card-link-hint[data-v-95736198]:after{transform:translate(2px)}.message-json-error[data-v-95736198],.message-json-raw[data-v-95736198]{display:inline-block;margin:8px 0;max-width:400px}.json-error-text[data-v-95736198]{color:#f44336;font-size:14px;font-weight:500}.json-label[data-v-95736198]{color:currentColor;opacity:.7;font-size:12px;font-weight:500;margin-bottom:8px}.json-raw-data[data-v-95736198]{margin-top:8px}.json-raw-data summary[data-v-95736198]{cursor:pointer;font-size:12px;color:#2196f3;font-weight:500;padding:4px 8px;border-radius:4px;background:#2196f31a;display:inline-block;transition:background-color .2s ease}.json-raw-data summary[data-v-95736198]:hover{background:#2196f333}.json-raw-content[data-v-95736198]{margin-top:8px;padding:12px;background:#8080801a;border-radius:8px;font-family:Courier New,monospace;font-size:12px;color:currentColor;opacity:.8;white-space:pre-wrap;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere;max-height:200px;overflow-y:auto;border:1px solid rgba(128,128,128,.2)}@media (prefers-color-scheme:dark){.message-share-card[data-v-95736198]{background:#ffffff14;border-color:#ffffff26}.message-share-card[data-v-95736198]:hover{border-color:#2196f380;box-shadow:0 8px 24px #0000004d}.json-raw-content[data-v-95736198]{background:#ffffff0d;border-color:#ffffff1a}}@media (max-width:768px){.chat-container[data-v-95736198]{position:relative;height:100vh;height:100dvh}.bot-list[data-v-95736198],.channel-list[data-v-95736198],.message-area[data-v-95736198]{position:absolute;top:0;left:0;width:100%;height:100%;transition:transform .3s ease;z-index:1}.bot-list[data-v-95736198]{transform:translate(0);z-index:3}.channel-list[data-v-95736198]{transform:translate(100%);z-index:2}.message-area[data-v-95736198]{transform:translate(200%);z-index:1}.chat-container.show-channels .bot-list[data-v-95736198]{transform:translate(-100%)}.chat-container.show-channels .channel-list[data-v-95736198]{transform:translate(0);z-index:3}.chat-container.show-channels .message-area[data-v-95736198]{transform:translate(100%)}.chat-container.show-messages .bot-list[data-v-95736198]{transform:translate(-200%)}.chat-container.show-messages .channel-list[data-v-95736198]{transform:translate(-100%)}.chat-container.show-messages .message-area[data-v-95736198]{transform:translate(0);z-index:3}.back-button[data-v-95736198]{display:none!important}.panel-header[data-v-95736198]{flex-direction:row-reverse;position:sticky;top:0;z-index:5;background:inherit}.panel-header h3[data-v-95736198]{text-align:right}.floating-scroll-button[data-v-95736198]{right:16px;bottom:calc(90px + env(safe-area-inset-bottom,0px));width:40px;height:40px;transition:bottom .3s ease}.message-input[data-v-95736198]{padding:8px 12px calc(12px + env(safe-area-inset-bottom,0px)) 12px;position:fixed;bottom:20px;left:0;right:0;background:inherit;border-top:1px solid rgba(128,128,128,.2);z-index:10;min-height:calc(60px + env(safe-area-inset-bottom,0px));transition:transform .3s ease;transform:translateZ(0)}.input-row input[data-v-95736198]{font-size:16px;padding:10px 12px}.input-row button[data-v-95736198]{padding:10px 16px;font-size:16px}.message-history[data-v-95736198]{padding:12px;max-height:calc(100vh - 140px - env(safe-area-inset-bottom,0px));max-height:calc(100dvh - 140px - env(safe-area-inset-bottom,0px));padding-bottom:calc(80px + env(safe-area-inset-bottom,0px));overflow-y:auto;-webkit-overflow-scrolling:touch;transition:max-height .3s ease}.message-item[data-v-95736198]{margin-bottom:12px;padding:6px}.message-text[data-v-95736198]{max-width:90%!important}.message-avatar[data-v-95736198]{width:28px;height:28px;margin-right:8px}.message-item.bot-message .message-avatar[data-v-95736198]{margin-left:8px}.message-image[data-v-95736198]{max-width:min(280px,66.67vw);max-height:160px}.quote-content .message-image[data-v-95736198]{max-width:min(150px,50vw);max-height:80px}.context-menu[data-v-95736198]{min-width:160px;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}.context-menu-item[data-v-95736198]{padding:14px 16px;font-size:16px}.bot-item[data-v-95736198],.channel-item[data-v-95736198]{padding:14px 16px}.bot-avatar[data-v-95736198]{width:36px;height:36px;margin-right:10px}.bot-name[data-v-95736198],.channel-name[data-v-95736198]{font-size:15px}.bot-platform[data-v-95736198],.channel-type[data-v-95736198]{font-size:13px}}@media (min-width:769px) and (max-width:1024px){.bot-list[data-v-95736198]{width:220px;min-width:220px;max-width:220px}.channel-list[data-v-95736198]{width:280px;min-width:280px;max-width:280px}.message-image[data-v-95736198]{max-width:min(350px,66.67vw);max-height:180px}}.chat-container.swiping[data-v-95736198]{overflow:hidden}.bot-list.swiping[data-v-95736198],.channel-list.swiping[data-v-95736198],.message-area.swiping[data-v-95736198]{transition:none!important}.swipe-indicator[data-v-95736198]{position:fixed;top:50%;left:20px;transform:translateY(-50%);background:#2196f3cc;color:#fff;padding:8px 12px;border-radius:20px;font-size:14px;z-index:1000;opacity:0;transition:opacity .2s ease;pointer-events:none;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.swipe-indicator.show[data-v-95736198]{opacity:1}.message-area .message-content[data-v-95736198]{padding-bottom:80px}.image-preview-container[data-v-95736198]{display:flex;flex-wrap:wrap;gap:8px;padding:8px 0;margin-bottom:8px;border-bottom:1px solid rgba(128,128,128,.1)}.image-preview-item[data-v-95736198]{position:relative;width:60px;height:60px;border-radius:8px;overflow:hidden;border:2px solid rgba(33,150,243,.3);background:#8080801a}.preview-image[data-v-95736198]{width:100%;height:100%;object-fit:cover;display:block}.remove-image-btn[data-v-95736198]{position:absolute;top:-6px;right:-6px;width:20px;height:20px;border-radius:50%;background:#f44336;color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:12px;transition:all .2s ease;box-shadow:0 2px 4px #0003}.remove-image-btn[data-v-95736198]:hover{background:#d32f2f;transform:scale(1.1)}.input-actions[data-v-95736198]{position:relative;margin-right:8px}.add-button[data-v-95736198]{width:36px;height:36px;border-radius:12px;background:linear-gradient(135deg,#667eea 0,#764ba2);border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s cubic-bezier(.4,0,.2,1);flex-shrink:0;box-shadow:0 2px 8px #667eea4d;position:relative;overflow:hidden}.add-button[data-v-95736198]:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(135deg,#fff3 0,#ffffff1a);border-radius:12px;opacity:0;transition:opacity .3s ease}.add-button[data-v-95736198]:hover{transform:translateY(-2px) scale(1.05);box-shadow:0 4px 16px #667eea66}.add-button[data-v-95736198]:hover:before{opacity:1}.add-button.active[data-v-95736198]{background:linear-gradient(135deg,#f093fb 0,#f5576c);transform:translateY(-2px) scale(1.05) rotate(45deg);box-shadow:0 4px 16px #f5576c66}.add-button[data-v-95736198]:active{transform:translateY(0) scale(.98);transition:all .1s ease}.action-menu[data-v-95736198]{position:absolute;bottom:100%;left:0;margin-bottom:12px;background:#fffffffa;border:none;border-radius:16px;box-shadow:0 8px 32px #0000001f,0 2px 8px #00000014;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);overflow:hidden;z-index:1000;min-width:140px;transform:translateY(8px);opacity:0;animation:menuSlideIn-95736198 .3s cubic-bezier(.4,0,.2,1) forwards}.action-menu-item[data-v-95736198]{display:flex;align-items:center;gap:12px;padding:14px 18px;background:0 0;border:none;color:#333;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);width:100%;text-align:left;position:relative}.action-menu-item[data-v-95736198]:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(135deg,#667eea 0,#764ba2);transform:scaleY(0);transition:transform .2s cubic-bezier(.4,0,.2,1)}.action-menu-item[data-v-95736198]:hover{background:linear-gradient(90deg,#667eea14 0,#764ba214);color:#667eea;transform:translate(4px)}.action-menu-item[data-v-95736198]:hover:before{transform:scaleY(1)}.action-menu-item svg[data-v-95736198]{flex-shrink:0}@media (prefers-color-scheme:dark){.action-menu[data-v-95736198]{background:#1e1e1efa;box-shadow:0 8px 32px #0000004d,0 2px 8px #0003}.action-menu-item[data-v-95736198]{color:#fff}.action-menu-item[data-v-95736198]:before{background:linear-gradient(135deg,#4facfe 0,#00f2fe)}.action-menu-item[data-v-95736198]:hover{background:linear-gradient(90deg,#4facfe1f 0,#00f2fe1f);color:#4facfe}.add-button[data-v-95736198]{background:linear-gradient(135deg,#4facfe 0,#00f2fe);box-shadow:0 2px 8px #4facfe4d}.add-button[data-v-95736198]:hover{box-shadow:0 4px 16px #4facfe66}.add-button.active[data-v-95736198]{background:linear-gradient(135deg,#fa709a 0,#fee140);box-shadow:0 4px 16px #fa709a66}.image-preview-item[data-v-95736198]{border-color:#64b5f680;background:#ffffff0d}}@media (max-width:768px){.image-preview-container[data-v-95736198]{padding:6px 0;margin-bottom:6px}.image-preview-item[data-v-95736198]{width:50px;height:50px}.add-button[data-v-95736198]{width:32px;height:32px;border-radius:10px}.action-menu[data-v-95736198]{min-width:100px}.action-menu-item[data-v-95736198]{padding:10px 12px;font-size:13px}.remove-image-btn[data-v-95736198]{width:18px;height:18px;top:-5px;right:-5px}}.message-history[data-v-95736198]::-webkit-scrollbar{width:6px}.message-history[data-v-95736198]::-webkit-scrollbar-track{background:0 0}.message-history[data-v-95736198]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.message-history[data-v-95736198]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.bot-items[data-v-95736198]::-webkit-scrollbar{width:6px}.bot-items[data-v-95736198]::-webkit-scrollbar-track{background:0 0}.bot-items[data-v-95736198]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.bot-items[data-v-95736198]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.channel-items[data-v-95736198]::-webkit-scrollbar{width:6px}.channel-items[data-v-95736198]::-webkit-scrollbar-track{background:0 0}.channel-items[data-v-95736198]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.channel-items[data-v-95736198]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.forward-message-expanded[data-v-95736198]::-webkit-scrollbar{width:6px}.forward-message-expanded[data-v-95736198]::-webkit-scrollbar-track{background:0 0}.forward-message-expanded[data-v-95736198]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.forward-message-expanded[data-v-95736198]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.json-raw-content[data-v-95736198]::-webkit-scrollbar{width:6px}.json-raw-content[data-v-95736198]::-webkit-scrollbar-track{background:0 0}.json-raw-content[data-v-95736198]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.json-raw-content[data-v-95736198]::-webkit-scrollbar-thumb:hover{background-color:#90939980}@media (prefers-color-scheme:dark){.bot-items[data-v-95736198]::-webkit-scrollbar-thumb,.channel-items[data-v-95736198]::-webkit-scrollbar-thumb,.forward-message-expanded[data-v-95736198]::-webkit-scrollbar-thumb,.json-raw-content[data-v-95736198]::-webkit-scrollbar-thumb,.message-history[data-v-95736198]::-webkit-scrollbar-thumb{background-color:#fff3}.bot-items[data-v-95736198]::-webkit-scrollbar-thumb:hover,.channel-items[data-v-95736198]::-webkit-scrollbar-thumb:hover,.forward-message-expanded[data-v-95736198]::-webkit-scrollbar-thumb:hover,.json-raw-content[data-v-95736198]::-webkit-scrollbar-thumb:hover,.message-history[data-v-95736198]::-webkit-scrollbar-thumb:hover{background-color:#fff6}}.layout-iframe{width:100%;height:100%;border:none}
|
|
1
|
+
.message-quote[data-v-de93bb69]{margin:8px 0;padding:8px 12px;background-color:#bebebe1a;border-left:4px solid rgba(151,152,152,.45);border-radius:6px;font-size:.9em;position:relative}.quote-indicator[data-v-de93bb69]{font-size:.75em;color:#007bff;font-weight:600;margin-bottom:4px;text-transform:uppercase}.quote-header[data-v-de93bb69]{display:flex;align-items:center;margin-bottom:4px;gap:6px}.quote-avatar[data-v-de93bb69]{width:20px;height:20px;border-radius:50%;overflow:hidden;flex-shrink:0}.quote-avatar img[data-v-de93bb69]{width:100%;height:100%;object-fit:cover}.quote-avatar .avatar-placeholder[data-v-de93bb69]{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background-color:#6c757d;color:#fff;font-size:10px;font-weight:700}.quote-username[data-v-de93bb69]{font-weight:600;color:#007bff;font-size:.85em}.quote-time[data-v-de93bb69]{color:#6c757d;font-size:.75em;margin-left:auto}.quote-content[data-v-de93bb69]{color:#7276b7;line-height:1.3;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere;-webkit-hyphens:auto;hyphens:auto}.quote-content .message-image[data-v-de93bb69]{max-width:min(200px,50vw);max-height:100px}.quote-content .message-image-container[data-v-de93bb69]{margin:2px 0}@media (prefers-color-scheme:dark){.message-quote[data-v-de93bb69]{background-color:#ffffff14;border-left-color:#0d6efd}.quote-content[data-v-de93bb69]{color:#adb5bd}.quote-username[data-v-de93bb69]{color:#0d6efd}}.chat-container[data-v-de93bb69]{display:flex;height:100vh;background:0 0;margin-left:0;width:100%;overflow:hidden;color:inherit;position:relative}.bot-list[data-v-de93bb69],.channel-list[data-v-de93bb69],.message-area[data-v-de93bb69]{display:flex;flex-direction:column;background:0 0;border-right:1px solid rgba(128,128,128,.2)}.bot-list[data-v-de93bb69]{width:250px;min-width:250px;max-width:250px;flex-shrink:0}.channel-list[data-v-de93bb69]{width:300px;min-width:300px;max-width:300px;flex-shrink:0}.message-area[data-v-de93bb69]{flex:1;border-right:none}.panel-header[data-v-de93bb69]{padding:16px;border-bottom:1px solid rgba(128,128,128,.2);background:0 0;display:flex;align-items:center;justify-content:space-between}.panel-header h3[data-v-de93bb69]{margin:0;font-size:16px;font-weight:600;color:currentColor}.back-button[data-v-de93bb69]{display:none;background:0 0;border:none;color:currentColor;font-size:18px;cursor:pointer;padding:4px 8px;border-radius:4px;transition:background-color .2s}.back-button[data-v-de93bb69]:hover{background:#8080801a}.bot-items[data-v-de93bb69],.channel-items[data-v-de93bb69]{flex:1;overflow-y:auto;max-height:calc(100vh - 60px)}.bot-item[data-v-de93bb69],.channel-item[data-v-de93bb69]{display:flex;align-items:center;padding:12px 16px;cursor:pointer;border-bottom:1px solid rgba(128,128,128,.1);transition:background-color .2s}.bot-item[data-v-de93bb69]:hover,.channel-item[data-v-de93bb69]:hover{background:#8080801a}.bot-item.active[data-v-de93bb69],.channel-item.active[data-v-de93bb69]{background:#2196f31a;border-right:3px solid #2196f3}.bot-avatar[data-v-de93bb69]{width:40px;height:40px;margin-right:12px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;background:#e0e0e0}.bot-avatar img[data-v-de93bb69]{width:100%;height:100%;object-fit:cover}.avatar-placeholder[data-v-de93bb69]{font-size:16px;font-weight:700;color:currentColor;opacity:.7}.bot-info[data-v-de93bb69]{flex:1}.bot-name[data-v-de93bb69]{font-weight:500;color:currentColor;margin-bottom:2px}.bot-platform[data-v-de93bb69]{font-size:12px;color:currentColor;opacity:.7}.bot-status[data-v-de93bb69]{width:8px;height:8px;border-radius:50%;margin-left:8px}.bot-status.online[data-v-de93bb69]{background:#4caf50}.bot-status.offline[data-v-de93bb69]{background:#f44336}.channel-info[data-v-de93bb69]{flex:1}.channel-name[data-v-de93bb69]{font-weight:500;color:currentColor;margin-bottom:2px}.channel-type[data-v-de93bb69]{font-size:12px;color:currentColor;opacity:.7}.channel-message-count[data-v-de93bb69]{background:#2196f3;color:#fff;font-size:12px;padding:2px 6px;border-radius:10px;min-width:18px;text-align:center;position:relative;transition:all .2s ease}.channel-message-count.draggable-bubble[data-v-de93bb69]{cursor:grab;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.channel-message-count.draggable-bubble[data-v-de93bb69]:hover{background:#1976d2;transform:scale(1.1);box-shadow:0 2px 8px #2196f34d}.channel-message-count.draggable-bubble.dragging[data-v-de93bb69],.channel-message-count.draggable-bubble[data-v-de93bb69]:active{cursor:grabbing;background:#1565c0;box-shadow:0 4px 12px #2196f366}.dragging-clone[data-v-de93bb69]{position:fixed;z-index:1000;pointer-events:none;transition:none;box-sizing:border-box;display:flex;align-items:center;justify-content:center;background:#2196f3;color:#fff;font-size:12px;padding:2px 6px;border-radius:10px;min-width:18px;text-align:center;box-shadow:0 4px 12px #2196f366}.dragging-clone.will-delete[data-v-de93bb69]{background:#f44336!important;animation:shake-de93bb69 .3s ease-in-out infinite}@keyframes pulseThreshold-de93bb69{0%,to{opacity:.4;transform:scale(.9);border-color:#f4433699;box-shadow:0 0 15px #f4433633}50%{opacity:.8;transform:scale(1.1);border-color:#f44336;box-shadow:0 0 25px #f4433666}}@keyframes menuSlideIn-de93bb69{0%{transform:translateY(8px);opacity:0}to{transform:translateY(0);opacity:1}}.message-content[data-v-de93bb69]{display:flex;flex-direction:column;height:calc(100vh - 60px);overflow:hidden;position:relative}.message-history[data-v-de93bb69]{flex:1;overflow-y:auto;padding:16px 16px 8px;max-height:calc(100vh - 200px)}.message-item[data-v-de93bb69]{display:flex;margin-bottom:16px;padding:8px;border-radius:8px;transition:background-color .3s ease}.message-item[data-v-de93bb69]:hover{background-color:#8080801a}.message-item.new-message[data-v-de93bb69]{background-color:#4caf5033;animation:highlight-de93bb69 2s ease-out}.message-item.bot-message[data-v-de93bb69]{flex-direction:row-reverse;justify-content:flex-start}.message-item.bot-message .message-avatar[data-v-de93bb69]{margin-right:0;margin-left:12px}.message-item.bot-message .message-content-wrapper[data-v-de93bb69]{display:flex;flex-direction:column;align-items:flex-end}.message-item.bot-message .message-header[data-v-de93bb69]{display:flex;align-items:center;justify-content:flex-end;margin-bottom:4px}.message-item.bot-message .message-username[data-v-de93bb69]{margin-right:0;margin-left:8px;order:2}.message-item.bot-message .message-time[data-v-de93bb69]{order:1}.message-item.bot-message .message-text[data-v-de93bb69]{background-color:#2196f31a;padding:8px 12px;border-radius:12px 12px 4px;display:inline-block;max-width:80%;text-align:left;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}@keyframes highlight-de93bb69{0%{background-color:#4caf504d}to{background-color:transparent}}.message-avatar[data-v-de93bb69]{width:32px;height:32px;margin-right:12px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;background:#e0e0e0;flex-shrink:0}.message-avatar img[data-v-de93bb69]{width:100%;height:100%;object-fit:cover}.message-avatar .avatar-placeholder[data-v-de93bb69]{font-size:12px;font-weight:700;color:currentColor;opacity:.7}.message-content-wrapper[data-v-de93bb69]{flex:1}.message-header[data-v-de93bb69]{display:flex;align-items:center;margin-bottom:4px}.message-username[data-v-de93bb69]{font-weight:500;color:currentColor;margin-right:8px}.message-time[data-v-de93bb69]{font-size:12px;color:currentColor;opacity:.5}.message-text[data-v-de93bb69]{color:currentColor;line-height:1.4;word-wrap:break-word;word-break:break-all;white-space:pre-wrap;max-width:100%;overflow-wrap:anywhere;-webkit-hyphens:auto;hyphens:auto}.message-item:not(.bot-message) .message-text[data-v-de93bb69]{background-color:#8080801a;padding:8px 12px;border-radius:12px 12px 12px 4px;display:inline-block;max-width:80%;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}.message-input[data-v-de93bb69]{display:flex;flex-direction:column;padding:12px 16px 16px;border-top:1px solid rgba(128,128,128,.2);background:0 0;flex-shrink:0;position:sticky;bottom:0;margin-top:-10px}.input-row[data-v-de93bb69]{display:flex;gap:8px;align-items:center}.floating-scroll-button[data-v-de93bb69]{position:absolute;right:24px;bottom:18%;width:48px;height:48px;background:#2196f3;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 12px #2196f34d;color:#fff;transition:all .3s ease;z-index:100;border:2px solid rgba(255,255,255,.2)}.floating-scroll-button[data-v-de93bb69]:hover{background:#1976d2;transform:scale(1.1);box-shadow:0 6px 16px #2196f366}.floating-scroll-button[data-v-de93bb69]:active{transform:scale(.95)}.input-row button[data-v-de93bb69]{padding:8px 16px;background:#2196f3;color:#fff;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s}.message-image-container[data-v-de93bb69]{margin:8px 0;max-width:100%;display:block}.message-image[data-v-de93bb69]{border-radius:8px;object-fit:contain;display:block;cursor:pointer;transition:transform .2s ease;max-width:min(400px,66.67vw);max-height:200px;width:auto;height:auto}.message-image-loading[data-v-de93bb69]{display:inline-block;padding:8px 12px;background:#8080801a;border-radius:4px;color:currentColor;opacity:.7;font-size:12px}.message-image-error[data-v-de93bb69]{display:inline-block;padding:8px 12px;background:#f443361a;border:1px solid rgba(244,67,54,.3);border-radius:4px;color:#f44336;font-size:12px;max-width:300px;word-break:break-word}.message-paragraph[data-v-de93bb69]{display:block;margin-bottom:4px}.message-paragraph[data-v-de93bb69]:last-child{margin-bottom:0}.forward-message-container[data-v-de93bb69]{border:1px solid #fff;border-radius:8px;margin:4px 0;overflow:hidden;background:#f9f9f900}.forward-message-preview[data-v-de93bb69]{padding:12px;cursor:pointer;transition:background-color .2s}.forward-message-preview[data-v-de93bb69]:hover{background:#f0f0f0}.forward-message-title[data-v-de93bb69]{font-weight:600;color:#333;margin-bottom:8px;font-size:14px}.forward-message-preview-item[data-v-de93bb69]{color:#666;font-size:13px;margin:2px 0;line-height:1.4;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}.forward-message-footer[data-v-de93bb69]{display:flex;justify-content:space-between;align-items:center;margin-top:8px;padding-top:8px;border-top:1px solid #e8e8e8}.forward-message-count[data-v-de93bb69]{color:#2196f3;font-size:12px}.forward-message-toggle[data-v-de93bb69]{color:#666;font-size:12px}.forward-message-expanded[data-v-de93bb69]{border-top:1px solid #e0e0e0;background:#fff;max-height:400px;overflow-y:auto}.forwarded-message-item[data-v-de93bb69]{padding:12px;border-bottom:1px solid #f0f0f0}.forwarded-message-item[data-v-de93bb69]:last-child{border-bottom:none}.forwarded-message-header[data-v-de93bb69]{display:flex;align-items:center;margin-bottom:6px}.forwarded-message-nickname[data-v-de93bb69]{font-weight:600;color:#333;font-size:13px}.forwarded-message-userid[data-v-de93bb69]{color:#999;font-size:11px;margin-left:6px}.forwarded-message-content[data-v-de93bb69]{color:#555;font-size:13px;line-height:1.4;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere}.message-at[data-v-de93bb69]{background:#2196f31a;color:#2196f3;padding:2px 4px;border-radius:3px;font-weight:500;cursor:pointer}.message-unknown[data-v-de93bb69]{background:#ff98001a;color:#ff9800;padding:2px 4px;border-radius:3px;font-style:italic;cursor:help}.input-row input[data-v-de93bb69]{flex:1;min-width:0;padding:8px 12px;border:1px solid rgba(128,128,128,.3);border-radius:4px;outline:0;background:0 0;color:currentColor}.input-row input[data-v-de93bb69]:focus{border-color:#2196f3;box-shadow:0 0 0 2px #2196f333}.input-row input[data-v-de93bb69]::placeholder{color:currentColor;opacity:.5}.input-row button[data-v-de93bb69]{padding:8px 16px;background:#2196f3;color:#fff;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;flex-shrink:0;white-space:nowrap}.input-row button[data-v-de93bb69]:hover:not(:disabled){background:#1976d2}.input-row button[data-v-de93bb69]:disabled{background:#8080804d;cursor:not-allowed}.input-row button.is-sending[data-v-de93bb69]{background:#ffc107!important;color:#333!important;cursor:default!important}.message-input .input-row button.is-sending[data-v-de93bb69]{background:#ffc107!important;color:#333!important;cursor:default!important;border-color:#ffc107!important}.empty-state[data-v-de93bb69]{display:flex;align-items:center;justify-content:center;height:100%;color:currentColor;opacity:.5;font-size:14px}.message-text-content[data-v-de93bb69]{display:inline;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere;-webkit-hyphens:auto;hyphens:auto}.message-image-container[data-v-de93bb69]{display:block;margin:4px 0}.message-image[data-v-de93bb69]{border-radius:8px;margin:4px 0;display:block;cursor:pointer;transition:transform .2s ease;object-fit:contain;background:#8080801a}.message-image[data-v-de93bb69]:hover{transform:scale(1.02)}.message-image-loading[data-v-de93bb69]{height:60px;width:200px;border-radius:8px;margin:4px 0;display:flex;align-items:center;justify-content:center;background:#8080801a;color:currentColor;opacity:.7;font-size:14px;border:1px dashed rgba(128,128,128,.3)}.message-image-error[data-v-de93bb69]{min-height:60px;width:200px;border-radius:8px;margin:4px 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#8080801a;color:currentColor;opacity:.7;font-size:14px;border:1px dashed rgba(128,128,128,.3);padding:8px;text-align:center}.message-at[data-v-de93bb69]{background:#2196f31a;color:#2196f3;padding:2px 6px;border-radius:4px;font-weight:500;cursor:pointer;display:inline-block;margin:0 2px}.message-at[data-v-de93bb69]:hover{background:#2196f333}.message-unknown[data-v-de93bb69]{background:#ff98001a;color:#ff9800;padding:2px 6px;border-radius:4px;font-size:12px;display:inline-block;margin:0 2px;cursor:help}@keyframes pulse-de93bb69{0%,to{transform:translate(-50%,-50%) scale(1)}50%{transform:translate(-50%,-50%) scale(1.1)}}.channel-message-count.will-delete[data-v-de93bb69]{background:#f44336!important;animation:shake-de93bb69 .3s ease-in-out infinite}@keyframes shake-de93bb69{0%,to{transform:translate(0)}25%{transform:translate(-2px)}75%{transform:translate(2px)}}body.dragging-bubble-global[data-v-de93bb69]{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:grabbing}.drag-threshold-circle[data-v-de93bb69]{position:fixed;pointer-events:none;border:3px dashed rgba(244,67,54,.8);border-radius:50%;z-index:999;background:#f443361a;box-shadow:0 0 20px #f443364d;animation:pulseThreshold-de93bb69 1.5s ease-in-out infinite}.context-menu[data-v-de93bb69]{position:fixed;background:#ffffffa6;border:1px solid rgba(0,0,0,.1);border-radius:8px;box-shadow:0 8px 32px #00000026;z-index:10000;min-width:180px;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);overflow:hidden}.context-menu-item[data-v-de93bb69]{padding:12px 16px;cursor:pointer;color:#333;font-size:14px;font-weight:500;transition:all .2s ease;border-bottom:1px solid rgba(0,0,0,.08);position:relative}.context-menu-item[data-v-de93bb69]:last-child{border-bottom:none}.context-menu-item[data-v-de93bb69]:hover{background:#2196f31a;color:#1976d2;transform:translate(2px)}.context-menu-item.danger[data-v-de93bb69]{color:#d32f2f}.context-menu-item.danger[data-v-de93bb69]:hover{background:#f443361a;color:#c62828}.bot-item.pinned[data-v-de93bb69],.channel-item.pinned[data-v-de93bb69]{background:#ffc1071a;border-left:3px solid #ffc107}.bot-item.pinned[data-v-de93bb69]:before,.channel-item.pinned[data-v-de93bb69]:before{content:"📌";position:absolute;left:4px;top:50%;transform:translateY(-50%);font-size:12px;opacity:.7}.bot-item.pinned[data-v-de93bb69],.channel-item.pinned[data-v-de93bb69]{position:relative;padding-left:24px}@media (prefers-color-scheme:dark){.context-menu[data-v-de93bb69]{background:#ffffff26;border-color:#fff3;box-shadow:0 8px 32px #0006}.context-menu-item[data-v-de93bb69]{color:#fff;border-bottom-color:#ffffff1a}.context-menu-item[data-v-de93bb69]:hover{background:#2196f333;color:#64b5f6}.context-menu-item.danger[data-v-de93bb69]{color:#ff8a80}.context-menu-item.danger[data-v-de93bb69]:hover{background:#f4433633;color:#ffab91}.bot-item.pinned[data-v-de93bb69],.channel-item.pinned[data-v-de93bb69]{background:#ffc10726}}.message-share-card[data-v-de93bb69]{display:inline-block;width:75px;margin:8px 0;border:1px solid rgba(128,128,128,.2);border-radius:12px;background:#ffffff0d;transition:all .3s ease;cursor:pointer;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.message-share-card[data-v-de93bb69]:hover{transform:translateY(-2px);box-shadow:0 8px 24px #00000026;border-color:#2196f34d}.share-card-preview[data-v-de93bb69]{width:100%;position:relative;display:flex;align-items:center;justify-content:center;padding:4px;border-radius:12px 12px 0 0}.share-card-image[data-v-de93bb69]{max-width:calc(100% - 8px);width:auto;height:auto;object-fit:contain;transition:transform .3s ease;display:block;border-radius:4px}.message-share-card:hover .share-card-image[data-v-de93bb69]{transform:scale(1.05)}.share-card-content[data-v-de93bb69]{padding:8px}.share-card-header[data-v-de93bb69]{display:flex;align-items:center;margin-bottom:12px;gap:12px}.share-card-icon[data-v-de93bb69]{width:32px;height:32px;border-radius:8px;object-fit:cover;flex-shrink:0}.share-card-app-info[data-v-de93bb69]{flex:1;min-width:0}.share-card-app-name[data-v-de93bb69]{font-size:12px;color:currentColor;opacity:.7;margin-bottom:2px;font-weight:500}.share-card-title[data-v-de93bb69]{font-size:10px;font-weight:600;color:currentColor;line-height:1.2;word-wrap:break-word;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden}.share-card-desc[data-v-de93bb69]{font-size:14px;color:currentColor;opacity:.8;line-height:1.4;margin-bottom:12px;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;word-wrap:break-word}.share-card-link-hint[data-v-de93bb69]{font-size:12px;color:#2196f3;font-weight:500;display:flex;align-items:center;gap:4px}.share-card-link-hint[data-v-de93bb69]:after{content:"→";transition:transform .2s ease}.message-share-card:hover .share-card-link-hint[data-v-de93bb69]:after{transform:translate(2px)}.message-json-error[data-v-de93bb69],.message-json-raw[data-v-de93bb69]{display:inline-block;margin:8px 0;max-width:400px}.json-error-text[data-v-de93bb69]{color:#f44336;font-size:14px;font-weight:500}.json-label[data-v-de93bb69]{color:currentColor;opacity:.7;font-size:12px;font-weight:500;margin-bottom:8px}.json-raw-data[data-v-de93bb69]{margin-top:8px}.json-raw-data summary[data-v-de93bb69]{cursor:pointer;font-size:12px;color:#2196f3;font-weight:500;padding:4px 8px;border-radius:4px;background:#2196f31a;display:inline-block;transition:background-color .2s ease}.json-raw-data summary[data-v-de93bb69]:hover{background:#2196f333}.json-raw-content[data-v-de93bb69]{margin-top:8px;padding:12px;background:#8080801a;border-radius:8px;font-family:Courier New,monospace;font-size:12px;color:currentColor;opacity:.8;white-space:pre-wrap;word-wrap:break-word;word-break:break-all;overflow-wrap:anywhere;max-height:200px;overflow-y:auto;border:1px solid rgba(128,128,128,.2)}@media (prefers-color-scheme:dark){.message-share-card[data-v-de93bb69]{background:#ffffff14;border-color:#ffffff26}.message-share-card[data-v-de93bb69]:hover{border-color:#2196f380;box-shadow:0 8px 24px #0000004d}.json-raw-content[data-v-de93bb69]{background:#ffffff0d;border-color:#ffffff1a}}@media (max-width:768px){.chat-container[data-v-de93bb69]{position:relative;height:100vh;height:100dvh}.bot-list[data-v-de93bb69],.channel-list[data-v-de93bb69],.message-area[data-v-de93bb69]{position:absolute;top:0;left:0;width:100%;height:100%;transition:transform .3s ease;z-index:1}.bot-list[data-v-de93bb69]{transform:translate(0);z-index:3}.channel-list[data-v-de93bb69]{transform:translate(100%);z-index:2}.message-area[data-v-de93bb69]{transform:translate(200%);z-index:1}.chat-container.show-channels .bot-list[data-v-de93bb69]{transform:translate(-100%)}.chat-container.show-channels .channel-list[data-v-de93bb69]{transform:translate(0);z-index:3}.chat-container.show-channels .message-area[data-v-de93bb69]{transform:translate(100%)}.chat-container.show-messages .bot-list[data-v-de93bb69]{transform:translate(-200%)}.chat-container.show-messages .channel-list[data-v-de93bb69]{transform:translate(-100%)}.chat-container.show-messages .message-area[data-v-de93bb69]{transform:translate(0);z-index:3}.back-button[data-v-de93bb69]{display:none!important}.panel-header[data-v-de93bb69]{flex-direction:row-reverse;position:sticky;top:0;z-index:5;background:inherit}.panel-header h3[data-v-de93bb69]{text-align:right}.floating-scroll-button[data-v-de93bb69]{right:16px;bottom:calc(90px + env(safe-area-inset-bottom,0px));width:40px;height:40px;transition:bottom .3s ease}.message-input[data-v-de93bb69]{padding:8px 12px calc(12px + env(safe-area-inset-bottom,0px)) 12px;position:fixed;bottom:20px;left:0;right:0;background:inherit;border-top:1px solid rgba(128,128,128,.2);z-index:10;min-height:calc(60px + env(safe-area-inset-bottom,0px));transition:transform .3s ease;transform:translateZ(0)}.input-row input[data-v-de93bb69]{font-size:16px;padding:10px 12px}.input-row button[data-v-de93bb69]{padding:10px 16px;font-size:16px}.message-history[data-v-de93bb69]{padding:12px;max-height:calc(100vh - 140px - env(safe-area-inset-bottom,0px));max-height:calc(100dvh - 140px - env(safe-area-inset-bottom,0px));padding-bottom:calc(80px + env(safe-area-inset-bottom,0px));overflow-y:auto;-webkit-overflow-scrolling:touch;transition:max-height .3s ease}.message-item[data-v-de93bb69]{margin-bottom:12px;padding:6px}.message-text[data-v-de93bb69]{max-width:90%!important}.message-avatar[data-v-de93bb69]{width:28px;height:28px;margin-right:8px}.message-item.bot-message .message-avatar[data-v-de93bb69]{margin-left:8px}.message-image[data-v-de93bb69]{max-width:min(280px,66.67vw);max-height:160px}.quote-content .message-image[data-v-de93bb69]{max-width:min(150px,50vw);max-height:80px}.context-menu[data-v-de93bb69]{min-width:160px;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}.context-menu-item[data-v-de93bb69]{padding:14px 16px;font-size:16px}.bot-item[data-v-de93bb69],.channel-item[data-v-de93bb69]{padding:14px 16px}.bot-avatar[data-v-de93bb69]{width:36px;height:36px;margin-right:10px}.bot-name[data-v-de93bb69],.channel-name[data-v-de93bb69]{font-size:15px}.bot-platform[data-v-de93bb69],.channel-type[data-v-de93bb69]{font-size:13px}}@media (min-width:769px) and (max-width:1024px){.bot-list[data-v-de93bb69]{width:220px;min-width:220px;max-width:220px}.channel-list[data-v-de93bb69]{width:280px;min-width:280px;max-width:280px}.message-image[data-v-de93bb69]{max-width:min(350px,66.67vw);max-height:180px}}.chat-container.swiping[data-v-de93bb69]{overflow:hidden}.bot-list.swiping[data-v-de93bb69],.channel-list.swiping[data-v-de93bb69],.message-area.swiping[data-v-de93bb69]{transition:none!important}.swipe-indicator[data-v-de93bb69]{position:fixed;top:50%;left:20px;transform:translateY(-50%);background:#2196f3cc;color:#fff;padding:8px 12px;border-radius:20px;font-size:14px;z-index:1000;opacity:0;transition:opacity .2s ease;pointer-events:none;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.swipe-indicator.show[data-v-de93bb69]{opacity:1}.message-area .message-content[data-v-de93bb69]{padding-bottom:80px}.image-preview-container[data-v-de93bb69]{display:flex;flex-wrap:wrap;gap:8px;padding:8px 0;margin-bottom:8px;border-bottom:1px solid rgba(128,128,128,.1)}.image-preview-item[data-v-de93bb69]{position:relative;width:60px;height:60px;border-radius:8px;overflow:hidden;border:2px solid rgba(33,150,243,.3);background:#8080801a}.preview-image[data-v-de93bb69]{width:100%;height:100%;object-fit:cover;display:block}.remove-image-btn[data-v-de93bb69]{position:absolute;top:-6px;right:-6px;width:20px;height:20px;border-radius:50%;background:#f44336;color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:12px;transition:all .2s ease;box-shadow:0 2px 4px #0003}.remove-image-btn[data-v-de93bb69]:hover{background:#d32f2f;transform:scale(1.1)}.input-actions[data-v-de93bb69]{position:relative;margin-right:8px}.add-button[data-v-de93bb69]{width:36px;height:36px;border-radius:12px;background:linear-gradient(135deg,#667eea 0,#764ba2);border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s cubic-bezier(.4,0,.2,1);flex-shrink:0;box-shadow:0 2px 8px #667eea4d;position:relative;overflow:hidden}.add-button[data-v-de93bb69]:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(135deg,#fff3 0,#ffffff1a);border-radius:12px;opacity:0;transition:opacity .3s ease}.add-button[data-v-de93bb69]:hover{transform:translateY(-2px) scale(1.05);box-shadow:0 4px 16px #667eea66}.add-button[data-v-de93bb69]:hover:before{opacity:1}.add-button.active[data-v-de93bb69]{background:linear-gradient(135deg,#f093fb 0,#f5576c);transform:translateY(-2px) scale(1.05) rotate(45deg);box-shadow:0 4px 16px #f5576c66}.add-button[data-v-de93bb69]:active{transform:translateY(0) scale(.98);transition:all .1s ease}.action-menu[data-v-de93bb69]{position:absolute;bottom:100%;left:0;margin-bottom:12px;background:#fffffffa;border:none;border-radius:16px;box-shadow:0 8px 32px #0000001f,0 2px 8px #00000014;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);overflow:hidden;z-index:1000;min-width:140px;transform:translateY(8px);opacity:0;animation:menuSlideIn-de93bb69 .3s cubic-bezier(.4,0,.2,1) forwards}.action-menu-item[data-v-de93bb69]{display:flex;align-items:center;gap:12px;padding:14px 18px;background:0 0;border:none;color:#333;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);width:100%;text-align:left;position:relative}.action-menu-item[data-v-de93bb69]:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(135deg,#667eea 0,#764ba2);transform:scaleY(0);transition:transform .2s cubic-bezier(.4,0,.2,1)}.action-menu-item[data-v-de93bb69]:hover{background:linear-gradient(90deg,#667eea14 0,#764ba214);color:#667eea;transform:translate(4px)}.action-menu-item[data-v-de93bb69]:hover:before{transform:scaleY(1)}.action-menu-item svg[data-v-de93bb69]{flex-shrink:0}@media (prefers-color-scheme:dark){.action-menu[data-v-de93bb69]{background:#1e1e1efa;box-shadow:0 8px 32px #0000004d,0 2px 8px #0003}.action-menu-item[data-v-de93bb69]{color:#fff}.action-menu-item[data-v-de93bb69]:before{background:linear-gradient(135deg,#4facfe 0,#00f2fe)}.action-menu-item[data-v-de93bb69]:hover{background:linear-gradient(90deg,#4facfe1f 0,#00f2fe1f);color:#4facfe}.add-button[data-v-de93bb69]{background:linear-gradient(135deg,#4facfe 0,#00f2fe);box-shadow:0 2px 8px #4facfe4d}.add-button[data-v-de93bb69]:hover{box-shadow:0 4px 16px #4facfe66}.add-button.active[data-v-de93bb69]{background:linear-gradient(135deg,#fa709a 0,#fee140);box-shadow:0 4px 16px #fa709a66}.image-preview-item[data-v-de93bb69]{border-color:#64b5f680;background:#ffffff0d}}@media (max-width:768px){.image-preview-container[data-v-de93bb69]{padding:6px 0;margin-bottom:6px}.image-preview-item[data-v-de93bb69]{width:50px;height:50px}.add-button[data-v-de93bb69]{width:32px;height:32px;border-radius:10px}.action-menu[data-v-de93bb69]{min-width:100px}.action-menu-item[data-v-de93bb69]{padding:10px 12px;font-size:13px}.remove-image-btn[data-v-de93bb69]{width:18px;height:18px;top:-5px;right:-5px}}.message-history[data-v-de93bb69]::-webkit-scrollbar{width:6px}.message-history[data-v-de93bb69]::-webkit-scrollbar-track{background:0 0}.message-history[data-v-de93bb69]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.message-history[data-v-de93bb69]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.bot-items[data-v-de93bb69]::-webkit-scrollbar{width:6px}.bot-items[data-v-de93bb69]::-webkit-scrollbar-track{background:0 0}.bot-items[data-v-de93bb69]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.bot-items[data-v-de93bb69]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.channel-items[data-v-de93bb69]::-webkit-scrollbar{width:6px}.channel-items[data-v-de93bb69]::-webkit-scrollbar-track{background:0 0}.channel-items[data-v-de93bb69]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.channel-items[data-v-de93bb69]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.forward-message-expanded[data-v-de93bb69]::-webkit-scrollbar{width:6px}.forward-message-expanded[data-v-de93bb69]::-webkit-scrollbar-track{background:0 0}.forward-message-expanded[data-v-de93bb69]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.forward-message-expanded[data-v-de93bb69]::-webkit-scrollbar-thumb:hover{background-color:#90939980}.json-raw-content[data-v-de93bb69]::-webkit-scrollbar{width:6px}.json-raw-content[data-v-de93bb69]::-webkit-scrollbar-track{background:0 0}.json-raw-content[data-v-de93bb69]::-webkit-scrollbar-thumb{background-color:#9093994d;border-radius:4px;transition:background-color .3s}.json-raw-content[data-v-de93bb69]::-webkit-scrollbar-thumb:hover{background-color:#90939980}@media (prefers-color-scheme:dark){.bot-items[data-v-de93bb69]::-webkit-scrollbar-thumb,.channel-items[data-v-de93bb69]::-webkit-scrollbar-thumb,.forward-message-expanded[data-v-de93bb69]::-webkit-scrollbar-thumb,.json-raw-content[data-v-de93bb69]::-webkit-scrollbar-thumb,.message-history[data-v-de93bb69]::-webkit-scrollbar-thumb{background-color:#fff3}.bot-items[data-v-de93bb69]::-webkit-scrollbar-thumb:hover,.channel-items[data-v-de93bb69]::-webkit-scrollbar-thumb:hover,.forward-message-expanded[data-v-de93bb69]::-webkit-scrollbar-thumb:hover,.json-raw-content[data-v-de93bb69]::-webkit-scrollbar-thumb:hover,.message-history[data-v-de93bb69]::-webkit-scrollbar-thumb:hover{background-color:#fff6}}.layout-iframe{width:100%;height:100%;border:none}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FileManager } from './file-manager';
|
|
2
|
+
import { MessageHandler } from './message-handler';
|
|
3
|
+
import { Context } from 'koishi';
|
|
4
|
+
import { Config } from './config';
|
|
5
|
+
export declare class ApiHandlers {
|
|
6
|
+
private ctx;
|
|
7
|
+
private config;
|
|
8
|
+
private fileManager;
|
|
9
|
+
private messageHandler;
|
|
10
|
+
private logger;
|
|
11
|
+
constructor(ctx: Context, config: Config, fileManager: FileManager, messageHandler: MessageHandler);
|
|
12
|
+
registerApiHandlers(): void;
|
|
13
|
+
private isFileUrl;
|
|
14
|
+
private createFileUrl;
|
|
15
|
+
private handleLocalFileRequest;
|
|
16
|
+
private setupTempFileCleanup;
|
|
17
|
+
private cleanupTempImagesByCount;
|
|
18
|
+
private logInfo;
|
|
19
|
+
}
|
package/lib/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Schema } from 'koishi';
|
|
2
|
+
export interface Config {
|
|
3
|
+
loggerinfo: boolean;
|
|
4
|
+
maxMessagesPerChannel: number;
|
|
5
|
+
keepMessagesOnClear: number;
|
|
6
|
+
keepTempImages: number;
|
|
7
|
+
blockedPlatforms: Array<{
|
|
8
|
+
platformName: string;
|
|
9
|
+
exactMatch: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
chatContainerHeight: number;
|
|
12
|
+
}
|
|
13
|
+
export declare const Config: Schema<Config>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ChatData, MessageInfo } from './types';
|
|
2
|
+
import { Context } from 'koishi';
|
|
3
|
+
import { Config } from './config';
|
|
4
|
+
export declare class FileManager {
|
|
5
|
+
private ctx;
|
|
6
|
+
private config;
|
|
7
|
+
private dataFilePath;
|
|
8
|
+
private fileOperationLock;
|
|
9
|
+
private logger;
|
|
10
|
+
private utils;
|
|
11
|
+
constructor(ctx: Context, config: Config);
|
|
12
|
+
private ensureDataDir;
|
|
13
|
+
readChatDataFromFile(): ChatData;
|
|
14
|
+
writeChatDataToFile(data: ChatData): void;
|
|
15
|
+
cleanExcessMessages(data: ChatData): ChatData;
|
|
16
|
+
addMessageToFile(messageInfo: MessageInfo): Promise<void>;
|
|
17
|
+
private logInfo;
|
|
18
|
+
}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Context } from 'koishi';
|
|
2
|
+
import { Config } from './config';
|
|
3
|
+
export declare const name = "chat-patch";
|
|
4
|
+
export declare const reusable = false;
|
|
5
|
+
export declare const filter = true;
|
|
6
|
+
export declare const inject: {
|
|
7
|
+
required: string[];
|
|
8
|
+
};
|
|
9
|
+
export declare const usage = "\n\n---\n\n\u5F00\u542F\u540E\uFF0C\u5373\u53EF\u5728koishi\u63A7\u5236\u53F0\u64CD\u4F5C\u673A\u5668\u4EBA\u6536\u53D1\u6D88\u606F\u5566\n\n\u6682\u65F6\u53EA\u652F\u6301\u63A5\u53D7\u56FE\u6587\u6D88\u606F / \u53D1\u9001\u6587\u5B57\u6D88\u606F\n\n---\n";
|
|
10
|
+
export { Config } from './config';
|
|
11
|
+
export declare function apply(ctx: Context, config: Config): Promise<void>;
|