mediasfu-angular 2.2.3 → 2.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, Input, Optional, Inject, Component, ViewChild, HostListener, Injector, EventEmitter, Output, ContentChildren, forwardRef, ViewEncapsulation, InjectionToken, TemplateRef, Directive } from '@angular/core';
3
- import { joinConsumeRoom, producerClosed, newPipeProducer, getOverlayPosition as getOverlayPosition$1, translationRoomConfig, translationConfigUpdated, translationLanguageSet, translationSubscribed, translationUnsubscribed, translationProducerReady, translationProducerClosed, translationChannelsAvailable, translationMemberState, translationError, translationTranscript, translationSpeakerOutputChanged, controlMedia, isSubtitleExpired, autoAdjust, calculateRowsAndColumns, changeVids, checkGrid, checkPermission, checkScreenShare, closeAndResize, compareActiveNames, compareScreenStates, connectIps, connectLocalIps, connectRecvTransport, connectSendTransport, connectSendTransportAudio, connectSendTransportScreen, connectSendTransportVideo, createSendTransport, disconnectSendTransportAudio, disconnectSendTransportVideo, disconnectSendTransportScreen, dispStreams, generatePageContent, getEstimate, getPipedProducersAlt, getProducersPiped, getVideos, mixStreams, onScreenChanges, processConsumerTransports, processConsumerTransportsAudio, readjust, receiveAllPipedTransports, reorderStreams, rePort, requestScreenShare, resumePauseAudioStreams, resumePauseStreams, resumeSendTransportAudio, reUpdateInter, signalNewConsumerTransport, startShareScreen, stopShareScreen, streamSuccessAudio, streamSuccessAudioSwitch, streamSuccessScreen, switchUserAudio, clickVideo, switchUserVideo, switchUserVideoAlt, trigger, updateMiniCardsGrid, updateParticipantAudioDecibels, aParams, hParams, screenParams, vParams, launchBackground, launchBreakoutRooms, breakoutRoomUpdated, launchCoHost as launchCoHost$1, modifyCoHostSettings, launchDisplaySettings, modifyDisplaySettings, launchConfirmExit, confirmExit, launchMediaSettings, launchMenuModal, launchMessages, sendMessage, launchParticipants, messageParticipants, muteParticipants, removeParticipants, handleCreatePoll, handleEndPoll, handleVotePoll, launchPoll, pollUpdated, checkPauseState, checkResumeState, confirmRecording, launchRecording, recordPauseTimer, recordResumeTimer, recordStartTimer, recordUpdateTimer, startRecording, stopRecording, updateRecording, launchRequests, respondToRequests, launchSettings, modifySettings, clickAudio, clickChat, clickScreenShare, switchAudio, switchVideo, switchVideoAlt, joinRoomOnMediaSFU, formatNumber, getModalPosition as getModalPosition$1, sleep as sleep$1, validateAlphanumeric, launchWaiting, respondToWaiting, launchConfigureWhiteboard, createDeviceClient, joinRoomClient, updateRoomParametersClient, joinConRoom, joinRoom, checkMediasfuURL, joinLocalRoom, allMembers, allMembersRest, allWaitingRoomMembers, banParticipant, controlMediaHost, disconnect, disconnectUserSelf, getDomains, hostRequestResponse, meetingEnded, meetingStillThere, meetingTimeRemaining, participantRequested, personJoined, producerMediaClosed, producerMediaPaused, producerMediaResumed, reInitiateRecording, receiveMessage, recordingNotice, roomRecordParams, screenProducerId, startRecords, stoppedRecording, timeLeftRecording, updateConsumingDomains, updateMediaSettings, updatedCoHost, userWaiting, connectSocket, connectLocalSocket, disconnectSocket, checkLimitsAndMakeRequest, createRoomOnMediaSFU, SUPPORTED_LANGUAGE_CODES as SUPPORTED_LANGUAGE_CODES$1, isLanguageSupported as isLanguageSupported$1, normalizeLanguageCode as normalizeLanguageCode$1, getLanguageName as getLanguageName$1, getLanguageNativeName as getLanguageNativeName$1, getSupportedLanguages as getSupportedLanguages$1, getLanguageMetadata, addPanelist, removePanelist, focusPanelists, updateParticipantPermission, bulkUpdateParticipantPermissions, updatePermissionConfig, isSpeakerInMyBreakoutRoom, pauseOriginalProducer, resumeOriginalProducer, isConsumingTranslationForSpeaker, getActiveTranslationConsumers, findOriginalProducerForSpeaker, stopConsumingTranslation, syncTranslationStateAfterBreakoutChange, panelistsUpdated, panelistFocusChanged, panelistControlMedia, addedAsPanelist, removedFromPanelists, permissionUpdated, permissionConfigUpdated, receiveRoomMessages, createResponseJoinRoom as createResponseJoinRoom$1, createLiveSubtitle, SoundPlayer as SoundPlayer$1 } from 'mediasfu-shared';
3
+ import { joinConsumeRoom, producerClosed, newPipeProducer, getOverlayPosition as getOverlayPosition$1, translationRoomConfig, translationConfigUpdated, translationLanguageSet, translationSubscribed, translationUnsubscribed, translationProducerReady, translationProducerClosed, translationChannelsAvailable, translationMemberState, translationError, translationTranscript, translationSpeakerOutputChanged, controlMedia, isSubtitleExpired, autoAdjust, calculateRowsAndColumns, changeVids, checkGrid, checkPermission, checkScreenShare, closeAndResize, compareActiveNames, compareScreenStates, connectIps, connectLocalIps, connectRecvTransport, connectSendTransport, connectSendTransportAudio, connectSendTransportScreen, connectSendTransportVideo, createSendTransport, disconnectSendTransportAudio, disconnectSendTransportVideo, disconnectSendTransportScreen, dispStreams, generatePageContent, getEstimate, getPipedProducersAlt, getProducersPiped, getVideos, mixStreams, onScreenChanges, processConsumerTransports, processConsumerTransportsAudio, readjust, receiveAllPipedTransports, reorderStreams, rePort, requestScreenShare, resumePauseAudioStreams, resumePauseStreams, resumeSendTransportAudio, reUpdateInter, signalNewConsumerTransport, startShareScreen, stopShareScreen, streamSuccessAudio, streamSuccessAudioSwitch, streamSuccessScreen, switchUserAudio, clickVideo, switchUserVideo, switchUserVideoAlt, trigger, updateMiniCardsGrid, updateParticipantAudioDecibels, aParams, hParams, screenParams, vParams, launchBackground, launchBreakoutRooms, breakoutRoomUpdated, launchCoHost as launchCoHost$1, modifyCoHostSettings, launchDisplaySettings, modifyDisplaySettings, launchConfirmExit, confirmExit, launchMediaSettings, launchMenuModal, launchMessages, launchParticipants, messageParticipants, muteParticipants, removeParticipants, handleCreatePoll, handleEndPoll, handleVotePoll, launchPoll, pollUpdated, checkPauseState, checkResumeState, confirmRecording, launchRecording, recordPauseTimer, recordResumeTimer, recordStartTimer, recordUpdateTimer, startRecording, stopRecording, updateRecording, launchRequests, respondToRequests, launchSettings, modifySettings, clickAudio, clickChat, clickScreenShare, switchAudio, switchVideo, switchVideoAlt, joinRoomOnMediaSFU, formatNumber, getModalPosition as getModalPosition$1, sleep as sleep$1, validateAlphanumeric, launchWaiting, respondToWaiting, launchConfigureWhiteboard, createDeviceClient, joinRoomClient, updateRoomParametersClient, joinConRoom, joinRoom, checkMediasfuURL, joinLocalRoom, allMembers, allMembersRest, allWaitingRoomMembers, banParticipant, controlMediaHost, disconnect, disconnectUserSelf, getDomains, hostRequestResponse, meetingEnded, meetingStillThere, meetingTimeRemaining, participantRequested, personJoined, producerMediaClosed, producerMediaPaused, producerMediaResumed, reInitiateRecording, receiveMessage, recordingNotice, roomRecordParams, screenProducerId, startRecords, stoppedRecording, timeLeftRecording, updateConsumingDomains, updateMediaSettings, updatedCoHost, userWaiting, connectSocket, connectLocalSocket, disconnectSocket, checkLimitsAndMakeRequest, createRoomOnMediaSFU, SUPPORTED_LANGUAGE_CODES as SUPPORTED_LANGUAGE_CODES$1, isLanguageSupported as isLanguageSupported$1, normalizeLanguageCode as normalizeLanguageCode$1, getLanguageName as getLanguageName$1, getLanguageNativeName as getLanguageNativeName$1, getSupportedLanguages as getSupportedLanguages$1, getLanguageMetadata, addPanelist, removePanelist, focusPanelists, updateParticipantPermission, bulkUpdateParticipantPermissions, updatePermissionConfig, isSpeakerInMyBreakoutRoom, pauseOriginalProducer, resumeOriginalProducer, isConsumingTranslationForSpeaker, getActiveTranslationConsumers, findOriginalProducerForSpeaker, stopConsumingTranslation, syncTranslationStateAfterBreakoutChange, panelistsUpdated, panelistFocusChanged, panelistControlMedia, addedAsPanelist, removedFromPanelists, permissionUpdated, permissionConfigUpdated, receiveRoomMessages, createResponseJoinRoom as createResponseJoinRoom$1, createLiveSubtitle, SoundPlayer as SoundPlayer$1 } from 'mediasfu-shared';
4
4
  export { createLiveSubtitle, isSubtitleExpired } from 'mediasfu-shared';
5
5
  import * as i1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
@@ -11292,23 +11292,59 @@ class SendMessage {
11292
11292
  * @throws Will throw an error if the message, sender, or receivers are not valid.
11293
11293
  * @throws Will throw an error if the user is not allowed to send a message in the event room.
11294
11294
  */
11295
- async sendMessage({ member, islevel, showAlert, coHostResponsibility, coHost, chatSetting, message, roomName, messagesLength, receivers, group, sender, socket, }) {
11296
- const normalizedEventType = roomName.startsWith('s') ? 'chat' : 'conference';
11297
- await sendMessage({
11298
- member,
11299
- islevel,
11300
- showAlert,
11301
- coHostResponsibility,
11302
- coHost,
11303
- chatSetting,
11295
+ async sendMessage({ message, receivers, group, messagesLength, member, sender, islevel, showAlert, coHostResponsibility, coHost, roomName, socket, chatSetting, }) {
11296
+ let chatValue = false;
11297
+ const normalizedReceivers = (receivers ?? []).filter((receiver) => typeof receiver === 'string' && receiver.trim().length > 0);
11298
+ if ((messagesLength > 100 && roomName.startsWith('d')) ||
11299
+ (messagesLength > 500 && roomName.startsWith('s')) ||
11300
+ (messagesLength > 100000 && roomName.startsWith('p'))) {
11301
+ showAlert?.({
11302
+ message: 'You have reached the maximum number of messages allowed.',
11303
+ type: 'danger',
11304
+ duration: 3000,
11305
+ });
11306
+ return;
11307
+ }
11308
+ if (!message || message === '') {
11309
+ showAlert?.({
11310
+ message: 'Message is not valid.',
11311
+ type: 'danger',
11312
+ duration: 3000,
11313
+ });
11314
+ return;
11315
+ }
11316
+ if (normalizedReceivers.length < 1 && group === false && islevel === '2') {
11317
+ showAlert?.({
11318
+ message: 'Please select a message to reply to',
11319
+ type: 'danger',
11320
+ duration: 3000,
11321
+ });
11322
+ return;
11323
+ }
11324
+ const messageObject = {
11325
+ sender: sender ? sender : member,
11326
+ receivers: normalizedReceivers,
11304
11327
  message,
11328
+ timestamp: new Date().toLocaleTimeString(),
11329
+ group: group !== undefined && group !== null ? group : false,
11330
+ };
11331
+ try {
11332
+ chatValue = coHostResponsibility.find((item) => item.name === 'chat')?.value ?? false;
11333
+ }
11334
+ catch (error) {
11335
+ console.error(error);
11336
+ }
11337
+ if (!(islevel === '2' || (coHost === member && chatValue === true)) && !chatSetting) {
11338
+ showAlert?.({
11339
+ message: 'You are not allowed to send a message in this event room',
11340
+ type: 'danger',
11341
+ duration: 3000,
11342
+ });
11343
+ return;
11344
+ }
11345
+ socket.emit('sendMessage', {
11346
+ messageObject,
11305
11347
  roomName,
11306
- messagesLength,
11307
- receivers,
11308
- group,
11309
- sender,
11310
- socket,
11311
- eventType: normalizedEventType,
11312
11348
  });
11313
11349
  }
11314
11350
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: SendMessage, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
@@ -24350,6 +24386,20 @@ class MessagePanel {
24350
24386
  };
24351
24387
  this.senderId = senderId;
24352
24388
  }
24389
+ getComposerPlaceholder() {
24390
+ if (this.type === 'direct') {
24391
+ if (this.senderId) {
24392
+ return `Send a direct message to ${this.senderId}`;
24393
+ }
24394
+ if (this.directMessageDetails) {
24395
+ return `Send a direct message to ${this.directMessageDetails.name}`;
24396
+ }
24397
+ return this.islevel === '2'
24398
+ ? 'Select a message to reply to'
24399
+ : 'Send a direct message to the host';
24400
+ }
24401
+ return this.eventType === 'chat' ? 'Send a message' : 'Send a message to everyone';
24402
+ }
24353
24403
  async handleSendButton() {
24354
24404
  const message = this.type === 'direct' ? this.directMessageText : this.groupMessageText;
24355
24405
  if (!message) {
@@ -24365,7 +24415,7 @@ class MessagePanel {
24365
24415
  return;
24366
24416
  }
24367
24417
  if (this.type === 'direct' && !this.senderId && this.islevel == '2') {
24368
- this.showAlert?.({ message: 'Please select a user to send a message to.', type: 'danger' });
24418
+ this.showAlert?.({ message: 'Please select a message to reply to.', type: 'danger' });
24369
24419
  return;
24370
24420
  }
24371
24421
  await this.onSendMessagePress({
@@ -24393,11 +24443,11 @@ class MessagePanel {
24393
24443
  this.senderId = null;
24394
24444
  }
24395
24445
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: MessagePanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
24396
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: MessagePanel, isStandalone: true, selector: "app-message-panel", inputs: { messages: "messages", messagesLength: "messagesLength", type: "type", username: "username", onSendMessagePress: "onSendMessagePress", backgroundColor: "backgroundColor", focusedInput: "focusedInput", eventType: "eventType", member: "member", islevel: "islevel", startDirectMessage: "startDirectMessage", updateStartDirectMessage: "updateStartDirectMessage", directMessageDetails: "directMessageDetails", updateDirectMessageDetails: "updateDirectMessageDetails", coHostResponsibility: "coHostResponsibility", coHost: "coHost", roomName: "roomName", socket: "socket", chatSetting: "chatSetting", showAlert: "showAlert" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"message-panel\" [style.background]=\"backgroundColor || 'transparent'\">\r\n <div class=\"message-panel__scroll\">\r\n <div *ngIf=\"!messages?.length\" class=\"message-panel__empty\">\r\n No messages yet.\r\n </div>\r\n\r\n <div\r\n *ngFor=\"let message of messages; let index = index\"\r\n class=\"message-panel__row\"\r\n [class.message-panel__row--self]=\"message.sender === username\"\r\n >\r\n <div class=\"message-panel__meta\">\r\n <span *ngIf=\"message.sender === username && !message.group\" class=\"message-panel__sender\">\r\n To: {{ message.receivers.join(', ') }}\r\n </span>\r\n <span *ngIf=\"message.sender !== username\" class=\"message-panel__sender\">\r\n {{ message.sender }}\r\n </span>\r\n <span class=\"message-panel__time\">{{ message.timestamp }}</span>\r\n <button\r\n *ngIf=\"message.sender !== username && !message.group\"\r\n type=\"button\"\r\n class=\"message-panel__reply\"\r\n (click)=\"openReplyInput(message.sender)\"\r\n aria-label=\"Reply\"\r\n >\r\n <fa-icon [icon]=\"faReply\" size=\"xs\"></fa-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"message-panel__bubble\" [class.message-panel__bubble--self]=\"message.sender === member\">\r\n {{ message.message }}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"replyInfo\" class=\"message-panel__replying\">\r\n <span>Replying to</span>\r\n <strong>{{ replyInfo.username }}</strong>\r\n </div>\r\n\r\n <div class=\"message-panel__composer\">\r\n <input\r\n type=\"text\"\r\n class=\"message-panel__input\"\r\n placeholder=\"{{ type === 'direct' ? (focusedInput && startDirectMessage && directMessageDetails ? 'Send a direct message to ' + directMessageDetails.name : 'Select a message to reply to') : (eventType === 'chat' ? 'Send a message' : 'Send a message to everyone') }}\"\r\n maxLength=\"350\"\r\n (input)=\"handleTextInputChange($event)\"\r\n [value]=\"type === 'direct' ? directMessageText : groupMessageText\"\r\n />\r\n <button type=\"button\" class=\"message-panel__send\" (click)=\"handleSendButton()\" aria-label=\"Send message\">\r\n <fa-icon [icon]=\"faPaperPlane\" size=\"sm\"></fa-icon>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".message-panel{display:flex;flex-direction:column;height:100%;max-height:100%;min-height:0;gap:12px;color:var(--ms-modern-text-primary, #e2e8f0);font-family:var(--ms-modern-font-family, \"Segoe UI\", \"Aptos\", sans-serif)}.message-panel__scroll{flex:1;min-height:0;overflow-y:auto;padding-right:4px}.message-panel__empty{padding:18px 12px;text-align:center;color:var(--ms-modern-text-secondary, #94a3b8);font-size:.86rem}.message-panel__row{display:flex;flex-direction:column;align-items:flex-start;gap:5px;margin-bottom:12px}.message-panel__row--self{align-items:flex-end}.message-panel__meta{display:inline-flex;align-items:center;gap:8px;max-width:84%;color:var(--ms-modern-text-secondary, #94a3b8);font-size:.72rem;font-weight:700}.message-panel__sender,.message-panel__time{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.message-panel__reply{width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--ms-modern-border-subtle, rgba(148, 163, 184, .24));border-radius:999px;background:var(--ms-modern-field-background, rgba(15, 23, 42, .48));color:var(--ms-modern-text-primary, #e2e8f0);cursor:pointer}.message-panel__bubble{max-width:min(82%,460px);padding:10px 13px;border-radius:16px 16px 16px 6px;background:color-mix(in srgb,var(--ms-modern-accent, #14b8a6) 18%,transparent);border:1px solid color-mix(in srgb,var(--ms-modern-accent, #14b8a6) 26%,transparent);color:var(--ms-modern-text-primary, #e2e8f0);font-size:.9rem;line-height:1.45;overflow-wrap:anywhere}.message-panel__bubble--self{border-radius:16px 16px 6px;background:color-mix(in srgb,var(--ms-modern-success, #22c55e) 18%,transparent);border-color:color-mix(in srgb,var(--ms-modern-success, #22c55e) 26%,transparent)}.message-panel__replying{display:inline-flex;align-items:center;gap:8px;padding:8px 10px;border-radius:12px;background:color-mix(in srgb,var(--ms-modern-info, #3b82f6) 10%,transparent);border:1px solid color-mix(in srgb,var(--ms-modern-info, #3b82f6) 24%,transparent);color:var(--ms-modern-text-secondary, #94a3b8);font-size:.78rem}.message-panel__replying strong{color:var(--ms-modern-text-primary, #e2e8f0)}.message-panel__composer{display:flex;align-items:center;gap:10px;padding-top:4px}.message-panel__input{flex:1;min-width:0;min-height:44px;padding:0 14px;border:1px solid var(--ms-modern-border-subtle, rgba(148, 163, 184, .24));border-radius:999px;outline:none;background:var(--ms-modern-field-background, rgba(15, 23, 42, .48));color:var(--ms-modern-text-primary, #e2e8f0)}.message-panel__input::placeholder{color:var(--ms-modern-text-secondary, #94a3b8)}.message-panel__send{width:44px;height:44px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:999px;background:var(--ms-modern-accent, #14b8a6);color:#fff;box-shadow:0 10px 24px #0f172a2e;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i2.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "ngmodule", type: FormsModule }] });
24446
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: MessagePanel, isStandalone: true, selector: "app-message-panel", inputs: { messages: "messages", messagesLength: "messagesLength", type: "type", username: "username", onSendMessagePress: "onSendMessagePress", backgroundColor: "backgroundColor", focusedInput: "focusedInput", eventType: "eventType", member: "member", islevel: "islevel", startDirectMessage: "startDirectMessage", updateStartDirectMessage: "updateStartDirectMessage", directMessageDetails: "directMessageDetails", updateDirectMessageDetails: "updateDirectMessageDetails", coHostResponsibility: "coHostResponsibility", coHost: "coHost", roomName: "roomName", socket: "socket", chatSetting: "chatSetting", showAlert: "showAlert" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"message-panel\" [style.background]=\"backgroundColor || 'transparent'\">\r\n <div class=\"message-panel__scroll\">\r\n <div *ngIf=\"!messages?.length\" class=\"message-panel__empty\">\r\n No messages yet.\r\n </div>\r\n\r\n <div\r\n *ngFor=\"let message of messages; let index = index\"\r\n class=\"message-panel__row\"\r\n [class.message-panel__row--self]=\"message.sender === username\"\r\n >\r\n <div class=\"message-panel__meta\">\r\n <span *ngIf=\"message.sender === username && !message.group\" class=\"message-panel__sender\">\r\n To: {{ message.receivers.join(', ') }}\r\n </span>\r\n <span *ngIf=\"message.sender !== username\" class=\"message-panel__sender\">\r\n {{ message.sender }}\r\n </span>\r\n <span class=\"message-panel__time\">{{ message.timestamp }}</span>\r\n <button\r\n *ngIf=\"message.sender !== username && !message.group\"\r\n type=\"button\"\r\n class=\"message-panel__reply\"\r\n (click)=\"openReplyInput(message.sender)\"\r\n aria-label=\"Reply\"\r\n >\r\n <fa-icon [icon]=\"faReply\" size=\"xs\"></fa-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"message-panel__bubble\" [class.message-panel__bubble--self]=\"message.sender === member\">\r\n {{ message.message }}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"replyInfo\" class=\"message-panel__replying\">\r\n <span>Replying to</span>\r\n <strong>{{ replyInfo.username }}</strong>\r\n </div>\r\n\r\n <div class=\"message-panel__composer\">\r\n <input\r\n type=\"text\"\r\n class=\"message-panel__input\"\r\n [placeholder]=\"getComposerPlaceholder()\"\r\n maxLength=\"350\"\r\n (input)=\"handleTextInputChange($event)\"\r\n [value]=\"type === 'direct' ? directMessageText : groupMessageText\"\r\n />\r\n <button type=\"button\" class=\"message-panel__send\" (click)=\"handleSendButton()\" aria-label=\"Send message\">\r\n <fa-icon [icon]=\"faPaperPlane\" size=\"sm\"></fa-icon>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".message-panel{display:flex;flex-direction:column;height:100%;max-height:100%;min-height:0;gap:12px;color:var(--ms-modern-text-primary, #e2e8f0);font-family:var(--ms-modern-font-family, \"Segoe UI\", \"Aptos\", sans-serif)}.message-panel__scroll{flex:1;min-height:0;overflow-y:auto;padding-right:4px}.message-panel__empty{padding:18px 12px;text-align:center;color:var(--ms-modern-text-secondary, #94a3b8);font-size:.86rem}.message-panel__row{display:flex;flex-direction:column;align-items:flex-start;gap:5px;margin-bottom:12px}.message-panel__row--self{align-items:flex-end}.message-panel__meta{display:inline-flex;align-items:center;gap:8px;max-width:84%;color:var(--ms-modern-text-secondary, #94a3b8);font-size:.72rem;font-weight:700}.message-panel__sender,.message-panel__time{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.message-panel__reply{width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--ms-modern-border-subtle, rgba(148, 163, 184, .24));border-radius:999px;background:var(--ms-modern-field-background, rgba(15, 23, 42, .48));color:var(--ms-modern-text-primary, #e2e8f0);cursor:pointer}.message-panel__bubble{max-width:min(82%,460px);padding:10px 13px;border-radius:16px 16px 16px 6px;background:color-mix(in srgb,var(--ms-modern-accent, #14b8a6) 18%,transparent);border:1px solid color-mix(in srgb,var(--ms-modern-accent, #14b8a6) 26%,transparent);color:var(--ms-modern-text-primary, #e2e8f0);font-size:.9rem;line-height:1.45;overflow-wrap:anywhere}.message-panel__bubble--self{border-radius:16px 16px 6px;background:color-mix(in srgb,var(--ms-modern-success, #22c55e) 18%,transparent);border-color:color-mix(in srgb,var(--ms-modern-success, #22c55e) 26%,transparent)}.message-panel__replying{display:inline-flex;align-items:center;gap:8px;padding:8px 10px;border-radius:12px;background:color-mix(in srgb,var(--ms-modern-info, #3b82f6) 10%,transparent);border:1px solid color-mix(in srgb,var(--ms-modern-info, #3b82f6) 24%,transparent);color:var(--ms-modern-text-secondary, #94a3b8);font-size:.78rem}.message-panel__replying strong{color:var(--ms-modern-text-primary, #e2e8f0)}.message-panel__composer{display:flex;align-items:center;gap:10px;padding-top:4px}.message-panel__input{flex:1;min-width:0;min-height:44px;padding:0 14px;border:1px solid var(--ms-modern-border-subtle, rgba(148, 163, 184, .24));border-radius:999px;outline:none;background:var(--ms-modern-field-background, rgba(15, 23, 42, .48));color:var(--ms-modern-text-primary, #e2e8f0)}.message-panel__input::placeholder{color:var(--ms-modern-text-secondary, #94a3b8)}.message-panel__send{width:44px;height:44px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:999px;background:var(--ms-modern-accent, #14b8a6);color:#fff;box-shadow:0 10px 24px #0f172a2e;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i2.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "ngmodule", type: FormsModule }] });
24397
24447
  }
24398
24448
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: MessagePanel, decorators: [{
24399
24449
  type: Component,
24400
- args: [{ selector: 'app-message-panel', imports: [CommonModule, FontAwesomeModule, FormsModule], template: "<div class=\"message-panel\" [style.background]=\"backgroundColor || 'transparent'\">\r\n <div class=\"message-panel__scroll\">\r\n <div *ngIf=\"!messages?.length\" class=\"message-panel__empty\">\r\n No messages yet.\r\n </div>\r\n\r\n <div\r\n *ngFor=\"let message of messages; let index = index\"\r\n class=\"message-panel__row\"\r\n [class.message-panel__row--self]=\"message.sender === username\"\r\n >\r\n <div class=\"message-panel__meta\">\r\n <span *ngIf=\"message.sender === username && !message.group\" class=\"message-panel__sender\">\r\n To: {{ message.receivers.join(', ') }}\r\n </span>\r\n <span *ngIf=\"message.sender !== username\" class=\"message-panel__sender\">\r\n {{ message.sender }}\r\n </span>\r\n <span class=\"message-panel__time\">{{ message.timestamp }}</span>\r\n <button\r\n *ngIf=\"message.sender !== username && !message.group\"\r\n type=\"button\"\r\n class=\"message-panel__reply\"\r\n (click)=\"openReplyInput(message.sender)\"\r\n aria-label=\"Reply\"\r\n >\r\n <fa-icon [icon]=\"faReply\" size=\"xs\"></fa-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"message-panel__bubble\" [class.message-panel__bubble--self]=\"message.sender === member\">\r\n {{ message.message }}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"replyInfo\" class=\"message-panel__replying\">\r\n <span>Replying to</span>\r\n <strong>{{ replyInfo.username }}</strong>\r\n </div>\r\n\r\n <div class=\"message-panel__composer\">\r\n <input\r\n type=\"text\"\r\n class=\"message-panel__input\"\r\n placeholder=\"{{ type === 'direct' ? (focusedInput && startDirectMessage && directMessageDetails ? 'Send a direct message to ' + directMessageDetails.name : 'Select a message to reply to') : (eventType === 'chat' ? 'Send a message' : 'Send a message to everyone') }}\"\r\n maxLength=\"350\"\r\n (input)=\"handleTextInputChange($event)\"\r\n [value]=\"type === 'direct' ? directMessageText : groupMessageText\"\r\n />\r\n <button type=\"button\" class=\"message-panel__send\" (click)=\"handleSendButton()\" aria-label=\"Send message\">\r\n <fa-icon [icon]=\"faPaperPlane\" size=\"sm\"></fa-icon>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".message-panel{display:flex;flex-direction:column;height:100%;max-height:100%;min-height:0;gap:12px;color:var(--ms-modern-text-primary, #e2e8f0);font-family:var(--ms-modern-font-family, \"Segoe UI\", \"Aptos\", sans-serif)}.message-panel__scroll{flex:1;min-height:0;overflow-y:auto;padding-right:4px}.message-panel__empty{padding:18px 12px;text-align:center;color:var(--ms-modern-text-secondary, #94a3b8);font-size:.86rem}.message-panel__row{display:flex;flex-direction:column;align-items:flex-start;gap:5px;margin-bottom:12px}.message-panel__row--self{align-items:flex-end}.message-panel__meta{display:inline-flex;align-items:center;gap:8px;max-width:84%;color:var(--ms-modern-text-secondary, #94a3b8);font-size:.72rem;font-weight:700}.message-panel__sender,.message-panel__time{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.message-panel__reply{width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--ms-modern-border-subtle, rgba(148, 163, 184, .24));border-radius:999px;background:var(--ms-modern-field-background, rgba(15, 23, 42, .48));color:var(--ms-modern-text-primary, #e2e8f0);cursor:pointer}.message-panel__bubble{max-width:min(82%,460px);padding:10px 13px;border-radius:16px 16px 16px 6px;background:color-mix(in srgb,var(--ms-modern-accent, #14b8a6) 18%,transparent);border:1px solid color-mix(in srgb,var(--ms-modern-accent, #14b8a6) 26%,transparent);color:var(--ms-modern-text-primary, #e2e8f0);font-size:.9rem;line-height:1.45;overflow-wrap:anywhere}.message-panel__bubble--self{border-radius:16px 16px 6px;background:color-mix(in srgb,var(--ms-modern-success, #22c55e) 18%,transparent);border-color:color-mix(in srgb,var(--ms-modern-success, #22c55e) 26%,transparent)}.message-panel__replying{display:inline-flex;align-items:center;gap:8px;padding:8px 10px;border-radius:12px;background:color-mix(in srgb,var(--ms-modern-info, #3b82f6) 10%,transparent);border:1px solid color-mix(in srgb,var(--ms-modern-info, #3b82f6) 24%,transparent);color:var(--ms-modern-text-secondary, #94a3b8);font-size:.78rem}.message-panel__replying strong{color:var(--ms-modern-text-primary, #e2e8f0)}.message-panel__composer{display:flex;align-items:center;gap:10px;padding-top:4px}.message-panel__input{flex:1;min-width:0;min-height:44px;padding:0 14px;border:1px solid var(--ms-modern-border-subtle, rgba(148, 163, 184, .24));border-radius:999px;outline:none;background:var(--ms-modern-field-background, rgba(15, 23, 42, .48));color:var(--ms-modern-text-primary, #e2e8f0)}.message-panel__input::placeholder{color:var(--ms-modern-text-secondary, #94a3b8)}.message-panel__send{width:44px;height:44px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:999px;background:var(--ms-modern-accent, #14b8a6);color:#fff;box-shadow:0 10px 24px #0f172a2e;cursor:pointer}\n"] }]
24450
+ args: [{ selector: 'app-message-panel', imports: [CommonModule, FontAwesomeModule, FormsModule], template: "<div class=\"message-panel\" [style.background]=\"backgroundColor || 'transparent'\">\r\n <div class=\"message-panel__scroll\">\r\n <div *ngIf=\"!messages?.length\" class=\"message-panel__empty\">\r\n No messages yet.\r\n </div>\r\n\r\n <div\r\n *ngFor=\"let message of messages; let index = index\"\r\n class=\"message-panel__row\"\r\n [class.message-panel__row--self]=\"message.sender === username\"\r\n >\r\n <div class=\"message-panel__meta\">\r\n <span *ngIf=\"message.sender === username && !message.group\" class=\"message-panel__sender\">\r\n To: {{ message.receivers.join(', ') }}\r\n </span>\r\n <span *ngIf=\"message.sender !== username\" class=\"message-panel__sender\">\r\n {{ message.sender }}\r\n </span>\r\n <span class=\"message-panel__time\">{{ message.timestamp }}</span>\r\n <button\r\n *ngIf=\"message.sender !== username && !message.group\"\r\n type=\"button\"\r\n class=\"message-panel__reply\"\r\n (click)=\"openReplyInput(message.sender)\"\r\n aria-label=\"Reply\"\r\n >\r\n <fa-icon [icon]=\"faReply\" size=\"xs\"></fa-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"message-panel__bubble\" [class.message-panel__bubble--self]=\"message.sender === member\">\r\n {{ message.message }}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"replyInfo\" class=\"message-panel__replying\">\r\n <span>Replying to</span>\r\n <strong>{{ replyInfo.username }}</strong>\r\n </div>\r\n\r\n <div class=\"message-panel__composer\">\r\n <input\r\n type=\"text\"\r\n class=\"message-panel__input\"\r\n [placeholder]=\"getComposerPlaceholder()\"\r\n maxLength=\"350\"\r\n (input)=\"handleTextInputChange($event)\"\r\n [value]=\"type === 'direct' ? directMessageText : groupMessageText\"\r\n />\r\n <button type=\"button\" class=\"message-panel__send\" (click)=\"handleSendButton()\" aria-label=\"Send message\">\r\n <fa-icon [icon]=\"faPaperPlane\" size=\"sm\"></fa-icon>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".message-panel{display:flex;flex-direction:column;height:100%;max-height:100%;min-height:0;gap:12px;color:var(--ms-modern-text-primary, #e2e8f0);font-family:var(--ms-modern-font-family, \"Segoe UI\", \"Aptos\", sans-serif)}.message-panel__scroll{flex:1;min-height:0;overflow-y:auto;padding-right:4px}.message-panel__empty{padding:18px 12px;text-align:center;color:var(--ms-modern-text-secondary, #94a3b8);font-size:.86rem}.message-panel__row{display:flex;flex-direction:column;align-items:flex-start;gap:5px;margin-bottom:12px}.message-panel__row--self{align-items:flex-end}.message-panel__meta{display:inline-flex;align-items:center;gap:8px;max-width:84%;color:var(--ms-modern-text-secondary, #94a3b8);font-size:.72rem;font-weight:700}.message-panel__sender,.message-panel__time{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.message-panel__reply{width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--ms-modern-border-subtle, rgba(148, 163, 184, .24));border-radius:999px;background:var(--ms-modern-field-background, rgba(15, 23, 42, .48));color:var(--ms-modern-text-primary, #e2e8f0);cursor:pointer}.message-panel__bubble{max-width:min(82%,460px);padding:10px 13px;border-radius:16px 16px 16px 6px;background:color-mix(in srgb,var(--ms-modern-accent, #14b8a6) 18%,transparent);border:1px solid color-mix(in srgb,var(--ms-modern-accent, #14b8a6) 26%,transparent);color:var(--ms-modern-text-primary, #e2e8f0);font-size:.9rem;line-height:1.45;overflow-wrap:anywhere}.message-panel__bubble--self{border-radius:16px 16px 6px;background:color-mix(in srgb,var(--ms-modern-success, #22c55e) 18%,transparent);border-color:color-mix(in srgb,var(--ms-modern-success, #22c55e) 26%,transparent)}.message-panel__replying{display:inline-flex;align-items:center;gap:8px;padding:8px 10px;border-radius:12px;background:color-mix(in srgb,var(--ms-modern-info, #3b82f6) 10%,transparent);border:1px solid color-mix(in srgb,var(--ms-modern-info, #3b82f6) 24%,transparent);color:var(--ms-modern-text-secondary, #94a3b8);font-size:.78rem}.message-panel__replying strong{color:var(--ms-modern-text-primary, #e2e8f0)}.message-panel__composer{display:flex;align-items:center;gap:10px;padding-top:4px}.message-panel__input{flex:1;min-width:0;min-height:44px;padding:0 14px;border:1px solid var(--ms-modern-border-subtle, rgba(148, 163, 184, .24));border-radius:999px;outline:none;background:var(--ms-modern-field-background, rgba(15, 23, 42, .48));color:var(--ms-modern-text-primary, #e2e8f0)}.message-panel__input::placeholder{color:var(--ms-modern-text-secondary, #94a3b8)}.message-panel__send{width:44px;height:44px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:999px;background:var(--ms-modern-accent, #14b8a6);color:#fff;box-shadow:0 10px 24px #0f172a2e;cursor:pointer}\n"] }]
24401
24451
  }], propDecorators: { messages: [{
24402
24452
  type: Input
24403
24453
  }], messagesLength: [{
@@ -29647,11 +29697,11 @@ class Screenboard {
29647
29697
  this.parameters.updateIsScreenboardModalVisible(false);
29648
29698
  };
29649
29699
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: Screenboard, deps: [{ token: 'customWidth', optional: true }, { token: 'customHeight', optional: true }, { token: 'parameters', optional: true }, { token: 'showAspect', optional: true }], target: i0.ɵɵFactoryTarget.Component });
29650
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: Screenboard, isStandalone: true, selector: "app-screenboard", inputs: { customWidth: "customWidth", customHeight: "customHeight", parameters: "parameters", showAspect: "showAspect" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvasRef"], descendants: true }, { propertyName: "screenboardRef", first: true, predicate: ["screenboardRef"], descendants: true }, { propertyName: "screenboardContentRef", first: true, predicate: ["screenboardContentRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"screenboard-interface\" *ngIf=\"showAspect\" style=\"position: relative; display: block; justify-content: center; align-items: center; background-color: transparent; z-index: 1000; width: 100%; height: 100%; max-width: 100%; max-height: 100%; overflow: auto;\" #screenboardRef>\r\n <div id=\"screenboardContent\" style=\"position: relative; display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; overflow: hidden; top: 0; left: 0;\" #screenboardContentRef>\r\n <button id=\"annotateScreen\" class=\"btn btn-primary btnBoardScreen annotateScreenBtn\" style=\"position: absolute; top: 5px; right: 10px; z-index: 1000;\" (click)=\"toggleAnnotate()\">\r\n <fa-icon [icon]=\"faPencilAlt\" [ngStyle]=\"{'color': parameters.annotateScreenStream ? 'red' : 'green'}\"></fa-icon>\r\n </button>\r\n\r\n <button id=\"toolbarToggleScreen\" *ngIf=\"parameters.annotateScreenStream\" class=\"btn btnBoardScreen btn-primary\" style=\"position: absolute; top: 5px; right: 55px; z-index: 1000;\" (click)=\"toggleToolbar()\">\r\n <fa-icon [icon]=\"toolbarVisible ? faChevronRight : faChevronLeft\"></fa-icon>\r\n </button>\r\n\r\n <div class=\"toolbarScreen mb-3\" id=\"toolbarScreen\" style=\"position: absolute; top: 5px; right: 105px; z-index: 1000; background-color: transparent;\" [style.display]=\"toolbarVisible ? 'block' : 'none'\">\r\n <!-- Draw Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-secondary dropdown-toggle\" id=\"drawModeScreen\" (click)=\"handleDropdownClick('drawModeScreen')\">\r\n <fa-icon [icon]=\"faPencilAlt\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'drawModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(3)\">XX-Small (3px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(6)\">X-Small (6px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(12)\">Small (12px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(18)\">Medium (18px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(24)\">Large (24px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(36)\">X-Large (36px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Freehand Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-dark dropdown-toggle\" id=\"freehandModeScreen\" (click)=\"handleDropdownClick('freehandModeScreen')\">\r\n <fa-icon [icon]=\"faPaintBrush\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'freehandModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(5)\">X-Small (5px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(10)\">Small (10px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(20)\">Medium (20px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(40)\">Large (40px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(60)\">X-Large (60px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Shape Mode Dropdown with Images -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-dark dropdown-toggle\" id=\"shapeModeScreen\" (click)=\"handleDropdownClick('shapeModeScreen')\">\r\n <fa-icon [icon]=\"faShapes\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'shapeModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('square')\">\r\n <img src=\"https://mediasfu.com/images/svg/square.svg\" alt=\"Square\" class=\"shape-icon\" /> Square\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('rectangle')\">\r\n <img src=\"https://mediasfu.com/images/svg/rectangle.svg\" alt=\"Rectangle\" class=\"shape-icon\" /> Rectangle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('circle')\">\r\n <img src=\"https://mediasfu.com/images/svg/circle.svg\" alt=\"Circle\" class=\"shape-icon\" /> Circle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('triangle')\">\r\n <img src=\"https://mediasfu.com/images/svg/triangle.svg\" alt=\"Triangle\" class=\"shape-icon\" /> Triangle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('hexagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/hexagon.svg\" alt=\"Hexagon\" class=\"shape-icon\" /> Hexagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('pentagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/pentagon.svg\" alt=\"Pentagon\" class=\"shape-icon\" /> Pentagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('rhombus')\">\r\n <img src=\"https://mediasfu.com/images/svg/rhombus.svg\" alt=\"Rhombus\" class=\"shape-icon\" /> Rhombus\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('octagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/octagon.svg\" alt=\"Octagon\" class=\"shape-icon\" /> Octagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('oval')\">\r\n <img src=\"https://mediasfu.com/images/svg/oval.svg\" alt=\"Oval\" class=\"shape-icon\" /> Oval\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('parallelogram')\">\r\n <img src=\"https://mediasfu.com/images/svg/parallelogram.svg\" alt=\"Parallelogram\" class=\"shape-icon\" /> Parallelogram\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Erase Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-danger dropdown-toggle\" id=\"eraseModeScreen\" (click)=\"handleDropdownClick('eraseModeScreen')\">\r\n <fa-icon [icon]=\"faEraser\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'eraseModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(5)\">X-Small (5px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(10)\">Small (10px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(20)\">Medium (20px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(30)\">Large (30px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(60)\">X-Large (60px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Additional Toolbar Controls -->\r\n <button class=\"btn btnBoard btn-success\" id=\"zoomResetScreen\" style=\"display: none;\">\r\n <fa-icon [icon]=\"faSearch\"></fa-icon>\r\n </button>\r\n\r\n <input type=\"color\" class=\"btn\" id=\"colorPickerScreen\" [(ngModel)]=\"color\">\r\n <select id=\"lineTypePickerScreen\" class=\"custom-select\" style=\"width: auto;\" [(ngModel)]=\"lineType\">\r\n <option value=\"solid\">Solid</option>\r\n <option value=\"dashed\">Dashed</option>\r\n <option value=\"dotted\">Dotted</option>\r\n <option value=\"dashDot\">Dash-Dot</option>\r\n </select>\r\n </div>\r\n\r\n <canvas id=\"canvasRef\" width=\"1280\" height=\"720\" [ngStyle]=\"{'display': parameters.annotateScreenStream ? 'block' : 'none'}\" style=\"padding: 0; margin: 0;\" #canvasRef></canvas>\r\n </div>\r\n</div>\r\n", styles: ["#whiteboardCanvas{border:1px solid #000;cursor:crosshair;background-color:#fff}.resize-handle,.move-handle{width:8px;height:8px;background:red;position:absolute}.move-handle{background:#00f}#textInput{display:none;position:absolute;z-index:10;width:200px}.shape-icon{width:20px;height:20px;color:#fff}.toolbar .btn-group button,.toolbar .dropdown-menu a{font-size:.8rem;padding:5px 10px;margin:0 2px;border-radius:4px;transition:background-color .2s}.toolbar .dropdown-menu a{background-color:transparent;color:#1b1a1a}.toolbar .btn-group button:hover,.toolbar .dropdown-menu a:hover{background-color:#e3e7eb}.toolbar .btn-group button.active{background-color:#454d55}.toolbarScreen .btn-group button,.toolbarScreen .dropdown-menu a{font-size:.8rem;padding:5px 10px;margin:1px 2px;border-radius:4px;transition:background-color .2s;background-color:transparent;color:\"black\"}.toolbarScreen .btn-group button{color:#060606;border:none}.toolbarScreen .dropdown-menu a{background-color:transparent;color:#1b1a1a}.toolbarScreen .btn-group button.active{background-color:#454d55}#toolbar,#toolbarScreen{transition:display .3s ease-in-out}#toolbarToggle,#toolbarToggleScreen{cursor:pointer;border:\"2px solid black\"!important;font-size:.8rem}#colorPicker,#colorPickerScreen{font-size:.8rem;padding:2px;width:32px;height:32px}#lineTypePicker{font-size:.8rem;padding:2px auto;width:32px;height:32px}.btnBoard{font-size:1rem;padding:2px;width:40px;height:40px;margin:2px}#lineTypePickerScreen{font-size:.7rem;padding:2px auto;width:28px;height:28px;background-color:#d6d1d166;color:#000;border-radius:4px}.toggle-icon{width:30px;height:30px;padding:0;margin:0}#toggleBackground.active{background-color:#fdfeff}.annotateScreenBtn{background-color:#2d2e2f!important;border:2px solid #000!important;color:green!important;font-size:.75rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i2.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
29700
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: Screenboard, isStandalone: true, selector: "app-screenboard", inputs: { customWidth: "customWidth", customHeight: "customHeight", parameters: "parameters", showAspect: "showAspect" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvasRef"], descendants: true }, { propertyName: "screenboardRef", first: true, predicate: ["screenboardRef"], descendants: true }, { propertyName: "screenboardContentRef", first: true, predicate: ["screenboardContentRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"screenboard-interface\" *ngIf=\"showAspect\" style=\"position: relative; display: block; justify-content: center; align-items: center; background-color: transparent; z-index: 1000; width: 100%; height: 100%; max-width: 100%; max-height: 100%; overflow: auto;\" #screenboardRef>\r\n <div id=\"screenboardContent\" style=\"position: relative; display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; overflow: hidden; top: 0; left: 0;\" #screenboardContentRef>\r\n <button id=\"annotateScreen\" class=\"btn btn-primary btnBoardScreen annotateScreenBtn\" style=\"position: absolute; top: 5px; right: 10px; z-index: 1000;\" (click)=\"toggleAnnotate()\">\r\n <fa-icon [icon]=\"faPencilAlt\" [ngStyle]=\"{'color': parameters.annotateScreenStream ? 'red' : 'green'}\"></fa-icon>\r\n </button>\r\n\r\n <button id=\"toolbarToggleScreen\" *ngIf=\"parameters.annotateScreenStream\" class=\"btn btnBoardScreen btn-primary\" style=\"position: absolute; top: 5px; right: 55px; z-index: 1000;\" (click)=\"toggleToolbar()\">\r\n <fa-icon [icon]=\"toolbarVisible ? faChevronRight : faChevronLeft\"></fa-icon>\r\n </button>\r\n\r\n <div class=\"toolbarScreen mb-3\" id=\"toolbarScreen\" style=\"position: absolute; top: 5px; right: 105px; z-index: 1000;\" [style.display]=\"toolbarVisible ? 'flex' : 'none'\">\r\n <!-- Draw Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-secondary dropdown-toggle\" id=\"drawModeScreen\" (click)=\"handleDropdownClick('drawModeScreen')\">\r\n <fa-icon [icon]=\"faPencilAlt\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'drawModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(3)\">XX-Small (3px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(6)\">X-Small (6px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(12)\">Small (12px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(18)\">Medium (18px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(24)\">Large (24px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(36)\">X-Large (36px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Freehand Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-dark dropdown-toggle\" id=\"freehandModeScreen\" (click)=\"handleDropdownClick('freehandModeScreen')\">\r\n <fa-icon [icon]=\"faPaintBrush\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'freehandModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(5)\">X-Small (5px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(10)\">Small (10px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(20)\">Medium (20px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(40)\">Large (40px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(60)\">X-Large (60px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Shape Mode Dropdown with Images -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-dark dropdown-toggle\" id=\"shapeModeScreen\" (click)=\"handleDropdownClick('shapeModeScreen')\">\r\n <fa-icon [icon]=\"faShapes\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'shapeModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('square')\">\r\n <img src=\"https://mediasfu.com/images/svg/square.svg\" alt=\"Square\" class=\"shape-icon\" /> Square\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('rectangle')\">\r\n <img src=\"https://mediasfu.com/images/svg/rectangle.svg\" alt=\"Rectangle\" class=\"shape-icon\" /> Rectangle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('circle')\">\r\n <img src=\"https://mediasfu.com/images/svg/circle.svg\" alt=\"Circle\" class=\"shape-icon\" /> Circle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('triangle')\">\r\n <img src=\"https://mediasfu.com/images/svg/triangle.svg\" alt=\"Triangle\" class=\"shape-icon\" /> Triangle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('hexagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/hexagon.svg\" alt=\"Hexagon\" class=\"shape-icon\" /> Hexagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('pentagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/pentagon.svg\" alt=\"Pentagon\" class=\"shape-icon\" /> Pentagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('rhombus')\">\r\n <img src=\"https://mediasfu.com/images/svg/rhombus.svg\" alt=\"Rhombus\" class=\"shape-icon\" /> Rhombus\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('octagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/octagon.svg\" alt=\"Octagon\" class=\"shape-icon\" /> Octagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('oval')\">\r\n <img src=\"https://mediasfu.com/images/svg/oval.svg\" alt=\"Oval\" class=\"shape-icon\" /> Oval\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('parallelogram')\">\r\n <img src=\"https://mediasfu.com/images/svg/parallelogram.svg\" alt=\"Parallelogram\" class=\"shape-icon\" /> Parallelogram\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Erase Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-danger dropdown-toggle\" id=\"eraseModeScreen\" (click)=\"handleDropdownClick('eraseModeScreen')\">\r\n <fa-icon [icon]=\"faEraser\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'eraseModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(5)\">X-Small (5px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(10)\">Small (10px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(20)\">Medium (20px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(30)\">Large (30px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(60)\">X-Large (60px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Additional Toolbar Controls -->\r\n <button class=\"btn btnBoard btn-success\" id=\"zoomResetScreen\" style=\"display: none;\">\r\n <fa-icon [icon]=\"faSearch\"></fa-icon>\r\n </button>\r\n\r\n <input type=\"color\" class=\"btn\" id=\"colorPickerScreen\" [(ngModel)]=\"color\">\r\n <select id=\"lineTypePickerScreen\" class=\"custom-select\" style=\"width: auto;\" [(ngModel)]=\"lineType\">\r\n <option value=\"solid\">Solid</option>\r\n <option value=\"dashed\">Dashed</option>\r\n <option value=\"dotted\">Dotted</option>\r\n <option value=\"dashDot\">Dash-Dot</option>\r\n </select>\r\n </div>\r\n\r\n <canvas id=\"canvasRef\" width=\"1280\" height=\"720\" [ngStyle]=\"{'display': parameters.annotateScreenStream ? 'block' : 'none'}\" style=\"padding: 0; margin: 0;\" #canvasRef></canvas>\r\n </div>\r\n</div>\r\n", styles: [".dropdown-menu{position:absolute;top:100%;left:0;z-index:1050;display:none;min-width:11rem;padding:.5rem 0;margin:.25rem 0 0;font-size:.85rem;color:#e2e8f0;text-align:left;background:#0f172afa;border:1px solid rgba(148,163,184,.24);border-radius:10px;box-shadow:0 18px 40px #0f172a59;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}.dropdown-menu.show{display:block}.dropdown-item{display:block;width:100%;padding:.5rem 1rem;clear:both;font-weight:500;color:#e2e8f0;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{background-color:#3b82f62e;color:#fff}#whiteboardCanvas{border:1px solid #000;cursor:crosshair;background-color:#fff}.resize-handle,.move-handle{width:8px;height:8px;background:red;position:absolute}.move-handle{background:#00f}#textInput{display:none;position:absolute;z-index:10;width:200px}.shape-icon{width:20px;height:20px;color:#fff}.toolbar .btn-group button,.toolbar .dropdown-menu a{font-size:.8rem;padding:5px 10px;margin:0 2px;border-radius:4px;transition:background-color .2s}.toolbar .dropdown-menu a{background-color:transparent;color:#1b1a1a}.toolbar .btn-group button:hover,.toolbar .dropdown-menu a:hover{background-color:#e3e7eb}.toolbar .btn-group button.active{background-color:#454d55}.toolbarScreen .btn-group>button{font-size:.8rem;padding:5px 10px;margin:1px 2px;border-radius:4px;transition:background-color .2s;background-color:#ffffff14;color:#f8fafc}.toolbarScreen{display:flex;align-items:center;gap:6px;padding:8px 12px;border-radius:12px;background:#0f172aeb;border:1px solid rgba(148,163,184,.28);box-shadow:0 16px 32px #0f172a47;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}.toolbarScreen .btn-group>button{color:#f8fafc;border:1px solid rgba(148,163,184,.28)}.toolbarScreen .btn-group>button:hover,.toolbarScreen .btn-group>button:focus-visible{background-color:#ffffff2e;border-color:#bfdbfe80;color:#fff}.toolbarScreen .btn-group>button svg,.toolbarScreen .btn-group>button i,.toolbarScreen .btn-group>button fa-icon{color:inherit;fill:currentColor}.toolbarScreen .btn-group>button.active{background-color:#2563ebb8;border-color:#bfdbfe8c}.toolbarScreen .dropdown-item{display:flex;align-items:center;gap:.65rem}.toolbarScreen .dropdown-item .shape-icon{filter:brightness(0) invert(1)}.toolbarScreen .dropdown-item svg,.toolbarScreen .dropdown-item i,.toolbarScreen .dropdown-item fa-icon{color:inherit;fill:currentColor}#toolbar,#toolbarScreen{transition:display .3s ease-in-out}#toolbarToggle,#toolbarToggleScreen{cursor:pointer;border:\"2px solid black\"!important;font-size:.8rem}#colorPicker,#colorPickerScreen{font-size:.8rem;padding:2px;width:32px;height:32px;border:1px solid rgba(148,163,184,.28);border-radius:8px;background-color:#ffffff14}#lineTypePicker{font-size:.8rem;padding:2px auto;width:32px;height:32px}.btnBoard{font-size:1rem;padding:2px;width:40px;height:40px;margin:2px}#lineTypePickerScreen{font-size:.7rem;padding:0 .6rem;min-width:108px;width:auto;height:36px;background-color:#ffffff14;color:#f8fafc;border:1px solid rgba(148,163,184,.28);border-radius:8px}.toggle-icon{width:30px;height:30px;padding:0;margin:0}#toggleBackground.active{background-color:#fdfeff}.annotateScreenBtn{background-color:#2d2e2f!important;border:2px solid #000!important;color:green!important;font-size:.75rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i2.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
29651
29701
  }
29652
29702
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: Screenboard, decorators: [{
29653
29703
  type: Component,
29654
- args: [{ selector: 'app-screenboard', imports: [CommonModule, FontAwesomeModule, FormsModule], template: "<div id=\"screenboard-interface\" *ngIf=\"showAspect\" style=\"position: relative; display: block; justify-content: center; align-items: center; background-color: transparent; z-index: 1000; width: 100%; height: 100%; max-width: 100%; max-height: 100%; overflow: auto;\" #screenboardRef>\r\n <div id=\"screenboardContent\" style=\"position: relative; display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; overflow: hidden; top: 0; left: 0;\" #screenboardContentRef>\r\n <button id=\"annotateScreen\" class=\"btn btn-primary btnBoardScreen annotateScreenBtn\" style=\"position: absolute; top: 5px; right: 10px; z-index: 1000;\" (click)=\"toggleAnnotate()\">\r\n <fa-icon [icon]=\"faPencilAlt\" [ngStyle]=\"{'color': parameters.annotateScreenStream ? 'red' : 'green'}\"></fa-icon>\r\n </button>\r\n\r\n <button id=\"toolbarToggleScreen\" *ngIf=\"parameters.annotateScreenStream\" class=\"btn btnBoardScreen btn-primary\" style=\"position: absolute; top: 5px; right: 55px; z-index: 1000;\" (click)=\"toggleToolbar()\">\r\n <fa-icon [icon]=\"toolbarVisible ? faChevronRight : faChevronLeft\"></fa-icon>\r\n </button>\r\n\r\n <div class=\"toolbarScreen mb-3\" id=\"toolbarScreen\" style=\"position: absolute; top: 5px; right: 105px; z-index: 1000; background-color: transparent;\" [style.display]=\"toolbarVisible ? 'block' : 'none'\">\r\n <!-- Draw Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-secondary dropdown-toggle\" id=\"drawModeScreen\" (click)=\"handleDropdownClick('drawModeScreen')\">\r\n <fa-icon [icon]=\"faPencilAlt\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'drawModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(3)\">XX-Small (3px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(6)\">X-Small (6px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(12)\">Small (12px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(18)\">Medium (18px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(24)\">Large (24px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(36)\">X-Large (36px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Freehand Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-dark dropdown-toggle\" id=\"freehandModeScreen\" (click)=\"handleDropdownClick('freehandModeScreen')\">\r\n <fa-icon [icon]=\"faPaintBrush\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'freehandModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(5)\">X-Small (5px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(10)\">Small (10px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(20)\">Medium (20px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(40)\">Large (40px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(60)\">X-Large (60px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Shape Mode Dropdown with Images -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-dark dropdown-toggle\" id=\"shapeModeScreen\" (click)=\"handleDropdownClick('shapeModeScreen')\">\r\n <fa-icon [icon]=\"faShapes\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'shapeModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('square')\">\r\n <img src=\"https://mediasfu.com/images/svg/square.svg\" alt=\"Square\" class=\"shape-icon\" /> Square\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('rectangle')\">\r\n <img src=\"https://mediasfu.com/images/svg/rectangle.svg\" alt=\"Rectangle\" class=\"shape-icon\" /> Rectangle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('circle')\">\r\n <img src=\"https://mediasfu.com/images/svg/circle.svg\" alt=\"Circle\" class=\"shape-icon\" /> Circle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('triangle')\">\r\n <img src=\"https://mediasfu.com/images/svg/triangle.svg\" alt=\"Triangle\" class=\"shape-icon\" /> Triangle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('hexagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/hexagon.svg\" alt=\"Hexagon\" class=\"shape-icon\" /> Hexagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('pentagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/pentagon.svg\" alt=\"Pentagon\" class=\"shape-icon\" /> Pentagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('rhombus')\">\r\n <img src=\"https://mediasfu.com/images/svg/rhombus.svg\" alt=\"Rhombus\" class=\"shape-icon\" /> Rhombus\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('octagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/octagon.svg\" alt=\"Octagon\" class=\"shape-icon\" /> Octagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('oval')\">\r\n <img src=\"https://mediasfu.com/images/svg/oval.svg\" alt=\"Oval\" class=\"shape-icon\" /> Oval\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('parallelogram')\">\r\n <img src=\"https://mediasfu.com/images/svg/parallelogram.svg\" alt=\"Parallelogram\" class=\"shape-icon\" /> Parallelogram\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Erase Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-danger dropdown-toggle\" id=\"eraseModeScreen\" (click)=\"handleDropdownClick('eraseModeScreen')\">\r\n <fa-icon [icon]=\"faEraser\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'eraseModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(5)\">X-Small (5px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(10)\">Small (10px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(20)\">Medium (20px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(30)\">Large (30px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(60)\">X-Large (60px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Additional Toolbar Controls -->\r\n <button class=\"btn btnBoard btn-success\" id=\"zoomResetScreen\" style=\"display: none;\">\r\n <fa-icon [icon]=\"faSearch\"></fa-icon>\r\n </button>\r\n\r\n <input type=\"color\" class=\"btn\" id=\"colorPickerScreen\" [(ngModel)]=\"color\">\r\n <select id=\"lineTypePickerScreen\" class=\"custom-select\" style=\"width: auto;\" [(ngModel)]=\"lineType\">\r\n <option value=\"solid\">Solid</option>\r\n <option value=\"dashed\">Dashed</option>\r\n <option value=\"dotted\">Dotted</option>\r\n <option value=\"dashDot\">Dash-Dot</option>\r\n </select>\r\n </div>\r\n\r\n <canvas id=\"canvasRef\" width=\"1280\" height=\"720\" [ngStyle]=\"{'display': parameters.annotateScreenStream ? 'block' : 'none'}\" style=\"padding: 0; margin: 0;\" #canvasRef></canvas>\r\n </div>\r\n</div>\r\n", styles: ["#whiteboardCanvas{border:1px solid #000;cursor:crosshair;background-color:#fff}.resize-handle,.move-handle{width:8px;height:8px;background:red;position:absolute}.move-handle{background:#00f}#textInput{display:none;position:absolute;z-index:10;width:200px}.shape-icon{width:20px;height:20px;color:#fff}.toolbar .btn-group button,.toolbar .dropdown-menu a{font-size:.8rem;padding:5px 10px;margin:0 2px;border-radius:4px;transition:background-color .2s}.toolbar .dropdown-menu a{background-color:transparent;color:#1b1a1a}.toolbar .btn-group button:hover,.toolbar .dropdown-menu a:hover{background-color:#e3e7eb}.toolbar .btn-group button.active{background-color:#454d55}.toolbarScreen .btn-group button,.toolbarScreen .dropdown-menu a{font-size:.8rem;padding:5px 10px;margin:1px 2px;border-radius:4px;transition:background-color .2s;background-color:transparent;color:\"black\"}.toolbarScreen .btn-group button{color:#060606;border:none}.toolbarScreen .dropdown-menu a{background-color:transparent;color:#1b1a1a}.toolbarScreen .btn-group button.active{background-color:#454d55}#toolbar,#toolbarScreen{transition:display .3s ease-in-out}#toolbarToggle,#toolbarToggleScreen{cursor:pointer;border:\"2px solid black\"!important;font-size:.8rem}#colorPicker,#colorPickerScreen{font-size:.8rem;padding:2px;width:32px;height:32px}#lineTypePicker{font-size:.8rem;padding:2px auto;width:32px;height:32px}.btnBoard{font-size:1rem;padding:2px;width:40px;height:40px;margin:2px}#lineTypePickerScreen{font-size:.7rem;padding:2px auto;width:28px;height:28px;background-color:#d6d1d166;color:#000;border-radius:4px}.toggle-icon{width:30px;height:30px;padding:0;margin:0}#toggleBackground.active{background-color:#fdfeff}.annotateScreenBtn{background-color:#2d2e2f!important;border:2px solid #000!important;color:green!important;font-size:.75rem}\n"] }]
29704
+ args: [{ selector: 'app-screenboard', imports: [CommonModule, FontAwesomeModule, FormsModule], template: "<div id=\"screenboard-interface\" *ngIf=\"showAspect\" style=\"position: relative; display: block; justify-content: center; align-items: center; background-color: transparent; z-index: 1000; width: 100%; height: 100%; max-width: 100%; max-height: 100%; overflow: auto;\" #screenboardRef>\r\n <div id=\"screenboardContent\" style=\"position: relative; display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; overflow: hidden; top: 0; left: 0;\" #screenboardContentRef>\r\n <button id=\"annotateScreen\" class=\"btn btn-primary btnBoardScreen annotateScreenBtn\" style=\"position: absolute; top: 5px; right: 10px; z-index: 1000;\" (click)=\"toggleAnnotate()\">\r\n <fa-icon [icon]=\"faPencilAlt\" [ngStyle]=\"{'color': parameters.annotateScreenStream ? 'red' : 'green'}\"></fa-icon>\r\n </button>\r\n\r\n <button id=\"toolbarToggleScreen\" *ngIf=\"parameters.annotateScreenStream\" class=\"btn btnBoardScreen btn-primary\" style=\"position: absolute; top: 5px; right: 55px; z-index: 1000;\" (click)=\"toggleToolbar()\">\r\n <fa-icon [icon]=\"toolbarVisible ? faChevronRight : faChevronLeft\"></fa-icon>\r\n </button>\r\n\r\n <div class=\"toolbarScreen mb-3\" id=\"toolbarScreen\" style=\"position: absolute; top: 5px; right: 105px; z-index: 1000;\" [style.display]=\"toolbarVisible ? 'flex' : 'none'\">\r\n <!-- Draw Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-secondary dropdown-toggle\" id=\"drawModeScreen\" (click)=\"handleDropdownClick('drawModeScreen')\">\r\n <fa-icon [icon]=\"faPencilAlt\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'drawModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(3)\">XX-Small (3px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(6)\">X-Small (6px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(12)\">Small (12px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(18)\">Medium (18px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(24)\">Large (24px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setDrawMode(36)\">X-Large (36px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Freehand Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-dark dropdown-toggle\" id=\"freehandModeScreen\" (click)=\"handleDropdownClick('freehandModeScreen')\">\r\n <fa-icon [icon]=\"faPaintBrush\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'freehandModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(5)\">X-Small (5px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(10)\">Small (10px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(20)\">Medium (20px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(40)\">Large (40px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setFreehandMode(60)\">X-Large (60px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Shape Mode Dropdown with Images -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-dark dropdown-toggle\" id=\"shapeModeScreen\" (click)=\"handleDropdownClick('shapeModeScreen')\">\r\n <fa-icon [icon]=\"faShapes\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'shapeModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('square')\">\r\n <img src=\"https://mediasfu.com/images/svg/square.svg\" alt=\"Square\" class=\"shape-icon\" /> Square\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('rectangle')\">\r\n <img src=\"https://mediasfu.com/images/svg/rectangle.svg\" alt=\"Rectangle\" class=\"shape-icon\" /> Rectangle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('circle')\">\r\n <img src=\"https://mediasfu.com/images/svg/circle.svg\" alt=\"Circle\" class=\"shape-icon\" /> Circle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('triangle')\">\r\n <img src=\"https://mediasfu.com/images/svg/triangle.svg\" alt=\"Triangle\" class=\"shape-icon\" /> Triangle\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('hexagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/hexagon.svg\" alt=\"Hexagon\" class=\"shape-icon\" /> Hexagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('pentagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/pentagon.svg\" alt=\"Pentagon\" class=\"shape-icon\" /> Pentagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('rhombus')\">\r\n <img src=\"https://mediasfu.com/images/svg/rhombus.svg\" alt=\"Rhombus\" class=\"shape-icon\" /> Rhombus\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('octagon')\">\r\n <img src=\"https://mediasfu.com/images/svg/octagon.svg\" alt=\"Octagon\" class=\"shape-icon\" /> Octagon\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('oval')\">\r\n <img src=\"https://mediasfu.com/images/svg/oval.svg\" alt=\"Oval\" class=\"shape-icon\" /> Oval\r\n </button>\r\n <button class=\"dropdown-item\" (click)=\"setShapeMode('parallelogram')\">\r\n <img src=\"https://mediasfu.com/images/svg/parallelogram.svg\" alt=\"Parallelogram\" class=\"shape-icon\" /> Parallelogram\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Erase Mode Dropdown -->\r\n <div class=\"btn-group\" role=\"group\">\r\n <button class=\"btn btnBoardScreen btn-danger dropdown-toggle\" id=\"eraseModeScreen\" (click)=\"handleDropdownClick('eraseModeScreen')\">\r\n <fa-icon [icon]=\"faEraser\"></fa-icon>\r\n </button>\r\n <div *ngIf=\"dropdownOpen === 'eraseModeScreen'\" class=\"dropdown-menu show\">\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(5)\">X-Small (5px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(10)\">Small (10px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(20)\">Medium (20px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(30)\">Large (30px)</button>\r\n <button class=\"dropdown-item\" (click)=\"setEraseMode(60)\">X-Large (60px)</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Additional Toolbar Controls -->\r\n <button class=\"btn btnBoard btn-success\" id=\"zoomResetScreen\" style=\"display: none;\">\r\n <fa-icon [icon]=\"faSearch\"></fa-icon>\r\n </button>\r\n\r\n <input type=\"color\" class=\"btn\" id=\"colorPickerScreen\" [(ngModel)]=\"color\">\r\n <select id=\"lineTypePickerScreen\" class=\"custom-select\" style=\"width: auto;\" [(ngModel)]=\"lineType\">\r\n <option value=\"solid\">Solid</option>\r\n <option value=\"dashed\">Dashed</option>\r\n <option value=\"dotted\">Dotted</option>\r\n <option value=\"dashDot\">Dash-Dot</option>\r\n </select>\r\n </div>\r\n\r\n <canvas id=\"canvasRef\" width=\"1280\" height=\"720\" [ngStyle]=\"{'display': parameters.annotateScreenStream ? 'block' : 'none'}\" style=\"padding: 0; margin: 0;\" #canvasRef></canvas>\r\n </div>\r\n</div>\r\n", styles: [".dropdown-menu{position:absolute;top:100%;left:0;z-index:1050;display:none;min-width:11rem;padding:.5rem 0;margin:.25rem 0 0;font-size:.85rem;color:#e2e8f0;text-align:left;background:#0f172afa;border:1px solid rgba(148,163,184,.24);border-radius:10px;box-shadow:0 18px 40px #0f172a59;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}.dropdown-menu.show{display:block}.dropdown-item{display:block;width:100%;padding:.5rem 1rem;clear:both;font-weight:500;color:#e2e8f0;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{background-color:#3b82f62e;color:#fff}#whiteboardCanvas{border:1px solid #000;cursor:crosshair;background-color:#fff}.resize-handle,.move-handle{width:8px;height:8px;background:red;position:absolute}.move-handle{background:#00f}#textInput{display:none;position:absolute;z-index:10;width:200px}.shape-icon{width:20px;height:20px;color:#fff}.toolbar .btn-group button,.toolbar .dropdown-menu a{font-size:.8rem;padding:5px 10px;margin:0 2px;border-radius:4px;transition:background-color .2s}.toolbar .dropdown-menu a{background-color:transparent;color:#1b1a1a}.toolbar .btn-group button:hover,.toolbar .dropdown-menu a:hover{background-color:#e3e7eb}.toolbar .btn-group button.active{background-color:#454d55}.toolbarScreen .btn-group>button{font-size:.8rem;padding:5px 10px;margin:1px 2px;border-radius:4px;transition:background-color .2s;background-color:#ffffff14;color:#f8fafc}.toolbarScreen{display:flex;align-items:center;gap:6px;padding:8px 12px;border-radius:12px;background:#0f172aeb;border:1px solid rgba(148,163,184,.28);box-shadow:0 16px 32px #0f172a47;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}.toolbarScreen .btn-group>button{color:#f8fafc;border:1px solid rgba(148,163,184,.28)}.toolbarScreen .btn-group>button:hover,.toolbarScreen .btn-group>button:focus-visible{background-color:#ffffff2e;border-color:#bfdbfe80;color:#fff}.toolbarScreen .btn-group>button svg,.toolbarScreen .btn-group>button i,.toolbarScreen .btn-group>button fa-icon{color:inherit;fill:currentColor}.toolbarScreen .btn-group>button.active{background-color:#2563ebb8;border-color:#bfdbfe8c}.toolbarScreen .dropdown-item{display:flex;align-items:center;gap:.65rem}.toolbarScreen .dropdown-item .shape-icon{filter:brightness(0) invert(1)}.toolbarScreen .dropdown-item svg,.toolbarScreen .dropdown-item i,.toolbarScreen .dropdown-item fa-icon{color:inherit;fill:currentColor}#toolbar,#toolbarScreen{transition:display .3s ease-in-out}#toolbarToggle,#toolbarToggleScreen{cursor:pointer;border:\"2px solid black\"!important;font-size:.8rem}#colorPicker,#colorPickerScreen{font-size:.8rem;padding:2px;width:32px;height:32px;border:1px solid rgba(148,163,184,.28);border-radius:8px;background-color:#ffffff14}#lineTypePicker{font-size:.8rem;padding:2px auto;width:32px;height:32px}.btnBoard{font-size:1rem;padding:2px;width:40px;height:40px;margin:2px}#lineTypePickerScreen{font-size:.7rem;padding:0 .6rem;min-width:108px;width:auto;height:36px;background-color:#ffffff14;color:#f8fafc;border:1px solid rgba(148,163,184,.28);border-radius:8px}.toggle-icon{width:30px;height:30px;padding:0;margin:0}#toggleBackground.active{background-color:#fdfeff}.annotateScreenBtn{background-color:#2d2e2f!important;border:2px solid #000!important;color:green!important;font-size:.75rem}\n"] }]
29655
29705
  }], ctorParameters: () => [{ type: undefined, decorators: [{
29656
29706
  type: Optional
29657
29707
  }, {
@@ -48382,6 +48432,7 @@ class MediasfuGeneric {
48382
48432
  parameters: {
48383
48433
  ...this.getAllParams(),
48384
48434
  ...this.mediaSFUFunctions(),
48435
+ mediaDevices: navigator.mediaDevices,
48385
48436
  },
48386
48437
  }),
48387
48438
  activeColor: 'green',
@@ -61322,6 +61373,7 @@ class MediasfuWebinar {
61322
61373
  parameters: {
61323
61374
  ...this.getAllParams(),
61324
61375
  ...this.mediaSFUFunctions(),
61376
+ mediaDevices: navigator.mediaDevices,
61325
61377
  },
61326
61378
  }),
61327
61379
  activeColor: 'green',
@@ -67262,6 +67314,7 @@ class MediasfuConference {
67262
67314
  parameters: {
67263
67315
  ...this.getAllParams(),
67264
67316
  ...this.mediaSFUFunctions(),
67317
+ mediaDevices: navigator.mediaDevices,
67265
67318
  },
67266
67319
  }),
67267
67320
  activeColor: 'green',