@memberjunction/ng-mj-livekit-room 5.43.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.
|
@@ -198,6 +198,14 @@ export declare class MJLiveKitRoomComponent extends BaseAngularComponent impleme
|
|
|
198
198
|
isRecording: boolean;
|
|
199
199
|
/** The active egress id, when recording. */
|
|
200
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;
|
|
201
209
|
ngOnInit(): void;
|
|
202
210
|
/**
|
|
203
211
|
* Max time to wait for the connection to start before surfacing a retryable error, so a hung or very
|
|
@@ -243,6 +251,14 @@ export declare class MJLiveKitRoomComponent extends BaseAngularComponent impleme
|
|
|
243
251
|
private joinRoom;
|
|
244
252
|
/** Toggles room recording via the RealtimeBridge GraphQL surface (server-authorized egress). */
|
|
245
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;
|
|
246
262
|
/** Records a failure and emits an error event. */
|
|
247
263
|
private fail;
|
|
248
264
|
static ɵfac: i0.ɵɵFactoryDeclaration<MJLiveKitRoomComponent, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mj-livekit-room.component.d.ts","sourceRoot":"","sources":["../../src/lib/mj-livekit-room.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyD,YAAY,EAAS,MAAM,EAA6B,MAAM,eAAe,CAAC;AAC9I,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;
|
|
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
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.ɵɵ
|
|
12
|
-
i0.ɵɵ
|
|
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
|
|
36
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
18
37
|
i0.ɵɵadvance(3);
|
|
19
|
-
i0.ɵɵtextInterpolate(
|
|
38
|
+
i0.ɵɵtextInterpolate(ctx_r1.Mode === "agent" ? "Starting agent session\u2026" : "Joining room\u2026");
|
|
20
39
|
} }
|
|
21
|
-
function
|
|
22
|
-
const
|
|
23
|
-
i0.ɵɵelementStart(0, "div",
|
|
24
|
-
i0.ɵɵelement(1, "i",
|
|
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",
|
|
29
|
-
i0.ɵɵlistener("click", function
|
|
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
|
|
52
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
34
53
|
i0.ɵɵadvance(3);
|
|
35
|
-
i0.ɵɵtextInterpolate(
|
|
54
|
+
i0.ɵɵtextInterpolate(ctx_r1.errorMessage);
|
|
36
55
|
} }
|
|
37
|
-
function
|
|
38
|
-
const
|
|
39
|
-
i0.ɵɵelementStart(0, "div",
|
|
40
|
-
i0.ɵɵelement(2, "i",
|
|
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",
|
|
44
|
-
i0.ɵɵlistener("click", function
|
|
45
|
-
i0.ɵɵelement(5, "i",
|
|
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
|
|
67
|
+
const a_r7 = ctx.$implicit;
|
|
49
68
|
i0.ɵɵadvance(3);
|
|
50
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
69
|
+
i0.ɵɵtextInterpolate1(" ", a_r7.Name);
|
|
51
70
|
i0.ɵɵadvance();
|
|
52
|
-
i0.ɵɵproperty("disabled",
|
|
71
|
+
i0.ɵɵproperty("disabled", a_r7.Removing);
|
|
53
72
|
i0.ɵɵadvance();
|
|
54
|
-
i0.ɵɵclassProp("fa-xmark", !
|
|
73
|
+
i0.ɵɵclassProp("fa-xmark", !a_r7.Removing)("fa-spinner", a_r7.Removing)("fa-spin", a_r7.Removing);
|
|
55
74
|
} }
|
|
56
|
-
function
|
|
57
|
-
i0.ɵɵelementStart(0, "option",
|
|
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
|
|
62
|
-
const
|
|
63
|
-
i0.ɵɵproperty("value",
|
|
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(
|
|
84
|
+
i0.ɵɵtextInterpolate(a_r9.Name);
|
|
66
85
|
} }
|
|
67
|
-
function
|
|
68
|
-
i0.ɵɵelementStart(0, "option",
|
|
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
|
|
73
|
-
const
|
|
74
|
-
i0.ɵɵproperty("value",
|
|
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(
|
|
95
|
+
i0.ɵɵtextInterpolate(m_r11.ModelName);
|
|
77
96
|
} }
|
|
78
|
-
function
|
|
79
|
-
i0.ɵɵelementStart(0, "option",
|
|
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
|
|
84
|
-
const
|
|
85
|
-
i0.ɵɵproperty("value",
|
|
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(
|
|
106
|
+
i0.ɵɵtextInterpolate(v_r13.Name);
|
|
88
107
|
} }
|
|
89
|
-
function
|
|
90
|
-
const
|
|
91
|
-
i0.ɵɵelementStart(0, "select",
|
|
92
|
-
i0.ɵɵlistener("change", function
|
|
93
|
-
i0.ɵɵelementStart(1, "option",
|
|
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,
|
|
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
|
|
118
|
+
const ctx_r1 = i0.ɵɵnextContext(6);
|
|
100
119
|
i0.ɵɵadvance(3);
|
|
101
|
-
i0.ɵɵrepeater(
|
|
120
|
+
i0.ɵɵrepeater(ctx_r1.addVoices);
|
|
102
121
|
} }
|
|
103
|
-
function
|
|
104
|
-
const
|
|
105
|
-
i0.ɵɵelementStart(0, "div",
|
|
106
|
-
i0.ɵɵlistener("change", function
|
|
107
|
-
i0.ɵɵelementStart(2, "option",
|
|
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,
|
|
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,
|
|
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
|
|
134
|
+
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
116
135
|
i0.ɵɵadvance(4);
|
|
117
|
-
i0.ɵɵrepeater(
|
|
136
|
+
i0.ɵɵrepeater(ctx_r1.AvailableModels);
|
|
118
137
|
i0.ɵɵadvance(2);
|
|
119
|
-
i0.ɵɵconditional(
|
|
138
|
+
i0.ɵɵconditional(ctx_r1.addVoices.length ? 6 : -1);
|
|
120
139
|
} }
|
|
121
|
-
function
|
|
122
|
-
const
|
|
123
|
-
i0.ɵɵelementStart(0, "div",
|
|
124
|
-
i0.ɵɵlistener("change", function
|
|
125
|
-
i0.ɵɵelementStart(2, "option",
|
|
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,
|
|
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",
|
|
131
|
-
i0.ɵɵlistener("click", function
|
|
132
|
-
i0.ɵɵelement(7, "i",
|
|
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,
|
|
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
|
|
155
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
137
156
|
i0.ɵɵadvance(4);
|
|
138
|
-
i0.ɵɵrepeater(
|
|
157
|
+
i0.ɵɵrepeater(ctx_r1.availableToAdd);
|
|
139
158
|
i0.ɵɵadvance(2);
|
|
140
|
-
i0.ɵɵproperty("disabled", !
|
|
159
|
+
i0.ɵɵproperty("disabled", !ctx_r1.addTargetId || ctx_r1.addingAgent);
|
|
141
160
|
i0.ɵɵadvance();
|
|
142
|
-
i0.ɵɵclassProp("fa-plus", !
|
|
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(
|
|
163
|
+
i0.ɵɵconditional(ctx_r1.CanPickModelVoice && ctx_r1.AvailableModels.length ? 8 : -1);
|
|
145
164
|
} }
|
|
146
|
-
function
|
|
147
|
-
i0.ɵɵelementStart(0, "div",
|
|
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
|
|
170
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
152
171
|
i0.ɵɵadvance();
|
|
153
|
-
i0.ɵɵtextInterpolate(
|
|
172
|
+
i0.ɵɵtextInterpolate(ctx_r1.addError);
|
|
154
173
|
} }
|
|
155
|
-
function
|
|
156
|
-
i0.ɵɵelementStart(0, "div",
|
|
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,
|
|
160
|
-
i0.ɵɵconditionalCreate(5,
|
|
161
|
-
i0.ɵɵconditionalCreate(6,
|
|
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
|
|
183
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
165
184
|
i0.ɵɵadvance(3);
|
|
166
|
-
i0.ɵɵrepeater(
|
|
185
|
+
i0.ɵɵrepeater(ctx_r1.agentsInRoom);
|
|
167
186
|
i0.ɵɵadvance(2);
|
|
168
|
-
i0.ɵɵconditional(
|
|
187
|
+
i0.ɵɵconditional(ctx_r1.availableToAdd.length ? 5 : -1);
|
|
169
188
|
i0.ɵɵadvance();
|
|
170
|
-
i0.ɵɵconditional(
|
|
189
|
+
i0.ɵɵconditional(ctx_r1.addError ? 6 : -1);
|
|
171
190
|
} }
|
|
172
|
-
function
|
|
173
|
-
const
|
|
174
|
-
i0.ɵɵelementStart(0, "button",
|
|
175
|
-
i0.ɵɵlistener("click", function
|
|
176
|
-
i0.ɵɵelement(1, "i",
|
|
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",
|
|
180
|
-
i0.ɵɵlistener("click", function
|
|
181
|
-
i0.ɵɵelement(4, "i",
|
|
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
|
|
204
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
186
205
|
i0.ɵɵadvance();
|
|
187
|
-
i0.ɵɵclassProp("fa-link", !
|
|
206
|
+
i0.ɵɵclassProp("fa-link", !ctx_r1.inviteCopied)("fa-check", ctx_r1.inviteCopied);
|
|
188
207
|
i0.ɵɵadvance();
|
|
189
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
208
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r1.inviteCopied ? "Link copied" : "Copy link", " ");
|
|
190
209
|
} }
|
|
191
|
-
function
|
|
192
|
-
const
|
|
193
|
-
i0.ɵɵelementStart(0, "div",
|
|
194
|
-
i0.ɵɵconditionalCreate(1,
|
|
195
|
-
i0.ɵɵelementStart(2, "div",
|
|
196
|
-
i0.ɵɵlistener("click", function
|
|
197
|
-
i0.ɵɵelement(4, "i",
|
|
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,
|
|
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
|
|
222
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
204
223
|
i0.ɵɵadvance();
|
|
205
|
-
i0.ɵɵconditional(
|
|
224
|
+
i0.ɵɵconditional(ctx_r1.showAgentsPanel ? 1 : -1);
|
|
206
225
|
i0.ɵɵadvance(4);
|
|
207
|
-
i0.ɵɵtextInterpolate1(" Agents (",
|
|
226
|
+
i0.ɵɵtextInterpolate1(" Agents (", ctx_r1.agentsInRoom.length, ") ");
|
|
208
227
|
i0.ɵɵadvance();
|
|
209
|
-
i0.ɵɵconditional(
|
|
228
|
+
i0.ɵɵconditional(ctx_r1.EnableInvite ? 6 : -1);
|
|
210
229
|
} }
|
|
211
|
-
function
|
|
212
|
-
const
|
|
213
|
-
i0.ɵɵelementStart(0, "div",
|
|
214
|
-
i0.ɵɵlistener("Connected", function
|
|
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,
|
|
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
|
|
238
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
220
239
|
i0.ɵɵadvance();
|
|
221
|
-
i0.ɵɵproperty("ServerUrl",
|
|
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(
|
|
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
|
|
@@ -405,10 +424,22 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
|
|
|
405
424
|
isRecording = false;
|
|
406
425
|
/** The active egress id, when recording. */
|
|
407
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;
|
|
408
435
|
ngOnInit() {
|
|
409
436
|
if (this.AutoStart) {
|
|
410
437
|
void this.Start();
|
|
411
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
|
+
}
|
|
412
443
|
}
|
|
413
444
|
/**
|
|
414
445
|
* Max time to wait for the connection to start before surfacing a retryable error, so a hung or very
|
|
@@ -473,6 +504,8 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
|
|
|
473
504
|
this.serverUrl = result.ServerUrl;
|
|
474
505
|
this.token = result.ClientToken;
|
|
475
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);
|
|
476
509
|
// Track the agent we just brought in as the first entry in the in-room roster.
|
|
477
510
|
this.agentsInRoom = [
|
|
478
511
|
{ SessionBridgeID: result.SessionBridgeID, TargetAgentID: this.TargetAgentID, Name: this.AgentName ?? 'Agent' },
|
|
@@ -640,12 +673,46 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
|
|
|
640
673
|
}
|
|
641
674
|
}
|
|
642
675
|
else if (this.currentEgressId) {
|
|
643
|
-
await client.StopRecording(this.currentEgressId);
|
|
676
|
+
const stopped = await client.StopRecording(this.currentEgressId);
|
|
644
677
|
this.isRecording = false;
|
|
645
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
|
+
}
|
|
646
685
|
}
|
|
647
686
|
this.cdr.markForCheck();
|
|
648
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
|
+
}
|
|
649
716
|
/** Records a failure and emits an error event. */
|
|
650
717
|
fail(message) {
|
|
651
718
|
this.errorMessage = message;
|
|
@@ -657,15 +724,29 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
|
|
|
657
724
|
} if (rf & 2) {
|
|
658
725
|
let _t;
|
|
659
726
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.roomComponent = _t.first);
|
|
660
|
-
} }, 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:
|
|
661
|
-
i0.ɵɵconditionalCreate(0, MJLiveKitRoomComponent_Conditional_0_Template,
|
|
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);
|
|
662
730
|
} if (rf & 2) {
|
|
663
|
-
i0.ɵɵconditional(ctx.
|
|
664
|
-
|
|
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 });
|
|
665
735
|
}
|
|
666
736
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJLiveKitRoomComponent, [{
|
|
667
737
|
type: Component,
|
|
668
|
-
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
|
+
}
|
|
669
750
|
@if (loading) {
|
|
670
751
|
<div class="mj-lk-status">
|
|
671
752
|
<i class="fa-solid fa-spinner fa-spin"></i>
|
|
@@ -790,7 +871,7 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
|
|
|
790
871
|
}
|
|
791
872
|
</div>
|
|
792
873
|
}
|
|
793
|
-
`, 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 "] }]
|
|
794
875
|
}], null, { Mode: [{
|
|
795
876
|
type: Input
|
|
796
877
|
}], AgentID: [{
|
|
@@ -893,5 +974,5 @@ export class MJLiveKitRoomComponent extends BaseAngularComponent {
|
|
|
893
974
|
}], ConnectTimeoutMs: [{
|
|
894
975
|
type: Input
|
|
895
976
|
}] }); })();
|
|
896
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLiveKitRoomComponent, { className: "MJLiveKitRoomComponent", filePath: "src/lib/mj-livekit-room.component.ts", lineNumber:
|
|
977
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLiveKitRoomComponent, { className: "MJLiveKitRoomComponent", filePath: "src/lib/mj-livekit-room.component.ts", lineNumber: 383 }); })();
|
|
897
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, ViewChild, 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 [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 `,\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 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 * **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 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.
|
|
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.
|
|
36
|
-
"@memberjunction/global": "5.
|
|
37
|
-
"@memberjunction/graphql-dataprovider": "5.
|
|
38
|
-
"@memberjunction/livekit-room-core": "5.
|
|
39
|
-
"@memberjunction/ng-base-types": "5.
|
|
40
|
-
"@memberjunction/ng-livekit-room": "5.
|
|
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,
|