@memberjunction/ng-mj-livekit-room 5.42.0 → 5.44.0

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.
@@ -58,6 +58,12 @@ export declare class MJLiveKitRoomComponent extends BaseAngularComponent impleme
58
58
  EnableAgentManagement: boolean;
59
59
  /** Show the "Invite" pill that copies a join link to this room. */
60
60
  EnableInvite: boolean;
61
+ /**
62
+ * Offer "End meeting for everyone" in the control bar's Zoom-style leave menu. When on (default) and a
63
+ * room is resolved, ending tears down every agent in the room server-side (by name — so it works even
64
+ * when this client only *joined*). Set `false` for contexts where only the local user should ever leave.
65
+ */
66
+ EnableEndForAll: boolean;
61
67
  /** Target agents the user can ADD in-room (id + name). The host (e.g. the Explorer resource) supplies these. */
62
68
  AvailableAgents: {
63
69
  ID: string;
@@ -93,6 +99,10 @@ export declare class MJLiveKitRoomComponent extends BaseAngularComponent impleme
93
99
  addingAgent: boolean;
94
100
  /** Last add error, shown under the picker. */
95
101
  addError: string | null;
102
+ /** True while an "End meeting" (stop all agents + leave) is in flight. */
103
+ endingMeeting: boolean;
104
+ /** The inner Generic room — used to trigger the local disconnect when ending/leaving the meeting. */
105
+ private roomComponent?;
96
106
  /** Available agents not already in the room (by target id) — the "Add" picker options. */
97
107
  get availableToAdd(): {
98
108
  ID: string;
@@ -188,6 +198,14 @@ export declare class MJLiveKitRoomComponent extends BaseAngularComponent impleme
188
198
  isRecording: boolean;
189
199
  /** The active egress id, when recording. */
190
200
  private currentEgressId;
201
+ /**
202
+ * The `MJ: Files` id of this room's meeting recording, when one exists — set when a recording is STOPPED
203
+ * (the server registers the egress MP4 and returns its file id) or resolved for an already-recorded room
204
+ * on join. Drives the {@link MJStorageMediaPlayerComponent} playback panel.
205
+ */
206
+ recordingFileId: string | null;
207
+ /** Whether the recording playback panel is shown (dismissable). */
208
+ showRecordingPanel: boolean;
191
209
  ngOnInit(): void;
192
210
  /**
193
211
  * Max time to wait for the connection to start before surfacing a retryable error, so a hung or very
@@ -213,6 +231,15 @@ export declare class MJLiveKitRoomComponent extends BaseAngularComponent impleme
213
231
  AddAgent(): Promise<void>;
214
232
  /** Removes an agent from the room — stops its bridge and drops it from the roster. */
215
233
  RemoveAgent(agent: AgentInRoom): Promise<void>;
234
+ /**
235
+ * **End meeting** (the Zoom/Teams "End for all", reached from the control-bar leave menu): tears down EVERY
236
+ * agent in the room server-side — *by room name*, so it works even when this client only **joined** the room
237
+ * and never tracked the bridge ids locally — then disconnects the local user. Contrast with **Leave** (the
238
+ * other menu item → {@link LiveKitRoomComponent.Leave}), which only disconnects YOU and lets the meeting
239
+ * continue; the server then auto-leaves the agents once the last human is gone, so neither path strands
240
+ * billable agent sessions in an empty room.
241
+ */
242
+ EndMeeting(): Promise<void>;
216
243
  /**
217
244
  * Builds the shareable invite URL for THIS room: the current page URL with a `room=<roomName>` query
218
245
  * param. Opening it lands the invitee on the Live Room in join mode for the same room.
@@ -224,9 +251,17 @@ export declare class MJLiveKitRoomComponent extends BaseAngularComponent impleme
224
251
  private joinRoom;
225
252
  /** Toggles room recording via the RealtimeBridge GraphQL surface (server-authorized egress). */
226
253
  onToggleRecording(): Promise<void>;
254
+ /**
255
+ * Resolves this room's already-registered meeting recording (if any) — the `MJ: Conversations` of
256
+ * `Type='Meeting Room'` keyed by the room name carries the `RecordingFileID`. Best-effort: any failure
257
+ * just leaves the playback panel hidden.
258
+ *
259
+ * @param roomName The LiveKit room name (= the Meeting-Room Conversation's `ExternalID`).
260
+ */
261
+ private loadExistingRecording;
227
262
  /** Records a failure and emits an error event. */
228
263
  private fail;
229
264
  static ɵfac: i0.ɵɵFactoryDeclaration<MJLiveKitRoomComponent, never>;
230
- static ɵcmp: i0.ɵɵComponentDeclaration<MJLiveKitRoomComponent, "mj-livekit-agent-room", never, { "Mode": { "alias": "Mode"; "required": false; }; "AgentID": { "alias": "AgentID"; "required": false; }; "AgentName": { "alias": "AgentName"; "required": false; }; "TargetAgentID": { "alias": "TargetAgentID"; "required": false; }; "RoomName": { "alias": "RoomName"; "required": false; }; "DisplayName": { "alias": "DisplayName"; "required": false; }; "TurnMode": { "alias": "TurnMode"; "required": false; }; "AutoStart": { "alias": "AutoStart"; "required": false; }; "EnableAgentManagement": { "alias": "EnableAgentManagement"; "required": false; }; "EnableInvite": { "alias": "EnableInvite"; "required": false; }; "AvailableAgents": { "alias": "AvailableAgents"; "required": false; }; "RealtimeModelID": { "alias": "RealtimeModelID"; "required": false; }; "RealtimeVoice": { "alias": "RealtimeVoice"; "required": false; }; "CanPickModelVoice": { "alias": "CanPickModelVoice"; "required": false; }; "AvailableModels": { "alias": "AvailableModels"; "required": false; }; "Layout": { "alias": "Layout"; "required": false; }; "Title": { "alias": "Title"; "required": false; }; "ShowHeader": { "alias": "ShowHeader"; "required": false; }; "ShowControlBar": { "alias": "ShowControlBar"; "required": false; }; "ShowChat": { "alias": "ShowChat"; "required": false; }; "ShowParticipantsPanel": { "alias": "ShowParticipantsPanel"; "required": false; }; "EnableMicrophoneControl": { "alias": "EnableMicrophoneControl"; "required": false; }; "EnableCameraControl": { "alias": "EnableCameraControl"; "required": false; }; "EnableScreenShareControl": { "alias": "EnableScreenShareControl"; "required": false; }; "EnableDeviceSettings": { "alias": "EnableDeviceSettings"; "required": false; }; "EnableLeaveControl": { "alias": "EnableLeaveControl"; "required": false; }; "StartWithMicrophone": { "alias": "StartWithMicrophone"; "required": false; }; "StartWithCamera": { "alias": "StartWithCamera"; "required": false; }; "AgentAvatarUrl": { "alias": "AgentAvatarUrl"; "required": false; }; "EnablePinning": { "alias": "EnablePinning"; "required": false; }; "EnableLayoutSwitcher": { "alias": "EnableLayoutSwitcher"; "required": false; }; "EnableNoiseFilter": { "alias": "EnableNoiseFilter"; "required": false; }; "EnableBackgroundEffects": { "alias": "EnableBackgroundEffects"; "required": false; }; "ShowAgentState": { "alias": "ShowAgentState"; "required": false; }; "ShowWhiteboard": { "alias": "ShowWhiteboard"; "required": false; }; "ShowPreJoin": { "alias": "ShowPreJoin"; "required": false; }; "EnableRecording": { "alias": "EnableRecording"; "required": false; }; "E2EEPassphrase": { "alias": "E2EEPassphrase"; "required": false; }; "E2EEWorker": { "alias": "E2EEWorker"; "required": false; }; "ConnectTimeoutMs": { "alias": "ConnectTimeoutMs"; "required": false; }; }, { "SessionStarted": "SessionStarted"; "InvitePeopleRequested": "InvitePeopleRequested"; "Connected": "Connected"; "Disconnected": "Disconnected"; "ParticipantJoined": "ParticipantJoined"; "ParticipantLeft": "ParticipantLeft"; "DataReceived": "DataReceived"; "ErrorOccurred": "ErrorOccurred"; }, never, never, true, never>;
265
+ static ɵcmp: i0.ɵɵComponentDeclaration<MJLiveKitRoomComponent, "mj-livekit-agent-room", never, { "Mode": { "alias": "Mode"; "required": false; }; "AgentID": { "alias": "AgentID"; "required": false; }; "AgentName": { "alias": "AgentName"; "required": false; }; "TargetAgentID": { "alias": "TargetAgentID"; "required": false; }; "RoomName": { "alias": "RoomName"; "required": false; }; "DisplayName": { "alias": "DisplayName"; "required": false; }; "TurnMode": { "alias": "TurnMode"; "required": false; }; "AutoStart": { "alias": "AutoStart"; "required": false; }; "EnableAgentManagement": { "alias": "EnableAgentManagement"; "required": false; }; "EnableInvite": { "alias": "EnableInvite"; "required": false; }; "EnableEndForAll": { "alias": "EnableEndForAll"; "required": false; }; "AvailableAgents": { "alias": "AvailableAgents"; "required": false; }; "RealtimeModelID": { "alias": "RealtimeModelID"; "required": false; }; "RealtimeVoice": { "alias": "RealtimeVoice"; "required": false; }; "CanPickModelVoice": { "alias": "CanPickModelVoice"; "required": false; }; "AvailableModels": { "alias": "AvailableModels"; "required": false; }; "Layout": { "alias": "Layout"; "required": false; }; "Title": { "alias": "Title"; "required": false; }; "ShowHeader": { "alias": "ShowHeader"; "required": false; }; "ShowControlBar": { "alias": "ShowControlBar"; "required": false; }; "ShowChat": { "alias": "ShowChat"; "required": false; }; "ShowParticipantsPanel": { "alias": "ShowParticipantsPanel"; "required": false; }; "EnableMicrophoneControl": { "alias": "EnableMicrophoneControl"; "required": false; }; "EnableCameraControl": { "alias": "EnableCameraControl"; "required": false; }; "EnableScreenShareControl": { "alias": "EnableScreenShareControl"; "required": false; }; "EnableDeviceSettings": { "alias": "EnableDeviceSettings"; "required": false; }; "EnableLeaveControl": { "alias": "EnableLeaveControl"; "required": false; }; "StartWithMicrophone": { "alias": "StartWithMicrophone"; "required": false; }; "StartWithCamera": { "alias": "StartWithCamera"; "required": false; }; "AgentAvatarUrl": { "alias": "AgentAvatarUrl"; "required": false; }; "EnablePinning": { "alias": "EnablePinning"; "required": false; }; "EnableLayoutSwitcher": { "alias": "EnableLayoutSwitcher"; "required": false; }; "EnableNoiseFilter": { "alias": "EnableNoiseFilter"; "required": false; }; "EnableBackgroundEffects": { "alias": "EnableBackgroundEffects"; "required": false; }; "ShowAgentState": { "alias": "ShowAgentState"; "required": false; }; "ShowWhiteboard": { "alias": "ShowWhiteboard"; "required": false; }; "ShowPreJoin": { "alias": "ShowPreJoin"; "required": false; }; "EnableRecording": { "alias": "EnableRecording"; "required": false; }; "E2EEPassphrase": { "alias": "E2EEPassphrase"; "required": false; }; "E2EEWorker": { "alias": "E2EEWorker"; "required": false; }; "ConnectTimeoutMs": { "alias": "ConnectTimeoutMs"; "required": false; }; }, { "SessionStarted": "SessionStarted"; "InvitePeopleRequested": "InvitePeopleRequested"; "Connected": "Connected"; "Disconnected": "Disconnected"; "ParticipantJoined": "ParticipantJoined"; "ParticipantLeft": "ParticipantLeft"; "DataReceived": "DataReceived"; "ErrorOccurred": "ErrorOccurred"; }, never, never, true, never>;
231
266
  }
232
267
  //# sourceMappingURL=mj-livekit-room.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mj-livekit-room.component.d.ts","sourceRoot":"","sources":["../../src/lib/mj-livekit-room.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mj-livekit-room.component.d.ts","sourceRoot":"","sources":["../../src/lib/mj-livekit-room.component.ts"],"names":[],"mappings":"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"}
@@ -1,226 +1,245 @@
1
- import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, inject } from '@angular/core';
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild, inject } from '@angular/core';
2
2
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
3
  import { UUIDsEqual } from '@memberjunction/global';
4
+ import { RunView } from '@memberjunction/core';
4
5
  import { GraphQLLiveKitClient } from '@memberjunction/graphql-dataprovider';
5
6
  import { LiveKitRoomComponent } from '@memberjunction/ng-livekit-room';
7
+ import { MJStorageMediaPlayerComponent } from '@memberjunction/ng-media-player';
6
8
  import * as i0 from "@angular/core";
7
9
  const _forTrack0 = ($index, $item) => $item.SessionBridgeID;
8
10
  const _forTrack1 = ($index, $item) => $item.ID;
9
11
  const _forTrack2 = ($index, $item) => $item.ModelID;
10
12
  function MJLiveKitRoomComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
11
- i0.ɵɵelementStart(0, "div", 0);
12
- i0.ɵɵelement(1, "i", 3);
13
+ const _r1 = i0.ɵɵgetCurrentView();
14
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 4)(2, "span", 5);
15
+ i0.ɵɵelement(3, "i", 6);
16
+ i0.ɵɵtext(4, " Meeting recording");
17
+ i0.ɵɵelementEnd();
18
+ i0.ɵɵelementStart(5, "button", 7);
19
+ i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_0_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showRecordingPanel = false); });
20
+ i0.ɵɵelement(6, "i", 8);
21
+ i0.ɵɵelementEnd()();
22
+ i0.ɵɵelement(7, "mj-storage-media-player", 9);
23
+ i0.ɵɵelementEnd();
24
+ } if (rf & 2) {
25
+ const ctx_r1 = i0.ɵɵnextContext();
26
+ i0.ɵɵadvance(7);
27
+ i0.ɵɵproperty("FileID", ctx_r1.recordingFileId)("Provider", ctx_r1.Provider);
28
+ } }
29
+ function MJLiveKitRoomComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
30
+ i0.ɵɵelementStart(0, "div", 1);
31
+ i0.ɵɵelement(1, "i", 10);
13
32
  i0.ɵɵelementStart(2, "span");
14
33
  i0.ɵɵtext(3);
15
34
  i0.ɵɵelementEnd()();
16
35
  } if (rf & 2) {
17
- const ctx_r0 = i0.ɵɵnextContext();
36
+ const ctx_r1 = i0.ɵɵnextContext();
18
37
  i0.ɵɵadvance(3);
19
- i0.ɵɵtextInterpolate(ctx_r0.Mode === "agent" ? "Starting agent session\u2026" : "Joining room\u2026");
38
+ i0.ɵɵtextInterpolate(ctx_r1.Mode === "agent" ? "Starting agent session\u2026" : "Joining room\u2026");
20
39
  } }
21
- function MJLiveKitRoomComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
22
- const _r2 = i0.ɵɵgetCurrentView();
23
- i0.ɵɵelementStart(0, "div", 1);
24
- i0.ɵɵelement(1, "i", 4);
40
+ function MJLiveKitRoomComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
41
+ const _r3 = i0.ɵɵgetCurrentView();
42
+ i0.ɵɵelementStart(0, "div", 2);
43
+ i0.ɵɵelement(1, "i", 11);
25
44
  i0.ɵɵelementStart(2, "span");
26
45
  i0.ɵɵtext(3);
27
46
  i0.ɵɵelementEnd();
28
- i0.ɵɵelementStart(4, "button", 5);
29
- i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_1_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.Start()); });
47
+ i0.ɵɵelementStart(4, "button", 12);
48
+ i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_2_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Start()); });
30
49
  i0.ɵɵtext(5, "Try again");
31
50
  i0.ɵɵelementEnd()();
32
51
  } if (rf & 2) {
33
- const ctx_r0 = i0.ɵɵnextContext();
52
+ const ctx_r1 = i0.ɵɵnextContext();
34
53
  i0.ɵɵadvance(3);
35
- i0.ɵɵtextInterpolate(ctx_r0.errorMessage);
54
+ i0.ɵɵtextInterpolate(ctx_r1.errorMessage);
36
55
  } }
37
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_For_4_Template(rf, ctx) { if (rf & 1) {
38
- const _r5 = i0.ɵɵgetCurrentView();
39
- i0.ɵɵelementStart(0, "div", 13)(1, "span", 15);
40
- i0.ɵɵelement(2, "i", 11);
56
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_For_4_Template(rf, ctx) { if (rf & 1) {
57
+ const _r6 = i0.ɵɵgetCurrentView();
58
+ i0.ɵɵelementStart(0, "div", 20)(1, "span", 22);
59
+ i0.ɵɵelement(2, "i", 18);
41
60
  i0.ɵɵtext(3);
42
61
  i0.ɵɵelementEnd();
43
- i0.ɵɵelementStart(4, "button", 16);
44
- i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_For_4_Template_button_click_4_listener() { const a_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.RemoveAgent(a_r6)); });
45
- i0.ɵɵelement(5, "i", 17);
62
+ i0.ɵɵelementStart(4, "button", 23);
63
+ i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_For_4_Template_button_click_4_listener() { const a_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.RemoveAgent(a_r7)); });
64
+ i0.ɵɵelement(5, "i", 24);
46
65
  i0.ɵɵelementEnd()();
47
66
  } if (rf & 2) {
48
- const a_r6 = ctx.$implicit;
67
+ const a_r7 = ctx.$implicit;
49
68
  i0.ɵɵadvance(3);
50
- i0.ɵɵtextInterpolate1(" ", a_r6.Name);
69
+ i0.ɵɵtextInterpolate1(" ", a_r7.Name);
51
70
  i0.ɵɵadvance();
52
- i0.ɵɵproperty("disabled", a_r6.Removing);
71
+ i0.ɵɵproperty("disabled", a_r7.Removing);
53
72
  i0.ɵɵadvance();
54
- i0.ɵɵclassProp("fa-xmark", !a_r6.Removing)("fa-spinner", a_r6.Removing)("fa-spin", a_r6.Removing);
73
+ i0.ɵɵclassProp("fa-xmark", !a_r7.Removing)("fa-spinner", a_r7.Removing)("fa-spin", a_r7.Removing);
55
74
  } }
56
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_For_5_Template(rf, ctx) { if (rf & 1) {
57
- i0.ɵɵelementStart(0, "option", 21);
75
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_For_5_Template(rf, ctx) { if (rf & 1) {
76
+ i0.ɵɵelementStart(0, "option", 28);
58
77
  i0.ɵɵtext(1);
59
78
  i0.ɵɵelementEnd();
60
79
  } if (rf & 2) {
61
- const a_r8 = ctx.$implicit;
62
- const ctx_r0 = i0.ɵɵnextContext(5);
63
- i0.ɵɵproperty("value", a_r8.ID)("selected", ctx_r0.UUIDsEqual(a_r8.ID, ctx_r0.addTargetId));
80
+ const a_r9 = ctx.$implicit;
81
+ const ctx_r1 = i0.ɵɵnextContext(5);
82
+ i0.ɵɵproperty("value", a_r9.ID)("selected", ctx_r1.UUIDsEqual(a_r9.ID, ctx_r1.addTargetId));
64
83
  i0.ɵɵadvance();
65
- i0.ɵɵtextInterpolate(a_r8.Name);
84
+ i0.ɵɵtextInterpolate(a_r9.Name);
66
85
  } }
67
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_For_5_Template(rf, ctx) { if (rf & 1) {
68
- i0.ɵɵelementStart(0, "option", 21);
86
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_For_5_Template(rf, ctx) { if (rf & 1) {
87
+ i0.ɵɵelementStart(0, "option", 28);
69
88
  i0.ɵɵtext(1);
70
89
  i0.ɵɵelementEnd();
71
90
  } if (rf & 2) {
72
- const m_r10 = ctx.$implicit;
73
- const ctx_r0 = i0.ɵɵnextContext(6);
74
- i0.ɵɵproperty("value", m_r10.ModelID)("selected", ctx_r0.UUIDsEqual(m_r10.ModelID, ctx_r0.addModelId));
91
+ const m_r11 = ctx.$implicit;
92
+ const ctx_r1 = i0.ɵɵnextContext(6);
93
+ i0.ɵɵproperty("value", m_r11.ModelID)("selected", ctx_r1.UUIDsEqual(m_r11.ModelID, ctx_r1.addModelId));
75
94
  i0.ɵɵadvance();
76
- i0.ɵɵtextInterpolate(m_r10.ModelName);
95
+ i0.ɵɵtextInterpolate(m_r11.ModelName);
77
96
  } }
78
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_For_4_Template(rf, ctx) { if (rf & 1) {
79
- i0.ɵɵelementStart(0, "option", 21);
97
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_For_4_Template(rf, ctx) { if (rf & 1) {
98
+ i0.ɵɵelementStart(0, "option", 28);
80
99
  i0.ɵɵtext(1);
81
100
  i0.ɵɵelementEnd();
82
101
  } if (rf & 2) {
83
- const v_r12 = ctx.$implicit;
84
- const ctx_r0 = i0.ɵɵnextContext(7);
85
- i0.ɵɵproperty("value", v_r12.ID)("selected", v_r12.ID === ctx_r0.addVoice);
102
+ const v_r13 = ctx.$implicit;
103
+ const ctx_r1 = i0.ɵɵnextContext(7);
104
+ i0.ɵɵproperty("value", v_r13.ID)("selected", v_r13.ID === ctx_r1.addVoice);
86
105
  i0.ɵɵadvance();
87
- i0.ɵɵtextInterpolate(v_r12.Name);
106
+ i0.ɵɵtextInterpolate(v_r13.Name);
88
107
  } }
89
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_Template(rf, ctx) { if (rf & 1) {
90
- const _r11 = i0.ɵɵgetCurrentView();
91
- i0.ɵɵelementStart(0, "select", 26);
92
- i0.ɵɵlistener("change", function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_Template_select_change_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r0.onAddVoiceChange($event)); });
93
- i0.ɵɵelementStart(1, "option", 20);
108
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_Template(rf, ctx) { if (rf & 1) {
109
+ const _r12 = i0.ɵɵgetCurrentView();
110
+ i0.ɵɵelementStart(0, "select", 33);
111
+ i0.ɵɵlistener("change", function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_Template_select_change_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r1.onAddVoiceChange($event)); });
112
+ i0.ɵɵelementStart(1, "option", 27);
94
113
  i0.ɵɵtext(2, "Default voice");
95
114
  i0.ɵɵelementEnd();
96
- i0.ɵɵrepeaterCreate(3, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_For_4_Template, 2, 3, "option", 21, _forTrack1);
115
+ i0.ɵɵrepeaterCreate(3, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_For_4_Template, 2, 3, "option", 28, _forTrack1);
97
116
  i0.ɵɵelementEnd();
98
117
  } if (rf & 2) {
99
- const ctx_r0 = i0.ɵɵnextContext(6);
118
+ const ctx_r1 = i0.ɵɵnextContext(6);
100
119
  i0.ɵɵadvance(3);
101
- i0.ɵɵrepeater(ctx_r0.addVoices);
120
+ i0.ɵɵrepeater(ctx_r1.addVoices);
102
121
  } }
103
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Template(rf, ctx) { if (rf & 1) {
104
- const _r9 = i0.ɵɵgetCurrentView();
105
- i0.ɵɵelementStart(0, "div", 23)(1, "select", 24);
106
- i0.ɵɵlistener("change", function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Template_select_change_1_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.onAddModelChange($event)); });
107
- i0.ɵɵelementStart(2, "option", 20);
122
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Template(rf, ctx) { if (rf & 1) {
123
+ const _r10 = i0.ɵɵgetCurrentView();
124
+ i0.ɵɵelementStart(0, "div", 30)(1, "select", 31);
125
+ i0.ɵɵlistener("change", function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Template_select_change_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onAddModelChange($event)); });
126
+ i0.ɵɵelementStart(2, "option", 27);
108
127
  i0.ɵɵtext(3, "Default model");
109
128
  i0.ɵɵelementEnd();
110
- i0.ɵɵrepeaterCreate(4, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_For_5_Template, 2, 3, "option", 21, _forTrack2);
129
+ i0.ɵɵrepeaterCreate(4, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_For_5_Template, 2, 3, "option", 28, _forTrack2);
111
130
  i0.ɵɵelementEnd();
112
- i0.ɵɵconditionalCreate(6, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_Template, 5, 0, "select", 25);
131
+ i0.ɵɵconditionalCreate(6, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Conditional_6_Template, 5, 0, "select", 32);
113
132
  i0.ɵɵelementEnd();
114
133
  } if (rf & 2) {
115
- const ctx_r0 = i0.ɵɵnextContext(5);
134
+ const ctx_r1 = i0.ɵɵnextContext(5);
116
135
  i0.ɵɵadvance(4);
117
- i0.ɵɵrepeater(ctx_r0.AvailableModels);
136
+ i0.ɵɵrepeater(ctx_r1.AvailableModels);
118
137
  i0.ɵɵadvance(2);
119
- i0.ɵɵconditional(ctx_r0.addVoices.length ? 6 : -1);
138
+ i0.ɵɵconditional(ctx_r1.addVoices.length ? 6 : -1);
120
139
  } }
121
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
122
- const _r7 = i0.ɵɵgetCurrentView();
123
- i0.ɵɵelementStart(0, "div", 18)(1, "select", 19);
124
- i0.ɵɵlistener("change", function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Template_select_change_1_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onAddTargetChange($event)); });
125
- i0.ɵɵelementStart(2, "option", 20);
140
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
141
+ const _r8 = i0.ɵɵgetCurrentView();
142
+ i0.ɵɵelementStart(0, "div", 25)(1, "select", 26);
143
+ i0.ɵɵlistener("change", function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Template_select_change_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.onAddTargetChange($event)); });
144
+ i0.ɵɵelementStart(2, "option", 27);
126
145
  i0.ɵɵtext(3, "Add an agent\u2026");
127
146
  i0.ɵɵelementEnd();
128
- i0.ɵɵrepeaterCreate(4, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_For_5_Template, 2, 3, "option", 21, _forTrack1);
147
+ i0.ɵɵrepeaterCreate(4, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_For_5_Template, 2, 3, "option", 28, _forTrack1);
129
148
  i0.ɵɵelementEnd();
130
- i0.ɵɵelementStart(6, "button", 22);
131
- i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.AddAgent()); });
132
- i0.ɵɵelement(7, "i", 17);
149
+ i0.ɵɵelementStart(6, "button", 29);
150
+ i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.AddAgent()); });
151
+ i0.ɵɵelement(7, "i", 24);
133
152
  i0.ɵɵelementEnd()();
134
- i0.ɵɵconditionalCreate(8, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Template, 7, 1, "div", 23);
153
+ i0.ɵɵconditionalCreate(8, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Conditional_8_Template, 7, 1, "div", 30);
135
154
  } if (rf & 2) {
136
- const ctx_r0 = i0.ɵɵnextContext(4);
155
+ const ctx_r1 = i0.ɵɵnextContext(4);
137
156
  i0.ɵɵadvance(4);
138
- i0.ɵɵrepeater(ctx_r0.availableToAdd);
157
+ i0.ɵɵrepeater(ctx_r1.availableToAdd);
139
158
  i0.ɵɵadvance(2);
140
- i0.ɵɵproperty("disabled", !ctx_r0.addTargetId || ctx_r0.addingAgent);
159
+ i0.ɵɵproperty("disabled", !ctx_r1.addTargetId || ctx_r1.addingAgent);
141
160
  i0.ɵɵadvance();
142
- i0.ɵɵclassProp("fa-plus", !ctx_r0.addingAgent)("fa-spinner", ctx_r0.addingAgent)("fa-spin", ctx_r0.addingAgent);
161
+ i0.ɵɵclassProp("fa-plus", !ctx_r1.addingAgent)("fa-spinner", ctx_r1.addingAgent)("fa-spin", ctx_r1.addingAgent);
143
162
  i0.ɵɵadvance();
144
- i0.ɵɵconditional(ctx_r0.CanPickModelVoice && ctx_r0.AvailableModels.length ? 8 : -1);
163
+ i0.ɵɵconditional(ctx_r1.CanPickModelVoice && ctx_r1.AvailableModels.length ? 8 : -1);
145
164
  } }
146
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
147
- i0.ɵɵelementStart(0, "div", 14);
165
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
166
+ i0.ɵɵelementStart(0, "div", 21);
148
167
  i0.ɵɵtext(1);
149
168
  i0.ɵɵelementEnd();
150
169
  } if (rf & 2) {
151
- const ctx_r0 = i0.ɵɵnextContext(4);
170
+ const ctx_r1 = i0.ɵɵnextContext(4);
152
171
  i0.ɵɵadvance();
153
- i0.ɵɵtextInterpolate(ctx_r0.addError);
172
+ i0.ɵɵtextInterpolate(ctx_r1.addError);
154
173
  } }
155
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
156
- i0.ɵɵelementStart(0, "div", 8)(1, "div", 12);
174
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
175
+ i0.ɵɵelementStart(0, "div", 15)(1, "div", 19);
157
176
  i0.ɵɵtext(2, "In this room");
158
177
  i0.ɵɵelementEnd();
159
- i0.ɵɵrepeaterCreate(3, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_For_4_Template, 6, 8, "div", 13, _forTrack0);
160
- i0.ɵɵconditionalCreate(5, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_5_Template, 9, 8);
161
- i0.ɵɵconditionalCreate(6, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Conditional_6_Template, 2, 1, "div", 14);
178
+ i0.ɵɵrepeaterCreate(3, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_For_4_Template, 6, 8, "div", 20, _forTrack0);
179
+ i0.ɵɵconditionalCreate(5, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_5_Template, 9, 8);
180
+ i0.ɵɵconditionalCreate(6, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Conditional_6_Template, 2, 1, "div", 21);
162
181
  i0.ɵɵelementEnd();
163
182
  } if (rf & 2) {
164
- const ctx_r0 = i0.ɵɵnextContext(3);
183
+ const ctx_r1 = i0.ɵɵnextContext(3);
165
184
  i0.ɵɵadvance(3);
166
- i0.ɵɵrepeater(ctx_r0.agentsInRoom);
185
+ i0.ɵɵrepeater(ctx_r1.agentsInRoom);
167
186
  i0.ɵɵadvance(2);
168
- i0.ɵɵconditional(ctx_r0.availableToAdd.length ? 5 : -1);
187
+ i0.ɵɵconditional(ctx_r1.availableToAdd.length ? 5 : -1);
169
188
  i0.ɵɵadvance();
170
- i0.ɵɵconditional(ctx_r0.addError ? 6 : -1);
189
+ i0.ɵɵconditional(ctx_r1.addError ? 6 : -1);
171
190
  } }
172
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
173
- const _r13 = i0.ɵɵgetCurrentView();
174
- i0.ɵɵelementStart(0, "button", 27);
175
- i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.CopyInvite()); });
176
- i0.ɵɵelement(1, "i", 17);
191
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
192
+ const _r14 = i0.ɵɵgetCurrentView();
193
+ i0.ɵɵelementStart(0, "button", 34);
194
+ i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CopyInvite()); });
195
+ i0.ɵɵelement(1, "i", 24);
177
196
  i0.ɵɵtext(2);
178
197
  i0.ɵɵelementEnd();
179
- i0.ɵɵelementStart(3, "button", 28);
180
- i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_6_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.InvitePeopleRequested.emit(ctx_r0.resolvedRoomName)); });
181
- i0.ɵɵelement(4, "i", 29);
198
+ i0.ɵɵelementStart(3, "button", 35);
199
+ i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_6_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.InvitePeopleRequested.emit(ctx_r1.resolvedRoomName)); });
200
+ i0.ɵɵelement(4, "i", 36);
182
201
  i0.ɵɵtext(5, " Invite people ");
183
202
  i0.ɵɵelementEnd();
184
203
  } if (rf & 2) {
185
- const ctx_r0 = i0.ɵɵnextContext(3);
204
+ const ctx_r1 = i0.ɵɵnextContext(3);
186
205
  i0.ɵɵadvance();
187
- i0.ɵɵclassProp("fa-link", !ctx_r0.inviteCopied)("fa-check", ctx_r0.inviteCopied);
206
+ i0.ɵɵclassProp("fa-link", !ctx_r1.inviteCopied)("fa-check", ctx_r1.inviteCopied);
188
207
  i0.ɵɵadvance();
189
- i0.ɵɵtextInterpolate1(" ", ctx_r0.inviteCopied ? "Link copied" : "Copy link", " ");
208
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.inviteCopied ? "Link copied" : "Copy link", " ");
190
209
  } }
191
- function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
192
- const _r4 = i0.ɵɵgetCurrentView();
193
- i0.ɵɵelementStart(0, "div", 7);
194
- i0.ɵɵconditionalCreate(1, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_1_Template, 7, 2, "div", 8);
195
- i0.ɵɵelementStart(2, "div", 9)(3, "button", 10);
196
- i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_2_Conditional_2_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.showAgentsPanel = !ctx_r0.showAgentsPanel); });
197
- i0.ɵɵelement(4, "i", 11);
210
+ function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
211
+ const _r5 = i0.ɵɵgetCurrentView();
212
+ i0.ɵɵelementStart(0, "div", 14);
213
+ i0.ɵɵconditionalCreate(1, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_1_Template, 7, 2, "div", 15);
214
+ i0.ɵɵelementStart(2, "div", 16)(3, "button", 17);
215
+ i0.ɵɵlistener("click", function MJLiveKitRoomComponent_Conditional_3_Conditional_2_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.showAgentsPanel = !ctx_r1.showAgentsPanel); });
216
+ i0.ɵɵelement(4, "i", 18);
198
217
  i0.ɵɵtext(5);
199
218
  i0.ɵɵelementEnd();
200
- i0.ɵɵconditionalCreate(6, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Conditional_6_Template, 6, 5);
219
+ i0.ɵɵconditionalCreate(6, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Conditional_6_Template, 6, 5);
201
220
  i0.ɵɵelementEnd()();
202
221
  } if (rf & 2) {
203
- const ctx_r0 = i0.ɵɵnextContext(2);
222
+ const ctx_r1 = i0.ɵɵnextContext(2);
204
223
  i0.ɵɵadvance();
205
- i0.ɵɵconditional(ctx_r0.showAgentsPanel ? 1 : -1);
224
+ i0.ɵɵconditional(ctx_r1.showAgentsPanel ? 1 : -1);
206
225
  i0.ɵɵadvance(4);
207
- i0.ɵɵtextInterpolate1(" Agents (", ctx_r0.agentsInRoom.length, ") ");
226
+ i0.ɵɵtextInterpolate1(" Agents (", ctx_r1.agentsInRoom.length, ") ");
208
227
  i0.ɵɵadvance();
209
- i0.ɵɵconditional(ctx_r0.EnableInvite ? 6 : -1);
228
+ i0.ɵɵconditional(ctx_r1.EnableInvite ? 6 : -1);
210
229
  } }
211
- function MJLiveKitRoomComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
212
- const _r3 = i0.ɵɵgetCurrentView();
213
- i0.ɵɵelementStart(0, "div", 2)(1, "mj-livekit-room", 6);
214
- i0.ɵɵlistener("Connected", function MJLiveKitRoomComponent_Conditional_2_Template_mj_livekit_room_Connected_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.Connected.emit($event)); })("Disconnected", function MJLiveKitRoomComponent_Conditional_2_Template_mj_livekit_room_Disconnected_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.Disconnected.emit($event)); })("ParticipantJoined", function MJLiveKitRoomComponent_Conditional_2_Template_mj_livekit_room_ParticipantJoined_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.ParticipantJoined.emit($event)); })("ParticipantLeft", function MJLiveKitRoomComponent_Conditional_2_Template_mj_livekit_room_ParticipantLeft_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.ParticipantLeft.emit($event)); })("DataReceived", function MJLiveKitRoomComponent_Conditional_2_Template_mj_livekit_room_DataReceived_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.DataReceived.emit($event)); })("ToggleRecording", function MJLiveKitRoomComponent_Conditional_2_Template_mj_livekit_room_ToggleRecording_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onToggleRecording()); })("ErrorOccurred", function MJLiveKitRoomComponent_Conditional_2_Template_mj_livekit_room_ErrorOccurred_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.ErrorOccurred.emit($event)); });
230
+ function MJLiveKitRoomComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
231
+ const _r4 = i0.ɵɵgetCurrentView();
232
+ i0.ɵɵelementStart(0, "div", 3)(1, "mj-livekit-room", 13);
233
+ i0.ɵɵlistener("Connected", function MJLiveKitRoomComponent_Conditional_3_Template_mj_livekit_room_Connected_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Connected.emit($event)); })("Disconnected", function MJLiveKitRoomComponent_Conditional_3_Template_mj_livekit_room_Disconnected_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Disconnected.emit($event)); })("EndForAll", function MJLiveKitRoomComponent_Conditional_3_Template_mj_livekit_room_EndForAll_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.EndMeeting()); })("ParticipantJoined", function MJLiveKitRoomComponent_Conditional_3_Template_mj_livekit_room_ParticipantJoined_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ParticipantJoined.emit($event)); })("ParticipantLeft", function MJLiveKitRoomComponent_Conditional_3_Template_mj_livekit_room_ParticipantLeft_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ParticipantLeft.emit($event)); })("DataReceived", function MJLiveKitRoomComponent_Conditional_3_Template_mj_livekit_room_DataReceived_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.DataReceived.emit($event)); })("ToggleRecording", function MJLiveKitRoomComponent_Conditional_3_Template_mj_livekit_room_ToggleRecording_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onToggleRecording()); })("ErrorOccurred", function MJLiveKitRoomComponent_Conditional_3_Template_mj_livekit_room_ErrorOccurred_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ErrorOccurred.emit($event)); });
215
234
  i0.ɵɵelementEnd();
216
- i0.ɵɵconditionalCreate(2, MJLiveKitRoomComponent_Conditional_2_Conditional_2_Template, 7, 3, "div", 7);
235
+ i0.ɵɵconditionalCreate(2, MJLiveKitRoomComponent_Conditional_3_Conditional_2_Template, 7, 3, "div", 14);
217
236
  i0.ɵɵelementEnd();
218
237
  } if (rf & 2) {
219
- const ctx_r0 = i0.ɵɵnextContext();
238
+ const ctx_r1 = i0.ɵɵnextContext();
220
239
  i0.ɵɵadvance();
221
- i0.ɵɵproperty("ServerUrl", ctx_r0.serverUrl)("Token", ctx_r0.token)("DisplayName", ctx_r0.resolvedDisplayName)("AutoConnect", true)("StartWithMicrophone", ctx_r0.StartWithMicrophone)("StartWithCamera", ctx_r0.StartWithCamera)("Layout", ctx_r0.Layout)("Title", ctx_r0.Title)("ShowHeader", ctx_r0.ShowHeader)("ShowControlBar", ctx_r0.ShowControlBar)("ShowChat", ctx_r0.ShowChat)("ShowParticipantsPanel", ctx_r0.ShowParticipantsPanel)("EnableMicrophoneControl", ctx_r0.EnableMicrophoneControl)("EnableCameraControl", ctx_r0.EnableCameraControl)("EnableScreenShareControl", ctx_r0.EnableScreenShareControl)("EnableDeviceSettings", ctx_r0.EnableDeviceSettings)("EnableLeaveControl", ctx_r0.EnableLeaveControl)("EnablePinning", ctx_r0.EnablePinning)("EnableLayoutSwitcher", ctx_r0.EnableLayoutSwitcher)("EnableNoiseFilter", ctx_r0.EnableNoiseFilter)("EnableBackgroundEffects", ctx_r0.EnableBackgroundEffects)("ShowAgentState", ctx_r0.ShowAgentState)("ShowWhiteboard", ctx_r0.ShowWhiteboard)("ShowPreJoin", ctx_r0.ShowPreJoin)("ShowRecordingControl", ctx_r0.EnableRecording)("IsRecording", ctx_r0.isRecording)("E2EEPassphrase", ctx_r0.E2EEPassphrase)("E2EEWorker", ctx_r0.E2EEWorker)("AgentAvatarUrl", ctx_r0.AgentAvatarUrl);
240
+ i0.ɵɵproperty("ServerUrl", ctx_r1.serverUrl)("Token", ctx_r1.token)("DisplayName", ctx_r1.resolvedDisplayName)("AutoConnect", true)("StartWithMicrophone", ctx_r1.StartWithMicrophone)("StartWithCamera", ctx_r1.StartWithCamera)("Layout", ctx_r1.Layout)("Title", ctx_r1.Title)("ShowHeader", ctx_r1.ShowHeader)("ShowControlBar", ctx_r1.ShowControlBar)("ShowChat", ctx_r1.ShowChat)("ShowParticipantsPanel", ctx_r1.ShowParticipantsPanel)("EnableMicrophoneControl", ctx_r1.EnableMicrophoneControl)("EnableCameraControl", ctx_r1.EnableCameraControl)("EnableScreenShareControl", ctx_r1.EnableScreenShareControl)("EnableDeviceSettings", ctx_r1.EnableDeviceSettings)("EnableLeaveControl", ctx_r1.EnableLeaveControl)("EnablePinning", ctx_r1.EnablePinning)("EnableLayoutSwitcher", ctx_r1.EnableLayoutSwitcher)("EnableNoiseFilter", ctx_r1.EnableNoiseFilter)("EnableBackgroundEffects", ctx_r1.EnableBackgroundEffects)("ShowAgentState", ctx_r1.ShowAgentState)("ShowWhiteboard", ctx_r1.ShowWhiteboard)("ShowPreJoin", ctx_r1.ShowPreJoin)("ShowRecordingControl", ctx_r1.EnableRecording)("IsRecording", ctx_r1.isRecording)("E2EEPassphrase", ctx_r1.E2EEPassphrase)("E2EEWorker", ctx_r1.E2EEWorker)("AgentAvatarUrl", ctx_r1.AgentAvatarUrl)("CanEndForAll", ctx_r1.EnableEndForAll && !!ctx_r1.resolvedRoomName);
222
241
  i0.ɵɵadvance();
223
- i0.ɵɵconditional(ctx_r0.Mode === "agent" && ctx_r0.EnableAgentManagement && ctx_r0.resolvedRoomName ? 2 : -1);
242
+ i0.ɵɵconditional(ctx_r1.Mode === "agent" && ctx_r1.EnableAgentManagement && ctx_r1.resolvedRoomName ? 2 : -1);
224
243
  } }
225
244
  /**
226
245
  * `mj-livekit-agent-room` — the MemberJunction binding for the LiveKit room UI. It resolves a scoped
@@ -257,6 +276,12 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
257
276
  EnableAgentManagement = true;
258
277
  /** Show the "Invite" pill that copies a join link to this room. */
259
278
  EnableInvite = true;
279
+ /**
280
+ * Offer "End meeting for everyone" in the control bar's Zoom-style leave menu. When on (default) and a
281
+ * room is resolved, ending tears down every agent in the room server-side (by name — so it works even
282
+ * when this client only *joined*). Set `false` for contexts where only the local user should ever leave.
283
+ */
284
+ EnableEndForAll = true;
260
285
  /** Target agents the user can ADD in-room (id + name). The host (e.g. the Explorer resource) supplies these. */
261
286
  AvailableAgents = [];
262
287
  /** Per-session Realtime MODEL override for the INITIAL agent (from the host's pre-join picker). */
@@ -289,6 +314,10 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
289
314
  addingAgent = false;
290
315
  /** Last add error, shown under the picker. */
291
316
  addError = null;
317
+ /** True while an "End meeting" (stop all agents + leave) is in flight. */
318
+ endingMeeting = false;
319
+ /** The inner Generic room — used to trigger the local disconnect when ending/leaving the meeting. */
320
+ roomComponent;
292
321
  /** Available agents not already in the room (by target id) — the "Add" picker options. */
293
322
  get availableToAdd() {
294
323
  const present = new Set(this.agentsInRoom.map((a) => (a.TargetAgentID ?? '').toLowerCase()));
@@ -395,10 +424,22 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
395
424
  isRecording = false;
396
425
  /** The active egress id, when recording. */
397
426
  currentEgressId = null;
427
+ /**
428
+ * The `MJ: Files` id of this room's meeting recording, when one exists — set when a recording is STOPPED
429
+ * (the server registers the egress MP4 and returns its file id) or resolved for an already-recorded room
430
+ * on join. Drives the {@link MJStorageMediaPlayerComponent} playback panel.
431
+ */
432
+ recordingFileId = null;
433
+ /** Whether the recording playback panel is shown (dismissable). */
434
+ showRecordingPanel = true;
398
435
  ngOnInit() {
399
436
  if (this.AutoStart) {
400
437
  void this.Start();
401
438
  }
439
+ // If this room already has a registered recording (e.g. joining/reviewing a past room), surface it.
440
+ if (this.RoomName) {
441
+ void this.loadExistingRecording(this.RoomName);
442
+ }
402
443
  }
403
444
  /**
404
445
  * Max time to wait for the connection to start before surfacing a retryable error, so a hung or very
@@ -463,6 +504,8 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
463
504
  this.serverUrl = result.ServerUrl;
464
505
  this.token = result.ClientToken;
465
506
  this.resolvedRoomName = result.RoomName;
507
+ // Surface a prior recording for this resolved room (the server may have generated the room name).
508
+ void this.loadExistingRecording(result.RoomName);
466
509
  // Track the agent we just brought in as the first entry in the in-room roster.
467
510
  this.agentsInRoom = [
468
511
  { SessionBridgeID: result.SessionBridgeID, TargetAgentID: this.TargetAgentID, Name: this.AgentName ?? 'Agent' },
@@ -541,6 +584,36 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
541
584
  this.cdr.markForCheck();
542
585
  }
543
586
  }
587
+ /**
588
+ * **End meeting** (the Zoom/Teams "End for all", reached from the control-bar leave menu): tears down EVERY
589
+ * agent in the room server-side — *by room name*, so it works even when this client only **joined** the room
590
+ * and never tracked the bridge ids locally — then disconnects the local user. Contrast with **Leave** (the
591
+ * other menu item → {@link LiveKitRoomComponent.Leave}), which only disconnects YOU and lets the meeting
592
+ * continue; the server then auto-leaves the agents once the last human is gone, so neither path strands
593
+ * billable agent sessions in an empty room.
594
+ */
595
+ async EndMeeting() {
596
+ if (this.endingMeeting) {
597
+ return;
598
+ }
599
+ this.endingMeeting = true;
600
+ this.cdr.markForCheck();
601
+ try {
602
+ if (this.resolvedRoomName) {
603
+ const client = new GraphQLLiveKitClient(this.ProviderToUse);
604
+ await client.EndRoom(this.resolvedRoomName);
605
+ }
606
+ this.agentsInRoom = [];
607
+ }
608
+ catch {
609
+ /* best-effort — fall through and still disconnect the local user */
610
+ }
611
+ finally {
612
+ await this.roomComponent?.Leave();
613
+ this.endingMeeting = false;
614
+ this.cdr.markForCheck();
615
+ }
616
+ }
544
617
  /**
545
618
  * Builds the shareable invite URL for THIS room: the current page URL with a `room=<roomName>` query
546
619
  * param. Opening it lands the invitee on the Live Room in join mode for the same room.
@@ -600,27 +673,80 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
600
673
  }
601
674
  }
602
675
  else if (this.currentEgressId) {
603
- await client.StopRecording(this.currentEgressId);
676
+ const stopped = await client.StopRecording(this.currentEgressId);
604
677
  this.isRecording = false;
605
678
  this.currentEgressId = null;
679
+ // The server registers the egress MP4 as an MJ: Files row on stop and returns its id — surface it
680
+ // in the playback panel. Absent when meeting-recording storage isn't configured server-side.
681
+ if (stopped.Success && stopped.RecordingFileID) {
682
+ this.recordingFileId = stopped.RecordingFileID;
683
+ this.showRecordingPanel = true;
684
+ }
606
685
  }
607
686
  this.cdr.markForCheck();
608
687
  }
688
+ /**
689
+ * Resolves this room's already-registered meeting recording (if any) — the `MJ: Conversations` of
690
+ * `Type='Meeting Room'` keyed by the room name carries the `RecordingFileID`. Best-effort: any failure
691
+ * just leaves the playback panel hidden.
692
+ *
693
+ * @param roomName The LiveKit room name (= the Meeting-Room Conversation's `ExternalID`).
694
+ */
695
+ async loadExistingRecording(roomName) {
696
+ try {
697
+ const escaped = roomName.replace(/'/g, "''");
698
+ const result = await RunView.FromMetadataProvider(this.ProviderToUse).RunView({
699
+ EntityName: 'MJ: Conversations',
700
+ ExtraFilter: `ExternalID='${escaped}' AND Type='Meeting Room' AND RecordingFileID IS NOT NULL`,
701
+ Fields: ['RecordingFileID'],
702
+ OrderBy: '__mj_CreatedAt DESC',
703
+ MaxRows: 1,
704
+ ResultType: 'simple',
705
+ }, this.ProviderToUse.CurrentUser);
706
+ const fileId = result.Success ? result.Results[0]?.RecordingFileID ?? null : null;
707
+ if (fileId) {
708
+ this.recordingFileId = fileId;
709
+ this.cdr.markForCheck();
710
+ }
711
+ }
712
+ catch {
713
+ // best-effort — no recording panel
714
+ }
715
+ }
609
716
  /** Records a failure and emits an error event. */
610
717
  fail(message) {
611
718
  this.errorMessage = message;
612
719
  this.ErrorOccurred.emit({ Kind: 'connect', Message: message });
613
720
  }
614
721
  static ɵfac = /*@__PURE__*/ (() => { let ɵMJLiveKitRoomComponent_BaseFactory; return function MJLiveKitRoomComponent_Factory(__ngFactoryType__) { return (ɵMJLiveKitRoomComponent_BaseFactory || (ɵMJLiveKitRoomComponent_BaseFactory = i0.ɵɵgetInheritedFactory(MJLiveKitRoomComponent)))(__ngFactoryType__ || MJLiveKitRoomComponent); }; })();
615
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJLiveKitRoomComponent, selectors: [["mj-livekit-agent-room"]], inputs: { Mode: "Mode", AgentID: "AgentID", AgentName: "AgentName", TargetAgentID: "TargetAgentID", RoomName: "RoomName", DisplayName: "DisplayName", TurnMode: "TurnMode", AutoStart: "AutoStart", EnableAgentManagement: "EnableAgentManagement", EnableInvite: "EnableInvite", AvailableAgents: "AvailableAgents", RealtimeModelID: "RealtimeModelID", RealtimeVoice: "RealtimeVoice", CanPickModelVoice: "CanPickModelVoice", AvailableModels: "AvailableModels", Layout: "Layout", Title: "Title", ShowHeader: "ShowHeader", ShowControlBar: "ShowControlBar", ShowChat: "ShowChat", ShowParticipantsPanel: "ShowParticipantsPanel", EnableMicrophoneControl: "EnableMicrophoneControl", EnableCameraControl: "EnableCameraControl", EnableScreenShareControl: "EnableScreenShareControl", EnableDeviceSettings: "EnableDeviceSettings", EnableLeaveControl: "EnableLeaveControl", StartWithMicrophone: "StartWithMicrophone", StartWithCamera: "StartWithCamera", AgentAvatarUrl: "AgentAvatarUrl", EnablePinning: "EnablePinning", EnableLayoutSwitcher: "EnableLayoutSwitcher", EnableNoiseFilter: "EnableNoiseFilter", EnableBackgroundEffects: "EnableBackgroundEffects", ShowAgentState: "ShowAgentState", ShowWhiteboard: "ShowWhiteboard", ShowPreJoin: "ShowPreJoin", EnableRecording: "EnableRecording", E2EEPassphrase: "E2EEPassphrase", E2EEWorker: "E2EEWorker", ConnectTimeoutMs: "ConnectTimeoutMs" }, outputs: { SessionStarted: "SessionStarted", InvitePeopleRequested: "InvitePeopleRequested", Connected: "Connected", Disconnected: "Disconnected", ParticipantJoined: "ParticipantJoined", ParticipantLeft: "ParticipantLeft", DataReceived: "DataReceived", ErrorOccurred: "ErrorOccurred" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 1, consts: [[1, "mj-lk-status"], [1, "mj-lk-status", "mj-lk-status--error"], [1, "mj-lk-room-wrap"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-triangle-exclamation"], ["type", "button", 1, "mj-lk-retry", 3, "click"], [3, "Connected", "Disconnected", "ParticipantJoined", "ParticipantLeft", "DataReceived", "ToggleRecording", "ErrorOccurred", "ServerUrl", "Token", "DisplayName", "AutoConnect", "StartWithMicrophone", "StartWithCamera", "Layout", "Title", "ShowHeader", "ShowControlBar", "ShowChat", "ShowParticipantsPanel", "EnableMicrophoneControl", "EnableCameraControl", "EnableScreenShareControl", "EnableDeviceSettings", "EnableLeaveControl", "EnablePinning", "EnableLayoutSwitcher", "EnableNoiseFilter", "EnableBackgroundEffects", "ShowAgentState", "ShowWhiteboard", "ShowPreJoin", "ShowRecordingControl", "IsRecording", "E2EEPassphrase", "E2EEWorker", "AgentAvatarUrl"], [1, "mj-lk-agents"], [1, "mj-lk-agents__panel"], [1, "mj-lk-agents__pills"], ["type", "button", 1, "mj-lk-agents__toggle", 3, "click"], [1, "fa-solid", "fa-robot"], [1, "mj-lk-agents__head"], [1, "mj-lk-agents__row"], [1, "mj-lk-agents__error"], [1, "mj-lk-agents__name"], ["type", "button", "title", "Remove agent", 1, "mj-lk-agents__remove", 3, "click", "disabled"], [1, "fa-solid"], [1, "mj-lk-agents__add"], [1, "mj-input", "mj-lk-agents__select", 3, "change"], ["value", ""], [3, "value", "selected"], ["type", "button", 1, "mj-lk-agents__addbtn", 3, "click", "disabled"], [1, "mj-lk-agents__overrides"], ["title", "Model (dev override)", 1, "mj-input", "mj-lk-agents__select", "mj-lk-agents__select--sm", 3, "change"], ["title", "Voice (dev override)", 1, "mj-input", "mj-lk-agents__select", "mj-lk-agents__select--sm"], ["title", "Voice (dev override)", 1, "mj-input", "mj-lk-agents__select", "mj-lk-agents__select--sm", 3, "change"], ["type", "button", "title", "Copy a link to invite someone to this room", 1, "mj-lk-agents__toggle", 3, "click"], ["type", "button", "title", "Invite people from this workspace", 1, "mj-lk-agents__toggle", 3, "click"], [1, "fa-solid", "fa-user-plus"]], template: function MJLiveKitRoomComponent_Template(rf, ctx) { if (rf & 1) {
616
- i0.ɵɵconditionalCreate(0, MJLiveKitRoomComponent_Conditional_0_Template, 4, 1, "div", 0)(1, MJLiveKitRoomComponent_Conditional_1_Template, 6, 1, "div", 1)(2, MJLiveKitRoomComponent_Conditional_2_Template, 3, 30, "div", 2);
722
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJLiveKitRoomComponent, selectors: [["mj-livekit-agent-room"]], viewQuery: function MJLiveKitRoomComponent_Query(rf, ctx) { if (rf & 1) {
723
+ i0.ɵɵviewQuery(LiveKitRoomComponent, 5);
724
+ } if (rf & 2) {
725
+ let _t;
726
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.roomComponent = _t.first);
727
+ } }, inputs: { Mode: "Mode", AgentID: "AgentID", AgentName: "AgentName", TargetAgentID: "TargetAgentID", RoomName: "RoomName", DisplayName: "DisplayName", TurnMode: "TurnMode", AutoStart: "AutoStart", EnableAgentManagement: "EnableAgentManagement", EnableInvite: "EnableInvite", EnableEndForAll: "EnableEndForAll", AvailableAgents: "AvailableAgents", RealtimeModelID: "RealtimeModelID", RealtimeVoice: "RealtimeVoice", CanPickModelVoice: "CanPickModelVoice", AvailableModels: "AvailableModels", Layout: "Layout", Title: "Title", ShowHeader: "ShowHeader", ShowControlBar: "ShowControlBar", ShowChat: "ShowChat", ShowParticipantsPanel: "ShowParticipantsPanel", EnableMicrophoneControl: "EnableMicrophoneControl", EnableCameraControl: "EnableCameraControl", EnableScreenShareControl: "EnableScreenShareControl", EnableDeviceSettings: "EnableDeviceSettings", EnableLeaveControl: "EnableLeaveControl", StartWithMicrophone: "StartWithMicrophone", StartWithCamera: "StartWithCamera", AgentAvatarUrl: "AgentAvatarUrl", EnablePinning: "EnablePinning", EnableLayoutSwitcher: "EnableLayoutSwitcher", EnableNoiseFilter: "EnableNoiseFilter", EnableBackgroundEffects: "EnableBackgroundEffects", ShowAgentState: "ShowAgentState", ShowWhiteboard: "ShowWhiteboard", ShowPreJoin: "ShowPreJoin", EnableRecording: "EnableRecording", E2EEPassphrase: "E2EEPassphrase", E2EEWorker: "E2EEWorker", ConnectTimeoutMs: "ConnectTimeoutMs" }, outputs: { SessionStarted: "SessionStarted", InvitePeopleRequested: "InvitePeopleRequested", Connected: "Connected", Disconnected: "Disconnected", ParticipantJoined: "ParticipantJoined", ParticipantLeft: "ParticipantLeft", DataReceived: "DataReceived", ErrorOccurred: "ErrorOccurred" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [[1, "mj-lk-recording"], [1, "mj-lk-status"], [1, "mj-lk-status", "mj-lk-status--error"], [1, "mj-lk-room-wrap"], [1, "mj-lk-recording__head"], [1, "mj-lk-recording__title"], [1, "fa-solid", "fa-circle-play"], ["type", "button", "title", "Dismiss", 1, "mj-lk-recording__close", 3, "click"], [1, "fa-solid", "fa-xmark"], [3, "FileID", "Provider"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-triangle-exclamation"], ["type", "button", 1, "mj-lk-retry", 3, "click"], [3, "Connected", "Disconnected", "EndForAll", "ParticipantJoined", "ParticipantLeft", "DataReceived", "ToggleRecording", "ErrorOccurred", "ServerUrl", "Token", "DisplayName", "AutoConnect", "StartWithMicrophone", "StartWithCamera", "Layout", "Title", "ShowHeader", "ShowControlBar", "ShowChat", "ShowParticipantsPanel", "EnableMicrophoneControl", "EnableCameraControl", "EnableScreenShareControl", "EnableDeviceSettings", "EnableLeaveControl", "EnablePinning", "EnableLayoutSwitcher", "EnableNoiseFilter", "EnableBackgroundEffects", "ShowAgentState", "ShowWhiteboard", "ShowPreJoin", "ShowRecordingControl", "IsRecording", "E2EEPassphrase", "E2EEWorker", "AgentAvatarUrl", "CanEndForAll"], [1, "mj-lk-agents"], [1, "mj-lk-agents__panel"], [1, "mj-lk-agents__pills"], ["type", "button", 1, "mj-lk-agents__toggle", 3, "click"], [1, "fa-solid", "fa-robot"], [1, "mj-lk-agents__head"], [1, "mj-lk-agents__row"], [1, "mj-lk-agents__error"], [1, "mj-lk-agents__name"], ["type", "button", "title", "Remove agent", 1, "mj-lk-agents__remove", 3, "click", "disabled"], [1, "fa-solid"], [1, "mj-lk-agents__add"], [1, "mj-input", "mj-lk-agents__select", 3, "change"], ["value", ""], [3, "value", "selected"], ["type", "button", 1, "mj-lk-agents__addbtn", 3, "click", "disabled"], [1, "mj-lk-agents__overrides"], ["title", "Model (dev override)", 1, "mj-input", "mj-lk-agents__select", "mj-lk-agents__select--sm", 3, "change"], ["title", "Voice (dev override)", 1, "mj-input", "mj-lk-agents__select", "mj-lk-agents__select--sm"], ["title", "Voice (dev override)", 1, "mj-input", "mj-lk-agents__select", "mj-lk-agents__select--sm", 3, "change"], ["type", "button", "title", "Copy a link to invite someone to this room", 1, "mj-lk-agents__toggle", 3, "click"], ["type", "button", "title", "Invite people from this workspace", 1, "mj-lk-agents__toggle", 3, "click"], [1, "fa-solid", "fa-user-plus"]], template: function MJLiveKitRoomComponent_Template(rf, ctx) { if (rf & 1) {
728
+ i0.ɵɵconditionalCreate(0, MJLiveKitRoomComponent_Conditional_0_Template, 8, 2, "div", 0);
729
+ i0.ɵɵconditionalCreate(1, MJLiveKitRoomComponent_Conditional_1_Template, 4, 1, "div", 1)(2, MJLiveKitRoomComponent_Conditional_2_Template, 6, 1, "div", 2)(3, MJLiveKitRoomComponent_Conditional_3_Template, 3, 31, "div", 3);
617
730
  } if (rf & 2) {
618
- i0.ɵɵconditional(ctx.loading ? 0 : ctx.errorMessage ? 1 : ctx.serverUrl && ctx.token ? 2 : -1);
619
- } }, dependencies: [LiveKitRoomComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n }\n .mj-lk-status[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n height: 100%;\n min-height: 220px;\n color: var(--mj-text-secondary, #475569);\n background: var(--mj-bg-surface-card, #f1f5f9);\n border-radius: 12px;\n }\n .mj-lk-status[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.6rem;\n color: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-status--error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error, #ef4444);\n }\n .mj-lk-retry[_ngcontent-%COMP%] {\n padding: 7px 16px;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-inverse, #fff);\n background: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-room-wrap[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 100%;\n }\n .mj-lk-agents[_ngcontent-%COMP%] {\n position: absolute;\n left: 16px;\n bottom: 84px;\n z-index: 40;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .mj-lk-agents__pills[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n }\n .mj-lk-agents__toggle[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n cursor: pointer;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.18));\n }\n .mj-lk-agents__panel[_ngcontent-%COMP%] {\n width: 260px;\n padding: 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-md, 0 6px 20px rgba(0, 0, 0, 0.25));\n }\n .mj-lk-agents__head[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n }\n .mj-lk-agents__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 5px 0;\n }\n .mj-lk-agents__name[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-lk-agents__name[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n .mj-lk-agents__remove[_ngcontent-%COMP%] {\n flex: none;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-agents__remove[_ngcontent-%COMP%]:hover:not(:disabled) {\n color: var(--mj-status-error);\n background: var(--mj-bg-surface-hover);\n }\n .mj-lk-agents__add[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n }\n .mj-lk-agents__select[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n font-size: 0.8125rem;\n }\n .mj-lk-agents__overrides[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n margin-top: 6px;\n }\n .mj-lk-agents__select--sm[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n }\n .mj-lk-agents__addbtn[_ngcontent-%COMP%] {\n flex: none;\n width: 32px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n }\n .mj-lk-agents__addbtn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .mj-lk-agents__error[_ngcontent-%COMP%] {\n margin-top: 6px;\n font-size: 0.75rem;\n color: var(--mj-status-error-text, var(--mj-status-error));\n }"], changeDetection: 0 });
731
+ i0.ɵɵconditional(ctx.recordingFileId && ctx.showRecordingPanel ? 0 : -1);
732
+ i0.ɵɵadvance();
733
+ i0.ɵɵconditional(ctx.loading ? 1 : ctx.errorMessage ? 2 : ctx.serverUrl && ctx.token ? 3 : -1);
734
+ } }, dependencies: [LiveKitRoomComponent, MJStorageMediaPlayerComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n }\n .mj-lk-status[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n height: 100%;\n min-height: 220px;\n color: var(--mj-text-secondary, #475569);\n background: var(--mj-bg-surface-card, #f1f5f9);\n border-radius: 12px;\n }\n .mj-lk-status[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.6rem;\n color: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-status--error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error, #ef4444);\n }\n .mj-lk-retry[_ngcontent-%COMP%] {\n padding: 7px 16px;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-inverse, #fff);\n background: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-room-wrap[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 100%;\n }\n .mj-lk-agents[_ngcontent-%COMP%] {\n position: absolute;\n left: 16px;\n bottom: 84px;\n z-index: 40;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .mj-lk-agents__pills[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n }\n .mj-lk-agents__toggle[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n cursor: pointer;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.18));\n }\n .mj-lk-agents__panel[_ngcontent-%COMP%] {\n width: 260px;\n padding: 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-md, 0 6px 20px rgba(0, 0, 0, 0.25));\n }\n .mj-lk-agents__head[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n }\n .mj-lk-agents__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 5px 0;\n }\n .mj-lk-agents__name[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-lk-agents__name[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n .mj-lk-agents__remove[_ngcontent-%COMP%] {\n flex: none;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-agents__remove[_ngcontent-%COMP%]:hover:not(:disabled) {\n color: var(--mj-status-error);\n background: var(--mj-bg-surface-hover);\n }\n .mj-lk-agents__add[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n }\n .mj-lk-agents__select[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n font-size: 0.8125rem;\n }\n .mj-lk-agents__overrides[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n margin-top: 6px;\n }\n .mj-lk-agents__select--sm[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n }\n .mj-lk-agents__addbtn[_ngcontent-%COMP%] {\n flex: none;\n width: 32px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n }\n .mj-lk-agents__addbtn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .mj-lk-agents__error[_ngcontent-%COMP%] {\n margin-top: 6px;\n font-size: 0.75rem;\n color: var(--mj-status-error-text, var(--mj-status-error));\n }\n .mj-lk-recording[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-card, var(--mj-bg-surface));\n }\n .mj-lk-recording__head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n }\n .mj-lk-recording__title[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n .mj-lk-recording__title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n .mj-lk-recording__close[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-recording__close[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n }"], changeDetection: 0 });
620
735
  }
621
736
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJLiveKitRoomComponent, [{
622
737
  type: Component,
623
- args: [{ selector: 'mj-livekit-agent-room', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [LiveKitRoomComponent], template: `
738
+ args: [{ selector: 'mj-livekit-agent-room', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [LiveKitRoomComponent, MJStorageMediaPlayerComponent], template: `
739
+ @if (recordingFileId && showRecordingPanel) {
740
+ <div class="mj-lk-recording">
741
+ <div class="mj-lk-recording__head">
742
+ <span class="mj-lk-recording__title"><i class="fa-solid fa-circle-play"></i> Meeting recording</span>
743
+ <button type="button" class="mj-lk-recording__close" title="Dismiss" (click)="showRecordingPanel = false">
744
+ <i class="fa-solid fa-xmark"></i>
745
+ </button>
746
+ </div>
747
+ <mj-storage-media-player [FileID]="recordingFileId" [Provider]="Provider"></mj-storage-media-player>
748
+ </div>
749
+ }
624
750
  @if (loading) {
625
751
  <div class="mj-lk-status">
626
752
  <i class="fa-solid fa-spinner fa-spin"></i>
@@ -664,8 +790,10 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
664
790
  [E2EEPassphrase]="E2EEPassphrase"
665
791
  [E2EEWorker]="E2EEWorker"
666
792
  [AgentAvatarUrl]="AgentAvatarUrl"
793
+ [CanEndForAll]="EnableEndForAll && !!resolvedRoomName"
667
794
  (Connected)="Connected.emit($event)"
668
795
  (Disconnected)="Disconnected.emit($event)"
796
+ (EndForAll)="EndMeeting()"
669
797
  (ParticipantJoined)="ParticipantJoined.emit($event)"
670
798
  (ParticipantLeft)="ParticipantLeft.emit($event)"
671
799
  (DataReceived)="DataReceived.emit($event)"
@@ -743,7 +871,7 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
743
871
  }
744
872
  </div>
745
873
  }
746
- `, styles: ["\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n .mj-lk-status {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n height: 100%;\n min-height: 220px;\n color: var(--mj-text-secondary, #475569);\n background: var(--mj-bg-surface-card, #f1f5f9);\n border-radius: 12px;\n }\n .mj-lk-status i {\n font-size: 1.6rem;\n color: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-status--error i {\n color: var(--mj-status-error, #ef4444);\n }\n .mj-lk-retry {\n padding: 7px 16px;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-inverse, #fff);\n background: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-room-wrap {\n position: relative;\n width: 100%;\n height: 100%;\n }\n .mj-lk-agents {\n position: absolute;\n left: 16px;\n bottom: 84px;\n z-index: 40;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .mj-lk-agents__pills {\n display: flex;\n gap: 8px;\n }\n .mj-lk-agents__toggle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n cursor: pointer;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.18));\n }\n .mj-lk-agents__panel {\n width: 260px;\n padding: 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-md, 0 6px 20px rgba(0, 0, 0, 0.25));\n }\n .mj-lk-agents__head {\n font-size: 0.6875rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n }\n .mj-lk-agents__row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 5px 0;\n }\n .mj-lk-agents__name {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-lk-agents__name i {\n color: var(--mj-brand-primary);\n }\n .mj-lk-agents__remove {\n flex: none;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-agents__remove:hover:not(:disabled) {\n color: var(--mj-status-error);\n background: var(--mj-bg-surface-hover);\n }\n .mj-lk-agents__add {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n }\n .mj-lk-agents__select {\n flex: 1;\n min-width: 0;\n font-size: 0.8125rem;\n }\n .mj-lk-agents__overrides {\n display: flex;\n gap: 6px;\n margin-top: 6px;\n }\n .mj-lk-agents__select--sm {\n font-size: 0.75rem;\n }\n .mj-lk-agents__addbtn {\n flex: none;\n width: 32px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n }\n .mj-lk-agents__addbtn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .mj-lk-agents__error {\n margin-top: 6px;\n font-size: 0.75rem;\n color: var(--mj-status-error-text, var(--mj-status-error));\n }\n "] }]
874
+ `, styles: ["\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n .mj-lk-status {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n height: 100%;\n min-height: 220px;\n color: var(--mj-text-secondary, #475569);\n background: var(--mj-bg-surface-card, #f1f5f9);\n border-radius: 12px;\n }\n .mj-lk-status i {\n font-size: 1.6rem;\n color: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-status--error i {\n color: var(--mj-status-error, #ef4444);\n }\n .mj-lk-retry {\n padding: 7px 16px;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-inverse, #fff);\n background: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-room-wrap {\n position: relative;\n width: 100%;\n height: 100%;\n }\n .mj-lk-agents {\n position: absolute;\n left: 16px;\n bottom: 84px;\n z-index: 40;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .mj-lk-agents__pills {\n display: flex;\n gap: 8px;\n }\n .mj-lk-agents__toggle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n cursor: pointer;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.18));\n }\n .mj-lk-agents__panel {\n width: 260px;\n padding: 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-md, 0 6px 20px rgba(0, 0, 0, 0.25));\n }\n .mj-lk-agents__head {\n font-size: 0.6875rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n }\n .mj-lk-agents__row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 5px 0;\n }\n .mj-lk-agents__name {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-lk-agents__name i {\n color: var(--mj-brand-primary);\n }\n .mj-lk-agents__remove {\n flex: none;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-agents__remove:hover:not(:disabled) {\n color: var(--mj-status-error);\n background: var(--mj-bg-surface-hover);\n }\n .mj-lk-agents__add {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n }\n .mj-lk-agents__select {\n flex: 1;\n min-width: 0;\n font-size: 0.8125rem;\n }\n .mj-lk-agents__overrides {\n display: flex;\n gap: 6px;\n margin-top: 6px;\n }\n .mj-lk-agents__select--sm {\n font-size: 0.75rem;\n }\n .mj-lk-agents__addbtn {\n flex: none;\n width: 32px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n }\n .mj-lk-agents__addbtn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .mj-lk-agents__error {\n margin-top: 6px;\n font-size: 0.75rem;\n color: var(--mj-status-error-text, var(--mj-status-error));\n }\n .mj-lk-recording {\n margin-bottom: 12px;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-card, var(--mj-bg-surface));\n }\n .mj-lk-recording__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n }\n .mj-lk-recording__title {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n .mj-lk-recording__title i {\n color: var(--mj-brand-primary);\n }\n .mj-lk-recording__close {\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-recording__close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n }\n "] }]
747
875
  }], null, { Mode: [{
748
876
  type: Input
749
877
  }], AgentID: [{
@@ -764,6 +892,8 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
764
892
  type: Input
765
893
  }], EnableInvite: [{
766
894
  type: Input
895
+ }], EnableEndForAll: [{
896
+ type: Input
767
897
  }], AvailableAgents: [{
768
898
  type: Input
769
899
  }], RealtimeModelID: [{
@@ -774,6 +904,9 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
774
904
  type: Input
775
905
  }], AvailableModels: [{
776
906
  type: Input
907
+ }], roomComponent: [{
908
+ type: ViewChild,
909
+ args: [LiveKitRoomComponent]
777
910
  }], Layout: [{
778
911
  type: Input
779
912
  }], Title: [{
@@ -841,5 +974,5 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
841
974
  }], ConnectTimeoutMs: [{
842
975
  type: Input
843
976
  }] }); })();
844
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLiveKitRoomComponent, { className: "MJLiveKitRoomComponent", filePath: "src/lib/mj-livekit-room.component.ts", lineNumber: 331 }); })();
977
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLiveKitRoomComponent, { className: "MJLiveKitRoomComponent", filePath: "src/lib/mj-livekit-room.component.ts", lineNumber: 383 }); })();
845
978
  //# sourceMappingURL=mj-livekit-room.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mj-livekit-room.component.js","sourceRoot":"","sources":["../../src/lib/mj-livekit-room.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { GraphQLDataProvider, GraphQLLiveKitClient, RealtimeModelVoices, RealtimeVoiceOption } from '@memberjunction/graphql-dataprovider';\nimport { LiveKitRoomComponent, type LiveKitRoomLayout } from '@memberjunction/ng-livekit-room';\nimport type {\n LiveKitDataMessage,\n LiveKitDisconnectedEvent,\n LiveKitParticipantJoinedEvent,\n LiveKitParticipantLeftEvent,\n LiveKitRoomError,\n LiveKitRoomState,\n} from '@memberjunction/livekit-room-core';\n\n/** How the MJ binding obtains its room: start an agent in a room, or just join an existing room. */\nexport type MJLiveKitConnectionMode = 'agent' | 'join';\n\n/** Emitted when an agent room session has been started server-side. */\nexport interface MJLiveKitSessionStartedEvent {\n /** The durable bridge-session row id. */\n SessionBridgeID: string;\n /** The room name. */\n RoomName: string;\n}\n\n/** One agent bot bridged into the room — tracked for the in-room add/remove roster. */\nexport interface AgentInRoom {\n /** The `MJ: AI Agent Session Bridges` row id (used to stop/remove this agent). */\n SessionBridgeID: string;\n /** The target agent this bot voices, when known. */\n TargetAgentID: string | null;\n /** Display name (the target agent's name). */\n Name: string;\n /** True while a remove request is in flight. */\n Removing?: boolean;\n}\n\n/**\n * `mj-livekit-agent-room` — the MemberJunction binding for the LiveKit room UI. It resolves a scoped\n * access token (and, in `'agent'` mode, starts the agent's presence in the room) via the RealtimeBridge\n * GraphQL surface, then renders {@link LiveKitRoomComponent} with the resolved connection. All the rich\n * feature gates of the generic component are forwarded; MJ user/provider context is threaded in.\n *\n * Public members are PascalCase (MJ convention); private members are camelCase.\n */\n@Component({\n selector: 'mj-livekit-agent-room',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [LiveKitRoomComponent],\n template: `\n @if (loading) {\n <div class=\"mj-lk-status\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>{{ Mode === 'agent' ? 'Starting agent session…' : 'Joining room…' }}</span>\n </div>\n } @else if (errorMessage) {\n <div class=\"mj-lk-status mj-lk-status--error\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ errorMessage }}</span>\n <button type=\"button\" class=\"mj-lk-retry\" (click)=\"Start()\">Try again</button>\n </div>\n } @else if (serverUrl && token) {\n <div class=\"mj-lk-room-wrap\">\n <mj-livekit-room\n [ServerUrl]=\"serverUrl\"\n [Token]=\"token\"\n [DisplayName]=\"resolvedDisplayName\"\n [AutoConnect]=\"true\"\n [StartWithMicrophone]=\"StartWithMicrophone\"\n [StartWithCamera]=\"StartWithCamera\"\n [Layout]=\"Layout\"\n [Title]=\"Title\"\n [ShowHeader]=\"ShowHeader\"\n [ShowControlBar]=\"ShowControlBar\"\n [ShowChat]=\"ShowChat\"\n [ShowParticipantsPanel]=\"ShowParticipantsPanel\"\n [EnableMicrophoneControl]=\"EnableMicrophoneControl\"\n [EnableCameraControl]=\"EnableCameraControl\"\n [EnableScreenShareControl]=\"EnableScreenShareControl\"\n [EnableDeviceSettings]=\"EnableDeviceSettings\"\n [EnableLeaveControl]=\"EnableLeaveControl\"\n [EnablePinning]=\"EnablePinning\"\n [EnableLayoutSwitcher]=\"EnableLayoutSwitcher\"\n [EnableNoiseFilter]=\"EnableNoiseFilter\"\n [EnableBackgroundEffects]=\"EnableBackgroundEffects\"\n [ShowAgentState]=\"ShowAgentState\"\n [ShowWhiteboard]=\"ShowWhiteboard\"\n [ShowPreJoin]=\"ShowPreJoin\"\n [ShowRecordingControl]=\"EnableRecording\"\n [IsRecording]=\"isRecording\"\n [E2EEPassphrase]=\"E2EEPassphrase\"\n [E2EEWorker]=\"E2EEWorker\"\n [AgentAvatarUrl]=\"AgentAvatarUrl\"\n (Connected)=\"Connected.emit($event)\"\n (Disconnected)=\"Disconnected.emit($event)\"\n (ParticipantJoined)=\"ParticipantJoined.emit($event)\"\n (ParticipantLeft)=\"ParticipantLeft.emit($event)\"\n (DataReceived)=\"DataReceived.emit($event)\"\n (ToggleRecording)=\"onToggleRecording()\"\n (ErrorOccurred)=\"ErrorOccurred.emit($event)\"\n ></mj-livekit-room>\n\n @if (Mode === 'agent' && EnableAgentManagement && resolvedRoomName) {\n <div class=\"mj-lk-agents\">\n @if (showAgentsPanel) {\n <div class=\"mj-lk-agents__panel\">\n <div class=\"mj-lk-agents__head\">In this room</div>\n @for (a of agentsInRoom; track a.SessionBridgeID) {\n <div class=\"mj-lk-agents__row\">\n <span class=\"mj-lk-agents__name\"><i class=\"fa-solid fa-robot\"></i> {{ a.Name }}</span>\n <button type=\"button\" class=\"mj-lk-agents__remove\" title=\"Remove agent\"\n [disabled]=\"a.Removing\" (click)=\"RemoveAgent(a)\">\n <i class=\"fa-solid\" [class.fa-xmark]=\"!a.Removing\" [class.fa-spinner]=\"a.Removing\" [class.fa-spin]=\"a.Removing\"></i>\n </button>\n </div>\n }\n @if (availableToAdd.length) {\n <div class=\"mj-lk-agents__add\">\n <select class=\"mj-input mj-lk-agents__select\" (change)=\"onAddTargetChange($event)\">\n <option value=\"\">Add an agent…</option>\n @for (a of availableToAdd; track a.ID) {\n <option [value]=\"a.ID\" [selected]=\"UUIDsEqual(a.ID, addTargetId)\">{{ a.Name }}</option>\n }\n </select>\n <button type=\"button\" class=\"mj-lk-agents__addbtn\" [disabled]=\"!addTargetId || addingAgent\" (click)=\"AddAgent()\">\n <i class=\"fa-solid\" [class.fa-plus]=\"!addingAgent\" [class.fa-spinner]=\"addingAgent\" [class.fa-spin]=\"addingAgent\"></i>\n </button>\n </div>\n @if (CanPickModelVoice && AvailableModels.length) {\n <div class=\"mj-lk-agents__overrides\">\n <select class=\"mj-input mj-lk-agents__select mj-lk-agents__select--sm\" (change)=\"onAddModelChange($event)\" title=\"Model (dev override)\">\n <option value=\"\">Default model</option>\n @for (m of AvailableModels; track m.ModelID) {\n <option [value]=\"m.ModelID\" [selected]=\"UUIDsEqual(m.ModelID, addModelId)\">{{ m.ModelName }}</option>\n }\n </select>\n @if (addVoices.length) {\n <select class=\"mj-input mj-lk-agents__select mj-lk-agents__select--sm\" (change)=\"onAddVoiceChange($event)\" title=\"Voice (dev override)\">\n <option value=\"\">Default voice</option>\n @for (v of addVoices; track v.ID) {\n <option [value]=\"v.ID\" [selected]=\"v.ID === addVoice\">{{ v.Name }}</option>\n }\n </select>\n }\n </div>\n }\n }\n @if (addError) {\n <div class=\"mj-lk-agents__error\">{{ addError }}</div>\n }\n </div>\n }\n <div class=\"mj-lk-agents__pills\">\n <button type=\"button\" class=\"mj-lk-agents__toggle\" (click)=\"showAgentsPanel = !showAgentsPanel\">\n <i class=\"fa-solid fa-robot\"></i> Agents ({{ agentsInRoom.length }})\n </button>\n @if (EnableInvite) {\n <button type=\"button\" class=\"mj-lk-agents__toggle\" title=\"Copy a link to invite someone to this room\"\n (click)=\"CopyInvite()\">\n <i class=\"fa-solid\" [class.fa-link]=\"!inviteCopied\" [class.fa-check]=\"inviteCopied\"></i>\n {{ inviteCopied ? 'Link copied' : 'Copy link' }}\n </button>\n <button type=\"button\" class=\"mj-lk-agents__toggle\" title=\"Invite people from this workspace\"\n (click)=\"InvitePeopleRequested.emit(resolvedRoomName)\">\n <i class=\"fa-solid fa-user-plus\"></i> Invite people\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n `,\n styles: [\n `\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n .mj-lk-status {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n height: 100%;\n min-height: 220px;\n color: var(--mj-text-secondary, #475569);\n background: var(--mj-bg-surface-card, #f1f5f9);\n border-radius: 12px;\n }\n .mj-lk-status i {\n font-size: 1.6rem;\n color: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-status--error i {\n color: var(--mj-status-error, #ef4444);\n }\n .mj-lk-retry {\n padding: 7px 16px;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-inverse, #fff);\n background: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-room-wrap {\n position: relative;\n width: 100%;\n height: 100%;\n }\n .mj-lk-agents {\n position: absolute;\n left: 16px;\n bottom: 84px;\n z-index: 40;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .mj-lk-agents__pills {\n display: flex;\n gap: 8px;\n }\n .mj-lk-agents__toggle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n cursor: pointer;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.18));\n }\n .mj-lk-agents__panel {\n width: 260px;\n padding: 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-md, 0 6px 20px rgba(0, 0, 0, 0.25));\n }\n .mj-lk-agents__head {\n font-size: 0.6875rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n }\n .mj-lk-agents__row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 5px 0;\n }\n .mj-lk-agents__name {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-lk-agents__name i {\n color: var(--mj-brand-primary);\n }\n .mj-lk-agents__remove {\n flex: none;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-agents__remove:hover:not(:disabled) {\n color: var(--mj-status-error);\n background: var(--mj-bg-surface-hover);\n }\n .mj-lk-agents__add {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n }\n .mj-lk-agents__select {\n flex: 1;\n min-width: 0;\n font-size: 0.8125rem;\n }\n .mj-lk-agents__overrides {\n display: flex;\n gap: 6px;\n margin-top: 6px;\n }\n .mj-lk-agents__select--sm {\n font-size: 0.75rem;\n }\n .mj-lk-agents__addbtn {\n flex: none;\n width: 32px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n }\n .mj-lk-agents__addbtn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .mj-lk-agents__error {\n margin-top: 6px;\n font-size: 0.75rem;\n color: var(--mj-status-error-text, var(--mj-status-error));\n }\n `,\n ],\n})\nexport class MJLiveKitRoomComponent extends BaseAngularComponent implements OnInit {\n private readonly cdr = inject(ChangeDetectorRef);\n\n // ── MJ connection inputs ───────────────────────────────────────────────────────\n /** Whether to start an agent in the room (`'agent'`) or just join an existing room (`'join'`). */\n @Input() public Mode: MJLiveKitConnectionMode = 'agent';\n /** The agent to voice (agent mode) — the Realtime Co-Agent / voice front-end. */\n @Input() public AgentID: string | null = null;\n /** The agent's display name (bot name + addressing). */\n @Input() public AgentName: string | null = null;\n /**\n * The TARGET agent the co-agent voices — the one being \"called\". The Realtime Co-Agent delegates to\n * it via `invoke-target-agent`; without it the agent has nobody to speak for and stays idle.\n */\n @Input() public TargetAgentID: string | null = null;\n /** The room name. Required for `'join'` mode; optional for `'agent'` (server generates one). */\n @Input() public RoomName: string | null = null;\n /** The display name the local user joins as. Defaults to the authenticated user server-side. */\n @Input() public DisplayName: string | null = null;\n /** Turn-taking mode for the agent. */\n @Input() public TurnMode: 'Passive' | 'Active' | 'Hybrid' | null = null;\n /** Resolve the connection automatically on init. */\n @Input() public AutoStart = true;\n\n // ── In-room agent management (agent mode) ─────────────────────────────────────────\n /** Show the in-room \"Agents\" panel to add/remove agents (agent mode only). */\n @Input() public EnableAgentManagement = true;\n /** Show the \"Invite\" pill that copies a join link to this room. */\n @Input() public EnableInvite = true;\n /** Target agents the user can ADD in-room (id + name). The host (e.g. the Explorer resource) supplies these. */\n @Input() public AvailableAgents: { ID: string; Name: string }[] = [];\n\n /** Per-session Realtime MODEL override for the INITIAL agent (from the host's pre-join picker). */\n @Input() public RealtimeModelID: string | null = null;\n /** Per-session VOICE override for the INITIAL agent (from the host's pre-join picker). */\n @Input() public RealtimeVoice: string | null = null;\n /**\n * Whether the dev model/voice pickers are shown in the in-room \"Add an agent\" control. The HOST\n * computes this (the `Realtime: Advanced Session Controls` authorization) and passes it down — this\n * generic component never evaluates authorizations itself.\n */\n @Input() public CanPickModelVoice = false;\n /** Active Realtime models + their voices, supplied by the host (for the add-agent dropdowns). */\n @Input() public AvailableModels: RealtimeModelVoices[] = [];\n\n /** True briefly after the invite link is copied (drives the \"Link copied\" pill state). */\n public inviteCopied = false;\n\n /** Whether the floating agents panel is open. */\n public showAgentsPanel = false;\n /** The agent bots currently bridged into the room (the first is the one started on join). */\n public agentsInRoom: AgentInRoom[] = [];\n /** The target id chosen in the \"Add an agent\" picker. */\n public addTargetId: string | null = null;\n /** The MODEL override chosen in the \"Add an agent\" picker (dev-only; null = co-agent/target default). */\n public addModelId: string | null = null;\n /** The VOICE override chosen in the \"Add an agent\" picker (dev-only; null = co-agent/target default). */\n public addVoice: string | null = null;\n /** Exposed for template use — platform-safe UUID equality (SQL upper vs PG lower). */\n public UUIDsEqual = UUIDsEqual;\n /** True while an Add request is in flight. */\n public addingAgent = false;\n /** Last add error, shown under the picker. */\n public addError: string | null = null;\n\n /** Available agents not already in the room (by target id) — the \"Add\" picker options. */\n public get availableToAdd(): { ID: string; Name: string }[] {\n const present = new Set(this.agentsInRoom.map((a) => (a.TargetAgentID ?? '').toLowerCase()));\n return this.AvailableAgents.filter((a) => !present.has(a.ID.toLowerCase()));\n }\n\n /** Voices for the model chosen in the add-agent picker (empty when no model picked or it has none). */\n public get addVoices(): RealtimeVoiceOption[] {\n const model = this.AvailableModels.find((m) => UUIDsEqual(m.ModelID, this.addModelId));\n return model?.Voices ?? [];\n }\n\n /** Records the add-agent MODEL choice; clears the voice so it can't outlive a model switch. */\n public onAddModelChange(event: Event): void {\n this.addModelId = (event.target as HTMLSelectElement).value || null;\n this.addVoice = null;\n }\n\n /** Records the add-agent VOICE choice. */\n public onAddVoiceChange(event: Event): void {\n this.addVoice = (event.target as HTMLSelectElement).value || null;\n }\n\n // ── Forwarded UI gates (see LiveKitRoomComponent) ────────────────────────────────\n /** @see LiveKitRoomComponent.Layout */\n @Input() public Layout: LiveKitRoomLayout = 'grid';\n /** @see LiveKitRoomComponent.Title */\n @Input() public Title: string | null = null;\n /** @see LiveKitRoomComponent.ShowHeader */\n @Input() public ShowHeader = true;\n /** @see LiveKitRoomComponent.ShowControlBar */\n @Input() public ShowControlBar = true;\n /** @see LiveKitRoomComponent.ShowChat */\n @Input() public ShowChat = true;\n /** @see LiveKitRoomComponent.ShowParticipantsPanel */\n @Input() public ShowParticipantsPanel = true;\n /** @see LiveKitRoomComponent.EnableMicrophoneControl */\n @Input() public EnableMicrophoneControl = true;\n /** @see LiveKitRoomComponent.EnableCameraControl */\n @Input() public EnableCameraControl = true;\n /** @see LiveKitRoomComponent.EnableScreenShareControl */\n @Input() public EnableScreenShareControl = true;\n /** @see LiveKitRoomComponent.EnableDeviceSettings */\n @Input() public EnableDeviceSettings = true;\n /** @see LiveKitRoomComponent.EnableLeaveControl */\n @Input() public EnableLeaveControl = true;\n /** @see LiveKitRoomComponent.StartWithMicrophone */\n @Input() public StartWithMicrophone = true;\n /** @see LiveKitRoomComponent.StartWithCamera */\n @Input() public StartWithCamera = false;\n /** @see LiveKitRoomComponent.AgentAvatarUrl */\n @Input() public AgentAvatarUrl: string | null = null;\n /** @see LiveKitRoomComponent.EnablePinning */\n @Input() public EnablePinning = true;\n /** @see LiveKitRoomComponent.EnableLayoutSwitcher */\n @Input() public EnableLayoutSwitcher = true;\n /** @see LiveKitRoomComponent.EnableNoiseFilter */\n @Input() public EnableNoiseFilter = false;\n /** @see LiveKitRoomComponent.EnableBackgroundEffects */\n @Input() public EnableBackgroundEffects = false;\n /** @see LiveKitRoomComponent.ShowAgentState */\n @Input() public ShowAgentState = false;\n /** @see LiveKitRoomComponent.ShowWhiteboard */\n @Input() public ShowWhiteboard = false;\n /** @see LiveKitRoomComponent.ShowPreJoin */\n @Input() public ShowPreJoin = false;\n /** Enable the server-authorized recording control (composite egress). */\n @Input() public EnableRecording = false;\n /** @see LiveKitRoomComponent.E2EEPassphrase */\n @Input() public E2EEPassphrase: string | null = null;\n /** @see LiveKitRoomComponent.E2EEWorker */\n @Input() public E2EEWorker: Worker | null = null;\n\n // ── Outputs ────────────────────────────────────────────────────────────────────\n /** Emitted once the agent room session is started (agent mode). */\n @Output() public SessionStarted = new EventEmitter<MJLiveKitSessionStartedEvent>();\n /**\n * Emitted (with the room name) when the user clicks \"Invite people\". The host (e.g. the Explorer\n * resource) opens an MJ user-picker and calls the invite mutation — kept out of this generic\n * component, which knows nothing about MJ users.\n */\n @Output() public InvitePeopleRequested = new EventEmitter<string>();\n /** Emitted when the room connects. */\n @Output() public Connected = new EventEmitter<LiveKitRoomState>();\n /** Emitted when the room disconnects. */\n @Output() public Disconnected = new EventEmitter<LiveKitDisconnectedEvent>();\n /** Emitted when a participant joins. */\n @Output() public ParticipantJoined = new EventEmitter<LiveKitParticipantJoinedEvent>();\n /** Emitted when a participant leaves. */\n @Output() public ParticipantLeft = new EventEmitter<LiveKitParticipantLeftEvent>();\n /** Emitted for inbound data-channel messages. */\n @Output() public DataReceived = new EventEmitter<LiveKitDataMessage>();\n /** Emitted on room errors (and on token/session-resolution failures). */\n @Output() public ErrorOccurred = new EventEmitter<LiveKitRoomError>();\n\n // ── View state ─────────────────────────────────────────────────────────────────\n /** Whether the binding is resolving the token/session. */\n public loading = false;\n /** The token/session-resolution error, if any. */\n public errorMessage: string | null = null;\n /** The resolved LiveKit server URL. */\n public serverUrl: string | null = null;\n /** The resolved access token. */\n public token: string | null = null;\n /** The display name passed to the room. */\n public resolvedDisplayName: string | null = null;\n /** The resolved room name (for recording calls). */\n public resolvedRoomName: string | null = null;\n /** Whether a recording is currently in progress. */\n public isRecording = false;\n /** The active egress id, when recording. */\n private currentEgressId: string | null = null;\n\n public ngOnInit(): void {\n if (this.AutoStart) {\n void this.Start();\n }\n }\n\n /**\n * Max time to wait for the connection to start before surfacing a retryable error, so a hung or very\n * slow server (e.g. an agent bot that can't reach the LiveKit media path) doesn't spin forever. Set\n * `0` to disable the client-side timeout.\n */\n @Input() public ConnectTimeoutMs = 25000;\n\n /** Resolves the connection (mints a token and, in agent mode, starts the agent session). */\n public async Start(): Promise<void> {\n this.loading = true;\n this.errorMessage = null;\n this.cdr.markForCheck();\n try {\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n this.resolvedDisplayName = this.DisplayName;\n const connect = this.Mode === 'agent' ? this.startAgentSession(client) : this.joinRoom(client);\n await this.withTimeout(connect, this.ConnectTimeoutMs);\n } catch (err) {\n this.fail(err instanceof Error ? err.message : String(err));\n } finally {\n this.loading = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Races `op` against a timeout: if it hasn't settled within `ms`, rejects with a clear, retryable\n * message (the template's \"Try again\" button re-runs {@link Start}). A non-positive `ms` disables it.\n */\n private withTimeout<T>(op: Promise<T>, ms: number): Promise<T> {\n if (!ms || ms <= 0) {\n return op;\n }\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(\n () =>\n reject(\n new Error(\n 'The connection is taking too long — the agent could not join the room. ' +\n 'Check that the LiveKit server is running and reachable, then try again.',\n ),\n ),\n ms,\n );\n op.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n }\n\n /** Starts the agent room session and applies the returned client token. */\n private async startAgentSession(client: GraphQLLiveKitClient): Promise<void> {\n const result = await client.StartAgentRoomSession({\n AgentID: this.AgentID ?? undefined,\n AgentName: this.AgentName ?? undefined,\n TargetAgentID: this.TargetAgentID ?? undefined,\n RealtimeModelID: this.RealtimeModelID ?? undefined,\n RealtimeVoice: this.RealtimeVoice ?? undefined,\n RoomName: this.RoomName ?? undefined,\n TurnMode: this.TurnMode ?? undefined,\n });\n if (!result.Success) {\n this.fail(result.ErrorMessage ?? 'Failed to start the agent session.');\n return;\n }\n this.serverUrl = result.ServerUrl;\n this.token = result.ClientToken;\n this.resolvedRoomName = result.RoomName;\n // Track the agent we just brought in as the first entry in the in-room roster.\n this.agentsInRoom = [\n { SessionBridgeID: result.SessionBridgeID, TargetAgentID: this.TargetAgentID, Name: this.AgentName ?? 'Agent' },\n ];\n this.SessionStarted.emit({ SessionBridgeID: result.SessionBridgeID, RoomName: result.RoomName });\n }\n\n /** Picker selection handler for the in-room \"Add an agent\" control (native select; no FormsModule dep). */\n public onAddTargetChange(event: Event): void {\n this.addTargetId = (event.target as HTMLSelectElement).value || null;\n this.addError = null;\n }\n\n /**\n * Adds another agent to the SAME room — starts a new bridge (the co-agent voicing the chosen target)\n * and appends it to the roster. The new bot joins the live room alongside the existing participants.\n */\n public async AddAgent(): Promise<void> {\n if (!this.addTargetId || !this.resolvedRoomName || this.addingAgent) {\n return;\n }\n const target = this.AvailableAgents.find((a) => UUIDsEqual(a.ID, this.addTargetId));\n this.addingAgent = true;\n this.addError = null;\n this.cdr.markForCheck();\n try {\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n const result = await client.StartAgentRoomSession({\n AgentID: this.AgentID ?? undefined,\n AgentName: target?.Name ?? undefined,\n TargetAgentID: this.addTargetId,\n RealtimeModelID: this.addModelId ?? undefined,\n RealtimeVoice: this.addVoice ?? undefined,\n RoomName: this.resolvedRoomName,\n TurnMode: this.TurnMode ?? undefined,\n });\n if (!result.Success) {\n this.addError = result.ErrorMessage ?? 'Failed to add the agent.';\n return;\n }\n this.agentsInRoom = [\n ...this.agentsInRoom,\n { SessionBridgeID: result.SessionBridgeID, TargetAgentID: this.addTargetId, Name: target?.Name ?? 'Agent' },\n ];\n this.addTargetId = null;\n this.addModelId = null;\n this.addVoice = null;\n } catch (err) {\n this.addError = err instanceof Error ? err.message : String(err);\n } finally {\n this.addingAgent = false;\n this.cdr.markForCheck();\n }\n }\n\n /** Removes an agent from the room — stops its bridge and drops it from the roster. */\n public async RemoveAgent(agent: AgentInRoom): Promise<void> {\n if (agent.Removing) {\n return;\n }\n agent.Removing = true;\n this.cdr.markForCheck();\n try {\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n const ok = await client.StopAgentRoomSession(agent.SessionBridgeID);\n if (ok) {\n this.agentsInRoom = this.agentsInRoom.filter((a) => a.SessionBridgeID !== agent.SessionBridgeID);\n } else {\n agent.Removing = false;\n }\n } catch {\n agent.Removing = false;\n } finally {\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Builds the shareable invite URL for THIS room: the current page URL with a `room=<roomName>` query\n * param. Opening it lands the invitee on the Live Room in join mode for the same room.\n */\n public get inviteUrl(): string {\n const url = new URL(window.location.href);\n url.searchParams.set('room', this.resolvedRoomName ?? '');\n return url.toString();\n }\n\n /** Copies {@link inviteUrl} to the clipboard and flips the pill to \"Link copied\" briefly. */\n public async CopyInvite(): Promise<void> {\n if (!this.resolvedRoomName) {\n return;\n }\n try {\n await navigator.clipboard.writeText(this.inviteUrl);\n this.inviteCopied = true;\n this.cdr.markForCheck();\n setTimeout(() => {\n this.inviteCopied = false;\n this.cdr.markForCheck();\n }, 2000);\n } catch {\n // Clipboard blocked (insecure context / permissions) — leave the pill unchanged.\n }\n }\n\n /** Joins an existing room by minting a client token. */\n private async joinRoom(client: GraphQLLiveKitClient): Promise<void> {\n if (!this.RoomName) {\n this.fail('RoomName is required when Mode is \"join\".');\n return;\n }\n const result = await client.MintClientToken({ RoomName: this.RoomName, DisplayName: this.DisplayName ?? undefined });\n if (!result.Success) {\n this.fail(result.ErrorMessage ?? 'Failed to obtain a room token.');\n return;\n }\n this.serverUrl = result.ServerUrl;\n this.token = result.Token;\n this.resolvedRoomName = this.RoomName;\n }\n\n /** Toggles room recording via the RealtimeBridge GraphQL surface (server-authorized egress). */\n public async onToggleRecording(): Promise<void> {\n if (!this.resolvedRoomName) {\n return;\n }\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n if (!this.isRecording) {\n const result = await client.StartRecording(this.resolvedRoomName);\n if (result.Success) {\n this.isRecording = true;\n this.currentEgressId = result.EgressID;\n } else {\n this.fail(result.ErrorMessage ?? 'Failed to start recording.');\n }\n } else if (this.currentEgressId) {\n await client.StopRecording(this.currentEgressId);\n this.isRecording = false;\n this.currentEgressId = null;\n }\n this.cdr.markForCheck();\n }\n\n /** Records a failure and emits an error event. */\n private fail(message: string): void {\n this.errorMessage = message;\n this.ErrorOccurred.emit({ Kind: 'connect', Message: message });\n }\n}\n"]}
1
+ {"version":3,"file":"mj-livekit-room.component.js","sourceRoot":"","sources":["../../src/lib/mj-livekit-room.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { RunView } from '@memberjunction/core';\nimport { GraphQLDataProvider, GraphQLLiveKitClient, RealtimeModelVoices, RealtimeVoiceOption } from '@memberjunction/graphql-dataprovider';\nimport { LiveKitRoomComponent, type LiveKitRoomLayout } from '@memberjunction/ng-livekit-room';\nimport { MJStorageMediaPlayerComponent } from '@memberjunction/ng-media-player';\nimport type {\n LiveKitDataMessage,\n LiveKitDisconnectedEvent,\n LiveKitParticipantJoinedEvent,\n LiveKitParticipantLeftEvent,\n LiveKitRoomError,\n LiveKitRoomState,\n} from '@memberjunction/livekit-room-core';\n\n/** How the MJ binding obtains its room: start an agent in a room, or just join an existing room. */\nexport type MJLiveKitConnectionMode = 'agent' | 'join';\n\n/** Emitted when an agent room session has been started server-side. */\nexport interface MJLiveKitSessionStartedEvent {\n /** The durable bridge-session row id. */\n SessionBridgeID: string;\n /** The room name. */\n RoomName: string;\n}\n\n/** One agent bot bridged into the room — tracked for the in-room add/remove roster. */\nexport interface AgentInRoom {\n /** The `MJ: AI Agent Session Bridges` row id (used to stop/remove this agent). */\n SessionBridgeID: string;\n /** The target agent this bot voices, when known. */\n TargetAgentID: string | null;\n /** Display name (the target agent's name). */\n Name: string;\n /** True while a remove request is in flight. */\n Removing?: boolean;\n}\n\n/**\n * `mj-livekit-agent-room` — the MemberJunction binding for the LiveKit room UI. It resolves a scoped\n * access token (and, in `'agent'` mode, starts the agent's presence in the room) via the RealtimeBridge\n * GraphQL surface, then renders {@link LiveKitRoomComponent} with the resolved connection. All the rich\n * feature gates of the generic component are forwarded; MJ user/provider context is threaded in.\n *\n * Public members are PascalCase (MJ convention); private members are camelCase.\n */\n@Component({\n selector: 'mj-livekit-agent-room',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [LiveKitRoomComponent, MJStorageMediaPlayerComponent],\n template: `\n @if (recordingFileId && showRecordingPanel) {\n <div class=\"mj-lk-recording\">\n <div class=\"mj-lk-recording__head\">\n <span class=\"mj-lk-recording__title\"><i class=\"fa-solid fa-circle-play\"></i> Meeting recording</span>\n <button type=\"button\" class=\"mj-lk-recording__close\" title=\"Dismiss\" (click)=\"showRecordingPanel = false\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <mj-storage-media-player [FileID]=\"recordingFileId\" [Provider]=\"Provider\"></mj-storage-media-player>\n </div>\n }\n @if (loading) {\n <div class=\"mj-lk-status\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>{{ Mode === 'agent' ? 'Starting agent session…' : 'Joining room…' }}</span>\n </div>\n } @else if (errorMessage) {\n <div class=\"mj-lk-status mj-lk-status--error\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span>{{ errorMessage }}</span>\n <button type=\"button\" class=\"mj-lk-retry\" (click)=\"Start()\">Try again</button>\n </div>\n } @else if (serverUrl && token) {\n <div class=\"mj-lk-room-wrap\">\n <mj-livekit-room\n [ServerUrl]=\"serverUrl\"\n [Token]=\"token\"\n [DisplayName]=\"resolvedDisplayName\"\n [AutoConnect]=\"true\"\n [StartWithMicrophone]=\"StartWithMicrophone\"\n [StartWithCamera]=\"StartWithCamera\"\n [Layout]=\"Layout\"\n [Title]=\"Title\"\n [ShowHeader]=\"ShowHeader\"\n [ShowControlBar]=\"ShowControlBar\"\n [ShowChat]=\"ShowChat\"\n [ShowParticipantsPanel]=\"ShowParticipantsPanel\"\n [EnableMicrophoneControl]=\"EnableMicrophoneControl\"\n [EnableCameraControl]=\"EnableCameraControl\"\n [EnableScreenShareControl]=\"EnableScreenShareControl\"\n [EnableDeviceSettings]=\"EnableDeviceSettings\"\n [EnableLeaveControl]=\"EnableLeaveControl\"\n [EnablePinning]=\"EnablePinning\"\n [EnableLayoutSwitcher]=\"EnableLayoutSwitcher\"\n [EnableNoiseFilter]=\"EnableNoiseFilter\"\n [EnableBackgroundEffects]=\"EnableBackgroundEffects\"\n [ShowAgentState]=\"ShowAgentState\"\n [ShowWhiteboard]=\"ShowWhiteboard\"\n [ShowPreJoin]=\"ShowPreJoin\"\n [ShowRecordingControl]=\"EnableRecording\"\n [IsRecording]=\"isRecording\"\n [E2EEPassphrase]=\"E2EEPassphrase\"\n [E2EEWorker]=\"E2EEWorker\"\n [AgentAvatarUrl]=\"AgentAvatarUrl\"\n [CanEndForAll]=\"EnableEndForAll && !!resolvedRoomName\"\n (Connected)=\"Connected.emit($event)\"\n (Disconnected)=\"Disconnected.emit($event)\"\n (EndForAll)=\"EndMeeting()\"\n (ParticipantJoined)=\"ParticipantJoined.emit($event)\"\n (ParticipantLeft)=\"ParticipantLeft.emit($event)\"\n (DataReceived)=\"DataReceived.emit($event)\"\n (ToggleRecording)=\"onToggleRecording()\"\n (ErrorOccurred)=\"ErrorOccurred.emit($event)\"\n ></mj-livekit-room>\n\n @if (Mode === 'agent' && EnableAgentManagement && resolvedRoomName) {\n <div class=\"mj-lk-agents\">\n @if (showAgentsPanel) {\n <div class=\"mj-lk-agents__panel\">\n <div class=\"mj-lk-agents__head\">In this room</div>\n @for (a of agentsInRoom; track a.SessionBridgeID) {\n <div class=\"mj-lk-agents__row\">\n <span class=\"mj-lk-agents__name\"><i class=\"fa-solid fa-robot\"></i> {{ a.Name }}</span>\n <button type=\"button\" class=\"mj-lk-agents__remove\" title=\"Remove agent\"\n [disabled]=\"a.Removing\" (click)=\"RemoveAgent(a)\">\n <i class=\"fa-solid\" [class.fa-xmark]=\"!a.Removing\" [class.fa-spinner]=\"a.Removing\" [class.fa-spin]=\"a.Removing\"></i>\n </button>\n </div>\n }\n @if (availableToAdd.length) {\n <div class=\"mj-lk-agents__add\">\n <select class=\"mj-input mj-lk-agents__select\" (change)=\"onAddTargetChange($event)\">\n <option value=\"\">Add an agent…</option>\n @for (a of availableToAdd; track a.ID) {\n <option [value]=\"a.ID\" [selected]=\"UUIDsEqual(a.ID, addTargetId)\">{{ a.Name }}</option>\n }\n </select>\n <button type=\"button\" class=\"mj-lk-agents__addbtn\" [disabled]=\"!addTargetId || addingAgent\" (click)=\"AddAgent()\">\n <i class=\"fa-solid\" [class.fa-plus]=\"!addingAgent\" [class.fa-spinner]=\"addingAgent\" [class.fa-spin]=\"addingAgent\"></i>\n </button>\n </div>\n @if (CanPickModelVoice && AvailableModels.length) {\n <div class=\"mj-lk-agents__overrides\">\n <select class=\"mj-input mj-lk-agents__select mj-lk-agents__select--sm\" (change)=\"onAddModelChange($event)\" title=\"Model (dev override)\">\n <option value=\"\">Default model</option>\n @for (m of AvailableModels; track m.ModelID) {\n <option [value]=\"m.ModelID\" [selected]=\"UUIDsEqual(m.ModelID, addModelId)\">{{ m.ModelName }}</option>\n }\n </select>\n @if (addVoices.length) {\n <select class=\"mj-input mj-lk-agents__select mj-lk-agents__select--sm\" (change)=\"onAddVoiceChange($event)\" title=\"Voice (dev override)\">\n <option value=\"\">Default voice</option>\n @for (v of addVoices; track v.ID) {\n <option [value]=\"v.ID\" [selected]=\"v.ID === addVoice\">{{ v.Name }}</option>\n }\n </select>\n }\n </div>\n }\n }\n @if (addError) {\n <div class=\"mj-lk-agents__error\">{{ addError }}</div>\n }\n </div>\n }\n <div class=\"mj-lk-agents__pills\">\n <button type=\"button\" class=\"mj-lk-agents__toggle\" (click)=\"showAgentsPanel = !showAgentsPanel\">\n <i class=\"fa-solid fa-robot\"></i> Agents ({{ agentsInRoom.length }})\n </button>\n @if (EnableInvite) {\n <button type=\"button\" class=\"mj-lk-agents__toggle\" title=\"Copy a link to invite someone to this room\"\n (click)=\"CopyInvite()\">\n <i class=\"fa-solid\" [class.fa-link]=\"!inviteCopied\" [class.fa-check]=\"inviteCopied\"></i>\n {{ inviteCopied ? 'Link copied' : 'Copy link' }}\n </button>\n <button type=\"button\" class=\"mj-lk-agents__toggle\" title=\"Invite people from this workspace\"\n (click)=\"InvitePeopleRequested.emit(resolvedRoomName)\">\n <i class=\"fa-solid fa-user-plus\"></i> Invite people\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n `,\n styles: [\n `\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n .mj-lk-status {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n height: 100%;\n min-height: 220px;\n color: var(--mj-text-secondary, #475569);\n background: var(--mj-bg-surface-card, #f1f5f9);\n border-radius: 12px;\n }\n .mj-lk-status i {\n font-size: 1.6rem;\n color: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-status--error i {\n color: var(--mj-status-error, #ef4444);\n }\n .mj-lk-retry {\n padding: 7px 16px;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-inverse, #fff);\n background: var(--mj-brand-primary, #0076b6);\n }\n .mj-lk-room-wrap {\n position: relative;\n width: 100%;\n height: 100%;\n }\n .mj-lk-agents {\n position: absolute;\n left: 16px;\n bottom: 84px;\n z-index: 40;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .mj-lk-agents__pills {\n display: flex;\n gap: 8px;\n }\n .mj-lk-agents__toggle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n cursor: pointer;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.18));\n }\n .mj-lk-agents__panel {\n width: 260px;\n padding: 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n box-shadow: var(--mj-shadow-md, 0 6px 20px rgba(0, 0, 0, 0.25));\n }\n .mj-lk-agents__head {\n font-size: 0.6875rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n margin-bottom: 6px;\n }\n .mj-lk-agents__row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 5px 0;\n }\n .mj-lk-agents__name {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n font-size: 0.8125rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-lk-agents__name i {\n color: var(--mj-brand-primary);\n }\n .mj-lk-agents__remove {\n flex: none;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-agents__remove:hover:not(:disabled) {\n color: var(--mj-status-error);\n background: var(--mj-bg-surface-hover);\n }\n .mj-lk-agents__add {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-subtle, var(--mj-border-default));\n }\n .mj-lk-agents__select {\n flex: 1;\n min-width: 0;\n font-size: 0.8125rem;\n }\n .mj-lk-agents__overrides {\n display: flex;\n gap: 6px;\n margin-top: 6px;\n }\n .mj-lk-agents__select--sm {\n font-size: 0.75rem;\n }\n .mj-lk-agents__addbtn {\n flex: none;\n width: 32px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n }\n .mj-lk-agents__addbtn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .mj-lk-agents__error {\n margin-top: 6px;\n font-size: 0.75rem;\n color: var(--mj-status-error-text, var(--mj-status-error));\n }\n .mj-lk-recording {\n margin-bottom: 12px;\n padding: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface-card, var(--mj-bg-surface));\n }\n .mj-lk-recording__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n }\n .mj-lk-recording__title {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n .mj-lk-recording__title i {\n color: var(--mj-brand-primary);\n }\n .mj-lk-recording__close {\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: var(--mj-text-muted);\n background: transparent;\n }\n .mj-lk-recording__close:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n }\n `,\n ],\n})\nexport class MJLiveKitRoomComponent extends BaseAngularComponent implements OnInit {\n private readonly cdr = inject(ChangeDetectorRef);\n\n // ── MJ connection inputs ───────────────────────────────────────────────────────\n /** Whether to start an agent in the room (`'agent'`) or just join an existing room (`'join'`). */\n @Input() public Mode: MJLiveKitConnectionMode = 'agent';\n /** The agent to voice (agent mode) — the Realtime Co-Agent / voice front-end. */\n @Input() public AgentID: string | null = null;\n /** The agent's display name (bot name + addressing). */\n @Input() public AgentName: string | null = null;\n /**\n * The TARGET agent the co-agent voices — the one being \"called\". The Realtime Co-Agent delegates to\n * it via `invoke-target-agent`; without it the agent has nobody to speak for and stays idle.\n */\n @Input() public TargetAgentID: string | null = null;\n /** The room name. Required for `'join'` mode; optional for `'agent'` (server generates one). */\n @Input() public RoomName: string | null = null;\n /** The display name the local user joins as. Defaults to the authenticated user server-side. */\n @Input() public DisplayName: string | null = null;\n /** Turn-taking mode for the agent. */\n @Input() public TurnMode: 'Passive' | 'Active' | 'Hybrid' | null = null;\n /** Resolve the connection automatically on init. */\n @Input() public AutoStart = true;\n\n // ── In-room agent management (agent mode) ─────────────────────────────────────────\n /** Show the in-room \"Agents\" panel to add/remove agents (agent mode only). */\n @Input() public EnableAgentManagement = true;\n /** Show the \"Invite\" pill that copies a join link to this room. */\n @Input() public EnableInvite = true;\n /**\n * Offer \"End meeting for everyone\" in the control bar's Zoom-style leave menu. When on (default) and a\n * room is resolved, ending tears down every agent in the room server-side (by name — so it works even\n * when this client only *joined*). Set `false` for contexts where only the local user should ever leave.\n */\n @Input() public EnableEndForAll = true;\n /** Target agents the user can ADD in-room (id + name). The host (e.g. the Explorer resource) supplies these. */\n @Input() public AvailableAgents: { ID: string; Name: string }[] = [];\n\n /** Per-session Realtime MODEL override for the INITIAL agent (from the host's pre-join picker). */\n @Input() public RealtimeModelID: string | null = null;\n /** Per-session VOICE override for the INITIAL agent (from the host's pre-join picker). */\n @Input() public RealtimeVoice: string | null = null;\n /**\n * Whether the dev model/voice pickers are shown in the in-room \"Add an agent\" control. The HOST\n * computes this (the `Realtime: Advanced Session Controls` authorization) and passes it down — this\n * generic component never evaluates authorizations itself.\n */\n @Input() public CanPickModelVoice = false;\n /** Active Realtime models + their voices, supplied by the host (for the add-agent dropdowns). */\n @Input() public AvailableModels: RealtimeModelVoices[] = [];\n\n /** True briefly after the invite link is copied (drives the \"Link copied\" pill state). */\n public inviteCopied = false;\n\n /** Whether the floating agents panel is open. */\n public showAgentsPanel = false;\n /** The agent bots currently bridged into the room (the first is the one started on join). */\n public agentsInRoom: AgentInRoom[] = [];\n /** The target id chosen in the \"Add an agent\" picker. */\n public addTargetId: string | null = null;\n /** The MODEL override chosen in the \"Add an agent\" picker (dev-only; null = co-agent/target default). */\n public addModelId: string | null = null;\n /** The VOICE override chosen in the \"Add an agent\" picker (dev-only; null = co-agent/target default). */\n public addVoice: string | null = null;\n /** Exposed for template use — platform-safe UUID equality (SQL upper vs PG lower). */\n public UUIDsEqual = UUIDsEqual;\n /** True while an Add request is in flight. */\n public addingAgent = false;\n /** Last add error, shown under the picker. */\n public addError: string | null = null;\n /** True while an \"End meeting\" (stop all agents + leave) is in flight. */\n public endingMeeting = false;\n\n /** The inner Generic room — used to trigger the local disconnect when ending/leaving the meeting. */\n @ViewChild(LiveKitRoomComponent) private roomComponent?: LiveKitRoomComponent;\n\n /** Available agents not already in the room (by target id) — the \"Add\" picker options. */\n public get availableToAdd(): { ID: string; Name: string }[] {\n const present = new Set(this.agentsInRoom.map((a) => (a.TargetAgentID ?? '').toLowerCase()));\n return this.AvailableAgents.filter((a) => !present.has(a.ID.toLowerCase()));\n }\n\n /** Voices for the model chosen in the add-agent picker (empty when no model picked or it has none). */\n public get addVoices(): RealtimeVoiceOption[] {\n const model = this.AvailableModels.find((m) => UUIDsEqual(m.ModelID, this.addModelId));\n return model?.Voices ?? [];\n }\n\n /** Records the add-agent MODEL choice; clears the voice so it can't outlive a model switch. */\n public onAddModelChange(event: Event): void {\n this.addModelId = (event.target as HTMLSelectElement).value || null;\n this.addVoice = null;\n }\n\n /** Records the add-agent VOICE choice. */\n public onAddVoiceChange(event: Event): void {\n this.addVoice = (event.target as HTMLSelectElement).value || null;\n }\n\n // ── Forwarded UI gates (see LiveKitRoomComponent) ────────────────────────────────\n /** @see LiveKitRoomComponent.Layout */\n @Input() public Layout: LiveKitRoomLayout = 'grid';\n /** @see LiveKitRoomComponent.Title */\n @Input() public Title: string | null = null;\n /** @see LiveKitRoomComponent.ShowHeader */\n @Input() public ShowHeader = true;\n /** @see LiveKitRoomComponent.ShowControlBar */\n @Input() public ShowControlBar = true;\n /** @see LiveKitRoomComponent.ShowChat */\n @Input() public ShowChat = true;\n /** @see LiveKitRoomComponent.ShowParticipantsPanel */\n @Input() public ShowParticipantsPanel = true;\n /** @see LiveKitRoomComponent.EnableMicrophoneControl */\n @Input() public EnableMicrophoneControl = true;\n /** @see LiveKitRoomComponent.EnableCameraControl */\n @Input() public EnableCameraControl = true;\n /** @see LiveKitRoomComponent.EnableScreenShareControl */\n @Input() public EnableScreenShareControl = true;\n /** @see LiveKitRoomComponent.EnableDeviceSettings */\n @Input() public EnableDeviceSettings = true;\n /** @see LiveKitRoomComponent.EnableLeaveControl */\n @Input() public EnableLeaveControl = true;\n /** @see LiveKitRoomComponent.StartWithMicrophone */\n @Input() public StartWithMicrophone = true;\n /** @see LiveKitRoomComponent.StartWithCamera */\n @Input() public StartWithCamera = false;\n /** @see LiveKitRoomComponent.AgentAvatarUrl */\n @Input() public AgentAvatarUrl: string | null = null;\n /** @see LiveKitRoomComponent.EnablePinning */\n @Input() public EnablePinning = true;\n /** @see LiveKitRoomComponent.EnableLayoutSwitcher */\n @Input() public EnableLayoutSwitcher = true;\n /** @see LiveKitRoomComponent.EnableNoiseFilter */\n @Input() public EnableNoiseFilter = false;\n /** @see LiveKitRoomComponent.EnableBackgroundEffects */\n @Input() public EnableBackgroundEffects = false;\n /** @see LiveKitRoomComponent.ShowAgentState */\n @Input() public ShowAgentState = false;\n /** @see LiveKitRoomComponent.ShowWhiteboard */\n @Input() public ShowWhiteboard = false;\n /** @see LiveKitRoomComponent.ShowPreJoin */\n @Input() public ShowPreJoin = false;\n /** Enable the server-authorized recording control (composite egress). */\n @Input() public EnableRecording = false;\n /** @see LiveKitRoomComponent.E2EEPassphrase */\n @Input() public E2EEPassphrase: string | null = null;\n /** @see LiveKitRoomComponent.E2EEWorker */\n @Input() public E2EEWorker: Worker | null = null;\n\n // ── Outputs ────────────────────────────────────────────────────────────────────\n /** Emitted once the agent room session is started (agent mode). */\n @Output() public SessionStarted = new EventEmitter<MJLiveKitSessionStartedEvent>();\n /**\n * Emitted (with the room name) when the user clicks \"Invite people\". The host (e.g. the Explorer\n * resource) opens an MJ user-picker and calls the invite mutation — kept out of this generic\n * component, which knows nothing about MJ users.\n */\n @Output() public InvitePeopleRequested = new EventEmitter<string>();\n /** Emitted when the room connects. */\n @Output() public Connected = new EventEmitter<LiveKitRoomState>();\n /** Emitted when the room disconnects. */\n @Output() public Disconnected = new EventEmitter<LiveKitDisconnectedEvent>();\n /** Emitted when a participant joins. */\n @Output() public ParticipantJoined = new EventEmitter<LiveKitParticipantJoinedEvent>();\n /** Emitted when a participant leaves. */\n @Output() public ParticipantLeft = new EventEmitter<LiveKitParticipantLeftEvent>();\n /** Emitted for inbound data-channel messages. */\n @Output() public DataReceived = new EventEmitter<LiveKitDataMessage>();\n /** Emitted on room errors (and on token/session-resolution failures). */\n @Output() public ErrorOccurred = new EventEmitter<LiveKitRoomError>();\n\n // ── View state ─────────────────────────────────────────────────────────────────\n /** Whether the binding is resolving the token/session. */\n public loading = false;\n /** The token/session-resolution error, if any. */\n public errorMessage: string | null = null;\n /** The resolved LiveKit server URL. */\n public serverUrl: string | null = null;\n /** The resolved access token. */\n public token: string | null = null;\n /** The display name passed to the room. */\n public resolvedDisplayName: string | null = null;\n /** The resolved room name (for recording calls). */\n public resolvedRoomName: string | null = null;\n /** Whether a recording is currently in progress. */\n public isRecording = false;\n /** The active egress id, when recording. */\n private currentEgressId: string | null = null;\n\n /**\n * The `MJ: Files` id of this room's meeting recording, when one exists — set when a recording is STOPPED\n * (the server registers the egress MP4 and returns its file id) or resolved for an already-recorded room\n * on join. Drives the {@link MJStorageMediaPlayerComponent} playback panel.\n */\n public recordingFileId: string | null = null;\n /** Whether the recording playback panel is shown (dismissable). */\n public showRecordingPanel = true;\n\n public ngOnInit(): void {\n if (this.AutoStart) {\n void this.Start();\n }\n // If this room already has a registered recording (e.g. joining/reviewing a past room), surface it.\n if (this.RoomName) {\n void this.loadExistingRecording(this.RoomName);\n }\n }\n\n /**\n * Max time to wait for the connection to start before surfacing a retryable error, so a hung or very\n * slow server (e.g. an agent bot that can't reach the LiveKit media path) doesn't spin forever. Set\n * `0` to disable the client-side timeout.\n */\n @Input() public ConnectTimeoutMs = 25000;\n\n /** Resolves the connection (mints a token and, in agent mode, starts the agent session). */\n public async Start(): Promise<void> {\n this.loading = true;\n this.errorMessage = null;\n this.cdr.markForCheck();\n try {\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n this.resolvedDisplayName = this.DisplayName;\n const connect = this.Mode === 'agent' ? this.startAgentSession(client) : this.joinRoom(client);\n await this.withTimeout(connect, this.ConnectTimeoutMs);\n } catch (err) {\n this.fail(err instanceof Error ? err.message : String(err));\n } finally {\n this.loading = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Races `op` against a timeout: if it hasn't settled within `ms`, rejects with a clear, retryable\n * message (the template's \"Try again\" button re-runs {@link Start}). A non-positive `ms` disables it.\n */\n private withTimeout<T>(op: Promise<T>, ms: number): Promise<T> {\n if (!ms || ms <= 0) {\n return op;\n }\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(\n () =>\n reject(\n new Error(\n 'The connection is taking too long — the agent could not join the room. ' +\n 'Check that the LiveKit server is running and reachable, then try again.',\n ),\n ),\n ms,\n );\n op.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n }\n\n /** Starts the agent room session and applies the returned client token. */\n private async startAgentSession(client: GraphQLLiveKitClient): Promise<void> {\n const result = await client.StartAgentRoomSession({\n AgentID: this.AgentID ?? undefined,\n AgentName: this.AgentName ?? undefined,\n TargetAgentID: this.TargetAgentID ?? undefined,\n RealtimeModelID: this.RealtimeModelID ?? undefined,\n RealtimeVoice: this.RealtimeVoice ?? undefined,\n RoomName: this.RoomName ?? undefined,\n TurnMode: this.TurnMode ?? undefined,\n });\n if (!result.Success) {\n this.fail(result.ErrorMessage ?? 'Failed to start the agent session.');\n return;\n }\n this.serverUrl = result.ServerUrl;\n this.token = result.ClientToken;\n this.resolvedRoomName = result.RoomName;\n // Surface a prior recording for this resolved room (the server may have generated the room name).\n void this.loadExistingRecording(result.RoomName);\n // Track the agent we just brought in as the first entry in the in-room roster.\n this.agentsInRoom = [\n { SessionBridgeID: result.SessionBridgeID, TargetAgentID: this.TargetAgentID, Name: this.AgentName ?? 'Agent' },\n ];\n this.SessionStarted.emit({ SessionBridgeID: result.SessionBridgeID, RoomName: result.RoomName });\n }\n\n /** Picker selection handler for the in-room \"Add an agent\" control (native select; no FormsModule dep). */\n public onAddTargetChange(event: Event): void {\n this.addTargetId = (event.target as HTMLSelectElement).value || null;\n this.addError = null;\n }\n\n /**\n * Adds another agent to the SAME room — starts a new bridge (the co-agent voicing the chosen target)\n * and appends it to the roster. The new bot joins the live room alongside the existing participants.\n */\n public async AddAgent(): Promise<void> {\n if (!this.addTargetId || !this.resolvedRoomName || this.addingAgent) {\n return;\n }\n const target = this.AvailableAgents.find((a) => UUIDsEqual(a.ID, this.addTargetId));\n this.addingAgent = true;\n this.addError = null;\n this.cdr.markForCheck();\n try {\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n const result = await client.StartAgentRoomSession({\n AgentID: this.AgentID ?? undefined,\n AgentName: target?.Name ?? undefined,\n TargetAgentID: this.addTargetId,\n RealtimeModelID: this.addModelId ?? undefined,\n RealtimeVoice: this.addVoice ?? undefined,\n RoomName: this.resolvedRoomName,\n TurnMode: this.TurnMode ?? undefined,\n });\n if (!result.Success) {\n this.addError = result.ErrorMessage ?? 'Failed to add the agent.';\n return;\n }\n this.agentsInRoom = [\n ...this.agentsInRoom,\n { SessionBridgeID: result.SessionBridgeID, TargetAgentID: this.addTargetId, Name: target?.Name ?? 'Agent' },\n ];\n this.addTargetId = null;\n this.addModelId = null;\n this.addVoice = null;\n } catch (err) {\n this.addError = err instanceof Error ? err.message : String(err);\n } finally {\n this.addingAgent = false;\n this.cdr.markForCheck();\n }\n }\n\n /** Removes an agent from the room — stops its bridge and drops it from the roster. */\n public async RemoveAgent(agent: AgentInRoom): Promise<void> {\n if (agent.Removing) {\n return;\n }\n agent.Removing = true;\n this.cdr.markForCheck();\n try {\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n const ok = await client.StopAgentRoomSession(agent.SessionBridgeID);\n if (ok) {\n this.agentsInRoom = this.agentsInRoom.filter((a) => a.SessionBridgeID !== agent.SessionBridgeID);\n } else {\n agent.Removing = false;\n }\n } catch {\n agent.Removing = false;\n } finally {\n this.cdr.markForCheck();\n }\n }\n\n /**\n * **End meeting** (the Zoom/Teams \"End for all\", reached from the control-bar leave menu): tears down EVERY\n * agent in the room server-side — *by room name*, so it works even when this client only **joined** the room\n * and never tracked the bridge ids locally — then disconnects the local user. Contrast with **Leave** (the\n * other menu item → {@link LiveKitRoomComponent.Leave}), which only disconnects YOU and lets the meeting\n * continue; the server then auto-leaves the agents once the last human is gone, so neither path strands\n * billable agent sessions in an empty room.\n */\n public async EndMeeting(): Promise<void> {\n if (this.endingMeeting) {\n return;\n }\n this.endingMeeting = true;\n this.cdr.markForCheck();\n try {\n if (this.resolvedRoomName) {\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n await client.EndRoom(this.resolvedRoomName);\n }\n this.agentsInRoom = [];\n } catch {\n /* best-effort — fall through and still disconnect the local user */\n } finally {\n await this.roomComponent?.Leave();\n this.endingMeeting = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Builds the shareable invite URL for THIS room: the current page URL with a `room=<roomName>` query\n * param. Opening it lands the invitee on the Live Room in join mode for the same room.\n */\n public get inviteUrl(): string {\n const url = new URL(window.location.href);\n url.searchParams.set('room', this.resolvedRoomName ?? '');\n return url.toString();\n }\n\n /** Copies {@link inviteUrl} to the clipboard and flips the pill to \"Link copied\" briefly. */\n public async CopyInvite(): Promise<void> {\n if (!this.resolvedRoomName) {\n return;\n }\n try {\n await navigator.clipboard.writeText(this.inviteUrl);\n this.inviteCopied = true;\n this.cdr.markForCheck();\n setTimeout(() => {\n this.inviteCopied = false;\n this.cdr.markForCheck();\n }, 2000);\n } catch {\n // Clipboard blocked (insecure context / permissions) — leave the pill unchanged.\n }\n }\n\n /** Joins an existing room by minting a client token. */\n private async joinRoom(client: GraphQLLiveKitClient): Promise<void> {\n if (!this.RoomName) {\n this.fail('RoomName is required when Mode is \"join\".');\n return;\n }\n const result = await client.MintClientToken({ RoomName: this.RoomName, DisplayName: this.DisplayName ?? undefined });\n if (!result.Success) {\n this.fail(result.ErrorMessage ?? 'Failed to obtain a room token.');\n return;\n }\n this.serverUrl = result.ServerUrl;\n this.token = result.Token;\n this.resolvedRoomName = this.RoomName;\n }\n\n /** Toggles room recording via the RealtimeBridge GraphQL surface (server-authorized egress). */\n public async onToggleRecording(): Promise<void> {\n if (!this.resolvedRoomName) {\n return;\n }\n const client = new GraphQLLiveKitClient(this.ProviderToUse as unknown as GraphQLDataProvider);\n if (!this.isRecording) {\n const result = await client.StartRecording(this.resolvedRoomName);\n if (result.Success) {\n this.isRecording = true;\n this.currentEgressId = result.EgressID;\n } else {\n this.fail(result.ErrorMessage ?? 'Failed to start recording.');\n }\n } else if (this.currentEgressId) {\n const stopped = await client.StopRecording(this.currentEgressId);\n this.isRecording = false;\n this.currentEgressId = null;\n // The server registers the egress MP4 as an MJ: Files row on stop and returns its id — surface it\n // in the playback panel. Absent when meeting-recording storage isn't configured server-side.\n if (stopped.Success && stopped.RecordingFileID) {\n this.recordingFileId = stopped.RecordingFileID;\n this.showRecordingPanel = true;\n }\n }\n this.cdr.markForCheck();\n }\n\n /**\n * Resolves this room's already-registered meeting recording (if any) — the `MJ: Conversations` of\n * `Type='Meeting Room'` keyed by the room name carries the `RecordingFileID`. Best-effort: any failure\n * just leaves the playback panel hidden.\n *\n * @param roomName The LiveKit room name (= the Meeting-Room Conversation's `ExternalID`).\n */\n private async loadExistingRecording(roomName: string): Promise<void> {\n try {\n const escaped = roomName.replace(/'/g, \"''\");\n const result = await RunView.FromMetadataProvider(this.ProviderToUse).RunView<{ RecordingFileID: string | null }>(\n {\n EntityName: 'MJ: Conversations',\n ExtraFilter: `ExternalID='${escaped}' AND Type='Meeting Room' AND RecordingFileID IS NOT NULL`,\n Fields: ['RecordingFileID'],\n OrderBy: '__mj_CreatedAt DESC',\n MaxRows: 1,\n ResultType: 'simple',\n },\n this.ProviderToUse.CurrentUser,\n );\n const fileId = result.Success ? result.Results[0]?.RecordingFileID ?? null : null;\n if (fileId) {\n this.recordingFileId = fileId;\n this.cdr.markForCheck();\n }\n } catch {\n // best-effort — no recording panel\n }\n }\n\n /** Records a failure and emits an error event. */\n private fail(message: string): void {\n this.errorMessage = message;\n this.ErrorOccurred.emit({ Kind: 'connect', Message: message });\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-mj-livekit-room",
3
- "version": "5.42.0",
3
+ "version": "5.44.0",
4
4
  "description": "MemberJunction: MJ binding layer for the LiveKit room UI. Wraps @memberjunction/ng-livekit-room and connects it to the MJ realtime-bridge infrastructure — mints scoped tokens and starts agent room sessions via the RealtimeBridge GraphQL surface, threading MJ user/provider/agent context.",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -32,12 +32,13 @@
32
32
  "rxjs": "^7.8.2"
33
33
  },
34
34
  "dependencies": {
35
- "@memberjunction/core": "5.42.0",
36
- "@memberjunction/global": "5.42.0",
37
- "@memberjunction/graphql-dataprovider": "5.42.0",
38
- "@memberjunction/livekit-room-core": "5.42.0",
39
- "@memberjunction/ng-base-types": "5.42.0",
40
- "@memberjunction/ng-livekit-room": "5.42.0",
35
+ "@memberjunction/core": "5.44.0",
36
+ "@memberjunction/global": "5.44.0",
37
+ "@memberjunction/graphql-dataprovider": "5.44.0",
38
+ "@memberjunction/livekit-room-core": "5.44.0",
39
+ "@memberjunction/ng-base-types": "5.44.0",
40
+ "@memberjunction/ng-livekit-room": "5.44.0",
41
+ "@memberjunction/ng-media-player": "5.44.0",
41
42
  "tslib": "^2.8.1"
42
43
  },
43
44
  "sideEffects": false,