import { Injectable } from '@angular/core'; import { ContextService, HttpService, PanelService, PanelType, OpenViduService, LoggerService } from 'projects/shared-meet-components/src/public-api'; import { OpenViduMeetMessage, ParentMessage, WebComponentActionType, WebComponentEventType } from 'webcomponent/src/types/message.type'; /** * Service to manage the commands from OpenVidu Meet WebComponent/Iframe. * This service listens for messages from the iframe and processes them. * It also sends messages to the iframe. */ @Injectable({ providedIn: 'root' }) export class WebComponentManagerService { protected isListenerStarted = false; protected log; constructor( protected loggerService: LoggerService, protected contextService: ContextService, protected panelService: PanelService, protected openviduService: OpenViduService, protected httpService: HttpService ) { this.log = this.loggerService.get('OpenVidu Meet - WebComponentManagerService'); } startCommandsListener(): void { if (this.isListenerStarted) return; this.isListenerStarted = true; // Listen for messages from the iframe window.addEventListener('message', async (event) => { const message: ParentMessage = event.data; const parentDomain = this.contextService.getParentDomain(); const { action, payload } = message; if (!parentDomain) { if (action === WebComponentActionType.INITIALIZE) { if (!payload || !('domain' in payload)) { console.error('Parent domain not provided in message payload'); return; } this.log.d(`Parent domain set: ${event.origin}`); this.contextService.setParentDomain(payload['domain']); } return; } if (event.origin !== parentDomain) { // console.warn(`Untrusted origin: ${event.origin}`); return; } console.debug('Message received from parent:', event.data); // TODO: reject if room is not connected switch (action) { case WebComponentActionType.END_MEETING: // Moderator only if (this.contextService.isModeratorParticipant()) { const roomId = this.contextService.getRoomId(); await this.httpService.deleteRoom(roomId); } break; case WebComponentActionType.TOGGLE_CHAT: // Toggle chat this.panelService.togglePanel(PanelType.CHAT); break; case WebComponentActionType.LEAVE_ROOM: // Leave room. await this.openviduService.disconnectRoom(); break; default: break; } }); } stopCommandsListener(): void { if (!this.isListenerStarted) return; this.isListenerStarted = false; window.removeEventListener('message', this.startCommandsListener); } sendMessageToParent(event: OpenViduMeetMessage /*| RoomDisconnectedEvent*/) { if (!this.contextService.isEmbeddedMode()) return; this.log.d('Sending message to parent :', event); const origin = this.contextService.getParentDomain(); window.parent.postMessage(event, origin); } }