koishi-plugin-chat-patch 1.1.0 → 1.1.1
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 +32 -17
- package/dist/index.js +3 -3
- package/lib/config.d.ts +14 -0
- package/lib/index.js +16 -3
- package/package.json +1 -1
- package/src/api-handlers.ts +13 -1
- package/src/config.ts +6 -1
- package/lib/index.d.ts +0 -17
package/client/vue/chat-logic.ts
CHANGED
|
@@ -661,6 +661,7 @@ export function useChatLogic() {
|
|
|
661
661
|
loading: boolean
|
|
662
662
|
}>>({})
|
|
663
663
|
|
|
664
|
+
// Config默认值,实际值将从后端获取
|
|
664
665
|
const pluginConfig = ref<{
|
|
665
666
|
maxMessagesPerChannel: number
|
|
666
667
|
keepMessagesOnClear: number
|
|
@@ -670,12 +671,14 @@ export function useChatLogic() {
|
|
|
670
671
|
exactMatch: boolean
|
|
671
672
|
}>
|
|
672
673
|
chatContainerHeight: number
|
|
674
|
+
clearIndexedDBOnStart: boolean
|
|
673
675
|
}>({
|
|
674
676
|
maxMessagesPerChannel: 1000,
|
|
675
677
|
keepMessagesOnClear: 50,
|
|
676
678
|
loggerinfo: false,
|
|
677
679
|
blockedPlatforms: [],
|
|
678
|
-
chatContainerHeight: 80
|
|
680
|
+
chatContainerHeight: 80,
|
|
681
|
+
clearIndexedDBOnStart: true
|
|
679
682
|
})
|
|
680
683
|
|
|
681
684
|
// 图片缓存 - IndexedDB
|
|
@@ -745,7 +748,7 @@ export function useChatLogic() {
|
|
|
745
748
|
const showScrollButton = ref<boolean>(false)
|
|
746
749
|
const isUserScrolling = ref<boolean>(false)
|
|
747
750
|
const isSending = ref<boolean>(false)
|
|
748
|
-
const isLoadingMore = ref<boolean>(false)
|
|
751
|
+
const isLoadingMore = ref<boolean>(false)
|
|
749
752
|
|
|
750
753
|
// 拖拽相关状态
|
|
751
754
|
const draggingChannel = ref<string>('')
|
|
@@ -1380,7 +1383,7 @@ export function useChatLogic() {
|
|
|
1380
1383
|
// 滚动到底部时,重置滚动状态
|
|
1381
1384
|
isUserScrolling.value = false
|
|
1382
1385
|
}
|
|
1383
|
-
|
|
1386
|
+
|
|
1384
1387
|
// 检查是否滚动到顶部,如果是则加载更多消息
|
|
1385
1388
|
if (scrollTop <= 10 && selectedBot.value && selectedChannel.value) {
|
|
1386
1389
|
loadMoreMessages()
|
|
@@ -1391,13 +1394,13 @@ export function useChatLogic() {
|
|
|
1391
1394
|
// 加载更多消息的函数
|
|
1392
1395
|
async function loadMoreMessages() {
|
|
1393
1396
|
if (!selectedBot.value || !selectedChannel.value) return
|
|
1394
|
-
|
|
1397
|
+
|
|
1395
1398
|
const channelKey = `${selectedBot.value}:${selectedChannel.value}`
|
|
1396
|
-
|
|
1399
|
+
|
|
1397
1400
|
// 检查是否正在加载或没有更多消息
|
|
1398
1401
|
const pagination = channelPagination.value[channelKey]
|
|
1399
1402
|
if (isLoadingMore.value || (pagination && !pagination.hasMore)) return
|
|
1400
|
-
|
|
1403
|
+
|
|
1401
1404
|
// 更新加载状态
|
|
1402
1405
|
if (!channelPagination.value[channelKey]) {
|
|
1403
1406
|
channelPagination.value[channelKey] = {
|
|
@@ -1406,18 +1409,18 @@ export function useChatLogic() {
|
|
|
1406
1409
|
loading: false
|
|
1407
1410
|
}
|
|
1408
1411
|
}
|
|
1409
|
-
|
|
1412
|
+
|
|
1410
1413
|
// 设置为加载中状态
|
|
1411
1414
|
isLoadingMore.value = true
|
|
1412
1415
|
channelPagination.value[channelKey].loading = true
|
|
1413
|
-
|
|
1416
|
+
|
|
1414
1417
|
try {
|
|
1415
1418
|
// 获取当前offset
|
|
1416
1419
|
const currentOffset = pagination?.offset || 0
|
|
1417
|
-
|
|
1420
|
+
|
|
1418
1421
|
// 加载下一批消息(50条)
|
|
1419
1422
|
const result = await loadHistoryMessages(selectedBot.value, selectedChannel.value, 50, currentOffset)
|
|
1420
|
-
|
|
1423
|
+
|
|
1421
1424
|
if (result) {
|
|
1422
1425
|
// 更新分页状态已在loadHistoryMessages中处理
|
|
1423
1426
|
} else {
|
|
@@ -2957,7 +2960,7 @@ export function useChatLogic() {
|
|
|
2957
2960
|
selfId: botId,
|
|
2958
2961
|
channelId: channelId
|
|
2959
2962
|
}
|
|
2960
|
-
|
|
2963
|
+
|
|
2961
2964
|
// 如果提供了分页参数,则添加到请求中
|
|
2962
2965
|
if (limit !== undefined) {
|
|
2963
2966
|
requestData.limit = limit
|
|
@@ -2991,7 +2994,7 @@ export function useChatLogic() {
|
|
|
2991
2994
|
if (limit !== undefined) {
|
|
2992
2995
|
// 按时间戳排序
|
|
2993
2996
|
messages.sort((a, b) => a.timestamp - b.timestamp)
|
|
2994
|
-
|
|
2997
|
+
|
|
2995
2998
|
// 如果是第一页(offset为0),则替换现有消息
|
|
2996
2999
|
if (offset === 0) {
|
|
2997
3000
|
chatData.value.messages[channelKey] = messages
|
|
@@ -3016,7 +3019,7 @@ export function useChatLogic() {
|
|
|
3016
3019
|
} else {
|
|
3017
3020
|
// 按时间戳排序
|
|
3018
3021
|
messages.sort((a, b) => a.timestamp - b.timestamp)
|
|
3019
|
-
|
|
3022
|
+
|
|
3020
3023
|
// 设置历史消息
|
|
3021
3024
|
chatData.value.messages[channelKey] = messages
|
|
3022
3025
|
// 初始化分页状态
|
|
@@ -3199,6 +3202,20 @@ export function useChatLogic() {
|
|
|
3199
3202
|
// 添加点击外部关闭菜单的监听器
|
|
3200
3203
|
document.addEventListener('click', handleClickOutside)
|
|
3201
3204
|
|
|
3205
|
+
// 首先加载插件配置
|
|
3206
|
+
await loadPluginConfig()
|
|
3207
|
+
|
|
3208
|
+
// 检查是否需要清空 IndexedDB
|
|
3209
|
+
if (pluginConfig.value.clearIndexedDBOnStart) {
|
|
3210
|
+
console.log('启动时清空 IndexedDB 缓存...')
|
|
3211
|
+
const clearResult = await clearAllIndexedDBData()
|
|
3212
|
+
if (clearResult) {
|
|
3213
|
+
console.log('IndexedDB 缓存已清空')
|
|
3214
|
+
} else {
|
|
3215
|
+
console.warn('清空 IndexedDB 缓存失败')
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
|
|
3202
3219
|
// 初始化IndexedDB
|
|
3203
3220
|
const dbInitialized = await initImageDB()
|
|
3204
3221
|
if (!dbInitialized) {
|
|
@@ -3217,9 +3234,6 @@ export function useChatLogic() {
|
|
|
3217
3234
|
}, 5 * 60 * 1000)
|
|
3218
3235
|
}
|
|
3219
3236
|
|
|
3220
|
-
// 首先加载插件配置
|
|
3221
|
-
await loadPluginConfig()
|
|
3222
|
-
|
|
3223
3237
|
// 然后加载历史数据
|
|
3224
3238
|
await loadChatData()
|
|
3225
3239
|
|
|
@@ -3307,7 +3321,7 @@ export function useChatLogic() {
|
|
|
3307
3321
|
// 响应式数据
|
|
3308
3322
|
chatData,
|
|
3309
3323
|
channelMessageCounts,
|
|
3310
|
-
channelPagination,
|
|
3324
|
+
channelPagination,
|
|
3311
3325
|
pluginConfig,
|
|
3312
3326
|
selectedBot,
|
|
3313
3327
|
selectedChannel,
|
|
@@ -3399,6 +3413,7 @@ export function useChatLogic() {
|
|
|
3399
3413
|
getCachedImageUrl,
|
|
3400
3414
|
cacheImage,
|
|
3401
3415
|
clearChannelImageCache,
|
|
3416
|
+
clearAllIndexedDBData,
|
|
3402
3417
|
getMemoryStats,
|
|
3403
3418
|
getCacheStats,
|
|
3404
3419
|
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{defineComponent as Ce,ref as g,onMounted as it,h as m,computed as te,watch as Tt,nextTick as me,onUnmounted as ba,createElementBlock as C,openBlock as w,unref as c,normalizeStyle as ut,normalizeClass as re,createCommentVNode as B,createElementVNode as f,Fragment as ae,renderList as Le,createBlock as Fe,toDisplayString as D,withDirectives as Mt,createTextVNode as dt,vShow as ka,withModifiers as qt,withKeys as Sa,isRef as Ba,vModelText as $a,resolveComponent as Da}from"vue";import{receive as ft,send as z,icons as _a}from"@koishijs/client";function La(){function ne(e){try{return new URL(e).protocol==="file:"}catch{return false}}const ce=Ce({props:{src:{type:String,required:true},alt:{type:String,default:"头像"},channelKey:{type:String,required:true}},setup(e){const t=g("loading"),a=g(e.src),n=g(""),o=async()=>{try{t.value="loading";const i=await ot(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 it(()=>{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 ot(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 it(()=>{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:{}}),U=g({}),K=g({}),ie=g({maxMessagesPerChannel:1e3,keepMessagesOnClear:50,loggerinfo:false,blockedPlatforms:[],chatContainerHeight:80}),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),se=g(null),Se=g(false),G=g({show:false,text:""}),L=g(),fe=g(),Be=g(false),oe=g(false),pe=g(false),we=g(false),le=g(""),R=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),O=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})),ht=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}),jt=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)||""}),Pt=te(()=>!y.value||!S.value?"":`${y.value}:${S.value}`),mt=te(()=>y.value&&S.value&&(ke.value.trim()||W.value.length>0)&&!pe.value),At=te(()=>y.value&&S.value&&!pe.value),Ut=te(()=>{if(!P.value)return"";switch(J.value){case"channels":return"show-channels";case"messages":return"show-messages";default:return""}}),Rt=te(()=>P.value?"输入消息...(屏幕左滑返回)":"输入消息..."),zt=te(()=>({}));function Ze(e){return e.size||0}function Pe(e){ye+=e,ie.value.loggerinfo&&console.log(`内存使用量变化: ${e>0?"+":""}${(e/1024/1024).toFixed(2)}MB, 总计: ${(ye/1024/1024).toFixed(2)}MB`)}function vt(e=10){const t=Object.entries(b.value);if(t.length<=e)return;const a=t.slice(0,t.length-e);let n=0;a.forEach(([o,s])=>{URL.revokeObjectURL(s),delete b.value[o],n+=500*1024,ie.value.loggerinfo&&console.log("清理旧blob URL:",o)}),Pe(-n)}function We(){Object.keys(b.value).length>ge&&vt(Math.floor(ge*.7)),ye>Te&&vt(Math.floor(ge*.5))}function Ot(e){y.value=e,S.value="",lt(),P.value&&(J.value="channels")}function Nt(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 Ft(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 Ht(e){h.value.has(e)?h.value.delete(e):h.value.add(e),await z("set-pinned-bots",{pinnedBots:Array.from(h.value)}),Q()}async function Xt(e){const t=`${y.value}:${e}`;r.value.has(t)?r.value.delete(t):r.value.add(t),await z("set-pinned-channels",{pinnedChannels:Array.from(r.value)}),Q()}async function Yt(e){try{const t=await z("delete-bot-data",{selfId:e});if(t.success){const a=Object.keys(u.value.messages).filter(n=>n.startsWith(`${e}:`));for(const n of a)delete u.value.messages[n],delete U.value[n],await 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 Vt(e){try{const t=await z("delete-channel-data",{selfId:y.value,channelId:e});if(t.success){const a=`${y.value}:${e}`;delete u.value.messages[a],delete U.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 Wt(e){S.value=e,oe.value=false,lt(),P.value&&(J.value="messages");const t=`${y.value}:${e}`;delete K.value[t],y.value&&await rt(y.value,e,50,0),me(()=>{he(),!P.value&&fe.value&&fe.value.focus()})}async function Jt(){if(!mt.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 z("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 z("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 Gt(){de.value=!de.value}function Zt(){Ke.value&&Ke.value.click(),de.value=false}async function Qt(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 Et(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 gt(e),a=URL.createObjectURL(e),n=await z("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 ea(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 z("delete-temp-image",{tempId:e})}catch(t){console.error("删除图片失败:",t)}}function gt(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 ta(e){return new Date(e).toLocaleTimeString("zh-CN",{hour:"2-digit",minute:"2-digit"})}function aa(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,oe.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?oe.value=false:oe.value=true,e<=10&&y.value&&S.value&&yt()}}async function yt(){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 rt(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 Ue(){if(!L.value)return true;const{scrollTop:e,scrollHeight:t,clientHeight:a}=L.value;return t-(e+a)<=200}function pt(e){var n;if(!y.value)return 0;const t=`${y.value}:${e}`,a=U.value[t];return a!==void 0?a:((n=u.value.messages[t])==null?void 0:n.length)||0}function na(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(),R.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},O.value=window.setTimeout(()=>{if(_e.value>0){ee.value=true,le.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"),It(R.value.x,R.value.y)}},60),document.addEventListener("mousemove",Re),document.addEventListener("mouseup",ze),document.addEventListener("touchmove",Re),document.addEventListener("touchend",ze)}function Re(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-R.value.x,o=A.value.y-R.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 ze(e){if(O.value&&(clearTimeout(O.value),O.value=null),O.value&&(clearTimeout(O.value),O.value=null),!ee.value||!le.value){Oe();return}const t=le.value;if(Math.sqrt(Math.pow(A.value.x-R.value.x,2)+Math.pow(A.value.y-R.value.y,2))>F)wt(t),Oe();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(()=>{Oe()},300)}else Oe()}function Oe(){O.value&&(clearTimeout(O.value),O.value=null),le.value="",R.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",Re),document.removeEventListener("mouseup",ze),document.removeEventListener("touchmove",Re),document.removeEventListener("touchend",ze),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),xt()}function sa(e){return le.value===e&&ee.value?{visibility:"hidden",pointerEvents:"none",transition:"none"}:{}}function oa(e){if(le.value!==e)return 0;const t=A.value.x-R.value.x,a=A.value.y-R.value.y;return Math.sqrt(t*t+a*a)}async function wt(e){if(y.value)try{const t=`${y.value}:${e}`,a=pt(e),n=ie.value.keepMessagesOnClear;if(n>0&&a<=n){T("当前消息还很少诶~ 无需清理","success");return}const o=await z("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)}U.value[t]=o.keptCount,await Ne(t),T(`历史记录已清理,清理了 ${o.clearedCount} 条消息,保留最新 ${o.keptCount} 条`,"success")}else n===0?(u.value.messages[t]&&(u.value.messages[t]=[]),U.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 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=`
|
|
2
2
|
position: fixed;
|
|
3
3
|
top: 20px;
|
|
4
4
|
right: 20px;
|
|
@@ -19,9 +19,9 @@ import{defineComponent as Ce,ref as g,onMounted as it,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(a),setTimeout(()=>{a.style.animation="slideOut 0.3s ease-in",setTimeout(()=>{a.parentNode&&a.parentNode.removeChild(a),o.parentNode&&o.parentNode.removeChild(o)},300)},3e3)}function
|
|
22
|
+
`,document.head.appendChild(o),document.body.appendChild(a),setTimeout(()=>{a.style.animation="slideOut 0.3s ease-in",setTimeout(()=>{a.parentNode&&a.parentNode.removeChild(a),o.parentNode&&o.parentNode.removeChild(o)},300)},3e3)}function xt(e,t){const a=document.createElement("div");a.className="drag-threshold-circle",a.style.cssText=`
|
|
23
23
|
left: ${e-F}px;
|
|
24
24
|
top: ${t-F}px;
|
|
25
25
|
width: ${F*2}px;
|
|
26
26
|
height: ${F*2}px;
|
|
27
|
-
`,document.body.appendChild(a),window.dragThresholdCircle=a}function xt(){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 Ct();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 la()),true}catch(e){return console.error("数据库健康检查失败:",e),false}}async function Ct(){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 bt();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 st(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 la(){try{console.log("开始紧急清理...");const e=await bt();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 st(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 bt(){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 ra(){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 kt()?(setTimeout(async()=>{const t=await Ct();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 ra(),await kt())}catch(e){return console.error("IndexedDB初始化出错:",e),false}}async function kt(){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 St(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 nt(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 st(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 ot(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 St(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 nt(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 St(t);if(s){We();const xe=URL.createObjectURL(s.blob);return b.value[t]=xe,Pe(Ze(s.blob)),s.timestamp=Date.now(),await nt(s),xe}const i=await z("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 nt(Ca))return null;We();const Lt=URL.createObjectURL(q);return b.value[t]=Lt,Pe(Ze(q)),Lt}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 st(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 lt(){y.value&&S.value&&(localStorage.setItem("chat-selected-bot",y.value),localStorage.setItem("chat-selected-channel",S.value))}function Bt(){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 $t(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)),U.value[s]=d.length;const p=Ue();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)),U.value[t]=o.length;const i=Ue();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)),U.value[s]=d.length;const p=Ue();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 z("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 z("get-all-channel-message-counts");if(e.success&&e.counts){const t={};for(const[a,n]of Object.entries(e.counts))t[a]=n;U.value=t}else console.warn("获取频道消息数量失败:",e.error)}catch(e){console.error("获取频道消息数量时出错:",e)}}async function ga(){try{const e=await z("get-plugin-config");e.success&&e.config?ie.value=e.config:console.warn("获取插件配置失败:",e.error)}catch(e){console.error("获取插件配置时出错:",e)}}async function rt(e,t,a,n){try{const o={selfId:e,channelId:t};a!==void 0&&(o.limit=a,o.offset=n||0);const s=await z("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 U.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()},se.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];se.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(se.value){const n=se.value.x-N.value.x,o=se.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,se.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 ct(){P.value=window.innerWidth<=768}function Dt(){return!oe.value||Ue()}const _t=()=>{P.value&&L.value&&me(()=>{Dt()&&he()})},xa=()=>{P.value&&setTimeout(()=>{L.value&&Dt()&&he()},300)};return Tt(ht,(e,t)=>{t.length===0&&e.length>0&&me(()=>{he()})}),it(async()=>{ct(),window.addEventListener("resize",ct),window.visualViewport&&window.visualViewport.addEventListener("resize",_t),document.addEventListener("click",tt),await ca()?(console.log("IndexedDB初始化成功"),setTimeout(async()=>{await at()},2e3),setInterval(async()=>{await at()},5*60*1e3)):console.warn("IndexedDB初始化失败,图片缓存功能将不可用"),await ga(),await ma(),me(()=>{Bt()});const t=ft("chat-message-event",$t),a=ft("bot-message-sent-event",fa),n=ft("chat-bot-message-event",ha);Tt(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",ct),window.visualViewport&&window.visualViewport.removeEventListener("resize",_t),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:ce,ImageComponent:X,JsonCardComponent:ve,ForwardMessageComponent:E,MessageElement:be,chatData:u,channelMessageCounts:U,channelPagination:K,pluginConfig:ie,selectedBot:y,selectedChannel:S,inputMessage:ke,imageBlobUrls:b,pinnedBots:h,pinnedChannels:r,uploadedImages:W,showActionMenu:de,isMobile:P,mobileView:J,touchStart:N,touchCurrent:se,isSwipeActive:Se,swipeIndicator:G,messageHistory:L,messageInput:fe,showScrollButton:Be,isUserScrolling:oe,isSending:pe,isLoadingMore:we,draggingChannel:le,dragStartPos:R,dragCurrentPos:A,dragElementInitialPos:$e,dragOffset:De,dragThreshold:F,isDragReady:ee,draggedBubbleElement:k,contextMenu:Z,fileInput:Ke,bots:M,currentChannels:je,currentMessages:ht,currentChannelName:jt,currentChannelKey:Pt,canSendMessage:mt,canInputMessage:At,mobileViewClass:Ut,inputPlaceholder:Rt,chatContainerStyle:zt,selectBot:Ot,selectChannel:Wt,handleBotRightClick:Nt,handleChannelRightClick:Ft,showContextMenu:Qe,hideContextMenu:Q,handleKeyDown:Ee,toggleBotPin:Ht,toggleChannelPin:Xt,deleteBotMessages:Yt,deleteChannelMessages:Vt,sendMessage:Jt,toggleActionMenu:Gt,triggerImageUpload:Zt,handleFileSelect:Qt,handlePaste:Et,uploadImage:et,removeImage:ea,fileToBase64:gt,handleClickOutside:tt,formatTime:ta,getChannelTypeText:aa,scrollToBottom:he,checkScrollPosition:Ae,isNearBottom:Ue,getChannelMessageCount:pt,startDrag:na,handleDragMove:Re,handleDragEnd:ze,resetDragState:Oe,getDragStyle:sa,getDragDistance:oa,clearChannelHistory:wt,showNotification:T,createThresholdCircle:It,removeThresholdCircle:xt,handleTouchStart:ya,handleTouchMove:pa,handleTouchEnd:wa,handleInputFocus:xa,loadMoreMessages:yt,getCachedImageUrl:ot,cacheImage:Ie,clearChannelImageCache:Ne,getMemoryStats:ua,getCacheStats:da,isFileUrl:ne,loadHistoryMessages:rt,handleMessageEvent:$t,saveSelectionState:lt,restoreSelectionState:Bt}}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"},Ua={class:"bot-platform"},Ra={class:"channel-list"},za={key:0,class:"empty-state"},Oa={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 ce=La(),{AvatarComponent:X,MessageElement:ve,selectedBot:E,selectedChannel:be,inputMessage:u,pinnedBots:U,pinnedChannels:K,uploadedImages:ie,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:se,deleteChannelMessages:Se,sendMessage:G,toggleActionMenu:L,triggerImageUpload:fe,handleFileSelect:Be,handlePaste:oe,removeImage:pe,formatTime:we,getChannelTypeText:le,scrollToBottom:R,getChannelMessageCount:A,startDrag:$e,getDragStyle:De,getDragDistance:F,handleTouchStart:_e,handleTouchMove:O,handleTouchEnd:ee,handleInputFocus:k}=ce;return(Z,h)=>(w(),C("div",{class:re(["chat-container",c(y)]),style:ut(c(ke)),onTouchstart:h[15]||(h[15]=(...r)=>c(_e)&&c(_e)(...r)),onTouchmove:h[16]||(h[16]=(...r)=>c(O)&&c(O)(...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:re(["bot-item",{active:c(E)===r.selfId,pinned:c(U).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",Ua,D(r.platform),1)]),f("div",{class:re(["bot-status",r.status])},null,2)],42,qa))),128))])]),B(" 中间频道列表 "),f("div",Ra,[h[19]||(h[19]=f("div",{class:"panel-header"},[f("h3",null,"频道")],-1)),c(E)?(w(),C("div",Oa,[(w(true),C(ae,null,Le(c(qe),r=>(w(),C("div",{key:r.id,class:re(["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(le)(r.type)),1)]),c(A)(r.id)>0?(w(),C("div",{key:0,class:re(["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:ut(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",za," 请选择一个机器人 "))]),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:re(["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},[dt(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},[dt(D(r.content),1)],64))])])],2))),128))],512),B(" 悬浮的滚动到底部按钮 "),Mt(f("div",{class:"floating-scroll-button",onClick:h[0]||(h[0]=(...r)=>c(R)&&c(R)(...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(ie).length>0?(w(),C("div",mn,[(w(true),C(ae,null,Le(c(ie),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:re(["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]=qt(()=>{},["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),dt(" 上传图片 ",-1)]))])):B("v-if",true)]),Mt(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(oe)&&c(oe)(...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:re({"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:ut({left:c(_).x+"px",top:c(_).y+"px"}),onClick:h[14]||(h[14]=qt(()=>{},["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(U).has(c(_).targetId)?"取消置顶":"置顶"),1),f("div",{class:"context-menu-item danger",onClick:h[11]||(h[11]=r=>c(se)(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:re(["swipe-indicator",{show:c(Y).show}])},D(c(Y).text),3)],38))}}),Kt=(ne,ce)=>{const X=ne.__vccOpts||ne;for(const[ve,E]of ce)X[ve]=E;return X},Cn=Kt(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,ce){return w(),C("svg",kn,ce[0]||(ce[0]=[f("path",{d:"M8 10.5H16",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),f("path",{d:"M8 14H13.5",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),f("path",{d:"M17 3.33782C15.5291 2.48697 13.8214 2 12 2C6.47715 2 2 6.47715 2 12C2 13.5997 2.37562 15.1116 3.04346 16.4525C3.22094 16.8088 3.28001 17.2161 3.17712 17.6006L2.58151 19.8267C2.32295 20.793 3.20701 21.677 4.17335 21.4185L6.39939 20.8229C6.78393 20.72 7.19121 20.7791 7.54753 20.9565C8.88837 21.6244 10.4003 22 12 22C17.5228 22 22 17.5228 22 12C22 10.1786 21.513 8.47087 20.6622 7",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1)]))}const Bn=Kt(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};
|
|
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};
|
package/lib/config.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Schema } from 'koishi';
|
|
2
|
+
export interface Config {
|
|
3
|
+
loggerinfo: boolean;
|
|
4
|
+
clearIndexedDBOnStart: boolean;
|
|
5
|
+
maxMessagesPerChannel: number;
|
|
6
|
+
keepMessagesOnClear: number;
|
|
7
|
+
keepTempImages: number;
|
|
8
|
+
blockedPlatforms: Array<{
|
|
9
|
+
platformName: string;
|
|
10
|
+
exactMatch: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
chatContainerHeight: number;
|
|
13
|
+
}
|
|
14
|
+
export declare const Config: Schema<Config>;
|
package/lib/index.js
CHANGED
|
@@ -511,6 +511,15 @@ var ApiHandlers = class {
|
|
|
511
511
|
}
|
|
512
512
|
logger;
|
|
513
513
|
registerApiHandlers() {
|
|
514
|
+
this.ctx.console.addListener("clear-all-indexeddb-data", async () => {
|
|
515
|
+
try {
|
|
516
|
+
this.logInfo("收到清空 IndexedDB 数据请求");
|
|
517
|
+
return { success: true, message: "可以清空 IndexedDB" };
|
|
518
|
+
} catch (error) {
|
|
519
|
+
this.logger.error("清空 IndexedDB 数据失败:", error);
|
|
520
|
+
return { success: false, error: error?.message || String(error) };
|
|
521
|
+
}
|
|
522
|
+
});
|
|
514
523
|
this.ctx.console.addListener("get-chat-data", async () => {
|
|
515
524
|
try {
|
|
516
525
|
const data = this.fileManager.readChatDataFromFile();
|
|
@@ -829,7 +838,8 @@ var ApiHandlers = class {
|
|
|
829
838
|
keepTempImages: this.config.keepTempImages,
|
|
830
839
|
loggerinfo: this.config.loggerinfo,
|
|
831
840
|
blockedPlatforms: this.config.blockedPlatforms || [],
|
|
832
|
-
chatContainerHeight: this.config.chatContainerHeight
|
|
841
|
+
chatContainerHeight: this.config.chatContainerHeight,
|
|
842
|
+
clearIndexedDBOnStart: this.config.clearIndexedDBOnStart
|
|
833
843
|
}
|
|
834
844
|
};
|
|
835
845
|
} catch (error) {
|
|
@@ -983,9 +993,12 @@ var Config = import_koishi2.Schema.intersect([
|
|
|
983
993
|
)
|
|
984
994
|
}).description("基础设置"),
|
|
985
995
|
import_koishi2.Schema.object({
|
|
986
|
-
chatContainerHeight: import_koishi2.Schema.number().default(80).description("手机端使用的视口高度(防止文本输入框被挡住)").min(50).max(100)
|
|
996
|
+
chatContainerHeight: import_koishi2.Schema.number().default(80).description("手机端使用的视口高度(防止文本输入框被挡住)").min(50).max(100)
|
|
997
|
+
}).description("进阶设置"),
|
|
998
|
+
import_koishi2.Schema.object({
|
|
999
|
+
clearIndexedDBOnStart: import_koishi2.Schema.boolean().default(true).description("启动时强制清空IndexedDB缓存(适用于紧急情况,防止浏览器卡死)"),
|
|
987
1000
|
loggerinfo: import_koishi2.Schema.boolean().default(false).description("日志调试模式").experimental()
|
|
988
|
-
}).description("
|
|
1001
|
+
}).description("开发者选项")
|
|
989
1002
|
]);
|
|
990
1003
|
|
|
991
1004
|
// src/index.ts
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-chat-patch",
|
|
3
3
|
"description": "[<ruby>chat-patch<rp>(</rp><rt>点我预览效果</rt><rp>)</rp></ruby>](https://i0.hdslb.com/bfs/openplatform/71074dfc9e5256fc3333d8bd8478bec1af874046.png) 视奸小插件((bushi( (低性能警告)。手机端适配。灵感来自 chat 插件。",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.1",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
package/src/api-handlers.ts
CHANGED
|
@@ -18,6 +18,17 @@ export class ApiHandlers {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
registerApiHandlers() {
|
|
21
|
+
this.ctx.console.addListener('clear-all-indexeddb-data' as any, async () => {
|
|
22
|
+
try {
|
|
23
|
+
this.logInfo('收到清空 IndexedDB 数据请求')
|
|
24
|
+
// 这个 API 主要用于前端调用,后端不直接操作 IndexedDB
|
|
25
|
+
return { success: true, message: '可以清空 IndexedDB' }
|
|
26
|
+
} catch (error: any) {
|
|
27
|
+
this.logger.error('清空 IndexedDB 数据失败:', error)
|
|
28
|
+
return { success: false, error: error?.message || String(error) }
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
21
32
|
// 获取所有聊天数据的 API
|
|
22
33
|
this.ctx.console.addListener('get-chat-data' as any, async () => {
|
|
23
34
|
try {
|
|
@@ -467,7 +478,8 @@ export class ApiHandlers {
|
|
|
467
478
|
keepTempImages: this.config.keepTempImages,
|
|
468
479
|
loggerinfo: this.config.loggerinfo,
|
|
469
480
|
blockedPlatforms: this.config.blockedPlatforms || [],
|
|
470
|
-
chatContainerHeight: this.config.chatContainerHeight
|
|
481
|
+
chatContainerHeight: this.config.chatContainerHeight,
|
|
482
|
+
clearIndexedDBOnStart: this.config.clearIndexedDBOnStart
|
|
471
483
|
}
|
|
472
484
|
}
|
|
473
485
|
} catch (error: any) {
|
package/src/config.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Schema } from 'koishi'
|
|
|
2
2
|
|
|
3
3
|
export interface Config {
|
|
4
4
|
loggerinfo: boolean
|
|
5
|
+
clearIndexedDBOnStart: boolean
|
|
5
6
|
maxMessagesPerChannel: number
|
|
6
7
|
keepMessagesOnClear: number
|
|
7
8
|
keepTempImages: number
|
|
@@ -40,6 +41,10 @@ export const Config: Schema<Config> = Schema.intersect([
|
|
|
40
41
|
|
|
41
42
|
Schema.object({
|
|
42
43
|
chatContainerHeight: Schema.number().default(80).description('手机端使用的视口高度(防止文本输入框被挡住)').min(50).max(100),
|
|
43
|
-
loggerinfo: Schema.boolean().default(false).description('日志调试模式').experimental(),
|
|
44
44
|
}).description('进阶设置'),
|
|
45
|
+
|
|
46
|
+
Schema.object({
|
|
47
|
+
clearIndexedDBOnStart: Schema.boolean().default(true).description('启动时强制清空IndexedDB缓存(适用于紧急情况,防止浏览器卡死)'),
|
|
48
|
+
loggerinfo: Schema.boolean().default(false).description('日志调试模式').experimental(),
|
|
49
|
+
}).description('开发者选项'),
|
|
45
50
|
])
|
package/lib/index.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Console } from '@koishijs/console';
|
|
2
|
-
import { Context } from 'koishi';
|
|
3
|
-
import { Config } from './config';
|
|
4
|
-
export declare const name = "chat-patch";
|
|
5
|
-
export declare const reusable = false;
|
|
6
|
-
export declare const filter = true;
|
|
7
|
-
export declare const inject: {
|
|
8
|
-
required: string[];
|
|
9
|
-
};
|
|
10
|
-
declare module 'koishi' {
|
|
11
|
-
interface Context {
|
|
12
|
-
console: Console;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
export declare const usage = "\n\n---\n\n\u5F00\u542F\u540E\uFF0C\u5373\u53EF\u5728koishi\u63A7\u5236\u53F0\u64CD\u4F5C\u673A\u5668\u4EBA\u6536\u53D1\u6D88\u606F\u5566\n\n\u6682\u65F6\u53EA\u652F\u6301\u63A5\u53D7\u56FE\u6587\u6D88\u606F / \u53D1\u9001\u6587\u5B57\u6D88\u606F\n\n---\n";
|
|
16
|
-
export { Config } from './config';
|
|
17
|
-
export declare function apply(ctx: Context, config: Config): Promise<void>;
|