@memberjunction/ng-conversations 6.2.0-edge.5 → 6.2.0-edge.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/attachment/image-viewer.component.d.ts +3 -1
- package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +5 -1
- package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +13 -6
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +74 -28
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +60 -20
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +282 -381
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +16 -1
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +180 -144
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +5 -0
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +53 -38
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +19 -0
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +125 -13
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +2 -2
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +6 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +110 -82
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts +13 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js +21 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js.map +1 -0
- package/dist/lib/components/realtime/realtime-composer.component.js +114 -102
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +21 -2
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +113 -76
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +7 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +37 -12
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +51 -27
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.d.ts +5 -0
- package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.js +52 -5
- package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +2 -1
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/utils/agent-failure-display.d.ts +14 -0
- package/dist/lib/utils/agent-failure-display.d.ts.map +1 -0
- package/dist/lib/utils/agent-failure-display.js +26 -0
- package/dist/lib/utils/agent-failure-display.js.map +1 -0
- package/dist/lib/utils/message-list-order.d.ts +13 -0
- package/dist/lib/utils/message-list-order.d.ts.map +1 -0
- package/dist/lib/utils/message-list-order.js +31 -0
- package/dist/lib/utils/message-list-order.js.map +1 -0
- package/dist/lib/utils/pin-state.d.ts +11 -0
- package/dist/lib/utils/pin-state.d.ts.map +1 -0
- package/dist/lib/utils/pin-state.js +9 -0
- package/dist/lib/utils/pin-state.js.map +1 -0
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +36 -36
|
@@ -71,80 +71,84 @@ function RealtimeSessionOverlayComponent_Conditional_0_Conditional_9_Template(rf
|
|
|
71
71
|
i0.ɵɵelementEnd();
|
|
72
72
|
} }
|
|
73
73
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
74
|
-
i0.ɵɵelement(0, "mj-realtime-agent-orb",
|
|
75
|
-
i0.ɵɵelementStart(1, "div",
|
|
74
|
+
i0.ɵɵelement(0, "mj-realtime-agent-orb", 31);
|
|
75
|
+
i0.ɵɵelementStart(1, "div", 32);
|
|
76
76
|
i0.ɵɵelement(2, "span")(3, "span")(4, "span")(5, "span")(6, "span")(7, "span")(8, "span")(9, "span")(10, "span");
|
|
77
77
|
i0.ɵɵelementEnd();
|
|
78
78
|
} if (rf & 2) {
|
|
79
|
-
const
|
|
79
|
+
const state_r4 = i0.ɵɵnextContext(2);
|
|
80
80
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
81
|
-
i0.ɵɵproperty("State", ctx_r1.HeroOrbState(
|
|
81
|
+
i0.ɵɵproperty("State", ctx_r1.HeroOrbState(state_r4));
|
|
82
82
|
} }
|
|
83
83
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
84
|
-
i0.ɵɵelementStart(0, "span",
|
|
84
|
+
i0.ɵɵelementStart(0, "span", 35);
|
|
85
85
|
i0.ɵɵtext(1);
|
|
86
86
|
i0.ɵɵelementEnd();
|
|
87
87
|
} if (rf & 2) {
|
|
88
|
-
const
|
|
88
|
+
const caption_r5 = i0.ɵɵnextContext();
|
|
89
89
|
i0.ɵɵadvance();
|
|
90
|
-
i0.ɵɵtextInterpolate1("",
|
|
90
|
+
i0.ɵɵtextInterpolate1("", caption_r5.Speaker, ":");
|
|
91
91
|
} }
|
|
92
92
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
93
|
-
i0.ɵɵelementStart(0, "p", 28)(1, "span",
|
|
94
|
-
i0.ɵɵconditionalCreate(3, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_4_Conditional_3_Template, 2, 1, "span",
|
|
93
|
+
i0.ɵɵelementStart(0, "p", 28)(1, "span", 33)(2, "span", 34);
|
|
94
|
+
i0.ɵɵconditionalCreate(3, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_4_Conditional_3_Template, 2, 1, "span", 35);
|
|
95
95
|
i0.ɵɵtext(4);
|
|
96
96
|
i0.ɵɵelementEnd()()();
|
|
97
97
|
} if (rf & 2) {
|
|
98
|
-
const
|
|
98
|
+
const caption_r5 = ctx;
|
|
99
99
|
i0.ɵɵadvance(3);
|
|
100
|
-
i0.ɵɵconditional(
|
|
100
|
+
i0.ɵɵconditional(caption_r5.Speaker ? 3 : -1);
|
|
101
101
|
i0.ɵɵadvance();
|
|
102
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
102
|
+
i0.ɵɵtextInterpolate1(" ", caption_r5.Text, " ");
|
|
103
103
|
} }
|
|
104
104
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
105
|
-
i0.ɵɵelementStart(0, "div",
|
|
105
|
+
i0.ɵɵelementStart(0, "div", 36);
|
|
106
106
|
i0.ɵɵtext(1);
|
|
107
107
|
i0.ɵɵelementEnd();
|
|
108
|
-
i0.ɵɵelementStart(2, "div",
|
|
108
|
+
i0.ɵɵelementStart(2, "div", 37);
|
|
109
109
|
i0.ɵɵtext(3);
|
|
110
110
|
i0.ɵɵelementEnd();
|
|
111
111
|
} if (rf & 2) {
|
|
112
|
-
const
|
|
112
|
+
const state_r4 = i0.ɵɵnextContext(2);
|
|
113
113
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
114
114
|
i0.ɵɵadvance();
|
|
115
115
|
i0.ɵɵtextInterpolate(ctx_r1.AgentName);
|
|
116
116
|
i0.ɵɵadvance(2);
|
|
117
|
-
i0.ɵɵtextInterpolate(ctx_r1.HeroStateLabel(
|
|
117
|
+
i0.ɵɵtextInterpolate(ctx_r1.HeroStateLabel(state_r4));
|
|
118
118
|
} }
|
|
119
119
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
120
120
|
i0.ɵɵelementStart(0, "span", 29);
|
|
121
121
|
i0.ɵɵtext(1);
|
|
122
122
|
i0.ɵɵelementEnd();
|
|
123
123
|
} if (rf & 2) {
|
|
124
|
-
const
|
|
124
|
+
const state_r4 = i0.ɵɵnextContext(2);
|
|
125
125
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
126
126
|
i0.ɵɵadvance();
|
|
127
|
-
i0.ɵɵtextInterpolate(ctx_r1.HeroStateLabel(
|
|
127
|
+
i0.ɵɵtextInterpolate(ctx_r1.HeroStateLabel(state_r4));
|
|
128
|
+
} }
|
|
129
|
+
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
130
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
131
|
+
i0.ɵɵelementStart(0, "button", 38);
|
|
132
|
+
i0.ɵɵlistener("click", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnTextReveal()); });
|
|
133
|
+
i0.ɵɵelement(1, "i", 39);
|
|
134
|
+
i0.ɵɵtext(2, " Show the conversation ");
|
|
135
|
+
i0.ɵɵelementEnd();
|
|
128
136
|
} }
|
|
129
137
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
130
|
-
const _r4 = i0.ɵɵgetCurrentView();
|
|
131
138
|
i0.ɵɵelementStart(0, "div", 26);
|
|
132
139
|
i0.ɵɵconditionalCreate(1, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_1_Template, 11, 1);
|
|
133
140
|
i0.ɵɵelementStart(2, "div", 27, 3);
|
|
134
141
|
i0.ɵɵconditionalCreate(4, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_4_Template, 5, 2, "p", 28);
|
|
135
142
|
i0.ɵɵelementEnd();
|
|
136
143
|
i0.ɵɵconditionalCreate(5, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_5_Template, 4, 2)(6, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_6_Template, 2, 1, "span", 29);
|
|
137
|
-
i0.ɵɵ
|
|
138
|
-
i0.ɵɵ
|
|
139
|
-
i0.ɵɵelement(8, "i", 31);
|
|
140
|
-
i0.ɵɵtext(9, " Show the conversation ");
|
|
141
|
-
i0.ɵɵelementEnd()();
|
|
144
|
+
i0.ɵɵconditionalCreate(7, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Conditional_7_Template, 3, 0, "button", 30);
|
|
145
|
+
i0.ɵɵelementEnd();
|
|
142
146
|
} if (rf & 2) {
|
|
143
147
|
let tmp_11_0;
|
|
144
|
-
const
|
|
148
|
+
const state_r4 = i0.ɵɵnextContext();
|
|
145
149
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
146
150
|
i0.ɵɵclassProp("hero--presenting", ctx_r1.PresenterOnStage);
|
|
147
|
-
i0.ɵɵattribute("data-state",
|
|
151
|
+
i0.ɵɵattribute("data-state", state_r4);
|
|
148
152
|
i0.ɵɵadvance();
|
|
149
153
|
i0.ɵɵconditional(!ctx_r1.PresenterOnStage ? 1 : -1);
|
|
150
154
|
i0.ɵɵadvance();
|
|
@@ -153,10 +157,12 @@ function RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Template(r
|
|
|
153
157
|
i0.ɵɵconditional((tmp_11_0 = ctx_r1.ShowAvatarCaptions && ctx_r1.AvatarCaption) ? 4 : -1, tmp_11_0);
|
|
154
158
|
i0.ɵɵadvance();
|
|
155
159
|
i0.ɵɵconditional(!ctx_r1.PresenterOnStage ? 5 : 6);
|
|
160
|
+
i0.ɵɵadvance(2);
|
|
161
|
+
i0.ɵɵconditional(ctx_r1.PresenterOnStage || !ctx_r1.Ui.showCaptionsControl ? 7 : -1);
|
|
156
162
|
} }
|
|
157
163
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
158
164
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
159
|
-
i0.ɵɵelementStart(0, "mj-realtime-session-thread",
|
|
165
|
+
i0.ɵɵelementStart(0, "mj-realtime-session-thread", 40);
|
|
160
166
|
i0.ɵɵlistener("OpenRunRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_11_Template_mj_realtime_session_thread_OpenRunRequested_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnOpenRunRequested($event)); })("OpenArtifactRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_11_Template_mj_realtime_session_thread_OpenArtifactRequested_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnOpenArtifactRequested($event)); })("CancelRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_11_Template_mj_realtime_session_thread_CancelRequested_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCancelDelegation($event)); });
|
|
161
167
|
i0.ɵɵelementEnd();
|
|
162
168
|
} if (rf & 2) {
|
|
@@ -168,24 +174,24 @@ function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Conditiona
|
|
|
168
174
|
} }
|
|
169
175
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
170
176
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
171
|
-
i0.ɵɵelementStart(0, "mj-realtime-perception-chip",
|
|
177
|
+
i0.ɵɵelementStart(0, "mj-realtime-perception-chip", 41);
|
|
172
178
|
i0.ɵɵlistener("SourceToggled", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_perception_chip_SourceToggled_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnVideoSourceToggled($event)); })("SourcePicked", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_perception_chip_SourcePicked_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnVideoSourcePicked($event)); });
|
|
173
179
|
i0.ɵɵelementEnd();
|
|
174
180
|
i0.ɵɵconditionalCreate(1, RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Conditional_1_Template, 1, 0, "mj-realtime-channel-strip");
|
|
175
|
-
i0.ɵɵelementStart(2, "mj-realtime-composer",
|
|
181
|
+
i0.ɵɵelementStart(2, "mj-realtime-composer", 42);
|
|
176
182
|
i0.ɵɵlistener("OpenChanged", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_OpenChanged_2_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnComposerOpenChanged($event)); })("CameraToggled", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_CameraToggled_2_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCameraToggled($event)); })("ShareRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_ShareRequested_2_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnShareRequested($event)); })("StopShareRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_StopShareRequested_2_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnStopShareRequested()); })("DeviceSelected", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_DeviceSelected_2_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeviceSelected($event)); })("CaptionsToggled", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_CaptionsToggled_2_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCaptionsToggled($event)); })("DetailsToggled", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_DetailsToggled_2_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDetailsToggled()); })("MuteChanged", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_MuteChanged_2_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnComposerMuteChanged($event)); })("EndRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template_mj_realtime_composer_EndRequested_2_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnEndCall()); });
|
|
177
183
|
i0.ɵɵelementEnd();
|
|
178
184
|
} if (rf & 2) {
|
|
179
185
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
180
|
-
i0.ɵɵproperty("Sources", ctx_r1.
|
|
186
|
+
i0.ɵɵproperty("Sources", ctx_r1.VisibleVideoSources);
|
|
181
187
|
i0.ɵɵadvance();
|
|
182
188
|
i0.ɵɵconditional(ctx_r1.ChannelStripVisible ? 1 : -1);
|
|
183
189
|
i0.ɵɵadvance();
|
|
184
|
-
i0.ɵɵproperty("Open", ctx_r1.ComposerOpen)("Compact", ctx_r1.Ui.
|
|
190
|
+
i0.ɵɵproperty("Open", ctx_r1.ComposerOpen)("Compact", ctx_r1.Ui.chrome === "orb" || ctx_r1.Ui.compact)("CaptionsOn", ctx_r1.ShowCaptions)("IsMuted", ctx_r1.Muted)("ShowCamera", ctx_r1.CaptureOffers.Camera)("ShowShare", ctx_r1.CaptureOffers.Screen)("CameraOn", ctx_r1.CameraOn)("Sharing", ctx_r1.Sharing)("SharePanels", ctx_r1.SharePanels)("Devices", ctx_r1.CallDevices)("SelectedMicrophoneID", ctx_r1.SelectedMicrophoneID)("SelectedCameraID", ctx_r1.SelectedCameraID)("ShowDetails", ctx_r1.ShowDetailsControl)("DetailsOn", ctx_r1.DetailsPeek);
|
|
185
191
|
} }
|
|
186
192
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
187
193
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
188
|
-
i0.ɵɵelementStart(0, "div",
|
|
194
|
+
i0.ɵɵelementStart(0, "div", 46);
|
|
189
195
|
i0.ɵɵlistener("mousedown", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnPanelResizeStart($event)); })("dblclick", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Conditional_0_Template_div_dblclick_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnPanelResizeReset()); });
|
|
190
196
|
i0.ɵɵelementEnd();
|
|
191
197
|
} if (rf & 2) {
|
|
@@ -194,8 +200,8 @@ function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Conditiona
|
|
|
194
200
|
} }
|
|
195
201
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
196
202
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
197
|
-
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Conditional_0_Template, 1, 2, "div",
|
|
198
|
-
i0.ɵɵelementStart(1, "div",
|
|
203
|
+
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Conditional_0_Template, 1, 2, "div", 43);
|
|
204
|
+
i0.ɵɵelementStart(1, "div", 44)(2, "mj-realtime-surface-tabs", 45);
|
|
199
205
|
i0.ɵɵlistener("OpenRunRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template_mj_realtime_surface_tabs_OpenRunRequested_2_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnOpenRunRequested($event)); })("CollapsedChange", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template_mj_realtime_surface_tabs_CollapsedChange_2_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnPanelCollapsedChange($event)); })("WideChanged", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template_mj_realtime_surface_tabs_WideChanged_2_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnPanelWideChanged($event)); })("ActiveChannelChange", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template_mj_realtime_surface_tabs_ActiveChannelChange_2_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnActiveChannelChange($event)); })("ChannelSlotChange", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template_mj_realtime_surface_tabs_ChannelSlotChange_2_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnChannelSlotChange($event)); })("MoveRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template_mj_realtime_surface_tabs_MoveRequested_2_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnMoveRequested($event)); })("ResetLayoutRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template_mj_realtime_surface_tabs_ResetLayoutRequested_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnResetLayout()); });
|
|
200
206
|
i0.ɵɵelementEnd()();
|
|
201
207
|
} if (rf & 2) {
|
|
@@ -208,7 +214,7 @@ function RealtimeSessionOverlayComponent_Conditional_0_Conditional_15_Template(r
|
|
|
208
214
|
} }
|
|
209
215
|
function RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
210
216
|
const _r11 = i0.ɵɵgetCurrentView();
|
|
211
|
-
i0.ɵɵelementStart(0, "mj-media-move-menu",
|
|
217
|
+
i0.ɵɵelementStart(0, "mj-media-move-menu", 50);
|
|
212
218
|
i0.ɵɵlistener("MoveRequested", function RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditional_0_Conditional_2_Template_mj_media_move_menu_MoveRequested_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnMoveRequested($event)); })("ResetLayoutRequested", function RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditional_0_Conditional_2_Template_mj_media_move_menu_ResetLayoutRequested_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnResetLayout()); });
|
|
213
219
|
i0.ɵɵelementEnd();
|
|
214
220
|
} if (rf & 2) {
|
|
@@ -218,9 +224,9 @@ function RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditiona
|
|
|
218
224
|
i0.ɵɵproperty("Key", key_r13)("Title", plugin_r12.TabTitle)("Allowed", ctx_r1.SurfaceStage.AllowedFor(key_r13));
|
|
219
225
|
} }
|
|
220
226
|
function RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
221
|
-
i0.ɵɵelementStart(0, "div",
|
|
222
|
-
i0.ɵɵelement(1, "mj-realtime-channel-pane",
|
|
223
|
-
i0.ɵɵconditionalCreate(2, RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditional_0_Conditional_2_Template, 1, 3, "mj-media-move-menu",
|
|
227
|
+
i0.ɵɵelementStart(0, "div", 47);
|
|
228
|
+
i0.ɵɵelement(1, "mj-realtime-channel-pane", 48);
|
|
229
|
+
i0.ɵɵconditionalCreate(2, RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditional_0_Conditional_2_Template, 1, 3, "mj-media-move-menu", 49);
|
|
224
230
|
i0.ɵɵelementEnd();
|
|
225
231
|
} if (rf & 2) {
|
|
226
232
|
const plugin_r12 = ctx;
|
|
@@ -235,7 +241,7 @@ function RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditiona
|
|
|
235
241
|
i0.ɵɵconditional(placement_r16 === "stage" && plugin_r12.ShowsAgentVideo ? 2 : -1);
|
|
236
242
|
} }
|
|
237
243
|
function RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Template(rf, ctx) { if (rf & 1) {
|
|
238
|
-
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditional_0_Template, 3, 7, "div",
|
|
244
|
+
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Conditional_0_Template, 3, 7, "div", 47);
|
|
239
245
|
} if (rf & 2) {
|
|
240
246
|
let tmp_9_0;
|
|
241
247
|
const key_r13 = ctx.$implicit;
|
|
@@ -244,7 +250,7 @@ function RealtimeSessionOverlayComponent_Conditional_0_ng_template_17_Template(r
|
|
|
244
250
|
} }
|
|
245
251
|
function RealtimeSessionOverlayComponent_Conditional_0_ng_template_18_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
246
252
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
247
|
-
i0.ɵɵelementStart(0, "mj-media-move-menu",
|
|
253
|
+
i0.ɵɵelementStart(0, "mj-media-move-menu", 52);
|
|
248
254
|
i0.ɵɵlistener("MoveRequested", function RealtimeSessionOverlayComponent_Conditional_0_ng_template_18_Conditional_0_Template_mj_media_move_menu_MoveRequested_0_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnMoveRequested($event)); })("ResetLayoutRequested", function RealtimeSessionOverlayComponent_Conditional_0_ng_template_18_Conditional_0_Template_mj_media_move_menu_ResetLayoutRequested_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnResetLayout()); });
|
|
249
255
|
i0.ɵɵelementEnd();
|
|
250
256
|
} if (rf & 2) {
|
|
@@ -253,7 +259,7 @@ function RealtimeSessionOverlayComponent_Conditional_0_ng_template_18_Conditiona
|
|
|
253
259
|
i0.ɵɵproperty("Key", key_r18)("Title", ctx.TabTitle)("Allowed", ctx_r1.SurfaceStage.AllowedFor(key_r18));
|
|
254
260
|
} }
|
|
255
261
|
function RealtimeSessionOverlayComponent_Conditional_0_ng_template_18_Template(rf, ctx) { if (rf & 1) {
|
|
256
|
-
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_Conditional_0_ng_template_18_Conditional_0_Template, 1, 3, "mj-media-move-menu",
|
|
262
|
+
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_Conditional_0_ng_template_18_Conditional_0_Template, 1, 3, "mj-media-move-menu", 51);
|
|
257
263
|
} if (rf & 2) {
|
|
258
264
|
let tmp_7_0;
|
|
259
265
|
const key_r18 = ctx.$implicit;
|
|
@@ -261,7 +267,7 @@ function RealtimeSessionOverlayComponent_Conditional_0_ng_template_18_Template(r
|
|
|
261
267
|
i0.ɵɵconditional((tmp_7_0 = ctx_r1.SurfaceStage.PluginFor(key_r18)) ? 0 : -1, tmp_7_0);
|
|
262
268
|
} }
|
|
263
269
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
264
|
-
i0.ɵɵelementStart(0, "span",
|
|
270
|
+
i0.ɵɵelementStart(0, "span", 56);
|
|
265
271
|
i0.ɵɵtext(1);
|
|
266
272
|
i0.ɵɵelementEnd();
|
|
267
273
|
} if (rf & 2) {
|
|
@@ -270,7 +276,7 @@ function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditiona
|
|
|
270
276
|
} }
|
|
271
277
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
272
278
|
const _r20 = i0.ɵɵgetCurrentView();
|
|
273
|
-
i0.ɵɵelementStart(0, "mj-media-move-menu",
|
|
279
|
+
i0.ɵɵelementStart(0, "mj-media-move-menu", 64);
|
|
274
280
|
i0.ɵɵlistener("MoveRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditional_10_Template_mj_media_move_menu_MoveRequested_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnMoveRequested($event)); })("ResetLayoutRequested", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditional_10_Template_mj_media_move_menu_ResetLayoutRequested_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnResetLayout()); });
|
|
275
281
|
i0.ɵɵelementEnd();
|
|
276
282
|
} if (rf & 2) {
|
|
@@ -281,36 +287,36 @@ function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditiona
|
|
|
281
287
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
282
288
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
283
289
|
i0.ɵɵelementStart(0, "div", 20);
|
|
284
|
-
i0.ɵɵelement(1, "span",
|
|
285
|
-
i0.ɵɵelementStart(2, "span",
|
|
290
|
+
i0.ɵɵelement(1, "span", 53);
|
|
291
|
+
i0.ɵɵelementStart(2, "span", 54)(3, "span", 55);
|
|
286
292
|
i0.ɵɵtext(4);
|
|
287
293
|
i0.ɵɵelementEnd();
|
|
288
|
-
i0.ɵɵconditionalCreate(5, RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditional_5_Template, 2, 1, "span",
|
|
294
|
+
i0.ɵɵconditionalCreate(5, RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditional_5_Template, 2, 1, "span", 56);
|
|
289
295
|
i0.ɵɵelementEnd();
|
|
290
|
-
i0.ɵɵelementStart(6, "button",
|
|
296
|
+
i0.ɵɵelementStart(6, "button", 57);
|
|
291
297
|
i0.ɵɵlistener("click", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFocusPillMute()); });
|
|
292
|
-
i0.ɵɵelement(7, "i",
|
|
298
|
+
i0.ɵɵelement(7, "i", 58);
|
|
293
299
|
i0.ɵɵelementEnd();
|
|
294
|
-
i0.ɵɵelementStart(8, "button",
|
|
300
|
+
i0.ɵɵelementStart(8, "button", 59);
|
|
295
301
|
i0.ɵɵlistener("click", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFocusPillExit()); });
|
|
296
|
-
i0.ɵɵelement(9, "i",
|
|
302
|
+
i0.ɵɵelement(9, "i", 60);
|
|
297
303
|
i0.ɵɵelementEnd();
|
|
298
|
-
i0.ɵɵconditionalCreate(10, RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditional_10_Template, 1, 3, "mj-media-move-menu",
|
|
299
|
-
i0.ɵɵelementStart(11, "button",
|
|
304
|
+
i0.ɵɵconditionalCreate(10, RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Conditional_10_Template, 1, 3, "mj-media-move-menu", 61);
|
|
305
|
+
i0.ɵɵelementStart(11, "button", 62);
|
|
300
306
|
i0.ɵɵlistener("click", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFocusPillEnd()); });
|
|
301
|
-
i0.ɵɵelement(12, "i",
|
|
307
|
+
i0.ɵɵelement(12, "i", 63);
|
|
302
308
|
i0.ɵɵelementEnd()();
|
|
303
309
|
} if (rf & 2) {
|
|
304
310
|
let tmp_8_0;
|
|
305
311
|
let tmp_14_0;
|
|
306
|
-
const
|
|
312
|
+
const state_r4 = i0.ɵɵnextContext();
|
|
307
313
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
308
314
|
i0.ɵɵadvance();
|
|
309
|
-
i0.ɵɵattribute("data-state",
|
|
315
|
+
i0.ɵɵattribute("data-state", state_r4);
|
|
310
316
|
i0.ɵɵadvance(3);
|
|
311
317
|
i0.ɵɵtextInterpolate1("Voice for ", ctx_r1.AgentName);
|
|
312
318
|
i0.ɵɵadvance();
|
|
313
|
-
i0.ɵɵconditional((tmp_8_0 = ctx_r1.FocusStateLabel(
|
|
319
|
+
i0.ɵɵconditional((tmp_8_0 = ctx_r1.FocusStateLabel(state_r4)) ? 5 : -1, tmp_8_0);
|
|
314
320
|
i0.ɵɵadvance();
|
|
315
321
|
i0.ɵɵclassProp("board-focus-pill__btn--active", ctx_r1.FocusPillMuted);
|
|
316
322
|
i0.ɵɵproperty("title", ctx_r1.FocusPillMuted ? "Unmute" : "Mute");
|
|
@@ -322,7 +328,7 @@ function RealtimeSessionOverlayComponent_Conditional_0_Conditional_19_Template(r
|
|
|
322
328
|
} }
|
|
323
329
|
function RealtimeSessionOverlayComponent_Conditional_0_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
324
330
|
const _r22 = i0.ɵɵgetCurrentView();
|
|
325
|
-
i0.ɵɵelementStart(0, "mj-realtime-camera-check-card",
|
|
331
|
+
i0.ɵɵelementStart(0, "mj-realtime-camera-check-card", 65);
|
|
326
332
|
i0.ɵɵlistener("Confirmed", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_20_Template_mj_realtime_camera_check_card_Confirmed_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCameraCheckConfirmed()); })("Declined", function RealtimeSessionOverlayComponent_Conditional_0_Conditional_20_Template_mj_realtime_camera_check_card_Declined_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCameraCheckDeclined()); });
|
|
327
333
|
i0.ɵɵelementEnd();
|
|
328
334
|
} if (rf & 2) {
|
|
@@ -340,7 +346,7 @@ function RealtimeSessionOverlayComponent_Conditional_0_Template(rf, ctx) { if (r
|
|
|
340
346
|
i0.ɵɵconditionalCreate(6, RealtimeSessionOverlayComponent_Conditional_0_Conditional_6_Template, 3, 1, "div", 10);
|
|
341
347
|
i0.ɵɵconditionalCreate(7, RealtimeSessionOverlayComponent_Conditional_0_Conditional_7_Template, 2, 2, "div", 11);
|
|
342
348
|
i0.ɵɵelementStart(8, "div", 12);
|
|
343
|
-
i0.ɵɵconditionalCreate(9, RealtimeSessionOverlayComponent_Conditional_0_Conditional_9_Template, 2, 0, "div", 13)(10, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Template,
|
|
349
|
+
i0.ɵɵconditionalCreate(9, RealtimeSessionOverlayComponent_Conditional_0_Conditional_9_Template, 2, 0, "div", 13)(10, RealtimeSessionOverlayComponent_Conditional_0_Conditional_10_Template, 8, 9, "div", 14)(11, RealtimeSessionOverlayComponent_Conditional_0_Conditional_11_Template, 1, 5, "mj-realtime-session-thread", 15);
|
|
344
350
|
i0.ɵɵelementEnd();
|
|
345
351
|
i0.ɵɵelementStart(12, "div", 16, 2);
|
|
346
352
|
i0.ɵɵconditionalCreate(14, RealtimeSessionOverlayComponent_Conditional_0_Conditional_14_Template, 3, 16);
|
|
@@ -354,17 +360,17 @@ function RealtimeSessionOverlayComponent_Conditional_0_Template(rf, ctx) { if (r
|
|
|
354
360
|
i0.ɵɵconditionalCreate(20, RealtimeSessionOverlayComponent_Conditional_0_Conditional_20_Template, 1, 3, "mj-realtime-camera-check-card", 21);
|
|
355
361
|
i0.ɵɵelementEnd();
|
|
356
362
|
} if (rf & 2) {
|
|
357
|
-
let
|
|
358
|
-
let
|
|
359
|
-
const
|
|
363
|
+
let tmp_26_0;
|
|
364
|
+
let tmp_41_0;
|
|
365
|
+
const state_r4 = ctx;
|
|
360
366
|
const callControls_r23 = i0.ɵɵreference(13);
|
|
361
367
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
362
368
|
i0.ɵɵclassProp("call-overlay--hidden", ctx_r1.Hidden)("call-overlay--review", ctx_r1.IsReviewing)("board-focus", ctx_r1.ChannelFocusMode);
|
|
363
369
|
i0.ɵɵattribute("aria-label", ctx_r1.IsReviewing ? "Past session review" : "Live voice session");
|
|
364
370
|
i0.ɵɵadvance(2);
|
|
365
|
-
i0.ɵɵproperty("State",
|
|
371
|
+
i0.ɵɵproperty("State", state_r4)("Compact", !ctx_r1.IsReviewing && ctx_r1.Ui.compact && ctx_r1.Ui.chrome === "orb")("HideState", ctx_r1.ShowHero && !ctx_r1.PresenterOnStage)("AgentName", ctx_r1.AgentName)("ErrorLabel", ctx_r1.CallEndLabel)("ModelName", ctx_r1.IsReviewing ? null : i0.ɵɵpipeBind1(3, 41, ctx_r1.ModelName$))("DevMode", ctx_r1.DevMode)("SessionID", ctx_r1.IsReviewing ? ctx_r1.ReviewSessionID : ctx_r1.SessionID)("ReviewMode", ctx_r1.IsReviewing)("ReviewStartedAt", ctx_r1.ReviewStartedAt)("ReviewClosedAt", ctx_r1.ReviewClosedAt)("ReviewCloseReason", ctx_r1.ReviewCloseReason)("ShowGear", !ctx_r1.IsReviewing && ctx_r1.Ui.showGear)("ShowDensityPicker", ctx_r1.Ui.showDensityPicker)("ShowMinimize", !ctx_r1.IsReviewing && ctx_r1.Ui.showMinimize)("ShowStartLive", ctx_r1.AllowStartLive)("Density", ctx_r1.Disclosure.Milestones.Density);
|
|
366
372
|
i0.ɵɵadvance(2);
|
|
367
|
-
i0.ɵɵconditional((
|
|
373
|
+
i0.ɵɵconditional((tmp_26_0 = ctx_r1.MicrophoneNotice) ? 4 : -1, tmp_26_0);
|
|
368
374
|
i0.ɵɵadvance();
|
|
369
375
|
i0.ɵɵconditional(ctx_r1.AvatarNotice ? 5 : -1);
|
|
370
376
|
i0.ɵɵadvance();
|
|
@@ -372,9 +378,9 @@ function RealtimeSessionOverlayComponent_Conditional_0_Template(rf, ctx) { if (r
|
|
|
372
378
|
i0.ɵɵadvance();
|
|
373
379
|
i0.ɵɵconditional(!ctx_r1.ShowHero ? 7 : -1);
|
|
374
380
|
i0.ɵɵadvance();
|
|
375
|
-
i0.ɵɵclassProp("call-body--hero", ctx_r1.ShowHero && !ctx_r1.ShowConnectingScreen(
|
|
381
|
+
i0.ɵɵclassProp("call-body--hero", ctx_r1.ShowHero && !ctx_r1.ShowConnectingScreen(state_r4));
|
|
376
382
|
i0.ɵɵadvance();
|
|
377
|
-
i0.ɵɵconditional(ctx_r1.ShowConnectingScreen(
|
|
383
|
+
i0.ɵɵconditional(ctx_r1.ShowConnectingScreen(state_r4) ? 9 : ctx_r1.ShowHero ? 10 : 11);
|
|
378
384
|
i0.ɵɵadvance(5);
|
|
379
385
|
i0.ɵɵconditional(!ctx_r1.IsReviewing ? 14 : -1);
|
|
380
386
|
i0.ɵɵadvance();
|
|
@@ -384,11 +390,11 @@ function RealtimeSessionOverlayComponent_Conditional_0_Template(rf, ctx) { if (r
|
|
|
384
390
|
i0.ɵɵadvance(3);
|
|
385
391
|
i0.ɵɵconditional(!ctx_r1.IsReviewing && ctx_r1.ChannelFocusMode ? 19 : -1);
|
|
386
392
|
i0.ɵɵadvance();
|
|
387
|
-
i0.ɵɵconditional((
|
|
393
|
+
i0.ɵɵconditional((tmp_41_0 = ctx_r1.CameraCheck) ? 20 : -1, tmp_41_0);
|
|
388
394
|
} }
|
|
389
395
|
function RealtimeSessionOverlayComponent_ng_template_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
390
|
-
i0.ɵɵelementStart(0, "div",
|
|
391
|
-
i0.ɵɵelement(1, "mj-realtime-whiteboard",
|
|
396
|
+
i0.ɵɵelementStart(0, "div", 66);
|
|
397
|
+
i0.ɵɵelement(1, "mj-realtime-whiteboard", 67);
|
|
392
398
|
i0.ɵɵelementEnd();
|
|
393
399
|
} if (rf & 2) {
|
|
394
400
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -396,15 +402,15 @@ function RealtimeSessionOverlayComponent_ng_template_2_Conditional_0_Template(rf
|
|
|
396
402
|
i0.ɵɵproperty("State", ctx)("AgentName", ctx_r1.AgentName)("ReadOnly", true);
|
|
397
403
|
} }
|
|
398
404
|
function RealtimeSessionOverlayComponent_ng_template_2_Template(rf, ctx) { if (rf & 1) {
|
|
399
|
-
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_ng_template_2_Conditional_0_Template, 2, 3, "div",
|
|
405
|
+
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_ng_template_2_Conditional_0_Template, 2, 3, "div", 66);
|
|
400
406
|
} if (rf & 2) {
|
|
401
407
|
let tmp_3_0;
|
|
402
408
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
403
409
|
i0.ɵɵconditional((tmp_3_0 = ctx_r1.ReviewWhiteboard) ? 0 : -1, tmp_3_0);
|
|
404
410
|
} }
|
|
405
411
|
function RealtimeSessionOverlayComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) {
|
|
406
|
-
i0.ɵɵelementStart(0, "div",
|
|
407
|
-
i0.ɵɵelement(1, "mj-storage-media-player",
|
|
412
|
+
i0.ɵɵelementStart(0, "div", 68);
|
|
413
|
+
i0.ɵɵelement(1, "mj-storage-media-player", 69);
|
|
408
414
|
i0.ɵɵelementEnd();
|
|
409
415
|
} if (rf & 2) {
|
|
410
416
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -502,6 +508,18 @@ export class RealtimeSessionOverlayComponent extends BaseAngularComponent {
|
|
|
502
508
|
* this version doesn't know, such as a newer server's, in place of `AVATAR_NOTICE_CALL_UNKNOWN_REASON_TEXT`.
|
|
503
509
|
*/
|
|
504
510
|
AvatarNoticeLabels = null;
|
|
511
|
+
/**
|
|
512
|
+
* Whether the top "Audio only: this voice model can't show an avatar" notice banner is shown when
|
|
513
|
+
* an audio-only call connects. Default `false` so standard voice sessions stay calm and uncluttered
|
|
514
|
+
* unless a host explicitly opts into showing avatar capability notices.
|
|
515
|
+
*/
|
|
516
|
+
ShowAvatarNotice = false;
|
|
517
|
+
/**
|
|
518
|
+
* Whether the bottom "Agent can see" perception chip is always shown even when only background channel
|
|
519
|
+
* bridges exist. Default `false`: the chip is only shown when the user actively captures their camera or
|
|
520
|
+
* screen ({@link CameraOn} / {@link Sharing}), or when explicitly enabled via `[ShowPerceptionChip]="true"`.
|
|
521
|
+
*/
|
|
522
|
+
ShowPerceptionChip = false;
|
|
505
523
|
// ── Declarative UI configuration (host controls every aspect of the surface) ──
|
|
506
524
|
//
|
|
507
525
|
// Each input is a thin, PascalCase setter over a private slot in {@link _uiInputs}.
|
|
@@ -989,11 +1007,11 @@ export class RealtimeSessionOverlayComponent extends BaseAngularComponent {
|
|
|
989
1007
|
avatarNoticeTimer = null;
|
|
990
1008
|
/**
|
|
991
1009
|
* Why this live call shows no avatar its agent asked for, while the notice shows: from the moment the call connects
|
|
992
|
-
* until the user dismisses it or it hides itself. `null` otherwise, and always in review.
|
|
1010
|
+
* until the user dismisses it or it hides itself. `null` otherwise, when {@link ShowAvatarNotice} is off, and always in review.
|
|
993
1011
|
*/
|
|
994
1012
|
get AvatarNotice() {
|
|
995
1013
|
const notice = this.avatarNotice;
|
|
996
|
-
return notice && notice !== this.avatarNoticeDone && !this.IsReviewing ? notice : null;
|
|
1014
|
+
return this.ShowAvatarNotice && notice && notice !== this.avatarNoticeDone && !this.IsReviewing ? notice : null;
|
|
997
1015
|
}
|
|
998
1016
|
/**
|
|
999
1017
|
* The notice's line, in the host's words when it gave some ({@link AvatarNoticeLabels}); a notice without a reason (one
|
|
@@ -1033,6 +1051,21 @@ export class RealtimeSessionOverlayComponent extends BaseAngularComponent {
|
|
|
1033
1051
|
}
|
|
1034
1052
|
/** The video sources the agent can or could see right now (see {@link RealtimeSessionService.VideoSources$}). */
|
|
1035
1053
|
VideoSources = [];
|
|
1054
|
+
/**
|
|
1055
|
+
* The video sources surfaced to `<mj-realtime-perception-chip>`.
|
|
1056
|
+
* By default (`ShowPerceptionChip = false`), the chip only appears when the user has an active camera or
|
|
1057
|
+
* screen capture (`CameraOn`, `Sharing`, or an enabled `'camera'` / `'screen'` source), preventing
|
|
1058
|
+
* background channel bridges from cluttering pure-voice calls.
|
|
1059
|
+
*/
|
|
1060
|
+
get VisibleVideoSources() {
|
|
1061
|
+
const hasUserCapture = this.CameraOn ||
|
|
1062
|
+
this.Sharing ||
|
|
1063
|
+
this.VideoSources.some((s) => (s.Kind === 'camera' || s.Kind === 'screen') && s.Enabled);
|
|
1064
|
+
if (!this.ShowPerceptionChip && !hasUserCapture) {
|
|
1065
|
+
return [];
|
|
1066
|
+
}
|
|
1067
|
+
return this.VideoSources;
|
|
1068
|
+
}
|
|
1036
1069
|
/** The user's camera and screen share (see {@link RealtimeSessionService.Captures$}). */
|
|
1037
1070
|
CaptureStates = REALTIME_CAPTURES_OFF;
|
|
1038
1071
|
/** Which captures the call offers (see {@link RealtimeSessionService.CaptureOffers$}); the composer shows Camera and Share from it. */
|
|
@@ -2532,8 +2565,8 @@ export class RealtimeSessionOverlayComponent extends BaseAngularComponent {
|
|
|
2532
2565
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.presenterSlotRef = _t.first);
|
|
2533
2566
|
} }, hostBindings: function RealtimeSessionOverlayComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
2534
2567
|
i0.ɵɵlistener("keydown", function RealtimeSessionOverlayComponent_keydown_HostBindingHandler($event) { return ctx.OnDocumentKeydown($event); }, i0.ɵɵresolveDocument);
|
|
2535
|
-
} }, inputs: { Hidden: "Hidden", AgentName: "AgentName", CurrentUser: "CurrentUser", EnvironmentID: "EnvironmentID", AvatarNoticeLabels: "AvatarNoticeLabels", Chrome: "Chrome", ConsoleBreakpointPx: "ConsoleBreakpointPx", Compact: "Compact", AutoHideControls: "AutoHideControls", AllowTextReveal: "AllowTextReveal", ShowCaptionsControl: "ShowCaptionsControl", ShowDensityPicker: "ShowDensityPicker", ShowMinimize: "ShowMinimize", ShowEnd: "ShowEnd", ShowSurfacePanel: "ShowSurfacePanel", ShowChannels: "ShowChannels", ShowActivityRail: "ShowActivityRail", ShowDevLinks: "ShowDevLinks", AllowResize: "AllowResize", UiConfig: "UiConfig", ReviewData: "ReviewData", AllowStartLive: "AllowStartLive" }, outputs: { Ended: "Ended", NavigateRequest: "NavigateRequest", StartLiveRequested: "StartLiveRequested", ReviewClosed: "ReviewClosed", Minimized: "Minimized", TextRevealed: "TextRevealed", ChromeChanged: "ChromeChanged", ConnectionStateChanged: "ConnectionStateChanged", MuteChanged: "MuteChanged", DensityChanged: "DensityChanged", SurfacePanelResized: "SurfacePanelResized", ControlInvoked: "ControlInvoked" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 3, consts: [["reviewBoardTpl", ""], ["recordingTpl", ""], ["callControls", ""], ["presenterSlot", ""], ["role", "region", 1, "call-overlay", 3, "call-overlay--hidden", "call-overlay--review", "board-focus"], ["role", "region", 1, "call-overlay"], [1, "call-main"], [3, "OpenSessionRequested", "DevModeToggled", "DensityChanged", "MinimizeRequested", "StartLiveRequested", "CloseRequested", "State", "Compact", "AgentName", "ErrorLabel", "ModelName", "DevMode", "SessionID", "ReviewMode", "ReviewStartedAt", "ReviewClosedAt", "ReviewCloseReason", "ShowGear", "ShowDensityPicker", "ShowMinimize", "ShowStartLive", "Density"], ["Variant", "warning", "Size", "sm", "Icon", "fa-solid fa-microphone-slash", 1, "call-microphone-notice", 3, "Message"], ["Variant", "info", "Size", "sm", "Icon", "fa-solid fa-video-slash", "Dismissible", "", 1, "call-avatar-notice", 3, "Message"], ["role", "status", "aria-live", "polite", 1, "banner-live-note"], [1, "call-presenter", 3, "call-presenter--on"], [1, "call-body"], [1, "call-connecting"], ["role", "status", "aria-live", "polite", 1, "hero", 3, "hero--presenting"], [3, "State", "AgentName", "UserName", "ShowCaptions", "DevMode"], [1, "call-controls"], [1, "call-stage", 3, "PipRectChange", "Surfaces", "TabSlot", "StageSlot", "ActiveTabKey", "PipRects", "PipKeepClear"], ["mjMediaStageSurface", ""], ["mjMediaStagePipActions", ""], ["role", "status", "aria-label", "Live call (board focus)", 1, "board-focus-pill"], [3, "Camera", "AgentName", "Switch"], ["Variant", "info", "Size", "sm", "Icon", "fa-solid fa-video-slash", "Dismissible", "", 1, "call-avatar-notice", 3, "Dismissed", "Message"], ["aria-hidden", "true", 1, "fa-solid", "fa-comment-dots"], [1, "call-presenter"], ["text", "Connecting to the live session\u2026", "size", "medium"], ["role", "status", "aria-live", "polite", 1, "hero"], [1, "hero__presenter"], ["aria-hidden", "true", 1, "hero__caption"], [1, "hero__sr"], ["type", "button", "title", "Show the conversation as text", 1, "hero__reveal", 3, "
|
|
2536
|
-
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_Conditional_0_Template, 21,
|
|
2568
|
+
} }, inputs: { Hidden: "Hidden", AgentName: "AgentName", CurrentUser: "CurrentUser", EnvironmentID: "EnvironmentID", AvatarNoticeLabels: "AvatarNoticeLabels", ShowAvatarNotice: "ShowAvatarNotice", ShowPerceptionChip: "ShowPerceptionChip", Chrome: "Chrome", ConsoleBreakpointPx: "ConsoleBreakpointPx", Compact: "Compact", AutoHideControls: "AutoHideControls", AllowTextReveal: "AllowTextReveal", ShowCaptionsControl: "ShowCaptionsControl", ShowDensityPicker: "ShowDensityPicker", ShowMinimize: "ShowMinimize", ShowEnd: "ShowEnd", ShowSurfacePanel: "ShowSurfacePanel", ShowChannels: "ShowChannels", ShowActivityRail: "ShowActivityRail", ShowDevLinks: "ShowDevLinks", AllowResize: "AllowResize", UiConfig: "UiConfig", ReviewData: "ReviewData", AllowStartLive: "AllowStartLive" }, outputs: { Ended: "Ended", NavigateRequest: "NavigateRequest", StartLiveRequested: "StartLiveRequested", ReviewClosed: "ReviewClosed", Minimized: "Minimized", TextRevealed: "TextRevealed", ChromeChanged: "ChromeChanged", ConnectionStateChanged: "ConnectionStateChanged", MuteChanged: "MuteChanged", DensityChanged: "DensityChanged", SurfacePanelResized: "SurfacePanelResized", ControlInvoked: "ControlInvoked" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 3, consts: [["reviewBoardTpl", ""], ["recordingTpl", ""], ["callControls", ""], ["presenterSlot", ""], ["role", "region", 1, "call-overlay", 3, "call-overlay--hidden", "call-overlay--review", "board-focus"], ["role", "region", 1, "call-overlay"], [1, "call-main"], [3, "OpenSessionRequested", "DevModeToggled", "DensityChanged", "MinimizeRequested", "StartLiveRequested", "CloseRequested", "State", "Compact", "HideState", "AgentName", "ErrorLabel", "ModelName", "DevMode", "SessionID", "ReviewMode", "ReviewStartedAt", "ReviewClosedAt", "ReviewCloseReason", "ShowGear", "ShowDensityPicker", "ShowMinimize", "ShowStartLive", "Density"], ["Variant", "warning", "Size", "sm", "Icon", "fa-solid fa-microphone-slash", 1, "call-microphone-notice", 3, "Message"], ["Variant", "info", "Size", "sm", "Icon", "fa-solid fa-video-slash", "Dismissible", "", 1, "call-avatar-notice", 3, "Message"], ["role", "status", "aria-live", "polite", 1, "banner-live-note"], [1, "call-presenter", 3, "call-presenter--on"], [1, "call-body"], [1, "call-connecting"], ["role", "status", "aria-live", "polite", 1, "hero", 3, "hero--presenting"], [3, "State", "AgentName", "UserName", "ShowCaptions", "DevMode"], [1, "call-controls"], [1, "call-stage", 3, "PipRectChange", "Surfaces", "TabSlot", "StageSlot", "ActiveTabKey", "PipRects", "PipKeepClear"], ["mjMediaStageSurface", ""], ["mjMediaStagePipActions", ""], ["role", "status", "aria-label", "Live call (board focus)", 1, "board-focus-pill"], [3, "Camera", "AgentName", "Switch"], ["Variant", "info", "Size", "sm", "Icon", "fa-solid fa-video-slash", "Dismissible", "", 1, "call-avatar-notice", 3, "Dismissed", "Message"], ["aria-hidden", "true", 1, "fa-solid", "fa-comment-dots"], [1, "call-presenter"], ["text", "Connecting to the live session\u2026", "size", "medium"], ["role", "status", "aria-live", "polite", 1, "hero"], [1, "hero__presenter"], ["aria-hidden", "true", 1, "hero__caption"], [1, "hero__sr"], ["type", "button", "title", "Show the conversation as text", 1, "hero__reveal"], [1, "hero__orb", 3, "State"], ["aria-hidden", "true", 1, "hero__eq"], [1, "hero__caption-window"], [1, "hero__caption-lines"], [1, "hero__caption-speaker"], [1, "hero__name"], [1, "hero__sub"], ["type", "button", "title", "Show the conversation as text", 1, "hero__reveal", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-closed-captioning"], [3, "OpenRunRequested", "OpenArtifactRequested", "CancelRequested", "State", "AgentName", "UserName", "ShowCaptions", "DevMode"], [3, "SourceToggled", "SourcePicked", "Sources"], [3, "OpenChanged", "CameraToggled", "ShareRequested", "StopShareRequested", "DeviceSelected", "CaptionsToggled", "DetailsToggled", "MuteChanged", "EndRequested", "Open", "Compact", "CaptionsOn", "IsMuted", "ShowCamera", "ShowShare", "CameraOn", "Sharing", "SharePanels", "Devices", "SelectedMicrophoneID", "SelectedCameraID", "ShowDetails", "DetailsOn"], ["role", "separator", "aria-orientation", "vertical", "aria-label", "Resize the surface panel (double-click to reset)", "title", "Drag to resize \u2022 double-click to reset", 1, "call-resizer", 3, "call-resizer--active"], [1, "call-panel"], [3, "OpenRunRequested", "CollapsedChange", "WideChanged", "ActiveChannelChange", "ChannelSlotChange", "MoveRequested", "ResetLayoutRequested", "State", "DevMode", "CurrentUser", "EnvironmentID", "ShowActivityTab", "ExtraArtifacts", "Collapsed", "SurfacePlacements", "AllowedPlacements"], ["role", "separator", "aria-orientation", "vertical", "aria-label", "Resize the surface panel (double-click to reset)", "title", "Drag to resize \u2022 double-click to reset", 1, "call-resizer", 3, "mousedown", "dblclick"], ["role", "region", 1, "stage-frame", 3, "mjSharePanel", "mjSharePanelIcon"], [3, "Plugin", "Visible", "Placement"], ["Placement", "stage", 1, "stage-presenter-move", 3, "Key", "Title", "Allowed"], ["Placement", "stage", 1, "stage-presenter-move", 3, "MoveRequested", "ResetLayoutRequested", "Key", "Title", "Allowed"], ["Placement", "pip", 3, "Key", "Title", "Allowed"], ["Placement", "pip", 3, "MoveRequested", "ResetLayoutRequested", "Key", "Title", "Allowed"], ["aria-hidden", "true", 1, "board-focus-pill__orb"], [1, "board-focus-pill__text"], [1, "board-focus-pill__name"], [1, "board-focus-pill__state"], ["type", "button", 1, "board-focus-pill__btn", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid"], ["type", "button", "title", "Show thread", "aria-label", "Show the conversation thread", 1, "board-focus-pill__btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-table-columns"], ["Placement", "stage", 3, "Key", "Title", "Allowed"], ["type", "button", "title", "End call", "aria-label", "End the call", 1, "board-focus-pill__btn", "board-focus-pill__btn--end", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-phone-slash"], ["Placement", "stage", 3, "MoveRequested", "ResetLayoutRequested", "Key", "Title", "Allowed"], [3, "Confirmed", "Declined", "Camera", "AgentName", "Switch"], [1, "review-board-host"], [3, "State", "AgentName", "ReadOnly"], [1, "review-recording-host"], [3, "FileID", "Transcript", "Provider"]], template: function RealtimeSessionOverlayComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2569
|
+
i0.ɵɵconditionalCreate(0, RealtimeSessionOverlayComponent_Conditional_0_Template, 21, 43, "div", 4);
|
|
2537
2570
|
i0.ɵɵpipe(1, "async");
|
|
2538
2571
|
i0.ɵɵtemplate(2, RealtimeSessionOverlayComponent_ng_template_2_Template, 1, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor)(4, RealtimeSessionOverlayComponent_ng_template_4_Template, 2, 3, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
|
|
2539
2572
|
} if (rf & 2) {
|
|
@@ -2580,7 +2613,7 @@ export class RealtimeSessionOverlayComponent extends BaseAngularComponent {
|
|
|
2580
2613
|
RealtimeWhiteboardBoardComponent,
|
|
2581
2614
|
MJStorageMediaPlayerComponent,
|
|
2582
2615
|
MJAlertComponent
|
|
2583
|
-
], template: "@if (ConnectionState$ | async; as state) {\n <div class=\"call-overlay\"\n [class.call-overlay--hidden]=\"Hidden\"\n [class.call-overlay--review]=\"IsReviewing\"\n [class.board-focus]=\"ChannelFocusMode\"\n role=\"region\" [attr.aria-label]=\"IsReviewing ? 'Past session review' : 'Live voice session'\">\n\n <!-- PROGRESSIVE DISCLOSURE (the console that grows with you \u2014 Redesign A Progressive):\n level 0 is PURE AUDIO (the hero orb owns the main column; no thread, no composer;\n the strip's Details control peeks at the panels on demand); level 1 reveals the\n caption thread + captions control + type-to-type hint; level 2+ docks the composer\n and keeps the surface panel. CONTENT NEVER FLIPS THE CONSOLE OPEN: finished\n artifacts land as glowing unfocused tabs; the ONE auto-reveal is a channel's\n first agent activity (e.g. the first whiteboard write), which opens the panel as\n a peek with that tab focused \u2014 the left column stays exactly as it was.\n REVIEW always renders the full console. -->\n <div class=\"call-main\">\n <!-- The UNIFIED APP-BAR: identity + state + every session action (Redesign A). -->\n <mj-realtime-agent-banner\n [State]=\"state\"\n [Compact]=\"!IsReviewing && Ui.compact && Ui.chrome === 'orb'\"\n [AgentName]=\"AgentName\"\n [ErrorLabel]=\"CallEndLabel\"\n [ModelName]=\"IsReviewing ? null : (ModelName$ | async)\"\n [DevMode]=\"DevMode\"\n [SessionID]=\"IsReviewing ? ReviewSessionID : SessionID\"\n [ReviewMode]=\"IsReviewing\"\n [ReviewStartedAt]=\"ReviewStartedAt\"\n [ReviewClosedAt]=\"ReviewClosedAt\"\n [ReviewCloseReason]=\"ReviewCloseReason\"\n [ShowGear]=\"!IsReviewing && Ui.showGear\"\n [ShowDensityPicker]=\"Ui.showDensityPicker\"\n [ShowMinimize]=\"!IsReviewing && Ui.showMinimize\"\n [ShowStartLive]=\"AllowStartLive\"\n [Density]=\"Disclosure.Milestones.Density\"\n (OpenSessionRequested)=\"OnOpenSessionRequested($event)\"\n (DevModeToggled)=\"OnDevModeToggled($event)\"\n (DensityChanged)=\"OnDensityChanged($event)\"\n (MinimizeRequested)=\"OnMinimize()\"\n (StartLiveRequested)=\"OnStartLive()\"\n (CloseRequested)=\"OnReviewClose()\">\n </mj-realtime-agent-banner>\n\n <!-- No microphone works: the call lost its microphone, so the agent hears nothing until the user picks one in the\n device menu. It stays for as long as that lasts, with no dismiss button, and goes once a microphone is on.\n Never in review. -->\n @if (MicrophoneNotice; as message) {\n <mj-alert class=\"call-microphone-notice\"\n Variant=\"warning\"\n Size=\"sm\"\n Icon=\"fa-solid fa-microphone-slash\"\n [Message]=\"message\">\n </mj-alert>\n }\n\n <!-- Why the call shows no avatar its agent asked for: once per call, from the moment it connects, until the user\n dismisses it or it hides itself after 10 s. Never in review. -->\n @if (AvatarNotice) {\n <mj-alert class=\"call-avatar-notice\"\n Variant=\"info\"\n Size=\"sm\"\n Icon=\"fa-solid fa-video-slash\"\n [Message]=\"AvatarNoticeMessage\"\n Dismissible\n (Dismissed)=\"OnAvatarNoticeDismissed()\">\n </mj-alert>\n }\n\n <!-- Ephemeral narration with no active working card to anchor to \u2192 under the banner -->\n @if (!IsReviewing && State.Narration && !State.ActiveCallId && Disclosure.ShowThread) {\n <div class=\"banner-live-note\" role=\"status\" aria-live=\"polite\">\n <i class=\"fa-solid fa-comment-dots\" aria-hidden=\"true\"></i>\n {{ State.Narration }}\n </div>\n }\n\n <!-- The agent's place above the thread in the console: the agent's video (the Avatar) lies over it while it presents.\n Outside the scrolling body, so it stays in view as the conversation grows. -->\n @if (!ShowHero) {\n <div class=\"call-presenter\" [class.call-presenter--on]=\"PresenterOnStage\" #presenterSlot></div>\n }\n\n <!-- While the call connects, the connecting screen takes the body, except from a hero the agent's video presents in:\n a resume on a new connection keeps that hero, so the video keeps its place and its last frame. -->\n <div class=\"call-body\" [class.call-body--hero]=\"ShowHero && !ShowConnectingScreen(state)\">\n @if (ShowConnectingScreen(state)) {\n <div class=\"call-connecting\">\n <mj-loading text=\"Connecting to the live session\u2026\" size=\"medium\"></mj-loading>\n </div>\n } @else if (ShowHero) {\n <!-- PURE-AUDIO HERO (level 0): the orb IS the interface \u2014 it breathes with the\n audio inside expanding sound-wave rings; nothing to read, nothing to configure. -->\n <div class=\"hero\" [class.hero--presenting]=\"PresenterOnStage\" [attr.data-state]=\"state\" role=\"status\" aria-live=\"polite\">\n @if (!PresenterOnStage) {\n <mj-realtime-agent-orb class=\"hero__orb\" [State]=\"HeroOrbState(state)\"></mj-realtime-agent-orb>\n <div class=\"hero__eq\" aria-hidden=\"true\">\n <span></span><span></span><span></span><span></span><span></span>\n <span></span><span></span><span></span><span></span>\n </div>\n }\n <!-- The agent's place in the hero: the agent's video (the Avatar) lies over it while it presents. With\n captions on, the newest caption runs over the video's lower third, as subtitles do. Hidden from\n assistive technology: the conversation, a click away, is the accessible transcript, and this live\n region would read every word as it arrives. -->\n <div class=\"hero__presenter\" [class.hero__presenter--on]=\"PresenterOnStage\" #presenterSlot>\n @if (ShowAvatarCaptions && AvatarCaption; as caption) {\n <p class=\"hero__caption\" aria-hidden=\"true\">\n <span class=\"hero__caption-window\">\n <span class=\"hero__caption-lines\">\n @if (caption.Speaker) {\n <span class=\"hero__caption-speaker\">{{ caption.Speaker }}:</span>\n }\n {{ caption.Text }}\n </span>\n </span>\n </p>\n }\n </div>\n @if (!PresenterOnStage) {\n <div class=\"hero__name\">{{ AgentName }}</div>\n <div class=\"hero__sub\">{{ HeroStateLabel(state) }}</div>\n } @else {\n <!-- The agent's tile names it and says what it is doing; this live region still says it for screen readers. -->\n <span class=\"hero__sr\">{{ HeroStateLabel(state) }}</span>\n }\n <button type=\"button\" class=\"hero__reveal\" (click)=\"OnTextReveal()\"\n title=\"Show the conversation as text\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n Show the conversation\n </button>\n </div>\n } @else {\n <mj-realtime-session-thread\n [State]=\"State\"\n [AgentName]=\"AgentName\"\n [UserName]=\"CurrentUser?.Name || 'You'\"\n [ShowCaptions]=\"IsReviewing ? true : ShowCaptions\"\n [DevMode]=\"DevMode\"\n (OpenRunRequested)=\"OnOpenRunRequested($event)\"\n (OpenArtifactRequested)=\"OnOpenArtifactRequested($event)\"\n (CancelRequested)=\"OnCancelDelegation($event)\">\n </mj-realtime-session-thread>\n }\n </div>\n\n <!-- The call's controls along the foot of the column. The stage starts its picture-in-picture boxes clear of\n them, so a camera or a shared screen never opens over End call (#5408). Empty, so with no size, in review. -->\n <div class=\"call-controls\" #callControls>\n @if (!IsReviewing) {\n <!-- \"Agent can see\": what the agent is looking at, with a switch per source. Always shown while any\n video source exists (a privacy indicator is never gated behind the disclosure ladder). -->\n <mj-realtime-perception-chip [Sources]=\"VideoSources\"\n (SourceToggled)=\"OnVideoSourceToggled($event)\"\n (SourcePicked)=\"OnVideoSourcePicked($event)\">\n </mj-realtime-perception-chip>\n\n <!-- Active channels (earned with the console at level 2+, host-gated via [ShowChannels]).\n The strip component self-hides when there are no active channels. -->\n @if (ChannelStripVisible) {\n <mj-realtime-channel-strip></mj-realtime-channel-strip>\n }\n\n <!-- The BOTTOM DOCK: phone-call strip \u21C4 fused minis+composer \u2014 the user's own\n two-way toggle (Type opens, hide closes), never level-forced. -->\n <mj-realtime-composer\n [Open]=\"ComposerOpen\"\n [Compact]=\"Ui.compact && Ui.chrome === 'orb'\"\n (OpenChanged)=\"OnComposerOpenChanged($event)\"\n [CaptionsOn]=\"ShowCaptions\"\n [IsMuted]=\"Muted\"\n [ShowCamera]=\"CaptureOffers.Camera\"\n [ShowShare]=\"CaptureOffers.Screen\"\n [CameraOn]=\"CameraOn\"\n [Sharing]=\"Sharing\"\n [SharePanels]=\"SharePanels\"\n [Devices]=\"CallDevices\"\n [SelectedMicrophoneID]=\"SelectedMicrophoneID\"\n [SelectedCameraID]=\"SelectedCameraID\"\n (CameraToggled)=\"OnCameraToggled($event)\"\n (ShareRequested)=\"OnShareRequested($event)\"\n (StopShareRequested)=\"OnStopShareRequested()\"\n (DeviceSelected)=\"OnDeviceSelected($event)\"\n [ShowDetails]=\"ShowDetailsControl\"\n [DetailsOn]=\"DetailsPeek\"\n (CaptionsToggled)=\"OnCaptionsToggled($event)\"\n (DetailsToggled)=\"OnDetailsToggled()\"\n (MuteChanged)=\"OnComposerMuteChanged($event)\"\n (EndRequested)=\"OnEndCall()\">\n </mj-realtime-composer>\n }\n </div>\n </div>\n\n <!-- RIGHT: TABBED SURFACE PANEL \u2014 disclosure-gated: it EXISTS once earned (level 2+,\n which the first delegation forces), peeked on demand via the strip's Details\n control, or always in review. Slides in from the right when it arrives \u2014 the\n panel's arrival IS the progress cue. -->\n @if (ShowPanelArea) {\n <!-- Resize handle (hidden while the panel is collapsed or a channel holds focus). -->\n @if (!PanelResizeDisabled) {\n <div class=\"call-resizer\"\n [class.call-resizer--active]=\"IsPanelResizing\"\n role=\"separator\" aria-orientation=\"vertical\"\n aria-label=\"Resize the surface panel (double-click to reset)\"\n title=\"Drag to resize \u2022 double-click to reset\"\n (mousedown)=\"OnPanelResizeStart($event)\"\n (dblclick)=\"OnPanelResizeReset()\"></div>\n }\n\n <div class=\"call-panel\" [style.width.px]=\"PanelAreaSize\">\n <mj-realtime-surface-tabs\n [State]=\"State\"\n [DevMode]=\"DevMode\"\n [CurrentUser]=\"CurrentUser\"\n [EnvironmentID]=\"EnvironmentID\"\n [ShowActivityTab]=\"ShowActivityTab\"\n [ExtraArtifacts]=\"ReviewArtifacts\"\n (OpenRunRequested)=\"OnOpenRunRequested($event)\"\n [Collapsed]=\"PanelCollapsed\"\n (CollapsedChange)=\"OnPanelCollapsedChange($event)\"\n (WideChanged)=\"OnPanelWideChanged($event)\"\n (ActiveChannelChange)=\"OnActiveChannelChange($event)\"\n (ChannelSlotChange)=\"OnChannelSlotChange($event)\"\n [SurfacePlacements]=\"SurfaceStage.Placements\"\n [AllowedPlacements]=\"SurfaceStage.AllowedPlacements\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-realtime-surface-tabs>\n </div>\n }\n\n <!-- THE STAGE: every channel surface lives here, in one layer over the overlay. A surface\n is created the first time it is seen, lies over its tab's slot while that tab is\n active, fills the overlay while its channel holds focus (or, for the agent's video,\n lies in the agent's place in the call), and otherwise waits out of sight \u2014 so\n collapsing the panel, switching tabs or entering focus never reloads it.\n The pane tells each channel when its surface goes out of sight, so it can pause.\n A channel that opts in (SurfaceShareable, such as the whiteboard) marks its frame as a panel the Share menu\n offers under \"This panel\" while it is on screen. A picture-in-picture box the user has not moved starts\n clear of the call's controls. -->\n <mj-media-stage class=\"call-stage\"\n [Surfaces]=\"SurfaceStage.Surfaces\"\n [TabSlot]=\"StageSlot?.Element ?? null\"\n [StageSlot]=\"StageSurfaceSlot\"\n [ActiveTabKey]=\"StageSlot?.Key ?? null\"\n [PipRects]=\"PipRects\"\n [PipKeepClear]=\"callControls\"\n (PipRectChange)=\"OnPipRectChange($event)\">\n <ng-template mjMediaStageSurface let-key let-visible=\"Visible\" let-placement=\"Placement\">\n @if (SurfaceStage.PluginFor(key); as plugin) {\n <div class=\"stage-frame\" role=\"region\" [attr.aria-label]=\"plugin.TabTitle\"\n [mjSharePanel]=\"plugin.SurfaceShareable ? plugin.TabTitle : null\" [mjSharePanelIcon]=\"plugin.TabIcon\">\n <mj-realtime-channel-pane [Plugin]=\"plugin\" [Visible]=\"visible\" [Placement]=\"placement\"></mj-realtime-channel-pane>\n <!-- A surface presenting the agent has no focus pill, so its \"Move to\u2026\" menu rides on it. -->\n @if (placement === 'stage' && plugin.ShowsAgentVideo) {\n <mj-media-move-menu\n class=\"stage-presenter-move\"\n [Key]=\"key\"\n [Title]=\"plugin.TabTitle\"\n Placement=\"stage\"\n [Allowed]=\"SurfaceStage.AllowedFor(key)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n </div>\n }\n </ng-template>\n <!-- A picture-in-picture box's bar carries the same \"Move to\u2026\" menu. -->\n <ng-template mjMediaStagePipActions let-key>\n @if (SurfaceStage.PluginFor(key); as plugin) {\n <mj-media-move-menu\n [Key]=\"key\"\n [Title]=\"plugin.TabTitle\"\n Placement=\"pip\"\n [Allowed]=\"SurfaceStage.AllowedFor(key)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n </ng-template>\n </mj-media-stage>\n\n <!-- FOCUS floating call pill: the main column is hidden, so the live call's\n identity + state + mute / show-thread / end controls ride over the surface. -->\n @if (!IsReviewing && ChannelFocusMode) {\n <div class=\"board-focus-pill\" role=\"status\" aria-label=\"Live call (board focus)\">\n <span class=\"board-focus-pill__orb\" [attr.data-state]=\"state\" aria-hidden=\"true\"></span>\n <span class=\"board-focus-pill__text\">\n <span class=\"board-focus-pill__name\">Voice for {{ AgentName }}</span>\n @if (FocusStateLabel(state); as label) {\n <span class=\"board-focus-pill__state\">{{ label }}</span>\n }\n </span>\n <button type=\"button\" class=\"board-focus-pill__btn\"\n [class.board-focus-pill__btn--active]=\"FocusPillMuted\"\n (click)=\"OnFocusPillMute()\"\n [title]=\"FocusPillMuted ? 'Unmute' : 'Mute'\"\n [attr.aria-label]=\"FocusPillMuted ? 'Unmute microphone' : 'Mute microphone'\">\n <i class=\"fa-solid\" [class.fa-microphone]=\"!FocusPillMuted\" [class.fa-microphone-slash]=\"FocusPillMuted\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"board-focus-pill__btn\"\n (click)=\"OnFocusPillExit()\"\n title=\"Show thread\" aria-label=\"Show the conversation thread\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n </button>\n @if (StagePlugin; as stagePlugin) {\n <mj-media-move-menu\n [Key]=\"stagePlugin.ChannelName\"\n [Title]=\"stagePlugin.TabTitle\"\n Placement=\"stage\"\n [Allowed]=\"SurfaceStage.AllowedFor(stagePlugin.ChannelName)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n <button type=\"button\" class=\"board-focus-pill__btn board-focus-pill__btn--end\"\n (click)=\"OnFocusPillEnd()\"\n title=\"End call\" aria-label=\"End the call\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- THE CAMERA CHECK: the first time the user turns the camera on in a call, they see it, and can pick another\n camera, before the agent does. Until they choose, the camera's own box says it is waiting. -->\n @if (CameraCheck; as camera) {\n <mj-realtime-camera-check-card\n [Camera]=\"camera\"\n [AgentName]=\"AgentName\"\n [Switch]=\"SwitchCheckedCamera\"\n (Confirmed)=\"OnCameraCheckConfirmed()\"\n (Declined)=\"OnCameraCheckDeclined()\">\n </mj-realtime-camera-check-card>\n }\n\n </div>\n}\n\n<!-- SESSION REVIEW whiteboard pane body: the reviewed session's saved board, rehydrated\n locally (WhiteboardState.FromJSON) and rendered READ-ONLY (pan/zoom only). Registered\n as a template-based channel tab ONLY when a parseable Whiteboard state exists. -->\n<ng-template #reviewBoardTpl>\n @if (ReviewWhiteboard; as board) {\n <!-- The board host positions itself absolutely \u2014 give it a filling, positioned frame. -->\n <div class=\"review-board-host\">\n <mj-realtime-whiteboard\n [State]=\"board\"\n [AgentName]=\"AgentName\"\n [ReadOnly]=\"true\">\n </mj-realtime-whiteboard>\n </div>\n }\n</ng-template>\n\n<!-- SESSION REVIEW recording pane body: the reviewed session's recorded audio synced to its\n transcript, replayed via the shared storage media player (click-to-seek transcript + playhead\n highlight). Registered as a template-based channel tab ONLY when the reviewed session carries a\n RecordingFileID; the player resolves the authenticated audio itself from that file id. -->\n<ng-template #recordingTpl>\n <div class=\"review-recording-host\">\n <mj-storage-media-player\n [FileID]=\"ReviewRecordingFileID\"\n [Transcript]=\"ReviewCues\"\n [Provider]=\"Provider\">\n </mj-storage-media-player>\n </div>\n</ng-template>\n", styles: [":host {\n display: contents;\n}\n\n/* Fills the conversation panel IN PLACE: the chat area host provides the positioned\n context (position:relative on .chat-area) and this covers it edge to edge \u2014 header,\n thread and composer included. Opaque-ish page surface with a slight blur so the\n conversation underneath reads as \"paused\", not as an app-wide modal. */\n.call-overlay {\n position: absolute;\n inset: 0;\n z-index: 50;\n display: flex;\n background: color-mix(in srgb, var(--mj-bg-page) 94%, transparent);\n backdrop-filter: blur(8px);\n overflow: hidden;\n}\n\n/* Minimized: hidden (NOT destroyed) so the shell's session/view state survives while\n the host shows its floating \"on call\" pill. The audio session is untouched. */\n.call-overlay--hidden {\n display: none;\n}\n\n/* MAIN column: banner (top) \u2192 scrolling thread \u2192 channel strip \u2192 composer \u2192 controls.\n The 420px floor keeps the call column readable while the panel is dragged wide\n (the drag clamp's 70% cap is the other guard). */\n.call-main {\n flex: 1;\n min-width: 420px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* The call's controls at the foot of the column: the \"Agent can see\" chip, the channel strip and the composer. The\n stage starts its picture-in-picture boxes above this box, so it is never squeezed below its content's height. */\n.call-controls {\n flex: none;\n}\n\n.call-body {\n flex: 1;\n overflow-y: auto;\n padding: 16px 22px;\n min-height: 0;\n scrollbar-width: thin;\n scrollbar-color: var(--mj-border-strong) transparent;\n}\n.call-body::-webkit-scrollbar {\n width: 6px;\n}\n.call-body::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.call-connecting {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n min-height: 160px;\n}\n\n/* ---------- PURE-AUDIO HERO (disclosure level 0) ----------\n The orb IS the interface: it breathes with the audio inside expanding sound-wave\n rings, with a small voice equalizer underneath. Nothing to read, nothing to\n configure \u2014 text, panels and the composer are revealed later (or peeked on demand). */\n.call-body--hero {\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n}\n.hero {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n animation: hero-in 420ms cubic-bezier(0.2, 0.8, 0.3, 1);\n}\n@keyframes hero-in {\n from { opacity: 0; transform: scale(0.94); }\n to { opacity: 1; transform: scale(1); }\n}\n/* The orb (mj-realtime-agent-orb) at hero scale. */\n.hero__orb {\n margin-bottom: 4px;\n}\n/* Voice equalizer: lively while the agent speaks, near-still otherwise. */\n.hero__eq {\n display: flex;\n align-items: center;\n gap: 4px;\n height: 30px;\n margin-bottom: 6px;\n}\n.hero__eq span {\n width: 4px;\n height: 8px;\n border-radius: var(--mj-radius-full, 9999px);\n background: var(--mj-brand-accent, var(--mj-brand-primary));\n opacity: 0.55;\n}\n.hero[data-state='speaking'] .hero__eq span {\n animation: hero-eq 1.05s ease-in-out infinite;\n}\n.hero__eq span:nth-child(1) { animation-delay: 0s; }\n.hero__eq span:nth-child(2) { animation-delay: 0.14s; }\n.hero__eq span:nth-child(3) { animation-delay: 0.28s; }\n.hero__eq span:nth-child(4) { animation-delay: 0.07s; }\n.hero__eq span:nth-child(5) { animation-delay: 0.21s; }\n.hero__eq span:nth-child(6) { animation-delay: 0.35s; }\n.hero__eq span:nth-child(7) { animation-delay: 0.1s; }\n.hero__eq span:nth-child(8) { animation-delay: 0.24s; }\n.hero__eq span:nth-child(9) { animation-delay: 0.03s; }\n@keyframes hero-eq {\n 0%, 100% { height: 7px; opacity: 0.6; }\n 50% { height: 28px; opacity: 1; }\n}\n/* ---------- the agent's place while its video presents (the Avatar) ----------\n The stage lays the agent's video over these boxes; each has a size only while the video presents. Portrait, as\n avatar video is (Google's samples are 704x1280). */\n.hero--presenting {\n height: 100%;\n min-height: 0;\n}\n.hero__presenter,\n.call-presenter {\n display: none;\n}\n.hero__presenter--on {\n display: block;\n position: relative;\n container-type: size;\n flex: 1 1 auto;\n min-height: 160px;\n max-height: 520px;\n aspect-ratio: 3 / 4;\n margin-bottom: 8px;\n}\n/* Captions over the agent's video, as subtitles: the newest two lines, over the lower third and clear of the tile's\n footer. Above the stage (z-index 1), where the video is. Light on a dark band in both themes, like the tile's chips. */\n.hero__caption {\n position: absolute;\n left: 6%;\n right: 6%;\n bottom: 16%;\n z-index: 2;\n margin: 0;\n padding: 6px 10px;\n border-radius: var(--mj-radius-md);\n background: rgba(0, 0, 0, 0.6);\n color: rgba(255, 255, 255, 0.95);\n font-size: 0.95rem;\n line-height: 1.4;\n text-align: center;\n}\n/* Two lines, the newest: older ones leave through the top. The window clips, not the padded band, so nothing of an\n older line shows in the padding. */\n.hero__caption-window {\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n max-height: 2.8em;\n overflow: hidden;\n}\n.hero__caption-speaker {\n font-weight: 600;\n}\n/* A small tile (a short window): one smaller line, so the video still shows. */\n@container (max-height: 240px) {\n .hero__caption {\n bottom: 22%;\n padding: 3px 6px;\n font-size: 0.75rem;\n }\n .hero__caption-window {\n max-height: 1.4em;\n }\n}\n/* In the console it sits above the scrolling thread, so it stays in view as the conversation grows. Wide enough for\n the tile's \"AI-generated video\" label on one line. */\n.call-presenter--on {\n display: block;\n flex: none;\n align-self: center;\n height: 200px;\n aspect-ratio: 4 / 5;\n margin-top: 12px;\n}\n.hero__name {\n font-size: 19px;\n font-weight: 800;\n letter-spacing: -0.01em;\n color: var(--mj-text-primary);\n}\n.hero__sub {\n font-size: 12.5px;\n color: var(--mj-text-muted);\n}\n/* The hero's state for screen readers only, while the agent's tile shows it. */\n.hero__sr {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n/* ---------- AUDIO-REACTIVE MODE (data-audio-live, set by the rAF meter loop) ----------\n With real audio metering the visuals stop acting and start REACTING: the EQ renders the\n true spectrum (--eq-1..9), and [data-voice-dir] colors it by who is speaking (agent =\n brand, user = green). The orb (mj-realtime-agent-orb) reads the same attributes and the\n smoothed output envelope (--voice-out) itself. Without metering (driver attached no\n meters) the attribute stays 'false' and the turn-state keyframe animations stay in charge. */\n/* True-spectrum EQ: per-bar heights from the meter's bins. */\n.call-overlay[data-audio-live='true'] .hero__eq span {\n animation: none;\n transition: height 70ms linear, opacity 120ms linear;\n}\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(1) { height: calc(6px + var(--eq-1, 0) * 24px); opacity: calc(0.45 + var(--eq-1, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(2) { height: calc(6px + var(--eq-2, 0) * 24px); opacity: calc(0.45 + var(--eq-2, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(3) { height: calc(6px + var(--eq-3, 0) * 24px); opacity: calc(0.45 + var(--eq-3, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(4) { height: calc(6px + var(--eq-4, 0) * 24px); opacity: calc(0.45 + var(--eq-4, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(5) { height: calc(6px + var(--eq-5, 0) * 24px); opacity: calc(0.45 + var(--eq-5, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(6) { height: calc(6px + var(--eq-6, 0) * 24px); opacity: calc(0.45 + var(--eq-6, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(7) { height: calc(6px + var(--eq-7, 0) * 24px); opacity: calc(0.45 + var(--eq-7, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(8) { height: calc(6px + var(--eq-8, 0) * 24px); opacity: calc(0.45 + var(--eq-8, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(9) { height: calc(6px + var(--eq-9, 0) * 24px); opacity: calc(0.45 + var(--eq-9, 0) * 0.55); }\n.call-overlay[data-audio-live='true'][data-voice-dir='user'] .hero__eq span {\n background: var(--mj-status-success);\n}\n\n/* The quiet first reveal: show the conversation as text (raises disclosure to level 1). */\n.hero__reveal {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: 18px;\n padding: 6px 14px;\n border-radius: var(--mj-radius-full, 9999px);\n border: 1px dashed var(--mj-border-strong);\n background: transparent;\n color: var(--mj-text-muted);\n font-family: inherit;\n font-size: 11.5px;\n font-weight: 600;\n cursor: pointer;\n transition: color 140ms ease, border-color 140ms ease, background 140ms ease;\n}\n.hero__reveal:hover {\n color: var(--mj-text-secondary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n.hero__reveal i {\n font-size: 11px;\n}\n\n/* Ephemeral narration shown under the banner when no working card anchors it */\n.banner-live-note {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n padding: 8px 22px 0;\n font-size: 12px;\n font-style: italic;\n color: var(--mj-text-muted);\n animation: overlay-note-in 220ms ease;\n}\n.banner-live-note i {\n font-size: 10px;\n margin-top: 3px;\n flex-shrink: 0;\n}\n@keyframes overlay-note-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* The call's notices under the banner (no microphone works; no avatar): mj-alert brings its own tint, border and text\n colours; this only places them. */\n.call-microphone-notice,\n.call-avatar-notice {\n flex-shrink: 0;\n margin: var(--mj-space-2) var(--mj-space-5) 0;\n}\n\n/* ---------- FOCUS-BOARD mode (whiteboard \"Focus board\" toggle) ----------\n The main call column collapses away entirely and the focused channel's surface fills\n the stage; a compact floating call pill keeps the live call reachable. */\n.call-overlay.board-focus .call-main {\n display: none;\n}\n\n/* ---------- the stage (every channel surface, in one layer) ----------\n mj-media-stage covers the overlay and places each surface itself. Above the panel it\n lays surfaces over, and above the call's controls, so its picture-in-picture boxes\n start clear of them (.call-controls); below the onboarding card (5), the menus of the\n dock and the chip (5) and the focus pill (60). */\n.call-stage {\n z-index: 1;\n}\n/* A surface's frame: fills the box the stage gives it. The surface component is created\n beside the pane host inside it, and sizes itself to it (height: 100%). */\n.stage-frame {\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n/* The \"Move to\u2026\" menu on a surface that presents the agent, backed so it reads over video. Bottom right, in the\n tile's footer, which holds nothing there for the agent, so it never covers the tile's labels. */\n.stage-presenter-move {\n position: absolute;\n bottom: 4px;\n right: 6px;\n z-index: 1;\n border-radius: var(--mj-radius-full);\n background: color-mix(in srgb, var(--mj-bg-surface) 85%, transparent);\n}\n\n/* Floating call pill: orb + state + mute / show-thread / end (per the whiteboard mockup). */\n.board-focus-pill {\n position: absolute;\n left: 64px;\n top: 12px;\n z-index: 60;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 9px 7px 12px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-bg-surface-card) 92%, transparent);\n backdrop-filter: blur(8px);\n border: 1px solid var(--mj-border-strong);\n box-shadow: var(--mj-shadow-xl, 0 12px 32px rgba(0, 0, 0, 0.18));\n animation: overlay-note-in 220ms ease;\n}\n.board-focus-pill__orb {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n flex-shrink: 0;\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n.board-focus-pill__orb[data-state='speaking'],\n.board-focus-pill__orb[data-state='listening'] {\n animation: board-pill-pulse 1.6s ease-in-out infinite;\n}\n.board-focus-pill__orb[data-state='error'] {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 18%, transparent);\n}\n@keyframes board-pill-pulse {\n 0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent); }\n 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--mj-brand-primary) 8%, transparent); }\n}\n.board-focus-pill__text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n.board-focus-pill__name {\n font-size: 12px;\n font-weight: 700;\n line-height: 1.2;\n white-space: nowrap;\n color: var(--mj-text-primary);\n}\n.board-focus-pill__state {\n font-size: 10.5px;\n font-weight: 600;\n white-space: nowrap;\n color: var(--mj-brand-primary);\n}\n.board-focus-pill__btn {\n width: 30px;\n height: 30px;\n border-radius: 50%;\n border: 1px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n font-size: 11px;\n display: grid;\n place-items: center;\n font-family: inherit;\n flex-shrink: 0;\n}\n.board-focus-pill__btn:hover {\n color: var(--mj-text-primary);\n}\n.board-focus-pill__btn--active {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n.board-focus-pill__btn--end {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n color: var(--mj-text-inverse, #fff);\n}\n\n/* ---------- Session review mode ---------- */\n/* Subtle archival tint so a glance says \"this is history, not a live call\". */\n.call-overlay--review {\n background:\n linear-gradient(180deg, color-mix(in srgb, var(--mj-text-muted) 4%, transparent), transparent 120px),\n var(--mj-bg-surface);\n}\n\n/* The review whiteboard pane body: the board component positions itself absolutely\n (inset: 0), so its template-based pane needs a filling, positioned frame. */\n.review-board-host {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n/* The review recording pane body: the evidence player fills its host (:host height:100%),\n so its template-based pane needs a filling, constrained frame. */\n.review-recording-host {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.review-recording-host mj-realtime-evidence-playback {\n flex: 1;\n min-height: 0;\n}\n\n/* ---------- flex layout (main column | resize handle | surface panel) ---------- */\n/* Token-styled resize handle: invisible until hover, brand-tinted while interacting.\n 7px hit target, col-resize cursor; removed (not rendered) while collapsed / focus. */\n.call-resizer {\n flex: 0 0 7px;\n width: 7px;\n cursor: col-resize;\n background: transparent;\n transition: background 140ms ease;\n}\n.call-resizer:hover,\n.call-resizer--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 26%, transparent);\n}\n/* The surface panel: a plain fixed-width flex item (inline width set by the overlay;\n collapsed = the slim strip width). flex-shrink lets it yield to the call column's\n min-width on tight overlays; overflow hidden keeps the flex height chain intact so\n the panel's content scrolls internally. */\n.call-panel {\n flex: 0 1 auto;\n min-width: 0;\n display: flex;\n overflow: hidden;\n /* Disclosure-gated: the panel is CREATED when earned/peeked \u2014 its arrival slides in\n from the right so the reveal doubles as the progress cue. */\n animation: panel-in 420ms cubic-bezier(0.25, 0.8, 0.3, 1);\n}\n@keyframes panel-in {\n from { opacity: 0; transform: translateX(48px); }\n to { opacity: 1; transform: translateX(0); }\n}\n.call-panel > * {\n flex: 1;\n min-width: 0;\n min-height: 0;\n}\n"] }]
|
|
2616
|
+
], template: "@if (ConnectionState$ | async; as state) {\n <div class=\"call-overlay\"\n [class.call-overlay--hidden]=\"Hidden\"\n [class.call-overlay--review]=\"IsReviewing\"\n [class.board-focus]=\"ChannelFocusMode\"\n role=\"region\" [attr.aria-label]=\"IsReviewing ? 'Past session review' : 'Live voice session'\">\n\n <!-- PROGRESSIVE DISCLOSURE (the console that grows with you \u2014 Redesign A Progressive):\n level 0 is PURE AUDIO (the hero orb owns the main column; no thread, no composer;\n the strip's Details control peeks at the panels on demand); level 1 reveals the\n caption thread + captions control + type-to-type hint; level 2+ docks the composer\n and keeps the surface panel. CONTENT NEVER FLIPS THE CONSOLE OPEN: finished\n artifacts land as glowing unfocused tabs; the ONE auto-reveal is a channel's\n first agent activity (e.g. the first whiteboard write), which opens the panel as\n a peek with that tab focused \u2014 the left column stays exactly as it was.\n REVIEW always renders the full console. -->\n <div class=\"call-main\">\n <!-- The UNIFIED APP-BAR: identity + state + every session action (Redesign A). -->\n <mj-realtime-agent-banner\n [State]=\"state\"\n [Compact]=\"!IsReviewing && Ui.compact && Ui.chrome === 'orb'\"\n [HideState]=\"ShowHero && !PresenterOnStage\"\n [AgentName]=\"AgentName\"\n [ErrorLabel]=\"CallEndLabel\"\n [ModelName]=\"IsReviewing ? null : (ModelName$ | async)\"\n [DevMode]=\"DevMode\"\n [SessionID]=\"IsReviewing ? ReviewSessionID : SessionID\"\n [ReviewMode]=\"IsReviewing\"\n [ReviewStartedAt]=\"ReviewStartedAt\"\n [ReviewClosedAt]=\"ReviewClosedAt\"\n [ReviewCloseReason]=\"ReviewCloseReason\"\n [ShowGear]=\"!IsReviewing && Ui.showGear\"\n [ShowDensityPicker]=\"Ui.showDensityPicker\"\n [ShowMinimize]=\"!IsReviewing && Ui.showMinimize\"\n [ShowStartLive]=\"AllowStartLive\"\n [Density]=\"Disclosure.Milestones.Density\"\n (OpenSessionRequested)=\"OnOpenSessionRequested($event)\"\n (DevModeToggled)=\"OnDevModeToggled($event)\"\n (DensityChanged)=\"OnDensityChanged($event)\"\n (MinimizeRequested)=\"OnMinimize()\"\n (StartLiveRequested)=\"OnStartLive()\"\n (CloseRequested)=\"OnReviewClose()\">\n </mj-realtime-agent-banner>\n\n <!-- No microphone works: the call lost its microphone, so the agent hears nothing until the user picks one in the\n device menu. It stays for as long as that lasts, with no dismiss button, and goes once a microphone is on.\n Never in review. -->\n @if (MicrophoneNotice; as message) {\n <mj-alert class=\"call-microphone-notice\"\n Variant=\"warning\"\n Size=\"sm\"\n Icon=\"fa-solid fa-microphone-slash\"\n [Message]=\"message\">\n </mj-alert>\n }\n\n <!-- Why the call shows no avatar its agent asked for: once per call, from the moment it connects, until the user\n dismisses it or it hides itself after 10 s. Never in review. -->\n @if (AvatarNotice) {\n <mj-alert class=\"call-avatar-notice\"\n Variant=\"info\"\n Size=\"sm\"\n Icon=\"fa-solid fa-video-slash\"\n [Message]=\"AvatarNoticeMessage\"\n Dismissible\n (Dismissed)=\"OnAvatarNoticeDismissed()\">\n </mj-alert>\n }\n\n <!-- Ephemeral narration with no active working card to anchor to \u2192 under the banner -->\n @if (!IsReviewing && State.Narration && !State.ActiveCallId && Disclosure.ShowThread) {\n <div class=\"banner-live-note\" role=\"status\" aria-live=\"polite\">\n <i class=\"fa-solid fa-comment-dots\" aria-hidden=\"true\"></i>\n {{ State.Narration }}\n </div>\n }\n\n <!-- The agent's place above the thread in the console: the agent's video (the Avatar) lies over it while it presents.\n Outside the scrolling body, so it stays in view as the conversation grows. -->\n @if (!ShowHero) {\n <div class=\"call-presenter\" [class.call-presenter--on]=\"PresenterOnStage\" #presenterSlot></div>\n }\n\n <!-- While the call connects, the connecting screen takes the body, except from a hero the agent's video presents in:\n a resume on a new connection keeps that hero, so the video keeps its place and its last frame. -->\n <div class=\"call-body\" [class.call-body--hero]=\"ShowHero && !ShowConnectingScreen(state)\">\n @if (ShowConnectingScreen(state)) {\n <div class=\"call-connecting\">\n <mj-loading text=\"Connecting to the live session\u2026\" size=\"medium\"></mj-loading>\n </div>\n } @else if (ShowHero) {\n <!-- PURE-AUDIO HERO (level 0): the orb IS the interface \u2014 it breathes with the\n audio inside expanding sound-wave rings; nothing to read, nothing to configure. -->\n <div class=\"hero\" [class.hero--presenting]=\"PresenterOnStage\" [attr.data-state]=\"state\" role=\"status\" aria-live=\"polite\">\n @if (!PresenterOnStage) {\n <mj-realtime-agent-orb class=\"hero__orb\" [State]=\"HeroOrbState(state)\"></mj-realtime-agent-orb>\n <div class=\"hero__eq\" aria-hidden=\"true\">\n <span></span><span></span><span></span><span></span><span></span>\n <span></span><span></span><span></span><span></span>\n </div>\n }\n <!-- The agent's place in the hero: the agent's video (the Avatar) lies over it while it presents. With\n captions on, the newest caption runs over the video's lower third, as subtitles do. Hidden from\n assistive technology: the conversation, a click away, is the accessible transcript, and this live\n region would read every word as it arrives. -->\n <div class=\"hero__presenter\" [class.hero__presenter--on]=\"PresenterOnStage\" #presenterSlot>\n @if (ShowAvatarCaptions && AvatarCaption; as caption) {\n <p class=\"hero__caption\" aria-hidden=\"true\">\n <span class=\"hero__caption-window\">\n <span class=\"hero__caption-lines\">\n @if (caption.Speaker) {\n <span class=\"hero__caption-speaker\">{{ caption.Speaker }}:</span>\n }\n {{ caption.Text }}\n </span>\n </span>\n </p>\n }\n </div>\n @if (!PresenterOnStage) {\n <div class=\"hero__name\">{{ AgentName }}</div>\n <div class=\"hero__sub\">{{ HeroStateLabel(state) }}</div>\n } @else {\n <!-- The agent's tile names it and says what it is doing; this live region still says it for screen readers. -->\n <span class=\"hero__sr\">{{ HeroStateLabel(state) }}</span>\n }\n @if (PresenterOnStage || !Ui.showCaptionsControl) {\n <button type=\"button\" class=\"hero__reveal\" (click)=\"OnTextReveal()\"\n title=\"Show the conversation as text\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n Show the conversation\n </button>\n }\n </div>\n } @else {\n <mj-realtime-session-thread\n [State]=\"State\"\n [AgentName]=\"AgentName\"\n [UserName]=\"CurrentUser?.Name || 'You'\"\n [ShowCaptions]=\"IsReviewing ? true : ShowCaptions\"\n [DevMode]=\"DevMode\"\n (OpenRunRequested)=\"OnOpenRunRequested($event)\"\n (OpenArtifactRequested)=\"OnOpenArtifactRequested($event)\"\n (CancelRequested)=\"OnCancelDelegation($event)\">\n </mj-realtime-session-thread>\n }\n </div>\n\n <!-- The call's controls along the foot of the column. The stage starts its picture-in-picture boxes clear of\n them, so a camera or a shared screen never opens over End call (#5408). Empty, so with no size, in review. -->\n <div class=\"call-controls\" #callControls>\n @if (!IsReviewing) {\n <!-- \"Agent can see\": what the agent is looking at, with a switch per source. Shown while the user\n captures camera/screen (or when [ShowPerceptionChip]=\"true\"). -->\n <mj-realtime-perception-chip [Sources]=\"VisibleVideoSources\"\n (SourceToggled)=\"OnVideoSourceToggled($event)\"\n (SourcePicked)=\"OnVideoSourcePicked($event)\">\n </mj-realtime-perception-chip>\n\n <!-- Active channels (earned with the console at level 2+, host-gated via [ShowChannels]).\n The strip component self-hides when there are no active channels. -->\n @if (ChannelStripVisible) {\n <mj-realtime-channel-strip></mj-realtime-channel-strip>\n }\n\n <!-- The BOTTOM DOCK: phone-call strip \u21C4 fused minis+composer \u2014 the user's own\n two-way toggle (Type opens, hide closes), never level-forced. -->\n <mj-realtime-composer\n [Open]=\"ComposerOpen\"\n [Compact]=\"Ui.chrome === 'orb' || Ui.compact\"\n (OpenChanged)=\"OnComposerOpenChanged($event)\"\n [CaptionsOn]=\"ShowCaptions\"\n [IsMuted]=\"Muted\"\n [ShowCamera]=\"CaptureOffers.Camera\"\n [ShowShare]=\"CaptureOffers.Screen\"\n [CameraOn]=\"CameraOn\"\n [Sharing]=\"Sharing\"\n [SharePanels]=\"SharePanels\"\n [Devices]=\"CallDevices\"\n [SelectedMicrophoneID]=\"SelectedMicrophoneID\"\n [SelectedCameraID]=\"SelectedCameraID\"\n (CameraToggled)=\"OnCameraToggled($event)\"\n (ShareRequested)=\"OnShareRequested($event)\"\n (StopShareRequested)=\"OnStopShareRequested()\"\n (DeviceSelected)=\"OnDeviceSelected($event)\"\n [ShowDetails]=\"ShowDetailsControl\"\n [DetailsOn]=\"DetailsPeek\"\n (CaptionsToggled)=\"OnCaptionsToggled($event)\"\n (DetailsToggled)=\"OnDetailsToggled()\"\n (MuteChanged)=\"OnComposerMuteChanged($event)\"\n (EndRequested)=\"OnEndCall()\">\n </mj-realtime-composer>\n }\n </div>\n </div>\n\n <!-- RIGHT: TABBED SURFACE PANEL \u2014 disclosure-gated: it EXISTS once earned (level 2+,\n which the first delegation forces), peeked on demand via the strip's Details\n control, or always in review. Slides in from the right when it arrives \u2014 the\n panel's arrival IS the progress cue. -->\n @if (ShowPanelArea) {\n <!-- Resize handle (hidden while the panel is collapsed or a channel holds focus). -->\n @if (!PanelResizeDisabled) {\n <div class=\"call-resizer\"\n [class.call-resizer--active]=\"IsPanelResizing\"\n role=\"separator\" aria-orientation=\"vertical\"\n aria-label=\"Resize the surface panel (double-click to reset)\"\n title=\"Drag to resize \u2022 double-click to reset\"\n (mousedown)=\"OnPanelResizeStart($event)\"\n (dblclick)=\"OnPanelResizeReset()\"></div>\n }\n\n <div class=\"call-panel\" [style.width.px]=\"PanelAreaSize\">\n <mj-realtime-surface-tabs\n [State]=\"State\"\n [DevMode]=\"DevMode\"\n [CurrentUser]=\"CurrentUser\"\n [EnvironmentID]=\"EnvironmentID\"\n [ShowActivityTab]=\"ShowActivityTab\"\n [ExtraArtifacts]=\"ReviewArtifacts\"\n (OpenRunRequested)=\"OnOpenRunRequested($event)\"\n [Collapsed]=\"PanelCollapsed\"\n (CollapsedChange)=\"OnPanelCollapsedChange($event)\"\n (WideChanged)=\"OnPanelWideChanged($event)\"\n (ActiveChannelChange)=\"OnActiveChannelChange($event)\"\n (ChannelSlotChange)=\"OnChannelSlotChange($event)\"\n [SurfacePlacements]=\"SurfaceStage.Placements\"\n [AllowedPlacements]=\"SurfaceStage.AllowedPlacements\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-realtime-surface-tabs>\n </div>\n }\n\n <!-- THE STAGE: every channel surface lives here, in one layer over the overlay. A surface\n is created the first time it is seen, lies over its tab's slot while that tab is\n active, fills the overlay while its channel holds focus (or, for the agent's video,\n lies in the agent's place in the call), and otherwise waits out of sight \u2014 so\n collapsing the panel, switching tabs or entering focus never reloads it.\n The pane tells each channel when its surface goes out of sight, so it can pause.\n A channel that opts in (SurfaceShareable, such as the whiteboard) marks its frame as a panel the Share menu\n offers under \"This panel\" while it is on screen. A picture-in-picture box the user has not moved starts\n clear of the call's controls. -->\n <mj-media-stage class=\"call-stage\"\n [Surfaces]=\"SurfaceStage.Surfaces\"\n [TabSlot]=\"StageSlot?.Element ?? null\"\n [StageSlot]=\"StageSurfaceSlot\"\n [ActiveTabKey]=\"StageSlot?.Key ?? null\"\n [PipRects]=\"PipRects\"\n [PipKeepClear]=\"callControls\"\n (PipRectChange)=\"OnPipRectChange($event)\">\n <ng-template mjMediaStageSurface let-key let-visible=\"Visible\" let-placement=\"Placement\">\n @if (SurfaceStage.PluginFor(key); as plugin) {\n <div class=\"stage-frame\" role=\"region\" [attr.aria-label]=\"plugin.TabTitle\"\n [mjSharePanel]=\"plugin.SurfaceShareable ? plugin.TabTitle : null\" [mjSharePanelIcon]=\"plugin.TabIcon\">\n <mj-realtime-channel-pane [Plugin]=\"plugin\" [Visible]=\"visible\" [Placement]=\"placement\"></mj-realtime-channel-pane>\n <!-- A surface presenting the agent has no focus pill, so its \"Move to\u2026\" menu rides on it. -->\n @if (placement === 'stage' && plugin.ShowsAgentVideo) {\n <mj-media-move-menu\n class=\"stage-presenter-move\"\n [Key]=\"key\"\n [Title]=\"plugin.TabTitle\"\n Placement=\"stage\"\n [Allowed]=\"SurfaceStage.AllowedFor(key)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n </div>\n }\n </ng-template>\n <!-- A picture-in-picture box's bar carries the same \"Move to\u2026\" menu. -->\n <ng-template mjMediaStagePipActions let-key>\n @if (SurfaceStage.PluginFor(key); as plugin) {\n <mj-media-move-menu\n [Key]=\"key\"\n [Title]=\"plugin.TabTitle\"\n Placement=\"pip\"\n [Allowed]=\"SurfaceStage.AllowedFor(key)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n </ng-template>\n </mj-media-stage>\n\n <!-- FOCUS floating call pill: the main column is hidden, so the live call's\n identity + state + mute / show-thread / end controls ride over the surface. -->\n @if (!IsReviewing && ChannelFocusMode) {\n <div class=\"board-focus-pill\" role=\"status\" aria-label=\"Live call (board focus)\">\n <span class=\"board-focus-pill__orb\" [attr.data-state]=\"state\" aria-hidden=\"true\"></span>\n <span class=\"board-focus-pill__text\">\n <span class=\"board-focus-pill__name\">Voice for {{ AgentName }}</span>\n @if (FocusStateLabel(state); as label) {\n <span class=\"board-focus-pill__state\">{{ label }}</span>\n }\n </span>\n <button type=\"button\" class=\"board-focus-pill__btn\"\n [class.board-focus-pill__btn--active]=\"FocusPillMuted\"\n (click)=\"OnFocusPillMute()\"\n [title]=\"FocusPillMuted ? 'Unmute' : 'Mute'\"\n [attr.aria-label]=\"FocusPillMuted ? 'Unmute microphone' : 'Mute microphone'\">\n <i class=\"fa-solid\" [class.fa-microphone]=\"!FocusPillMuted\" [class.fa-microphone-slash]=\"FocusPillMuted\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"board-focus-pill__btn\"\n (click)=\"OnFocusPillExit()\"\n title=\"Show thread\" aria-label=\"Show the conversation thread\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n </button>\n @if (StagePlugin; as stagePlugin) {\n <mj-media-move-menu\n [Key]=\"stagePlugin.ChannelName\"\n [Title]=\"stagePlugin.TabTitle\"\n Placement=\"stage\"\n [Allowed]=\"SurfaceStage.AllowedFor(stagePlugin.ChannelName)\"\n (MoveRequested)=\"OnMoveRequested($event)\"\n (ResetLayoutRequested)=\"OnResetLayout()\">\n </mj-media-move-menu>\n }\n <button type=\"button\" class=\"board-focus-pill__btn board-focus-pill__btn--end\"\n (click)=\"OnFocusPillEnd()\"\n title=\"End call\" aria-label=\"End the call\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- THE CAMERA CHECK: the first time the user turns the camera on in a call, they see it, and can pick another\n camera, before the agent does. Until they choose, the camera's own box says it is waiting. -->\n @if (CameraCheck; as camera) {\n <mj-realtime-camera-check-card\n [Camera]=\"camera\"\n [AgentName]=\"AgentName\"\n [Switch]=\"SwitchCheckedCamera\"\n (Confirmed)=\"OnCameraCheckConfirmed()\"\n (Declined)=\"OnCameraCheckDeclined()\">\n </mj-realtime-camera-check-card>\n }\n\n </div>\n}\n\n<!-- SESSION REVIEW whiteboard pane body: the reviewed session's saved board, rehydrated\n locally (WhiteboardState.FromJSON) and rendered READ-ONLY (pan/zoom only). Registered\n as a template-based channel tab ONLY when a parseable Whiteboard state exists. -->\n<ng-template #reviewBoardTpl>\n @if (ReviewWhiteboard; as board) {\n <!-- The board host positions itself absolutely \u2014 give it a filling, positioned frame. -->\n <div class=\"review-board-host\">\n <mj-realtime-whiteboard\n [State]=\"board\"\n [AgentName]=\"AgentName\"\n [ReadOnly]=\"true\">\n </mj-realtime-whiteboard>\n </div>\n }\n</ng-template>\n\n<!-- SESSION REVIEW recording pane body: the reviewed session's recorded audio synced to its\n transcript, replayed via the shared storage media player (click-to-seek transcript + playhead\n highlight). Registered as a template-based channel tab ONLY when the reviewed session carries a\n RecordingFileID; the player resolves the authenticated audio itself from that file id. -->\n<ng-template #recordingTpl>\n <div class=\"review-recording-host\">\n <mj-storage-media-player\n [FileID]=\"ReviewRecordingFileID\"\n [Transcript]=\"ReviewCues\"\n [Provider]=\"Provider\">\n </mj-storage-media-player>\n </div>\n</ng-template>\n", styles: [":host {\n display: contents;\n}\n\n/* Fills the conversation panel IN PLACE: the chat area host provides the positioned\n context (position:relative on .chat-area) and this covers it edge to edge \u2014 header,\n thread and composer included. Opaque-ish page surface with a slight blur so the\n conversation underneath reads as \"paused\", not as an app-wide modal. */\n.call-overlay {\n position: absolute;\n inset: 0;\n z-index: 50;\n display: flex;\n background: color-mix(in srgb, var(--mj-bg-page) 94%, transparent);\n backdrop-filter: blur(8px);\n overflow: hidden;\n}\n\n/* Minimized: hidden (NOT destroyed) so the shell's session/view state survives while\n the host shows its floating \"on call\" pill. The audio session is untouched. */\n.call-overlay--hidden {\n display: none;\n}\n\n/* MAIN column: banner (top) \u2192 scrolling thread \u2192 channel strip \u2192 composer \u2192 controls.\n The 420px floor keeps the call column readable while the panel is dragged wide\n (the drag clamp's 70% cap is the other guard). */\n.call-main {\n flex: 1;\n min-width: 420px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* The call's controls at the foot of the column: the \"Agent can see\" chip, the channel strip and the composer. The\n stage starts its picture-in-picture boxes above this box, so it is never squeezed below its content's height. */\n.call-controls {\n flex: none;\n}\n\n.call-body {\n flex: 1;\n overflow-y: auto;\n padding: 16px 22px;\n min-height: 0;\n scrollbar-width: thin;\n scrollbar-color: var(--mj-border-strong) transparent;\n}\n.call-body::-webkit-scrollbar {\n width: 6px;\n}\n.call-body::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.call-connecting {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n min-height: 160px;\n}\n\n/* ---------- PURE-AUDIO HERO (disclosure level 0) ----------\n The orb IS the interface: it breathes with the audio inside expanding sound-wave\n rings, with a small voice equalizer underneath. Nothing to read, nothing to\n configure \u2014 text, panels and the composer are revealed later (or peeked on demand). */\n.call-body--hero {\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n}\n.hero {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n animation: hero-in 420ms cubic-bezier(0.2, 0.8, 0.3, 1);\n}\n@keyframes hero-in {\n from { opacity: 0; transform: scale(0.94); }\n to { opacity: 1; transform: scale(1); }\n}\n/* The orb (mj-realtime-agent-orb) at hero scale. */\n.hero__orb {\n margin-bottom: 4px;\n}\n/* Voice equalizer: lively while the agent speaks, near-still otherwise. */\n.hero__eq {\n display: flex;\n align-items: center;\n gap: 4px;\n height: 30px;\n margin-bottom: 6px;\n}\n.hero__eq span {\n width: 4px;\n height: 8px;\n border-radius: var(--mj-radius-full, 9999px);\n background: var(--mj-brand-accent, var(--mj-brand-primary));\n opacity: 0.55;\n}\n.hero[data-state='speaking'] .hero__eq span {\n animation: hero-eq 1.05s ease-in-out infinite;\n}\n.hero__eq span:nth-child(1) { animation-delay: 0s; }\n.hero__eq span:nth-child(2) { animation-delay: 0.14s; }\n.hero__eq span:nth-child(3) { animation-delay: 0.28s; }\n.hero__eq span:nth-child(4) { animation-delay: 0.07s; }\n.hero__eq span:nth-child(5) { animation-delay: 0.21s; }\n.hero__eq span:nth-child(6) { animation-delay: 0.35s; }\n.hero__eq span:nth-child(7) { animation-delay: 0.1s; }\n.hero__eq span:nth-child(8) { animation-delay: 0.24s; }\n.hero__eq span:nth-child(9) { animation-delay: 0.03s; }\n@keyframes hero-eq {\n 0%, 100% { height: 7px; opacity: 0.6; }\n 50% { height: 28px; opacity: 1; }\n}\n/* ---------- the agent's place while its video presents (the Avatar) ----------\n The stage lays the agent's video over these boxes; each has a size only while the video presents. Portrait, as\n avatar video is (Google's samples are 704x1280). */\n.hero--presenting {\n height: 100%;\n min-height: 0;\n}\n.hero__presenter,\n.call-presenter {\n display: none;\n}\n.hero__presenter--on {\n display: block;\n position: relative;\n container-type: size;\n flex: 1 1 auto;\n min-height: 160px;\n max-height: 520px;\n aspect-ratio: 3 / 4;\n margin-bottom: 8px;\n}\n/* Captions over the agent's video, as subtitles: the newest two lines, over the lower third and clear of the tile's\n footer. Above the stage (z-index 1), where the video is. Light on a dark band in both themes, like the tile's chips. */\n.hero__caption {\n position: absolute;\n left: 6%;\n right: 6%;\n bottom: 16%;\n z-index: 2;\n margin: 0;\n padding: 6px 10px;\n border-radius: var(--mj-radius-md);\n background: rgba(0, 0, 0, 0.6);\n color: rgba(255, 255, 255, 0.95);\n font-size: 0.95rem;\n line-height: 1.4;\n text-align: center;\n}\n/* Two lines, the newest: older ones leave through the top. The window clips, not the padded band, so nothing of an\n older line shows in the padding. */\n.hero__caption-window {\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n max-height: 2.8em;\n overflow: hidden;\n}\n.hero__caption-speaker {\n font-weight: 600;\n}\n/* A small tile (a short window): one smaller line, so the video still shows. */\n@container (max-height: 240px) {\n .hero__caption {\n bottom: 22%;\n padding: 3px 6px;\n font-size: 0.75rem;\n }\n .hero__caption-window {\n max-height: 1.4em;\n }\n}\n/* In the console it sits above the scrolling thread, so it stays in view as the conversation grows. Wide enough for\n the tile's \"AI-generated video\" label on one line. */\n.call-presenter--on {\n display: block;\n flex: none;\n align-self: center;\n height: 200px;\n aspect-ratio: 4 / 5;\n margin-top: 12px;\n}\n.hero__name {\n font-size: 19px;\n font-weight: 800;\n letter-spacing: -0.01em;\n color: var(--mj-text-primary);\n}\n.hero__sub {\n font-size: 12.5px;\n color: var(--mj-text-muted);\n}\n/* The hero's state for screen readers only, while the agent's tile shows it. */\n.hero__sr {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n/* ---------- AUDIO-REACTIVE MODE (data-audio-live, set by the rAF meter loop) ----------\n With real audio metering the visuals stop acting and start REACTING: the EQ renders the\n true spectrum (--eq-1..9), and [data-voice-dir] colors it by who is speaking (agent =\n brand, user = green). The orb (mj-realtime-agent-orb) reads the same attributes and the\n smoothed output envelope (--voice-out) itself. Without metering (driver attached no\n meters) the attribute stays 'false' and the turn-state keyframe animations stay in charge. */\n/* True-spectrum EQ: per-bar heights from the meter's bins. */\n.call-overlay[data-audio-live='true'] .hero__eq span {\n animation: none;\n transition: height 70ms linear, opacity 120ms linear;\n}\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(1) { height: calc(6px + var(--eq-1, 0) * 24px); opacity: calc(0.45 + var(--eq-1, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(2) { height: calc(6px + var(--eq-2, 0) * 24px); opacity: calc(0.45 + var(--eq-2, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(3) { height: calc(6px + var(--eq-3, 0) * 24px); opacity: calc(0.45 + var(--eq-3, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(4) { height: calc(6px + var(--eq-4, 0) * 24px); opacity: calc(0.45 + var(--eq-4, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(5) { height: calc(6px + var(--eq-5, 0) * 24px); opacity: calc(0.45 + var(--eq-5, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(6) { height: calc(6px + var(--eq-6, 0) * 24px); opacity: calc(0.45 + var(--eq-6, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(7) { height: calc(6px + var(--eq-7, 0) * 24px); opacity: calc(0.45 + var(--eq-7, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(8) { height: calc(6px + var(--eq-8, 0) * 24px); opacity: calc(0.45 + var(--eq-8, 0) * 0.55); }\n.call-overlay[data-audio-live='true'] .hero__eq span:nth-child(9) { height: calc(6px + var(--eq-9, 0) * 24px); opacity: calc(0.45 + var(--eq-9, 0) * 0.55); }\n.call-overlay[data-audio-live='true'][data-voice-dir='user'] .hero__eq span {\n background: var(--mj-status-success);\n}\n\n/* The quiet first reveal: show the conversation as text (raises disclosure to level 1). */\n.hero__reveal {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: 18px;\n padding: 6px 14px;\n border-radius: var(--mj-radius-full, 9999px);\n border: 1px dashed var(--mj-border-strong);\n background: transparent;\n color: var(--mj-text-muted);\n font-family: inherit;\n font-size: 11.5px;\n font-weight: 600;\n cursor: pointer;\n transition: color 140ms ease, border-color 140ms ease, background 140ms ease;\n}\n.hero__reveal:hover {\n color: var(--mj-text-secondary);\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n.hero__reveal i {\n font-size: 11px;\n}\n\n/* Ephemeral narration shown under the banner when no working card anchors it */\n.banner-live-note {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n padding: 8px 22px 0;\n font-size: 12px;\n font-style: italic;\n color: var(--mj-text-muted);\n animation: overlay-note-in 220ms ease;\n}\n.banner-live-note i {\n font-size: 10px;\n margin-top: 3px;\n flex-shrink: 0;\n}\n@keyframes overlay-note-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* The call's notices under the banner (no microphone works; no avatar): mj-alert brings its own tint, border and text\n colours; this only places them. */\n.call-microphone-notice,\n.call-avatar-notice {\n flex-shrink: 0;\n margin: var(--mj-space-2) var(--mj-space-5) 0;\n}\n\n/* ---------- FOCUS-BOARD mode (whiteboard \"Focus board\" toggle) ----------\n The main call column collapses away entirely and the focused channel's surface fills\n the stage; a compact floating call pill keeps the live call reachable. */\n.call-overlay.board-focus .call-main {\n display: none;\n}\n\n/* ---------- the stage (every channel surface, in one layer) ----------\n mj-media-stage covers the overlay and places each surface itself. Above the panel it\n lays surfaces over, and above the call's controls, so its picture-in-picture boxes\n start clear of them (.call-controls); below the onboarding card (5), the menus of the\n dock and the chip (5) and the focus pill (60). */\n.call-stage {\n z-index: 1;\n}\n/* A surface's frame: fills the box the stage gives it. The surface component is created\n beside the pane host inside it, and sizes itself to it (height: 100%). */\n.stage-frame {\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n/* The \"Move to\u2026\" menu on a surface that presents the agent, backed so it reads over video. Bottom right, in the\n tile's footer, which holds nothing there for the agent, so it never covers the tile's labels. */\n.stage-presenter-move {\n position: absolute;\n bottom: 4px;\n right: 6px;\n z-index: 1;\n border-radius: var(--mj-radius-full);\n background: color-mix(in srgb, var(--mj-bg-surface) 85%, transparent);\n}\n\n/* Floating call pill: orb + state + mute / show-thread / end (per the whiteboard mockup). */\n.board-focus-pill {\n position: absolute;\n left: 64px;\n top: 12px;\n z-index: 60;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 7px 9px 7px 12px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-bg-surface-card) 92%, transparent);\n backdrop-filter: blur(8px);\n border: 1px solid var(--mj-border-strong);\n box-shadow: var(--mj-shadow-xl, 0 12px 32px rgba(0, 0, 0, 0.18));\n animation: overlay-note-in 220ms ease;\n}\n.board-focus-pill__orb {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n flex-shrink: 0;\n background: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n.board-focus-pill__orb[data-state='speaking'],\n.board-focus-pill__orb[data-state='listening'] {\n animation: board-pill-pulse 1.6s ease-in-out infinite;\n}\n.board-focus-pill__orb[data-state='error'] {\n background: var(--mj-status-error);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-status-error) 18%, transparent);\n}\n@keyframes board-pill-pulse {\n 0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent); }\n 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--mj-brand-primary) 8%, transparent); }\n}\n.board-focus-pill__text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n.board-focus-pill__name {\n font-size: 12px;\n font-weight: 700;\n line-height: 1.2;\n white-space: nowrap;\n color: var(--mj-text-primary);\n}\n.board-focus-pill__state {\n font-size: 10.5px;\n font-weight: 600;\n white-space: nowrap;\n color: var(--mj-brand-primary);\n}\n.board-focus-pill__btn {\n width: 30px;\n height: 30px;\n border-radius: 50%;\n border: 1px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n font-size: 11px;\n display: grid;\n place-items: center;\n font-family: inherit;\n flex-shrink: 0;\n}\n.board-focus-pill__btn:hover {\n color: var(--mj-text-primary);\n}\n.board-focus-pill__btn--active {\n background: var(--mj-bg-surface-active);\n color: var(--mj-text-primary);\n}\n.board-focus-pill__btn--end {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n color: var(--mj-text-inverse, #fff);\n}\n\n/* ---------- Session review mode ---------- */\n/* Subtle archival tint so a glance says \"this is history, not a live call\". */\n.call-overlay--review {\n background:\n linear-gradient(180deg, color-mix(in srgb, var(--mj-text-muted) 4%, transparent), transparent 120px),\n var(--mj-bg-surface);\n}\n\n/* The review whiteboard pane body: the board component positions itself absolutely\n (inset: 0), so its template-based pane needs a filling, positioned frame. */\n.review-board-host {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n/* The review recording pane body: the evidence player fills its host (:host height:100%),\n so its template-based pane needs a filling, constrained frame. */\n.review-recording-host {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.review-recording-host mj-realtime-evidence-playback {\n flex: 1;\n min-height: 0;\n}\n\n/* ---------- flex layout (main column | resize handle | surface panel) ---------- */\n/* Token-styled resize handle: invisible until hover, brand-tinted while interacting.\n 7px hit target, col-resize cursor; removed (not rendered) while collapsed / focus. */\n.call-resizer {\n flex: 0 0 7px;\n width: 7px;\n cursor: col-resize;\n background: transparent;\n transition: background 140ms ease;\n}\n.call-resizer:hover,\n.call-resizer--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 26%, transparent);\n}\n/* The surface panel: a plain fixed-width flex item (inline width set by the overlay;\n collapsed = the slim strip width). flex-shrink lets it yield to the call column's\n min-width on tight overlays; overflow hidden keeps the flex height chain intact so\n the panel's content scrolls internally. */\n.call-panel {\n flex: 0 1 auto;\n min-width: 0;\n display: flex;\n overflow: hidden;\n /* Disclosure-gated: the panel is CREATED when earned/peeked \u2014 its arrival slides in\n from the right so the reveal doubles as the progress cue. */\n animation: panel-in 420ms cubic-bezier(0.25, 0.8, 0.3, 1);\n}\n@keyframes panel-in {\n from { opacity: 0; transform: translateX(48px); }\n to { opacity: 1; transform: translateX(0); }\n}\n.call-panel > * {\n flex: 1;\n min-width: 0;\n min-height: 0;\n}\n"] }]
|
|
2584
2617
|
}], () => [], { Hidden: [{
|
|
2585
2618
|
type: Input
|
|
2586
2619
|
}], AgentName: [{
|
|
@@ -2591,6 +2624,10 @@ export class RealtimeSessionOverlayComponent extends BaseAngularComponent {
|
|
|
2591
2624
|
type: Input
|
|
2592
2625
|
}], AvatarNoticeLabels: [{
|
|
2593
2626
|
type: Input
|
|
2627
|
+
}], ShowAvatarNotice: [{
|
|
2628
|
+
type: Input
|
|
2629
|
+
}], ShowPerceptionChip: [{
|
|
2630
|
+
type: Input
|
|
2594
2631
|
}], Chrome: [{
|
|
2595
2632
|
type: Input
|
|
2596
2633
|
}], ConsoleBreakpointPx: [{
|