Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share messages between tabs #75

Merged
merged 3 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Share messages between tabs
  • Loading branch information
petar-basic committed Aug 16, 2024
commit d7b77b1fe5213a78105dbc04c79f0e6b02099724
9 changes: 9 additions & 0 deletions packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ export class Rasa extends EventEmitter {
public reconnection(value: boolean): void {
this.connection.reconnection(value);
}

public overrideChatHistory = (chatHistoryString: string): void => {
this.storageService.overrideChatHistory(chatHistoryString);
this.loadChatHistory();
}

public getChatHistory(): string {
return JSON.stringify(this.storageService.getChatHistory());
}
//#endregion
}

Expand Down
22 changes: 15 additions & 7 deletions packages/sdk/src/services/storage.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ import { SESSION_STORAGE_KEYS } from '../constants';
import { CustomErrorClass, ErrorSeverity } from '../errors';

export class StorageService {
//#region Private Methods
private parseSessionStorageValue(value: string | null) {
if (!value) return null;
try {
return JSON.parse(value);
} catch (e) {
return null;
}
}
//#endregion

//#region Public Methods
public setSession(sessionId: string, sessionStart: Date): boolean {
const preservedHistory = this.getChatHistory() || {};
if (!preservedHistory[sessionId]) {
Expand Down Expand Up @@ -57,12 +69,8 @@ export class StorageService {
}
}

private parseSessionStorageValue(value: string | null) {
if (!value) return null;
try {
return JSON.parse(value);
} catch (e) {
return null;
}
public overrideChatHistory(chatHistory: string) {
sessionStorage.setItem(SESSION_STORAGE_KEYS.CHAT_HISTORY, chatHistory);
}
//#endregion
}
2 changes: 1 addition & 1 deletion packages/ui/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
<link rel="icon" type="image/png" sizes="16x16" href="https://rasa.com/favicon-16x16.png?v=210226" />
</head>
<body>
<rasa-chatbot-widget></rasa-chatbot-widget>
<rasa-chatbot-widget server-url="https://pro.vortexwe.com" sender-id="aaa"></rasa-chatbot-widget>
sava-vidakovic marked this conversation as resolved.
Show resolved Hide resolved
</body>
</html>
19 changes: 18 additions & 1 deletion packages/ui/src/rasa-chatbot-widget/rasa-chatbot-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { isValidURL } from '../utils/validate-url';
import { messageQueueService } from '../store/message-queue';
import { v4 as uuidv4 } from 'uuid';
import { widgetState } from '../store/widget-state-store';
import { broadcastChatHistoryEvent, receiveChatHistoryEvent } from '../utils/eventChannel';
import { debounce } from '../utils/debounce';

@Component({
tag: 'rasa-chatbot-widget',
Expand All @@ -19,6 +21,7 @@ export class RasaChatbotWidget {
private client: Rasa;
private messageDelayQueue: Promise<void> = Promise.resolve();
private disconnectTimeout: NodeJS.Timeout | null = null;
private sentMessage = false;

@Element() el: HTMLRasaChatbotWidgetElement;
@State() isOpen: boolean = false;
Expand Down Expand Up @@ -202,6 +205,12 @@ export class RasaChatbotWidget {
if (this.autoOpen) {
this.toggleOpenState();
}

if (this.senderId) {
window.onstorage = ev => {
receiveChatHistoryEvent(ev, this.client.overrideChatHistory, this.senderId);
};
}
}

private scrollToBottom(): void {
Expand All @@ -227,14 +236,20 @@ export class RasaChatbotWidget {
setTimeout(() => {
messageQueueService.enqueueMessage(data);
this.typingIndicator = false;
if (this.senderId && this.sentMessage) {
debounce(() => {
broadcastChatHistoryEvent(this.client.getChatHistory(), this.senderId);
this.sentMessage = false;
}, 1000)();
sava-vidakovic marked this conversation as resolved.
Show resolved Hide resolved
}
resolve();
}, delay);
});
});
};

private loadHistory = (data: Message[]): void => {
this.messageHistory = data;
this.messages = data;
};

private connect(): void {
Expand Down Expand Up @@ -281,6 +296,7 @@ export class RasaChatbotWidget {
this.chatWidgetSentMessage.emit(event.detail);
this.messages = [...this.messages, { type: 'text', text: event.detail, sender: 'user', timestamp }];
this.scrollToBottom();
this.sentMessage = true;
}

@Listen('quickReplySelected')
Expand All @@ -293,6 +309,7 @@ export class RasaChatbotWidget {
this.messages[key] = updatedMessage;
this.client.sendMessage({ text: quickReply.text, reply: quickReply.reply, timestamp }, true, key - 1);
this.chatWidgetQuickReply.emit(quickReply.reply);
this.sentMessage = true;
}

@Listen('linkClicked')
Expand Down
7 changes: 7 additions & 0 deletions packages/ui/src/utils/debounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const debounce = (fn: Function, ms = 300) => {
sava-vidakovic marked this conversation as resolved.
Show resolved Hide resolved
let timeoutId: ReturnType<typeof setTimeout>;
return function (this: any, ...args: any[]) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), ms);
};
};
13 changes: 13 additions & 0 deletions packages/ui/src/utils/eventChannel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const broadcastChatHistoryEvent = (chatHistory: string, senderID) => {
if (!senderID) return;
localStorage.setItem(`rasaChatHistory-${senderID}`, chatHistory);
localStorage.removeItem(`rasaChatHistory-${senderID}`);
};

export const receiveChatHistoryEvent = (ev, callback, senderID) => {
if (ev.key != `rasaChatHistory-${senderID}`) return;
var message = ev.newValue;
console.log(ev.newValue);
if (!message) return;
callback(ev.newValue);
};
sava-vidakovic marked this conversation as resolved.
Show resolved Hide resolved