Skip to content

Commit e5ef12f

Browse files
authored
Merge pull request #119 from iceljc/features/refine-chat-window
Features/refine chat window
2 parents 8d4778a + 1672a56 commit e5ef12f

File tree

16 files changed

+290
-83
lines changed

16 files changed

+290
-83
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: 4 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,8 +52,10 @@
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={''} />
56+
{#if !!file.file_name}
5657
<div class="item-text">{file.file_name}</div>
58+
{/if}
5759
</GalleryImage>
5860
{/each}
5961
</LightboxGallery>

src/lib/helpers/http.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,20 @@ axios.interceptors.response.use(
5454

5555
/** @param {import('axios').InternalAxiosRequestConfig<any>} config */
5656
function skipLoader(config) {
57-
let regex = new RegExp('http(s*)://(.*?)/conversation/(.*?)/(.*?)', 'g');
58-
if (config.method === 'post' && !!config.data && regex.test(config.url || '')) {
57+
const postRegexes = [
58+
new RegExp('http(s*)://(.*?)/conversation/(.*?)/(.*?)', 'g')
59+
];
60+
61+
const getRegexes = [
62+
new RegExp('http(s*)://(.*?)/address/options(.*?)', 'g'),
63+
new RegExp('http(s*)://(.*?)/conversation/(.*?)/files/(.*?)', 'g')
64+
];
65+
66+
if (config.method === 'post' && !!config.data && postRegexes.some(regex => regex.test(config.url || ''))) {
5967
return true;
6068
}
6169

62-
regex = new RegExp('http(s*)://(.*?)/address/options(.*?)', 'g');
63-
if (config.method === 'get' && regex.test(config.url || '')) {
70+
if (config.method === 'get' && getRegexes.some(regex => regex.test(config.url || ''))) {
6471
return true;
6572
}
6673

src/lib/helpers/store.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,22 @@ export const conversationUserMessageStore = createConversationUserMessageStore()
133133

134134

135135
const createConversationUserAttachmentStore = () => {
136+
const { subscribe, set } = writable({ accepted_files: [] });
137+
136138
return {
137139
reset: () => {
138140
localStorage.removeItem(conversationUserAttachmentKey);
141+
set({ accepted_files: [] });
139142
},
140143
get: () => {
141144
const json = localStorage.getItem(conversationUserAttachmentKey);
142145
return json ? JSON.parse(json) : {};
143146
},
144147
put: (value) => {
145148
localStorage.setItem(conversationUserAttachmentKey, JSON.stringify(value));
146-
}
149+
set(value);
150+
},
151+
subscribe
147152
}
148153
};
149154

src/lib/helpers/types.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,13 @@ 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.
278279
* @property {string} data - The message data.
279280
* @property {Date} created_at - The message sent time.
281+
* @property {boolean} is_load_images - Check of the message needs to load images.
280282
*/
281283

282284
/**

src/lib/scss/custom/components/_file.scss

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ $file-screen-max-width: 500px;
1515

1616
.gallery-item-wrapper {
1717
position: relative;
18+
width: 100%;
19+
height: 100%;
1820

1921
.gallery-item-icon {
2022
position: absolute;
21-
color: white;
23+
color: red;
2224
cursor: pointer;
23-
z-index: 1000;
25+
z-index: 500;
2426
right: 3px;
2527
font-size: 1.5em;
2628
}
@@ -72,4 +74,12 @@ $file-screen-max-width: 500px;
7274
.add-file-icon {
7375
font-size: 2em;
7476
}
77+
}
78+
79+
.chat-file-upload-gallery {
80+
margin: 5px 10px;
81+
display: flex;
82+
flex-wrap: wrap;
83+
gap: 3px;
84+
justify-content: center;
7585
}

src/lib/scss/custom/pages/_chat.scss

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,19 +387,26 @@
387387
background-color: var(--#{$prefix}light) !important;
388388
border-color: var(--#{$prefix}light) !important;
389389
resize: none;
390+
padding-right: 1rem;
391+
}
392+
393+
.chat-input-image {
394+
padding-right: 4em;
390395
}
391396

392397
.chat-input-links {
393398
position: absolute;
394-
right: 16px;
399+
right: 3px;
395400
top: 50%;
396401
transform: translateY(-50%);
402+
width: 3em;
397403
li {
398-
a {
404+
span {
399405
font-size: 16px;
400406
line-height: 36px;
401407
padding: 0px 4px;
402408
display: inline-block;
409+
color: var(--bs-primary);
403410
}
404411
}
405412
}

src/lib/services/api-endpoints.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const endpoints = {
4141
conversationCountUrl: `${host}/conversations/count`,
4242
conversationDeletionUrl: `${host}/conversation/{conversationId}`,
4343
conversationDetailUrl: `${host}/conversation/{conversationId}`,
44+
conversationAttachmentUrl: `${host}/conversation/{conversationId}/files/{messageId}`,
4445
dialogsUrl: `${host}/conversation/{conversationId}/dialogs`,
4546
conversationMessageDeletionUrl: `${host}/conversation/{conversationId}/message/{messageId}`,
4647

src/lib/services/conversation-service.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ export async function getConversations(filter) {
3737
return response.data;
3838
}
3939

40+
/**
41+
* Get conversation files
42+
* @param {string} conversationId
43+
* @param {string} messageId
44+
*/
45+
export async function getConversationFiles(conversationId, messageId) {
46+
const url = replaceUrl(endpoints.conversationAttachmentUrl, { conversationId: conversationId, messageId: messageId });
47+
const response = await axios.get(url);
48+
return response?.data;
49+
}
50+
4051
/**
4152
* Delete conversation
4253
* @param {string} conversationId
@@ -64,8 +75,9 @@ export async function GetDialogs(conversationId) {
6475
* @param {string} conversationId - The conversation id
6576
* @param {string} message - The text message sent to CSR
6677
* @param {import('$types').MessageData?} data - Additional data
78+
* @param {any[]} files - The chat files
6779
*/
68-
export async function sendMessageToHub(agentId, conversationId, message, data = null) {
80+
export async function sendMessageToHub(agentId, conversationId, message, data = null, files = []) {
6981
let url = replaceUrl(endpoints.conversationMessageUrl, {
7082
agentId: agentId,
7183
conversationId: conversationId
@@ -76,7 +88,8 @@ export async function sendMessageToHub(agentId, conversationId, message, data =
7688
text: message,
7789
truncateMessageId: data?.truncateMsgId,
7890
states: totalStates,
79-
postback: data?.postback
91+
postback: data?.postback,
92+
files: files
8093
});
8194
return response.data;
8295
}

0 commit comments

Comments
 (0)