koishi-plugin-chat-patch 1.1.1 → 1.2.0
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 +410 -52
- package/client/vue/index.vue +44 -14
- package/client/vue/style.css +75 -46
- package/dist/index.js +8 -8
- package/dist/style.css +1 -1
- package/lib/index.js +28 -2
- package/package.json +1 -1
- package/src/api-handlers.ts +29 -3
- package/src/index.ts +2 -2
package/client/vue/style.css
CHANGED
|
@@ -1021,36 +1021,60 @@ body.dragging-bubble-global {
|
|
|
1021
1021
|
|
|
1022
1022
|
.context-menu {
|
|
1023
1023
|
position: fixed;
|
|
1024
|
-
background: rgba(255, 255, 255, .
|
|
1025
|
-
border:
|
|
1026
|
-
border-radius:
|
|
1027
|
-
box-shadow: 0 8px 32px rgba(0, 0, 0, .
|
|
1024
|
+
background: rgba(255, 255, 255, .98);
|
|
1025
|
+
border: none;
|
|
1026
|
+
border-radius: 16px;
|
|
1027
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .08);
|
|
1028
|
+
backdrop-filter: blur(20px);
|
|
1029
|
+
-webkit-backdrop-filter: blur(20px);
|
|
1030
|
+
overflow: hidden;
|
|
1028
1031
|
z-index: 10000;
|
|
1029
|
-
min-width: 180px
|
|
1030
|
-
backdrop-filter: blur(16px);
|
|
1031
|
-
-webkit-backdrop-filter: blur(16px);
|
|
1032
|
-
overflow: hidden
|
|
1032
|
+
min-width: 180px
|
|
1033
1033
|
}
|
|
1034
1034
|
|
|
1035
1035
|
.context-menu-item {
|
|
1036
|
-
|
|
1037
|
-
|
|
1036
|
+
display: flex;
|
|
1037
|
+
align-items: center;
|
|
1038
|
+
gap: 12px;
|
|
1039
|
+
padding: 14px 18px;
|
|
1040
|
+
background: 0 0;
|
|
1041
|
+
border: none;
|
|
1038
1042
|
color: #333;
|
|
1039
1043
|
font-size: 14px;
|
|
1040
1044
|
font-weight: 500;
|
|
1041
|
-
|
|
1045
|
+
cursor: pointer;
|
|
1046
|
+
transition: all .2s cubic-bezier(.4, 0, .2, 1);
|
|
1047
|
+
width: 100%;
|
|
1048
|
+
text-align: left;
|
|
1049
|
+
position: relative;
|
|
1042
1050
|
border-bottom: 1px solid rgba(0, 0, 0, .08);
|
|
1043
|
-
|
|
1051
|
+
min-width: 140px
|
|
1044
1052
|
}
|
|
1045
1053
|
|
|
1046
1054
|
.context-menu-item:last-child {
|
|
1047
1055
|
border-bottom: none
|
|
1048
1056
|
}
|
|
1049
1057
|
|
|
1058
|
+
.context-menu-item::before {
|
|
1059
|
+
content: '';
|
|
1060
|
+
position: absolute;
|
|
1061
|
+
left: 0;
|
|
1062
|
+
top: 0;
|
|
1063
|
+
bottom: 0;
|
|
1064
|
+
width: 3px;
|
|
1065
|
+
background: linear-gradient(135deg, #667eea 0, #764ba2 100%);
|
|
1066
|
+
transform: scaleY(0);
|
|
1067
|
+
transition: transform .2s cubic-bezier(.4, 0, .2, 1)
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1050
1070
|
.context-menu-item:hover {
|
|
1051
|
-
background: rgba(
|
|
1052
|
-
color: #
|
|
1053
|
-
transform: translateX(
|
|
1071
|
+
background: linear-gradient(90deg, rgba(102, 126, 234, .08) 0, rgba(118, 75, 162, .08) 100%);
|
|
1072
|
+
color: #667eea;
|
|
1073
|
+
transform: translateX(4px)
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
.context-menu-item:hover::before {
|
|
1077
|
+
transform: scaleY(1)
|
|
1054
1078
|
}
|
|
1055
1079
|
|
|
1056
1080
|
.context-menu-item.danger {
|
|
@@ -1058,8 +1082,8 @@ body.dragging-bubble-global {
|
|
|
1058
1082
|
}
|
|
1059
1083
|
|
|
1060
1084
|
.context-menu-item.danger:hover {
|
|
1061
|
-
background: rgba(244, 67, 54, .
|
|
1062
|
-
color: #
|
|
1085
|
+
background: linear-gradient(90deg, rgba(244, 67, 54, .08) 0, rgba(211, 47, 47, .08) 100%);
|
|
1086
|
+
color: #d32f2f
|
|
1063
1087
|
}
|
|
1064
1088
|
|
|
1065
1089
|
.bot-item.pinned,
|
|
@@ -1091,9 +1115,8 @@ body.dragging-bubble-global {
|
|
|
1091
1115
|
|
|
1092
1116
|
@media (prefers-color-scheme:dark) {
|
|
1093
1117
|
.context-menu {
|
|
1094
|
-
background: rgba(
|
|
1095
|
-
|
|
1096
|
-
box-shadow: 0 8px 32px rgba(0, 0, 0, .4)
|
|
1118
|
+
background: rgba(30, 30, 30, .98);
|
|
1119
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, .3), 0 2px 8px rgba(0, 0, 0, .2)
|
|
1097
1120
|
}
|
|
1098
1121
|
|
|
1099
1122
|
.context-menu-item {
|
|
@@ -1101,18 +1124,18 @@ body.dragging-bubble-global {
|
|
|
1101
1124
|
border-bottom-color: rgba(255, 255, 255, .1)
|
|
1102
1125
|
}
|
|
1103
1126
|
|
|
1104
|
-
.context-menu-item
|
|
1105
|
-
background:
|
|
1106
|
-
color: #64b5f6
|
|
1127
|
+
.context-menu-item::before {
|
|
1128
|
+
background: linear-gradient(135deg, #4facfe 0, #00f2fe 100%)
|
|
1107
1129
|
}
|
|
1108
1130
|
|
|
1109
|
-
.context-menu-item
|
|
1110
|
-
|
|
1131
|
+
.context-menu-item:hover {
|
|
1132
|
+
background: linear-gradient(90deg, rgba(79, 172, 254, .12) 0, rgba(0, 242, 254, .12) 100%);
|
|
1133
|
+
color: #4facfe
|
|
1111
1134
|
}
|
|
1112
1135
|
|
|
1113
1136
|
.context-menu-item.danger:hover {
|
|
1114
|
-
background: rgba(244, 67, 54, .
|
|
1115
|
-
color: #
|
|
1137
|
+
background: linear-gradient(90deg, rgba(244, 67, 54, .12) 0, rgba(255, 138, 128, .12) 100%);
|
|
1138
|
+
color: #ff8a80
|
|
1116
1139
|
}
|
|
1117
1140
|
|
|
1118
1141
|
.bot-item.pinned,
|
|
@@ -1467,8 +1490,9 @@ body.dragging-bubble-global {
|
|
|
1467
1490
|
}
|
|
1468
1491
|
|
|
1469
1492
|
.context-menu-item {
|
|
1470
|
-
padding:
|
|
1471
|
-
font-size:
|
|
1493
|
+
padding: 10px 12px;
|
|
1494
|
+
font-size: 13px;
|
|
1495
|
+
min-width: 100px
|
|
1472
1496
|
}
|
|
1473
1497
|
|
|
1474
1498
|
.bot-item,
|
|
@@ -1492,20 +1516,20 @@ body.dragging-bubble-global {
|
|
|
1492
1516
|
font-size: 13px
|
|
1493
1517
|
}
|
|
1494
1518
|
|
|
1495
|
-
.bot-items,
|
|
1496
|
-
.channel-items {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
}
|
|
1519
|
+
.bot-items,
|
|
1520
|
+
.channel-items {
|
|
1521
|
+
flex: 1;
|
|
1522
|
+
overflow-y: auto;
|
|
1523
|
+
overflow-x: hidden;
|
|
1524
|
+
max-height: calc(100vh - 140px);
|
|
1525
|
+
max-height: calc(100dvh - 140px);
|
|
1526
|
+
-webkit-overflow-scrolling: touch;
|
|
1527
|
+
scrollbar-width: thin;
|
|
1528
|
+
scrollbar-color: rgba(144, 147, 153, .4) rgba(0, 0, 0, .05);
|
|
1529
|
+
scroll-behavior: smooth;
|
|
1530
|
+
overscroll-behavior: contain;
|
|
1531
|
+
padding-bottom: 8px
|
|
1532
|
+
}
|
|
1509
1533
|
}
|
|
1510
1534
|
|
|
1511
1535
|
@media (min-width:769px) and (max-width:1024px) {
|
|
@@ -1939,6 +1963,11 @@ body.dragging-bubble-global {
|
|
|
1939
1963
|
}
|
|
1940
1964
|
|
|
1941
1965
|
@keyframes spin {
|
|
1942
|
-
0% {
|
|
1943
|
-
|
|
1944
|
-
}
|
|
1966
|
+
0% {
|
|
1967
|
+
transform: rotate(0deg);
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
100% {
|
|
1971
|
+
transform: rotate(360deg);
|
|
1972
|
+
}
|
|
1973
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{defineComponent as Ce,ref as g,onMounted as ut,h as m,computed as te,watch as Mt,nextTick as me,onUnmounted as ba,createElementBlock as C,openBlock as w,unref as c,normalizeStyle as dt,normalizeClass as ce,createCommentVNode as B,createElementVNode as f,Fragment as ae,renderList as Le,createBlock as Fe,toDisplayString as D,withDirectives as qt,createTextVNode as ft,vShow as ka,withModifiers as Kt,withKeys as Sa,isRef as Ba,vModelText as $a,resolveComponent as Da}from"vue";import{receive as ht,send as U,icons as _a}from"@koishijs/client";function La(){function ne(e){try{return new URL(e).protocol==="file:"}catch{return false}}const ie=Ce({props:{src:{type:String,required:true},alt:{type:String,default:"头像"},channelKey:{type:String,required:true}},setup(e){const t=g("loading"),a=g(e.src),n=g(""),o=async()=>{try{t.value="loading";const i=await lt(e.channelKey,e.src);if(i){a.value=i,t.value="loaded";return}const l=new Image;l.crossOrigin="anonymous",l.referrerPolicy="no-referrer",l.draggable=false;const d=new Promise((p,I)=>{l.onload=()=>p(),l.onerror=()=>I(new Error("Direct load failed")),l.src=e.src}),v=new Promise((p,I)=>{setTimeout(()=>I(new Error("Timeout")),3e3)});try{await Promise.race([d,v]),a.value=e.src,t.value="loaded",Ie(e.channelKey,e.src).catch(p=>{console.warn("异步缓存头像失败:",p)})}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 ut(()=>{o()}),()=>{switch(t.value){case"loading":case"caching":return m("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase());case"loaded":return m("img",{src:a.value,alt:e.alt,draggable:false,style:{width:"100%",height:"100%","object-fit":"cover"}});case"error":return m("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase());default:return m("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase())}}}}),X=Ce({props:{src:{type:String,required:true},alt:{type:String,default:"图片"},filename:{type:String,default:""},channelKey:{type:String,required:true}},setup(e){const t=g("loading"),a=g(e.src),n=g(""),o=g(null),s=async()=>{try{t.value="loading";const l=await lt(e.channelKey,e.src);if(l){a.value=l,t.value="loaded";return}if(ne(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 v=new Promise((I,q)=>{d.onload=()=>I(),d.onerror=()=>q(new Error("Direct load failed")),d.src=e.src}),p=new Promise((I,q)=>{setTimeout(()=>q(new Error("Timeout")),3e3)});try{await Promise.race([v,p]),a.value=e.src,t.value="loaded",Ie(e.channelKey,e.src).catch(I=>{console.warn("异步缓存图片失败:",I)})}catch{await i()}}catch(l){console.error("图片加载失败:",l),t.value="error",n.value="图片加载失败"}},i=async()=>{try{t.value="caching";const l=await Ie(e.channelKey,e.src);if(l)a.value=l,t.value="loaded";else throw new Error("缓存系统加载失败")}catch(l){console.error("缓存系统加载图片失败:",l),t.value="error",n.value=(l==null?void 0:l.message)||"缓存加载失败"}};return ut(()=>{s()}),()=>{switch(t.value){case"loading":return m("div",{class:"message-image-loading"},"加载中...");case"caching":return m("div",{class:"message-image-loading"},"[图片加载缓存中...]");case"loaded":return m("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"},onLoad:()=>{o.value&&e.src.toLowerCase().includes(".gif")&&(o.value.style.imageRendering="auto")}});case"error":return m("div",{class:"message-image-error"},["图片加载失败",m("br"),m("small",e.filename||e.alt||"未知图片"),m("br"),m("small",{style:"color: #ff9800;"},n.value)]);default:return m("div",{class:"message-image-error"},"未知状态")}}}}),ve=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?m("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"?m("div",{class:"message-json-error"},[m("span",{class:"json-error-text"},a.error),m("details",{class:"json-raw-data"},[m("summary","查看原始数据"),m("pre",{class:"json-raw-content"},e.data)])]):m("div",{class:"message-json-raw"},[m("div",{class:"json-label"},"[JSON数据]"),m("details",{class:"json-raw-data"},[m("summary","查看详情"),m("pre",{class:"json-raw-content"},JSON.stringify(a.data,null,2))])])}}),E=Ce({props:{element:{type:Object,required:true},channelKey:{type:String,required:true}},setup(e){const t=g(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 I,q;const v=((I=d.attrs)==null?void 0:I.nickname)||"用户";let p="";if(d.children&&d.children.length>0){const H=d.children[0];H.type==="text"?(p=(((q=H.attrs)==null?void 0:q.content)||"").substring(0,20),p.length>15&&(p+="...")):H.type==="img"?p="[图片]":H.type==="video"?p="[视频]":p=`[${H.type}]`}return`${v}:${p}`}),messageCount:i}},o=(s,i)=>{var v,p,I;const l=((v=s.attrs)==null?void 0:v.nickname)||"用户",d=((p=s.attrs)==null?void 0:p.userId)||"unknown";return m("div",{key:i,class:"forwarded-message-item"},[m("div",{class:"forwarded-message-header"},[m("span",{class:"forwarded-message-nickname"},l),m("span",{class:"forwarded-message-userid"},`(${d})`)]),m("div",{class:"forwarded-message-content"},((I=s.children)==null?void 0:I.map((q,H)=>m(be,{key:H,element:q,channelKey:e.channelKey})))||[])])};return()=>{var l;const{previews:s,messageCount:i}=n();return m("div",{class:"forward-message-container"},[m("div",{class:"forward-message-preview",onClick:a},[m("div",{class:"forward-message-title"},"聊天记录"),...s.map((d,v)=>m("div",{key:v,class:"forward-message-preview-item"},d)),m("div",{class:"forward-message-footer"},[m("span",{class:"forward-message-count"},`查看${i}条转发消息`),m("span",{class:"forward-message-toggle"},t.value?"▲":"▼")])]),t.value&&m("div",{class:"forward-message-expanded"},((l=e.element.children)==null?void 0:l.filter(d=>d.type==="message").map((d,v)=>o(d,v)))||[])])}}}),be=Ce({props:{element:{type:Object,required:true},channelKey:{type:String,required:true}},setup(e){const t=a=>{var n,o,s,i,l,d;switch(a.type){case"text":return m("span",{class:"message-text-content"},a.attrs.content||"");case"forward":return m("span",{class:"message-text-content"},`[转发消息 ${a.attrs.id}]`||"[转发消息]");case"img":case"image":const v=a.attrs.src||a.attrs.url||a.attrs.file;return m("div",{class:"message-image-container"},[m(X,{src:v,alt:a.attrs.summary||"图片",filename:a.attrs.filename||a.attrs.summary||"",channelKey:e.channelKey})]);case"mface":const p=a.attrs.src||a.attrs.url||a.attrs.file;return m("div",{class:"message-image-container"},[m(X,{src:p,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 I=((i=(s=a.children[0])==null?void 0:s.attrs)==null?void 0:i.src)||((d=(l=a.children[0])==null?void 0:l.attrs)==null?void 0:d.url);return m("div",{class:"message-image-container"},[m(X,{src:I,alt:a.attrs.name||a.attrs.id||"[表情]",filename:a.attrs.name||a.attrs.id||"[表情]",channelKey:e.channelKey})])}else return m("span",{class:"message-text-content"},`[${a.attrs.name||a.attrs.id}]`||"[表情]");case"at":return m("span",{class:"message-at",title:a.attrs.name},`${a.attrs.name||a.attrs.id}`);case"json":return m("div",{class:"message-image-container"},[m(ve,{data:a.attrs.data||"",channelKey:e.channelKey})]);case"p":if(a.children&&a.children.length>0){const I=a.children.map((q,H)=>m(be,{key:H,element:q,channelKey:e.channelKey}));return m("div",{class:"message-paragraph"},I)}else return m("div",{class:"message-paragraph"},"");case"figure":return m(E,{element:a,channelKey:e.channelKey});default:return m("span",{class:"message-unknown",title:`未知消息类型: ${a.type}`},a.attrs.content||`[${a.type}]`)}};return()=>t(e.element)}}),u=g({bots:{},channels:{},messages:{}}),R=g({}),K=g({}),se=g({maxMessagesPerChannel:1e3,keepMessagesOnClear:50,loggerinfo:false,blockedPlatforms:[],chatContainerHeight:80,clearIndexedDBOnStart:true}),b=g({}),Y=new Map,Te=100*1024*1024,ge=50;let ye=0,x=null;const He="ChatImageCache",Me=2,$="images",_=50*1024*1024,Xe=100,ue=500,qe=12*1024*1024,Ye=.8,Ge=60*1e3;let j=0,V=0,Ve=0;const y=g(""),S=g(""),ke=g(""),W=g([]),de=g(false),Ke=g(),P=g(false),J=g("bots"),N=g(null),oe=g(null),Se=g(false),G=g({show:false,text:""}),L=g(),fe=g(),Be=g(false),le=g(false),pe=g(false),we=g(false),re=g(""),O=g({x:0,y:0}),A=g({x:0,y:0}),$e=g({x:0,y:0}),De=g({x:0,y:0}),F=80,_e=g(0),z=g(null),ee=g(false),k=g(null),Z=g({show:false,x:0,y:0,type:null,targetId:"",isSecondClick:false}),h=g(new Set),r=g(new Set),M=te(()=>Object.values(u.value.bots).sort((t,a)=>{const n=h.value.has(t.selfId),o=h.value.has(a.selfId);return n&&!o?-1:!n&&o?1:0})),je=te(()=>!y.value||!u.value.channels[y.value]?[]:Object.values(u.value.channels[y.value]).sort((t,a)=>{const n=r.value.has(`${y.value}:${t.id}`),o=r.value.has(`${y.value}:${a.id}`);return n&&!o?-1:!n&&o?1:0})),mt=te(()=>{if(!y.value||!S.value)return[];const e=`${y.value}:${S.value}`,t=u.value.messages[e]||[];return t.filter(a=>a.quote),t}),Pt=te(()=>{var t;if(!y.value||!S.value)return"";const e=u.value.channels[y.value];return((t=e==null?void 0:e[S.value])==null?void 0:t.name)||""}),At=te(()=>!y.value||!S.value?"":`${y.value}:${S.value}`),vt=te(()=>y.value&&S.value&&(ke.value.trim()||W.value.length>0)&&!pe.value),Rt=te(()=>y.value&&S.value&&!pe.value),Ot=te(()=>{if(!P.value)return"";switch(J.value){case"channels":return"show-channels";case"messages":return"show-messages";default:return""}}),Ut=te(()=>P.value?"输入消息...(屏幕左滑返回)":"输入消息..."),zt=te(()=>({}));function Ze(e){return e.size||0}function Pe(e){ye+=e,se.value.loggerinfo&&console.log(`内存使用量变化: ${e>0?"+":""}${(e/1024/1024).toFixed(2)}MB, 总计: ${(ye/1024/1024).toFixed(2)}MB`)}function gt(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,se.value.loggerinfo&&console.log("清理旧blob URL:",o)}),Pe(-n)}function We(){Object.keys(b.value).length>ge&>(Math.floor(ge*.7)),ye>Te&>(Math.floor(ge*.5))}function Nt(e){y.value=e,S.value="",rt(),P.value&&(J.value="channels")}function Ft(e,t){if(e.preventDefault(),e.stopPropagation(),Z.value.show&&Z.value.type==="bot"&&Z.value.targetId===t){Q();return}Qe(e,"bot",t)}function Ht(e,t){if(e.preventDefault(),e.stopPropagation(),Z.value.show&&Z.value.type==="channel"&&Z.value.targetId===t){Q();return}Qe(e,"channel",t)}function Qe(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),Z.value={show:true,x:s,y:i,type:t,targetId:a,isSecondClick:false},document.addEventListener("click",Q,{once:true}),document.addEventListener("keydown",Ee)}function Q(){Z.value.show=false,document.removeEventListener("click",Q),document.removeEventListener("keydown",Ee)}function Ee(e){e.key==="Escape"&&Z.value.show&&Q()}async function Xt(e){h.value.has(e)?h.value.delete(e):h.value.add(e),await U("set-pinned-bots",{pinnedBots:Array.from(h.value)}),Q()}async function Yt(e){const t=`${y.value}:${e}`;r.value.has(t)?r.value.delete(t):r.value.add(t),await U("set-pinned-channels",{pinnedChannels:Array.from(r.value)}),Q()}async function Vt(e){try{const t=await U("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 R.value[n],await Ne(n);delete u.value.bots[e],delete u.value.channels[e],y.value===e&&(y.value="",S.value=""),T(t.message||"已删除该机器人的所有数据","success")}else throw new Error(t.error||"删除失败")}catch(t){console.error("删除机器人数据失败:",t),T("删除失败: "+((t==null?void 0:t.message)||String(t)),"error")}Q()}async function Wt(e){try{const t=await U("delete-channel-data",{selfId:y.value,channelId:e});if(t.success){const a=`${y.value}:${e}`;delete u.value.messages[a],delete R.value[a],u.value.channels[y.value]&&delete u.value.channels[y.value][e],await Ne(a),S.value===e&&(S.value=""),T(t.message||"已删除该频道的所有数据","success")}else throw new Error(t.error||"删除失败")}catch(t){console.error("删除频道数据失败:",t),T("删除失败: "+((t==null?void 0:t.message)||String(t)),"error")}Q()}async function Jt(e){S.value=e,le.value=false,rt(),P.value&&(J.value="messages");const t=`${y.value}:${e}`;delete K.value[t],y.value&&await ct(y.value,e,50,0),me(()=>{he(),!P.value&&fe.value&&fe.value.focus()})}async function Gt(){if(!vt.value)return;const e=ke.value.trim();if(!e&&W.value.length===0)return;pe.value=true;const t=[...W.value];try{const a=await U("send-message",{selfId:y.value,channelId:S.value,content:e,images:t.map(n=>({tempId:n.tempId,filename:n.filename}))});if(a.success){if(ke.value="",t.forEach(n=>{URL.revokeObjectURL(n.preview)}),W.value=[],de.value=false,a.tempImageIds&&a.tempImageIds.length>0)try{await U("cleanup-temp-images",{tempImageIds:a.tempImageIds}),console.log("临时图片清理完成:",a.tempImageIds)}catch(n){console.warn("清理临时图片失败:",n)}}else console.error("消息发送失败:",a.error),T("发送失败: "+a.error,"error")}catch(a){console.error("发送消息时出错:",a),T("发送失败: "+((a==null?void 0:a.message)||String(a)),"error")}finally{pe.value=false}}function Zt(){de.value=!de.value}function Qt(){Ke.value&&Ke.value.click(),de.value=false}async function Et(e){const t=e.target,a=t.files;if(!(!a||a.length===0)){for(const n of Array.from(a))await et(n);t.value=""}}async function ea(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();if(o){const s=n.type==="image/gif"?".gif":n.type==="image/png"?".png":(n.type==="image/jpeg",".jpg"),i=`pasted-image-${Date.now()}${s}`,l=new File([o],i,{type:n.type,lastModified:Date.now()});await et(l)}}}}async function et(e){try{if(e.size>10*1024*1024){T("图片文件过大,请选择小于10MB的图片","error");return}if(!e.type.startsWith("image/")){T("请选择图片文件","error");return}const t=await yt(e),a=URL.createObjectURL(e),n=await U("upload-image",{file:t,filename:e.name,mimeType:e.type,isGif:e.type==="image/gif"});n.success?W.value.push({tempId:n.tempId,filename:e.name,preview:a,size:e.size}):(URL.revokeObjectURL(a),T("图片上传失败: "+n.error,"error"))}catch(t){console.error("上传图片失败:",t),T("图片上传失败: "+((t==null?void 0:t.message)||String(t)),"error")}}async function ta(e){try{const t=W.value.findIndex(a=>a.tempId===e);if(t!==-1){const a=W.value[t];URL.revokeObjectURL(a.preview),W.value.splice(t,1)}await U("delete-temp-image",{tempId:e})}catch(t){console.error("删除图片失败:",t)}}function yt(e){return new Promise((t,a)=>{const n=new FileReader;n.onload=()=>t(n.result),n.onerror=a,n.readAsDataURL(e)})}function tt(e){const t=e.target;t.closest(".input-actions")||(de.value=false),t.closest(".context-menu")||Q()}function aa(e){return new Date(e).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit"})}function na(e){if(typeof e=="number")switch(e){case 0:return"文本";case 1:return"私聊";default:return"未知"}return String(e)}function he(){L.value&&(L.value.scrollTop=L.value.scrollHeight,Be.value=false,le.value=false)}function Ae(){if(L.value){const{scrollTop:e,scrollHeight:t,clientHeight:a}=L.value,o=t-(e+a)<=50,s=!o;Be.value=s,o?le.value=false:le.value=true,e<=10&&y.value&&S.value&&pt()}}async function pt(){if(!y.value||!S.value)return;const e=`${y.value}:${S.value}`,t=K.value[e];if(!(we.value||t&&!t.hasMore)){K.value[e]||(K.value[e]={offset:0,hasMore:true,loading:false}),we.value=true,K.value[e].loading=true;try{const a=(t==null?void 0:t.offset)||0;await ct(y.value,S.value,50,a)||(K.value[e].loading=false)}catch(a){console.error("加载更多消息失败:",a),K.value[e]&&(K.value[e].loading=false)}finally{we.value=false}}}function Re(){if(!L.value)return true;const{scrollTop:e,scrollHeight:t,clientHeight:a}=L.value;return t-(e+a)<=200}function wt(e){var n;if(!y.value)return 0;const t=`${y.value}:${e}`,a=R.value[t];return a!==void 0?a:((n=u.value.messages[t])==null?void 0:n.length)||0}function sa(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;_e.value=Date.now(),O.value={x:a,y:n},A.value={x:a,y:n},ee.value=false;const s=e.target.getBoundingClientRect();$e.value={x:s.left,y:s.top},De.value={x:a-s.left,y:n-s.top},z.value=window.setTimeout(()=>{if(_e.value>0){ee.value=true,re.value=t;const i=e.target,l=i.cloneNode(true);l.classList.add("dragging-clone"),l.style.position="fixed",l.style.zIndex="1000",l.style.pointerEvents="none";const d=i.getBoundingClientRect();l.style.left=`${d.left}px`,l.style.top=`${d.top}px`,l.style.width=`${d.width}px`,l.style.height=`${d.height}px`,document.body.appendChild(l),k.value=l,document.body.style.userSelect="none",document.body.style.cursor="grabbing",document.body.classList.add("dragging-bubble-global"),xt(O.value.x,O.value.y)}},60),document.addEventListener("mousemove",Oe),document.addEventListener("mouseup",Ue),document.addEventListener("touchmove",Oe),document.addEventListener("touchend",Ue)}function Oe(e){if(!ee.value||!k.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;A.value={x:t,y:a};const n=A.value.x-O.value.x,o=A.value.y-O.value.y,s=Math.sqrt(n*n+o*o),i=Math.max(.3,1-s/(F*2)),l=Math.max(.8,1-s/(F*3)),d=s>F,v=A.value.x-De.value.x,p=A.value.y-De.value.y;k.value.style.left=`${v}px`,k.value.style.top=`${p}px`,k.value.style.transform=`scale(${l})`,k.value.style.opacity=`${i}`,k.value.style.backgroundColor=d?"#f44336":"#2196f3",k.value.style.boxShadow=d?"0 4px 12px rgba(244, 67, 54, 0.4)":"0 4px 12px rgba(33, 150, 243, 0.4)",d?k.value.classList.add("will-delete"):k.value.classList.remove("will-delete")}function Ue(e){if(z.value&&(clearTimeout(z.value),z.value=null),z.value&&(clearTimeout(z.value),z.value=null),!ee.value||!re.value){ze();return}const t=re.value;if(Math.sqrt(Math.pow(A.value.x-O.value.x,2)+Math.pow(A.value.y-O.value.y,2))>F)It(t),ze();else if(k.value){k.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();k.value.style.left=`${o.left}px`,k.value.style.top=`${o.top}px`,k.value.style.transform="scale(1)",k.value.style.opacity="1",k.value.style.backgroundColor="#2196f3",k.value.style.boxShadow="0 4px 12px rgba(33, 150, 243, 0.4)"}setTimeout(()=>{ze()},300)}else ze()}function ze(){z.value&&(clearTimeout(z.value),z.value=null),re.value="",O.value={x:0,y:0},A.value={x:0,y:0},$e.value={x:0,y:0},_e.value=0,ee.value=false,document.removeEventListener("mousemove",Oe),document.removeEventListener("mouseup",Ue),document.removeEventListener("touchmove",Oe),document.removeEventListener("touchend",Ue),document.body.style.userSelect="",document.body.style.cursor="",document.body.classList.remove("dragging-bubble-global"),k.value&&k.value.parentNode&&(k.value.parentNode.removeChild(k.value),k.value=null),Ct()}function oa(e){return re.value===e&&ee.value?{visibility:"hidden",pointerEvents:"none",transition:"none"}:{}}function la(e){if(re.value!==e)return 0;const t=A.value.x-O.value.x,a=A.value.y-O.value.y;return Math.sqrt(t*t+a*a)}async function It(e){if(y.value)try{const t=`${y.value}:${e}`,a=wt(e),n=se.value.keepMessagesOnClear;if(n>0&&a<=n){T("当前消息还很少诶~ 无需清理","success");return}const o=await U("clear-channel-history",{selfId:y.value,channelId:e});if(o.success)if(o.clearedCount&&o.clearedCount>0){if(u.value.messages[t]){const i=[...u.value.messages[t]].sort((l,d)=>l.timestamp-d.timestamp);u.value.messages[t]=i.slice(-o.keptCount)}R.value[t]=o.keptCount,await Ne(t),T(`历史记录已清理,清理了 ${o.clearedCount} 条消息,保留最新 ${o.keptCount} 条`,"success")}else n===0?(u.value.messages[t]&&(u.value.messages[t]=[]),R.value[t]=0,await Ne(t),T("历史记录已清理,所有消息已删除","success")):T("当前消息还很少诶~ 无需清理","success");else console.error("清理历史记录失败:",o.error),T("清理失败: "+o.error,"error")}catch(t){console.error("清理历史记录时出错:",t),T("清理失败: "+((t==null?void 0:t.message)||String(t)),"error")}}function T(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=`
|
|
1
|
+
import{defineComponent as De,ref as g,onMounted as wt,h as m,computed as re,watch as Ft,nextTick as le,onUnmounted as Pn,createElementBlock as C,openBlock as w,unref as r,normalizeStyle as It,normalizeClass as ve,createCommentVNode as $,createElementVNode as f,Fragment as ee,renderList as Re,createBlock as Ye,toDisplayString as L,withDirectives as Ht,createTextVNode as xt,vShow as jn,withModifiers as Xt,withKeys as An,isRef as On,vModelText as zn,resolveComponent as Nn}from"vue";import{receive as Ct,send as F,icons as Fn}from"@koishijs/client";function Hn(){function ce(e){try{return new URL(e).protocol==="file:"}catch{return false}}const ge=De({props:{src:{type:String,required:true},alt:{type:String,default:"头像"},channelKey:{type:String,required:true}},setup(e){const t=g("loading"),n=g(e.src),a=g(""),o=async()=>{try{t.value="loading";const c=await vt(e.channelKey,e.src);if(c){n.value=c,t.value="loaded";return}const l=new Image;l.crossOrigin="anonymous",l.referrerPolicy="no-referrer",l.draggable=false;const u=new Promise((p,I)=>{l.onload=()=>p(),l.onerror=()=>I(new Error("Direct load failed")),l.src=e.src}),v=new Promise((p,I)=>{setTimeout(()=>I(new Error("Timeout")),3e3)});try{await Promise.race([u,v]),n.value=e.src,t.value="loaded",$e(e.channelKey,e.src).catch(p=>{console.warn("异步缓存头像失败:",p)})}catch{await s()}}catch(c){console.error("头像加载失败:",c),t.value="error",a.value="头像加载失败"}},s=async()=>{try{t.value="caching";const c=await $e(e.channelKey,e.src);if(c)n.value=c,t.value="loaded";else throw new Error("缓存系统加载失败")}catch(c){console.error("缓存系统加载头像失败:",c),t.value="error",a.value=(c==null?void 0:c.message)||"缓存加载失败"}};return wt(()=>{o()}),()=>{switch(t.value){case"loading":case"caching":return m("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase());case"loaded":return m("img",{src:n.value,alt:e.alt,draggable:false,style:{width:"100%",height:"100%","object-fit":"cover"}});case"error":return m("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase());default:return m("div",{class:"avatar-placeholder"},e.alt.charAt(0).toUpperCase())}}}}),Y=De({props:{src:{type:String,required:true},alt:{type:String,default:"图片"},filename:{type:String,default:""},channelKey:{type:String,required:true}},setup(e){const t=g("loading"),n=g(e.src),a=g(""),o=g(null),s=async()=>{try{t.value="loading";const l=await vt(e.channelKey,e.src);if(l){n.value=l,t.value="loaded";return}if(ce(e.src)){console.log("ImageComponent: 检测到本地文件,使用代理请求:",e.src),await c();return}const u=new Image;u.crossOrigin="anonymous",u.referrerPolicy="no-referrer",u.draggable=false;const v=new Promise((I,R)=>{u.onload=()=>I(),u.onerror=()=>R(new Error("Direct load failed")),u.src=e.src}),p=new Promise((I,R)=>{setTimeout(()=>R(new Error("Timeout")),3e3)});try{await Promise.race([v,p]),n.value=e.src,t.value="loaded",$e(e.channelKey,e.src).catch(I=>{console.warn("异步缓存图片失败:",I)})}catch{await c()}}catch(l){console.error("图片加载失败:",l),t.value="error",a.value="图片加载失败"}},c=async()=>{try{t.value="caching";const l=await $e(e.channelKey,e.src);if(l)n.value=l,t.value="loaded";else throw new Error("缓存系统加载失败")}catch(l){console.error("缓存系统加载图片失败:",l),t.value="error",a.value=(l==null?void 0:l.message)||"缓存加载失败"}};return wt(()=>{s()}),()=>{switch(t.value){case"loading":return m("div",{class:"message-image-loading"},"加载中...");case"caching":return m("div",{class:"message-image-loading"},"[图片加载缓存中...]");case"loaded":return m("img",{src:n.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"},onLoad:()=>{o.value&&e.src.toLowerCase().includes(".gif")&&(o.value.style.imageRendering="auto")}});case"error":return m("div",{class:"message-image-error"},["图片加载失败",m("br"),m("small",e.filename||e.alt||"未知图片"),m("br"),m("small",{style:"color: #ff9800;"},a.value)]);default:return m("div",{class:"message-image-error"},"未知状态")}}}}),xe=De({props:{data:{type:String,required:true},channelKey:{type:String,required:true}},setup(e){const n=(()=>{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数据"}}})(),a=()=>{n.type==="share_card"&&n.url&&window.open(n.url,"_blank","noopener,noreferrer")};return()=>n.type==="share_card"&&n.preview?m("img",{src:n.preview,alt:n.title||"[分享小程序]",class:"message-image",loading:"lazy",draggable:false,onClick:a,style:{"max-width":"400px","max-height":"200px",width:"auto",height:"auto","object-fit":"contain",cursor:n.url?"pointer":"default"},title:n.url?`点击打开: ${n.title||"链接"}`:n.title,onError:o=>{const c=o.target.parentElement;c&&(c.style.display="none")}}):n.type==="error"?m("div",{class:"message-json-error"},[m("span",{class:"json-error-text"},n.error),m("details",{class:"json-raw-data"},[m("summary","查看原始数据"),m("pre",{class:"json-raw-content"},e.data)])]):m("div",{class:"message-json-raw"},[m("div",{class:"json-label"},"[JSON数据]"),m("details",{class:"json-raw-data"},[m("summary","查看详情"),m("pre",{class:"json-raw-content"},JSON.stringify(n.data,null,2))])])}}),te=De({props:{element:{type:Object,required:true},channelKey:{type:String,required:true}},setup(e){const t=g(false),n=()=>{t.value=!t.value},a=()=>{if(!e.element.children||e.element.children.length===0)return{previews:[],messageCount:0};const s=e.element.children.filter(u=>u.type==="message"),c=s.length;return{previews:s.slice(0,3).map(u=>{var I,R;const v=((I=u.attrs)==null?void 0:I.nickname)||"用户";let p="";if(u.children&&u.children.length>0){const Q=u.children[0];Q.type==="text"?(p=(((R=Q.attrs)==null?void 0:R.content)||"").substring(0,20),p.length>15&&(p+="...")):Q.type==="img"?p="[图片]":Q.type==="video"?p="[视频]":p=`[${Q.type}]`}return`${v}:${p}`}),messageCount:c}},o=(s,c)=>{var v,p,I;const l=((v=s.attrs)==null?void 0:v.nickname)||"用户",u=((p=s.attrs)==null?void 0:p.userId)||"unknown";return m("div",{key:c,class:"forwarded-message-item"},[m("div",{class:"forwarded-message-header"},[m("span",{class:"forwarded-message-nickname"},l),m("span",{class:"forwarded-message-userid"},`(${u})`)]),m("div",{class:"forwarded-message-content"},((I=s.children)==null?void 0:I.map((R,Q)=>m(Me,{key:Q,element:R,channelKey:e.channelKey})))||[])])};return()=>{var l;const{previews:s,messageCount:c}=a();return m("div",{class:"forward-message-container"},[m("div",{class:"forward-message-preview",onClick:n},[m("div",{class:"forward-message-title"},"聊天记录"),...s.map((u,v)=>m("div",{key:v,class:"forward-message-preview-item"},u)),m("div",{class:"forward-message-footer"},[m("span",{class:"forward-message-count"},`查看${c}条转发消息`),m("span",{class:"forward-message-toggle"},t.value?"▲":"▼")])]),t.value&&m("div",{class:"forward-message-expanded"},((l=e.element.children)==null?void 0:l.filter(u=>u.type==="message").map((u,v)=>o(u,v)))||[])])}}}),Me=De({props:{element:{type:Object,required:true},channelKey:{type:String,required:true}},setup(e){const t=n=>{var a,o,s,c,l,u;switch(n.type){case"text":return m("span",{class:"message-text-content"},n.attrs.content||"");case"forward":return m("span",{class:"message-text-content"},`[转发消息 ${n.attrs.id}]`||"[转发消息]");case"img":case"image":const v=n.attrs.src||n.attrs.url||n.attrs.file;return m("div",{class:"message-image-container"},[m(Y,{src:v,alt:n.attrs.summary||"图片",filename:n.attrs.filename||n.attrs.summary||"",channelKey:e.channelKey})]);case"mface":const p=n.attrs.src||n.attrs.url||n.attrs.file;return m("div",{class:"message-image-container"},[m(Y,{src:p,alt:n.attrs.summary||"表情",filename:n.attrs.emojiId||n.attrs.summary||"",channelKey:e.channelKey})]);case"face":if((o=(a=n.children[0])==null?void 0:a.attrs)!=null&&o.src){const I=((c=(s=n.children[0])==null?void 0:s.attrs)==null?void 0:c.src)||((u=(l=n.children[0])==null?void 0:l.attrs)==null?void 0:u.url);return m("div",{class:"message-image-container"},[m(Y,{src:I,alt:n.attrs.name||n.attrs.id||"[表情]",filename:n.attrs.name||n.attrs.id||"[表情]",channelKey:e.channelKey})])}else return m("span",{class:"message-text-content"},`[${n.attrs.name||n.attrs.id}]`||"[表情]");case"at":return m("span",{class:"message-at",title:n.attrs.name},`@${(n.attrs.name||n.attrs.id).replace("@","")}`);case"json":return m("div",{class:"message-image-container"},[m(xe,{data:n.attrs.data||"",channelKey:e.channelKey})]);case"p":if(n.children&&n.children.length>0){const I=n.children.map((R,Q)=>m(Me,{key:Q,element:R,channelKey:e.channelKey}));return m("div",{class:"message-paragraph"},I)}else return m("div",{class:"message-paragraph"},"");case"figure":return m(te,{element:n,channelKey:e.channelKey});default:return m("span",{class:"message-unknown",title:`未知消息类型: ${n.type}`},n.attrs.content||`[${n.type}]`)}};return()=>t(e.element)}}),d=g({bots:{},channels:{},messages:{}}),z=g({}),P=g({}),ie=g({maxMessagesPerChannel:1e3,keepMessagesOnClear:50,loggerinfo:false,blockedPlatforms:[],chatContainerHeight:80,clearIndexedDBOnStart:true}),k=g({}),V=new Map,Pe=100*1024*1024,Ce=50;let be=0,x=null;const Ve="ChatImageCache",je=2,_="images",B=50*1024*1024,Je=100,ye=500,Ae=12*1024*1024,q=.8,tt=60*1e3;let j=0,J=0,Ge=0;const y=g(""),b=g(""),ue=g(""),G=g([]),pe=g(false),Oe=g(),A=g(false),Z=g("bots"),X=g(null),de=g(null),_e=g(false),E=g({show:false,text:""}),T=g(),ne=g(),Le=g(false),fe=g(false),ke=g(false),Se=g(false),he=g(""),N=g({x:0,y:0}),O=g({x:0,y:0}),Te=g({x:0,y:0}),qe=g({x:0,y:0}),W=80,Ue=g(0),H=g(null),ae=g(false),S=g(null),U=g({show:false,x:0,y:0,type:"bot",targetId:"",isSecondClick:false,message:void 0}),se=g(new Set),oe=g(new Set),nt=re(()=>Object.values(d.value.bots).sort((t,n)=>{const a=se.value.has(t.selfId),o=se.value.has(n.selfId);return a&&!o?-1:!a&&o?1:0})),at=re(()=>!y.value||!d.value.channels[y.value]?[]:Object.values(d.value.channels[y.value]).sort((t,n)=>{const a=oe.value.has(`${y.value}:${t.id}`),o=oe.value.has(`${y.value}:${n.id}`);return a&&!o?-1:!a&&o?1:0})),we=re(()=>{if(!y.value||!b.value)return[];const e=`${y.value}:${b.value}`,t=d.value.messages[e]||[];return t.filter(n=>n.quote),t}),st=re(()=>{var t;if(!y.value||!b.value)return"";const e=d.value.channels[y.value];return((t=e==null?void 0:e[b.value])==null?void 0:t.name)||""}),ot=re(()=>!y.value||!b.value?"":`${y.value}:${b.value}`),Ke=re(()=>y.value&&b.value&&(ue.value.trim()||G.value.length>0)&&!ke.value),rt=re(()=>y.value&&b.value&&!ke.value),bt=re(()=>{if(!A.value)return"";switch(Z.value){case"channels":return"show-channels";case"messages":return"show-messages";default:return""}}),h=re(()=>A.value?"输入消息...(屏幕左滑返回)":"输入消息..."),i=re(()=>({}));function M(e){return e.size||0}function me(e){be+=e,ie.value.loggerinfo&&console.log(`内存使用量变化: ${e>0?"+":""}${(e/1024/1024).toFixed(2)}MB, 总计: ${(be/1024/1024).toFixed(2)}MB`)}function kt(e=10){const t=Object.entries(k.value);if(t.length<=e)return;const n=t.slice(0,t.length-e);let a=0;n.forEach(([o,s])=>{URL.revokeObjectURL(s),delete k.value[o],a+=500*1024,ie.value.loggerinfo&&console.log("清理旧blob URL:",o)}),me(-a)}function Ze(){Object.keys(k.value).length>Ce&&kt(Math.floor(Ce*.7)),be>Pe&&kt(Math.floor(Ce*.5))}function Qt(e){y.value=e,b.value="",gt(),A.value&&(Z.value="channels")}function Yt(e,t){const n=/^<quote\s+id="([^"]+)"\s*\/>(.*)/,a=e.match(n);if(a){const o=a[1],s=a[2];return{quotedMessage:t.find(l=>l.id===o)||null,restContent:s}}return{quotedMessage:null,restContent:e}}function lt(e,t){return Yt(e,t)}function ze(e,t){return!e||!e.content?null:lt(e.content,t).quotedMessage}function Vt(e,t){if(e.quote&&e.quote.user)return{avatar:e.quote.user.avatar||"",username:e.quote.user.username||""};const n=ze(e,t);return n?{avatar:n.avatar||"",username:n.username||""}:{avatar:"",username:""}}function Jt(e,t){if(e.quote&&e.quote.timestamp)return e.quote.timestamp;const n=ze(e,t);return n?n.timestamp:Date.now()}function Gt(e,t){if(e.quote&&e.quote.content)return e.quote.content;const n=ze(e,t);return n?n.content:""}function Zt(e,t){if(e.quote&&e.quote.elements)return e.quote.elements;const n=ze(e,t);return n?n.elements||[]:[]}function Et(e,t){return!e||!e.content?"":lt(e.content,t).restContent||e.content}function en(e,t){if(e.preventDefault(),e.stopPropagation(),U.value.show&&U.value.type==="bot"&&U.value.targetId===t){K();return}ct(e,"bot",t)}function tn(e,t){if(e.preventDefault(),e.stopPropagation(),U.value.show&&U.value.type==="channel"&&U.value.targetId===t){K();return}ct(e,"channel",t)}function nn(e,t){var a;if(e.preventDefault(),e.stopPropagation(),U.value.show&&U.value.type==="message"&&((a=U.value.message)==null?void 0:a.id)===t.id){K();return}an(e,t)}function ct(e,t,n){let s=e.clientX,c=e.clientY;s+180>window.innerWidth&&(s=window.innerWidth-180-10),c+80>window.innerHeight&&(c=window.innerHeight-80-10),U.value={show:true,x:s,y:c,type:t,targetId:n,isSecondClick:false},document.addEventListener("click",K,{once:true}),document.addEventListener("keydown",Ee)}function an(e,t){let o=e.clientX,s=e.clientY;o+180>window.innerWidth&&(o=window.innerWidth-180-10),s+120>window.innerHeight&&(s=window.innerHeight-120-10),U.value={show:true,x:o,y:s,type:"message",targetId:t.id,isSecondClick:false,message:t},document.addEventListener("click",K,{once:true}),document.addEventListener("keydown",Ee)}function K(){U.value.show=false,document.removeEventListener("click",K),document.removeEventListener("keydown",Ee)}function Ee(e){e.key==="Escape"&&U.value.show&&K()}async function sn(e){se.value.has(e)?se.value.delete(e):se.value.add(e),await F("set-pinned-bots",{pinnedBots:Array.from(se.value)}),K()}async function on(e){const t=`${y.value}:${e}`;oe.value.has(t)?oe.value.delete(t):oe.value.add(t),await F("set-pinned-channels",{pinnedChannels:Array.from(oe.value)}),K()}async function rn(e){try{const t=await F("delete-bot-data",{selfId:e});if(t.success){const n=Object.keys(d.value.messages).filter(a=>a.startsWith(`${e}:`));for(const a of n)delete d.value.messages[a],delete z.value[a],await Qe(a);delete d.value.bots[e],delete d.value.channels[e],y.value===e&&(y.value="",b.value=""),D(t.message||"已删除该机器人的所有数据","success")}else throw new Error(t.error||"删除失败")}catch(t){console.error("删除机器人数据失败:",t),D("删除失败: "+((t==null?void 0:t.message)||String(t)),"error")}K()}async function ln(e){try{const t=await F("delete-channel-data",{selfId:y.value,channelId:e});if(t.success){const n=`${y.value}:${e}`;delete d.value.messages[n],delete z.value[n],d.value.channels[y.value]&&delete d.value.channels[y.value][e],await Qe(n),b.value===e&&(b.value=""),D(t.message||"已删除该频道的所有数据","success")}else throw new Error(t.error||"删除失败")}catch(t){console.error("删除频道数据失败:",t),D("删除失败: "+((t==null?void 0:t.message)||String(t)),"error")}K()}async function St(e){b.value=e,fe.value=false,gt(),A.value&&(Z.value="messages");const t=`${y.value}:${e}`;delete P.value[t],y.value&&await yt(y.value,e,50,0),le(()=>{Ie(),!A.value&&ne.value&&ne.value.focus()})}async function $t(){if(!Ke.value)return;const e=ue.value.trim();if(!e&&G.value.length===0)return;const t=b.value;ke.value=true;const n=[...G.value];try{const a=await F("send-message",{selfId:y.value,channelId:b.value,content:e,images:n.map(o=>({tempId:o.tempId,filename:o.filename}))});if(a.success){if(ue.value="",n.forEach(o=>{URL.revokeObjectURL(o.preview)}),G.value=[],pe.value=false,t&&(b.value="",await le(),St(t)),a.tempImageIds&&a.tempImageIds.length>0)try{await F("cleanup-temp-images",{tempImageIds:a.tempImageIds}),console.log("临时图片清理完成:",a.tempImageIds)}catch(o){console.warn("清理临时图片失败:",o)}}else console.error("消息发送失败:",a.error),D("发送失败: "+a.error,"error")}catch(a){console.error("发送消息时出错:",a),D("发送失败: "+((a==null?void 0:a.message)||String(a)),"error")}finally{ke.value=false}}function cn(){pe.value=!pe.value}function un(){Oe.value&&Oe.value.click(),pe.value=false}async function dn(e){const t=e.target,n=t.files;if(!(!n||n.length===0)){for(const a of Array.from(n))await it(a);t.value=""}}async function fn(e){var n;const t=(n=e.clipboardData)==null?void 0:n.items;if(t){for(const a of Array.from(t))if(a.type.startsWith("image/")){e.preventDefault();const o=a.getAsFile();if(o){const s=a.type==="image/gif"?".gif":a.type==="image/png"?".png":(a.type==="image/jpeg",".jpg"),c=`pasted-image-${Date.now()}${s}`,l=new File([o],c,{type:a.type,lastModified:Date.now()});await it(l)}}}}async function it(e){try{if(e.size>10*1024*1024){D("图片文件过大,请选择小于10MB的图片","error");return}if(!e.type.startsWith("image/")){D("请选择图片文件","error");return}const t=await Bt(e),n=URL.createObjectURL(e),a=await F("upload-image",{file:t,filename:e.name,mimeType:e.type,isGif:e.type==="image/gif"});a.success?G.value.push({tempId:a.tempId,filename:e.name,preview:n,size:e.size}):(URL.revokeObjectURL(n),D("图片上传失败: "+a.error,"error"))}catch(t){console.error("上传图片失败:",t),D("图片上传失败: "+((t==null?void 0:t.message)||String(t)),"error")}}async function hn(e){try{const t=G.value.findIndex(n=>n.tempId===e);if(t!==-1){const n=G.value[t];URL.revokeObjectURL(n.preview),G.value.splice(t,1)}await F("delete-temp-image",{tempId:e})}catch(t){console.error("删除图片失败:",t)}}function Bt(e){return new Promise((t,n)=>{const a=new FileReader;a.onload=()=>t(a.result),a.onerror=n,a.readAsDataURL(e)})}function ut(e){const t=e.target;t.closest(".input-actions")||(pe.value=false),t.closest(".context-menu")||K()}function mn(e){return new Date(e).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit"})}async function vn(e){var t,n;if(e){K();try{let a="";const o=e.elements||[];if(o.length>0)for(const s of o)switch(s.type){case"img":case"image":const c=s.attrs.src||s.attrs.url||s.attrs.file;c&&(a+=`<img src="${c}"/>`);break;case"mface":const l=s.attrs.src||s.attrs.url||s.attrs.file;l&&(a+=`<img src="${l}"/>`);break;case"face":if(s.children&&((n=(t=s.children[0])==null?void 0:t.attrs)!=null&&n.src)){const u=s.children[0].attrs.src;a+=`<img src="${u}"/>`}else a+=`[${s.attrs.name||s.attrs.id}]`;break;case"at":a+=`<at id="${s.attrs.id}" name="${s.attrs.name}"/>`;break;case"text":a+=s.attrs.content||"";break;default:a+=e.content;break}else a=e.content;ue.value=a,await $t()}catch(a){console.error("+1操作失败:",a),D("操作失败: "+((a==null?void 0:a.message)||String(a)),"error")}}}async function gn(e){var t,n;if(e){K();try{let a="";const o=e.elements||[];if(o.length>0)for(const s of o)switch(s.type){case"img":case"image":const c=s.attrs.src||s.attrs.url||s.attrs.file;c&&(a+=`<img src="${c}"/>`);break;case"mface":const l=s.attrs.src||s.attrs.url||s.attrs.file;l&&(a+=`<img src="${l}"/>`);break;case"face":if(s.children&&((n=(t=s.children[0])==null?void 0:t.attrs)!=null&&n.src)){const u=s.children[0].attrs.src;a+=`<img src="${u}"/>`}else a+=`[${s.attrs.name||s.attrs.id}]`;break;case"at":a+=`<at id="${s.attrs.id}" name="${s.attrs.name}"/>`;break;case"text":a+=s.attrs.content||"";break;default:a+=e.content;break}else a=e.content;await navigator.clipboard.writeText(a),D("已复制到剪贴板","success")}catch(a){console.error("复制失败:",a),D("复制失败: "+((a==null?void 0:a.message)||String(a)),"error")}}}function yn(e){if(e){K();try{const t=`<quote id="${e.id.replace("bot-msg-","")}"/>`;ue.value=t+ue.value,le(()=>{ne.value&&ne.value.focus()})}catch(t){console.error("回复操作失败:",t),D("操作失败: "+((t==null?void 0:t.message)||String(t)),"error")}}}function pn(e){if(typeof e=="number")switch(e){case 0:return"文本";case 1:return"私聊";default:return"未知"}return String(e)}function Ie(){T.value&&(T.value.scrollTop=T.value.scrollHeight,Le.value=false,fe.value=false)}function Ne(){if(T.value){const{scrollTop:e,scrollHeight:t,clientHeight:n}=T.value,o=t-(e+n)<=50,s=!o;Le.value=s,o?fe.value=false:fe.value=true,e<=10&&y.value&&b.value&&Dt()}}async function Dt(){if(!y.value||!b.value)return;const e=`${y.value}:${b.value}`,t=P.value[e];if(!(Se.value||t&&!t.hasMore)){P.value[e]||(P.value[e]={offset:0,hasMore:true,loading:false}),Se.value=true,P.value[e].loading=true;try{const n=(t==null?void 0:t.offset)||0;await yt(y.value,b.value,50,n)||(P.value[e].loading=false)}catch(n){console.error("加载更多消息失败:",n),P.value[e]&&(P.value[e].loading=false)}finally{Se.value=false}}}function Fe(){if(!T.value)return true;const{scrollTop:e,scrollHeight:t,clientHeight:n}=T.value;return t-(e+n)<=200}function Mt(e){var a;if(!y.value)return 0;const t=`${y.value}:${e}`,n=z.value[t];return n!==void 0?n:((a=d.value.messages[t])==null?void 0:a.length)||0}function wn(e,t){e.preventDefault(),e.stopPropagation();const n="touches"in e?e.touches[0].clientX:e.clientX,a="touches"in e?e.touches[0].clientY:e.clientY;Ue.value=Date.now(),N.value={x:n,y:a},O.value={x:n,y:a},ae.value=false;const s=e.target.getBoundingClientRect();Te.value={x:s.left,y:s.top},qe.value={x:n-s.left,y:a-s.top},H.value=window.setTimeout(()=>{if(Ue.value>0){ae.value=true,he.value=t;const c=e.target,l=c.cloneNode(true);l.classList.add("dragging-clone"),l.style.position="fixed",l.style.zIndex="1000",l.style.pointerEvents="none";const u=c.getBoundingClientRect();l.style.left=`${u.left}px`,l.style.top=`${u.top}px`,l.style.width=`${u.width}px`,l.style.height=`${u.height}px`,document.body.appendChild(l),S.value=l,document.body.style.userSelect="none",document.body.style.cursor="grabbing",document.body.classList.add("dragging-bubble-global"),Lt(N.value.x,N.value.y)}},60),document.addEventListener("mousemove",He),document.addEventListener("mouseup",Xe),document.addEventListener("touchmove",He),document.addEventListener("touchend",Xe)}function He(e){if(!ae.value||!S.value)return;e.preventDefault();const t="touches"in e?e.touches[0].clientX:e.clientX,n="touches"in e?e.touches[0].clientY:e.clientY;O.value={x:t,y:n};const a=O.value.x-N.value.x,o=O.value.y-N.value.y,s=Math.sqrt(a*a+o*o),c=Math.max(.3,1-s/(W*2)),l=Math.max(.8,1-s/(W*3)),u=s>W,v=O.value.x-qe.value.x,p=O.value.y-qe.value.y;S.value.style.left=`${v}px`,S.value.style.top=`${p}px`,S.value.style.transform=`scale(${l})`,S.value.style.opacity=`${c}`,S.value.style.backgroundColor=u?"#f44336":"#2196f3",S.value.style.boxShadow=u?"0 4px 12px rgba(244, 67, 54, 0.4)":"0 4px 12px rgba(33, 150, 243, 0.4)",u?S.value.classList.add("will-delete"):S.value.classList.remove("will-delete")}function Xe(e){if(H.value&&(clearTimeout(H.value),H.value=null),H.value&&(clearTimeout(H.value),H.value=null),!ae.value||!he.value){We();return}const t=he.value;if(Math.sqrt(Math.pow(O.value.x-N.value.x,2)+Math.pow(O.value.y-N.value.y,2))>W)_t(t),We();else if(S.value){S.value.style.transition="all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55)";const a=document.querySelector(`[data-channel-id="${t}"] .channel-message-count`);if(a){const o=a.getBoundingClientRect();S.value.style.left=`${o.left}px`,S.value.style.top=`${o.top}px`,S.value.style.transform="scale(1)",S.value.style.opacity="1",S.value.style.backgroundColor="#2196f3",S.value.style.boxShadow="0 4px 12px rgba(33, 150, 243, 0.4)"}setTimeout(()=>{We()},300)}else We()}function We(){H.value&&(clearTimeout(H.value),H.value=null),he.value="",N.value={x:0,y:0},O.value={x:0,y:0},Te.value={x:0,y:0},Ue.value=0,ae.value=false,document.removeEventListener("mousemove",He),document.removeEventListener("mouseup",Xe),document.removeEventListener("touchmove",He),document.removeEventListener("touchend",Xe),document.body.style.userSelect="",document.body.style.cursor="",document.body.classList.remove("dragging-bubble-global"),S.value&&S.value.parentNode&&(S.value.parentNode.removeChild(S.value),S.value=null),Tt()}function In(e){return he.value===e&&ae.value?{visibility:"hidden",pointerEvents:"none",transition:"none"}:{}}function xn(e){if(he.value!==e)return 0;const t=O.value.x-N.value.x,n=O.value.y-N.value.y;return Math.sqrt(t*t+n*n)}async function _t(e){if(y.value)try{const t=`${y.value}:${e}`,n=Mt(e),a=ie.value.keepMessagesOnClear;if(a>0&&n<=a){D("当前消息还很少诶~ 无需清理","success");return}const o=await F("clear-channel-history",{selfId:y.value,channelId:e});if(o.success)if(o.clearedCount&&o.clearedCount>0){if(d.value.messages[t]){const c=[...d.value.messages[t]].sort((l,u)=>l.timestamp-u.timestamp);d.value.messages[t]=c.slice(-o.keptCount)}z.value[t]=o.keptCount,await Qe(t),D(`历史记录已清理,清理了 ${o.clearedCount} 条消息,保留最新 ${o.keptCount} 条`,"success")}else a===0?(d.value.messages[t]&&(d.value.messages[t]=[]),z.value[t]=0,await Qe(t),D("历史记录已清理,所有消息已删除","success")):D("当前消息还很少诶~ 无需清理","success");else console.error("清理历史记录失败:",o.error),D("清理失败: "+o.error,"error")}catch(t){console.error("清理历史记录时出错:",t),D("清理失败: "+((t==null?void 0:t.message)||String(t)),"error")}}function D(e,t="success"){const n=document.createElement("div");n.className=`notification ${t}`,n.textContent=e;let a="#4caf50";switch(t){case"info":a="#2196f3";break;case"warn":a="#ff9800";break;case"error":a="#f44336";break;case"success":a="#4caf50";break}n.style.cssText=`
|
|
2
2
|
position: fixed;
|
|
3
3
|
top: 20px;
|
|
4
4
|
right: 20px;
|
|
@@ -8,7 +8,7 @@ import{defineComponent as Ce,ref as g,onMounted as ut,h as m,computed as te,watc
|
|
|
8
8
|
font-weight: 500;
|
|
9
9
|
z-index: 10000;
|
|
10
10
|
animation: slideIn 0.3s ease-out;
|
|
11
|
-
background: ${
|
|
11
|
+
background: ${a};
|
|
12
12
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
13
13
|
`;const o=document.createElement("style");o.textContent=`
|
|
14
14
|
@keyframes slideIn {
|
|
@@ -19,9 +19,9 @@ import{defineComponent as Ce,ref as g,onMounted as ut,h as m,computed as te,watc
|
|
|
19
19
|
from { transform: translateX(0); opacity: 1; }
|
|
20
20
|
to { transform: translateX(100%); opacity: 0; }
|
|
21
21
|
}
|
|
22
|
-
`,document.head.appendChild(o),document.body.appendChild(
|
|
23
|
-
left: ${e-
|
|
24
|
-
top: ${t-
|
|
25
|
-
width: ${
|
|
26
|
-
height: ${
|
|
27
|
-
`,document.body.appendChild(a),window.dragThresholdCircle=a}function Ct(){const e=window.dragThresholdCircle;e&&e.parentNode&&(e.parentNode.removeChild(e),window.dragThresholdCircle=null)}async function at(){try{if(!x)return false;const e=Date.now();if(e-Ve<Ge)return true;Ve=e;const t=await bt();j=t.totalSize,V=t.totalImages,console.log("数据库健康检查:",{大小:`${(j/1024/1024).toFixed(2)}MB / ${(_/1024/1024).toFixed(2)}MB`,图片数量:`${V} / ${ue}`,使用率:`${(j/_*100).toFixed(1)}%`});const a=j/_,n=V/ue;return(a>Ye||n>Ye)&&(console.warn("数据库使用率过高,开始自动清理"),await Je()),(a>.95||n>.95)&&(console.error("数据库接近极限,执行紧急清理"),await ra()),true}catch(e){return console.error("数据库健康检查失败:",e),false}}async function bt(){return x?new Promise(e=>{const n=x.transaction([$],"readonly").objectStore($).getAll();n.onsuccess=()=>{const o=n.result||[];let s=0;const i={};o.forEach(l=>{s+=l.size||0,i[l.channelKey]=(i[l.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 Je(){try{console.log("开始自动清理...");const e=await kt();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>Xe){s.sort((l,d)=>l.timestamp-d.timestamp);const i=s.slice(0,s.length-Xe);for(const l of i)await ot(l.url),a++,n+=l.size||0,b.value[l.url]&&(URL.revokeObjectURL(b.value[l.url]),delete b.value[l.url])}console.log(`自动清理完成: 清理了 ${a} 张图片,释放了 ${(n/1024/1024).toFixed(2)}MB`),V-=a,j-=n}catch(e){console.error("自动清理失败:",e)}}async function ra(){try{console.log("开始紧急清理...");const e=await kt();if(e.length===0)return;e.sort((s,i)=>i.timestamp-s.timestamp);const t=Math.floor(ue*.3),a=e.slice(t);let n=0,o=0;for(const s of a)await ot(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`),V=t,j-=o}catch(e){console.error("紧急清理失败:",e)}}async function kt(){return x?new Promise(e=>{const n=x.transaction([$],"readonly").objectStore($).getAll();n.onsuccess=()=>{e(n.result||[])},n.onerror=()=>{console.error("获取所有图片失败:",n.error),e([])}}):[]}async function nt(){return new Promise(e=>{try{x&&(x.close(),x=null);const t=indexedDB.deleteDatabase(He);t.onsuccess=()=>{console.log("IndexedDB数据库已完全清理"),j=0,V=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 ca(){try{return await St()?(setTimeout(async()=>{const t=await bt();console.log("数据库初始状态:",{大小:`${(t.totalSize/1024/1024).toFixed(2)}MB`,图片数量:t.totalImages,频道分布:t.channelStats}),(t.totalSize>_*.9||t.totalImages>ue*.9)&&(console.warn("数据库初始状态接近限制,执行清理"),await Je())},1e3),true):(console.warn("数据库打开失败,尝试清理后重新初始化"),await nt(),await St())}catch(e){return console.error("IndexedDB初始化出错:",e),false}}async function St(){return new Promise(e=>{try{const t=indexedDB.open(He,Me);t.onerror=()=>{console.error("IndexedDB打开失败:",t.error),e(false)},t.onsuccess=()=>{x=t.result,x.onerror=a=>{console.error("IndexedDB运行时错误:",a)},x.onversionchange=()=>{console.warn("IndexedDB版本变更,关闭连接"),x==null||x.close(),x=null},e(true)},t.onupgradeneeded=a=>{const n=a.target.result;if(!n.objectStoreNames.contains($)){const o=n.createObjectStore($,{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 Bt(e){return x?new Promise((t,a)=>{const s=x.transaction([$],"readonly").objectStore($).get(e);s.onsuccess=()=>{t(s.result||null)},s.onerror=()=>{console.error("从IndexedDB获取图片失败:",s.error),t(null)}}):null}async function st(e){if(!x)return false;try{return e.size>qe?(console.warn(`图片过大,跳过缓存: ${(e.size/1024/1024).toFixed(2)}MB > ${(qe/1024/1024).toFixed(2)}MB`),false):(await at(),j+e.size>_&&(console.warn("添加图片会超过数据库大小限制,执行清理"),await Je(),j+e.size>_)?(console.warn("清理后仍会超过限制,跳过此图片"),false):V>=ue&&(console.warn("图片数量已达上限,执行清理"),await Je(),V>=ue)?(console.warn("清理后仍达上限,跳过此图片"),false):new Promise(t=>{const o=x.transaction([$],"readwrite").objectStore($).put(e);o.onsuccess=()=>{j+=e.size,V+=1,t(true)},o.onerror=()=>{console.error("保存图片到IndexedDB失败:",o.error),t(false)}}))}catch(t){return console.error("保存图片时出错:",t),false}}async function ot(e){return x?new Promise(t=>{const o=x.transaction([$],"readwrite").objectStore($).delete(e);o.onsuccess=()=>{t(true)},o.onerror=()=>{console.error("从IndexedDB删除图片失败:",o.error),t(false)}}):false}async function ia(e){return x?new Promise(t=>{const s=x.transaction([$],"readonly").objectStore($).index("channelKey").getAll(e);s.onsuccess=()=>{t(s.result||[])},s.onerror=()=>{console.error("获取频道图片失败:",s.error),t([])}}):[]}async function lt(e,t){if(Y.has(t))return Y.get(t)||null;const a=b.value[t];if(a)return a;const n=(async()=>{try{const o=b.value[t];if(o)return o;const s=await Bt(t);if(!s)return null;We();const i=URL.createObjectURL(s.blob);return b.value[t]=i,Pe(Ze(s.blob)),s.timestamp=Date.now(),await st(s),i}catch(o){return console.error("获取缓存图片失败:",o),null}finally{Y.delete(t)}})();return Y.set(t,n),n}async function Ie(e,t){if(Y.has(t))return Y.get(t)||null;const a=b.value[t];if(a)return a;const n=(async()=>{try{const o=b.value[t];if(o)return o;const s=await Bt(t);if(s){We();const xe=URL.createObjectURL(s.blob);return b.value[t]=xe,Pe(Ze(s.blob)),s.timestamp=Date.now(),await st(s),xe}const i=await U("fetch-image",{url:t});if(!i.success)return null;const l=i.base64,d=i.contentType||"image/jpeg",v=atob(l),p=new Array(v.length);for(let xe=0;xe<v.length;xe++)p[xe]=v.charCodeAt(xe);const I=new Uint8Array(p),q=new Blob([I],{type:d});if(q.size>qe)return null;const H=b.value[t];if(H)return H;const Ca={url:t,blob:q,timestamp:Date.now(),size:q.size,channelKey:e};if(!await st(Ca))return null;We();const Tt=URL.createObjectURL(q);return b.value[t]=Tt,Pe(Ze(q)),Tt}catch(o){return console.error("缓存图片失败:",o),null}finally{Y.delete(t)}})();return Y.set(t,n),n}async function Ne(e){try{const t=await ia(e);let a=0;for(const n of t)await ot(n.url),b.value[n.url]&&(URL.revokeObjectURL(b.value[n.url]),delete b.value[n.url],a+=n.size||0);a>0&&Pe(-a)}catch(t){console.error("清理频道图片缓存失败:",t)}}function ua(){const e=Object.keys(b.value).length;return{blobCount:e,estimatedMemoryUsage:ye,maxMemoryLimit:Te,maxBlobLimit:ge,memoryUsagePercent:(ye/Te*100).toFixed(1),blobUsagePercent:(e/ge*100).toFixed(1)}}async function da(){return x?new Promise(e=>{const n=x.transaction([$],"readonly").objectStore($).getAll();n.onsuccess=()=>{const o=n.result||[],s=new Set;let i=0;o.forEach(l=>{s.add(l.channelKey),i+=l.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 rt(){y.value&&S.value&&(localStorage.setItem("chat-selected-bot",y.value),localStorage.setItem("chat-selected-channel",S.value))}function $t(){const e=localStorage.getItem("chat-selected-bot"),t=localStorage.getItem("chat-selected-channel");return e&&t&&u.value.bots[e]&&u.value.channels[e]&&u.value.channels[e][t]?(y.value=e,S.value=t,true):false}function Dt(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(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},d=u.value.messages[s];let v=d.length;for(let I=d.length-1;I>=0;I--){if(d[I].timestamp<=e.timestamp){v=I+1;break}I===0&&(v=0)}d.splice(v,0,l),d.length>100&&(u.value.messages[s]=d.slice(-100)),R.value[s]=d.length;const p=Re();me(()=>{setTimeout(()=>{p&&he()},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 l=i.attrs.src||i.attrs.url||i.attrs.file;l&&Ie(s,l).catch(d=>{console.warn("预缓存图片失败:",l,d)})}})}u.value={...u.value}}function fa(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 l=o.length-1;l>=0;l--){if(o[l].timestamp<=e.timestamp){s=l+1;break}l===0&&(s=0)}o.splice(s,0,n),o.length>100&&(u.value.messages[t]=o.slice(-100)),R.value[t]=o.length;const i=Re();me(()=>{setTimeout(()=>{i&&he()},10)})}u.value={...u.value}}function ha(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(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},d=u.value.messages[s];let v=d.length;for(let I=d.length-1;I>=0;I--){if(d[I].timestamp<=e.timestamp){v=I+1;break}I===0&&(v=0)}d.splice(v,0,l),d.length>100&&(u.value.messages[s]=d.slice(-100)),R.value[s]=d.length;const p=Re();me(()=>{setTimeout(()=>{p&&he()},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 l=i.attrs.src||i.attrs.url||i.attrs.file;l&&Ie(s,l).catch(d=>{console.warn("预缓存图片失败:",l,d)})}})}u.value={...u.value}}async function ma(){try{const e=await U("get-chat-data");if(e.success&&e.data){const t={};h.value=new Set(e.data.pinnedBots||[]),r.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 va(),true}else return console.warn("获取聊天数据失败:",e.error),false}catch(e){return console.error("获取聊天数据时出错:",e),false}}async function va(){try{const e=await U("get-all-channel-message-counts");if(e.success&&e.counts){const t={};for(const[a,n]of Object.entries(e.counts))t[a]=n;R.value=t}else console.warn("获取频道消息数量失败:",e.error)}catch(e){console.error("获取频道消息数量时出错:",e)}}async function ga(){try{const e=await U("get-plugin-config");e.success&&e.config?se.value=e.config:console.warn("获取插件配置失败:",e.error)}catch(e){console.error("获取插件配置时出错:",e)}}async function ct(e,t,a,n){try{const o={selfId:e,channelId:t};a!==void 0&&(o.limit=a,o.offset=n||0);const s=await U("get-history-messages",o);if(s.success&&s.messages){const i=`${e}:${t}`,l=s.messages.map(v=>({id:v.id,content:v.content,userId:v.userId,username:v.username,avatar:v.avatar,timestamp:v.timestamp,channelId:v.channelId,selfId:v.selfId,elements:v.elements,isBot:v.type==="bot",quote:v.quote})),d=n||0;if(a!==void 0)if(l.sort((v,p)=>v.timestamp-p.timestamp),n===0)u.value.messages[i]=l,K.value[i]={offset:l.length,hasMore:l.length>=a&&s.total>l.length,loading:false};else{const v=u.value.messages[i]||[];u.value.messages[i]=[...l,...v];const p=n||0;K.value[i]={offset:p+l.length,hasMore:l.length>=a&&s.total>p+l.length,loading:false}}else l.sort((v,p)=>v.timestamp-p.timestamp),u.value.messages[i]=l,K.value[i]={offset:l.length,hasMore:false,loading:false};return R.value[i]=s.total||l.length,u.value={...u.value},true}else return console.warn("获取历史消息失败:",s.error),false}catch(o){return console.error("获取历史消息时出错:",o),false}}function ya(e){if(!P.value||e.touches.length!==1)return;const t=e.touches[0];N.value={x:t.clientX,y:t.clientY,time:Date.now()},oe.value={x:t.clientX,y:t.clientY},Se.value=false}function pa(e){if(!P.value||!N.value||e.touches.length!==1)return;const t=e.touches[0];oe.value={x:t.clientX,y:t.clientY};const a=t.clientX-N.value.x,n=t.clientY-N.value.y;if(Math.abs(a)>Math.abs(n)&&Math.abs(a)>30){const o=a>0,s=J.value==="messages"||J.value==="channels";if(o&&s){Se.value=true;const i=Math.min(a,200),l=150;i>l?G.value={show:true,text:"松开返回"}:G.value={show:true,text:`滑动返回 ${Math.round(i/l*100)}%`},e.preventDefault()}else G.value={show:false,text:""}}else G.value={show:false,text:""}}function wa(e){if(!P.value||!N.value)return;const a=Date.now()-N.value.time;if(oe.value){const n=oe.value.x-N.value.x,o=oe.value.y-N.value.y,s=n>150,i=Math.abs(n)>Math.abs(o),l=a<300&&n>80;(s&&i||l)&&Ia()}N.value=null,oe.value=null,Se.value=false,G.value={show:false,text:""}}function Ia(){switch(J.value){case"messages":J.value="channels";break;case"channels":J.value="bots",y.value="",S.value="";break}}function it(){P.value=window.innerWidth<=768}function _t(){return!le.value||Re()}const Lt=()=>{P.value&&L.value&&me(()=>{_t()&&he()})},xa=()=>{P.value&&setTimeout(()=>{L.value&&_t()&&he()},300)};return Mt(mt,(e,t)=>{t.length===0&&e.length>0&&me(()=>{he()})}),ut(async()=>{it(),window.addEventListener("resize",it),window.visualViewport&&window.visualViewport.addEventListener("resize",Lt),document.addEventListener("click",tt),await ga(),se.value.clearIndexedDBOnStart&&(console.log("启动时清空 IndexedDB 缓存..."),await nt()?console.log("IndexedDB 缓存已清空"):console.warn("清空 IndexedDB 缓存失败")),await ca()?(console.log("IndexedDB初始化成功"),setTimeout(async()=>{await at()},2e3),setInterval(async()=>{await at()},5*60*1e3)):console.warn("IndexedDB初始化失败,图片缓存功能将不可用"),await ma(),me(()=>{$t()});const t=ht("chat-message-event",Dt),a=ht("bot-message-sent-event",fa),n=ht("chat-bot-message-event",ha);Mt(S,o=>{o&&me(()=>{L.value&&(L.value.removeEventListener("scroll",Ae),L.value.addEventListener("scroll",Ae),Ae()),!P.value&&fe.value&&fe.value.focus()})},{immediate:true}),setInterval(()=>{We()},2*60*1e3),ba(()=>{window.removeEventListener("resize",it),window.visualViewport&&window.visualViewport.removeEventListener("resize",Lt),document.removeEventListener("click",tt),t&&typeof t=="function"&&t(),a&&typeof a=="function"&&a(),n&&typeof n=="function"&&n(),L.value&&L.value.removeEventListener("scroll",Ae),Object.values(b.value).forEach(o=>{URL.revokeObjectURL(o)}),b.value={},x&&(x.close(),x=null)})}),{AvatarComponent:ie,ImageComponent:X,JsonCardComponent:ve,ForwardMessageComponent:E,MessageElement:be,chatData:u,channelMessageCounts:R,channelPagination:K,pluginConfig:se,selectedBot:y,selectedChannel:S,inputMessage:ke,imageBlobUrls:b,pinnedBots:h,pinnedChannels:r,uploadedImages:W,showActionMenu:de,isMobile:P,mobileView:J,touchStart:N,touchCurrent:oe,isSwipeActive:Se,swipeIndicator:G,messageHistory:L,messageInput:fe,showScrollButton:Be,isUserScrolling:le,isSending:pe,isLoadingMore:we,draggingChannel:re,dragStartPos:O,dragCurrentPos:A,dragElementInitialPos:$e,dragOffset:De,dragThreshold:F,isDragReady:ee,draggedBubbleElement:k,contextMenu:Z,fileInput:Ke,bots:M,currentChannels:je,currentMessages:mt,currentChannelName:Pt,currentChannelKey:At,canSendMessage:vt,canInputMessage:Rt,mobileViewClass:Ot,inputPlaceholder:Ut,chatContainerStyle:zt,selectBot:Nt,selectChannel:Jt,handleBotRightClick:Ft,handleChannelRightClick:Ht,showContextMenu:Qe,hideContextMenu:Q,handleKeyDown:Ee,toggleBotPin:Xt,toggleChannelPin:Yt,deleteBotMessages:Vt,deleteChannelMessages:Wt,sendMessage:Gt,toggleActionMenu:Zt,triggerImageUpload:Qt,handleFileSelect:Et,handlePaste:ea,uploadImage:et,removeImage:ta,fileToBase64:yt,handleClickOutside:tt,formatTime:aa,getChannelTypeText:na,scrollToBottom:he,checkScrollPosition:Ae,isNearBottom:Re,getChannelMessageCount:wt,startDrag:sa,handleDragMove:Oe,handleDragEnd:Ue,resetDragState:ze,getDragStyle:oa,getDragDistance:la,clearChannelHistory:It,showNotification:T,createThresholdCircle:xt,removeThresholdCircle:Ct,handleTouchStart:ya,handleTouchMove:pa,handleTouchEnd:wa,handleInputFocus:xa,loadMoreMessages:pt,getCachedImageUrl:lt,cacheImage:Ie,clearChannelImageCache:Ne,clearAllIndexedDBData:nt,getMemoryStats:ua,getCacheStats:da,isFileUrl:ne,loadHistoryMessages:ct,handleMessageEvent:Dt,saveSelectionState:rt,restoreSelectionState:$t}}const Ta={class:"bot-list"},Ma={class:"bot-items"},qa=["onClick","onContextmenu"],Ka={class:"bot-avatar"},ja={key:1,class:"avatar-placeholder"},Pa={class:"bot-info"},Aa={class:"bot-name"},Ra={class:"bot-platform"},Oa={class:"channel-list"},Ua={key:0,class:"empty-state"},za={key:1,class:"channel-items"},Na=["data-channel-id","onClick","onContextmenu"],Fa={class:"channel-info"},Ha={class:"channel-name"},Xa={class:"channel-type"},Ya=["onMousedown","onTouchstart","title"],Va={class:"message-area"},Wa={class:"panel-header"},Ja={key:0,class:"empty-state"},Ga={key:1,class:"message-content"},Za={key:0,class:"loading-more-indicator"},Qa={class:"message-avatar"},Ea={key:1,class:"avatar-placeholder"},en={class:"message-content-wrapper"},tn={class:"message-header"},an={class:"message-username"},nn={class:"message-time"},sn={key:0,class:"message-quote"},on={class:"quote-header"},ln={class:"quote-avatar"},rn={key:1,class:"avatar-placeholder"},cn={class:"quote-username"},un={class:"quote-time"},dn={class:"quote-content"},fn={class:"message-text"},hn={class:"message-input"},mn={key:0,class:"image-preview-container"},vn=["src","alt"],gn=["onClick"],yn={class:"input-row"},pn={class:"input-actions"},wn=["placeholder","disabled"],In=["disabled"],xn=Ce({__name:"index",setup(ne){const ie=La(),{AvatarComponent:X,MessageElement:ve,selectedBot:E,selectedChannel:be,inputMessage:u,pinnedBots:R,pinnedChannels:K,uploadedImages:se,showActionMenu:b,swipeIndicator:Y,messageHistory:Te,messageInput:ge,showScrollButton:ye,isSending:x,isLoadingMore:He,draggingChannel:Me,dragThreshold:$,contextMenu:_,fileInput:Xe,bots:ue,currentChannels:qe,currentMessages:Ye,currentChannelName:Ge,currentChannelKey:j,canSendMessage:V,canInputMessage:Ve,mobileViewClass:y,inputPlaceholder:S,chatContainerStyle:ke,selectBot:W,selectChannel:de,handleBotRightClick:Ke,handleChannelRightClick:P,toggleBotPin:J,toggleChannelPin:N,deleteBotMessages:oe,deleteChannelMessages:Se,sendMessage:G,toggleActionMenu:L,triggerImageUpload:fe,handleFileSelect:Be,handlePaste:le,removeImage:pe,formatTime:we,getChannelTypeText:re,scrollToBottom:O,getChannelMessageCount:A,startDrag:$e,getDragStyle:De,getDragDistance:F,handleTouchStart:_e,handleTouchMove:z,handleTouchEnd:ee,handleInputFocus:k}=ie;return(Z,h)=>(w(),C("div",{class:ce(["chat-container",c(y)]),style:dt(c(ke)),onTouchstart:h[15]||(h[15]=(...r)=>c(_e)&&c(_e)(...r)),onTouchmove:h[16]||(h[16]=(...r)=>c(z)&&c(z)(...r)),onTouchend:h[17]||(h[17]=(...r)=>c(ee)&&c(ee)(...r))},[B(" 左侧机器人列表 "),f("div",Ta,[h[18]||(h[18]=f("div",{class:"panel-header"},[f("h3",null,"机器人")],-1)),f("div",Ma,[(w(true),C(ae,null,Le(c(ue),r=>(w(),C("div",{key:r.selfId,class:ce(["bot-item",{active:c(E)===r.selfId,pinned:c(R).has(r.selfId)}]),onClick:M=>c(W)(r.selfId),onContextmenu:M=>c(Ke)(M,r.selfId)},[f("div",Ka,[r.avatar?(w(),Fe(c(X),{key:0,src:r.avatar,alt:r.username,"channel-key":"bot-list"},null,8,["src","alt"])):(w(),C("div",ja,D(r.username.charAt(0).toUpperCase()),1))]),f("div",Pa,[f("div",Aa,D(r.username),1),f("div",Ra,D(r.platform),1)]),f("div",{class:ce(["bot-status",r.status])},null,2)],42,qa))),128))])]),B(" 中间频道列表 "),f("div",Oa,[h[19]||(h[19]=f("div",{class:"panel-header"},[f("h3",null,"频道")],-1)),c(E)?(w(),C("div",za,[(w(true),C(ae,null,Le(c(qe),r=>(w(),C("div",{key:r.id,class:ce(["channel-item",{active:c(be)===r.id,pinned:c(K).has(`${c(E)}:${r.id}`)}]),"data-channel-id":r.id,onClick:M=>c(de)(r.id),onContextmenu:M=>c(P)(M,r.id)},[f("div",Fa,[f("div",Ha,D(r.name),1),f("div",Xa,D(c(re)(r.type)),1)]),c(A)(r.id)>0?(w(),C("div",{key:0,class:ce(["channel-message-count draggable-bubble",{dragging:c(Me)===r.id,"will-delete":c(Me)===r.id&&c(F)(r.id)>c($)}]),onMousedown:M=>c($e)(M,r.id),onTouchstart:M=>c($e)(M,r.id),style:dt(c(De)(r.id)),title:c(Me)===r.id?c(F)(r.id)>c($)?"松开清理历史记录":"拖拽更远以清理历史记录":"拖拽清理历史记录"},D(c(A)(r.id)),47,Ya)):B("v-if",true)],42,Na))),128))])):(w(),C("div",Ua," 请选择一个机器人 "))]),B(" 右侧消息区域 "),f("div",Va,[f("div",Wa,[f("h3",null,D(c(Ge)||"选择频道"),1)]),!c(E)||!c(be)?(w(),C("div",Ja," 请选择机器人和频道 ")):(w(),C("div",Ga,[B(" 消息历史 "),f("div",{class:"message-history",ref_key:"messageHistory",ref:Te},[B(" 加载更多指示器 "),c(He)?(w(),C("div",Za,h[20]||(h[20]=[f("div",{class:"loading-spinner"},null,-1),f("span",null,"加载更多消息中...",-1)]))):B("v-if",true),(w(true),C(ae,null,Le(c(Ye),r=>(w(),C("div",{key:r.id,class:ce(["message-item",{"bot-message":r.isBot}])},[f("div",Qa,[r.avatar?(w(),Fe(c(X),{key:0,src:r.avatar,alt:r.username,"channel-key":c(j)},null,8,["src","alt","channel-key"])):(w(),C("div",Ea,D(r.username.charAt(0).toUpperCase()),1))]),f("div",en,[f("div",tn,[f("span",an,D(r.username),1),f("span",nn,D(c(we)(r.timestamp)),1)]),B(" 引用消息显示 "),r.quote?(w(),C("div",sn,[f("div",on,[f("div",ln,[r.quote.user.avatar?(w(),Fe(c(X),{key:0,src:r.quote.user.avatar,alt:r.quote.user.username,"channel-key":c(j)},null,8,["src","alt","channel-key"])):(w(),C("div",rn,D(r.quote.user.username.charAt(0).toUpperCase()),1))]),f("span",cn,D(r.quote.user.username),1),f("span",un,D(c(we)(r.quote.timestamp)),1)]),f("div",dn,[r.quote.elements&&r.quote.elements.length>0?(w(true),C(ae,{key:0},Le(r.quote.elements,(M,je)=>(w(),Fe(c(ve),{key:`quote-${je}`,element:M,"channel-key":c(j)},null,8,["element","channel-key"]))),128)):(w(),C(ae,{key:1},[ft(D(r.quote.content),1)],64))])])):B("v-if",true),f("div",fn,[r.elements&&r.elements.length>0?(w(true),C(ae,{key:0},Le(r.elements,(M,je)=>(w(),Fe(c(ve),{key:je,element:M,"channel-key":c(j)},null,8,["element","channel-key"]))),128)):(w(),C(ae,{key:1},[ft(D(r.content),1)],64))])])],2))),128))],512),B(" 悬浮的滚动到底部按钮 "),qt(f("div",{class:"floating-scroll-button",onClick:h[0]||(h[0]=(...r)=>c(O)&&c(O)(...r))},h[21]||(h[21]=[f("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor"},[f("path",{d:"M7 10l5 5 5-5z"})],-1)]),512),[[ka,c(ye)]]),B(" 输入框 "),f("div",hn,[B(" 图片预览区域 "),c(se).length>0?(w(),C("div",mn,[(w(true),C(ae,null,Le(c(se),r=>(w(),C("div",{key:r.tempId,class:"image-preview-item"},[f("img",{src:r.preview,alt:r.filename,class:"preview-image"},null,8,vn),f("button",{class:"remove-image-btn",onClick:M=>c(pe)(r.tempId),title:"删除图片"},h[22]||(h[22]=[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,gn)]))),128))])):B("v-if",true),f("div",yn,[B(" 加号按钮 "),f("div",pn,[f("button",{class:ce(["add-button",{active:c(b)}]),onClick:h[1]||(h[1]=(...r)=>c(L)&&c(L)(...r)),title:"更多操作"},h[23]||(h[23]=[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),B(" 操作菜单 "),c(b)?(w(),C("div",{key:0,class:"action-menu",onClick:h[3]||(h[3]=Kt(()=>{},["stop"]))},[f("button",{class:"action-menu-item",onClick:h[2]||(h[2]=(...r)=>c(fe)&&c(fe)(...r))},h[24]||(h[24]=[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),ft(" 上传图片 ",-1)]))])):B("v-if",true)]),qt(f("input",{"onUpdate:modelValue":h[4]||(h[4]=r=>Ba(u)?u.value=r:null),type:"text",placeholder:c(S),onKeyup:h[5]||(h[5]=Sa((...r)=>c(G)&&c(G)(...r),["enter"])),disabled:!c(Ve),ref_key:"messageInput",ref:ge,onPaste:h[6]||(h[6]=(...r)=>c(le)&&c(le)(...r)),onFocus:h[7]||(h[7]=(...r)=>c(k)&&c(k)(...r))},null,40,wn),[[$a,c(u)]]),f("button",{onClick:h[8]||(h[8]=(...r)=>c(G)&&c(G)(...r)),disabled:!c(V),class:ce({"is-sending":c(x)})},D(c(x)?"发送中...":"发送"),11,In)]),B(" 隐藏的文件输入 "),f("input",{type:"file",ref_key:"fileInput",ref:Xe,onChange:h[9]||(h[9]=(...r)=>c(Be)&&c(Be)(...r)),accept:"image/*",multiple:"",style:{display:"none"}},null,544)])]))]),B(" 右键菜单 "),c(_).show?(w(),C("div",{key:0,class:"context-menu",style:dt({left:c(_).x+"px",top:c(_).y+"px"}),onClick:h[14]||(h[14]=Kt(()=>{},["stop"]))},[B(" 机器人右键菜单 "),c(_).type==="bot"?(w(),C(ae,{key:0},[f("div",{class:"context-menu-item",onClick:h[10]||(h[10]=r=>c(J)(c(_).targetId))},D(c(R).has(c(_).targetId)?"取消置顶":"置顶"),1),f("div",{class:"context-menu-item danger",onClick:h[11]||(h[11]=r=>c(oe)(c(_).targetId))}," 彻底删除此机器人所有数据 ")],64)):B("v-if",true),B(" 频道右键菜单 "),c(_).type==="channel"?(w(),C(ae,{key:1},[f("div",{class:"context-menu-item",onClick:h[12]||(h[12]=r=>c(N)(c(_).targetId))},D(c(K).has(`${c(E)}:${c(_).targetId}`)?"取消置顶":"置顶"),1),f("div",{class:"context-menu-item danger",onClick:h[13]||(h[13]=r=>c(Se)(c(_).targetId))}," 彻底删除此频道所有数据 ")],64)):B("v-if",true)],4)):B("v-if",true),B(" 滑动指示器 "),f("div",{class:ce(["swipe-indicator",{show:c(Y).show}])},D(c(Y).text),3)],38))}}),jt=(ne,ie)=>{const X=ne.__vccOpts||ne;for(const[ve,E]of ie)X[ve]=E;return X},Cn=jt(xn,[["__scopeId","data-v-f8e0fc57"]]),bn={},kn={class:"k-icon",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none"};function Sn(ne,ie){return w(),C("svg",kn,ie[0]||(ie[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 Bn=jt(bn,[["render",Sn]]);_a.register("activity:chat",Bn);const Ln=ne=>{ne.page({name:"聊天室",path:"/chat-patch",desc:"",authority:4,icon:"activity:chat",component:Ce({setup(){return()=>m(Da("k-layout"),{},{default:()=>m(Cn)})}})})};export{Ln as default};
|
|
22
|
+
`,document.head.appendChild(o),document.body.appendChild(n),setTimeout(()=>{n.style.animation="slideOut 0.3s ease-in",setTimeout(()=>{n.parentNode&&n.parentNode.removeChild(n),o.parentNode&&o.parentNode.removeChild(o)},300)},3e3)}function Lt(e,t){const n=document.createElement("div");n.className="drag-threshold-circle",n.style.cssText=`
|
|
23
|
+
left: ${e-W}px;
|
|
24
|
+
top: ${t-W}px;
|
|
25
|
+
width: ${W*2}px;
|
|
26
|
+
height: ${W*2}px;
|
|
27
|
+
`,document.body.appendChild(n),window.dragThresholdCircle=n}function Tt(){const e=window.dragThresholdCircle;e&&e.parentNode&&(e.parentNode.removeChild(e),window.dragThresholdCircle=null)}async function dt(){try{if(!x)return false;const e=Date.now();if(e-Ge<tt)return true;Ge=e;const t=await qt();j=t.totalSize,J=t.totalImages,console.log("数据库健康检查:",{大小:`${(j/1024/1024).toFixed(2)}MB / ${(B/1024/1024).toFixed(2)}MB`,图片数量:`${J} / ${ye}`,使用率:`${(j/B*100).toFixed(1)}%`});const n=j/B,a=J/ye;return(n>q||a>q)&&(console.warn("数据库使用率过高,开始自动清理"),await et()),(n>.95||a>.95)&&(console.error("数据库接近极限,执行紧急清理"),await Cn()),true}catch(e){return console.error("数据库健康检查失败:",e),false}}async function qt(){return x?new Promise(e=>{const a=x.transaction([_],"readonly").objectStore(_).getAll();a.onsuccess=()=>{const o=a.result||[];let s=0;const c={};o.forEach(l=>{s+=l.size||0,c[l.channelKey]=(c[l.channelKey]||0)+1}),e({totalSize:s,totalImages:o.length,channelStats:c})},a.onerror=()=>{console.error("获取数据库统计失败:",a.error),e({totalSize:0,totalImages:0,channelStats:{}})}}):{totalSize:0,totalImages:0,channelStats:{}}}async function et(){try{console.log("开始自动清理...");const e=await Ut();if(e.length===0)return;const t={};e.forEach(o=>{t[o.channelKey]||(t[o.channelKey]=[]),t[o.channelKey].push(o)});let n=0,a=0;for(const[o,s]of Object.entries(t))if(s.length>Je){s.sort((l,u)=>l.timestamp-u.timestamp);const c=s.slice(0,s.length-Je);for(const l of c)await mt(l.url),n++,a+=l.size||0,k.value[l.url]&&(URL.revokeObjectURL(k.value[l.url]),delete k.value[l.url])}console.log(`自动清理完成: 清理了 ${n} 张图片,释放了 ${(a/1024/1024).toFixed(2)}MB`),J-=n,j-=a}catch(e){console.error("自动清理失败:",e)}}async function Cn(){try{console.log("开始紧急清理...");const e=await Ut();if(e.length===0)return;e.sort((s,c)=>c.timestamp-s.timestamp);const t=Math.floor(ye*.3),n=e.slice(t);let a=0,o=0;for(const s of n)await mt(s.url),a++,o+=s.size||0,k.value[s.url]&&(URL.revokeObjectURL(k.value[s.url]),delete k.value[s.url]);console.log(`紧急清理完成: 清理了 ${a} 张图片,释放了 ${(o/1024/1024).toFixed(2)}MB`),J=t,j-=o}catch(e){console.error("紧急清理失败:",e)}}async function Ut(){return x?new Promise(e=>{const a=x.transaction([_],"readonly").objectStore(_).getAll();a.onsuccess=()=>{e(a.result||[])},a.onerror=()=>{console.error("获取所有图片失败:",a.error),e([])}}):[]}async function ft(){return new Promise(e=>{try{x&&(x.close(),x=null);const t=indexedDB.deleteDatabase(Ve);t.onsuccess=()=>{console.log("IndexedDB数据库已完全清理"),j=0,J=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 bn(){try{return await Kt()?(setTimeout(async()=>{const t=await qt();console.log("数据库初始状态:",{大小:`${(t.totalSize/1024/1024).toFixed(2)}MB`,图片数量:t.totalImages,频道分布:t.channelStats}),(t.totalSize>B*.9||t.totalImages>ye*.9)&&(console.warn("数据库初始状态接近限制,执行清理"),await et())},1e3),true):(console.warn("数据库打开失败,尝试清理后重新初始化"),await ft(),await Kt())}catch(e){return console.error("IndexedDB初始化出错:",e),false}}async function Kt(){return new Promise(e=>{try{const t=indexedDB.open(Ve,je);t.onerror=()=>{console.error("IndexedDB打开失败:",t.error),e(false)},t.onsuccess=()=>{x=t.result,x.onerror=n=>{console.error("IndexedDB运行时错误:",n)},x.onversionchange=()=>{console.warn("IndexedDB版本变更,关闭连接"),x==null||x.close(),x=null},e(true)},t.onupgradeneeded=n=>{const a=n.target.result;if(!a.objectStoreNames.contains(_)){const o=a.createObjectStore(_,{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 Rt(e){return x?new Promise((t,n)=>{const s=x.transaction([_],"readonly").objectStore(_).get(e);s.onsuccess=()=>{t(s.result||null)},s.onerror=()=>{console.error("从IndexedDB获取图片失败:",s.error),t(null)}}):null}async function ht(e){if(!x)return false;try{return e.size>Ae?(console.warn(`图片过大,跳过缓存: ${(e.size/1024/1024).toFixed(2)}MB > ${(Ae/1024/1024).toFixed(2)}MB`),false):(await dt(),j+e.size>B&&(console.warn("添加图片会超过数据库大小限制,执行清理"),await et(),j+e.size>B)?(console.warn("清理后仍会超过限制,跳过此图片"),false):J>=ye&&(console.warn("图片数量已达上限,执行清理"),await et(),J>=ye)?(console.warn("清理后仍达上限,跳过此图片"),false):new Promise(t=>{const o=x.transaction([_],"readwrite").objectStore(_).put(e);o.onsuccess=()=>{j+=e.size,J+=1,t(true)},o.onerror=()=>{console.error("保存图片到IndexedDB失败:",o.error),t(false)}}))}catch(t){return console.error("保存图片时出错:",t),false}}async function mt(e){return x?new Promise(t=>{const o=x.transaction([_],"readwrite").objectStore(_).delete(e);o.onsuccess=()=>{t(true)},o.onerror=()=>{console.error("从IndexedDB删除图片失败:",o.error),t(false)}}):false}async function kn(e){return x?new Promise(t=>{const s=x.transaction([_],"readonly").objectStore(_).index("channelKey").getAll(e);s.onsuccess=()=>{t(s.result||[])},s.onerror=()=>{console.error("获取频道图片失败:",s.error),t([])}}):[]}async function vt(e,t){if(V.has(t))return V.get(t)||null;const n=k.value[t];if(n)return n;const a=(async()=>{try{const o=k.value[t];if(o)return o;const s=await Rt(t);if(!s)return null;Ze();const c=URL.createObjectURL(s.blob);return k.value[t]=c,me(M(s.blob)),s.timestamp=Date.now(),await ht(s),c}catch(o){return console.error("获取缓存图片失败:",o),null}finally{V.delete(t)}})();return V.set(t,a),a}async function $e(e,t){if(V.has(t))return V.get(t)||null;const n=k.value[t];if(n)return n;const a=(async()=>{try{const o=k.value[t];if(o)return o;const s=await Rt(t);if(s){Ze();const Be=URL.createObjectURL(s.blob);return k.value[t]=Be,me(M(s.blob)),s.timestamp=Date.now(),await ht(s),Be}const c=await F("fetch-image",{url:t});if(!c.success)return null;const l=c.base64,u=c.contentType||"image/jpeg",v=atob(l),p=new Array(v.length);for(let Be=0;Be<v.length;Be++)p[Be]=v.charCodeAt(Be);const I=new Uint8Array(p),R=new Blob([I],{type:u});if(R.size>Ae)return null;const Q=k.value[t];if(Q)return Q;const Rn={url:t,blob:R,timestamp:Date.now(),size:R.size,channelKey:e};if(!await ht(Rn))return null;Ze();const Nt=URL.createObjectURL(R);return k.value[t]=Nt,me(M(R)),Nt}catch(o){return console.error("缓存图片失败:",o),null}finally{V.delete(t)}})();return V.set(t,a),a}async function Qe(e){try{const t=await kn(e);let n=0;for(const a of t)await mt(a.url),k.value[a.url]&&(URL.revokeObjectURL(k.value[a.url]),delete k.value[a.url],n+=a.size||0);n>0&&me(-n)}catch(t){console.error("清理频道图片缓存失败:",t)}}function Sn(){const e=Object.keys(k.value).length;return{blobCount:e,estimatedMemoryUsage:be,maxMemoryLimit:Pe,maxBlobLimit:Ce,memoryUsagePercent:(be/Pe*100).toFixed(1),blobUsagePercent:(e/Ce*100).toFixed(1)}}async function $n(){return x?new Promise(e=>{const a=x.transaction([_],"readonly").objectStore(_).getAll();a.onsuccess=()=>{const o=a.result||[],s=new Set;let c=0;o.forEach(l=>{s.add(l.channelKey),c+=l.size}),e({totalImages:o.length,totalSize:c,channels:s.size})},a.onerror=()=>{console.error("获取缓存统计失败:",a.error),e({totalImages:0,totalSize:0,channels:0})}}):{totalImages:0,totalSize:0,channels:0}}function gt(){y.value&&b.value&&(localStorage.setItem("chat-selected-bot",y.value),localStorage.setItem("chat-selected-channel",b.value))}function Pt(){const e=localStorage.getItem("chat-selected-bot"),t=localStorage.getItem("chat-selected-channel");return e&&t&&d.value.bots[e]&&d.value.channels[e]&&d.value.channels[e][t]?(y.value=e,b.value=t,true):false}function jt(e){var t,n,a,o;if(!d.value.bots[e.selfId])d.value.bots[e.selfId]={selfId:e.selfId,platform:e.platform,username:((t=e.bot)==null?void 0:t.name)||`Bot-${e.selfId}`,avatar:(n=e.bot)==null?void 0:n.avatar,status:"online"};else{const s=d.value.bots[e.selfId];s.status="online",(a=e.bot)!=null&&a.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(d.value.channels[e.selfId]||(d.value.channels[e.selfId]={}),e.channelId&&!d.value.channels[e.selfId][e.channelId]){const s=e.isDirect?`私信 ${e.channelId}`:`${e.guildName||e.channelId} (${e.channelId})`;d.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(d.value.messages[s]||(d.value.messages[s]=[]),!d.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},u=d.value.messages[s];let v=u.length;for(let I=u.length-1;I>=0;I--){if(u[I].timestamp<=e.timestamp){v=I+1;break}I===0&&(v=0)}u.splice(v,0,l),u.length>100&&(d.value.messages[s]=u.slice(-100)),z.value[s]=u.length;const p=Fe();le(()=>{setTimeout(()=>{p&&Ie()},10)})}}if(e.elements&&e.elements.length>0){const s=`${e.selfId}:${e.channelId}`;e.elements.forEach(c=>{if((c.type==="img"||c.type==="image"||c.type==="mface")&&c.attrs){const l=c.attrs.src||c.attrs.url||c.attrs.file;l&&$e(s,l).catch(u=>{console.warn("预缓存图片失败:",l,u)})}})}d.value={...d.value}}function At(e){const t=`${e.selfId}:${e.channelId}`;d.value.messages[t]||(d.value.messages[t]=[]);const n=d.value.messages[t],a=n.findIndex(o=>o.id.startsWith("bot-msg-")&&Math.abs(o.timestamp-e.timestamp)<5e3);if(a!==-1){const o=n[a];o.id=e.messageId,o.content=e.content,o.userId=e.selfId,o.username=e.botUsername,o.avatar=e.botAvatar,o.channelId=e.channelId,o.selfId=e.selfId,o.elements=e.elements,o.isBot=true,o.quote=e.quote}else if(!n.find(s=>s.id===e.messageId)){const s={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};let c=n.length;for(let u=n.length-1;u>=0;u--){if(n[u].timestamp<=e.timestamp){c=u+1;break}u===0&&(c=0)}n.splice(c,0,s),n.length>100&&(d.value.messages[t]=n.slice(-100)),z.value[t]=n.length;const l=Fe();le(()=>{setTimeout(()=>{l&&Ie()},10)})}d.value={...d.value}}function Bn(e){var t,n,a,o;if(!d.value.bots[e.selfId])d.value.bots[e.selfId]={selfId:e.selfId,platform:e.platform,username:((t=e.bot)==null?void 0:t.name)||`Bot-${e.selfId}`,avatar:(n=e.bot)==null?void 0:n.avatar,status:"online"};else{const s=d.value.bots[e.selfId];s.status="online",(a=e.bot)!=null&&a.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(d.value.channels[e.selfId]||(d.value.channels[e.selfId]={}),e.channelId&&!d.value.channels[e.selfId][e.channelId]){const s=e.isDirect?`私信 ${e.channelId}`:`${e.guildName||e.channelId} (${e.channelId})`;d.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(d.value.messages[s]||(d.value.messages[s]=[]),!d.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},u=d.value.messages[s];let v=u.length;for(let I=u.length-1;I>=0;I--){if(u[I].timestamp<=e.timestamp){v=I+1;break}I===0&&(v=0)}u.splice(v,0,l),u.length>100&&(d.value.messages[s]=u.slice(-100)),z.value[s]=u.length;const p=Fe();le(()=>{setTimeout(()=>{p&&Ie()},10)})}}if(e.elements&&e.elements.length>0){const s=`${e.selfId}:${e.channelId}`;e.elements.forEach(c=>{if((c.type==="img"||c.type==="image"||c.type==="mface")&&c.attrs){const l=c.attrs.src||c.attrs.url||c.attrs.file;l&&$e(s,l).catch(u=>{console.warn("预缓存图片失败:",l,u)})}})}d.value={...d.value}}async function Dn(){try{const e=await F("get-chat-data");if(e.success&&e.data){const t={};se.value=new Set(e.data.pinnedBots||[]),oe.value=new Set(e.data.pinnedChannels||[]);for(const[n,a]of Object.entries(e.data.messages||{})){const o=a.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,c)=>s.timestamp-c.timestamp),t[n]=o}return d.value={bots:e.data.bots||{},channels:e.data.channels||{},messages:t},await Mn(),true}else return console.warn("获取聊天数据失败:",e.error),false}catch(e){return console.error("获取聊天数据时出错:",e),false}}async function Mn(){try{const e=await F("get-all-channel-message-counts");if(e.success&&e.counts){const t={};for(const[n,a]of Object.entries(e.counts))t[n]=a;z.value=t}else console.warn("获取频道消息数量失败:",e.error)}catch(e){console.error("获取频道消息数量时出错:",e)}}async function _n(){try{const e=await F("get-plugin-config");e.success&&e.config?ie.value=e.config:console.warn("获取插件配置失败:",e.error)}catch(e){console.error("获取插件配置时出错:",e)}}async function yt(e,t,n,a){try{const o={selfId:e,channelId:t};n!==void 0&&(o.limit=n,o.offset=a||0);const s=await F("get-history-messages",o);if(s.success&&s.messages){const c=`${e}:${t}`,l=s.messages.map(v=>({id:v.id,content:v.content,userId:v.userId,username:v.username,avatar:v.avatar,timestamp:v.timestamp,channelId:v.channelId,selfId:v.selfId,elements:v.elements,isBot:v.type==="bot",quote:v.quote})),u=a||0;if(n!==void 0)if(l.sort((v,p)=>v.timestamp-p.timestamp),a===0)d.value.messages[c]=l,P.value[c]={offset:l.length,hasMore:l.length>=n&&s.total>l.length,loading:false};else{const v=d.value.messages[c]||[];d.value.messages[c]=[...l,...v];const p=a||0;P.value[c]={offset:p+l.length,hasMore:l.length>=n&&s.total>p+l.length,loading:false}}else l.sort((v,p)=>v.timestamp-p.timestamp),d.value.messages[c]=l,P.value[c]={offset:l.length,hasMore:false,loading:false};return z.value[c]=s.total||l.length,d.value={...d.value},true}else return console.warn("获取历史消息失败:",s.error),false}catch(o){return console.error("获取历史消息时出错:",o),false}}function Ln(e){if(!A.value||e.touches.length!==1)return;const t=e.touches[0];X.value={x:t.clientX,y:t.clientY,time:Date.now()},de.value={x:t.clientX,y:t.clientY},_e.value=false}function Tn(e){if(!A.value||!X.value||e.touches.length!==1)return;const t=e.touches[0];de.value={x:t.clientX,y:t.clientY};const n=t.clientX-X.value.x,a=t.clientY-X.value.y;if(Math.abs(n)>Math.abs(a)&&Math.abs(n)>30){const o=n>0,s=Z.value==="messages"||Z.value==="channels";if(o&&s){_e.value=true;const c=Math.min(n,200),l=150;c>l?E.value={show:true,text:"松开返回"}:E.value={show:true,text:`滑动返回 ${Math.round(c/l*100)}%`},e.preventDefault()}else E.value={show:false,text:""}}else E.value={show:false,text:""}}function qn(e){if(!A.value||!X.value)return;const n=Date.now()-X.value.time;if(de.value){const a=de.value.x-X.value.x,o=de.value.y-X.value.y,s=a>150,c=Math.abs(a)>Math.abs(o),l=n<300&&a>80;(s&&c||l)&&Un()}X.value=null,de.value=null,_e.value=false,E.value={show:false,text:""}}function Un(){switch(Z.value){case"messages":Z.value="channels";break;case"channels":Z.value="bots",y.value="",b.value="";break}}function pt(){A.value=window.innerWidth<=768}function Ot(){return!fe.value||Fe()}const zt=()=>{A.value&&T.value&&le(()=>{Ot()&&Ie()})},Kn=()=>{A.value&&setTimeout(()=>{T.value&&Ot()&&Ie()},300)};return Ft(we,(e,t)=>{t.length===0&&e.length>0&&le(()=>{Ie()})}),wt(async()=>{pt(),window.addEventListener("resize",pt),window.visualViewport&&window.visualViewport.addEventListener("resize",zt),document.addEventListener("click",ut),await _n(),ie.value.clearIndexedDBOnStart&&(console.log("启动时清空 IndexedDB 缓存..."),await ft()?console.log("IndexedDB 缓存已清空"):console.warn("清空 IndexedDB 缓存失败")),await bn()?(console.log("IndexedDB初始化成功"),setTimeout(async()=>{await dt()},2e3),setInterval(async()=>{await dt()},5*60*1e3)):console.warn("IndexedDB初始化失败,图片缓存功能将不可用"),await Dn(),le(()=>{Pt()});const t=Ct("chat-message-event",jt),n=Ct("bot-message-sent-event",At),a=Ct("chat-bot-message-event",Bn);Ft(b,o=>{o&&le(()=>{T.value&&(T.value.removeEventListener("scroll",Ne),T.value.addEventListener("scroll",Ne),Ne()),!A.value&&ne.value&&ne.value.focus()})},{immediate:true}),setInterval(()=>{Ze()},2*60*1e3),Pn(()=>{window.removeEventListener("resize",pt),window.visualViewport&&window.visualViewport.removeEventListener("resize",zt),document.removeEventListener("click",ut),t&&typeof t=="function"&&t(),n&&typeof n=="function"&&n(),a&&typeof a=="function"&&a(),T.value&&T.value.removeEventListener("scroll",Ne),Object.values(k.value).forEach(o=>{URL.revokeObjectURL(o)}),k.value={},x&&(x.close(),x=null)})}),{AvatarComponent:ge,ImageComponent:Y,JsonCardComponent:xe,ForwardMessageComponent:te,MessageElement:Me,chatData:d,channelMessageCounts:z,channelPagination:P,pluginConfig:ie,selectedBot:y,selectedChannel:b,inputMessage:ue,imageBlobUrls:k,pinnedBots:se,pinnedChannels:oe,uploadedImages:G,showActionMenu:pe,isMobile:A,mobileView:Z,touchStart:X,touchCurrent:de,isSwipeActive:_e,swipeIndicator:E,messageHistory:T,messageInput:ne,showScrollButton:Le,isUserScrolling:fe,isSending:ke,isLoadingMore:Se,draggingChannel:he,dragStartPos:N,dragCurrentPos:O,dragElementInitialPos:Te,dragOffset:qe,dragThreshold:W,isDragReady:ae,draggedBubbleElement:S,contextMenu:U,fileInput:Oe,bots:nt,currentChannels:at,currentMessages:we,currentChannelName:st,currentChannelKey:ot,canSendMessage:Ke,canInputMessage:rt,mobileViewClass:bt,inputPlaceholder:h,chatContainerStyle:i,selectBot:Qt,selectChannel:St,handleBotRightClick:en,handleChannelRightClick:tn,handleMessageRightClick:nn,showContextMenu:ct,hideContextMenu:K,handleKeyDown:Ee,toggleBotPin:sn,toggleChannelPin:on,deleteBotMessages:rn,deleteChannelMessages:ln,sendMessage:$t,toggleActionMenu:cn,triggerImageUpload:un,handleFileSelect:dn,handlePaste:fn,uploadImage:it,removeImage:hn,fileToBase64:Bt,handleClickOutside:ut,formatTime:mn,getChannelTypeText:pn,scrollToBottom:Ie,checkScrollPosition:Ne,isNearBottom:Fe,getChannelMessageCount:Mt,startDrag:wn,handleDragMove:He,handleDragEnd:Xe,resetDragState:We,getDragStyle:In,getDragDistance:xn,clearChannelHistory:_t,showNotification:D,createThresholdCircle:Lt,removeThresholdCircle:Tt,handleTouchStart:Ln,handleTouchMove:Tn,handleTouchEnd:qn,handleInputFocus:Kn,loadMoreMessages:Dt,handlePlusOne:vn,handleCopyMessage:gn,handleReplyMessage:yn,parseInlineQuote:lt,getInlineQuoteMessage:ze,getQuoteUser:Vt,getQuoteTimestamp:Jt,getQuoteContent:Gt,getQuoteElements:Zt,getMessageContentWithoutQuote:Et,getCachedImageUrl:vt,cacheImage:$e,clearChannelImageCache:Qe,clearAllIndexedDBData:ft,getMemoryStats:Sn,getCacheStats:$n,isFileUrl:ce,loadHistoryMessages:yt,handleMessageEvent:jt,handleBotMessageSentEvent:At,saveSelectionState:gt,restoreSelectionState:Pt}}const Xn={class:"bot-list"},Wn={class:"bot-items"},Qn=["onClick","onContextmenu"],Yn={class:"bot-avatar"},Vn={key:1,class:"avatar-placeholder"},Jn={class:"bot-info"},Gn={class:"bot-name"},Zn={class:"bot-platform"},En={class:"channel-list"},ea={key:0,class:"empty-state"},ta={key:1,class:"channel-items"},na=["data-channel-id","onClick","onContextmenu"],aa={class:"channel-info"},sa={class:"channel-name"},oa={class:"channel-type"},ra=["onMousedown","onTouchstart","title"],la={class:"message-area"},ca={class:"panel-header"},ia={key:0,class:"empty-state"},ua={key:1,class:"message-content"},da={key:0,class:"loading-more-indicator"},fa=["onContextmenu"],ha={class:"message-avatar"},ma={key:1,class:"avatar-placeholder"},va={class:"message-content-wrapper"},ga={class:"message-header"},ya={class:"message-username"},pa={class:"message-time"},wa={key:0,class:"message-quote"},Ia={class:"quote-header"},xa={class:"quote-avatar"},Ca={key:1,class:"avatar-placeholder"},ba={class:"quote-username"},ka={class:"quote-time"},Sa={class:"quote-content"},$a={class:"message-text"},Ba={class:"message-input"},Da={key:0,class:"image-preview-container"},Ma=["src","alt"],_a=["onClick"],La={class:"input-row"},Ta={class:"input-actions"},qa=["placeholder","disabled"],Ua=["disabled"],Ka=De({__name:"index",setup(ce){const ge=Hn(),{AvatarComponent:Y,MessageElement:xe,selectedBot:te,selectedChannel:Me,inputMessage:d,pinnedBots:z,pinnedChannels:P,uploadedImages:ie,showActionMenu:k,swipeIndicator:V,messageHistory:Pe,messageInput:Ce,showScrollButton:be,isSending:x,isLoadingMore:Ve,draggingChannel:je,dragThreshold:_,contextMenu:B,fileInput:Je,bots:ye,currentChannels:Ae,currentMessages:q,currentChannelName:tt,currentChannelKey:j,canSendMessage:J,canInputMessage:Ge,mobileViewClass:y,inputPlaceholder:b,chatContainerStyle:ue,selectBot:G,selectChannel:pe,handleBotRightClick:Oe,handleChannelRightClick:A,toggleBotPin:Z,toggleChannelPin:X,deleteBotMessages:de,deleteChannelMessages:_e,sendMessage:E,toggleActionMenu:T,triggerImageUpload:ne,handleFileSelect:Le,handlePaste:fe,removeImage:ke,formatTime:Se,getChannelTypeText:he,scrollToBottom:N,getChannelMessageCount:O,startDrag:Te,getDragStyle:qe,getDragDistance:W,handleTouchStart:Ue,handleTouchMove:H,handleTouchEnd:ae,handleInputFocus:S,handleMessageRightClick:U,handlePlusOne:se,handleCopyMessage:oe,handleReplyMessage:nt,getInlineQuoteMessage:at,getQuoteUser:we,getQuoteTimestamp:st,getQuoteContent:ot,getQuoteElements:Ke,getMessageContentWithoutQuote:rt}=ge;return(bt,h)=>(w(),C("div",{class:ve(["chat-container",r(y)]),style:It(r(ue)),onTouchstart:h[18]||(h[18]=(...i)=>r(Ue)&&r(Ue)(...i)),onTouchmove:h[19]||(h[19]=(...i)=>r(H)&&r(H)(...i)),onTouchend:h[20]||(h[20]=(...i)=>r(ae)&&r(ae)(...i))},[$(" 左侧机器人列表 "),f("div",Xn,[h[21]||(h[21]=f("div",{class:"panel-header"},[f("h3",null,"机器人")],-1)),f("div",Wn,[(w(true),C(ee,null,Re(r(ye),i=>(w(),C("div",{key:i.selfId,class:ve(["bot-item",{active:r(te)===i.selfId,pinned:r(z).has(i.selfId)}]),onClick:M=>r(G)(i.selfId),onContextmenu:M=>r(Oe)(M,i.selfId)},[f("div",Yn,[i.avatar?(w(),Ye(r(Y),{key:0,src:i.avatar,alt:i.username,"channel-key":"bot-list"},null,8,["src","alt"])):(w(),C("div",Vn,L(i.username.charAt(0).toUpperCase()),1))]),f("div",Jn,[f("div",Gn,L(i.username),1),f("div",Zn,L(i.platform),1)]),f("div",{class:ve(["bot-status",i.status])},null,2)],42,Qn))),128))])]),$(" 中间频道列表 "),f("div",En,[h[22]||(h[22]=f("div",{class:"panel-header"},[f("h3",null,"频道")],-1)),r(te)?(w(),C("div",ta,[(w(true),C(ee,null,Re(r(Ae),i=>(w(),C("div",{key:i.id,class:ve(["channel-item",{active:r(Me)===i.id,pinned:r(P).has(`${r(te)}:${i.id}`)}]),"data-channel-id":i.id,onClick:M=>r(pe)(i.id),onContextmenu:M=>r(A)(M,i.id)},[f("div",aa,[f("div",sa,L(i.name),1),f("div",oa,L(r(he)(i.type)),1)]),r(O)(i.id)>0?(w(),C("div",{key:0,class:ve(["channel-message-count draggable-bubble",{dragging:r(je)===i.id,"will-delete":r(je)===i.id&&r(W)(i.id)>r(_)}]),onMousedown:M=>r(Te)(M,i.id),onTouchstart:M=>r(Te)(M,i.id),style:It(r(qe)(i.id)),title:r(je)===i.id?r(W)(i.id)>r(_)?"松开清理历史记录":"拖拽更远以清理历史记录":"拖拽清理历史记录"},L(r(O)(i.id)),47,ra)):$("v-if",true)],42,na))),128))])):(w(),C("div",ea," 请选择一个机器人 "))]),$(" 右侧消息区域 "),f("div",la,[f("div",ca,[f("h3",null,L(r(tt)||"选择频道"),1)]),!r(te)||!r(Me)?(w(),C("div",ia," 请选择机器人和频道 ")):(w(),C("div",ua,[$(" 消息历史 "),f("div",{class:"message-history",ref_key:"messageHistory",ref:Pe},[$(" 加载更多指示器 "),r(Ve)?(w(),C("div",da,h[23]||(h[23]=[f("div",{class:"loading-spinner"},null,-1),f("span",null,"加载更多消息中...",-1)]))):$("v-if",true),(w(true),C(ee,null,Re(r(q),i=>(w(),C("div",{key:i.id,class:ve(["message-item",{"bot-message":i.isBot}]),onContextmenu:M=>i.isBot?null:r(U)(M,i)},[f("div",ha,[i.avatar?(w(),Ye(r(Y),{key:0,src:i.avatar,alt:i.username,"channel-key":r(j)},null,8,["src","alt","channel-key"])):(w(),C("div",ma,L(i.username.charAt(0).toUpperCase()),1))]),f("div",va,[f("div",ga,[f("span",ya,L(i.username),1),f("span",pa,L(r(Se)(i.timestamp)),1)]),$(" 引用消息显示 "),i.quote||r(at)(i,r(q))?(w(),C("div",wa,[f("div",Ia,[f("div",xa,[r(we)(i,r(q)).avatar?(w(),Ye(r(Y),{key:0,src:r(we)(i,r(q)).avatar,alt:r(we)(i,r(q)).username,"channel-key":r(j)},null,8,["src","alt","channel-key"])):(w(),C("div",Ca,L(r(we)(i,r(q)).username.charAt(0).toUpperCase()),1))]),f("span",ba,L(r(we)(i,r(q)).username),1),f("span",ka,L(r(Se)(r(st)(i,r(q)))),1)]),f("div",Sa,[r(Ke)(i,r(q))&&r(Ke)(i,r(q)).length>0?(w(true),C(ee,{key:0},Re(r(Ke)(i,r(q)),(M,me)=>(w(),Ye(r(xe),{key:`quote-${me}`,element:M,"channel-key":r(j)},null,8,["element","channel-key"]))),128)):(w(),C(ee,{key:1},[xt(L(r(ot)(i,r(q))),1)],64))])])):$("v-if",true),f("div",$a,[i.elements&&i.elements.length>0?(w(true),C(ee,{key:0},Re(i.elements,(M,me)=>(w(),Ye(r(xe),{key:me,element:M,"channel-key":r(j)},null,8,["element","channel-key"]))),128)):(w(),C(ee,{key:1},[xt(L(r(rt)(i,r(q))),1)],64))])])],42,fa))),128))],512),$(" 悬浮的滚动到底部按钮 "),Ht(f("div",{class:"floating-scroll-button",onClick:h[0]||(h[0]=(...i)=>r(N)&&r(N)(...i))},h[24]||(h[24]=[f("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor"},[f("path",{d:"M7 10l5 5 5-5z"})],-1)]),512),[[jn,r(be)]]),$(" 输入框 "),f("div",Ba,[$(" 图片预览区域 "),r(ie).length>0?(w(),C("div",Da,[(w(true),C(ee,null,Re(r(ie),i=>(w(),C("div",{key:i.tempId,class:"image-preview-item"},[f("img",{src:i.preview,alt:i.filename,class:"preview-image"},null,8,Ma),f("button",{class:"remove-image-btn",onClick:M=>r(ke)(i.tempId),title:"删除图片"},h[25]||(h[25]=[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,_a)]))),128))])):$("v-if",true),f("div",La,[$(" 加号按钮 "),f("div",Ta,[f("button",{class:ve(["add-button",{active:r(k)}]),onClick:h[1]||(h[1]=(...i)=>r(T)&&r(T)(...i)),title:"更多操作"},h[26]||(h[26]=[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),$(" 操作菜单 "),r(k)?(w(),C("div",{key:0,class:"action-menu",onClick:h[3]||(h[3]=Xt(()=>{},["stop"]))},[f("button",{class:"action-menu-item",onClick:h[2]||(h[2]=(...i)=>r(ne)&&r(ne)(...i))},h[27]||(h[27]=[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),xt(" 上传图片 ",-1)]))])):$("v-if",true)]),Ht(f("input",{"onUpdate:modelValue":h[4]||(h[4]=i=>On(d)?d.value=i:null),type:"text",placeholder:r(b),onKeyup:h[5]||(h[5]=An((...i)=>r(E)&&r(E)(...i),["enter"])),disabled:!r(Ge),ref_key:"messageInput",ref:Ce,onPaste:h[6]||(h[6]=(...i)=>r(fe)&&r(fe)(...i)),onFocus:h[7]||(h[7]=(...i)=>r(S)&&r(S)(...i))},null,40,qa),[[zn,r(d)]]),f("button",{onClick:h[8]||(h[8]=(...i)=>r(E)&&r(E)(...i)),disabled:!r(J),class:ve({"is-sending":r(x)})},L(r(x)?"发送中...":"发送"),11,Ua)]),$(" 隐藏的文件输入 "),f("input",{type:"file",ref_key:"fileInput",ref:Je,onChange:h[9]||(h[9]=(...i)=>r(Le)&&r(Le)(...i)),accept:"image/*",multiple:"",style:{display:"none"}},null,544)])]))]),$(" 右键菜单 "),r(B).show?(w(),C("div",{key:0,class:"context-menu",style:It({left:r(B).x+"px",top:r(B).y+"px"}),onClick:h[17]||(h[17]=Xt(()=>{},["stop"]))},[$(" 机器人右键菜单 "),r(B).type==="bot"?(w(),C(ee,{key:0},[f("div",{class:"context-menu-item",onClick:h[10]||(h[10]=i=>r(Z)(r(B).targetId))},L(r(z).has(r(B).targetId)?"取消置顶":"置顶"),1),f("div",{class:"context-menu-item danger",onClick:h[11]||(h[11]=i=>r(de)(r(B).targetId))}," 彻底删除此机器人所有数据 ")],64)):$("v-if",true),$(" 频道右键菜单 "),r(B).type==="channel"?(w(),C(ee,{key:1},[f("div",{class:"context-menu-item",onClick:h[12]||(h[12]=i=>r(X)(r(B).targetId))},L(r(P).has(`${r(te)}:${r(B).targetId}`)?"取消置顶":"置顶"),1),f("div",{class:"context-menu-item danger",onClick:h[13]||(h[13]=i=>r(_e)(r(B).targetId))}," 彻底删除此频道所有数据 ")],64)):$("v-if",true),$(" 消息右键菜单 "),r(B).type==="message"&&r(B).message?(w(),C(ee,{key:2},[f("div",{class:"context-menu-item",onClick:h[14]||(h[14]=i=>r(se)(r(B).message))}," +1 "),f("div",{class:"context-menu-item",onClick:h[15]||(h[15]=i=>r(oe)(r(B).message))}," 复制 "),f("div",{class:"context-menu-item",onClick:h[16]||(h[16]=i=>r(nt)(r(B).message))}," 回复 ")],64)):$("v-if",true)],4)):$("v-if",true),$(" 滑动指示器 "),f("div",{class:ve(["swipe-indicator",{show:r(V).show}])},L(r(V).text),3)],38))}}),Wt=(ce,ge)=>{const Y=ce.__vccOpts||ce;for(const[xe,te]of ge)Y[xe]=te;return Y},Ra=Wt(Ka,[["__scopeId","data-v-bda63c05"]]),Pa={},ja={class:"k-icon",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none"};function Aa(ce,ge){return w(),C("svg",ja,ge[0]||(ge[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 Oa=Wt(Pa,[["render",Aa]]);Fn.register("activity:chat",Oa);const Ha=ce=>{ce.page({name:"聊天室",path:"/chat-patch",desc:"",authority:4,icon:"activity:chat",component:De({setup(){return()=>m(Nn("k-layout"),{},{default:()=>m(Ra)})}})})};export{Ha as default};
|