plugin-ai-chat-file-preview 1.0.16 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -44
- package/dist/client/index.js +1 -1
- package/dist/externalVersion.js +3 -3
- package/package.json +1 -1
- package/src/client/ChatFilePreviewProvider.tsx +40 -7
package/README.md
CHANGED
|
@@ -1,44 +1,15 @@
|
|
|
1
|
-
# plugin-ai-chat-file-preview
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- **Graceful Fallback**: Automatically provides a secure download link containing the proper Bearer Token for un-previewable formats.
|
|
17
|
-
|
|
18
|
-
## Installation
|
|
19
|
-
|
|
20
|
-
You can install this plugin in your NocoBase project via the Plugin Manager:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
yarn pm add plugin-ai-chat-file-preview
|
|
24
|
-
yarn pm enable plugin-ai-chat-file-preview
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
*(If utilizing the `.tgz` package directly offline, place it in the application or upload it via UI)*
|
|
28
|
-
|
|
29
|
-
## Technical Details
|
|
30
|
-
|
|
31
|
-
- **No Core Modifications**: This plugin relies on catching global DOM click events targeted at `.ant-attachments-file-card` components rendered by `@ant-design/x`, avoiding any necessity to modify the core `@nocobase/plugin-ai`.
|
|
32
|
-
- **Session Continuity**: Hooks into the Axios instance to track NocoBase's `sessionId`, ensuring that files are grouped naturally and their Blob caches are completely cleared when a conversation is destroyed.
|
|
33
|
-
|
|
34
|
-
## Usage
|
|
35
|
-
|
|
36
|
-
Simply enable the plugin. Once activated:
|
|
37
|
-
1. Open the **AI Chat** panel on any page.
|
|
38
|
-
2. Drag and drop, or select a file to upload.
|
|
39
|
-
3. Once the file appears as a chip in the chat, click it!
|
|
40
|
-
4. The file will pop up in a gorgeous, centered overlay window.
|
|
41
|
-
|
|
42
|
-
## License
|
|
43
|
-
|
|
44
|
-
Apache-2.0
|
|
1
|
+
# plugin-ai-chat-file-preview
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
NocoBase AI Assistant file preview plugin supporting Word, Excel, PDF, CSV, and S3 authentication.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
- **Multi-format Support**: Natively preview `.docx`, `.xlsx`, `.pdf`, and `.csv` files directly in the browser.
|
|
8
|
+
- **Secure Access**: Integrates with S3 authentication for securely loading private files.
|
|
9
|
+
- **AI Chat Integration**: Allows users to preview attachments uploaded during AI conversations without downloading them.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
1. Ensure the plugin is activated in the NocoBase Plugin Manager.
|
|
13
|
+
2. In the AI Chat interface, upload a supported document.
|
|
14
|
+
3. Click on the document thumbnail or link within the chat.
|
|
15
|
+
4. A modal or inline viewer will render the document content securely.
|
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 q}});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 O,S=(n||[])[Symbol.iterator]();!(w=(O=S.next()).done);w=!0){var k=O.value,C=k.filename||k.name||"",P="".concat(k.title||"").concat(k.extname||"");if(C===e||P===e||C&&e.includes(C.replace(/\.[^/.]+$/,""))||k.title&&e.includes(k.title))return y(k)}}catch(e){x=!0,E=e}finally{try{w||null==S.return||S.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,O=(n||[])[Symbol.iterator]();!(g=(E=O.next()).done);g=!0){var S=E.value;if(r(S.url,e)||r(S.preview,e))return y(S)}}catch(e){w=!0,x=e}finally{try{g||null==O.return||O.return()}finally{if(w)throw x}}return null}var w=function(o){var a=o.children,i=d((0,t.useState)(!1),2),l=i[0],c=i[1],u=d((0,t.useState)(null),2),f=u[0],p=u[1],y=d((0,t.useState)(""),2),w=(y[0],y[1]),x=(0,e.useAPIClient)(),E=r.useChatMessagesStore.use.messages(),O=r.useChatMessagesStore.use.attachments(),S=(0,t.useRef)(E),k=(0,t.useRef)(O);S.current=E,k.current=O;var C=(0,t.useRef)("");(0,t.useEffect)(function(){var e=x.axios.interceptors.request.use(function(e){var t=e.url||"";if(t.includes("aiConversations:getMessages")){var n=t.match(/sessionId=([^&]+)/);n&&(C.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)&&(C.current=r.sessionId)}catch(e){}return e});return function(){x.axios.interceptors.request.eject(e)}},[x]),(0,t.useEffect)(function(){var e=setInterval(function(){document.querySelectorAll(".ant-attachment-list-card-name").forEach(function(e){var t=e.getAttribute("href");t&&!t.includes("/api/filePreviewAuth:download")&&e.setAttribute("href","/api/filePreviewAuth:download?url=".concat(encodeURIComponent(t)))}),document.querySelectorAll("a.ai-attachment-link").forEach(function(e){var t=e.getAttribute("href");!t||t.includes("/api/filePreviewAuth:download")||t.includes("skillHub:download")||t.includes("worker-monitor")||e.setAttribute("href","/api/filePreviewAuth:download?url=".concat(encodeURIComponent(t)))}),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)}},[]),(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=k.current)?void 0:e.length)&&k.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,k.current)||g(n,S.current,k.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 u=new URL(n,window.location.origin);l=decodeURIComponent(u.searchParams.get("url")||n)}catch(e){}var s=b(r,S.current,k.current)||g(l,S.current,k.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,v,h=null==(v=l.match(/\.([a-z0-9]+)(?:[\?#]|$)/i))?void 0:v[1];s={id:l,uid:l,url:l,filename:r||"attachment",name:r||"attachment",extname:h?".".concat(h):void 0,mimetype:""}}if(s||f){e.preventDefault(),e.stopPropagation();var y,x,E=!l||l.includes("skillHub:download")||l.includes("worker-monitor")?l||s.url:"/api/filePreviewAuth:download?url=".concat(encodeURIComponent(l));y=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),x=x={url:E},Object.getOwnPropertyDescriptors?Object.defineProperties(y,Object.getOwnPropertyDescriptors(x)):(function(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n.push.apply(n,r)}return n})(Object(x)).forEach(function(e){Object.defineProperty(y,e,Object.getOwnPropertyDescriptor(x,e))}),s=y,w(C.current||""),p(s),c(!0)}}}};return document.addEventListener("click",e,{capture:!0}),function(){return document.removeEventListener("click",e,{capture:!0})}},[]);var P=(0,t.useCallback)(function(){c(!1),p(null)},[]),j=(0,t.useMemo)(function(){if(!f||!l)return null;var t=e.attachmentFileTypes.getTypeByFile(f);return(null==t?void 0:t.Previewer)||v},[f,l]);return n().createElement(n().Fragment,null,a,j&&l&&f&&n().createElement(j,{index:0,list:[f],onSwitchIndex:function(e){null===e&&P()}}))},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 O(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 S(e,t,n){return(S=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 k(e){return(k=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 S(e,arguments,k(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=k(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||[],k(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){O(a,r,o,i,l,"next",e)}function l(e){O(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)),q=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 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}()});
|
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.46",
|
|
13
|
+
"@nocobase/plugin-ai": "2.0.46",
|
|
14
14
|
"antd": "5.24.2",
|
|
15
|
-
"@nocobase/server": "2.0.
|
|
15
|
+
"@nocobase/server": "2.0.46"
|
|
16
16
|
};
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"description": "NocoBase AI Assistant 预览附件(Word, Excel, PDF, CSV...)支持 S3 auth",
|
|
7
7
|
"description.vi-VN": "Preview file attachment tren AI Chat (Word, Excel, PDF, CSV...) kem S3 auth",
|
|
8
8
|
"description.zh-CN": "在AI员工聊天中直接预览上传的文件附件,支持浏览器缓存。",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.1.1",
|
|
10
10
|
"main": "dist/server/index.js",
|
|
11
11
|
"dependencies": {},
|
|
12
12
|
"peerDependencies": {
|
|
@@ -246,26 +246,44 @@ const ChatFilePreviewInner: React.FC<{ children: React.ReactNode }> = ({ childre
|
|
|
246
246
|
};
|
|
247
247
|
}, [apiClient]);
|
|
248
248
|
|
|
249
|
+
const token = apiClient.auth?.token || '';
|
|
250
|
+
|
|
249
251
|
// Track global drop and input change events to intercept file object selection ONLY for AI chat
|
|
250
252
|
useEffect(() => {
|
|
251
|
-
// Modify href attributes of native NocoBase file links in chat to use the proxy
|
|
253
|
+
// Modify href attributes of native NocoBase file links and images in chat to use the proxy and append the token
|
|
252
254
|
const rewriteObtrusiveLinks = () => {
|
|
253
|
-
const
|
|
255
|
+
const appendToken = (url: string) => {
|
|
256
|
+
if (!token) return url;
|
|
257
|
+
if (url.includes('token=')) return url;
|
|
258
|
+
return url + (url.includes('?') ? '&' : '?') + `token=${token}`;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const links = document.querySelectorAll<HTMLAnchorElement>('a[href*="/api/attachments"]');
|
|
254
262
|
links.forEach(link => {
|
|
255
263
|
const href = link.getAttribute('href');
|
|
256
264
|
if (href && !href.includes('/api/filePreviewAuth:download')) {
|
|
257
|
-
link.setAttribute('href', `/api/filePreviewAuth:download?url=${encodeURIComponent(href)}`);
|
|
265
|
+
link.setAttribute('href', appendToken(`/api/filePreviewAuth:download?url=${encodeURIComponent(href)}`));
|
|
258
266
|
}
|
|
259
267
|
});
|
|
268
|
+
|
|
260
269
|
// Also rewrite ai-attachment-link anchors
|
|
261
270
|
const aiLinks = document.querySelectorAll<HTMLAnchorElement>('a.ai-attachment-link');
|
|
262
271
|
aiLinks.forEach(link => {
|
|
263
272
|
const href = link.getAttribute('href');
|
|
264
273
|
if (href && !href.includes('/api/filePreviewAuth:download') && !href.includes('skillHub:download') && !href.includes('worker-monitor')) {
|
|
265
|
-
link.setAttribute('href', `/api/filePreviewAuth:download?url=${encodeURIComponent(href)}`);
|
|
274
|
+
link.setAttribute('href', appendToken(`/api/filePreviewAuth:download?url=${encodeURIComponent(href)}`));
|
|
266
275
|
}
|
|
267
276
|
});
|
|
268
277
|
|
|
278
|
+
// Also rewrite image tags so thumbnails don't 404
|
|
279
|
+
const imgs = document.querySelectorAll<HTMLImageElement>('img[src*="/api/attachments"]');
|
|
280
|
+
imgs.forEach(img => {
|
|
281
|
+
const src = img.getAttribute('src');
|
|
282
|
+
if (src && !src.includes('/api/filePreviewAuth:download')) {
|
|
283
|
+
img.setAttribute('src', appendToken(`/api/filePreviewAuth:download?url=${encodeURIComponent(src)}`));
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
|
|
269
287
|
// Auto-style raw markdown links for Skill Hub and Worker Monitor as interactive file attachments
|
|
270
288
|
const rawFileLinks = document.querySelectorAll<HTMLAnchorElement>('.nb-markdown a[href*="skillHub:download"], .nb-markdown a[href*="worker-monitor"]');
|
|
271
289
|
rawFileLinks.forEach(link => {
|
|
@@ -278,7 +296,7 @@ const ChatFilePreviewInner: React.FC<{ children: React.ReactNode }> = ({ childre
|
|
|
278
296
|
// Run periodically to catch newly rendered chat messages
|
|
279
297
|
const timer = setInterval(rewriteObtrusiveLinks, 1000);
|
|
280
298
|
return () => clearInterval(timer);
|
|
281
|
-
}, []);
|
|
299
|
+
}, [token]);
|
|
282
300
|
|
|
283
301
|
useEffect(() => {
|
|
284
302
|
const handleDrop = (e: DragEvent) => {
|
|
@@ -554,8 +572,23 @@ const ChatFilePreviewInner: React.FC<{ children: React.ReactNode }> = ({ childre
|
|
|
554
572
|
e.stopPropagation();
|
|
555
573
|
|
|
556
574
|
// Convert to secure proxy URL for everything EXCEPT natively secured endpoints that don't belong to the attachments table
|
|
557
|
-
const
|
|
558
|
-
const
|
|
575
|
+
const proxyTargetUrl = originalFallbackUrl || file.url;
|
|
576
|
+
const shouldUseProxy = proxyTargetUrl && !proxyTargetUrl.includes('skillHub:download') && !proxyTargetUrl.includes('worker-monitor') && !proxyTargetUrl.includes('filePreviewAuth:download');
|
|
577
|
+
|
|
578
|
+
let secureUrl = proxyTargetUrl;
|
|
579
|
+
if (shouldUseProxy) {
|
|
580
|
+
secureUrl = `/api/filePreviewAuth:download?url=${encodeURIComponent(proxyTargetUrl)}`;
|
|
581
|
+
const collectionName = (file as any).collectionName || (isAIGenerated ? 'aiFiles' : '');
|
|
582
|
+
const storageId = (file as any).storage_id || (file as any).storageId;
|
|
583
|
+
|
|
584
|
+
if (collectionName) {
|
|
585
|
+
secureUrl += `&collection=${encodeURIComponent(collectionName)}`;
|
|
586
|
+
}
|
|
587
|
+
if (storageId) {
|
|
588
|
+
secureUrl += `&storageId=${encodeURIComponent(storageId)}`;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
559
592
|
file = { ...file, url: secureUrl };
|
|
560
593
|
|
|
561
594
|
setSessionId(currentSessionIdRef.current || '');
|