mediasfu-angular 2.2.3 → 2.2.4
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.
- package/dist/fesm2022/mediasfu-angular.mjs +69 -19
- package/dist/fesm2022/mediasfu-angular.mjs.map +1 -1
- package/dist/lib/components/mediasfu-components/mediasfu-broadcast.component.d.ts +55 -55
- package/dist/lib/components/mediasfu-components/mediasfu-chat.component.d.ts +29 -29
- package/dist/lib/components/mediasfu-components/mediasfu-conference.component.d.ts +29 -29
- package/dist/lib/components/mediasfu-components/mediasfu-generic.component.d.ts +29 -29
- package/dist/lib/components/mediasfu-components/mediasfu-webinar.component.d.ts +27 -27
- package/dist/lib/components/message-components/message-panel/message-panel.component.d.ts +1 -0
- package/dist/lib/methods/message-methods/send-message.service.d.ts +1 -1
- package/package.json +2 -2
|
@@ -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,
|
|
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({
|
|
11296
|
-
|
|
11297
|
-
|
|
11298
|
-
|
|
11299
|
-
|
|
11300
|
-
|
|
11301
|
-
|
|
11302
|
-
|
|
11303
|
-
|
|
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
|
|
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=\"
|
|
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=\"
|
|
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: [{
|