Skip to content

Commit 4d70365

Browse files
author
Jicheng Lu
committed
refine file drop with limit
1 parent 8d4778a commit 4d70365

File tree

7 files changed

+65
-26
lines changed

7 files changed

+65
-26
lines changed

src/lib/common/FileDropZone.svelte

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@
3535
export let inputElement = undefined;
3636
export let required = false;
3737
export let dropText = "Drag and drop some files here, or click to select files";
38+
export let fileLimit = 5;
3839
3940
let innerDropText = dropText;
41+
let innerDisabled = disabled;
4042
let isLoading = false;
4143
let isError = false;
4244
let isSuccess = false;
@@ -48,16 +50,16 @@
4850
$: {
4951
if (isLoading) {
5052
innerDropText = "Uploading...";
51-
disabled = true;
53+
innerDisabled = true;
5254
} else if (isSuccess) {
5355
innerDropText = defaultSuccessMesssage;
54-
disabled = true;
56+
innerDisabled = true;
5557
} else if (isError) {
5658
innerDropText = reason;
57-
disabled = true;
59+
innerDisabled = true;
5860
} else {
5961
innerDropText = dropText;
60-
disabled = false;
62+
innerDisabled = disabled;
6163
}
6264
}
6365
@@ -225,9 +227,9 @@
225227
}
226228
227229
/** @type {any[]} */
228-
const acceptedFiles = [];
230+
let acceptedFiles = [];
229231
/** @type {any[]} */
230-
const fileRejections = [];
232+
let fileRejections = [];
231233
232234
/** @type {Promise<any>[]} */
233235
const promises = [];
@@ -236,12 +238,14 @@
236238
promises.push(new Promise((resolve, reject) => {
237239
const [accepted, acceptError] = fileAccepted(file, accept);
238240
const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
239-
getBase64(file).then(res => {
241+
getBase64(file).then(data => {
240242
if (accepted && sizeMatch) {
241243
acceptedFiles.push({
242244
file_name: file.name,
243245
file_path: file.path,
244-
url: res
246+
file_data: data,
247+
content_type: file.type,
248+
file_size: file.size
245249
});
246250
} else {
247251
const errors = [acceptError, sizeError].filter(Boolean);
@@ -254,6 +258,9 @@
254258
255259
Promise.all(promises).then(() => {
256260
isLoading = false;
261+
if (acceptedFiles.length >= fileLimit) {
262+
acceptedFiles = acceptedFiles.slice(0, Math.max(fileLimit, 0));
263+
}
257264
258265
if (!multiple && acceptedFiles.length > 1) {
259266
// Reject everything and empty accepted files
@@ -310,7 +317,7 @@
310317
resetState();
311318
}
312319
313-
$: composeHandler = (/** @type {any} */ fn) => (disabled ? null : fn);
320+
$: composeHandler = (/** @type {any} */ fn) => (innerDisabled ? null : fn);
314321
315322
$: composeKeyboardHandler = (/** @type {any} */ fn) => (noKeyboard ? null : composeHandler(fn));
316323

src/lib/common/FileGallery.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<i class="bx bx-trash" />
4444
</div>
4545
{/if}
46-
<img class="gallery-item-image" src={file.url} alt={''}>
46+
<img class="gallery-item-image" src={file.file_data} alt={''}>
4747
</div>
4848
</GalleryThumbnail>
4949
</div>
@@ -52,7 +52,7 @@
5252

5353
{#each files as file, idx (idx)}
5454
<GalleryImage title={file.file_name}>
55-
<img src={file.url} alt={''} />
55+
<img src={file.file_data} alt={''} />
5656
<div class="item-text">{file.file_name}</div>
5757
</GalleryImage>
5858
{/each}

src/lib/helpers/types.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ IRichContent.prototype.text;
272272
* @property {UserModel} sender - The message sender.
273273
* @property {string} message_id - The message id.
274274
* @property {string} text - The message content.
275+
* @property {string} editor - The message editor.
275276
* @property {string} function - The function name.
276277
* @property {RichContent} rich_content - Rich content.
277278
* @property {string} post_action_disclaimer - The message disclaimer.

src/lib/services/conversation-service.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ export async function GetDialogs(conversationId) {
6464
* @param {string} conversationId - The conversation id
6565
* @param {string} message - The text message sent to CSR
6666
* @param {import('$types').MessageData?} data - Additional data
67+
* @param {any[]} files - The chat files
6768
*/
68-
export async function sendMessageToHub(agentId, conversationId, message, data = null) {
69+
export async function sendMessageToHub(agentId, conversationId, message, data = null, files = []) {
6970
let url = replaceUrl(endpoints.conversationMessageUrl, {
7071
agentId: agentId,
7172
conversationId: conversationId
@@ -76,7 +77,8 @@ export async function sendMessageToHub(agentId, conversationId, message, data =
7677
text: message,
7778
truncateMessageId: data?.truncateMsgId,
7879
states: totalStates,
79-
postback: data?.postback
80+
postback: data?.postback,
81+
files: files
8082
});
8183
return response.data;
8284
}

src/routes/chat/[agentId]/[conversationId]/chat-box.svelte

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import _ from "lodash";
3131
import { Pane, Splitpanes } from 'svelte-splitpanes';
3232
import StateLog from './stateLogs/state-log.svelte';
33-
import ChatImage from './chatImage/chat-image.svelte';
3433
import Swal from 'sweetalert2/dist/sweetalert2.js';
3534
import "sweetalert2/src/sweetalert2.scss";
3635
import moment from 'moment';
@@ -273,6 +272,22 @@
273272
});
274273
}
275274
275+
function getChatFiles() {
276+
if (lastBotMsg?.rich_content?.editor !== EditorType.File) {
277+
return [];
278+
}
279+
280+
const attachments = conversationUserAttachmentStore.get();
281+
const files = attachments?.accepted_files || [];
282+
return files.map((/** @type {any} */ f) => {
283+
return {
284+
...f,
285+
conversation_id: params.conversationId,
286+
message_id: lastBotMsg?.message_id
287+
};
288+
});
289+
}
290+
276291
277292
/** @param {import('$types').ChatResponseModel} message */
278293
function onMessageReceivedFromClient(message) {
@@ -357,22 +372,26 @@
357372
isSendingMsg = true;
358373
clearEventLogs();
359374
renewUserSentMessages(msgText);
360-
361375
const postback = buildPostbackMessage(dialogs, data?.payload || msgText, data?.truncateMsgId);
362376
/** @type {import('$types').MessageData?} */
363377
const messageData = {
364378
...data,
365379
postback: postback
366380
};
367-
381+
382+
/** @type {any[]} */
383+
let files = [];
384+
if (!!!data?.truncateMsgId) {
385+
files = getChatFiles();
386+
}
387+
resetStorage();
388+
368389
return new Promise((resolve, reject) => {
369-
sendMessageToHub(params.agentId, params.conversationId, msgText, messageData).then(res => {
390+
sendMessageToHub(params.agentId, params.conversationId, msgText, messageData, files).then(res => {
370391
isSendingMsg = false;
371-
resetStorage();
372392
resolve(res);
373393
}).catch(err => {
374394
isSendingMsg = false;
375-
resetStorage();
376395
reject(err);
377396
});
378397
});

src/routes/chat/[agentId]/[conversationId]/chatImage/chat-attachment.svelte

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,28 @@
1515
1616
/** @type {any[]} */
1717
let files = [];
18-
1918
/** @type {any} */
2019
let confirmOption;
2120
/** @type {any} */
2221
let cancelOption;
22+
/** @type {boolean} */
23+
let disableFileDrop = false;
24+
/** @type {number} */
25+
let fileUploadLimit = 0;
26+
27+
const fileUpperLimit = 5;
2328
2429
onMount(() => {
2530
collectOptions(options);
2631
const savedAttachments = conversationUserAttachmentStore.get();
27-
files = savedAttachments.acceptedFiles || [];
32+
files = savedAttachments.accepted_files || [];
2833
});
2934
35+
$: {
36+
disableFileDrop = disabled || files.length >= fileUpperLimit;
37+
fileUploadLimit = Math.max(fileUpperLimit - files.length, 0);
38+
}
39+
3040
3141
/** @param {any[]} options */
3242
function collectOptions(options) {
@@ -69,9 +79,9 @@
6979
async function handleFileDrop(e) {
7080
const { acceptedFiles } = e.detail;
7181
const savedAttachments = conversationUserAttachmentStore.get();
72-
const newAttachments = [...savedAttachments.acceptedFiles || [], ...acceptedFiles];
82+
const newAttachments = [...savedAttachments.accepted_files || [], ...acceptedFiles];
7383
conversationUserAttachmentStore.put({
74-
acceptedFiles: newAttachments
84+
accepted_files: newAttachments
7585
});
7686
files = newAttachments;
7787
}
@@ -80,15 +90,15 @@
8090
function deleteFile(index) {
8191
files = files?.filter((f, idx) => idx !== index) || [];
8292
conversationUserAttachmentStore.put({
83-
acceptedFiles: files
93+
accepted_files: files
8494
});
8595
}
8696
</script>
8797
8898
<div style="display: block; margin-top: 3px;">
8999
<div style="display: flex; flex-wrap: wrap; gap: 3px;">
90100
<FileGallery files={files} disabled={disabled} needDelete onDelete={deleteFile} />
91-
<FileDropZone accept="image/*" disabled={disabled} on:drop={e => handleFileDrop(e)} />
101+
<FileDropZone accept="image/*" disabled={disableFileDrop} fileLimit={fileUploadLimit} on:drop={e => handleFileDrop(e)} />
92102
</div>
93103
</div>
94104

src/routes/chat/[agentId]/[conversationId]/chatImage/chat-image.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
export let message;
66
</script>
77

8-
{#if message?.data && typeof message.data === 'string' && message.data.includes('data:image/png;base64,')}
8+
{#if message?.data && typeof message.data === 'string' && message.data.startsWith('data:image/png;base64,')}
99
<div class="image-wrap">
1010
<Lightbox transitionDuration={100}>
1111
<img src={message.data} alt={''} class="rounded img-fluid" />

0 commit comments

Comments
 (0)