import { IStorage, StudentStatusModel } from '@lenovo-software/lsa-clients-common'; import { LocalizeUtils } from '../common/localizeUtils'; import { Logger } from 'common/logger'; import { Starter } from './index'; export interface ChatWindowState { classId: string; handRaised: { isRaised: boolean; timestamp: number; }; doNotDisturb: boolean; } export interface WebViewParams { params: any; openWindow: boolean; } export class WebViewDispatcher { private chatWindowState: ChatWindowState; private msgQueue: Array; private webViewReady: boolean; private logger = Logger.getInstance(); constructor(private storage: IStorage) { this.msgQueue = []; this.webViewReady = false; chrome.runtime.onMessage.addListener((request) => { if (request.message) { switch (request.message) { case 'PolicyRequest': { chrome.runtime.sendMessage({ message: 'PolicyUpdate', policy: Starter.policy }); break; } case 'ChatWebViewReady': { chrome.runtime.sendMessage({ message: 'PolicyUpdate', policy: Starter.policy }); this.webViewReady = true; this.setChatWindowState(); } break; } } }); this.chatWindowState = { classId: '', handRaised: { isRaised: false, timestamp: 0 }, doNotDisturb: false }; } sendToWebView(params: any, openWindow: boolean) { this.msgQueue.push({ params: params, openWindow: openWindow }); if (this.webViewReady === true) { while (this.msgQueue.length > 0) { const t = this.msgQueue.shift(); if (t) { chrome.runtime.sendMessage({ message: 'ToWebView', params: t.params, openWindow: t.openWindow }); } } } } setChatWindowState() { this.setConnectivityStatusSupportInUI(); this.sendToWebViewDND(this.chatWindowState.doNotDisturb); // To make the raised hand persist across a webview restart, we need to wait // a few seconds so to make this next line functional we would need to wrap // this in a setTimeout() or queue the ToWebView message received at the // webview window. This is because the webview is not ready to receive the // raised hand state. It does, however, receive the DND and class ID just // fine immediately after it has started. // // The other problem with this next line is LSA-2051. If the hand is raised // and we keep sending a raised hand state to the webview, it will keep adding // a new "You have raised your hand" in the chat // window. Though this is an issue best addressed by the chat window code, // the previous incarnation of the client (with the backend living entirely // under the chat window) also did not persist the raised hand across webview // restarts, therefore we are no worse off with the current version of the // client where the webview is completely abstracted from the backend. // // sendToWebViewRaisedHand(chatWindowState.handRaised.isRaised); this.sendToWebViewClassId(this.chatWindowState.classId); this.setChatWindowLanguage(LocalizeUtils.getLanguage()); this.setChatWindowAPIServerAndOrgId( this.storage.loadAPIServer(), this.storage.loadProvisioningData()?.orgId || '' ); } setConnectivityStatusSupportInUI() { this.sendToWebView( { message: 'UI_SetState', state: { supportsConnectivityStatus: true, supportsConnectivityDetail: true, supportsDownloadLogs: true, supportsLearnMoreAboutStatus: true } }, false ); } sendToWebViewDND(dnd: boolean) { this.sendToWebView( { message: 'UI_SetState', state: { doNotDisturb: dnd } }, false ); } setChatDoNotDisturb(dnd: boolean) { this.chatWindowState.doNotDisturb = dnd; this.sendToWebViewDND(dnd); } sendToWebViewClassId(classID: string) { this.sendToWebView( { message: 'UI_SetState', state: { className: classID } }, false ); } setChatWindowLanguage(lang: string) { this.sendToWebView( { message: 'UI_SetState', state: { language: lang } }, false ); } setChatWindowAPIServerAndOrgId(apiServer: string, orgId: string) { this.sendToWebView( { message: 'UI_SetState', state: { provisioningData: { apiServer: apiServer, orgId: orgId } } }, false ); } updateConnectivityStatus(studentStatus: StudentStatusModel) { const param = { message: 'UI_SetConnectivityStatus', status: studentStatus }; this.sendToWebView(param, false); } }