Skip to content

Commit 93021f3

Browse files
authored
Merge pull request #230 from iceljc/features/refine-chat-window
add like message
2 parents 1187c03 + 8e710db commit 93021f3

File tree

8 files changed

+124
-52
lines changed

8 files changed

+124
-52
lines changed

src/lib/common/LiveChatEntry.svelte

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,20 @@
1010
1111
onMount(async () => {
1212
const agentSettings = await getSettingDetail("Agent");
13-
chatUrl = `${PUBLIC_LIVECHAT_HOST}chat/${agentSettings.hostAgentId}?isFrame=true`;
13+
chatUrl = `${PUBLIC_LIVECHAT_HOST}chat/${agentSettings.hostAgentId}`;
1414
});
1515
1616
// Handle event from iframe
1717
window.onmessage = async function(e) {
1818
if (e.data.action == 'close') {
19-
chatBotStore.set({
20-
showChatBox: false
21-
});
19+
chatBotStore.set({ showChatBox: false });
20+
} else if (e.data.action == 'open') {
21+
chatBotStore.set({ showChatBox: true });
2222
}
2323
};
2424
2525
function openChatBox() {
26-
chatBotStore.set({
27-
showChatBox: true
28-
});
26+
chatBotStore.set({ showChatBox: true });
2927
}
3028
</script>
3129

@@ -51,7 +49,6 @@
5149
src={chatUrl}
5250
width="0px"
5351
height="0px"
54-
class={`border border-2 rounded-3 m-3 float-end chat-iframe`}
5552
title="live chat"
5653
id={CHAT_FRAME_ID}
5754
/>

src/lib/common/ProfileDropdown.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import { PUBLIC_SERVICE_URL } from '$env/static/public';
88
import { _ } from 'svelte-i18n';
99
import { buildUrl } from '$lib/helpers/utils/common';
10+
import { ChatAction } from '$lib/helpers/enums';
1011
1112
/** @type {any} */
1213
export let user;
@@ -19,7 +20,7 @@
1920
const chatFrame = document.getElementById('chat-frame');
2021
if (chatFrame) {
2122
// @ts-ignore
22-
chatFrame.contentWindow.postMessage({ action: "logout" }, "*");
23+
chatFrame.contentWindow.postMessage({ action: ChatAction.Logout }, "*");
2324
}
2425
2526
goto('login');

src/lib/common/audio-player/AudioSpeaker.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@
8484
<!-- svelte-ignore a11y-click-events-have-key-events -->
8585
<!-- svelte-ignore a11y-no-static-element-interactions -->
8686
<div
87-
class="{disableDefaultStyles ? '' : 'chat-speaker-container'} {containerClasses}"
87+
class="{disableDefaultStyles ? '' : 'chat-speaker-container'} line-align-center {containerClasses}"
8888
style={`${containerStyles}`}
8989
>
90-
<span style="display: inline-block;" on:click={() => speak()}>
90+
<div on:click={() => speak()}>
9191
{#if !speaking}
92-
<i class="bx bx-volume-full" />
92+
<i class="bx bx-volume-full clickable" />
9393
{:else}
9494
<Stretch unit='px' size='5' gap='5' color="var(--bs-primary)" />
9595
{/if}
96-
</span>
96+
</div>
9797
</div>

src/lib/helpers/enums.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,11 @@ const knowledgeDocSource = {
9898
User: 'user',
9999
Web: 'web'
100100
};
101-
export const KnowledgeDocSource = Object.freeze(knowledgeDocSource);
101+
export const KnowledgeDocSource = Object.freeze(knowledgeDocSource);
102+
103+
const chatAction = {
104+
Logout: 'logout',
105+
Chat: 'chat',
106+
NewChat: 'new-chat'
107+
};
108+
export const ChatAction = Object.freeze(chatAction);

src/lib/helpers/utils/chat.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/**
2+
* @param {string} action
23
* @param {string} chatFrameId
3-
* @param {string} text
4+
* @param {string | null} text
45
* @param {import('$conversationTypes').MessageData | null} data
56
*/
6-
export function sendToChatBot(chatFrameId, text, data = null) {
7+
export function sendToChatBot(action, chatFrameId, text = null, data = null) {
78
const chatFrame = document.getElementById(chatFrameId);
8-
const content = { action: "chat", text: text, data: data };
9+
const content = { action: action, text: text, data: data };
910

1011
if (chatFrame) {
1112
// @ts-ignore

src/routes/chat/[agentId]/+page.svelte

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,15 @@
4040
}
4141
4242
conversationId = conversation.id;
43-
let chatUrl = `chat/${agentId}/${conversationId}`;
44-
let query = "";
45-
43+
const chatUrl = new URL(`chat/${agentId}/${conversationId}`, window.location.origin);
44+
45+
const searchParams = new URLSearchParams();
4646
if (agentId === LERNER_ID) {
47-
query += `mode=${TRAINING_MODE}`;
48-
}
49-
50-
const isFrame = $page.url.searchParams.get('isFrame');
51-
if (isFrame === 'true') {
52-
query += "isFrame=true";
53-
}
54-
55-
if (!!query) {
56-
chatUrl = `${chatUrl}?${query}`;
47+
searchParams.append('mode', TRAINING_MODE);
5748
}
5849
59-
window.location.href = chatUrl;
50+
chatUrl.search = searchParams?.toString();
51+
window.location.href = chatUrl.toString();
6052
});
6153
</script>
6254

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

Lines changed: 91 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
import { utcToLocal } from '$lib/helpers/datetime';
4949
import { replaceNewLine } from '$lib/helpers/http';
5050
import { isAudio, isExcel, isPdf } from '$lib/helpers/utils/file';
51-
import { EditorType, FileSourceType, SenderAction, UserRole } from '$lib/helpers/enums';
51+
import { ChatAction, EditorType, FileSourceType, SenderAction, UserRole } from '$lib/helpers/enums';
5252
import RichContent from './rich-content/rich-content.svelte';
5353
import RcMessage from "./rich-content/rc-message.svelte";
5454
import RcDisclaimer from './rich-content/rc-disclaimer.svelte';
@@ -59,6 +59,7 @@
5959
import ChatBigMessage from './chat-util/chat-big-message.svelte';
6060
import PersistLog from './persist-log/persist-log.svelte';
6161
import InstantLog from './instant-log/instant-log.svelte';
62+
import Loader from '$lib/common/Loader.svelte';
6263
6364
6465
const options = {
@@ -155,6 +156,7 @@
155156
let disableAction = false;
156157
let loadChatUtils = false;
157158
let disableSpeech = false;
159+
let isLoading = false;
158160
159161
160162
$: {
@@ -196,19 +198,38 @@
196198
refresh();
197199
autoScrollLog = false;
198200
199-
window.addEventListener('message', e => {
200-
if (e.data.action === 'logout') {
201+
window.addEventListener('message', async e => {
202+
if (e.data.action === ChatAction.Logout) {
201203
resetLocalStorage(true);
204+
return;
202205
}
203206
204-
if (e.data.action === 'chat' && !isThinking && !isSendingMsg) {
205-
sendChatMessage(e.data.text, e.data.data || null);
207+
if (e.data.action === ChatAction.NewChat) {
208+
const conv = await createNewConversation();
209+
if (!!e.data.text && !isThinking && !isSendingMsg) {
210+
isLoading = true;
211+
sendChatMessage(e.data.text, e.data.data || null, conv.id).then(() => {
212+
redirectToNewConversation(conv);
213+
isLoading = false;
214+
openFrame();
215+
});
216+
}
217+
return;
218+
}
219+
220+
if (e.data.action === ChatAction.Chat && !!e.data.text && !isThinking && !isSendingMsg) {
221+
sendChatMessage(e.data.text, e.data.data || null).then(() => {
222+
openFrame();
223+
});
224+
return;
206225
}
207226
});
208-
209-
// window.parent.postMessage({ event: "chat-box-mounted" }, "*");
210227
});
211228
229+
function openFrame() {
230+
window.parent.postMessage({ action: "open" }, "*");
231+
}
232+
212233
function resizeChatWindow() {
213234
isLite = Viewport.Width <= screenWidthThreshold;
214235
if (!isLite) {
@@ -223,7 +244,7 @@
223244
}
224245
225246
function initChatView() {
226-
isFrame = $page.url.searchParams.get('isFrame') === 'true';
247+
isFrame = window.location != window.parent.location;
227248
mode = $page.url.searchParams.get('mode') || '';
228249
// initial condition
229250
isPersistLogClosed = false;
@@ -434,10 +455,22 @@
434455
}
435456
436457
async function handleNewConversation() {
458+
const conv = await createNewConversation();
459+
redirectToNewConversation(conv);
460+
}
461+
462+
async function createNewConversation() {
437463
const conversation = await newConversation(params.agentId);
438464
conversationStore.set(conversation);
439-
const url = `chat/${params.agentId}/${conversation.id}`;
440-
window.location.href = url;
465+
return conversation;
466+
}
467+
468+
/** @param {import('$conversationTypes').ConversationModel} conversation */
469+
function redirectToNewConversation(conversation) {
470+
const url = new URL(`chat/${params.agentId}/${conversation.id}`, window.location.origin);
471+
const searchParams = $page.url.searchParams;
472+
url.search = searchParams?.toString();
473+
window.location.href = url.toString();
441474
}
442475
443476
function handleSaveKnowledge() {
@@ -447,8 +480,9 @@
447480
/**
448481
* @param {string} msgText
449482
* @param {import('$conversationTypes').MessageData?} data
483+
* @param {string?} conversationId
450484
*/
451-
function sendChatMessage(msgText, data = null) {
485+
function sendChatMessage(msgText, data = null, conversationId = null) {
452486
isSendingMsg = true;
453487
autoScrollLog = true;
454488
clearInstantLogs();
@@ -475,7 +509,7 @@
475509
if (files?.length > 0 && !!!messageData.inputMessageId) {
476510
const filePayload = buildFilePayload(files);
477511
return new Promise((resolve, reject) => {
478-
uploadConversationFiles(params.agentId, params.conversationId, files).then(resMessageId => {
512+
uploadConversationFiles(params.agentId, conversationId || params.conversationId, files).then(resMessageId => {
479513
messageData = { ...messageData, inputMessageId: resMessageId };
480514
if (!!filePayload) {
481515
messageData = {
@@ -488,7 +522,7 @@
488522
};
489523
}
490524
491-
sendMessageToHub(params.agentId, params.conversationId, msgText, messageData).then(res => {
525+
sendMessageToHub(params.agentId, conversationId || params.conversationId, msgText, messageData).then(res => {
492526
resolve(res);
493527
}).catch(err => {
494528
reject(err);
@@ -514,7 +548,7 @@
514548
};
515549
}
516550
517-
sendMessageToHub(params.agentId, params.conversationId, msgText, messageData).then(res => {
551+
sendMessageToHub(params.agentId, conversationId || params.conversationId, msgText, messageData).then(res => {
518552
resolve(res);
519553
}).catch(err => {
520554
reject(err);
@@ -524,7 +558,7 @@
524558
});
525559
});
526560
} else {
527-
sendMessageToHub(params.agentId, params.conversationId, msgText, messageData).then(res => {
561+
sendMessageToHub(params.agentId, conversationId || params.conversationId, msgText, messageData).then(res => {
528562
resolve(res);
529563
}).catch(err => {
530564
reject(err);
@@ -1007,11 +1041,34 @@
10071041
bigText = '';
10081042
sendChatMessage(text);
10091043
}
1044+
1045+
/**
1046+
* @param {any} e
1047+
* @param {any} message
1048+
*/
1049+
function likeMessage(e, message) {
1050+
e.preventDefault();
1051+
1052+
const text = 'I like this message.';
1053+
const data = {
1054+
postback: {
1055+
functionName: 'like_response',
1056+
payload: 'I really like this message!',
1057+
parentId: message?.id
1058+
},
1059+
states: []
1060+
};
1061+
sendChatMessage(text, data);
1062+
}
10101063
</script>
10111064
10121065
10131066
<svelte:window on:resize={() => resizeChatWindow()}/>
10141067
1068+
{#if isLoading}
1069+
<Loader size={35} />
1070+
{/if}
1071+
10151072
<DialogModal
10161073
title={'Edit message'}
10171074
size={'md'}
@@ -1221,10 +1278,25 @@
12211278
<div class="msg-container">
12221279
<RcMessage message={message} />
12231280
{#if message?.message_id === lastBotMsg?.message_id}
1224-
<AudioSpeaker
1225-
id={message?.message_id}
1226-
text={message?.rich_content?.message?.text || message?.text}
1227-
/>
1281+
<div style="display: flex; gap: 10px;">
1282+
<AudioSpeaker
1283+
id={message?.message_id}
1284+
text={message?.rich_content?.message?.text || message?.text}
1285+
/>
1286+
<div class="line-align-center" style="font-size: 17px;">
1287+
<!-- svelte-ignore a11y-click-events-have-key-events -->
1288+
<!-- svelte-ignore a11y-no-static-element-interactions -->
1289+
<div
1290+
class="clickable"
1291+
style="height: 95%;"
1292+
on:click={e => likeMessage(e, message)}
1293+
>
1294+
<i
1295+
class="mdi mdi-thumb-up-outline text-primary"
1296+
/>
1297+
</div>
1298+
</div>
1299+
</div>
12281300
{/if}
12291301
{#if !!message.is_chat_message || !!message.has_message_files}
12301302
<MessageFileGallery

src/routes/page/plugin/plugin-list.svelte

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
import { installPlugin, removePlugin } from '$lib/services/plugin-service';
1111
import Swal from 'sweetalert2';
1212
import { sendToChatBot } from '$lib/helpers/utils/chat';
13-
1413
import { CHAT_FRAME_ID } from '$lib/helpers/constants';
14+
import { ChatAction } from '$lib/helpers/enums';
1515
1616
/** @type {import('$pluginTypes').PluginDefModel[]} */
1717
export let plugins;
@@ -59,7 +59,9 @@
5959
},
6060
states: []
6161
};
62-
sendToChatBot(CHAT_FRAME_ID, text, data);
62+
// ChatAction.Chat: send to current chat
63+
// ChatAction.NewChat: init a new conversation, and then send the message
64+
sendToChatBot(ChatAction.Chat, CHAT_FRAME_ID, text, data);
6365
}
6466
</script>
6567

0 commit comments

Comments
 (0)