Skip to content

Commit c3fc6df

Browse files
authored
Merge pull request #120 from iceljc/features/refine-chat-window
Features/refine chat window
2 parents e5ef12f + a312a70 commit c3fc6df

File tree

9 files changed

+133
-68
lines changed

9 files changed

+133
-68
lines changed

src/lib/common/FileGallery.svelte

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@
1313
/** @type {(args0: number) => void} */
1414
export let onDelete = () => {};
1515
16+
/** @type {string} */
17+
export let containerClasses = "";
18+
19+
/** @type {string} */
20+
export let containerStyles = "";
21+
22+
/** @type {boolean} */
23+
export let disableDefaultStyles = false;
24+
1625
/**
1726
* @param {any} e
1827
* @param {number} idx
@@ -26,6 +35,10 @@
2635
</script>
2736

2837
{#if files?.length > 0}
38+
<div
39+
class="{disableDefaultStyles ? '' : 'file-gallery-list'} {containerClasses}"
40+
style={`${containerStyles}`}
41+
>
2942
<LightboxGallery transitionDuration={100}>
3043
<svelte:fragment slot="thumbnail">
3144
{#each files as file, idx (idx)}
@@ -59,4 +72,5 @@
5972
</GalleryImage>
6073
{/each}
6174
</LightboxGallery>
62-
{/if}
75+
</div>
76+
{/if}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script>
2+
import { onMount } from 'svelte';
3+
import FileGallery from '$lib/common/FileGallery.svelte';
4+
import { getUserStore } from '$lib/helpers/store';
5+
import { PUBLIC_SERVICE_URL } from '$env/static/public';
6+
7+
/** @type {string} */
8+
export let galleryClasses = '';
9+
10+
/** @type {string} */
11+
export let galleryStyles = '';
12+
13+
/** @type {() => Promise<any>} */
14+
export let fetchFiles = () => Promise.resolve([]);
15+
16+
/** @type {any[]} */
17+
let files = [];
18+
/** @type {string} */
19+
let token = "";
20+
21+
onMount(() => {
22+
const user = getUserStore();
23+
token = user.token;
24+
if (fetchFiles != null && fetchFiles != undefined) {
25+
fetchFiles().then(data => {
26+
// @ts-ignore
27+
files = data?.filter(item => !!item.file_url)?.map(item => {
28+
return {
29+
...item,
30+
file_data: `${PUBLIC_SERVICE_URL}${item.file_url}?access_token=${token}`
31+
};
32+
}) || [];
33+
});
34+
}
35+
});
36+
</script>
37+
38+
<div>
39+
<FileGallery
40+
containerClasses={galleryClasses}
41+
containerStyles={galleryStyles}
42+
files={files}
43+
/>
44+
</div>

src/lib/helpers/constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ export const USER_SENDERS = [
44
UserRole.Admin,
55
UserRole.User,
66
UserRole.Client
7+
];
8+
9+
export const BOT_SENDERS = [
10+
UserRole.Assistant
711
];

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,17 @@ $file-screen-max-width: 500px;
7676
}
7777
}
7878

79-
.chat-file-upload-gallery {
80-
margin: 5px 10px;
79+
.file-gallery-list {
80+
margin: 5px 0px;
8181
display: flex;
8282
flex-wrap: wrap;
8383
gap: 3px;
84-
justify-content: center;
84+
justify-content: flex-start;
85+
}
86+
87+
.dialog-file-display {
88+
.gallery-item {
89+
width: $attachment-width-lite;
90+
height: $attachment-height-lite;
91+
}
8592
}

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

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,28 @@
55
DropdownMenu,
66
DropdownItem,
77
} from '@sveltestrap/sveltestrap';
8+
import {
9+
conversationStore,
10+
conversationUserStateStore,
11+
conversationUserMessageStore,
12+
conversationUserAttachmentStore
13+
} from '$lib/helpers/store.js';
14+
import {
15+
sendMessageToHub,
16+
GetDialogs,
17+
deleteConversationMessage,
18+
getConversationFiles
19+
} from '$lib/services/conversation-service.js';
820
import 'overlayscrollbars/overlayscrollbars.css';
921
import { OverlayScrollbars } from 'overlayscrollbars';
1022
import { page } from '$app/stores';
1123
import { onMount, setContext, tick } from 'svelte';
1224
import Viewport from 'svelte-viewport-info';
1325
import { PUBLIC_LIVECHAT_ENTRY_ICON } from '$env/static/public';
14-
import { USER_SENDERS } from '$lib/helpers/constants';
26+
import { BOT_SENDERS, USER_SENDERS } from '$lib/helpers/constants';
1527
import { signalr } from '$lib/services/signalr-service.js';
1628
import { webSpeech } from '$lib/services/web-speech.js';
17-
import { sendMessageToHub, GetDialogs, deleteConversationMessage } from '$lib/services/conversation-service.js';
1829
import { newConversation } from '$lib/services/conversation-service';
19-
import { conversationStore, conversationUserStateStore, conversationUserMessageStore, conversationUserAttachmentStore } from '$lib/helpers/store.js';
2030
import DialogModal from '$lib/common/DialogModal.svelte';
2131
import HeadTitle from '$lib/common/HeadTitle.svelte';
2232
import LoadingDots from '$lib/common/LoadingDots.svelte';
@@ -27,7 +37,7 @@
2737
import { EditorType, SenderAction, UserRole } from '$lib/helpers/enums';
2838
import RichContent from './richContent/rich-content.svelte';
2939
import RcDisclaimer from './richContent/rc-disclaimer.svelte';
30-
import MessageImageGallery from './chatImage/message-image-gallery.svelte';
40+
import MessageImageGallery from '$lib/common/MessageImageGallery.svelte';
3141
import ChatImageUploader from './chatImage/chat-image-uploader.svelte';
3242
import ChatImageGallery from './chatImage/chat-image-gallery.svelte';
3343
import ContentLog from './contentLogs/content-log.svelte';
@@ -38,7 +48,6 @@
3848
import "sweetalert2/src/sweetalert2.scss";
3949
import moment from 'moment';
4050
41-
4251
const options = {
4352
scrollbars: {
4453
visibility: 'auto',
@@ -161,7 +170,7 @@
161170
162171
/** @param {import('$types').ChatResponseModel[]} dialogs */
163172
function initUserSentMessages(dialogs) {
164-
const curConvMessages = dialogs?.filter(x => x.sender?.role != UserRole.Assistant).map(x => {
173+
const curConvMessages = dialogs?.filter(x => USER_SENDERS.includes(x.sender?.role || '')).map(x => {
165174
return {
166175
conversationId: params.conversationId,
167176
text: x.text || ''
@@ -212,7 +221,7 @@
212221
/** @param {import('$types').ChatResponseModel[]} dialogs */
213222
function findLastBotMessage(dialogs) {
214223
const lastMsg = dialogs.slice(-1)[0];
215-
return lastMsg?.sender?.role === UserRole.Assistant ? lastMsg : null;
224+
return BOT_SENDERS.includes(lastMsg?.sender?.role || '') ? lastMsg : null;
216225
}
217226
218227
async function refresh() {
@@ -247,15 +256,10 @@
247256
continue;
248257
}
249258
250-
const botMsgId = dialogs.findLastIndex((x, i) => i < idx && !USER_SENDERS.includes(x.sender?.role || ''));
251-
if (botMsgId > -1 && dialogs[botMsgId]?.rich_content?.editor === EditorType.File) {
252-
const userMsgs = dialogs.filter(x => x.message_id === curMsg.message_id && USER_SENDERS.includes(x.sender?.role || ''));
253-
if (userMsgs?.length > 1) {
254-
const userMsg = userMsgs.slice(-1)[0];
255-
userMsg.is_load_images = true;
256-
} else {
257-
curMsg.is_load_images = true;
258-
}
259+
const prevMsg = dialogs[idx-1];
260+
if (!!prevMsg && BOT_SENDERS.includes(prevMsg?.sender?.role || '')
261+
&& prevMsg?.rich_content?.editor === EditorType.File) {
262+
curMsg.is_load_images = true;
259263
}
260264
}
261265
}
@@ -506,7 +510,7 @@
506510
507511
if (!!lastMsg?.rich_content?.fill_postback
508512
&& !!lastMsg?.function
509-
&& lastMsg?.sender?.role === UserRole.Assistant) {
513+
&& BOT_SENDERS.includes(lastMsg?.sender?.role || '')) {
510514
postback = {
511515
functionName: lastMsg?.function,
512516
parentId: lastMsg?.message_id,
@@ -947,7 +951,10 @@
947951
<RcDisclaimer content={message.post_action_disclaimer} />
948952
{/if}
949953
{#if message.is_load_images}
950-
<MessageImageGallery message={message} />
954+
<MessageImageGallery
955+
galleryStyles={'justify-content: flex-end;'}
956+
fetchFiles={() => getConversationFiles(params.conversationId, message.message_id)}
957+
/>
951958
{/if}
952959
</div>
953960
{#if !isLite}

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@
3434
</script>
3535
3636
<div>
37-
<div class="chat-file-upload-gallery">
38-
<FileGallery files={files} disabled={disabled} needDelete onDelete={deleteFile} />
39-
</div>
37+
<FileGallery
38+
containerStyles={'justify-content: center; margin: 5px 10px;'}
39+
files={files}
40+
disabled={disabled}
41+
needDelete
42+
onDelete={deleteFile} />
4043
</div>
4144

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

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/routes/chat/[agentId]/[conversationId]/richContent/rich-content.svelte

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import RcComplexOptions from "./rc-complex-options.svelte";
55
import RcMessage from "./rc-message.svelte";
66
import ChatAttachmentOptions from "../chatImage/chat-attachment-options.svelte";
7-
import FileGallery from "$lib/common/FileGallery.svelte";
87
98
/** @type {any} */
109
export let message;
@@ -61,10 +60,6 @@
6160
<ChatAttachmentOptions options={options} disabled={disabled} onConfirm={handleConfirm} />
6261
{/if}
6362
64-
{#if message.message_id !== lastBotMessage?.message_id}
65-
<FileGallery files={message.files} />
66-
{/if}
67-
6863
{#if message.message_id === lastBotMessage?.message_id && !disabled && lastBotMessage?.rich_content?.editor !== EditorType.File}
6964
{#if !isComplexElement}
7065
<RcPlainOptions options={options} isMultiSelect={isMultiSelect} disabled={disabled} onConfirm={handleConfirm} />

src/routes/page/conversation/[conversationId]/conv-dialogs.svelte

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<script>
22
import { Card, CardBody, CardTitle, Col, Row } from '@sveltestrap/sveltestrap';
33
import Link from 'svelte-link/src/Link.svelte';
4-
import { GetDialogs } from '$lib/services/conversation-service.js';
4+
import { GetDialogs, getConversationFiles } from '$lib/services/conversation-service.js';
55
import { utcToLocal } from '$lib/helpers/datetime';
66
import { onMount } from 'svelte';
77
import { _ } from 'svelte-i18n'
8-
import { USER_SENDERS } from '$lib/helpers/constants';
8+
import { BOT_SENDERS, USER_SENDERS } from '$lib/helpers/constants';
9+
import { EditorType } from '$lib/helpers/enums';
910
import Markdown from '$lib/common/Markdown.svelte';
11+
import MessageImageGallery from '$lib/common/MessageImageGallery.svelte';
1012
1113
/** @type {import('$types').ChatResponseModel[]} */
1214
let dialogs = [];
@@ -16,8 +18,27 @@
1618
1719
onMount(async () => {
1820
dialogs = await GetDialogs(conversation.id);
21+
loadMessageImages(dialogs);
1922
});
2023
24+
/** @param {import('$types').ChatResponseModel[]} dialogs */
25+
function loadMessageImages(dialogs) {
26+
if (!!!dialogs) return;
27+
28+
for (let idx = 0; idx < dialogs.length; idx++) {
29+
const curMsg = dialogs[idx];
30+
if (!USER_SENDERS.includes(curMsg?.sender?.role || '')) {
31+
continue;
32+
}
33+
34+
const prevMsg = dialogs[idx-1];
35+
if (!!prevMsg && BOT_SENDERS.includes(prevMsg?.sender?.role || '')
36+
&& prevMsg?.rich_content?.editor === EditorType.File) {
37+
curMsg.is_load_images = true;
38+
}
39+
}
40+
}
41+
2142
/**
2243
* @param {import('$types').ChatResponseModel} dialog
2344
* @returns {boolean}
@@ -67,6 +88,12 @@
6788
<p class="fw-bold">
6889
<Markdown text={dialog?.rich_content?.message?.text || dialog?.text} />
6990
</p>
91+
{#if dialog.is_load_images}
92+
<MessageImageGallery
93+
galleryClasses={'dialog-file-display'}
94+
fetchFiles={() => getConversationFiles(conversation.id, dialog.message_id)}
95+
/>
96+
{/if}
7097
</div>
7198
{#if dialog.message_id}
7299
<div>

0 commit comments

Comments
 (0)