koishi-plugin-chat-patch 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .scrollbar-hide::-webkit-scrollbar{display:none}.chat-patch-wrapper .el-textarea__inner{border-radius:12px;padding:10px 12px;resize:none}.chat-patch-wrapper .el-button--primary{border-radius:10px}.forward-dialog .el-dialog__body{padding:0}.image-viewer-dialog .el-dialog__header{padding-bottom:10px}.fixed{position:fixed!important}.absolute{position:absolute!important}.relative{position:relative!important}.inset-0{top:0!important;right:0!important;bottom:0!important;left:0!important}.-right-2{right:-.5rem!important}.-top-2{top:-.5rem!important}.z-10{z-index:10!important}.z-50{z-index:50!important}.z-\[2000\]{z-index:2000!important}.z-\[60\]{z-index:60!important}.mx-0\.5{margin-left:.125rem!important;margin-right:.125rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-1\.5{margin-top:.375rem!important;margin-bottom:.375rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.mb-1{margin-bottom:.25rem!important}.mb-1\.5{margin-bottom:.375rem!important}.mb-2{margin-bottom:.5rem!important}.mb-2\.5{margin-bottom:.625rem!important}.mb-3{margin-bottom:.75rem!important}.mb-6{margin-bottom:1.5rem!important}.ml-2{margin-left:.5rem!important}.ml-3{margin-left:.75rem!important}.mr-1{margin-right:.25rem!important}.mr-3{margin-right:.75rem!important}.mt-2{margin-top:.5rem!important}.block{display:block!important}.flex{display:flex!important}.\!h-10,.h-10{height:2.5rem!important}.h-14{height:3.5rem!important}.h-2\.5{height:.625rem!important}.h-20{height:5rem!important}.h-full{height:100%!important}.max-h-\[100px\]{max-height:100px!important}.max-h-\[400px\]{max-height:400px!important}.max-h-\[70vh\]{max-height:70vh!important}.max-h-full{max-height:100%!important}.min-h-\[1em\]{min-height:1em!important}.min-h-full{min-height:100%!important}.\!w-10{width:2.5rem!important}.w-2\.5{width:.625rem!important}.w-20{width:5rem!important}.w-full{width:100%!important}.min-w-\[140px\]{min-width:140px!important}.min-w-\[20px\]{min-width:20px!important}.max-w-\[100px\]{max-width:100px!important}.max-w-\[300px\]{max-width:300px!important}.max-w-\[85\%\]{max-width:85%!important}.max-w-full{max-width:100%!important}.flex-1{flex:1 1 0%!important}.flex-shrink-0{flex-shrink:0!important}.cursor-default{cursor:default!important}.cursor-pointer{cursor:pointer!important}.resize{resize:both!important}.flex-row{flex-direction:row!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-col{flex-direction:column!important}.items-start{align-items:flex-start!important}.items-end{align-items:flex-end!important}.items-center{align-items:center!important}.justify-center{justify-content:center!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:.75rem!important}.gap-4{gap:1rem!important}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0 !important;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)))!important;margin-bottom:calc(.375rem * var(--tw-space-y-reverse))!important}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0 !important;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)))!important;margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))!important}.overflow-hidden{overflow:hidden!important}.overflow-x-auto{overflow-x:auto!important}.truncate{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.break-all{word-break:break-all!important}.rounded{border-radius:.25rem!important}.rounded-2xl{border-radius:1rem!important}.rounded-full{border-radius:9999px!important}.rounded-lg{border-radius:.5rem!important}.rounded-xl{border-radius:.75rem!important}.rounded-tl-none{border-top-left-radius:0!important}.rounded-tr-none{border-top-right-radius:0!important}.border{border-width:1px!important}.border-2{border-width:2px!important}.border-b{border-bottom-width:1px!important}.border-l-4{border-left-width:4px!important}.border-r{border-right-width:1px!important}.border-t{border-top-width:1px!important}.\!border-none{border-style:none!important}.\!border-\[var\(--k-color-primary\)\]{border-color:var(--k-color-primary)!important}.border-\[var\(--k-border-color\)\]{border-color:var(--k-border-color)!important}.border-black\/10{border-color:#0000001a!important}.border-black\/5{border-color:#0000000d!important}.border-gray-400\/50{border-color:#9ca3af80!important}.border-transparent{border-color:transparent!important}.border-white\/10{border-color:#ffffff1a!important}.\!bg-white\/10{background-color:#ffffff1a!important}.bg-\[\#95ec69\]{--tw-bg-opacity: 1 !important;background-color:rgb(149 236 105 / var(--tw-bg-opacity, 1))!important}.bg-\[var\(--k-button-active-bg\)\]{background-color:var(--k-button-active-bg)!important}.bg-\[var\(--k-card-bg\)\]{background-color:var(--k-card-bg)!important}.bg-\[var\(--k-page-bg\)\]{background-color:var(--k-page-bg)!important}.bg-black{--tw-bg-opacity: 1 !important;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))!important}.bg-black\/5{background-color:#0000000d!important}.bg-gray-100{--tw-bg-opacity: 1 !important;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))!important}.bg-gray-400{--tw-bg-opacity: 1 !important;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))!important}.bg-gray-50{--tw-bg-opacity: 1 !important;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))!important}.bg-green-500{--tw-bg-opacity: 1 !important;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))!important}.bg-white{--tw-bg-opacity: 1 !important;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))!important}.bg-opacity-50{--tw-bg-opacity: .5 !important}.bg-opacity-90{--tw-bg-opacity: .9 !important}.object-contain{-o-object-fit:contain!important;object-fit:contain!important}.p-0{padding:0!important}.p-2\.5{padding:.625rem!important}.p-3{padding:.75rem!important}.p-3\.5{padding:.875rem!important}.p-4{padding:1rem!important}.p-6{padding:1.5rem!important}.px-4{padding-left:1rem!important;padding-right:1rem!important}.px-6{padding-left:1.5rem!important;padding-right:1.5rem!important}.py-1\.5{padding-top:.375rem!important;padding-bottom:.375rem!important}.py-2\.5{padding-top:.625rem!important;padding-bottom:.625rem!important}.py-4{padding-top:1rem!important;padding-bottom:1rem!important}.pb-2{padding-bottom:.5rem!important}.pt-2{padding-top:.5rem!important}.text-left{text-align:left!important}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"!important}.\!text-base{font-size:1rem!important;line-height:1.5rem!important}.\!text-xl{font-size:1.25rem!important;line-height:1.75rem!important}.text-\[10px\]{font-size:10px!important}.text-\[15px\]{font-size:15px!important}.text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.text-sm{font-size:.875rem!important;line-height:1.25rem!important}.text-xs{font-size:.75rem!important;line-height:1rem!important}.font-bold{font-weight:700!important}.font-medium{font-weight:500!important}.italic{font-style:italic!important}.leading-relaxed{line-height:1.625!important}.\!text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.text-\[var\(--k-color-primary\)\]{color:var(--k-color-primary)!important}.text-\[var\(--k-text-color\)\]{color:var(--k-text-color)!important}.text-\[var\(--k-text-color-secondary\)\]{color:var(--k-text-color-secondary)!important}.text-black{--tw-text-opacity: 1 !important;color:rgb(0 0 0 / var(--tw-text-opacity, 1))!important}.text-blue-500{--tw-text-opacity: 1 !important;color:rgb(59 130 246 / var(--tw-text-opacity, 1))!important}.text-gray-400{--tw-text-opacity: 1 !important;color:rgb(156 163 175 / var(--tw-text-opacity, 1))!important}.text-orange-400{--tw-text-opacity: 1 !important;color:rgb(251 146 60 / var(--tw-text-opacity, 1))!important}.text-red-500{--tw-text-opacity: 1 !important;color:rgb(239 68 68 / var(--tw-text-opacity, 1))!important}.text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.opacity-0{opacity:0!important}.opacity-50{opacity:.5!important}.opacity-60{opacity:.6!important}.opacity-70{opacity:.7!important}.opacity-80{opacity:.8!important}.opacity-90{opacity:.9!important}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25) !important;--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-\[0_-2px_10px_rgba\(0\,0\,0\,0\.05\)\]{--tw-shadow: 0 -2px 10px rgba(0,0,0,.05) !important;--tw-shadow-colored: 0 -2px 10px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.brightness-100{--tw-brightness: brightness(1) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-105{--tw-brightness: brightness(1.05) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-95{--tw-brightness: brightness(.95) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px) !important;-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important;backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important}.transition-all{transition-property:all!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-opacity{transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-transform{transition-property:transform!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}:root{--chat-bg: var(--k-page-bg);--chat-panel-bg: var(--k-card-bg);--chat-border: var(--k-border-color);--chat-text: var(--k-text-color);--chat-text-sub: var(--k-text-color-secondary)}.chat-patch-wrapper{color:var(--chat-text);background-color:var(--chat-bg)}.chat-patch-wrapper .el-aside,.chat-patch-wrapper .el-main,.chat-patch-wrapper .el-header,.chat-patch-wrapper .el-footer{background-color:transparent!important;color:inherit!important}.chat-patch-wrapper .el-scrollbar{background-color:transparent!important}.chat-patch-wrapper .el-input__wrapper,.chat-patch-wrapper .el-textarea__inner{background-color:var(--k-input-bg)!important;color:var(--chat-text)!important;box-shadow:0 0 0 1px var(--chat-border) inset!important}.chat-patch-wrapper .el-empty{background-color:transparent!important}.layout-iframe{width:100%;height:100%;border:none}.hover\:scale-105:hover{--tw-scale-x: 1.05 !important;--tw-scale-y: 1.05 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.hover\:bg-\[var\(--k-button-hover-bg\)\]:hover{background-color:var(--k-button-hover-bg)!important}.hover\:bg-black\/10:hover{background-color:#0000001a!important}.hover\:underline:hover{text-decoration-line:underline!important}.hover\:opacity-90:hover{opacity:.9!important}.group:hover .group-hover\:opacity-100{opacity:1!important}@media (min-width: 768px){.md\:max-w-\[75\%\]{max-width:75%!important}}@media (prefers-color-scheme: dark){.dark\:border-white\/10{border-color:#ffffff1a!important}.dark\:border-white\/5{border-color:#ffffff0d!important}.dark\:bg-black\/10{background-color:#0000001a!important}.dark\:bg-black\/20{background-color:#0003!important}.dark\:bg-white\/5{background-color:#ffffff0d!important}.dark\:brightness-100{--tw-brightness: brightness(1) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:brightness-90{--tw-brightness: brightness(.9) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:brightness-95{--tw-brightness: brightness(.95) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:hover\:bg-white\/10:hover{background-color:#ffffff1a!important}}
1
+ @charset "UTF-8";.scrollbar-hide::-webkit-scrollbar{display:none}.chat-patch-wrapper .el-textarea__inner{border-radius:12px;padding:10px 12px;resize:none}.chat-patch-wrapper .raw-content-area .el-textarea__inner{font-family:monospace;font-size:14px;line-height:1.5;background:var(--k-card-bg)!important}.chat-patch-wrapper .el-button--primary{border-radius:10px}.forward-dialog .el-dialog__body{padding:0}.image-viewer-dialog .el-dialog__header{padding-bottom:10px}.fixed{position:fixed!important}.absolute{position:absolute!important}.relative{position:relative!important}.inset-0{top:0!important;right:0!important;bottom:0!important;left:0!important}.-right-1\.5{right:-.375rem!important}.-top-1\.5{top:-.375rem!important}.left-0{left:0!important}.right-0{right:0!important}.right-1{right:.25rem!important}.top-1{top:.25rem!important}.z-10{z-index:10!important}.z-50{z-index:50!important}.z-\[2000\]{z-index:2000!important}.z-\[60\]{z-index:60!important}.z-\[70\]{z-index:70!important}.z-\[80\]{z-index:80!important}.mx-0\.5{margin-left:.125rem!important;margin-right:.125rem!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-1\.5{margin-top:.375rem!important;margin-bottom:.375rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.mb-1{margin-bottom:.25rem!important}.mb-1\.5{margin-bottom:.375rem!important}.mb-2{margin-bottom:.5rem!important}.mb-2\.5{margin-bottom:.625rem!important}.mb-3{margin-bottom:.75rem!important}.mb-6{margin-bottom:1.5rem!important}.ml-2{margin-left:.5rem!important}.ml-3{margin-left:.75rem!important}.mr-1{margin-right:.25rem!important}.mr-2{margin-right:.5rem!important}.mr-3{margin-right:.75rem!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-4{margin-top:1rem!important}.block{display:block!important}.flex{display:flex!important}.hidden{display:none!important}.\!h-10,.h-10{height:2.5rem!important}.h-14{height:3.5rem!important}.h-2\.5{height:.625rem!important}.h-20{height:5rem!important}.h-8{height:2rem!important}.h-full{height:100%!important}.max-h-\[100px\]{max-height:100px!important}.max-h-\[400px\]{max-height:400px!important}.max-h-\[70vh\]{max-height:70vh!important}.max-h-full{max-height:100%!important}.min-h-\[1em\]{min-height:1em!important}.\!w-10{width:2.5rem!important}.w-2\.5{width:.625rem!important}.w-20{width:5rem!important}.w-8{width:2rem!important}.w-full{width:100%!important}.min-w-\[140px\]{min-width:140px!important}.min-w-\[20px\]{min-width:20px!important}.max-w-\[100px\]{max-width:100px!important}.max-w-\[300px\]{max-width:300px!important}.max-w-\[85\%\]{max-width:85%!important}.max-w-full{max-width:100%!important}.flex-1{flex:1 1 0%!important}.flex-shrink-0{flex-shrink:0!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.cursor-context-menu{cursor:context-menu!important}.cursor-default{cursor:default!important}.cursor-pointer{cursor:pointer!important}.resize{resize:both!important}.flex-row{flex-direction:row!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-col{flex-direction:column!important}.items-start{align-items:flex-start!important}.items-end{align-items:flex-end!important}.items-center{align-items:center!important}.justify-center{justify-content:center!important}.justify-between{justify-content:space-between!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:.75rem!important}.gap-4{gap:1rem!important}.gap-6{gap:1.5rem!important}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0 !important;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)))!important;margin-bottom:calc(.375rem * var(--tw-space-y-reverse))!important}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0 !important;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)))!important;margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-x-auto{overflow-x:auto!important}.truncate{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.break-all{word-break:break-all!important}.rounded{border-radius:.25rem!important}.rounded-2xl{border-radius:1rem!important}.rounded-full{border-radius:9999px!important}.rounded-lg{border-radius:.5rem!important}.rounded-xl{border-radius:.75rem!important}.rounded-tl-none{border-top-left-radius:0!important}.rounded-tr-none{border-top-right-radius:0!important}.border{border-width:1px!important}.border-2{border-width:2px!important}.border-b{border-bottom-width:1px!important}.border-l-4{border-left-width:4px!important}.border-r{border-right-width:1px!important}.border-t{border-top-width:1px!important}.\!border-none{border-style:none!important}.\!border-\[var\(--k-color-primary\)\]{border-color:var(--k-color-primary)!important}.border-\[var\(--k-border-color\)\]{border-color:var(--k-border-color)!important}.border-black\/10{border-color:#0000001a!important}.border-black\/5{border-color:#0000000d!important}.border-blue-500{--tw-border-opacity: 1 !important;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))!important}.border-gray-400\/50{border-color:#9ca3af80!important}.border-transparent{border-color:transparent!important}.border-white\/10{border-color:#ffffff1a!important}.\!bg-white\/10{background-color:#ffffff1a!important}.bg-\[\#95ec69\]{--tw-bg-opacity: 1 !important;background-color:rgb(149 236 105 / var(--tw-bg-opacity, 1))!important}.bg-\[var\(--k-button-active-bg\)\]{background-color:var(--k-button-active-bg)!important}.bg-\[var\(--k-card-bg\)\]{background-color:var(--k-card-bg)!important}.bg-\[var\(--k-page-bg\)\]{background-color:var(--k-page-bg)!important}.bg-black{--tw-bg-opacity: 1 !important;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))!important}.bg-black\/5{background-color:#0000000d!important}.bg-blue-50\/10{background-color:#eff6ff1a!important}.bg-gray-100{--tw-bg-opacity: 1 !important;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))!important}.bg-gray-400{--tw-bg-opacity: 1 !important;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))!important}.bg-gray-50{--tw-bg-opacity: 1 !important;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))!important}.bg-green-500{--tw-bg-opacity: 1 !important;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))!important}.bg-white{--tw-bg-opacity: 1 !important;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))!important}.bg-opacity-50{--tw-bg-opacity: .5 !important}.bg-opacity-90{--tw-bg-opacity: .9 !important}.object-contain{-o-object-fit:contain!important;object-fit:contain!important}.p-0{padding:0!important}.p-10{padding:2.5rem!important}.p-2\.5{padding:.625rem!important}.p-3{padding:.75rem!important}.p-3\.5{padding:.875rem!important}.p-4{padding:1rem!important}.p-6{padding:1.5rem!important}.p-8{padding:2rem!important}.px-3{padding-left:.75rem!important;padding-right:.75rem!important}.px-4{padding-left:1rem!important;padding-right:1rem!important}.px-6{padding-left:1.5rem!important;padding-right:1.5rem!important}.py-1\.5{padding-top:.375rem!important;padding-bottom:.375rem!important}.py-2\.5{padding-top:.625rem!important;padding-bottom:.625rem!important}.py-4{padding-top:1rem!important;padding-bottom:1rem!important}.pb-2{padding-bottom:.5rem!important}.pb-8{padding-bottom:2rem!important}.pr-8{padding-right:2rem!important}.pt-2{padding-top:.5rem!important}.text-left{text-align:left!important}.text-center{text-align:center!important}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"!important}.\!text-base{font-size:1rem!important;line-height:1.5rem!important}.\!text-xl{font-size:1.25rem!important;line-height:1.75rem!important}.text-2xl{font-size:1.5rem!important;line-height:2rem!important}.text-\[10px\]{font-size:10px!important}.text-\[15px\]{font-size:15px!important}.text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.text-sm{font-size:.875rem!important;line-height:1.25rem!important}.text-xl{font-size:1.25rem!important;line-height:1.75rem!important}.text-xs{font-size:.75rem!important;line-height:1rem!important}.font-bold{font-weight:700!important}.font-medium{font-weight:500!important}.italic{font-style:italic!important}.leading-relaxed{line-height:1.625!important}.\!text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.text-\[var\(--k-color-primary\)\]{color:var(--k-color-primary)!important}.text-\[var\(--k-text-color\)\]{color:var(--k-text-color)!important}.text-\[var\(--k-text-color-secondary\)\]{color:var(--k-text-color-secondary)!important}.text-black{--tw-text-opacity: 1 !important;color:rgb(0 0 0 / var(--tw-text-opacity, 1))!important}.text-blue-500{--tw-text-opacity: 1 !important;color:rgb(59 130 246 / var(--tw-text-opacity, 1))!important}.text-gray-400{--tw-text-opacity: 1 !important;color:rgb(156 163 175 / var(--tw-text-opacity, 1))!important}.text-orange-400{--tw-text-opacity: 1 !important;color:rgb(251 146 60 / var(--tw-text-opacity, 1))!important}.text-red-500{--tw-text-opacity: 1 !important;color:rgb(239 68 68 / var(--tw-text-opacity, 1))!important}.text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.opacity-0{opacity:0!important}.opacity-100{opacity:1!important}.opacity-40{opacity:.4!important}.opacity-50{opacity:.5!important}.opacity-60{opacity:.6!important}.opacity-70{opacity:.7!important}.opacity-80{opacity:.8!important}.opacity-90{opacity:.9!important}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-\[0_-2px_10px_rgba\(0\,0\,0\,0\.05\)\]{--tw-shadow: 0 -2px 10px rgba(0,0,0,.05) !important;--tw-shadow-colored: 0 -2px 10px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.blur{--tw-blur: blur(8px) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-100{--tw-brightness: brightness(1) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-105{--tw-brightness: brightness(1.05) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-95{--tw-brightness: brightness(.95) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px) !important;-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important;backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important}.transition-all{transition-property:all!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-opacity{transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-transform{transition-property:transform!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.duration-200{transition-duration:.2s!important}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)!important}.will-change-transform{will-change:transform!important}:root{--chat-bg: var(--k-page-bg);--chat-panel-bg: var(--k-card-bg);--chat-border: var(--k-border-color);--chat-text: var(--k-text-color);--chat-text-sub: var(--k-text-color-secondary)}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__bar{display:none!important;opacity:0!important;width:0!important;height:0!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__thumb{display:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap{overflow-x:hidden!important;scrollbar-width:none!important;-ms-overflow-style:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar{display:none!important;width:0!important;height:0!important;background:transparent!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar-track{display:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar-thumb{display:none!important}.chat-patch-wrapper{color:var(--chat-text);background-color:var(--chat-bg)}.chat-patch-wrapper .el-aside,.chat-patch-wrapper .el-main,.chat-patch-wrapper .el-header,.chat-patch-wrapper .el-footer{background-color:transparent!important;color:inherit!important}.chat-patch-wrapper .el-scrollbar{background-color:transparent!important}.chat-patch-wrapper .el-input__wrapper,.chat-patch-wrapper .el-textarea__inner{background-color:var(--k-input-bg)!important;color:var(--chat-text)!important;box-shadow:0 0 0 1px var(--chat-border) inset!important}.chat-patch-wrapper .el-empty{background-color:transparent!important}.layout-iframe{width:100%;height:100%;border:none}.message-highlight{animation:highlight-fade 1.5s ease-in-out;border-radius:8px}@keyframes highlight-fade{0%{background-color:transparent}10%{background-color:#409eff66;filter:brightness(1.2)}30%{background-color:#409eff66;filter:brightness(1.2)}to{background-color:transparent}}.hover\:scale-105:hover{--tw-scale-x: 1.05 !important;--tw-scale-y: 1.05 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.hover\:scale-110:hover{--tw-scale-x: 1.1 !important;--tw-scale-y: 1.1 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.hover\:bg-\[var\(--k-button-hover-bg\)\]:hover{background-color:var(--k-button-hover-bg)!important}.hover\:bg-black\/10:hover{background-color:#0000001a!important}.hover\:text-red-500:hover{--tw-text-opacity: 1 !important;color:rgb(239 68 68 / var(--tw-text-opacity, 1))!important}.hover\:underline:hover{text-decoration-line:underline!important}.hover\:opacity-90:hover{opacity:.9!important}.hover\:brightness-90:hover{--tw-brightness: brightness(.9) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.active\:scale-95:active{--tw-scale-x: .95 !important;--tw-scale-y: .95 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.group\/msg:hover .group-hover\/msg\:opacity-100,.group\/quote:hover .group-hover\/quote\:opacity-100,.group:hover .group-hover\:opacity-100{opacity:1!important}@media (min-width: 768px){.md\:inline{display:inline!important}.md\:max-w-\[75\%\]{max-width:75%!important}}@media (prefers-color-scheme: dark){.dark\:border-white\/10{border-color:#ffffff1a!important}.dark\:border-white\/5{border-color:#ffffff0d!important}.dark\:bg-black\/10{background-color:#0000001a!important}.dark\:bg-black\/20{background-color:#0003!important}.dark\:bg-white\/5{background-color:#ffffff0d!important}.dark\:brightness-100{--tw-brightness: brightness(1) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:brightness-90{--tw-brightness: brightness(.9) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:brightness-95{--tw-brightness: brightness(.95) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:hover\:bg-white\/10:hover{background-color:#ffffff1a!important}}
@@ -0,0 +1,19 @@
1
+ import { FileManager } from './file-manager';
2
+ import { MessageHandler } from './message-handler';
3
+ import { Context } from 'koishi';
4
+ import { Config } from './config';
5
+ export declare class ApiHandlers {
6
+ private ctx;
7
+ private config;
8
+ private fileManager;
9
+ private messageHandler;
10
+ private logger;
11
+ constructor(ctx: Context, config: Config, fileManager: FileManager, messageHandler: MessageHandler);
12
+ registerApiHandlers(): void;
13
+ private isFileUrl;
14
+ private createFileUrl;
15
+ private handleLocalFileRequest;
16
+ private setupTempFileCleanup;
17
+ private cleanupMediaCache;
18
+ private logInfo;
19
+ }
package/lib/index.js CHANGED
@@ -197,55 +197,118 @@ var MessageHandler = class {
197
197
  }
198
198
  // 更新频道信息到JSON文件
199
199
  async updateChannelInfoToFile(session) {
200
+ const isDirect = session.isDirect || session.channelId?.includes("private");
200
201
  let guildName = session.channelId;
201
- let directUserName = session.username || session.userId || "未知用户";
202
+ const directUserName = session.username || session.event?.user?.name || session.userId;
202
203
  const data = this.fileManager.readChatDataFromFile();
203
- try {
204
- if (session.guildId && session.bot.getGuild && typeof session.bot.getGuild === "function") {
205
- const guild = await session.bot.getGuild(session.guildId);
206
- guildName = guild?.name || session.channelId;
207
- }
208
- if (session.userId && session.isDirect && session.bot.getUser && typeof session.bot.getUser === "function") {
209
- try {
210
- const user = await session.bot.getUser(session.userId);
211
- directUserName = user?.name || session.username || session.userId || "未知用户";
212
- } catch (userError) {
213
- this.logInfo("获取用户信息失败,使用备用名称:", userError);
204
+ if (!isDirect) {
205
+ try {
206
+ if (session.guildId && session.bot.getGuild && typeof session.bot.getGuild === "function") {
207
+ const guild = await session.bot.getGuild(session.guildId);
208
+ guildName = guild?.name || session.channelId;
214
209
  }
215
- }
216
- if (session.guildId && !session.bot.getGuild && session.bot.getChannel && typeof session.bot.getChannel === "function") {
217
- try {
218
- const channel = await session.bot.getChannel(session.guildId);
219
- guildName = channel?.name || session.channelId;
220
- } catch (channelError) {
221
- this.logInfo("获取频道信息失败,使用频道ID作为备用:", channelError);
210
+ if (session.guildId && !session.bot.getGuild && session.bot.getChannel && typeof session.bot.getChannel === "function") {
211
+ try {
212
+ const channel = await session.bot.getChannel(session.guildId);
213
+ guildName = channel?.name || session.channelId;
214
+ } catch (channelError) {
215
+ this.logInfo("获取频道信息失败,使用频道ID作为备用:", channelError);
216
+ }
222
217
  }
218
+ } catch (error) {
219
+ this.logInfo("获取频道信息失败,使用频道ID作为备用:", error);
220
+ guildName = session.channelId;
223
221
  }
224
- } catch (error) {
225
- this.logInfo("获取频道信息失败,使用频道ID作为备用:", error);
226
- guildName = session.channelId;
227
222
  }
228
223
  if (!data.channels[session.selfId]) {
229
224
  data.channels[session.selfId] = {};
230
225
  }
226
+ const existingChannel = data.channels[session.selfId][session.channelId];
227
+ let finalName;
228
+ if (isDirect) {
229
+ if (directUserName && directUserName !== session.userId) {
230
+ finalName = `私聊(${directUserName})`;
231
+ } else if (existingChannel?.name && !existingChannel.name.includes("未知")) {
232
+ finalName = existingChannel.name;
233
+ } else {
234
+ finalName = "私聊(未知用户)";
235
+ }
236
+ } else {
237
+ finalName = guildName || session.channelId;
238
+ }
231
239
  const channelInfo = {
232
240
  id: session.channelId,
233
- name: session.isDirect ? `私聊(${session.username || session.userId || directUserName})` : `${guildName} (${session.channelId})`,
241
+ name: finalName,
234
242
  type: session.type || 0,
235
243
  channelId: session.channelId,
236
244
  guildName,
237
- isDirect: session.isDirect
245
+ isDirect: !!isDirect
238
246
  };
247
+ if (existingChannel && existingChannel.name !== finalName) {
248
+ this.logInfo("更新频道名称:", {
249
+ channelId: session.channelId,
250
+ oldName: existingChannel.name,
251
+ newName: finalName
252
+ });
253
+ }
239
254
  data.channels[session.selfId][session.channelId] = channelInfo;
240
255
  this.fileManager.writeChatDataToFile(data);
241
256
  this.logInfo("更新频道信息到文件:", channelInfo.name);
242
257
  return guildName;
243
258
  }
259
+ // 下载并缓存媒体文件
260
+ async downloadAndCacheMedia(url, type) {
261
+ try {
262
+ if (!url || url.startsWith("data:") || url.startsWith("file:")) return url;
263
+ let folder = "media";
264
+ if (type === "image") folder = "images";
265
+ else if (type === "avatar") folder = "avatars";
266
+ const dir = require("node:path").join(this.ctx.baseDir, "data", "chat-patch", "persist-media", folder);
267
+ if (!require("node:fs").existsSync(dir)) {
268
+ require("node:fs").mkdirSync(dir, { recursive: true });
269
+ }
270
+ const crypto = require("node:crypto");
271
+ const hash = crypto.createHash("md5").update(url).digest("hex");
272
+ const ext = require("node:path").extname(new URL(url).pathname) || (type === "image" ? ".jpg" : ".mp4");
273
+ const filename = `${hash}${ext}`;
274
+ const filePath = require("node:path").join(dir, filename);
275
+ if (require("node:fs").existsSync(filePath)) {
276
+ return require("node:url").pathToFileURL(filePath).href;
277
+ }
278
+ const buffer = await this.ctx.http.get(url, { responseType: "arraybuffer" });
279
+ require("node:fs").writeFileSync(filePath, Buffer.from(buffer));
280
+ return require("node:url").pathToFileURL(filePath).href;
281
+ } catch (e) {
282
+ return url;
283
+ }
284
+ }
285
+ // 处理消息中的媒体元素并缓存
286
+ async processMediaElements(elements) {
287
+ if (!elements) return elements;
288
+ for (const el of elements) {
289
+ if (["image", "img", "mface"].includes(el.type)) {
290
+ const src = el.attrs.src || el.attrs.url || el.attrs.file;
291
+ if (src) el.attrs.src = await this.downloadAndCacheMedia(src, "image");
292
+ } else if (["audio", "video"].includes(el.type)) {
293
+ const src = el.attrs.src || el.attrs.url || el.attrs.file;
294
+ if (src) el.attrs.src = await this.downloadAndCacheMedia(src, "media");
295
+ }
296
+ if (el.children) await this.processMediaElements(el.children);
297
+ }
298
+ return elements;
299
+ }
244
300
  async broadcastMessageEvent(session) {
245
301
  try {
246
302
  await this.updateBotInfoToFile(session);
247
303
  const guildName = await this.updateChannelInfoToFile(session);
304
+ const isDirect = session.isDirect || session.channelId?.includes("private");
248
305
  const timestamp = Date.now();
306
+ if (session.elements) {
307
+ await this.processMediaElements(session.elements);
308
+ }
309
+ if (session.quote?.elements) {
310
+ await this.processMediaElements(session.quote.elements);
311
+ }
249
312
  let quoteInfo = void 0;
250
313
  if (session.quote) {
251
314
  quoteInfo = {
@@ -290,7 +353,7 @@ var MessageHandler = class {
290
353
  guildName,
291
354
  platform: session.platform || "unknown",
292
355
  quote: quoteInfo ? this.utils.cleanBase64Content(quoteInfo) : void 0,
293
- isDirect: session.isDirect
356
+ isDirect: !!isDirect
294
357
  };
295
358
  await this.fileManager.addMessageToFile(messageInfo);
296
359
  const messageEvent = {
@@ -323,22 +386,47 @@ var MessageHandler = class {
323
386
  async broadcastBotMessageEvent(session) {
324
387
  try {
325
388
  const correctChannelId = this.getCorrectChannelId(session.selfId);
326
- this.logInfo("机器人发送消息调试信息:", {
327
- "session.channelId": session.channelId,
328
- "session.event?.channel?.id": session.event?.channel?.id,
329
- "correctChannelId": correctChannelId,
330
- "session.guildId": session.guildId,
331
- "session.isDirect": session.isDirect,
332
- "session.platform": session.platform
333
- });
334
389
  const finalChannelId = correctChannelId || session.channelId;
335
390
  await this.updateBotInfoToFile(session);
336
391
  const guildName = await this.updateChannelInfoToFile(session);
392
+ const isDirect = session.isDirect || finalChannelId?.includes("private");
337
393
  const timestamp = Date.now();
394
+ if (session.event?.message?.elements) {
395
+ await this.processMediaElements(session.event.message.elements);
396
+ }
338
397
  let content = session.content || "";
339
398
  if (!content && session.event?.message?.elements) {
340
399
  content = this.utils.extractTextContent(session.event.message.elements).trim();
341
400
  }
401
+ let quoteInfo = void 0;
402
+ const quoteMatch = content.match(/<quote id="([^"]+)"\/>/);
403
+ if (quoteMatch) {
404
+ const quoteId = quoteMatch[1];
405
+ const data = this.fileManager.readChatDataFromFile();
406
+ const channelKey = `${session.selfId}:${finalChannelId}`;
407
+ const quotedMsg = data.messages[channelKey]?.find((m) => m.id === quoteId);
408
+ if (quotedMsg) {
409
+ const realId = quotedMsg.id.startsWith("bot-msg-") ? quotedMsg.realId : quotedMsg.id;
410
+ quoteInfo = {
411
+ messageId: realId || quotedMsg.id,
412
+ id: realId || quotedMsg.id,
413
+ content: quotedMsg.content,
414
+ elements: quotedMsg.elements,
415
+ user: {
416
+ id: quotedMsg.userId,
417
+ name: quotedMsg.username,
418
+ userId: quotedMsg.userId,
419
+ avatar: quotedMsg.avatar,
420
+ username: quotedMsg.username
421
+ },
422
+ timestamp: quotedMsg.timestamp
423
+ };
424
+ content = content.replace(/<quote id="[^"]+"\/>\s*/, "");
425
+ if (realId) {
426
+ session.content = session.content.replace(/id="[^"]+"/, `id="${realId}"`);
427
+ }
428
+ }
429
+ }
342
430
  const messageInfo = {
343
431
  id: `bot-msg-${timestamp}`,
344
432
  content,
@@ -352,7 +440,10 @@ var MessageHandler = class {
352
440
  type: "bot",
353
441
  guildName,
354
442
  platform: session.platform || "unknown",
355
- isDirect: session.isDirect
443
+ quote: quoteInfo,
444
+ isDirect: !!isDirect,
445
+ sending: true
446
+ // 标记为正在发送
356
447
  };
357
448
  await this.fileManager.addMessageToFile(messageInfo);
358
449
  const messageEvent = {
@@ -369,26 +460,14 @@ var MessageHandler = class {
369
460
  guildName,
370
461
  channelType: session.event?.channel?.type || session.type || 0,
371
462
  elements: this.utils.cleanBase64Content(session.event?.message?.elements),
372
- isDirect: session.isDirect,
463
+ quote: quoteInfo,
464
+ isDirect: !!isDirect,
465
+ sending: true,
373
466
  bot: {
374
467
  avatar: session.bot.user?.avatar,
375
468
  name: session.bot.user?.name
376
469
  }
377
470
  };
378
- const imageElements = session.event?.message?.elements?.filter(
379
- (element) => element.type === "img" || element.type === "image" || element.type === "mface"
380
- ) || [];
381
- this.logInfo("机器人发送消息 (before-send):", {
382
- selfId: session.selfId,
383
- channelId: messageEvent.channelId,
384
- originalChannelId: session.channelId,
385
- correctedChannelId: finalChannelId,
386
- content,
387
- platform: session.platform,
388
- imageCount: imageElements.length,
389
- imageUrls: imageElements.map((el) => el.attrs?.src || el.attrs?.url || el.attrs?.file)
390
- });
391
- this.correctChannelIds.delete(session.selfId);
392
471
  this.ctx.console.broadcast("chat-bot-message-event", messageEvent);
393
472
  } catch (error) {
394
473
  this.logger.error("广播机器人消息事件失败:", error);
@@ -574,19 +653,16 @@ var ApiHandlers = class {
574
653
  this.ctx.console.addListener("get-chat-data", async () => {
575
654
  try {
576
655
  const data = this.fileManager.readChatDataFromFile();
577
- const cleanedData = this.fileManager.cleanExcessMessages(data);
578
- this.logInfo("获取聊天数据:", {
579
- 机器人数量: Object.keys(cleanedData.bots).length,
580
- 频道数量: Object.keys(cleanedData.channels).reduce((total, botId) => total + Object.keys(cleanedData.channels[botId] || {}).length, 0),
581
- 消息频道数: Object.keys(cleanedData.messages).length,
582
- 总消息数: Object.values(cleanedData.messages).reduce((total, msgs) => total + msgs.length, 0)
583
- });
656
+ this.logInfo("获取基础聊天数据");
584
657
  return {
585
658
  success: true,
586
659
  data: {
587
- ...cleanedData,
588
- pinnedBots: cleanedData.pinnedBots,
589
- pinnedChannels: cleanedData.pinnedChannels
660
+ bots: data.bots || {},
661
+ channels: data.channels || {},
662
+ pinnedBots: data.pinnedBots || [],
663
+ pinnedChannels: data.pinnedChannels || [],
664
+ // 不返回 messages,由前端按需拉取
665
+ messages: {}
590
666
  }
591
667
  };
592
668
  } catch (error) {
@@ -731,31 +807,23 @@ var ApiHandlers = class {
731
807
  this.logInfo("消息发送成功:", result);
732
808
  const messageId = Array.isArray(result) ? result[0] : result;
733
809
  if (messageId) {
734
- const bot2 = this.ctx.bots.find((b) => b.selfId === data.selfId);
735
- const botMessageEvent = {
736
- type: "bot-message-sent",
737
- selfId: data.selfId,
738
- platform: bot2?.platform || "unknown",
739
- channelId: data.channelId,
740
- messageId,
741
- content: messageContent,
742
- userId: data.selfId,
743
- username: bot2?.user?.name || `Bot-${data.selfId}`,
744
- avatar: bot2?.user?.avatar,
745
- timestamp: Date.now(),
746
- guildName: "",
747
- // 这个信息在前端会补充
748
- channelType: 0,
749
- // 这个信息在前端会补充
750
- elements: [],
751
- // 这个信息在前端会补充
752
- isDirect: false
753
- // 这个信息在前端会补充
754
- };
755
- this.ctx.console.broadcast("bot-message-sent-event", botMessageEvent);
810
+ const chatData = this.fileManager.readChatDataFromFile();
811
+ const channelKey = `${data.selfId}:${data.channelId}`;
812
+ const messages = chatData.messages[channelKey] || [];
813
+ const msg = [...messages].reverse().find((m) => m.type === "bot" && m.sending);
814
+ if (msg) {
815
+ msg.realId = messageId;
816
+ msg.sending = false;
817
+ this.fileManager.writeChatDataToFile(chatData);
818
+ this.ctx.console.broadcast("bot-message-updated", {
819
+ channelKey,
820
+ tempId: msg.id,
821
+ realId: messageId
822
+ });
823
+ }
756
824
  }
757
825
  return {
758
- success: true,
826
+ success: !!messageId,
759
827
  messageId,
760
828
  tempImageIds: data.images?.map((img) => img.tempId) || []
761
829
  };
@@ -923,6 +991,61 @@ var ApiHandlers = class {
923
991
  return { success: false, error: error?.message || String(error) };
924
992
  }
925
993
  });
994
+ this.ctx.console.addListener("get-user-info", async (data) => {
995
+ try {
996
+ const bot = this.ctx.bots.find((b) => b.selfId === data.selfId);
997
+ if (!bot) return { success: false, error: "机器人不存在" };
998
+ const user = await bot.getUser(data.userId, data.guildId);
999
+ if (user) {
1000
+ if (user.avatar) {
1001
+ user.avatar = await this.messageHandler.downloadAndCacheMedia(user.avatar, "avatar");
1002
+ }
1003
+ const chatData = this.fileManager.readChatDataFromFile();
1004
+ let changed = false;
1005
+ const botChannels = chatData.channels[data.selfId] || {};
1006
+ const possibleChannelIds = [
1007
+ data.userId,
1008
+ `private:${data.userId}`,
1009
+ `direct:${data.userId}`
1010
+ ];
1011
+ for (const channelId of possibleChannelIds) {
1012
+ const channel = botChannels[channelId];
1013
+ if (channel && channel.isDirect) {
1014
+ const newName = `私聊(${user.name})`;
1015
+ if (channel.name !== newName) {
1016
+ channel.name = newName;
1017
+ changed = true;
1018
+ this.logInfo("更新私聊频道名称:", { channelId, oldName: channel.name, newName });
1019
+ }
1020
+ }
1021
+ }
1022
+ const channelKeyPrefix = `${data.selfId}:`;
1023
+ for (const [key, messages] of Object.entries(chatData.messages)) {
1024
+ if (key.startsWith(channelKeyPrefix)) {
1025
+ messages.forEach((msg) => {
1026
+ if (msg.userId === data.userId) {
1027
+ if (user.name && msg.username !== user.name) {
1028
+ msg.username = user.name;
1029
+ changed = true;
1030
+ }
1031
+ if (user.avatar && msg.avatar !== user.avatar) {
1032
+ msg.avatar = user.avatar;
1033
+ changed = true;
1034
+ }
1035
+ }
1036
+ });
1037
+ }
1038
+ }
1039
+ if (changed) {
1040
+ this.fileManager.writeChatDataToFile(chatData);
1041
+ this.ctx.console.broadcast("chat-data-updated", {});
1042
+ }
1043
+ }
1044
+ return { success: true, data: user };
1045
+ } catch (error) {
1046
+ return { success: false, error: error?.message || "获取用户信息失败" };
1047
+ }
1048
+ });
926
1049
  this.ctx.console.addListener("debug-get-raw-data", async () => {
927
1050
  try {
928
1051
  const data = this.fileManager.readChatDataFromFile();
@@ -979,61 +1102,32 @@ var ApiHandlers = class {
979
1102
  // 设置定时清理临时文件
980
1103
  setupTempFileCleanup() {
981
1104
  setInterval(() => {
982
- this.cleanupTempImagesByCount();
1105
+ this.cleanupMediaCache();
983
1106
  }, 5 * 60 * 1e3);
984
1107
  }
985
- // 基于数量清理临时图片(保留最新的N张)
986
- async cleanupTempImagesByCount() {
987
- try {
988
- const tempDir = this.ctx.baseDir + "/data/chat-patch/temp";
989
- if (!require("fs").existsSync(tempDir)) {
990
- return;
991
- }
992
- const now = Date.now();
993
- const protectionTime = 30 * 1e3;
994
- const files = require("fs").readdirSync(tempDir).filter((file) => file.startsWith("temp_")).map((file) => {
995
- const filePath = `${tempDir}/${file}`;
996
- try {
997
- const stats = require("fs").statSync(filePath);
998
- const fileAge = now - stats.mtime.getTime();
999
- return {
1000
- name: file,
1001
- path: filePath,
1002
- mtime: stats.mtime.getTime(),
1003
- age: fileAge,
1004
- protected: fileAge < protectionTime
1005
- // 是否在保护期内
1006
- };
1007
- } catch (error) {
1008
- return null;
1009
- }
1010
- }).filter((file) => file !== null).sort((a, b) => b.mtime - a.mtime);
1011
- const keepCount = this.config.keepTempImages;
1012
- let cleanedCount = 0;
1013
- let protectedCount = 0;
1014
- const protectedFiles = files.filter((file) => file.protected);
1015
- const deletableFiles = files.filter((file) => !file.protected);
1016
- protectedCount = protectedFiles.length;
1017
- if (deletableFiles.length > keepCount) {
1018
- const filesToDelete = deletableFiles.slice(keepCount);
1019
- for (const file of filesToDelete) {
1108
+ // 统一清理媒体缓存
1109
+ async cleanupMediaCache() {
1110
+ const baseDir = this.ctx.baseDir + "/data/chat-patch/persist-media";
1111
+ if (!require("node:fs").existsSync(baseDir)) return;
1112
+ const cleanupDir = /* @__PURE__ */ __name((dirName, limit) => {
1113
+ const dirPath = require("node:path").join(baseDir, dirName);
1114
+ if (!require("node:fs").existsSync(dirPath)) return;
1115
+ const files = require("node:fs").readdirSync(dirPath).map((file) => {
1116
+ const filePath = require("node:path").join(dirPath, file);
1117
+ const stats = require("node:fs").statSync(filePath);
1118
+ return { name: file, path: filePath, mtime: stats.mtimeMs };
1119
+ }).sort((a, b) => b.mtime - a.mtime);
1120
+ if (files.length > limit) {
1121
+ files.slice(limit).forEach((f) => {
1020
1122
  try {
1021
- if (require("fs").existsSync(file.path)) {
1022
- require("fs").unlinkSync(file.path);
1023
- cleanedCount++;
1024
- this.logInfo("清理多余临时图片:", file.path);
1025
- }
1026
- } catch (fileError) {
1027
- this.logger.warn("删除临时文件失败:", { file: file.name, error: fileError });
1123
+ require("node:fs").unlinkSync(f.path);
1124
+ } catch {
1028
1125
  }
1029
- }
1030
- }
1031
- if (cleanedCount > 0 || protectedCount > 0) {
1032
- this.logInfo(`基于数量清理完成,保留最新 ${keepCount} 张图片,清理了 ${cleanedCount} 张多余图片,保护了 ${protectedCount} 张新上传图片`);
1126
+ });
1033
1127
  }
1034
- } catch (error) {
1035
- this.logger.warn("基于数量清理临时文件失败:", error);
1036
- }
1128
+ }, "cleanupDir");
1129
+ cleanupDir("images", 100);
1130
+ cleanupDir("media", 20);
1037
1131
  }
1038
1132
  logInfo(...args) {
1039
1133
  if (this.config.loggerinfo) {
@@ -0,0 +1,21 @@
1
+ import { Context, Session } from 'koishi';
2
+ import { FileManager } from './file-manager';
3
+ import { Config } from './config';
4
+ export declare class MessageHandler {
5
+ private ctx;
6
+ private config;
7
+ private fileManager;
8
+ private logger;
9
+ private utils;
10
+ private correctChannelIds;
11
+ constructor(ctx: Context, config: Config, fileManager: FileManager);
12
+ setCorrectChannelId(selfId: string, channelId: string): void;
13
+ getCorrectChannelId(selfId: string): string | undefined;
14
+ updateBotInfoToFile(session: Session): Promise<void>;
15
+ updateChannelInfoToFile(session: Session): Promise<string>;
16
+ downloadAndCacheMedia(url: string, type: 'image' | 'media' | 'avatar'): Promise<any>;
17
+ private processMediaElements;
18
+ broadcastMessageEvent(session: Session): Promise<void>;
19
+ broadcastBotMessageEvent(session: Session): Promise<void>;
20
+ private logInfo;
21
+ }
package/lib/types.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ import { h } from 'koishi';
2
+ export interface BotInfo {
3
+ selfId: string;
4
+ platform: string;
5
+ username: string;
6
+ avatar?: string;
7
+ status: 'online' | 'offline';
8
+ }
9
+ export interface ChannelInfo {
10
+ id: string;
11
+ name: string;
12
+ type: number | string;
13
+ channelId?: string;
14
+ guildName?: string;
15
+ isDirect?: boolean;
16
+ }
17
+ export interface QuoteInfo {
18
+ messageId: string;
19
+ id: string;
20
+ content: string;
21
+ elements?: h[];
22
+ user: {
23
+ id: string;
24
+ name: string;
25
+ userId: string;
26
+ avatar?: string;
27
+ username: string;
28
+ };
29
+ timestamp: number;
30
+ }
31
+ export interface MessageInfo {
32
+ id: string;
33
+ content: string;
34
+ userId: string;
35
+ username: string;
36
+ avatar?: string;
37
+ timestamp: number;
38
+ channelId: string;
39
+ selfId: string;
40
+ elements?: h[];
41
+ type: 'user' | 'bot';
42
+ guildId?: string;
43
+ guildName?: string;
44
+ platform: string;
45
+ quote?: QuoteInfo;
46
+ isDirect?: boolean;
47
+ sending?: boolean;
48
+ realId?: string;
49
+ }
50
+ export interface ChatData {
51
+ bots: Record<string, BotInfo>;
52
+ channels: Record<string, Record<string, ChannelInfo>>;
53
+ messages: Record<string, MessageInfo[]>;
54
+ pinnedBots: string[];
55
+ pinnedChannels: string[];
56
+ lastSaveTime?: number;
57
+ }
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": "2.0.1",
4
+ "version": "2.1.0",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [