@stack-spot/ai-chat-widget 1.28.1 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/app-metadata.json +2 -2
- package/dist/layout.css +19 -0
- package/dist/utils/upload/UploadManager.d.ts +2 -0
- package/dist/utils/upload/UploadManager.d.ts.map +1 -1
- package/dist/utils/upload/UploadManager.js +32 -25
- package/dist/utils/upload/UploadManager.js.map +1 -1
- package/dist/utils/upload/use-paste-upload.d.ts +8 -0
- package/dist/utils/upload/use-paste-upload.d.ts.map +1 -0
- package/dist/utils/upload/use-paste-upload.js +19 -0
- package/dist/utils/upload/use-paste-upload.js.map +1 -0
- package/dist/views/MessageInput/UploadDragNDrop.d.ts +14 -0
- package/dist/views/MessageInput/UploadDragNDrop.d.ts.map +1 -0
- package/dist/views/MessageInput/UploadDragNDrop.js +52 -0
- package/dist/views/MessageInput/UploadDragNDrop.js.map +1 -0
- package/dist/views/MessageInput/dictionary.d.ts +1 -1
- package/dist/views/MessageInput/dictionary.d.ts.map +1 -1
- package/dist/views/MessageInput/dictionary.js +10 -0
- package/dist/views/MessageInput/dictionary.js.map +1 -1
- package/dist/views/MessageInput/index.d.ts.map +1 -1
- package/dist/views/MessageInput/index.js +11 -1
- package/dist/views/MessageInput/index.js.map +1 -1
- package/package.json +1 -1
- package/src/app-metadata.json +2 -2
- package/src/layout.css +19 -0
- package/src/utils/upload/UploadManager.ts +32 -23
- package/src/utils/upload/use-paste-upload.tsx +30 -0
- package/src/views/MessageInput/UploadDragNDrop.tsx +82 -0
- package/src/views/MessageInput/dictionary.ts +10 -0
- package/src/views/MessageInput/index.tsx +15 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.29.0](https://github.com/stack-spot/portal-ai-chat-widget/compare/ai-chat-widget@v1.28.1...ai-chat-widget@v1.29.0) (2025-07-03)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* Adds drag-and-drop and paste upload functionality ([#192](https://github.com/stack-spot/portal-ai-chat-widget/issues/192)) ([a052b9e](https://github.com/stack-spot/portal-ai-chat-widget/commit/a052b9e8108b6a0971d96596f25c6be873664980))
|
|
9
|
+
|
|
3
10
|
## [1.28.1](https://github.com/stack-spot/portal-ai-chat-widget/compare/ai-chat-widget@v1.28.0...ai-chat-widget@v1.28.1) (2025-07-03)
|
|
4
11
|
|
|
5
12
|
|
package/dist/app-metadata.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stack-spot/ai-chat-widget",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"date": "Thu Jul 03 2025
|
|
3
|
+
"version": "1.29.0",
|
|
4
|
+
"date": "Thu Jul 03 2025 20:22:32 GMT+0000 (Coordinated Universal Time)",
|
|
5
5
|
"dependencies": [
|
|
6
6
|
{
|
|
7
7
|
"name": "@stack-spot/app-metadata",
|
package/dist/layout.css
CHANGED
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
.chat-container {
|
|
97
|
+
position: relative;
|
|
97
98
|
padding: 20px;
|
|
98
99
|
max-width: 1200px;
|
|
99
100
|
width: calc(100% - 40px);
|
|
@@ -186,4 +187,22 @@
|
|
|
186
187
|
border: 1px solid var(--primary-500);
|
|
187
188
|
border-left: none;
|
|
188
189
|
color: var(--light-contrastText);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.upload-drag-drop {
|
|
193
|
+
display: flex;
|
|
194
|
+
background-color: #00000090;
|
|
195
|
+
background-color: color-mix(in srgb, var(--light-300) 80%, transparent);
|
|
196
|
+
position: absolute;
|
|
197
|
+
width: 99%;
|
|
198
|
+
height: 99%;
|
|
199
|
+
top: 0;
|
|
200
|
+
left: 0;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
justify-content: center;
|
|
203
|
+
align-items: center;
|
|
204
|
+
border: 1px dashed var(--secondary-500);
|
|
205
|
+
z-index: 9999;
|
|
206
|
+
pointer-events: auto;
|
|
207
|
+
color: var(--light-contrastText)
|
|
189
208
|
}
|
|
@@ -24,12 +24,14 @@ export declare class UploadManager {
|
|
|
24
24
|
private runChangeListeners;
|
|
25
25
|
private runStatusListeners;
|
|
26
26
|
private hasEquivalentFile;
|
|
27
|
+
private processFiles;
|
|
27
28
|
private attachEventListeners;
|
|
28
29
|
private createInput;
|
|
29
30
|
private computeStatus;
|
|
30
31
|
open(): void;
|
|
31
32
|
get(): FileUpload[];
|
|
32
33
|
reset(): void;
|
|
34
|
+
add(files?: File | File[]): void;
|
|
33
35
|
remove(file: FileUpload): void;
|
|
34
36
|
onChange(listener: UploadChangeListener): () => void;
|
|
35
37
|
onChangeStatus(listener: UploadStatusChangeListener): () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadManager.d.ts","sourceRoot":"","sources":["../../../src/utils/upload/UploadManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAsD,WAAW,EAAE,MAAM,UAAU,CAAA;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAGzC,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAA;AAChE,MAAM,MAAM,0BAA0B,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAA;AAC9E,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,IAAI,CAAA;AACjE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAA;AAEhE,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,MAAM,EAAE,mBAAmB,CAAS;gBAExB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAMlF,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"UploadManager.d.ts","sourceRoot":"","sources":["../../../src/utils/upload/UploadManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAsD,WAAW,EAAE,MAAM,UAAU,CAAA;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAGzC,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAA;AAChE,MAAM,MAAM,0BAA0B,GAAG,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAA;AAC9E,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,IAAI,CAAA;AACjE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAA;AAEhE,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAU;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,MAAM,EAAE,mBAAmB,CAAS;gBAExB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAMlF,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,aAAa;IASrB,IAAI;IAKJ,GAAG,IAAI,UAAU,EAAE;IAInB,KAAK;IAML,GAAG,CAAC,KAAK,GAAE,IAAI,GAAG,IAAI,EAAO;IAK7B,MAAM,CAAC,IAAI,EAAE,UAAU;IAOvB,QAAQ,CAAC,QAAQ,EAAE,oBAAoB;IAOvC,cAAc,CAAC,QAAQ,EAAE,0BAA0B;IAOnD,OAAO,CAAC,QAAQ,EAAE,mBAAmB;IAOrC,MAAM;IAIN,OAAO;CAIR"}
|
|
@@ -32,34 +32,37 @@ export class UploadManager {
|
|
|
32
32
|
const id = getFileId(file);
|
|
33
33
|
return this.value.some(f => id === f.id);
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
errors.push(new MaxFilesReached(f.name, this.maxItems));
|
|
45
|
-
}
|
|
46
|
-
else if (this.hasEquivalentFile(f)) {
|
|
47
|
-
errors.push(new FileAlreadyExists(f.name));
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
const upload = new FileUpload(f);
|
|
51
|
-
newFiles.push(upload);
|
|
52
|
-
upload.onChange(() => this.runStatusListeners());
|
|
53
|
-
}
|
|
35
|
+
processFiles(files) {
|
|
36
|
+
const newFiles = [];
|
|
37
|
+
const errors = [];
|
|
38
|
+
for (const f of files ?? []) {
|
|
39
|
+
if (this.maxSize && f.size > this.maxSize.value * Math.pow(1024, unitPower[this.maxSize?.unit])) {
|
|
40
|
+
errors.push(new FileIsTooLarge(f.name, this.maxSize));
|
|
41
|
+
}
|
|
42
|
+
else if (this.maxItems && this.value.length + newFiles.length === this.maxItems) {
|
|
43
|
+
errors.push(new MaxFilesReached(f.name, this.maxItems));
|
|
54
44
|
}
|
|
55
|
-
if (
|
|
56
|
-
|
|
57
|
-
this.runChangeListeners();
|
|
58
|
-
this.runStatusListeners();
|
|
45
|
+
else if (this.hasEquivalentFile(f)) {
|
|
46
|
+
errors.push(new FileAlreadyExists(f.name));
|
|
59
47
|
}
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
else {
|
|
49
|
+
const upload = new FileUpload(f);
|
|
50
|
+
newFiles.push(upload);
|
|
51
|
+
upload.onChange(() => this.runStatusListeners());
|
|
62
52
|
}
|
|
53
|
+
}
|
|
54
|
+
if (newFiles.length) {
|
|
55
|
+
this.value = [...this.value, ...newFiles];
|
|
56
|
+
this.runChangeListeners();
|
|
57
|
+
this.runStatusListeners();
|
|
58
|
+
}
|
|
59
|
+
if (errors.length) {
|
|
60
|
+
this.errorListeners.forEach(l => l(errors));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
attachEventListeners() {
|
|
64
|
+
const handleChange = () => {
|
|
65
|
+
this.processFiles(this.input?.files || []);
|
|
63
66
|
this.destroy();
|
|
64
67
|
};
|
|
65
68
|
this.onDestroy = () => this.input?.removeEventListener('change', handleChange);
|
|
@@ -96,6 +99,10 @@ export class UploadManager {
|
|
|
96
99
|
this.value = [];
|
|
97
100
|
this.runChangeListeners();
|
|
98
101
|
}
|
|
102
|
+
add(files = []) {
|
|
103
|
+
const fileList = Array.isArray(files) ? files : [files];
|
|
104
|
+
this.processFiles(fileList);
|
|
105
|
+
}
|
|
99
106
|
remove(file) {
|
|
100
107
|
file.destroy();
|
|
101
108
|
this.value = this.value.filter(f => f !== file);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadManager.js","sourceRoot":"","sources":["../../../src/utils/upload/UploadManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAe,MAAM,UAAU,CAAA;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAO9C,MAAM,OAAO,aAAa;IAChB,eAAe,GAA2B,EAAE,CAAA;IAC5C,eAAe,GAAiC,EAAE,CAAA;IAClD,cAAc,GAA0B,EAAE,CAAA;IAC1C,KAAK,GAA4B,IAAI,CAAA;IACrC,KAAK,GAAiB,EAAE,CAAA;IACxB,OAAO,CAAW;IAClB,QAAQ,CAAQ;IAChB,MAAM,CAAU;IAChB,SAAS,GAAe,GAAG,EAAE,GAAE,CAAC,CAAA;IACxC,MAAM,GAAwB,MAAM,CAAA;IAEpC,YAAY,OAAsE;QAChF,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,CAAA;QAC/B,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAA;QACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAA;IACxC,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAClD,CAAC;IAEO,kBAAkB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACnC,IAAI,MAAM,KAAK,IAAI,CAAC,MAAM;YAAE,OAAM;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC9C,CAAC;IAEO,iBAAiB,CAAC,IAAU;QAClC,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAA;IAC1C,CAAC;IAEO,
|
|
1
|
+
{"version":3,"file":"UploadManager.js","sourceRoot":"","sources":["../../../src/utils/upload/UploadManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAe,MAAM,UAAU,CAAA;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAO9C,MAAM,OAAO,aAAa;IAChB,eAAe,GAA2B,EAAE,CAAA;IAC5C,eAAe,GAAiC,EAAE,CAAA;IAClD,cAAc,GAA0B,EAAE,CAAA;IAC1C,KAAK,GAA4B,IAAI,CAAA;IACrC,KAAK,GAAiB,EAAE,CAAA;IACxB,OAAO,CAAW;IAClB,QAAQ,CAAQ;IAChB,MAAM,CAAU;IAChB,SAAS,GAAe,GAAG,EAAE,GAAE,CAAC,CAAA;IACxC,MAAM,GAAwB,MAAM,CAAA;IAEpC,YAAY,OAAsE;QAChF,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,CAAA;QAC/B,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAA;QACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAA;IACxC,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAClD,CAAC;IAEO,kBAAkB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QACnC,IAAI,MAAM,KAAK,IAAI,CAAC,MAAM;YAAE,OAAM;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC9C,CAAC;IAEO,iBAAiB,CAAC,IAAU;QAClC,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAA;IAC1C,CAAC;IAEO,YAAY,CAAC,KAAwB;QAC3C,MAAM,QAAQ,GAAiB,EAAE,CAAA;QACjC,MAAM,MAAM,GAAkB,EAAE,CAAA;QAChC,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;gBAChG,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;YACvD,CAAC;iBAAM,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClF,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;YACzD,CAAC;iBAAM,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;gBAChC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBACrB,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAA;YAClD,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,CAAA;YACzC,IAAI,CAAC,kBAAkB,EAAE,CAAA;YACzB,IAAI,CAAC,kBAAkB,EAAE,CAAA;QAC3B,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;IAEO,oBAAoB;QAC1B,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAA;YAC1C,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC,CAAA;QACD,IAAI,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;QAC9E,IAAI,CAAC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IACtD,CAAC;IAEO,WAAW;QACjB,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QAC5C,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACvC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;QACvC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;QACjD,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC/D,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChC,IAAI,CAAC,oBAAoB,EAAE,CAAA;IAC7B,CAAC;IAEO,aAAa;QACnB,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;gBAAE,OAAO,OAAO,CAAA;YACxC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;gBAAE,SAAS,GAAG,IAAI,CAAA;QAC9C,CAAC;QACD,OAAO,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAA;IACzC,CAAC;IAED,IAAI;QACF,IAAI,CAAC,WAAW,EAAE,CAAA;QAClB,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,CAAA;IACrB,CAAC;IAED,GAAG;QACD,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACpC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAA;QACf,IAAI,CAAC,kBAAkB,EAAE,CAAA;IAC3B,CAAC;IAED,GAAG,CAAC,QAAuB,EAAE;QAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACvD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC;IAED,MAAM,CAAC,IAAgB;QACrB,IAAI,CAAC,OAAO,EAAE,CAAA;QACd,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;QAC/C,IAAI,CAAC,kBAAkB,EAAE,CAAA;QACzB,IAAI,CAAC,kBAAkB,EAAE,CAAA;IAC3B,CAAC;IAED,QAAQ,CAAC,QAA8B;QACrC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACnC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAA;QACtC,CAAC,CAAA;IACH,CAAC;IAED,cAAc,CAAC,QAAoC;QACjD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACnC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAA;QACtC,CAAC,CAAA;IACH,CAAC;IAED,OAAO,CAAC,QAA6B;QACnC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAClC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;QACrC,CAAC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ,CAAA;IAC/D,CAAC;IAED,OAAO;QACL,IAAI,CAAC,SAAS,EAAE,CAAA;QAChB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAA;IACtB,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface UsePasteUploadProps {
|
|
2
|
+
textAreaRef: React.RefObject<HTMLTextAreaElement>;
|
|
3
|
+
onUploadFiles: (files: File[]) => void;
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const usePasteUpload: ({ textAreaRef, onUploadFiles, enabled, }: UsePasteUploadProps) => void;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=use-paste-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-paste-upload.d.ts","sourceRoot":"","sources":["../../../src/utils/upload/use-paste-upload.tsx"],"names":[],"mappings":"AAEA,UAAU,mBAAmB;IAC3B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAClD,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,cAAc,6CAIxB,mBAAmB,SAiBrB,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
export const usePasteUpload = ({ textAreaRef, onUploadFiles, enabled = true, }) => {
|
|
3
|
+
useEffect(() => {
|
|
4
|
+
const textarea = textAreaRef.current;
|
|
5
|
+
if (!textarea || !enabled)
|
|
6
|
+
return;
|
|
7
|
+
const handlePaste = (e) => {
|
|
8
|
+
if (e.clipboardData?.files?.length) {
|
|
9
|
+
onUploadFiles(Array.from(e.clipboardData.files));
|
|
10
|
+
e.preventDefault();
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
textarea.addEventListener('paste', handlePaste);
|
|
14
|
+
return () => {
|
|
15
|
+
textarea.removeEventListener('paste', handlePaste);
|
|
16
|
+
};
|
|
17
|
+
}, [onUploadFiles, textAreaRef, enabled]);
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=use-paste-upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-paste-upload.js","sourceRoot":"","sources":["../../../src/utils/upload/use-paste-upload.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQjC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAC7B,WAAW,EACX,aAAa,EACb,OAAO,GAAG,IAAI,GACM,EAAE,EAAE;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAA;QACpC,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO;YAAE,OAAM;QAEjC,MAAM,WAAW,GAAG,CAAC,CAAiB,EAAE,EAAE;YACxC,IAAI,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;gBACnC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;gBAChD,CAAC,CAAC,cAAc,EAAE,CAAA;YACpB,CAAC;QACH,CAAC,CAAA;QAED,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QAC/C,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QACpD,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAA;AAC3C,CAAC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DragEvent } from 'react';
|
|
2
|
+
export declare function useUploadDragDrop(containerSelector?: string): {
|
|
3
|
+
isDragging: boolean;
|
|
4
|
+
handleDrop: (e: DragEvent) => void;
|
|
5
|
+
handleDragLeave: (e: DragEvent) => void;
|
|
6
|
+
};
|
|
7
|
+
interface UploadDragNDropProps {
|
|
8
|
+
isDragging?: boolean;
|
|
9
|
+
onDrop?: (e: DragEvent) => void;
|
|
10
|
+
onDragLeave?: (e: DragEvent) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const UploadDragNDrop: ({ isDragging, onDrop, onDragLeave }: UploadDragNDropProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=UploadDragNDrop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UploadDragNDrop.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/UploadDragNDrop.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAoC,MAAM,OAAO,CAAA;AAInE,wBAAgB,iBAAiB,CAAC,iBAAiB,GAAE,MAA0B;;oBAI1C,SAAS;yBASJ,SAAS;EA2BlD;AAED,UAAU,oBAAoB;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;CACtC;AAED,eAAO,MAAM,eAAe,wCAAyC,oBAAoB,mDA2BxF,CAAA"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IconBox } from '@citric/core';
|
|
3
|
+
import { Document } from '@citric/icons';
|
|
4
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
5
|
+
import { useCurrentChat } from '../../context/hooks.js';
|
|
6
|
+
import { useMessageInputDictionary } from './dictionary.js';
|
|
7
|
+
export function useUploadDragDrop(containerSelector = '.chat-container') {
|
|
8
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
9
|
+
const chat = useCurrentChat();
|
|
10
|
+
const handleDrop = useCallback((e) => {
|
|
11
|
+
e.preventDefault();
|
|
12
|
+
e.stopPropagation();
|
|
13
|
+
setIsDragging(false);
|
|
14
|
+
if (e.dataTransfer?.files?.length) {
|
|
15
|
+
chat.uploadManager.add(Array.from(e.dataTransfer.files));
|
|
16
|
+
}
|
|
17
|
+
}, [chat]);
|
|
18
|
+
const handleDragLeave = useCallback((e) => {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
if (e.currentTarget && !e.currentTarget.contains(e.relatedTarget)) {
|
|
21
|
+
setIsDragging(false);
|
|
22
|
+
}
|
|
23
|
+
}, []);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const container = document.querySelector(containerSelector);
|
|
26
|
+
if (!container)
|
|
27
|
+
return;
|
|
28
|
+
const nativeHandleDragEnter = (e) => {
|
|
29
|
+
e.preventDefault();
|
|
30
|
+
setIsDragging(true);
|
|
31
|
+
};
|
|
32
|
+
container.addEventListener('dragenter', nativeHandleDragEnter);
|
|
33
|
+
return () => {
|
|
34
|
+
container.removeEventListener('dragenter', nativeHandleDragEnter);
|
|
35
|
+
};
|
|
36
|
+
}, [containerSelector]);
|
|
37
|
+
return {
|
|
38
|
+
isDragging,
|
|
39
|
+
handleDrop,
|
|
40
|
+
handleDragLeave,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export const UploadDragNDrop = ({ isDragging, onDrop, onDragLeave }) => {
|
|
44
|
+
const t = useMessageInputDictionary();
|
|
45
|
+
if (!isDragging)
|
|
46
|
+
return null;
|
|
47
|
+
return (_jsxs("div", { className: "upload-drag-drop", role: "dialog", "aria-modal": "true", "aria-labelledby": "upload-drag-drop-title", "aria-describedby": "upload-drag-drop-description", tabIndex: -1, onDrop: onDrop, onDragLeave: onDragLeave, onDragOver: e => {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
e.stopPropagation();
|
|
50
|
+
}, children: [_jsx(IconBox, { size: "lg", "aria-hidden": true, children: _jsx(Document, {}) }), _jsx("h2", { id: "upload-drag-drop-title", children: t.uploadDragDropTitle }), _jsx("p", { id: "upload-drag-drop-description", children: t.uploadDragDropDescription })] }));
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=UploadDragNDrop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UploadDragNDrop.js","sourceRoot":"","sources":["../../../src/views/MessageInput/UploadDragNDrop.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const useMessageInputDictionary: () => Record<"code" | "placeholder" | "selected" | "send" | "cancel" | "stack" | "knowledgeSource" | "agent" | "upload" | "remove" | "collapse" | "spot" | "removeConfig" | "removeStack" | "removeWorkspace" | "removeKS" | "removeSelection" | "expand" | "uploadSizeError" | "uploadItemLimitError" | "cantSendBecauseOfUploadError" | "cantSendBecauseOfUploadProgress" | "cantSendBecauseOfEmptyContent" | "chatAgent", string>;
|
|
1
|
+
export declare const useMessageInputDictionary: () => Record<"code" | "placeholder" | "selected" | "send" | "cancel" | "stack" | "knowledgeSource" | "agent" | "upload" | "remove" | "collapse" | "spot" | "typing" | "removeConfig" | "removeStack" | "removeWorkspace" | "removeKS" | "removeSelection" | "expand" | "uploadSizeError" | "uploadItemLimitError" | "uploadError" | "uploadDragging" | "uploadDragDropTitle" | "uploadDragDropDescription" | "unknownUploadError" | "cantSendBecauseOfUploadError" | "cantSendBecauseOfUploadProgress" | "cantSendBecauseOfEmptyContent" | "chatAgent", string>;
|
|
2
2
|
//# sourceMappingURL=dictionary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictionary.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/dictionary.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dictionary.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/dictionary.ts"],"names":[],"mappings":"AAqEA,eAAO,MAAM,yBAAyB,iiBAAiC,CAAA"}
|
|
@@ -8,6 +8,7 @@ const dictionary = {
|
|
|
8
8
|
agent: 'Select agent',
|
|
9
9
|
send: 'Send message',
|
|
10
10
|
placeholder: 'Send a message to $0. For commands, use @ or /',
|
|
11
|
+
typing: 'Type your message...',
|
|
11
12
|
cancel: 'Cancel',
|
|
12
13
|
removeConfig: 'Remove all the configuration',
|
|
13
14
|
removeStack: 'Stop using the current stack',
|
|
@@ -21,6 +22,11 @@ const dictionary = {
|
|
|
21
22
|
collapse: 'Collapse options',
|
|
22
23
|
uploadSizeError: 'The following files were not added to the upload list because they\'re larger than $1:',
|
|
23
24
|
uploadItemLimitError: 'The following files were not added because no more than $1 items may be uploaded at a time:',
|
|
25
|
+
uploadError: 'An error occurred while uploading the file "$0".',
|
|
26
|
+
uploadDragging: 'Drop the file here to upload',
|
|
27
|
+
uploadDragDropTitle: 'Drop your files here',
|
|
28
|
+
uploadDragDropDescription: 'Drag or drop files to share in the conversation',
|
|
29
|
+
unknownUploadError: 'An error occurred while uploading the files.',
|
|
24
30
|
cantSendBecauseOfUploadError: 'Can\'t send the message because one of the files in the upload list could not be uploaded. Please, retry it or remove it from the list.',
|
|
25
31
|
cantSendBecauseOfUploadProgress: 'Please wait until all files are uploaded before sending the message. You can also cancel the upload by removing it from the list of uploads.',
|
|
26
32
|
cantSendBecauseOfEmptyContent: 'You can\'t send empty messages. Please write some text or upload a file.',
|
|
@@ -34,6 +40,7 @@ const dictionary = {
|
|
|
34
40
|
agent: 'Selecionar agente',
|
|
35
41
|
send: 'Enviar mensagem',
|
|
36
42
|
placeholder: 'Envie uma mensagem para $0. Para comandos, use @ ou /',
|
|
43
|
+
typing: 'Digite sua mensagem...',
|
|
37
44
|
cancel: 'Cancelar',
|
|
38
45
|
removeConfig: 'Remover todas as configurações',
|
|
39
46
|
removeStack: 'Parar de usar a stack atual',
|
|
@@ -48,6 +55,9 @@ const dictionary = {
|
|
|
48
55
|
uploadSizeError: 'Os seguintes arquivos não foram adicionados à lista de upload porque eles são maiores que $0:',
|
|
49
56
|
uploadItemLimitError: 'Os seguintes arquivos não foram adicionados à lista de upload porque é permitido enviar no máximo $0 arquivos por vez:',
|
|
50
57
|
uploadError: 'Ocorreu um erro ao enviar o arquivo "$0".',
|
|
58
|
+
uploadDragging: 'Solte o arquivo aqui para fazer upload',
|
|
59
|
+
uploadDragDropTitle: 'Solte seus arquivos aqui',
|
|
60
|
+
uploadDragDropDescription: 'Arraste ou solte arquivos para compartilhar na conversa',
|
|
51
61
|
unknownUploadError: 'Ocorreu um erro ao enviar os arquivos.',
|
|
52
62
|
cantSendBecauseOfUploadError: 'Não é possível enviar a mensagem, pois um dos arquivos na lista de uploads não pôde ser enviado. Por favor, tente enviá-lo novamente ou remova-o da lista.',
|
|
53
63
|
cantSendBecauseOfUploadProgress: 'Por favor aguarde todos os uploads de arquivos antes de enviar a mensagem. Você pode cancelar o upload removendo o arquivo da lista de uploads.',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictionary.js","sourceRoot":"","sources":["../../../src/views/MessageInput/dictionary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAEvE,MAAM,UAAU,GAAG;IACjB,EAAE,EAAE;QACF,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,aAAa;QACnB,eAAe,EAAE,0BAA0B;QAC3C,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,gDAAgD;QAC7D,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,8BAA8B;QAC5C,WAAW,EAAE,8BAA8B;QAC3C,eAAe,EAAE,6BAA6B;QAC9C,QAAQ,EAAE,kCAAkC;QAC5C,QAAQ,EAAE,UAAU;QACpB,eAAe,EAAE,+BAA+B;QAChD,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,kBAAkB;QAC5B,eAAe,EAAE,wFAAwF;QACzG,oBAAoB,EAAE,6FAA6F;QACnH,4BAA4B,EAAE,yIAAyI;QACvK,+BAA+B,EAAE,8IAA8I;QAC/K,6BAA6B,EAAE,0EAA0E;QACzG,SAAS,EAAE,QAAQ;KACpB;IACD,EAAE,EAAE;QACF,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,wBAAwB;QAC9B,IAAI,EAAE,iBAAiB;QACvB,eAAe,EAAE,8BAA8B;QAC/C,KAAK,EAAE,mBAAmB;QAC1B,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,uDAAuD;QACpE,MAAM,EAAE,UAAU;QAClB,YAAY,EAAE,gCAAgC;QAC9C,WAAW,EAAE,6BAA6B;QAC1C,eAAe,EAAE,4BAA4B;QAC7C,QAAQ,EAAE,qCAAqC;QAC/C,QAAQ,EAAE,aAAa;QACvB,eAAe,EAAE,4BAA4B;QAC7C,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,iBAAiB;QAC3B,eAAe,EAAE,+FAA+F;QAChH,oBAAoB,EAAE,wHAAwH;QAC9I,WAAW,EAAE,2CAA2C;QACxD,kBAAkB,EAAE,wCAAwC;QAC5D,4BAA4B,EAAE,4JAA4J;QAC1L,+BAA+B,EAAE,iJAAiJ;QAClL,6BAA6B,EAAE,6FAA6F;QAC5H,SAAS,EAAE,SAAS;KACrB;CACmB,CAAA;AAEtB,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"dictionary.js","sourceRoot":"","sources":["../../../src/views/MessageInput/dictionary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAEvE,MAAM,UAAU,GAAG;IACjB,EAAE,EAAE;QACF,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,aAAa;QACnB,eAAe,EAAE,0BAA0B;QAC3C,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,gDAAgD;QAC7D,MAAM,EAAE,sBAAsB;QAC9B,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,8BAA8B;QAC5C,WAAW,EAAE,8BAA8B;QAC3C,eAAe,EAAE,6BAA6B;QAC9C,QAAQ,EAAE,kCAAkC;QAC5C,QAAQ,EAAE,UAAU;QACpB,eAAe,EAAE,+BAA+B;QAChD,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,kBAAkB;QAC5B,eAAe,EAAE,wFAAwF;QACzG,oBAAoB,EAAE,6FAA6F;QACnH,WAAW,EAAE,kDAAkD;QAC/D,cAAc,EAAE,8BAA8B;QAC9C,mBAAmB,EAAE,sBAAsB;QAC3C,yBAAyB,EAAE,iDAAiD;QAC5E,kBAAkB,EAAE,8CAA8C;QAClE,4BAA4B,EAAE,yIAAyI;QACvK,+BAA+B,EAAE,8IAA8I;QAC/K,6BAA6B,EAAE,0EAA0E;QACzG,SAAS,EAAE,QAAQ;KACpB;IACD,EAAE,EAAE;QACF,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,wBAAwB;QAC9B,IAAI,EAAE,iBAAiB;QACvB,eAAe,EAAE,8BAA8B;QAC/C,KAAK,EAAE,mBAAmB;QAC1B,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,uDAAuD;QACpE,MAAM,EAAE,wBAAwB;QAChC,MAAM,EAAE,UAAU;QAClB,YAAY,EAAE,gCAAgC;QAC9C,WAAW,EAAE,6BAA6B;QAC1C,eAAe,EAAE,4BAA4B;QAC7C,QAAQ,EAAE,qCAAqC;QAC/C,QAAQ,EAAE,aAAa;QACvB,eAAe,EAAE,4BAA4B;QAC7C,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,gBAAgB;QACxB,QAAQ,EAAE,iBAAiB;QAC3B,eAAe,EAAE,+FAA+F;QAChH,oBAAoB,EAAE,wHAAwH;QAC9I,WAAW,EAAE,2CAA2C;QACxD,cAAc,EAAE,wCAAwC;QACxD,mBAAmB,EAAE,0BAA0B;QAC/C,yBAAyB,EAAE,yDAAyD;QACpF,kBAAkB,EAAE,wCAAwC;QAC5D,4BAA4B,EAAE,4JAA4J;QAC1L,+BAA+B,EAAE,iJAAiJ;QAClL,6BAA6B,EAAE,6FAA6F;QAC5H,SAAS,EAAE,SAAS;KACrB;CACmB,CAAA;AAEtB,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/views/MessageInput/index.tsx"],"names":[],"mappings":"AAsBA;;;;GAIG;AACH,eAAO,MAAM,YAAY,+CA0HxB,CAAA"}
|
|
@@ -9,6 +9,7 @@ import { quickCommandRegex } from '../../regex.js';
|
|
|
9
9
|
import { ChatEntry } from '../../state/ChatEntry.js';
|
|
10
10
|
import { checkIsTrial } from '../../utils/check-is-trial.js';
|
|
11
11
|
import { UploadProvider } from '../../utils/upload/context.js';
|
|
12
|
+
import { usePasteUpload } from '../../utils/upload/use-paste-upload.js';
|
|
12
13
|
import { AgentSelector } from './AgentSelector.js';
|
|
13
14
|
import { ButtonAgent } from './ButtonAgent.js';
|
|
14
15
|
import { ButtonBar } from './ButtonBar.js';
|
|
@@ -18,6 +19,7 @@ import { useMessageInputDictionary } from './dictionary.js';
|
|
|
18
19
|
import { QuickCommandSelector } from './QuickCommandSelector.js';
|
|
19
20
|
import { MAX_INPUT_HEIGHT, MessageInputBox, MIN_INPUT_HEIGHT } from './styled.js';
|
|
20
21
|
import { UploadBar } from './UploadBar.js';
|
|
22
|
+
import { UploadDragNDrop, useUploadDragDrop } from './UploadDragNDrop.js';
|
|
21
23
|
/**
|
|
22
24
|
* This renders the MessageInput part of the layout which includes the progress bar, the actual textarea, the badges telling what is
|
|
23
25
|
* going to be used for the question and the buttons to send, cancel, set the workspace, among others. This also includes the Quick
|
|
@@ -36,6 +38,12 @@ export const MessageInput = () => {
|
|
|
36
38
|
const agentLabel = useCurrentChatState('agent')?.label;
|
|
37
39
|
const { handleKeyDown, handleKeyUp } = useUserEntryHistoryShortcut();
|
|
38
40
|
const isTrial = checkIsTrial();
|
|
41
|
+
const { isDragging, handleDrop, handleDragLeave } = useUploadDragDrop();
|
|
42
|
+
usePasteUpload({
|
|
43
|
+
textAreaRef,
|
|
44
|
+
onUploadFiles: files => chat.uploadManager.add(files),
|
|
45
|
+
enabled: !isLoading,
|
|
46
|
+
});
|
|
39
47
|
const checkSendRequirements = useCallback(() => {
|
|
40
48
|
if (chat.uploadManager.status === 'error') {
|
|
41
49
|
chat.pushMessage(new ChatEntry({
|
|
@@ -96,6 +104,8 @@ export const MessageInput = () => {
|
|
|
96
104
|
if (!isLoading)
|
|
97
105
|
textAreaRef.current?.focus();
|
|
98
106
|
}, [isLoading]);
|
|
99
|
-
return (
|
|
107
|
+
return (_jsxs(UploadProvider, { value: chat.uploadManager, children: [_jsxs(MessageInputBox, { "aria-busy": isLoading, className: "message-input", "$inputFocused": focused, children: [_jsxs("div", { className: "wrapper-action", children: [_jsx(QuickCommandSelector, { inputRef: textAreaRef, isTrial: isTrial }), _jsx(AgentSelector, { inputRef: textAreaRef, isTrial: isTrial }), _jsxs("div", { className: listToClass(['action-box', focused && 'focused', isLoading && 'disabled']), children: [_jsx(ButtonAgent, {}), _jsx(AdaptiveTextArea, { ref: textAreaRef, placeholder: agentLabel
|
|
108
|
+
? interpolate(t.placeholder, agentLabel)
|
|
109
|
+
: t.typing, onChange: e => chat.set('nextMessage', e.target.value), value: value, onFocus: () => setFocused(true), onBlur: () => setFocused(false), onKeyDown: onKeyDown, onKeyUp: handleKeyUp, onIncreaseSize: () => setExpanded(false), onResetSize: () => !expansionLocked.current && setExpanded(true), maxHeight: isMinimized ? MIN_INPUT_HEIGHT : MAX_INPUT_HEIGHT })] })] }), _jsx(ProgressBar, { visible: true, animate: isLoading, backgroundColor: isLoading || !focused ? theme.color.light[500] : theme.color.primary[500] }), _jsx(ContextBar, {}), chat.get('features').upload && _jsx(UploadBar, {}), _jsx(ButtonBar, { onSend: onSend, isLoading: isLoading })] }), _jsx(UploadDragNDrop, { isDragging: isDragging, onDrop: handleDrop, onDragLeave: handleDragLeave })] }));
|
|
100
110
|
};
|
|
101
111
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/views/MessageInput/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/views/MessageInput/index.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/app-metadata.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stack-spot/ai-chat-widget",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"date": "Thu Jul 03 2025
|
|
3
|
+
"version": "1.29.0",
|
|
4
|
+
"date": "Thu Jul 03 2025 20:22:32 GMT+0000 (Coordinated Universal Time)",
|
|
5
5
|
"dependencies": [
|
|
6
6
|
{
|
|
7
7
|
"name": "@stack-spot/app-metadata",
|
package/src/layout.css
CHANGED
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
.chat-container {
|
|
97
|
+
position: relative;
|
|
97
98
|
padding: 20px;
|
|
98
99
|
max-width: 1200px;
|
|
99
100
|
width: calc(100% - 40px);
|
|
@@ -186,4 +187,22 @@
|
|
|
186
187
|
border: 1px solid var(--primary-500);
|
|
187
188
|
border-left: none;
|
|
188
189
|
color: var(--light-contrastText);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.upload-drag-drop {
|
|
193
|
+
display: flex;
|
|
194
|
+
background-color: #00000090;
|
|
195
|
+
background-color: color-mix(in srgb, var(--light-300) 80%, transparent);
|
|
196
|
+
position: absolute;
|
|
197
|
+
width: 99%;
|
|
198
|
+
height: 99%;
|
|
199
|
+
top: 0;
|
|
200
|
+
left: 0;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
justify-content: center;
|
|
203
|
+
align-items: center;
|
|
204
|
+
border: 1px dashed var(--secondary-500);
|
|
205
|
+
z-index: 9999;
|
|
206
|
+
pointer-events: auto;
|
|
207
|
+
color: var(--light-contrastText)
|
|
189
208
|
}
|
|
@@ -43,31 +43,35 @@ export class UploadManager {
|
|
|
43
43
|
return this.value.some(f => id === f.id)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
private processFiles(files: FileList | File[]) {
|
|
47
|
+
const newFiles: FileUpload[] = []
|
|
48
|
+
const errors: UploadError[] = []
|
|
49
|
+
for (const f of files ?? []) {
|
|
50
|
+
if (this.maxSize && f.size > this.maxSize.value * Math.pow(1024, unitPower[this.maxSize?.unit])) {
|
|
51
|
+
errors.push(new FileIsTooLarge(f.name, this.maxSize))
|
|
52
|
+
} else if (this.maxItems && this.value.length + newFiles.length === this.maxItems) {
|
|
53
|
+
errors.push(new MaxFilesReached(f.name, this.maxItems))
|
|
54
|
+
} else if (this.hasEquivalentFile(f)) {
|
|
55
|
+
errors.push(new FileAlreadyExists(f.name))
|
|
56
|
+
} else {
|
|
57
|
+
const upload = new FileUpload(f)
|
|
58
|
+
newFiles.push(upload)
|
|
59
|
+
upload.onChange(() => this.runStatusListeners())
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (newFiles.length) {
|
|
63
|
+
this.value = [...this.value, ...newFiles]
|
|
64
|
+
this.runChangeListeners()
|
|
65
|
+
this.runStatusListeners()
|
|
66
|
+
}
|
|
67
|
+
if (errors.length) {
|
|
68
|
+
this.errorListeners.forEach(l => l(errors))
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
46
72
|
private attachEventListeners() {
|
|
47
73
|
const handleChange = () => {
|
|
48
|
-
|
|
49
|
-
const errors: UploadError[] = []
|
|
50
|
-
for (const f of this.input?.files ?? []) {
|
|
51
|
-
if (this.maxSize && f.size > this.maxSize.value * Math.pow(1024, unitPower[this.maxSize?.unit])) {
|
|
52
|
-
errors.push(new FileIsTooLarge(f.name, this.maxSize))
|
|
53
|
-
} else if (this.maxItems && this.value.length + newFiles.length === this.maxItems) {
|
|
54
|
-
errors.push(new MaxFilesReached(f.name, this.maxItems))
|
|
55
|
-
} else if (this.hasEquivalentFile(f)) {
|
|
56
|
-
errors.push(new FileAlreadyExists(f.name))
|
|
57
|
-
} else {
|
|
58
|
-
const upload = new FileUpload(f)
|
|
59
|
-
newFiles.push(upload)
|
|
60
|
-
upload.onChange(() => this.runStatusListeners())
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (newFiles.length) {
|
|
64
|
-
this.value = [...this.value, ...newFiles]
|
|
65
|
-
this.runChangeListeners()
|
|
66
|
-
this.runStatusListeners()
|
|
67
|
-
}
|
|
68
|
-
if (errors.length) {
|
|
69
|
-
this.errorListeners.forEach(l => l(errors))
|
|
70
|
-
}
|
|
74
|
+
this.processFiles(this.input?.files || [])
|
|
71
75
|
this.destroy()
|
|
72
76
|
}
|
|
73
77
|
this.onDestroy = () => this.input?.removeEventListener('change', handleChange)
|
|
@@ -108,6 +112,11 @@ export class UploadManager {
|
|
|
108
112
|
this.runChangeListeners()
|
|
109
113
|
}
|
|
110
114
|
|
|
115
|
+
add(files: File | File[] = []) {
|
|
116
|
+
const fileList = Array.isArray(files) ? files : [files]
|
|
117
|
+
this.processFiles(fileList)
|
|
118
|
+
}
|
|
119
|
+
|
|
111
120
|
remove(file: FileUpload) {
|
|
112
121
|
file.destroy()
|
|
113
122
|
this.value = this.value.filter(f => f !== file)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
|
|
3
|
+
interface UsePasteUploadProps {
|
|
4
|
+
textAreaRef: React.RefObject<HTMLTextAreaElement>,
|
|
5
|
+
onUploadFiles: (files: File[]) => void,
|
|
6
|
+
enabled?: boolean,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const usePasteUpload = ({
|
|
10
|
+
textAreaRef,
|
|
11
|
+
onUploadFiles,
|
|
12
|
+
enabled = true,
|
|
13
|
+
}: UsePasteUploadProps) => {
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const textarea = textAreaRef.current
|
|
16
|
+
if (!textarea || !enabled) return
|
|
17
|
+
|
|
18
|
+
const handlePaste = (e: ClipboardEvent) => {
|
|
19
|
+
if (e.clipboardData?.files?.length) {
|
|
20
|
+
onUploadFiles(Array.from(e.clipboardData.files))
|
|
21
|
+
e.preventDefault()
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
textarea.addEventListener('paste', handlePaste)
|
|
26
|
+
return () => {
|
|
27
|
+
textarea.removeEventListener('paste', handlePaste)
|
|
28
|
+
}
|
|
29
|
+
}, [onUploadFiles, textAreaRef, enabled])
|
|
30
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { IconBox } from '@citric/core'
|
|
2
|
+
import { Document } from '@citric/icons'
|
|
3
|
+
import { DragEvent, useCallback, useEffect, useState } from 'react'
|
|
4
|
+
import { useCurrentChat } from '../../context/hooks'
|
|
5
|
+
import { useMessageInputDictionary } from './dictionary'
|
|
6
|
+
|
|
7
|
+
export function useUploadDragDrop(containerSelector: string = '.chat-container') {
|
|
8
|
+
const [isDragging, setIsDragging] = useState(false)
|
|
9
|
+
const chat = useCurrentChat()
|
|
10
|
+
|
|
11
|
+
const handleDrop = useCallback((e: DragEvent) => {
|
|
12
|
+
e.preventDefault()
|
|
13
|
+
e.stopPropagation()
|
|
14
|
+
setIsDragging(false)
|
|
15
|
+
if (e.dataTransfer?.files?.length) {
|
|
16
|
+
chat.uploadManager.add(Array.from(e.dataTransfer.files))
|
|
17
|
+
}
|
|
18
|
+
}, [chat])
|
|
19
|
+
|
|
20
|
+
const handleDragLeave = useCallback((e: DragEvent) => {
|
|
21
|
+
e.preventDefault()
|
|
22
|
+
if (e.currentTarget && !e.currentTarget.contains(e.relatedTarget as Node)) {
|
|
23
|
+
setIsDragging(false)
|
|
24
|
+
}
|
|
25
|
+
}, [])
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const container = document.querySelector(containerSelector) as HTMLDivElement | null
|
|
29
|
+
if (!container) return
|
|
30
|
+
|
|
31
|
+
const nativeHandleDragEnter = (e: Event) => {
|
|
32
|
+
e.preventDefault()
|
|
33
|
+
setIsDragging(true)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
container.addEventListener('dragenter', nativeHandleDragEnter)
|
|
37
|
+
return () => {
|
|
38
|
+
container.removeEventListener('dragenter', nativeHandleDragEnter)
|
|
39
|
+
}
|
|
40
|
+
}, [containerSelector])
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
isDragging,
|
|
44
|
+
handleDrop,
|
|
45
|
+
handleDragLeave,
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface UploadDragNDropProps {
|
|
50
|
+
isDragging?: boolean,
|
|
51
|
+
onDrop?: (e: DragEvent) => void,
|
|
52
|
+
onDragLeave?: (e: DragEvent) => void,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const UploadDragNDrop = ({ isDragging, onDrop, onDragLeave }: UploadDragNDropProps) => {
|
|
56
|
+
const t = useMessageInputDictionary()
|
|
57
|
+
|
|
58
|
+
if (!isDragging) return null
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div
|
|
62
|
+
className="upload-drag-drop"
|
|
63
|
+
role="dialog"
|
|
64
|
+
aria-modal="true"
|
|
65
|
+
aria-labelledby="upload-drag-drop-title"
|
|
66
|
+
aria-describedby="upload-drag-drop-description"
|
|
67
|
+
tabIndex={-1}
|
|
68
|
+
onDrop={onDrop}
|
|
69
|
+
onDragLeave={onDragLeave}
|
|
70
|
+
onDragOver={e => {
|
|
71
|
+
e.preventDefault()
|
|
72
|
+
e.stopPropagation()
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
<IconBox size="lg" aria-hidden={true}>
|
|
76
|
+
<Document />
|
|
77
|
+
</IconBox>
|
|
78
|
+
<h2 id="upload-drag-drop-title">{t.uploadDragDropTitle}</h2>
|
|
79
|
+
<p id="upload-drag-drop-description">{t.uploadDragDropDescription}</p>
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
@@ -9,6 +9,7 @@ const dictionary = {
|
|
|
9
9
|
agent: 'Select agent',
|
|
10
10
|
send: 'Send message',
|
|
11
11
|
placeholder: 'Send a message to $0. For commands, use @ or /',
|
|
12
|
+
typing: 'Type your message...',
|
|
12
13
|
cancel: 'Cancel',
|
|
13
14
|
removeConfig: 'Remove all the configuration',
|
|
14
15
|
removeStack: 'Stop using the current stack',
|
|
@@ -22,6 +23,11 @@ const dictionary = {
|
|
|
22
23
|
collapse: 'Collapse options',
|
|
23
24
|
uploadSizeError: 'The following files were not added to the upload list because they\'re larger than $1:',
|
|
24
25
|
uploadItemLimitError: 'The following files were not added because no more than $1 items may be uploaded at a time:',
|
|
26
|
+
uploadError: 'An error occurred while uploading the file "$0".',
|
|
27
|
+
uploadDragging: 'Drop the file here to upload',
|
|
28
|
+
uploadDragDropTitle: 'Drop your files here',
|
|
29
|
+
uploadDragDropDescription: 'Drag or drop files to share in the conversation',
|
|
30
|
+
unknownUploadError: 'An error occurred while uploading the files.',
|
|
25
31
|
cantSendBecauseOfUploadError: 'Can\'t send the message because one of the files in the upload list could not be uploaded. Please, retry it or remove it from the list.',
|
|
26
32
|
cantSendBecauseOfUploadProgress: 'Please wait until all files are uploaded before sending the message. You can also cancel the upload by removing it from the list of uploads.',
|
|
27
33
|
cantSendBecauseOfEmptyContent: 'You can\'t send empty messages. Please write some text or upload a file.',
|
|
@@ -35,6 +41,7 @@ const dictionary = {
|
|
|
35
41
|
agent: 'Selecionar agente',
|
|
36
42
|
send: 'Enviar mensagem',
|
|
37
43
|
placeholder: 'Envie uma mensagem para $0. Para comandos, use @ ou /',
|
|
44
|
+
typing: 'Digite sua mensagem...',
|
|
38
45
|
cancel: 'Cancelar',
|
|
39
46
|
removeConfig: 'Remover todas as configurações',
|
|
40
47
|
removeStack: 'Parar de usar a stack atual',
|
|
@@ -49,6 +56,9 @@ const dictionary = {
|
|
|
49
56
|
uploadSizeError: 'Os seguintes arquivos não foram adicionados à lista de upload porque eles são maiores que $0:',
|
|
50
57
|
uploadItemLimitError: 'Os seguintes arquivos não foram adicionados à lista de upload porque é permitido enviar no máximo $0 arquivos por vez:',
|
|
51
58
|
uploadError: 'Ocorreu um erro ao enviar o arquivo "$0".',
|
|
59
|
+
uploadDragging: 'Solte o arquivo aqui para fazer upload',
|
|
60
|
+
uploadDragDropTitle: 'Solte seus arquivos aqui',
|
|
61
|
+
uploadDragDropDescription: 'Arraste ou solte arquivos para compartilhar na conversa',
|
|
52
62
|
unknownUploadError: 'Ocorreu um erro ao enviar os arquivos.',
|
|
53
63
|
cantSendBecauseOfUploadError: 'Não é possível enviar a mensagem, pois um dos arquivos na lista de uploads não pôde ser enviado. Por favor, tente enviá-lo novamente ou remova-o da lista.',
|
|
54
64
|
cantSendBecauseOfUploadProgress: 'Por favor aguarde todos os uploads de arquivos antes de enviar a mensagem. Você pode cancelar o upload removendo o arquivo da lista de uploads.',
|
|
@@ -8,6 +8,7 @@ import { quickCommandRegex } from '../../regex'
|
|
|
8
8
|
import { ChatEntry } from '../../state/ChatEntry'
|
|
9
9
|
import { checkIsTrial } from '../../utils/check-is-trial'
|
|
10
10
|
import { UploadProvider } from '../../utils/upload/context'
|
|
11
|
+
import { usePasteUpload } from '../../utils/upload/use-paste-upload'
|
|
11
12
|
import { AgentSelector } from './AgentSelector'
|
|
12
13
|
import { ButtonAgent } from './ButtonAgent'
|
|
13
14
|
import { ButtonBar } from './ButtonBar'
|
|
@@ -17,6 +18,7 @@ import { useMessageInputDictionary } from './dictionary'
|
|
|
17
18
|
import { QuickCommandSelector } from './QuickCommandSelector'
|
|
18
19
|
import { MAX_INPUT_HEIGHT, MessageInputBox, MIN_INPUT_HEIGHT } from './styled'
|
|
19
20
|
import { UploadBar } from './UploadBar'
|
|
21
|
+
import { UploadDragNDrop, useUploadDragDrop } from './UploadDragNDrop'
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* This renders the MessageInput part of the layout which includes the progress bar, the actual textarea, the badges telling what is
|
|
@@ -36,6 +38,13 @@ export const MessageInput = () => {
|
|
|
36
38
|
const agentLabel = useCurrentChatState('agent')?.label
|
|
37
39
|
const { handleKeyDown, handleKeyUp } = useUserEntryHistoryShortcut()
|
|
38
40
|
const isTrial = checkIsTrial()
|
|
41
|
+
const { isDragging, handleDrop, handleDragLeave } = useUploadDragDrop()
|
|
42
|
+
|
|
43
|
+
usePasteUpload({
|
|
44
|
+
textAreaRef,
|
|
45
|
+
onUploadFiles: files => chat.uploadManager.add(files),
|
|
46
|
+
enabled: !isLoading,
|
|
47
|
+
})
|
|
39
48
|
|
|
40
49
|
const checkSendRequirements = useCallback(() => {
|
|
41
50
|
if (chat.uploadManager.status === 'error') {
|
|
@@ -112,7 +121,11 @@ export const MessageInput = () => {
|
|
|
112
121
|
<ButtonAgent />
|
|
113
122
|
<AdaptiveTextArea
|
|
114
123
|
ref={textAreaRef}
|
|
115
|
-
placeholder={
|
|
124
|
+
placeholder={
|
|
125
|
+
agentLabel
|
|
126
|
+
? interpolate(t.placeholder, agentLabel)
|
|
127
|
+
: t.typing
|
|
128
|
+
}
|
|
116
129
|
onChange={e => chat.set('nextMessage', e.target.value)}
|
|
117
130
|
value={value}
|
|
118
131
|
onFocus={() => setFocused(true)}
|
|
@@ -131,6 +144,7 @@ export const MessageInput = () => {
|
|
|
131
144
|
{chat.get('features').upload && <UploadBar />}
|
|
132
145
|
<ButtonBar onSend={onSend} isLoading={isLoading} />
|
|
133
146
|
</MessageInputBox>
|
|
147
|
+
<UploadDragNDrop isDragging={isDragging} onDrop={handleDrop} onDragLeave={handleDragLeave} />
|
|
134
148
|
</UploadProvider>
|
|
135
149
|
)
|
|
136
150
|
}
|