plugin-ai-chat-file-preview 1.1.1 → 1.1.2
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/client/index.js +1 -1
- package/dist/externalVersion.js +3 -3
- package/package.json +32 -32
- package/src/client/ChatFilePreviewProvider.tsx +137 -69
package/dist/client/index.js
CHANGED
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("@nocobase/plugin-ai/client"),require("@nocobase/client"),require("antd")):"function"==typeof define&&define.amd?define("plugin-ai-chat-file-preview",["react","@nocobase/plugin-ai/client","@nocobase/client","antd"],t):"object"==typeof exports?exports["plugin-ai-chat-file-preview"]=t(require("react"),require("@nocobase/plugin-ai/client"),require("@nocobase/client"),require("antd")):e["plugin-ai-chat-file-preview"]=t(e.react,e["@nocobase/plugin-ai/client"],e["@nocobase/client"],e.antd)}(self,function(e,t,n,r){return function(){"use strict";var o={772:function(e){e.exports=n},645:function(e){e.exports=t},721:function(e){e.exports=r},156:function(t){t.exports=e}},a={};function i(e){var t=a[e];if(void 0!==t)return t.exports;var n=a[e]={exports:{}};return o[e](n,n.exports,i),n.exports}i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,{a:t}),t},i.d=function(e,t){for(var n in t)i.o(t,n)&&!i.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var l={};return!function(){i.r(l),i.d(l,{PluginAIChatFilePreviewClient:function(){return A},default:function(){return I}});var e=i(772),t=i(156),n=i.n(t),r=i(645),o=i(721);function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function c(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function u(e){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function s(e,t){return null!=t&&"undefined"!=typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function d(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n,r,o=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=o){var a=[],i=!0,l=!1;try{for(o=o.call(e);!(i=(n=o.next()).done)&&(a.push(n.value),!t||a.length!==t);i=!0);}catch(e){l=!0,r=e}finally{try{i||null==o.return||o.return()}finally{if(l)throw r}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(p=function(){return!!e})()}function v(e){var t=e.index,r=e.list,a=e.onSwitchIndex,i=null==r?void 0:r[t];if(!i)return null;var l="string"==typeof i?i:null==i?void 0:i.url,c=l&&(l.startsWith("https://")||l.startsWith("http://"))?l:"".concat(window.location.origin,"/").concat((l||"").replace(/^\//,""));return n().createElement(o.Modal,{open:null!=t,title:(null==i?void 0:i.title)||(null==i?void 0:i.filename)||(null==i?void 0:i.name)||"File Preview (Fallback)",onCancel:function(){return a(null)},footer:n().createElement("div",{style:{display:"flex",justifyContent:"flex-end",gap:8}},n().createElement(o.Button,{onClick:function(){return window.open(c,"_blank")}},"Open Default"),n().createElement(o.Button,{onClick:function(){return a(null)}},"Close")),width:"90%",centered:!0},n().createElement("div",{style:{width:"100%",height:"70vh",background:"white",display:"flex",flexDirection:"column"}},n().createElement("iframe",{src:c,style:{width:"100%",height:"100%",border:"none",flex:1}})))}var h=new Map;function m(e){if("A"===e.tagName)return(null==(o=e.textContent)?void 0:o.trim())||"";var t=e.querySelector('[class*="-name"]');if(null==t?void 0:t.textContent)return t.textContent.trim();for(var n=e.querySelectorAll("a"),r=0;r<n.length;r++){var o,a,i,l=null==(i=n[r].textContent)?void 0:i.trim();if(l)return l}var c=e.querySelector('[class*="ellipsis-prefix"]'),u=e.querySelector('[class*="ellipsis-suffix"]');return c&&u?(c.textContent||"")+(u.textContent||""):(null==(a=e.textContent)?void 0:a.trim())||""}function y(e){return{id:e.id,uid:e.uid,url:e.url,filename:e.filename||e.name,name:e.name||e.filename,title:e.title,extname:e.extname,mimetype:e.mimetype,size:e.size}}function b(e,t,n){if(!e)return null;var r=!0,o=!1,a=void 0;try{for(var i,l=t[Symbol.iterator]();!(r=(i=l.next()).done);r=!0){var c=i.value,u=c.content||c,s=null==u?void 0:u.attachments;if(null==s?void 0:s.length){var f=!0,d=!1,p=void 0;try{for(var v,h=s[Symbol.iterator]();!(f=(v=h.next()).done);f=!0){var m=v.value,b=m.filename||m.name||"",g="".concat(m.title||"").concat(m.extname||"");if(b===e||g===e||b&&e.includes(b.replace(/\.[^/.]+$/,""))||m.title&&e.includes(m.title))return y(m)}}catch(e){d=!0,p=e}finally{try{f||null==h.return||h.return()}finally{if(d)throw p}}}}}catch(e){o=!0,a=e}finally{try{r||null==l.return||l.return()}finally{if(o)throw a}}var w=!0,x=!1,E=void 0;try{for(var k,O=(n||[])[Symbol.iterator]();!(w=(k=O.next()).done);w=!0){var S=k.value,C=S.filename||S.name||"",P="".concat(S.title||"").concat(S.extname||"");if(C===e||P===e||C&&e.includes(C.replace(/\.[^/.]+$/,""))||S.title&&e.includes(S.title))return y(S)}}catch(e){x=!0,E=e}finally{try{w||null==O.return||O.return()}finally{if(x)throw E}}return null}function g(e,t,n){if(!e)return null;var r=function(e,t){return!!e&&!!t&&e.split("?")[0].replace(location.origin,"").replace(/^\//,"")===t.split("?")[0].replace(location.origin,"").replace(/^\//,"")},o=!0,a=!1,i=void 0;try{for(var l,c=t[Symbol.iterator]();!(o=(l=c.next()).done);o=!0){var u=l.value,s=u.content||u,f=null==s?void 0:s.attachments;if(null==f?void 0:f.length){var d=!0,p=!1,v=void 0;try{for(var h,m=f[Symbol.iterator]();!(d=(h=m.next()).done);d=!0){var b=h.value;if(r(b.url,e)||r(b.preview,e))return y(b)}}catch(e){p=!0,v=e}finally{try{d||null==m.return||m.return()}finally{if(p)throw v}}}}}catch(e){a=!0,i=e}finally{try{o||null==c.return||c.return()}finally{if(a)throw i}}var g=!0,w=!1,x=void 0;try{for(var E,k=(n||[])[Symbol.iterator]();!(g=(E=k.next()).done);g=!0){var O=E.value;if(r(O.url,e)||r(O.preview,e))return y(O)}}catch(e){w=!0,x=e}finally{try{g||null==k.return||k.return()}finally{if(w)throw x}}return null}var w=function(o){var a,i=o.children,l=d((0,t.useState)(!1),2),c=l[0],u=l[1],f=d((0,t.useState)(null),2),p=f[0],y=f[1],w=d((0,t.useState)(""),2),x=(w[0],w[1]),E=(0,e.useAPIClient)(),k=r.useChatMessagesStore.use.messages(),O=r.useChatMessagesStore.use.attachments(),S=(0,t.useRef)(k),C=(0,t.useRef)(O);S.current=k,C.current=O;var P=(0,t.useRef)("");(0,t.useEffect)(function(){var e=E.axios.interceptors.request.use(function(e){var t=e.url||"";if(t.includes("aiConversations:getMessages")){var n=t.match(/sessionId=([^&]+)/);n&&(P.current=decodeURIComponent(n[1]))}if(t.includes("aiConversations:sendMessages")&&e.data)try{var r="string"==typeof e.data?JSON.parse(e.data):e.data;(null==r?void 0:r.sessionId)&&(P.current=r.sessionId)}catch(e){}return e});return function(){E.axios.interceptors.request.eject(e)}},[E]);var j=(null==(a=E.auth)?void 0:a.token)||"";(0,t.useEffect)(function(){var e=setInterval(function(){var e=function(e){return!j||e.includes("token=")?e:e+(e.includes("?")?"&":"?")+"token=".concat(j)};document.querySelectorAll('a[href*="/api/attachments"]').forEach(function(t){var n=t.getAttribute("href");n&&!n.includes("/api/filePreviewAuth:download")&&t.setAttribute("href",e("/api/filePreviewAuth:download?url=".concat(encodeURIComponent(n))))}),document.querySelectorAll("a.ai-attachment-link").forEach(function(t){var n=t.getAttribute("href");!n||n.includes("/api/filePreviewAuth:download")||n.includes("skillHub:download")||n.includes("worker-monitor")||t.setAttribute("href",e("/api/filePreviewAuth:download?url=".concat(encodeURIComponent(n))))}),document.querySelectorAll('img[src*="/api/attachments"]').forEach(function(t){var n=t.getAttribute("src");n&&!n.includes("/api/filePreviewAuth:download")&&t.setAttribute("src",e("/api/filePreviewAuth:download?url=".concat(encodeURIComponent(n))))}),document.querySelectorAll('.nb-markdown a[href*="skillHub:download"], .nb-markdown a[href*="worker-monitor"]').forEach(function(e){e.classList.contains("ai-attachment-link")||e.classList.add("ai-attachment-link")})},1e3);return function(){return clearInterval(e)}},[j]),(0,t.useEffect)(function(){var e=function(e){var t,n=e.target;n&&n.closest&&(n.closest(".ant-x-sender")||n.closest(".ant-x-attachments"))&&(null==(t=e.dataTransfer)?void 0:t.files)&&Array.from(e.dataTransfer.files).forEach(function(e){e.name&&h.set(e.name,e)})},t=function(e){var t=e.target;t&&t.closest&&(t.closest(".ant-x-sender")||t.closest(".ant-x-attachments"))&&(null==t?void 0:t.type)==="file"&&t.files&&Array.from(t.files).forEach(function(e){e.name&&h.set(e.name,e)})};return window.addEventListener("drop",e,!0),document.addEventListener("change",t,!0),function(){window.removeEventListener("drop",e,!0),document.removeEventListener("change",t,!0)}},[]),(0,t.useEffect)(function(){var e;(null==(e=C.current)?void 0:e.length)&&C.current.forEach(function(e){var t=e.originFileObj||e;if(t&&(s(t,Blob)||s(t,File)||"size"in t)){var n=e.name||e.filename||t.name;n&&h.set(n,t)}})},[O]),(0,t.useEffect)(function(){var e=setInterval(function(){var e=document.querySelectorAll(".ant-x-sender, .ant-x-attachments, .ant-x-message"),t=[];e.forEach(function(e){e.querySelectorAll('div[class*="attachment-list-card"]:not([class*="attachment-list-card-"])').forEach(function(e){return t.push(e)}),e.querySelectorAll("a").forEach(function(e){var n=e.href;n&&(n.includes("/api/attachments/")||n.includes("/api/files/download/")||n.includes("/api/worker-monitor/")||n.includes("/api/skillHub:download"))&&(t.push(e),e.classList.contains("ai-attachment-link")||(e.classList.add("ai-attachment-link"),e.classList.add("attachment-list-card")))})}),t.forEach(function(e){var t=m(e),n="";"A"===e.tagName?n=e.href:e.querySelectorAll("a").forEach(function(e){e.href&&(n=e.href)});var r=b(t,S.current,C.current)||g(n,S.current,C.current),o=(null==r?void 0:r.filename)||(null==r?void 0:r.name)||(null==r?void 0:r.title),a=o&&h.has(o)?o:t&&h.has(t)?t:null,i=n&&(n.includes("/api/attachments/")||n.includes("/api/files/download/")||n.includes("/api/worker-monitor/")||n.includes("/api/skillHub:download"));r||a||i?e.classList.add("is-cached-previewable"):e.classList.remove("is-cached-previewable")})},1e3);return function(){return clearInterval(e)}},[]),(0,t.useEffect)(function(){var e=document.createElement("style");return e.innerHTML="\n .ant-attachment-list-card {\n position: relative !important;\n cursor: pointer !important;\n }\n /* Prevent pointer events on inner text and icons so the outer div receives the absolute click */\n .ant-attachment-list-card a,\n .ant-attachment-list-card [class*=\"-icon\"],\n .ant-attachment-list-card span {\n pointer-events: none !important;\n }\n /* Re-enable pointer events for the delete button specifically */\n .ant-attachment-list-card [class*=\"-remove\"],\n .ant-attachment-list-card button,\n .ant-attachment-list-card .ant-btn {\n pointer-events: auto !important;\n }\n /* Visual \"Preview\" badge at the top-left corner using proper SVG */\n .ant-attachment-list-card.is-cached-previewable::after {\n content: '';\n background-image: url(\"data:image/svg+xml,%3Csvg viewBox='64 64 896 896' xmlns='http://www.w3.org/2000/svg' fill='rgba(0,0,0,0.65)'%3E%3Cpath d='M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z'/%3E%3C/svg%3E\");\n background-size: contain;\n background-repeat: no-repeat;\n position: absolute;\n top: 6px;\n left: 6px;\n width: 14px;\n height: 14px;\n z-index: 10;\n pointer-events: none;\n }\n /* Hide native antd thumbnail icon if we placed an eye so it doesnt look messy */\n .ant-attachment-list-card.is-cached-previewable .ant-upload-list-item-thumbnail {\n opacity: 0.2;\n }\n /* Custom aesthetics for raw AI-generated links to match cards */\n a.ai-attachment-link {\n display: inline-flex;\n align-items: center;\n padding: 8px 12px;\n margin: 4px;\n border: 1px solid #d9d9d9;\n border-radius: 8px;\n background: #fafafa;\n color: rgba(0, 0, 0, 0.88);\n text-decoration: none !important;\n position: relative;\n cursor: pointer !important;\n transition: all 0.2s;\n line-height: 1.5;\n }\n a.ai-attachment-link:hover {\n background: #f0f0f0;\n }\n a.ai-attachment-link::before {\n content: '\uD83D\uDCC4 ';\n margin-right: 8px;\n font-size: 14px;\n }\n a.ai-attachment-link.is-cached-previewable::after {\n content: '';\n background-image: url(\"data:image/svg+xml,%3Csvg viewBox='64 64 896 896' xmlns='http://www.w3.org/2000/svg' fill='rgba(0,0,0,0.65)'%3E%3Cpath d='M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z'/%3E%3C/svg%3E\");\n background-size: contain;\n background-repeat: no-repeat;\n position: absolute;\n top: -6px;\n left: -6px;\n width: 14px;\n height: 14px;\n z-index: 10;\n pointer-events: none;\n }\n ",document.head.appendChild(e),function(){e.remove()}},[]),(0,t.useEffect)(function(){var e=function(e){var t=e.target;if(!t||"function"!=typeof t.closest)return;var n="",r="",o=t.closest("a"),a=t.closest(".ant-attachment-list-card"),i=t.closest(".ant-tag");if(!(!o&&!a&&!i||t.closest('[class*="-remove"]')||t.closest(".ant-tag-close-icon")||t.closest(".ant-btn"))){a?(r=m(a),"A"===a.tagName?n=a.href:a.querySelectorAll("a").forEach(function(e){e.href&&(n=e.href)})):o?(n=o.href,r=o.textContent||"download"):i&&(r=(null==(d=i.textContent)?void 0:d.trim())||"");var l=n;if(n&&n.includes("/api/filePreviewAuth:download?url="))try{var c=new URL(n,window.location.origin);l=decodeURIComponent(c.searchParams.get("url")||n)}catch(e){}var s=b(r,S.current,C.current)||g(l,S.current,C.current),f=l&&(l.includes("/api/attachments/")||l.includes("/api/files/download/")||l.includes("/api/worker-monitor/")||l.includes("/api/skillHub:download")||l.includes("/storage/uploads/")||l.includes("amazonaws.com"));if(s||f||!o||a){if(!s&&f){var d,p,v=null==(p=l.match(/\.([a-z0-9]+)(?:[\?#]|$)/i))?void 0:p[1];s={id:l,uid:l,url:l,filename:r||"attachment",name:r||"attachment",extname:v?".".concat(v):void 0,mimetype:""}}if(s||f){e.preventDefault(),e.stopPropagation();var h,w,E=l||s.url,k=E&&!E.includes("skillHub:download")&&!E.includes("worker-monitor")&&!E.includes("filePreviewAuth:download"),O=E;if(k){O="/api/filePreviewAuth:download?url=".concat(encodeURIComponent(E));var j=s.collectionName||(f?"aiFiles":""),A=s.storage_id||s.storageId;j&&(O+="&collection=".concat(encodeURIComponent(j))),A&&(O+="&storageId=".concat(encodeURIComponent(A)))}h=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){var r;r=n[t],t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r})}return e}({},s),w=w={url:O},Object.getOwnPropertyDescriptors?Object.defineProperties(h,Object.getOwnPropertyDescriptors(w)):(function(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n.push.apply(n,r)}return n})(Object(w)).forEach(function(e){Object.defineProperty(h,e,Object.getOwnPropertyDescriptor(w,e))}),s=h,x(P.current||""),y(s),u(!0)}}}};return document.addEventListener("click",e,{capture:!0}),function(){return document.removeEventListener("click",e,{capture:!0})}},[]);var A=(0,t.useCallback)(function(){u(!1),y(null)},[]),I=(0,t.useMemo)(function(){if(!p||!c)return null;var t=e.attachmentFileTypes.getTypeByFile(p);return(null==t?void 0:t.Previewer)||v},[p,c]);return n().createElement(n().Fragment,null,i,I&&c&&p&&n().createElement(I,{index:0,list:[p],onSwitchIndex:function(e){null===e&&A()}}))},x=function(e){var t,n;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function r(e){var t,n,o;if(!(this instanceof r))throw TypeError("Cannot call a class as a function");return n=r,o=[e],n=u(n),(t=function(e,t){var n;if(t&&("object"==((n=t)&&"undefined"!=typeof Symbol&&n.constructor===Symbol?"symbol":typeof n)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,p()?Reflect.construct(n,o||[],u(this).constructor):n.apply(this,o))).state={hasError:!1},t}return r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),e&&f(r,e),n=[{key:"getDerivedStateFromError",value:function(){return{hasError:!0}}}],t=[{key:"render",value:function(){return this.state.hasError,this.props.children}}],c(r.prototype,t),n&&c(r,n),r}(n().Component),E=function(e){var t=e.children;return n().createElement(x,null,n().createElement(w,null,t))};function k(e,t,n,r,o,a,i){try{var l=e[a](i),c=l.value}catch(e){n(e);return}l.done?t(c):Promise.resolve(c).then(r,o)}function O(e,t,n){return(O=j()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&C(o,n.prototype),o}).apply(null,arguments)}function S(e){return(S=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function C(e,t){return(C=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function P(e){var t="function"==typeof Map?new Map:void 0;return(P=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return O(e,arguments,S(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),C(n,e)})(e)}function j(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(j=function(){return!!e})()}var A=function(e){var t;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function n(){var e,t;if(!(this instanceof n))throw TypeError("Cannot call a class as a function");return e=n,t=arguments,e=S(e),function(e,t){var n;if(t&&("object"==((n=t)&&"undefined"!=typeof Symbol&&n.constructor===Symbol?"symbol":typeof n)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,j()?Reflect.construct(e,t||[],S(this).constructor):e.apply(this,t))}return n.prototype=Object.create(e&&e.prototype,{constructor:{value:n,writable:!0,configurable:!0}}),e&&C(n,e),t=[{key:"load",value:function(){var e,t=this;return(e=function(){return function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:l(0),throw:l(1),return:l(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function l(a){return function(l){var c=[a,l];if(n)throw TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&c[0]?r.return:c[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,c[1])).done)return o;switch(r=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return i.label++,{value:c[1],done:!1};case 5:i.label++,r=c[1],c=[0];continue;case 7:c=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===c[0]||2===c[0])){i=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){i.label=c[1];break}if(6===c[0]&&i.label<o[1]){i.label=o[1],o=c;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(c);break}o[2]&&i.ops.pop(),i.trys.pop();continue}c=t.call(e,i)}catch(e){c=[6,e],r=0}finally{n=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}}}(this,function(e){return t.app.use(E),[2]})},function(){var t=this,n=arguments;return new Promise(function(r,o){var a=e.apply(t,n);function i(e){k(a,r,o,i,l,"next",e)}function l(e){k(a,r,o,i,l,"throw",e)}i(void 0)})})()}}],function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(n.prototype,t),n}(P(e.Plugin)),I=A}(),l}()});
|
|
10
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("@nocobase/plugin-ai/client"),require("@nocobase/client"),require("antd")):"function"==typeof define&&define.amd?define("plugin-ai-chat-file-preview",["react","@nocobase/plugin-ai/client","@nocobase/client","antd"],t):"object"==typeof exports?exports["plugin-ai-chat-file-preview"]=t(require("react"),require("@nocobase/plugin-ai/client"),require("@nocobase/client"),require("antd")):e["plugin-ai-chat-file-preview"]=t(e.react,e["@nocobase/plugin-ai/client"],e["@nocobase/client"],e.antd)}(self,function(e,t,n,r){return function(){"use strict";var o={772:function(e){e.exports=n},645:function(e){e.exports=t},721:function(e){e.exports=r},156:function(t){t.exports=e}},a={};function i(e){var t=a[e];if(void 0!==t)return t.exports;var n=a[e]={exports:{}};return o[e](n,n.exports,i),n.exports}i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,{a:t}),t},i.d=function(e,t){for(var n in t)i.o(t,n)&&!i.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var l={};return!function(){i.r(l),i.d(l,{PluginAIChatFilePreviewClient:function(){return z},default:function(){return R}});var e=i(772),t=i(156),n=i.n(t),r=i(645),o=i(721);function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function c(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function u(e){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function s(e,t){return null!=t&&"undefined"!=typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function d(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n,r,o=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=o){var a=[],i=!0,l=!1;try{for(o=o.call(e);!(i=(n=o.next()).done)&&(a.push(n.value),!t||a.length!==t);i=!0);}catch(e){l=!0,r=e}finally{try{i||null==o.return||o.return()}finally{if(l)throw r}}return a}}(e,t)||function(e,t){if(e){if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if("Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}}(e,t)||function(){throw TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(p=function(){return!!e})()}function v(e){var t=e.index,r=e.list,a=e.onSwitchIndex,i=null==r?void 0:r[t];if(!i)return null;var l="string"==typeof i?i:null==i?void 0:i.url,c=l&&(l.startsWith("https://")||l.startsWith("http://"))?l:"".concat(window.location.origin,"/").concat((l||"").replace(/^\//,""));return n().createElement(o.Modal,{open:null!=t,title:(null==i?void 0:i.title)||(null==i?void 0:i.filename)||(null==i?void 0:i.name)||"File Preview (Fallback)",onCancel:function(){return a(null)},footer:n().createElement("div",{style:{display:"flex",justifyContent:"flex-end",gap:8}},n().createElement(o.Button,{onClick:function(){return window.open(c,"_blank")}},"Open Default"),n().createElement(o.Button,{onClick:function(){return a(null)}},"Close")),width:"90%",centered:!0},n().createElement("div",{style:{width:"100%",height:"70vh",background:"white",display:"flex",flexDirection:"column"}},n().createElement("iframe",{src:c,style:{width:"100%",height:"100%",border:"none",flex:1}})))}var h=new Map,m=RegExp("[^\\s\"'<>()[\\]{}]+\\.(".concat("doc|docx|xls|xlsx|pdf|csv|txt|ppt|pptx|zip|rar|7z|png|jpg|jpeg|gif|webp|svg",")(?=$|[\\s\"'<>()[\\]{},.;:!?])"),"gi");function y(e){return e.trim().replace(/^[\s"'`(<[{]+/,"").replace(/[\s"'`)>}\].,;:!?]+$/,"")}function b(e){var t=y(e);if(!t)return"";var n=Array.from(t.matchAll(m)),r=n[n.length-1];return(null==r?void 0:r[0])?y(r[0]):t}function g(e){return!!e&&(e.includes("/api/attachments/")||e.includes("/api/files/download/")||e.includes("/api/worker-monitor/")||e.includes("/api/skillHub:download")||e.includes("/storage/uploads/")||e.includes("amazonaws.com"))}function w(e){if("A"===e.tagName)return(null==(o=e.textContent)?void 0:o.trim())||"";var t=e.querySelector('[class*="-name"]');if(null==t?void 0:t.textContent)return t.textContent.trim();for(var n=e.querySelectorAll("a"),r=0;r<n.length;r++){var o,a,i,l=null==(i=n[r].textContent)?void 0:i.trim();if(l)return l}var c=e.querySelector('[class*="ellipsis-prefix"]'),u=e.querySelector('[class*="ellipsis-suffix"]');return c&&u?(c.textContent||"")+(u.textContent||""):(null==(a=e.textContent)?void 0:a.trim())||""}function x(e){return{id:e.id,uid:e.uid,url:e.url,filename:e.filename||e.name,name:e.name||e.filename,title:e.title,extname:e.extname,mimetype:e.mimetype,size:e.size}}function E(e,t,n){if(!e)return null;var r=Array.from(new Set([e,b(e)].map(function(e){return y(e)}).filter(Boolean))),o=!0,a=!1,i=void 0;try{for(var l,c=t[Symbol.iterator]();!(o=(l=c.next()).done);o=!0){var u=l.value,s=u.content||u,f=null==s?void 0:s.attachments;if(null==f?void 0:f.length){var d=!0,p=!1,v=void 0;try{for(var h,m=f[Symbol.iterator]();!(d=(h=m.next()).done);d=!0){var g=h.value,w=g.filename||g.name||"",E="".concat(g.title||"").concat(g.extname||"");if(r.includes(w)||r.includes(E))return x(g);var S=!0,O=!1,k=void 0;try{for(var C,P=r[Symbol.iterator]();!(S=(C=P.next()).done);S=!0){var j=C.value;if(w&&j.includes(w.replace(/\.[^/.]+$/,""))||g.title&&j.includes(g.title))return x(g)}}catch(e){O=!0,k=e}finally{try{S||null==P.return||P.return()}finally{if(O)throw k}}}}catch(e){p=!0,v=e}finally{try{d||null==m.return||m.return()}finally{if(p)throw v}}}}}catch(e){a=!0,i=e}finally{try{o||null==c.return||c.return()}finally{if(a)throw i}}var A=!0,I=!1,q=void 0;try{for(var _,z=(n||[])[Symbol.iterator]();!(A=(_=z.next()).done);A=!0){var R=_.value,M=R.filename||R.name||"",L="".concat(R.title||"").concat(R.extname||"");if(r.includes(M)||r.includes(L))return x(R);var T=!0,F=!1,B=void 0;try{for(var D,U=r[Symbol.iterator]();!(T=(D=U.next()).done);T=!0){var H=D.value;if(M&&H.includes(M.replace(/\.[^/.]+$/,""))||R.title&&H.includes(R.title))return x(R)}}catch(e){F=!0,B=e}finally{try{T||null==U.return||U.return()}finally{if(F)throw B}}}}catch(e){I=!0,q=e}finally{try{A||null==z.return||z.return()}finally{if(I)throw q}}return null}function S(e,t,n){if(!e)return null;var r=function(e,t){return!!e&&!!t&&e.split("?")[0].replace(location.origin,"").replace(/^\//,"")===t.split("?")[0].replace(location.origin,"").replace(/^\//,"")},o=!0,a=!1,i=void 0;try{for(var l,c=t[Symbol.iterator]();!(o=(l=c.next()).done);o=!0){var u=l.value,s=u.content||u,f=null==s?void 0:s.attachments;if(null==f?void 0:f.length){var d=!0,p=!1,v=void 0;try{for(var h,m=f[Symbol.iterator]();!(d=(h=m.next()).done);d=!0){var y=h.value;if(r(y.url,e)||r(y.preview,e))return x(y)}}catch(e){p=!0,v=e}finally{try{d||null==m.return||m.return()}finally{if(p)throw v}}}}}catch(e){a=!0,i=e}finally{try{o||null==c.return||c.return()}finally{if(a)throw i}}var b=!0,g=!1,w=void 0;try{for(var E,S=(n||[])[Symbol.iterator]();!(b=(E=S.next()).done);b=!0){var O=E.value;if(r(O.url,e)||r(O.preview,e))return x(O)}}catch(e){g=!0,w=e}finally{try{b||null==S.return||S.return()}finally{if(g)throw w}}return null}var O=function(o){var a,i=o.children,l=d((0,t.useState)(!1),2),c=l[0],u=l[1],f=d((0,t.useState)(null),2),p=f[0],m=f[1],y=d((0,t.useState)(""),2),x=(y[0],y[1]),O=(0,e.useAPIClient)(),k=r.useChatMessagesStore.use.messages(),C=r.useChatMessagesStore.use.attachments(),P=(0,t.useRef)(k),j=(0,t.useRef)(C);P.current=k,j.current=C;var A=(0,t.useRef)("");(0,t.useEffect)(function(){var e=O.axios.interceptors.request.use(function(e){var t=e.url||"";if(t.includes("aiConversations:getMessages")){var n=t.match(/sessionId=([^&]+)/);n&&(A.current=decodeURIComponent(n[1]))}if(t.includes("aiConversations:sendMessages")&&e.data)try{var r="string"==typeof e.data?JSON.parse(e.data):e.data;(null==r?void 0:r.sessionId)&&(A.current=r.sessionId)}catch(e){}return e});return function(){O.axios.interceptors.request.eject(e)}},[O]);var I=(null==(a=O.auth)?void 0:a.token)||"";(0,t.useEffect)(function(){var e=setInterval(function(){var e=function(e){return!I||e.includes("token=")?e:e+(e.includes("?")?"&":"?")+"token=".concat(I)};document.querySelectorAll('a[href*="/api/attachments"]').forEach(function(t){var n=t.getAttribute("href");n&&!n.includes("/api/filePreviewAuth:download")&&t.setAttribute("href",e("/api/filePreviewAuth:download?url=".concat(encodeURIComponent(n))))}),document.querySelectorAll("a.ai-attachment-link").forEach(function(t){var n=t.getAttribute("href");!n||n.includes("/api/filePreviewAuth:download")||n.includes("skillHub:download")||n.includes("worker-monitor")||t.setAttribute("href",e("/api/filePreviewAuth:download?url=".concat(encodeURIComponent(n))))}),document.querySelectorAll('img[src*="/api/attachments"]').forEach(function(t){var n=t.getAttribute("src");n&&!n.includes("/api/filePreviewAuth:download")&&t.setAttribute("src",e("/api/filePreviewAuth:download?url=".concat(encodeURIComponent(n))))}),document.querySelectorAll('.nb-markdown a[href*="skillHub:download"], .nb-markdown a[href*="worker-monitor"]').forEach(function(e){e.classList.contains("ai-attachment-link")||e.classList.add("ai-attachment-link")})},1e3);return function(){return clearInterval(e)}},[I]),(0,t.useEffect)(function(){var e=function(e){var t,n=e.target;n&&n.closest&&(n.closest(".ant-x-sender")||n.closest(".ant-x-attachments"))&&(null==(t=e.dataTransfer)?void 0:t.files)&&Array.from(e.dataTransfer.files).forEach(function(e){e.name&&h.set(e.name,e)})},t=function(e){var t=e.target;t&&t.closest&&(t.closest(".ant-x-sender")||t.closest(".ant-x-attachments"))&&(null==t?void 0:t.type)==="file"&&t.files&&Array.from(t.files).forEach(function(e){e.name&&h.set(e.name,e)})};return window.addEventListener("drop",e,!0),document.addEventListener("change",t,!0),function(){window.removeEventListener("drop",e,!0),document.removeEventListener("change",t,!0)}},[]),(0,t.useEffect)(function(){var e;(null==(e=j.current)?void 0:e.length)&&j.current.forEach(function(e){var t=e.originFileObj||e;if(t&&(s(t,Blob)||s(t,File)||"size"in t)){var n=e.name||e.filename||t.name;n&&h.set(n,t)}})},[C]),(0,t.useEffect)(function(){var e=setInterval(function(){var e=document.querySelectorAll(".ant-x-sender, .ant-x-attachments, .ant-x-message"),t=[];e.forEach(function(e){e.querySelectorAll('div[class*="attachment-list-card"]:not([class*="attachment-list-card-"])').forEach(function(e){return t.push(e)}),e.querySelectorAll("a").forEach(function(e){var n=e.href;n&&(n.includes("/api/attachments/")||n.includes("/api/files/download/")||n.includes("/api/worker-monitor/")||n.includes("/api/skillHub:download"))&&(t.push(e),e.classList.contains("ai-attachment-link")||(e.classList.add("ai-attachment-link"),e.classList.add("attachment-list-card")))})}),t.forEach(function(e){var t=w(e),n="";"A"===e.tagName?n=e.href:e.querySelectorAll("a").forEach(function(e){e.href&&(n=e.href)});var r=E(t,P.current,j.current)||S(n,P.current,j.current),o=(null==r?void 0:r.filename)||(null==r?void 0:r.name)||(null==r?void 0:r.title),a=b(t),i=o&&h.has(o)?o:t&&h.has(t)?t:a&&h.has(a)?a:null,l=g(n);r||i||l?e.classList.add("is-cached-previewable"):e.classList.remove("is-cached-previewable")})},1e3);return function(){return clearInterval(e)}},[]),(0,t.useEffect)(function(){var e=document.createElement("style");return e.innerHTML="\n .ant-attachment-list-card {\n position: relative !important;\n cursor: pointer !important;\n }\n /* Prevent pointer events on inner text and icons so the outer div receives the absolute click */\n .ant-attachment-list-card a,\n .ant-attachment-list-card [class*=\"-icon\"],\n .ant-attachment-list-card span {\n pointer-events: none !important;\n }\n /* Re-enable pointer events for the delete button specifically */\n .ant-attachment-list-card [class*=\"-remove\"],\n .ant-attachment-list-card button,\n .ant-attachment-list-card .ant-btn {\n pointer-events: auto !important;\n }\n /* Visual \"Preview\" badge at the top-left corner using proper SVG */\n .ant-attachment-list-card.is-cached-previewable::after {\n content: '';\n background-image: url(\"data:image/svg+xml,%3Csvg viewBox='64 64 896 896' xmlns='http://www.w3.org/2000/svg' fill='rgba(0,0,0,0.65)'%3E%3Cpath d='M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z'/%3E%3C/svg%3E\");\n background-size: contain;\n background-repeat: no-repeat;\n position: absolute;\n top: 6px;\n left: 6px;\n width: 14px;\n height: 14px;\n z-index: 10;\n pointer-events: none;\n }\n /* Hide native antd thumbnail icon if we placed an eye so it doesnt look messy */\n .ant-attachment-list-card.is-cached-previewable .ant-upload-list-item-thumbnail {\n opacity: 0.2;\n }\n /* Custom aesthetics for raw AI-generated links to match cards */\n a.ai-attachment-link {\n display: inline-flex;\n align-items: center;\n padding: 8px 12px;\n margin: 4px;\n border: 1px solid #d9d9d9;\n border-radius: 8px;\n background: #fafafa;\n color: rgba(0, 0, 0, 0.88);\n text-decoration: none !important;\n position: relative;\n cursor: pointer !important;\n transition: all 0.2s;\n line-height: 1.5;\n }\n a.ai-attachment-link:hover {\n background: #f0f0f0;\n }\n a.ai-attachment-link::before {\n content: '\uD83D\uDCC4 ';\n margin-right: 8px;\n font-size: 14px;\n }\n a.ai-attachment-link.is-cached-previewable::after {\n content: '';\n background-image: url(\"data:image/svg+xml,%3Csvg viewBox='64 64 896 896' xmlns='http://www.w3.org/2000/svg' fill='rgba(0,0,0,0.65)'%3E%3Cpath d='M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z'/%3E%3C/svg%3E\");\n background-size: contain;\n background-repeat: no-repeat;\n position: absolute;\n top: -6px;\n left: -6px;\n width: 14px;\n height: 14px;\n z-index: 10;\n pointer-events: none;\n }\n ",document.head.appendChild(e),function(){e.remove()}},[]),(0,t.useEffect)(function(){var e=function(e){var t=e.target;if(!t||"function"!=typeof t.closest)return;var n="",r="",o=t.closest("a"),a=t.closest(".ant-attachment-list-card"),i=t.closest(".ant-tag");if(!(!o&&!a&&!i||t.closest('[class*="-remove"]')||t.closest(".ant-tag-close-icon")||t.closest(".ant-btn"))){a?(r=w(a),"A"===a.tagName?n=a.href:a.querySelectorAll("a").forEach(function(e){e.href&&(n=e.href)})):o?(n=o.href,r=o.textContent||"download"):i&&(r=(null==(p=i.textContent)?void 0:p.trim())||"");var l=n;if(n&&n.includes("/api/filePreviewAuth:download?url="))try{var c=new URL(n,window.location.origin);l=decodeURIComponent(c.searchParams.get("url")||n)}catch(e){}var s=E(r,P.current,j.current)||S(l,P.current,j.current),f=b(r),d=g(l);if(s||d||!o||a){if(!s&&d){var p,v,h,y=(null==(v=f.match(/\.([a-z0-9]+)$/i))?void 0:v[1])||(null==(h=l.match(/\.([a-z0-9]+)(?:[\?#]|$)/i))?void 0:h[1]);s={id:l,uid:l,url:l,filename:f||"attachment",name:f||"attachment",extname:y?".".concat(y):void 0,mimetype:""}}if(s||d){e.preventDefault(),e.stopPropagation();var O,k,C=s.url||l,I=C&&!C.includes("skillHub:download")&&!C.includes("worker-monitor")&&!C.includes("filePreviewAuth:download"),q=C;if(I){q="/api/filePreviewAuth:download?url=".concat(encodeURIComponent(C));var _=s.collectionName||(d?"aiFiles":""),z=s.storage_id||s.storageId;_&&(q+="&collection=".concat(encodeURIComponent(_))),z&&(q+="&storageId=".concat(encodeURIComponent(z)))}O=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){var r;r=n[t],t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r})}return e}({},s),k=k={url:q},Object.getOwnPropertyDescriptors?Object.defineProperties(O,Object.getOwnPropertyDescriptors(k)):(function(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n.push.apply(n,r)}return n})(Object(k)).forEach(function(e){Object.defineProperty(O,e,Object.getOwnPropertyDescriptor(k,e))}),s=O,x(A.current||""),m(s),u(!0)}}}};return document.addEventListener("click",e,{capture:!0}),function(){return document.removeEventListener("click",e,{capture:!0})}},[]);var q=(0,t.useCallback)(function(){u(!1),m(null)},[]),_=(0,t.useMemo)(function(){if(!p||!c)return null;var t=e.attachmentFileTypes.getTypeByFile(p);return(null==t?void 0:t.Previewer)||v},[p,c]);return n().createElement(n().Fragment,null,i,_&&c&&p&&n().createElement(_,{index:0,list:[p],onSwitchIndex:function(e){null===e&&q()}}))},k=function(e){var t,n;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function r(e){var t,n,o;if(!(this instanceof r))throw TypeError("Cannot call a class as a function");return n=r,o=[e],n=u(n),(t=function(e,t){var n;if(t&&("object"==((n=t)&&"undefined"!=typeof Symbol&&n.constructor===Symbol?"symbol":typeof n)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,p()?Reflect.construct(n,o||[],u(this).constructor):n.apply(this,o))).state={hasError:!1},t}return r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),e&&f(r,e),n=[{key:"getDerivedStateFromError",value:function(){return{hasError:!0}}}],t=[{key:"render",value:function(){return this.state.hasError,this.props.children}}],c(r.prototype,t),n&&c(r,n),r}(n().Component),C=function(e){var t=e.children;return n().createElement(k,null,n().createElement(O,null,t))};function P(e,t,n,r,o,a,i){try{var l=e[a](i),c=l.value}catch(e){n(e);return}l.done?t(c):Promise.resolve(c).then(r,o)}function j(e,t,n){return(j=_()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&I(o,n.prototype),o}).apply(null,arguments)}function A(e){return(A=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function I(e,t){return(I=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function q(e){var t="function"==typeof Map?new Map:void 0;return(q=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,n)}function n(){return j(e,arguments,A(this).constructor)}return n.prototype=Object.create(e.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),I(n,e)})(e)}function _(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(e){}return(_=function(){return!!e})()}var z=function(e){var t;if("function"!=typeof e&&null!==e)throw TypeError("Super expression must either be null or a function");function n(){var e,t;if(!(this instanceof n))throw TypeError("Cannot call a class as a function");return e=n,t=arguments,e=A(e),function(e,t){var n;if(t&&("object"==((n=t)&&"undefined"!=typeof Symbol&&n.constructor===Symbol?"symbol":typeof n)||"function"==typeof t))return t;if(void 0===e)throw ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(this,_()?Reflect.construct(e,t||[],A(this).constructor):e.apply(this,t))}return n.prototype=Object.create(e&&e.prototype,{constructor:{value:n,writable:!0,configurable:!0}}),e&&I(n,e),t=[{key:"load",value:function(){var e,t=this;return(e=function(){return function(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:l(0),throw:l(1),return:l(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function l(a){return function(l){var c=[a,l];if(n)throw TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&c[0]?r.return:c[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,c[1])).done)return o;switch(r=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return i.label++,{value:c[1],done:!1};case 5:i.label++,r=c[1],c=[0];continue;case 7:c=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===c[0]||2===c[0])){i=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){i.label=c[1];break}if(6===c[0]&&i.label<o[1]){i.label=o[1],o=c;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(c);break}o[2]&&i.ops.pop(),i.trys.pop();continue}c=t.call(e,i)}catch(e){c=[6,e],r=0}finally{n=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}}}(this,function(e){return t.app.use(C),[2]})},function(){var t=this,n=arguments;return new Promise(function(r,o){var a=e.apply(t,n);function i(e){P(a,r,o,i,l,"next",e)}function l(e){P(a,r,o,i,l,"throw",e)}i(void 0)})})()}}],function(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}(n.prototype,t),n}(q(e.Plugin)),R=z}(),l}()});
|
package/dist/externalVersion.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
|
11
11
|
"react": "18.2.0",
|
|
12
|
-
"@nocobase/client": "2.0.
|
|
13
|
-
"@nocobase/plugin-ai": "2.0.
|
|
12
|
+
"@nocobase/client": "2.0.47",
|
|
13
|
+
"@nocobase/plugin-ai": "2.0.47",
|
|
14
14
|
"antd": "5.24.2",
|
|
15
|
-
"@nocobase/server": "2.0.
|
|
15
|
+
"@nocobase/server": "2.0.47"
|
|
16
16
|
};
|
package/package.json
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "plugin-ai-chat-file-preview",
|
|
3
|
-
"displayName": "AI Chat File Preview",
|
|
4
|
-
"displayName.vi-VN": "Xem trước file trong Chat AI",
|
|
5
|
-
"displayName.zh-CN": "AI聊天文件预览",
|
|
6
|
-
"description": "NocoBase AI Assistant 预览附件(Word, Excel, PDF, CSV...)支持 S3 auth",
|
|
7
|
-
"description.vi-VN": "Preview file attachment tren AI Chat (Word, Excel, PDF, CSV...) kem S3 auth",
|
|
8
|
-
"description.zh-CN": "在AI员工聊天中直接预览上传的文件附件,支持浏览器缓存。",
|
|
9
|
-
"version": "1.1.
|
|
10
|
-
"main": "dist/server/index.js",
|
|
11
|
-
"dependencies": {},
|
|
12
|
-
"peerDependencies": {
|
|
13
|
-
"@nocobase/client": "2.x",
|
|
14
|
-
"@nocobase/server": "2.x",
|
|
15
|
-
"@nocobase/database": "2.x",
|
|
16
|
-
"@nocobase/plugin-ai": "2.x",
|
|
17
|
-
"@nocobase/plugin-file-manager": "2.x"
|
|
18
|
-
},
|
|
19
|
-
"nocobase": {
|
|
20
|
-
"supportedVersions": [
|
|
21
|
-
"2.x"
|
|
22
|
-
]
|
|
23
|
-
},
|
|
24
|
-
"devDependencies": {},
|
|
25
|
-
"keywords": [
|
|
26
|
-
"AI",
|
|
27
|
-
"Chat",
|
|
28
|
-
"File preview",
|
|
29
|
-
"Cache"
|
|
30
|
-
],
|
|
31
|
-
"license": "Apache-2.0"
|
|
32
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "plugin-ai-chat-file-preview",
|
|
3
|
+
"displayName": "AI Chat File Preview",
|
|
4
|
+
"displayName.vi-VN": "Xem trước file trong Chat AI",
|
|
5
|
+
"displayName.zh-CN": "AI聊天文件预览",
|
|
6
|
+
"description": "NocoBase AI Assistant 预览附件(Word, Excel, PDF, CSV...)支持 S3 auth",
|
|
7
|
+
"description.vi-VN": "Preview file attachment tren AI Chat (Word, Excel, PDF, CSV...) kem S3 auth",
|
|
8
|
+
"description.zh-CN": "在AI员工聊天中直接预览上传的文件附件,支持浏览器缓存。",
|
|
9
|
+
"version": "1.1.2",
|
|
10
|
+
"main": "dist/server/index.js",
|
|
11
|
+
"dependencies": {},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@nocobase/client": "2.x",
|
|
14
|
+
"@nocobase/server": "2.x",
|
|
15
|
+
"@nocobase/database": "2.x",
|
|
16
|
+
"@nocobase/plugin-ai": "2.x",
|
|
17
|
+
"@nocobase/plugin-file-manager": "2.x"
|
|
18
|
+
},
|
|
19
|
+
"nocobase": {
|
|
20
|
+
"supportedVersions": [
|
|
21
|
+
"2.x"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"AI",
|
|
27
|
+
"Chat",
|
|
28
|
+
"File preview",
|
|
29
|
+
"Cache"
|
|
30
|
+
],
|
|
31
|
+
"license": "Apache-2.0"
|
|
32
|
+
}
|
|
@@ -73,12 +73,77 @@ function FallbackModalPreviewer({ index, list, onSwitchIndex }: any) {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
// Define a reliable, context-isolated module-level RAM cache independent of the window object
|
|
76
|
-
export const AppRamCache = new Map<string, File | Blob>();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
export const AppRamCache = new Map<string, File | Blob>();
|
|
77
|
+
|
|
78
|
+
const FILE_EXTENSIONS = [
|
|
79
|
+
'doc',
|
|
80
|
+
'docx',
|
|
81
|
+
'xls',
|
|
82
|
+
'xlsx',
|
|
83
|
+
'pdf',
|
|
84
|
+
'csv',
|
|
85
|
+
'txt',
|
|
86
|
+
'ppt',
|
|
87
|
+
'pptx',
|
|
88
|
+
'zip',
|
|
89
|
+
'rar',
|
|
90
|
+
'7z',
|
|
91
|
+
'png',
|
|
92
|
+
'jpg',
|
|
93
|
+
'jpeg',
|
|
94
|
+
'gif',
|
|
95
|
+
'webp',
|
|
96
|
+
'svg',
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
const FILENAME_IN_TEXT_RE = new RegExp(
|
|
100
|
+
`[^\\s"'<>()[\\]{}]+\\.(${FILE_EXTENSIONS.join('|')})(?=$|[\\s"'<>()[\\]{},.;:!?])`,
|
|
101
|
+
'gi',
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
function stripFilenameNoise(value: string): string {
|
|
105
|
+
return value
|
|
106
|
+
.trim()
|
|
107
|
+
.replace(/^[\s"'`(<[{]+/, '')
|
|
108
|
+
.replace(/[\s"'`)>}\].,;:!?]+$/, '');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function extractFilenameFromText(value: string): string {
|
|
112
|
+
const text = stripFilenameNoise(value);
|
|
113
|
+
if (!text) return '';
|
|
114
|
+
|
|
115
|
+
const matches = Array.from(text.matchAll(FILENAME_IN_TEXT_RE));
|
|
116
|
+
const lastMatch = matches[matches.length - 1];
|
|
117
|
+
if (lastMatch?.[0]) {
|
|
118
|
+
return stripFilenameNoise(lastMatch[0]);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return text;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getDisplayNameCandidates(displayName: string): string[] {
|
|
125
|
+
const candidates = [displayName, extractFilenameFromText(displayName)]
|
|
126
|
+
.map((value) => stripFilenameNoise(value))
|
|
127
|
+
.filter(Boolean);
|
|
128
|
+
|
|
129
|
+
return Array.from(new Set(candidates));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function isKnownFileUrl(url?: string): boolean {
|
|
133
|
+
return !!url && (
|
|
134
|
+
url.includes('/api/attachments/') ||
|
|
135
|
+
url.includes('/api/files/download/') ||
|
|
136
|
+
url.includes('/api/worker-monitor/') ||
|
|
137
|
+
url.includes('/api/skillHub:download') ||
|
|
138
|
+
url.includes('/storage/uploads/') ||
|
|
139
|
+
url.includes('amazonaws.com')
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Extract displayed filename from a FileListCard DOM element.
|
|
145
|
+
*/
|
|
146
|
+
function getDisplayNameFromCard(cardEl: HTMLElement): string {
|
|
82
147
|
if (cardEl.tagName === 'A') return cardEl.textContent?.trim() || '';
|
|
83
148
|
|
|
84
149
|
// 1. Try antd generic filename classes
|
|
@@ -120,49 +185,54 @@ function attToPreviewFile(att: any): PreviewFile {
|
|
|
120
185
|
/**
|
|
121
186
|
* Find file metadata matching the displayed filename across all message attachments.
|
|
122
187
|
*/
|
|
123
|
-
function findFileByDisplayName(displayName: string, messages: any[], pendingAttachments: any[]): PreviewFile | null {
|
|
124
|
-
if (!displayName) return null;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
188
|
+
function findFileByDisplayName(displayName: string, messages: any[], pendingAttachments: any[]): PreviewFile | null {
|
|
189
|
+
if (!displayName) return null;
|
|
190
|
+
const displayNames = getDisplayNameCandidates(displayName);
|
|
191
|
+
|
|
192
|
+
// Search sent messages
|
|
193
|
+
for (const msg of messages) {
|
|
128
194
|
const content = msg.content || msg;
|
|
129
195
|
const attachments = content?.attachments;
|
|
130
196
|
if (!attachments?.length) continue;
|
|
131
197
|
|
|
132
|
-
for (const att of attachments) {
|
|
133
|
-
const attName = att.filename || att.name || '';
|
|
134
|
-
const attTitleExt = `${att.title || ''}${att.extname || ''}`;
|
|
135
|
-
if (attName
|
|
136
|
-
return attToPreviewFile(att);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Relaxed match for NocoBase hashed file names
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
198
|
+
for (const att of attachments) {
|
|
199
|
+
const attName = att.filename || att.name || '';
|
|
200
|
+
const attTitleExt = `${att.title || ''}${att.extname || ''}`;
|
|
201
|
+
if (displayNames.includes(attName) || displayNames.includes(attTitleExt)) {
|
|
202
|
+
return attToPreviewFile(att);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Relaxed match for NocoBase hashed file names
|
|
206
|
+
for (const name of displayNames) {
|
|
207
|
+
if (
|
|
208
|
+
(attName && name.includes(attName.replace(/\.[^/.]+$/, ''))) ||
|
|
209
|
+
(att.title && name.includes(att.title))
|
|
210
|
+
) {
|
|
211
|
+
return attToPreviewFile(att);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
148
216
|
|
|
149
217
|
// Search pending (not yet sent) attachments
|
|
150
218
|
for (const att of pendingAttachments || []) {
|
|
151
|
-
const attName = att.filename || att.name || '';
|
|
152
|
-
const attTitleExt = `${att.title || ''}${att.extname || ''}`;
|
|
153
|
-
if (attName
|
|
154
|
-
return attToPreviewFile(att);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Relaxed match for NocoBase hashed file names (e.g. report.docx-c2ywti.docx)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
219
|
+
const attName = att.filename || att.name || '';
|
|
220
|
+
const attTitleExt = `${att.title || ''}${att.extname || ''}`;
|
|
221
|
+
if (displayNames.includes(attName) || displayNames.includes(attTitleExt)) {
|
|
222
|
+
return attToPreviewFile(att);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Relaxed match for NocoBase hashed file names (e.g. report.docx-c2ywti.docx)
|
|
226
|
+
for (const name of displayNames) {
|
|
227
|
+
if (
|
|
228
|
+
(attName && name.includes(attName.replace(/\.[^/.]+$/, ''))) ||
|
|
229
|
+
(att.title && name.includes(att.title))
|
|
230
|
+
) {
|
|
231
|
+
return attToPreviewFile(att);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
166
236
|
return null;
|
|
167
237
|
}
|
|
168
238
|
|
|
@@ -389,13 +459,15 @@ const ChatFilePreviewInner: React.FC<{ children: React.ReactNode }> = ({ childre
|
|
|
389
459
|
// Resolve real file name from data store
|
|
390
460
|
const file = findFileByDisplayName(displayName, messagesRef.current, pendingAttachmentsRef.current) ||
|
|
391
461
|
findFileByUrl(fallbackUrl, messagesRef.current, pendingAttachmentsRef.current);
|
|
392
|
-
const realName = file?.filename || file?.name || file?.title;
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
462
|
+
const realName = file?.filename || file?.name || file?.title;
|
|
463
|
+
const normalizedDisplayName = extractFilenameFromText(displayName);
|
|
464
|
+
|
|
465
|
+
// Strict RAM cache check
|
|
466
|
+
const cacheHitName = realName && AppRamCache.has(realName) ? realName
|
|
467
|
+
: (displayName && AppRamCache.has(displayName) ? displayName
|
|
468
|
+
: (normalizedDisplayName && AppRamCache.has(normalizedDisplayName) ? normalizedDisplayName : null));
|
|
469
|
+
|
|
470
|
+
const isAIGenerated = isKnownFileUrl(fallbackUrl);
|
|
399
471
|
|
|
400
472
|
if (file || cacheHitName || isAIGenerated) {
|
|
401
473
|
el.classList.add('is-cached-previewable');
|
|
@@ -539,31 +611,27 @@ const ChatFilePreviewInner: React.FC<{ children: React.ReactNode }> = ({ childre
|
|
|
539
611
|
let file = findFileByDisplayName(displayName, messagesRef.current, pendingAttachmentsRef.current) ||
|
|
540
612
|
findFileByUrl(originalFallbackUrl, messagesRef.current, pendingAttachmentsRef.current);
|
|
541
613
|
|
|
542
|
-
const
|
|
543
|
-
|
|
544
|
-
originalFallbackUrl.includes('/api/files/download/') ||
|
|
545
|
-
originalFallbackUrl.includes('/api/worker-monitor/') ||
|
|
546
|
-
originalFallbackUrl.includes('/api/skillHub:download') ||
|
|
547
|
-
originalFallbackUrl.includes('/storage/uploads/') ||
|
|
548
|
-
originalFallbackUrl.includes('amazonaws.com') // Ensure only explicitly known S3 formats are caught if not in messagesRef
|
|
549
|
-
);
|
|
614
|
+
const normalizedDisplayName = extractFilenameFromText(displayName);
|
|
615
|
+
const isAIGenerated = isKnownFileUrl(originalFallbackUrl);
|
|
550
616
|
|
|
551
617
|
// If we clicked a completely unrelated anchor tag in the admin panel and it's not a known file, abort immediately
|
|
552
618
|
if (!file && !isAIGenerated && anchorNode && !cardEl) {
|
|
553
619
|
return;
|
|
554
620
|
}
|
|
555
621
|
|
|
556
|
-
if (!file && isAIGenerated) {
|
|
557
|
-
const extname =
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
622
|
+
if (!file && isAIGenerated) {
|
|
623
|
+
const extname =
|
|
624
|
+
normalizedDisplayName.match(/\.([a-z0-9]+)$/i)?.[1] ||
|
|
625
|
+
originalFallbackUrl.match(/\.([a-z0-9]+)(?:[\?#]|$)/i)?.[1];
|
|
626
|
+
file = {
|
|
627
|
+
id: originalFallbackUrl,
|
|
628
|
+
uid: originalFallbackUrl,
|
|
629
|
+
url: originalFallbackUrl,
|
|
630
|
+
filename: normalizedDisplayName || 'attachment',
|
|
631
|
+
name: normalizedDisplayName || 'attachment',
|
|
632
|
+
extname: extname ? `.${extname}` : undefined,
|
|
633
|
+
mimetype: '',
|
|
634
|
+
} as PreviewFile;
|
|
567
635
|
}
|
|
568
636
|
|
|
569
637
|
if (!file && !isAIGenerated) return;
|
|
@@ -572,7 +640,7 @@ const ChatFilePreviewInner: React.FC<{ children: React.ReactNode }> = ({ childre
|
|
|
572
640
|
e.stopPropagation();
|
|
573
641
|
|
|
574
642
|
// Convert to secure proxy URL for everything EXCEPT natively secured endpoints that don't belong to the attachments table
|
|
575
|
-
const proxyTargetUrl =
|
|
643
|
+
const proxyTargetUrl = file.url || originalFallbackUrl;
|
|
576
644
|
const shouldUseProxy = proxyTargetUrl && !proxyTargetUrl.includes('skillHub:download') && !proxyTargetUrl.includes('worker-monitor') && !proxyTargetUrl.includes('filePreviewAuth:download');
|
|
577
645
|
|
|
578
646
|
let secureUrl = proxyTargetUrl;
|