@memberjunction/ng-conversations 6.1.2 → 6.2.0-edge.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +9 -26
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.js +1 -1
- package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +3 -0
- package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.d.ts +2 -1
- package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/media/media-channel.js +1 -1
- package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +1 -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.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts +3 -1
- package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +26 -8
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +2 -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 +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.d.ts +2 -3
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.js +3 -2
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts +17 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.js +122 -45
- package/dist/lib/components/realtime/realtime-session-thread.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts +1 -9
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +13 -43
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +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 +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +1 -1
- package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/services/browser-realtime-media-host.d.ts +24 -0
- package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -0
- package/dist/lib/services/browser-realtime-media-host.js +95 -0
- package/dist/lib/services/browser-realtime-media-host.js.map +1 -0
- package/dist/lib/services/conversation-attachment.service.d.ts +24 -2
- package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-attachment.service.js +43 -4
- package/dist/lib/services/conversation-attachment.service.js.map +1 -1
- package/dist/lib/services/graphql-attachment-blob-store.d.ts +44 -0
- package/dist/lib/services/graphql-attachment-blob-store.d.ts.map +1 -0
- package/dist/lib/services/graphql-attachment-blob-store.js +113 -0
- package/dist/lib/services/graphql-attachment-blob-store.js.map +1 -0
- package/dist/lib/services/mention-autocomplete.service.d.ts +17 -141
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +15 -460
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session-review.service.js +1 -1
- package/dist/lib/services/realtime-session-review.service.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +16 -1150
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +28 -2430
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/utils/realtime-session-timeline.d.ts +8 -79
- package/dist/lib/utils/realtime-session-timeline.d.ts.map +1 -1
- package/dist/lib/utils/realtime-session-timeline.js +8 -89
- package/dist/lib/utils/realtime-session-timeline.js.map +1 -1
- package/dist/public-api.d.ts +2 -2
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +6 -2
- package/dist/public-api.js.map +1 -1
- package/package.json +33 -32
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts +0 -384
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.d.ts.map +0 -1
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js +0 -231
- package/dist/lib/components/realtime/channels/base-realtime-channel-client.js.map +0 -1
- package/dist/lib/services/delegation-result-parser.d.ts +0 -50
- package/dist/lib/services/delegation-result-parser.d.ts.map +0 -1
- package/dist/lib/services/delegation-result-parser.js +0 -60
- package/dist/lib/services/delegation-result-parser.js.map +0 -1
- package/dist/lib/services/narration-template.d.ts +0 -42
- package/dist/lib/services/narration-template.d.ts.map +0 -1
- package/dist/lib/services/narration-template.js +0 -73
- package/dist/lib/services/narration-template.js.map +0 -1
- package/dist/lib/services/skill-picker-narrowing.d.ts +0 -13
- package/dist/lib/services/skill-picker-narrowing.d.ts.map +0 -1
- package/dist/lib/services/skill-picker-narrowing.js +0 -13
- package/dist/lib/services/skill-picker-narrowing.js.map +0 -1
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Component, EventEmitter, Input, Output, ViewChild, ChangeDetectorRef, inject } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { MarkdownModule } from '@memberjunction/ng-markdown';
|
|
3
4
|
import { RealtimeDelegationCardComponent } from './realtime-delegation-card.component';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
|
-
import * as i1 from "@
|
|
6
|
+
import * as i1 from "@memberjunction/ng-markdown";
|
|
7
|
+
import * as i2 from "@angular/common";
|
|
6
8
|
const _c0 = ["scrollAnchor"];
|
|
7
9
|
function RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
8
10
|
i0.ɵɵelementStart(0, "span", 10);
|
|
@@ -15,13 +17,32 @@ function RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Conditional_5
|
|
|
15
17
|
} }
|
|
16
18
|
function RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
17
19
|
i0.ɵɵtext(0);
|
|
18
|
-
i0.ɵɵelementStart(1, "span",
|
|
20
|
+
i0.ɵɵelementStart(1, "span", 15);
|
|
19
21
|
i0.ɵɵtext(2, "\u00B7 voice");
|
|
20
22
|
i0.ɵɵelementEnd();
|
|
21
23
|
} if (rf & 2) {
|
|
22
24
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
23
25
|
i0.ɵɵtextInterpolate1(" ", ctx_r0.AgentName, " ");
|
|
24
26
|
} }
|
|
27
|
+
function RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
28
|
+
const _r2 = i0.ɵɵgetCurrentView();
|
|
29
|
+
i0.ɵɵelementStart(0, "div", 14)(1, "button", 16);
|
|
30
|
+
i0.ɵɵlistener("click", function RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Conditional_10_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r2); const $index_r3 = i0.ɵɵnextContext(3).$index; const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.ToggleExpanded($index_r3, $event)); });
|
|
31
|
+
i0.ɵɵelementStart(2, "span");
|
|
32
|
+
i0.ɵɵtext(3);
|
|
33
|
+
i0.ɵɵelementEnd();
|
|
34
|
+
i0.ɵɵelement(4, "i", 17);
|
|
35
|
+
i0.ɵɵelementEnd()();
|
|
36
|
+
} if (rf & 2) {
|
|
37
|
+
const $index_r3 = i0.ɵɵnextContext(3).$index;
|
|
38
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
39
|
+
i0.ɵɵadvance();
|
|
40
|
+
i0.ɵɵattribute("aria-expanded", ctx_r0.IsExpanded($index_r3));
|
|
41
|
+
i0.ɵɵadvance(2);
|
|
42
|
+
i0.ɵɵtextInterpolate(ctx_r0.IsExpanded($index_r3) ? "Show less" : "Show more");
|
|
43
|
+
i0.ɵɵadvance();
|
|
44
|
+
i0.ɵɵclassProp("fa-chevron-up", ctx_r0.IsExpanded($index_r3))("fa-chevron-down", !ctx_r0.IsExpanded($index_r3));
|
|
45
|
+
} }
|
|
25
46
|
function RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
26
47
|
i0.ɵɵelementStart(0, "div", 6)(1, "div", 7);
|
|
27
48
|
i0.ɵɵtext(2);
|
|
@@ -29,70 +50,80 @@ function RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Template(rf,
|
|
|
29
50
|
i0.ɵɵelementStart(3, "div", 8)(4, "div", 9);
|
|
30
51
|
i0.ɵɵconditionalCreate(5, RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Conditional_5_Template, 2, 1, "span", 10)(6, RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Conditional_6_Template, 3, 1);
|
|
31
52
|
i0.ɵɵelementEnd();
|
|
32
|
-
i0.ɵɵelementStart(7, "div", 11);
|
|
33
|
-
i0.ɵɵ
|
|
53
|
+
i0.ɵɵelementStart(7, "div", 11)(8, "div", 12);
|
|
54
|
+
i0.ɵɵelement(9, "mj-markdown", 13);
|
|
55
|
+
i0.ɵɵelementEnd();
|
|
56
|
+
i0.ɵɵconditionalCreate(10, RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Conditional_10_Template, 5, 6, "div", 14);
|
|
34
57
|
i0.ɵɵelementEnd()()();
|
|
35
58
|
} if (rf & 2) {
|
|
36
|
-
const
|
|
59
|
+
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
60
|
+
const item_r5 = ctx_r3.$implicit;
|
|
61
|
+
const $index_r3 = ctx_r3.$index;
|
|
37
62
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
38
|
-
i0.ɵɵclassProp("turn--user",
|
|
63
|
+
i0.ɵɵclassProp("turn--user", item_r5.Role === "User")("turn--agent", item_r5.Role === "Assistant");
|
|
39
64
|
i0.ɵɵadvance(2);
|
|
40
|
-
i0.ɵɵtextInterpolate((
|
|
41
|
-
i0.ɵɵadvance(3);
|
|
42
|
-
i0.ɵɵconditional(item_r2.Role === "User" ? 5 : 6);
|
|
65
|
+
i0.ɵɵtextInterpolate((item_r5.Role === "User" ? ctx_r0.UserName : ctx_r0.AgentName).charAt(0).toUpperCase());
|
|
43
66
|
i0.ɵɵadvance(3);
|
|
44
|
-
i0.ɵɵ
|
|
67
|
+
i0.ɵɵconditional(item_r5.Role === "User" ? 5 : 6);
|
|
68
|
+
i0.ɵɵadvance(2);
|
|
69
|
+
i0.ɵɵclassProp("bubble--clamped", ctx_r0.IsLongText(item_r5.Text) && !ctx_r0.IsExpanded($index_r3))("bubble--expanded", ctx_r0.IsLongText(item_r5.Text) && ctx_r0.IsExpanded($index_r3));
|
|
70
|
+
i0.ɵɵadvance();
|
|
71
|
+
i0.ɵɵclassProp("bubble-content--clamped", ctx_r0.IsLongText(item_r5.Text) && !ctx_r0.IsExpanded($index_r3))("bubble-content--expanded", ctx_r0.IsLongText(item_r5.Text) && ctx_r0.IsExpanded($index_r3));
|
|
72
|
+
i0.ɵɵadvance();
|
|
73
|
+
i0.ɵɵproperty("data", ctx_r0.FormatMarkdownText(item_r5.Text))("enableCollapsibleHeadings", true);
|
|
74
|
+
i0.ɵɵadvance();
|
|
75
|
+
i0.ɵɵconditional(ctx_r0.IsLongText(item_r5.Text) ? 10 : -1);
|
|
45
76
|
} }
|
|
46
77
|
function RealtimeSessionThreadComponent_For_2_Case_0_Template(rf, ctx) { if (rf & 1) {
|
|
47
|
-
i0.ɵɵconditionalCreate(0, RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Template,
|
|
78
|
+
i0.ɵɵconditionalCreate(0, RealtimeSessionThreadComponent_For_2_Case_0_Conditional_0_Template, 11, 17, "div", 5);
|
|
48
79
|
} if (rf & 2) {
|
|
49
80
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
50
81
|
i0.ɵɵconditional(ctx_r0.ShowCaptions ? 0 : -1);
|
|
51
82
|
} }
|
|
52
83
|
function RealtimeSessionThreadComponent_For_2_Case_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
53
|
-
i0.ɵɵelementStart(0, "span",
|
|
84
|
+
i0.ɵɵelementStart(0, "span", 21);
|
|
54
85
|
i0.ɵɵtext(1);
|
|
55
86
|
i0.ɵɵpipe(2, "date");
|
|
56
87
|
i0.ɵɵelementEnd();
|
|
57
88
|
} if (rf & 2) {
|
|
58
|
-
const
|
|
89
|
+
const item_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
59
90
|
i0.ɵɵadvance();
|
|
60
|
-
i0.ɵɵtextInterpolate1("\u00B7 ", i0.ɵɵpipeBind2(2, 1,
|
|
91
|
+
i0.ɵɵtextInterpolate1("\u00B7 ", i0.ɵɵpipeBind2(2, 1, item_r5.At, "MMM d, h:mm a"));
|
|
61
92
|
} }
|
|
62
93
|
function RealtimeSessionThreadComponent_For_2_Case_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
63
|
-
i0.ɵɵelementStart(0, "span",
|
|
94
|
+
i0.ɵɵelementStart(0, "span", 22);
|
|
64
95
|
i0.ɵɵtext(1);
|
|
65
96
|
i0.ɵɵelementEnd();
|
|
66
97
|
} if (rf & 2) {
|
|
67
|
-
const
|
|
98
|
+
const item_r5 = i0.ɵɵnextContext(2).$implicit;
|
|
68
99
|
i0.ɵɵadvance();
|
|
69
|
-
i0.ɵɵtextInterpolate(
|
|
100
|
+
i0.ɵɵtextInterpolate(item_r5.CloseReason);
|
|
70
101
|
} }
|
|
71
102
|
function RealtimeSessionThreadComponent_For_2_Case_1_Template(rf, ctx) { if (rf & 1) {
|
|
72
103
|
i0.ɵɵelementStart(0, "div", 3);
|
|
73
|
-
i0.ɵɵelement(1, "span",
|
|
74
|
-
i0.ɵɵelementStart(2, "span",
|
|
75
|
-
i0.ɵɵelement(3, "i",
|
|
104
|
+
i0.ɵɵelement(1, "span", 18);
|
|
105
|
+
i0.ɵɵelementStart(2, "span", 19);
|
|
106
|
+
i0.ɵɵelement(3, "i", 20);
|
|
76
107
|
i0.ɵɵtext(4);
|
|
77
|
-
i0.ɵɵconditionalCreate(5, RealtimeSessionThreadComponent_For_2_Case_1_Conditional_5_Template, 3, 4, "span",
|
|
108
|
+
i0.ɵɵconditionalCreate(5, RealtimeSessionThreadComponent_For_2_Case_1_Conditional_5_Template, 3, 4, "span", 21);
|
|
78
109
|
i0.ɵɵelementEnd();
|
|
79
|
-
i0.ɵɵconditionalCreate(6, RealtimeSessionThreadComponent_For_2_Case_1_Conditional_6_Template, 2, 1, "span",
|
|
80
|
-
i0.ɵɵelement(7, "span",
|
|
110
|
+
i0.ɵɵconditionalCreate(6, RealtimeSessionThreadComponent_For_2_Case_1_Conditional_6_Template, 2, 1, "span", 22);
|
|
111
|
+
i0.ɵɵelement(7, "span", 18);
|
|
81
112
|
i0.ɵɵelementEnd();
|
|
82
113
|
} if (rf & 2) {
|
|
83
|
-
const
|
|
114
|
+
const item_r5 = i0.ɵɵnextContext().$implicit;
|
|
84
115
|
i0.ɵɵadvance(3);
|
|
85
|
-
i0.ɵɵclassMap(
|
|
116
|
+
i0.ɵɵclassMap(item_r5.Icon);
|
|
86
117
|
i0.ɵɵadvance();
|
|
87
|
-
i0.ɵɵtextInterpolate1(" ",
|
|
118
|
+
i0.ɵɵtextInterpolate1(" ", item_r5.Label, " ");
|
|
88
119
|
i0.ɵɵadvance();
|
|
89
|
-
i0.ɵɵconditional(
|
|
120
|
+
i0.ɵɵconditional(item_r5.At ? 5 : -1);
|
|
90
121
|
i0.ɵɵadvance();
|
|
91
|
-
i0.ɵɵconditional(
|
|
122
|
+
i0.ɵɵconditional(item_r5.CloseReason ? 6 : -1);
|
|
92
123
|
} }
|
|
93
124
|
function RealtimeSessionThreadComponent_For_2_Case_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
94
|
-
i0.ɵɵelementStart(0, "div",
|
|
95
|
-
i0.ɵɵelement(1, "i",
|
|
125
|
+
i0.ɵɵelementStart(0, "div", 24);
|
|
126
|
+
i0.ɵɵelement(1, "i", 25);
|
|
96
127
|
i0.ɵɵtext(2);
|
|
97
128
|
i0.ɵɵelementEnd();
|
|
98
129
|
} if (rf & 2) {
|
|
@@ -101,26 +132,26 @@ function RealtimeSessionThreadComponent_For_2_Case_2_Conditional_2_Template(rf,
|
|
|
101
132
|
i0.ɵɵtextInterpolate1(" ", ctx_r0.State.Narration, " ");
|
|
102
133
|
} }
|
|
103
134
|
function RealtimeSessionThreadComponent_For_2_Case_2_Template(rf, ctx) { if (rf & 1) {
|
|
104
|
-
const
|
|
105
|
-
i0.ɵɵelementStart(0, "div", 4)(1, "mj-realtime-delegation-card",
|
|
106
|
-
i0.ɵɵlistener("OpenRunRequested", function RealtimeSessionThreadComponent_For_2_Case_2_Template_mj_realtime_delegation_card_OpenRunRequested_1_listener($event) { i0.ɵɵrestoreView(
|
|
135
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
136
|
+
i0.ɵɵelementStart(0, "div", 4)(1, "mj-realtime-delegation-card", 23);
|
|
137
|
+
i0.ɵɵlistener("OpenRunRequested", function RealtimeSessionThreadComponent_For_2_Case_2_Template_mj_realtime_delegation_card_OpenRunRequested_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OpenRunRequested.emit($event)); })("OpenArtifactRequested", function RealtimeSessionThreadComponent_For_2_Case_2_Template_mj_realtime_delegation_card_OpenArtifactRequested_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OpenArtifactRequested.emit($event)); })("CancelRequested", function RealtimeSessionThreadComponent_For_2_Case_2_Template_mj_realtime_delegation_card_CancelRequested_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.CancelRequested.emit($event)); });
|
|
107
138
|
i0.ɵɵelementEnd();
|
|
108
|
-
i0.ɵɵconditionalCreate(2, RealtimeSessionThreadComponent_For_2_Case_2_Conditional_2_Template, 3, 1, "div",
|
|
139
|
+
i0.ɵɵconditionalCreate(2, RealtimeSessionThreadComponent_For_2_Case_2_Conditional_2_Template, 3, 1, "div", 24);
|
|
109
140
|
i0.ɵɵelementEnd();
|
|
110
141
|
} if (rf & 2) {
|
|
111
|
-
const
|
|
142
|
+
const item_r5 = i0.ɵɵnextContext().$implicit;
|
|
112
143
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
113
144
|
i0.ɵɵadvance();
|
|
114
|
-
i0.ɵɵproperty("Card",
|
|
145
|
+
i0.ɵɵproperty("Card", item_r5.Card)("DevMode", ctx_r0.DevMode);
|
|
115
146
|
i0.ɵɵadvance();
|
|
116
|
-
i0.ɵɵconditional(ctx_r0.ShowsLiveNote(
|
|
147
|
+
i0.ɵɵconditional(ctx_r0.ShowsLiveNote(item_r5) ? 2 : -1);
|
|
117
148
|
} }
|
|
118
149
|
function RealtimeSessionThreadComponent_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
119
150
|
i0.ɵɵconditionalCreate(0, RealtimeSessionThreadComponent_For_2_Case_0_Template, 1, 1)(1, RealtimeSessionThreadComponent_For_2_Case_1_Template, 8, 5, "div", 3)(2, RealtimeSessionThreadComponent_For_2_Case_2_Template, 3, 3, "div", 4);
|
|
120
151
|
} if (rf & 2) {
|
|
121
152
|
let tmp_11_0;
|
|
122
|
-
const
|
|
123
|
-
i0.ɵɵconditional((tmp_11_0 =
|
|
153
|
+
const item_r5 = ctx.$implicit;
|
|
154
|
+
i0.ɵɵconditional((tmp_11_0 = item_r5.Kind) === "caption" ? 0 : tmp_11_0 === "divider" ? 1 : tmp_11_0 === "delegation" ? 2 : -1);
|
|
124
155
|
} }
|
|
125
156
|
function RealtimeSessionThreadComponent_ForEmpty_3_Template(rf, ctx) { if (rf & 1) {
|
|
126
157
|
i0.ɵɵelementStart(0, "div", 2);
|
|
@@ -165,7 +196,7 @@ export class RealtimeSessionThreadComponent {
|
|
|
165
196
|
/** Drives auto-scroll: set whenever the list grows. */
|
|
166
197
|
pendingScroll = false;
|
|
167
198
|
changedSub;
|
|
168
|
-
cdr = inject(ChangeDetectorRef);
|
|
199
|
+
cdr = inject(ChangeDetectorRef, { optional: true });
|
|
169
200
|
ngOnInit() {
|
|
170
201
|
this.changedSub = this.State.Changed$.subscribe(() => this.onStateChanged());
|
|
171
202
|
this.lastItemCount = this.State.Items.length;
|
|
@@ -194,13 +225,59 @@ export class RealtimeSessionThreadComponent {
|
|
|
194
225
|
&& this.State.Narration !== null
|
|
195
226
|
&& item.Card.CallID === this.State.ActiveCallId;
|
|
196
227
|
}
|
|
228
|
+
/** Set of item indices whose long text has been expanded by the user. */
|
|
229
|
+
ExpandedItems = new Set();
|
|
230
|
+
/**
|
|
231
|
+
* Returns true when the caption text is considered a "long blob" (>280 chars or >4 lines)
|
|
232
|
+
* that warrants height clamping and an expand/collapse toggle.
|
|
233
|
+
*/
|
|
234
|
+
IsLongText(text) {
|
|
235
|
+
if (!text) {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
return text.length > 280 || text.split('\n').length > 4;
|
|
239
|
+
}
|
|
240
|
+
/** Returns whether the caption item at the specified index is expanded. */
|
|
241
|
+
IsExpanded(index) {
|
|
242
|
+
return this.ExpandedItems.has(index);
|
|
243
|
+
}
|
|
244
|
+
/** Toggles expanded/collapsed state for the caption item at the given index. */
|
|
245
|
+
ToggleExpanded(index, event) {
|
|
246
|
+
if (event) {
|
|
247
|
+
event.stopPropagation();
|
|
248
|
+
}
|
|
249
|
+
if (this.ExpandedItems.has(index)) {
|
|
250
|
+
this.ExpandedItems.delete(index);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
this.ExpandedItems.add(index);
|
|
254
|
+
}
|
|
255
|
+
this.cdr?.markForCheck();
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Prepares text for markdown rendering, restoring structure (headings, horizontal rules,
|
|
259
|
+
* bullet items) if newlines were stripped by single-line input paste or speech-to-text.
|
|
260
|
+
*/
|
|
261
|
+
FormatMarkdownText(text) {
|
|
262
|
+
if (!text) {
|
|
263
|
+
return '';
|
|
264
|
+
}
|
|
265
|
+
let cleaned = text;
|
|
266
|
+
// Restore newlines before markdown headings on same line: "Title ### Heading" -> "Title\n\n### Heading"
|
|
267
|
+
cleaned = cleaned.replace(/[ \t]+(?:—\s*)?(#{1,6}[ \t]+)/g, '\n\n$1');
|
|
268
|
+
// Restore newlines around horizontal rules on same line: "Text --- ##" -> "Text\n\n---\n\n##"
|
|
269
|
+
cleaned = cleaned.replace(/[ \t]+(?:—\s*)?(---|___|\*\*\*)[ \t]*/g, '\n\n$1\n\n');
|
|
270
|
+
// Restore newlines before bullet items on same line: "around: - Item 1 - Item 2" -> "around:\n- Item 1\n- Item 2"
|
|
271
|
+
cleaned = cleaned.replace(/[ \t]+-[ \t]+(?=[A-Za-z0-9\*])/g, '\n- ');
|
|
272
|
+
return cleaned;
|
|
273
|
+
}
|
|
197
274
|
/** Marks for check on every state change; auto-scrolls when the thread grew. */
|
|
198
275
|
onStateChanged() {
|
|
199
276
|
if (this.State.Items.length > this.lastItemCount) {
|
|
200
277
|
this.pendingScroll = true;
|
|
201
278
|
}
|
|
202
279
|
this.lastItemCount = this.State.Items.length;
|
|
203
|
-
this.cdr
|
|
280
|
+
this.cdr?.markForCheck();
|
|
204
281
|
}
|
|
205
282
|
static ɵfac = function RealtimeSessionThreadComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RealtimeSessionThreadComponent)(); };
|
|
206
283
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RealtimeSessionThreadComponent, selectors: [["mj-realtime-session-thread"]], viewQuery: function RealtimeSessionThreadComponent_Query(rf, ctx) { if (rf & 1) {
|
|
@@ -208,7 +285,7 @@ export class RealtimeSessionThreadComponent {
|
|
|
208
285
|
} if (rf & 2) {
|
|
209
286
|
let _t;
|
|
210
287
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollAnchor = _t.first);
|
|
211
|
-
} }, inputs: { AgentName: "AgentName", UserName: "UserName", State: "State", ShowCaptions: "ShowCaptions", DevMode: "DevMode" }, outputs: { OpenRunRequested: "OpenRunRequested", OpenArtifactRequested: "OpenArtifactRequested", CancelRequested: "CancelRequested" }, decls: 6, vars: 1, consts: [["scrollAnchor", ""], [1, "thread"], [1, "thread-empty"], ["role", "separator", 1, "thread-divider"], [1, "delegation-block"], [1, "turn", 3, "turn--user", "turn--agent"], [1, "turn"], [1, "turn-avatar"], [1, "turn-body"], [1, "turn-meta"], [1, "typed-tag"], [1, "bubble"], [1, "muted"], ["aria-hidden", "true", 1, "thread-divider__line"], [1, "thread-divider__label"], ["aria-hidden", "true"], [1, "thread-divider__time"], ["title", "Why the previous session leg ended", 1, "thread-divider__chip"], [3, "OpenRunRequested", "OpenArtifactRequested", "CancelRequested", "Card", "DevMode"], ["role", "status", "aria-live", "polite", 1, "live-note"], ["aria-hidden", "true", 1, "fa-solid", "fa-comment-dots"]], template: function RealtimeSessionThreadComponent_Template(rf, ctx) { if (rf & 1) {
|
|
288
|
+
} }, inputs: { AgentName: "AgentName", UserName: "UserName", State: "State", ShowCaptions: "ShowCaptions", DevMode: "DevMode" }, outputs: { OpenRunRequested: "OpenRunRequested", OpenArtifactRequested: "OpenArtifactRequested", CancelRequested: "CancelRequested" }, decls: 6, vars: 1, consts: [["scrollAnchor", ""], [1, "thread"], [1, "thread-empty"], ["role", "separator", 1, "thread-divider"], [1, "delegation-block"], [1, "turn", 3, "turn--user", "turn--agent"], [1, "turn"], [1, "turn-avatar"], [1, "turn-body"], [1, "turn-meta"], [1, "typed-tag"], [1, "bubble"], [1, "bubble-content"], [3, "data", "enableCollapsibleHeadings"], [1, "bubble-actions"], [1, "muted"], ["type", "button", 1, "bubble-expand-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid"], ["aria-hidden", "true", 1, "thread-divider__line"], [1, "thread-divider__label"], ["aria-hidden", "true"], [1, "thread-divider__time"], ["title", "Why the previous session leg ended", 1, "thread-divider__chip"], [3, "OpenRunRequested", "OpenArtifactRequested", "CancelRequested", "Card", "DevMode"], ["role", "status", "aria-live", "polite", 1, "live-note"], ["aria-hidden", "true", 1, "fa-solid", "fa-comment-dots"]], template: function RealtimeSessionThreadComponent_Template(rf, ctx) { if (rf & 1) {
|
|
212
289
|
i0.ɵɵelementStart(0, "div", 1);
|
|
213
290
|
i0.ɵɵrepeaterCreate(1, RealtimeSessionThreadComponent_For_2_Template, 3, 1, null, null, ctx.TrackItem, true, RealtimeSessionThreadComponent_ForEmpty_3_Template, 2, 0, "div", 2);
|
|
214
291
|
i0.ɵɵelement(4, "div", null, 0);
|
|
@@ -216,11 +293,11 @@ export class RealtimeSessionThreadComponent {
|
|
|
216
293
|
} if (rf & 2) {
|
|
217
294
|
i0.ɵɵadvance();
|
|
218
295
|
i0.ɵɵrepeater(ctx.State.Items);
|
|
219
|
-
} }, dependencies: [CommonModule, RealtimeDelegationCardComponent, i1.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n}\n\n.thread[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.thread-empty[_ngcontent-%COMP%] {\n text-align: center;\n font-size: 12.5px;\n color: var(--mj-text-disabled);\n padding: 24px 0;\n}\n\n\n.turn[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n max-width: 100%;\n}\n.turn--user[_ngcontent-%COMP%] {\n flex-direction: row-reverse;\n}\n.turn-body[_ngcontent-%COMP%] {\n min-width: 0;\n}\n.turn-avatar[_ngcontent-%COMP%] {\n width: 26px;\n height: 26px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 700;\n margin-top: 2px;\n}\n.turn--agent[_ngcontent-%COMP%] .turn-avatar[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, var(--mj-brand-primary), var(--mj-brand-accent, var(--mj-brand-primary)));\n color: var(--mj-text-inverse, #fff);\n}\n.turn--user[_ngcontent-%COMP%] .turn-avatar[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-strong);\n}\n.bubble[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border-radius: 12px;\n max-width: 560px;\n font-size: 13.5px;\n line-height: 1.5;\n position: relative;\n}\n.turn--agent[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-top-left-radius: 4px;\n color: var(--mj-text-primary);\n}\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #fff);\n border-top-right-radius: 4px;\n}\n.turn-meta[_ngcontent-%COMP%] {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n margin-bottom: 3px;\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n}\n.turn--user[_ngcontent-%COMP%] .turn-meta[_ngcontent-%COMP%] {\n justify-content: flex-end;\n}\n.muted[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n.typed-tag[_ngcontent-%COMP%] {\n font-size: 9.5px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 1px 5px;\n}\n\n\n.delegation-block[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.live-note[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n margin-left: 22px;\n max-width: 520px;\n font-size: 12px;\n font-style: italic;\n color: var(--mj-text-muted);\n animation: _ngcontent-%COMP%_live-note-in 220ms ease;\n}\n.live-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-top: 3px;\n flex-shrink: 0;\n}\n@keyframes _ngcontent-%COMP%_live-note-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n.thread-divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 10px 0 6px;\n user-select: none;\n}\n.thread-divider__line[_ngcontent-%COMP%] {\n flex: 1;\n height: 1px;\n background: var(--mj-border-subtle);\n}\n.thread-divider__label[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n.thread-divider__label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n.thread-divider__time[_ngcontent-%COMP%] {\n font-weight: 400;\n}\n.thread-divider__chip[_ngcontent-%COMP%] {\n font-size: 9.5px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n padding: 1px 7px;\n background: var(--mj-bg-surface-card);\n white-space: nowrap;\n}"] });
|
|
296
|
+
} }, dependencies: [CommonModule, RealtimeDelegationCardComponent, MarkdownModule, i1.MarkdownComponent, i2.DatePipe], styles: ["[_nghost-%COMP%] {\n display: block;\n}\n\n.thread[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.thread-empty[_ngcontent-%COMP%] {\n text-align: center;\n font-size: 12.5px;\n color: var(--mj-text-disabled);\n padding: 24px 0;\n}\n\n\n.turn[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n max-width: 100%;\n}\n.turn--user[_ngcontent-%COMP%] {\n flex-direction: row-reverse;\n}\n.turn-body[_ngcontent-%COMP%] {\n min-width: 0;\n}\n.turn-avatar[_ngcontent-%COMP%] {\n width: 26px;\n height: 26px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 700;\n margin-top: 2px;\n}\n.turn--agent[_ngcontent-%COMP%] .turn-avatar[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, var(--mj-brand-primary), var(--mj-brand-accent, var(--mj-brand-primary)));\n color: var(--mj-text-inverse, #fff);\n}\n.turn--user[_ngcontent-%COMP%] .turn-avatar[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-strong);\n}\n.bubble[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border-radius: 12px;\n max-width: 560px;\n font-size: 13.5px;\n line-height: 1.5;\n position: relative;\n}\n.turn--agent[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-top-left-radius: 4px;\n color: var(--mj-text-primary);\n}\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #fff);\n border-top-right-radius: 4px;\n}\n\n\n.bubble-content[_ngcontent-%COMP%] {\n position: relative;\n word-break: break-word;\n}\n\n.bubble-content--clamped[_ngcontent-%COMP%] {\n max-height: 120px;\n overflow: hidden;\n -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 60%, rgba(0, 0, 0, 0) 100%);\n mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 60%, rgba(0, 0, 0, 0) 100%);\n}\n\n.bubble-content--expanded[_ngcontent-%COMP%] {\n max-height: 440px;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: rgba(255, 255, 255, 0.4) transparent;\n}\n.turn--agent[_ngcontent-%COMP%] .bubble-content--expanded[_ngcontent-%COMP%] {\n scrollbar-color: var(--mj-border-strong) transparent;\n}\n.bubble-content--expanded[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 5px;\n}\n.bubble-content--expanded[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.35);\n border-radius: 3px;\n}\n.turn--agent[_ngcontent-%COMP%] .bubble-content--expanded[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n}\n\n.bubble-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin-top: 6px;\n padding-top: 2px;\n}\n.turn--user[_ngcontent-%COMP%] .bubble-actions[_ngcontent-%COMP%] {\n justify-content: flex-end;\n}\n\n.bubble-expand-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n font-size: 11.5px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n background: transparent;\n border: none;\n transition: background-color 140ms ease, color 140ms ease;\n user-select: none;\n}\n\n.bubble-expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.turn--agent[_ngcontent-%COMP%] .bubble-expand-btn[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n.turn--agent[_ngcontent-%COMP%] .bubble-expand-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, transparent);\n}\n\n.turn--user[_ngcontent-%COMP%] .bubble-expand-btn[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse, #fff);\n background: rgba(255, 255, 255, 0.18);\n border: 1px solid rgba(255, 255, 255, 0.28);\n}\n.turn--user[_ngcontent-%COMP%] .bubble-expand-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.28);\n}\n\n\n.bubble[_ngcontent-%COMP%] .mj-markdown-container {\n font-size: 13.5px;\n line-height: 1.55;\n}\n\n.bubble[_ngcontent-%COMP%] .mj-markdown-container h1 { font-size: 1.35em; font-weight: 700; margin-top: 0.6em; margin-bottom: 0.3em; }\n.bubble[_ngcontent-%COMP%] .mj-markdown-container h2 { font-size: 1.2em; font-weight: 650; margin-top: 0.5em; margin-bottom: 0.25em; }\n.bubble[_ngcontent-%COMP%] .mj-markdown-container h3 { font-size: 1.1em; font-weight: 600; margin-top: 0.4em; margin-bottom: 0.2em; }\n.bubble[_ngcontent-%COMP%] .mj-markdown-container h4, \n.bubble[_ngcontent-%COMP%] .mj-markdown-container h5, \n.bubble[_ngcontent-%COMP%] .mj-markdown-container h6 { font-size: 1em; font-weight: 600; margin-top: 0.4em; margin-bottom: 0.2em; }\n.bubble[_ngcontent-%COMP%] .mj-markdown-container p { margin: 0 0 0.6em 0; }\n.bubble[_ngcontent-%COMP%] .mj-markdown-container p:last-child { margin-bottom: 0; }\n.bubble[_ngcontent-%COMP%] .mj-markdown-container ul, \n.bubble[_ngcontent-%COMP%] .mj-markdown-container ol { margin: 0.25em 0 0.6em 1.25em; padding: 0; }\n.bubble[_ngcontent-%COMP%] .mj-markdown-container li { margin-bottom: 0.25em; line-height: 1.45; }\n\n\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container p, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container h1, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container h2, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container h3, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container h4, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container h5, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container h6, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container strong, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container b, \n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container li {\n color: var(--mj-text-inverse, #fff);\n}\n\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container li::marker {\n color: var(--mj-text-inverse, #fff);\n}\n\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container a {\n color: #fff;\n text-decoration: underline;\n}\n\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container code {\n color: #fff;\n background: rgba(255, 255, 255, 0.2);\n}\n\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container pre {\n background: rgba(0, 0, 0, 0.25);\n color: #fff;\n}\n\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container blockquote {\n border-left-color: rgba(255, 255, 255, 0.5);\n color: rgba(255, 255, 255, 0.9);\n}\n\n.turn--user[_ngcontent-%COMP%] .bubble[_ngcontent-%COMP%] .mj-markdown-container hr {\n border-color: rgba(255, 255, 255, 0.25);\n margin: 0.6em 0;\n}\n.turn-meta[_ngcontent-%COMP%] {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n margin-bottom: 3px;\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n}\n.turn--user[_ngcontent-%COMP%] .turn-meta[_ngcontent-%COMP%] {\n justify-content: flex-end;\n}\n.muted[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n.typed-tag[_ngcontent-%COMP%] {\n font-size: 9.5px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 1px 5px;\n}\n\n\n.delegation-block[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.live-note[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n margin-left: 22px;\n max-width: 520px;\n font-size: 12px;\n font-style: italic;\n color: var(--mj-text-muted);\n animation: _ngcontent-%COMP%_live-note-in 220ms ease;\n}\n.live-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-top: 3px;\n flex-shrink: 0;\n}\n@keyframes _ngcontent-%COMP%_live-note-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n.thread-divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 10px 0 6px;\n user-select: none;\n}\n.thread-divider__line[_ngcontent-%COMP%] {\n flex: 1;\n height: 1px;\n background: var(--mj-border-subtle);\n}\n.thread-divider__label[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n.thread-divider__label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n.thread-divider__time[_ngcontent-%COMP%] {\n font-weight: 400;\n}\n.thread-divider__chip[_ngcontent-%COMP%] {\n font-size: 9.5px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n padding: 1px 7px;\n background: var(--mj-bg-surface-card);\n white-space: nowrap;\n}"] });
|
|
220
297
|
}
|
|
221
298
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RealtimeSessionThreadComponent, [{
|
|
222
299
|
type: Component,
|
|
223
|
-
args: [{ standalone: true, selector: 'mj-realtime-session-thread', imports: [CommonModule, RealtimeDelegationCardComponent], template: "<div class=\"thread\">\n @for (item of State.Items; track TrackItem($index, item)) {\n @switch (item.Kind) {\n @case ('caption') {\n @if (ShowCaptions) {\n <div class=\"turn\" [class.turn--user]=\"item.Role === 'User'\" [class.turn--agent]=\"item.Role === 'Assistant'\">\n <div class=\"turn-avatar\">{{ (item.Role === 'User' ? UserName : AgentName).charAt(0).toUpperCase() }}</div>\n <div class=\"turn-body\">\n <div class=\"turn-meta\">\n @if (item.Role === 'User') {\n <span class=\"typed-tag\">{{ UserName }}</span>\n } @else {\n {{ AgentName }} <span class=\"muted\">\u00B7 voice</span>\n }\n </div>\n <div class=\"bubble\">{{ item.Text }}</div>\n </div>\n </div>\n }\n }\n @case ('divider') {\n <!-- Session-leg boundary: subtle rule marking a resume / chained leg -->\n <div class=\"thread-divider\" role=\"separator\">\n <span class=\"thread-divider__line\" aria-hidden=\"true\"></span>\n <span class=\"thread-divider__label\">\n <i [class]=\"item.Icon\" aria-hidden=\"true\"></i>\n {{ item.Label }}\n @if (item.At) {\n <span class=\"thread-divider__time\">\u00B7 {{ item.At | date:'MMM d, h:mm a' }}</span>\n }\n </span>\n @if (item.CloseReason) {\n <span class=\"thread-divider__chip\" title=\"Why the previous session leg ended\">{{ item.CloseReason }}</span>\n }\n <span class=\"thread-divider__line\" aria-hidden=\"true\"></span>\n </div>\n }\n @case ('delegation') {\n <div class=\"delegation-block\">\n <mj-realtime-delegation-card\n [Card]=\"item.Card\"\n [DevMode]=\"DevMode\"\n (OpenRunRequested)=\"OpenRunRequested.emit($event)\"\n (OpenArtifactRequested)=\"OpenArtifactRequested.emit($event)\"\n (CancelRequested)=\"CancelRequested.emit($event)\">\n </mj-realtime-delegation-card>\n @if (ShowsLiveNote(item)) {\n <!-- Ephemeral narration: latest only, never persisted, fades with completion -->\n <div class=\"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 </div>\n }\n }\n } @empty {\n <div class=\"thread-empty\">The live transcript and any delegated work will appear here.</div>\n }\n <div #scrollAnchor></div>\n</div>\n", styles: [":host {\n display: block;\n}\n\n.thread {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.thread-empty {\n text-align: center;\n font-size: 12.5px;\n color: var(--mj-text-disabled);\n padding: 24px 0;\n}\n\n/* ---------- Transcript bubbles ---------- */\n.turn {\n display: flex;\n gap: 10px;\n max-width: 100%;\n}\n.turn--user {\n flex-direction: row-reverse;\n}\n.turn-body {\n min-width: 0;\n}\n.turn-avatar {\n width: 26px;\n height: 26px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 700;\n margin-top: 2px;\n}\n.turn--agent .turn-avatar {\n background: linear-gradient(135deg, var(--mj-brand-primary), var(--mj-brand-accent, var(--mj-brand-primary)));\n color: var(--mj-text-inverse, #fff);\n}\n.turn--user .turn-avatar {\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-strong);\n}\n.bubble {\n padding: 8px 12px;\n border-radius: 12px;\n max-width: 560px;\n font-size: 13.5px;\n line-height: 1.5;\n position: relative;\n}\n.turn--agent .bubble {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-top-left-radius: 4px;\n color: var(--mj-text-primary);\n}\n.turn--user .bubble {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #fff);\n border-top-right-radius: 4px;\n}\n.turn-meta {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n margin-bottom: 3px;\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n}\n.turn--user .turn-meta {\n justify-content: flex-end;\n}\n.muted {\n color: var(--mj-text-muted);\n}\n.typed-tag {\n font-size: 9.5px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 1px 5px;\n}\n\n/* ---------- Delegation block + ephemeral live note ---------- */\n.delegation-block {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.live-note {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n margin-left: 22px;\n max-width: 520px;\n font-size: 12px;\n font-style: italic;\n color: var(--mj-text-muted);\n animation: live-note-in 220ms ease;\n}\n.live-note i {\n font-size: 10px;\n margin-top: 3px;\n flex-shrink: 0;\n}\n@keyframes live-note-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* ---------- Session-leg divider (resume / chained-leg boundary) ---------- */\n.thread-divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 10px 0 6px;\n user-select: none;\n}\n.thread-divider__line {\n flex: 1;\n height: 1px;\n background: var(--mj-border-subtle);\n}\n.thread-divider__label {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n.thread-divider__label i {\n font-size: 10px;\n}\n.thread-divider__time {\n font-weight: 400;\n}\n.thread-divider__chip {\n font-size: 9.5px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n padding: 1px 7px;\n background: var(--mj-bg-surface-card);\n white-space: nowrap;\n}\n"] }]
|
|
300
|
+
args: [{ standalone: true, selector: 'mj-realtime-session-thread', imports: [CommonModule, RealtimeDelegationCardComponent, MarkdownModule], template: "<div class=\"thread\">\n @for (item of State.Items; track TrackItem($index, item)) {\n @switch (item.Kind) {\n @case ('caption') {\n @if (ShowCaptions) {\n <div class=\"turn\" [class.turn--user]=\"item.Role === 'User'\" [class.turn--agent]=\"item.Role === 'Assistant'\">\n <div class=\"turn-avatar\">{{ (item.Role === 'User' ? UserName : AgentName).charAt(0).toUpperCase() }}</div>\n <div class=\"turn-body\">\n <div class=\"turn-meta\">\n @if (item.Role === 'User') {\n <span class=\"typed-tag\">{{ UserName }}</span>\n } @else {\n {{ AgentName }} <span class=\"muted\">\u00B7 voice</span>\n }\n </div>\n <div class=\"bubble\" [class.bubble--clamped]=\"IsLongText(item.Text) && !IsExpanded($index)\" [class.bubble--expanded]=\"IsLongText(item.Text) && IsExpanded($index)\">\n <div class=\"bubble-content\" [class.bubble-content--clamped]=\"IsLongText(item.Text) && !IsExpanded($index)\" [class.bubble-content--expanded]=\"IsLongText(item.Text) && IsExpanded($index)\">\n <mj-markdown [data]=\"FormatMarkdownText(item.Text)\" [enableCollapsibleHeadings]=\"true\"></mj-markdown>\n </div>\n @if (IsLongText(item.Text)) {\n <div class=\"bubble-actions\">\n <button\n type=\"button\"\n class=\"bubble-expand-btn\"\n (click)=\"ToggleExpanded($index, $event)\"\n [attr.aria-expanded]=\"IsExpanded($index)\">\n <span>{{ IsExpanded($index) ? 'Show less' : 'Show more' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-up]=\"IsExpanded($index)\" [class.fa-chevron-down]=\"!IsExpanded($index)\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n }\n }\n @case ('divider') {\n <!-- Session-leg boundary: subtle rule marking a resume / chained leg -->\n <div class=\"thread-divider\" role=\"separator\">\n <span class=\"thread-divider__line\" aria-hidden=\"true\"></span>\n <span class=\"thread-divider__label\">\n <i [class]=\"item.Icon\" aria-hidden=\"true\"></i>\n {{ item.Label }}\n @if (item.At) {\n <span class=\"thread-divider__time\">\u00B7 {{ item.At | date:'MMM d, h:mm a' }}</span>\n }\n </span>\n @if (item.CloseReason) {\n <span class=\"thread-divider__chip\" title=\"Why the previous session leg ended\">{{ item.CloseReason }}</span>\n }\n <span class=\"thread-divider__line\" aria-hidden=\"true\"></span>\n </div>\n }\n @case ('delegation') {\n <div class=\"delegation-block\">\n <mj-realtime-delegation-card\n [Card]=\"item.Card\"\n [DevMode]=\"DevMode\"\n (OpenRunRequested)=\"OpenRunRequested.emit($event)\"\n (OpenArtifactRequested)=\"OpenArtifactRequested.emit($event)\"\n (CancelRequested)=\"CancelRequested.emit($event)\">\n </mj-realtime-delegation-card>\n @if (ShowsLiveNote(item)) {\n <!-- Ephemeral narration: latest only, never persisted, fades with completion -->\n <div class=\"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 </div>\n }\n }\n } @empty {\n <div class=\"thread-empty\">The live transcript and any delegated work will appear here.</div>\n }\n <div #scrollAnchor></div>\n</div>\n", styles: [":host {\n display: block;\n}\n\n.thread {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.thread-empty {\n text-align: center;\n font-size: 12.5px;\n color: var(--mj-text-disabled);\n padding: 24px 0;\n}\n\n/* ---------- Transcript bubbles ---------- */\n.turn {\n display: flex;\n gap: 10px;\n max-width: 100%;\n}\n.turn--user {\n flex-direction: row-reverse;\n}\n.turn-body {\n min-width: 0;\n}\n.turn-avatar {\n width: 26px;\n height: 26px;\n border-radius: 50%;\n display: grid;\n place-items: center;\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 700;\n margin-top: 2px;\n}\n.turn--agent .turn-avatar {\n background: linear-gradient(135deg, var(--mj-brand-primary), var(--mj-brand-accent, var(--mj-brand-primary)));\n color: var(--mj-text-inverse, #fff);\n}\n.turn--user .turn-avatar {\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-strong);\n}\n.bubble {\n padding: 8px 12px;\n border-radius: 12px;\n max-width: 560px;\n font-size: 13.5px;\n line-height: 1.5;\n position: relative;\n}\n.turn--agent .bubble {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-top-left-radius: 4px;\n color: var(--mj-text-primary);\n}\n.turn--user .bubble {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #fff);\n border-top-right-radius: 4px;\n}\n\n/* ---------- Bubble content clamping and expansion ---------- */\n.bubble-content {\n position: relative;\n word-break: break-word;\n}\n\n.bubble-content--clamped {\n max-height: 120px;\n overflow: hidden;\n -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 60%, rgba(0, 0, 0, 0) 100%);\n mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 60%, rgba(0, 0, 0, 0) 100%);\n}\n\n.bubble-content--expanded {\n max-height: 440px;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: rgba(255, 255, 255, 0.4) transparent;\n}\n.turn--agent .bubble-content--expanded {\n scrollbar-color: var(--mj-border-strong) transparent;\n}\n.bubble-content--expanded::-webkit-scrollbar {\n width: 5px;\n}\n.bubble-content--expanded::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.35);\n border-radius: 3px;\n}\n.turn--agent .bubble-content--expanded::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n}\n\n.bubble-actions {\n display: flex;\n align-items: center;\n margin-top: 6px;\n padding-top: 2px;\n}\n.turn--user .bubble-actions {\n justify-content: flex-end;\n}\n\n.bubble-expand-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n font-size: 11.5px;\n font-weight: 600;\n border-radius: 6px;\n cursor: pointer;\n background: transparent;\n border: none;\n transition: background-color 140ms ease, color 140ms ease;\n user-select: none;\n}\n\n.bubble-expand-btn i {\n font-size: 10px;\n}\n\n.turn--agent .bubble-expand-btn {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n.turn--agent .bubble-expand-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, transparent);\n}\n\n.turn--user .bubble-expand-btn {\n color: var(--mj-text-inverse, #fff);\n background: rgba(255, 255, 255, 0.18);\n border: 1px solid rgba(255, 255, 255, 0.28);\n}\n.turn--user .bubble-expand-btn:hover {\n background: rgba(255, 255, 255, 0.28);\n}\n\n/* ---------- Markdown styling within realtime bubbles ---------- */\n.bubble ::ng-deep .mj-markdown-container {\n font-size: 13.5px;\n line-height: 1.55;\n}\n\n.bubble ::ng-deep .mj-markdown-container h1 { font-size: 1.35em; font-weight: 700; margin-top: 0.6em; margin-bottom: 0.3em; }\n.bubble ::ng-deep .mj-markdown-container h2 { font-size: 1.2em; font-weight: 650; margin-top: 0.5em; margin-bottom: 0.25em; }\n.bubble ::ng-deep .mj-markdown-container h3 { font-size: 1.1em; font-weight: 600; margin-top: 0.4em; margin-bottom: 0.2em; }\n.bubble ::ng-deep .mj-markdown-container h4,\n.bubble ::ng-deep .mj-markdown-container h5,\n.bubble ::ng-deep .mj-markdown-container h6 { font-size: 1em; font-weight: 600; margin-top: 0.4em; margin-bottom: 0.2em; }\n.bubble ::ng-deep .mj-markdown-container p { margin: 0 0 0.6em 0; }\n.bubble ::ng-deep .mj-markdown-container p:last-child { margin-bottom: 0; }\n.bubble ::ng-deep .mj-markdown-container ul,\n.bubble ::ng-deep .mj-markdown-container ol { margin: 0.25em 0 0.6em 1.25em; padding: 0; }\n.bubble ::ng-deep .mj-markdown-container li { margin-bottom: 0.25em; line-height: 1.45; }\n\n/* User turn contrast: markdown on brand-primary background */\n.turn--user .bubble ::ng-deep .mj-markdown-container,\n.turn--user .bubble ::ng-deep .mj-markdown-container p,\n.turn--user .bubble ::ng-deep .mj-markdown-container h1,\n.turn--user .bubble ::ng-deep .mj-markdown-container h2,\n.turn--user .bubble ::ng-deep .mj-markdown-container h3,\n.turn--user .bubble ::ng-deep .mj-markdown-container h4,\n.turn--user .bubble ::ng-deep .mj-markdown-container h5,\n.turn--user .bubble ::ng-deep .mj-markdown-container h6,\n.turn--user .bubble ::ng-deep .mj-markdown-container strong,\n.turn--user .bubble ::ng-deep .mj-markdown-container b,\n.turn--user .bubble ::ng-deep .mj-markdown-container li {\n color: var(--mj-text-inverse, #fff);\n}\n\n.turn--user .bubble ::ng-deep .mj-markdown-container li::marker {\n color: var(--mj-text-inverse, #fff);\n}\n\n.turn--user .bubble ::ng-deep .mj-markdown-container a {\n color: #fff;\n text-decoration: underline;\n}\n\n.turn--user .bubble ::ng-deep .mj-markdown-container code {\n color: #fff;\n background: rgba(255, 255, 255, 0.2);\n}\n\n.turn--user .bubble ::ng-deep .mj-markdown-container pre {\n background: rgba(0, 0, 0, 0.25);\n color: #fff;\n}\n\n.turn--user .bubble ::ng-deep .mj-markdown-container blockquote {\n border-left-color: rgba(255, 255, 255, 0.5);\n color: rgba(255, 255, 255, 0.9);\n}\n\n.turn--user .bubble ::ng-deep .mj-markdown-container hr {\n border-color: rgba(255, 255, 255, 0.25);\n margin: 0.6em 0;\n}\n.turn-meta {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n margin-bottom: 3px;\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n}\n.turn--user .turn-meta {\n justify-content: flex-end;\n}\n.muted {\n color: var(--mj-text-muted);\n}\n.typed-tag {\n font-size: 9.5px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 1px 5px;\n}\n\n/* ---------- Delegation block + ephemeral live note ---------- */\n.delegation-block {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.live-note {\n display: flex;\n align-items: flex-start;\n gap: 7px;\n margin-left: 22px;\n max-width: 520px;\n font-size: 12px;\n font-style: italic;\n color: var(--mj-text-muted);\n animation: live-note-in 220ms ease;\n}\n.live-note i {\n font-size: 10px;\n margin-top: 3px;\n flex-shrink: 0;\n}\n@keyframes live-note-in {\n from { opacity: 0; transform: translateY(2px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* ---------- Session-leg divider (resume / chained-leg boundary) ---------- */\n.thread-divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 10px 0 6px;\n user-select: none;\n}\n.thread-divider__line {\n flex: 1;\n height: 1px;\n background: var(--mj-border-subtle);\n}\n.thread-divider__label {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n.thread-divider__label i {\n font-size: 10px;\n}\n.thread-divider__time {\n font-weight: 400;\n}\n.thread-divider__chip {\n font-size: 9.5px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n border: 1px solid var(--mj-border-default);\n border-radius: 999px;\n padding: 1px 7px;\n background: var(--mj-bg-surface-card);\n white-space: nowrap;\n}\n"] }]
|
|
224
301
|
}], null, { scrollAnchor: [{
|
|
225
302
|
type: ViewChild,
|
|
226
303
|
args: ['scrollAnchor']
|
|
@@ -242,5 +319,5 @@ export class RealtimeSessionThreadComponent {
|
|
|
242
319
|
}], CancelRequested: [{
|
|
243
320
|
type: Output
|
|
244
321
|
}] }); })();
|
|
245
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RealtimeSessionThreadComponent, { className: "RealtimeSessionThreadComponent", filePath: "src/lib/components/realtime/realtime-session-thread.component.ts", lineNumber:
|
|
322
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RealtimeSessionThreadComponent, { className: "RealtimeSessionThreadComponent", filePath: "src/lib/components/realtime/realtime-session-thread.component.ts", lineNumber: 30 }); })();
|
|
246
323
|
//# sourceMappingURL=realtime-session-thread.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-session-thread.component.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-session-thread.component.ts","../../../../src/lib/components/realtime/realtime-session-thread.component.html"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAc,SAAS,EAC7D,iBAAiB,EAAE,MAAM,EAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;;;;;ICGrE,gCAAwB;IAAA,YAAc;IAAA,iBAAO;;;IAArB,cAAc;IAAd,qCAAc;;;IAEtC,YAAgB;IAAA,gCAAoB;IAAA,4BAAO;IAAA,iBAAO;;;IAAlD,iDAAgB;;;IANtB,AADF,8BAA4G,aACjF;IAAA,YAA2E;IAAA,iBAAM;IAExG,AADF,8BAAuB,aACE;IAGnB,AAFF,6HAA4B,2FAEnB;IAGX,iBAAM;IACN,+BAAoB;IAAA,YAAe;IAEvC,AADE,AADqC,iBAAM,EACrC,EACF;;;;IAZsD,AAA1C,qDAAyC,6CAAgD;IAChF,eAA2E;IAA3E,4GAA2E;IAGhG,eAIC;IAJD,iDAIC;IAEiB,eAAe;IAAf,kCAAe;;;IAXzC,6GAAoB;;;IAApB,8CAcC;;;IAUK,gCAAmC;IAAA,YAAsC;;IAAA,iBAAO;;;IAA7C,cAAsC;IAAtC,mFAAsC;;;IAI3E,gCAA8E;IAAA,YAAsB;IAAA,iBAAO;;;IAA7B,cAAsB;IAAtB,yCAAsB;;;IAVxG,8BAA6C;IAC3C,2BAA6D;IAC7D,gCAAoC;IAClC,wBAA8C;IAC9C,YACA;IAAA,+GAAe;IAGjB,iBAAO;IACP,+GAAwB;IAGxB,2BAA6D;IAC/D,iBAAM;;;IAVC,eAAmB;IAAnB,2BAAmB;IACtB,cACA;IADA,8CACA;IAAA,cAEC;IAFD,qCAEC;IAEH,cAEC;IAFD,8CAEC;;;IAeC,+BAAwD;IACtD,wBAA2D;IAC3D,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,uDACF;;;;IAZF,AADF,8BAA8B,sCAMuB;IAAjD,AADA,AADA,mPAAoB,oCAA6B,KAAC,gPACzB,yCAAkC,KAAC,oOACzC,mCAA4B,KAAC;IAClD,iBAA8B;IAC9B,8GAA2B;IAO7B,iBAAM;;;;IAbF,cAAkB;IAClB,AADA,mCAAkB,2BACC;IAKrB,cAMC;IAND,wDAMC;;;IAfL,AAjBA,AAjBA,qFAAmB,yEAiBA,yEAiBG;;;;IAnCxB,+CAAA,SAAS,oBAAT,SAAS,oBAAT,YAAY,UAqDX;;;IAED,8BAA0B;IAAA,4EAA4D;IAAA,iBAAM;;AD/ChG;;;;;;;;;;GAUG;AAQH,MAAM,OAAO,8BAA8B;IACN,YAAY,CAA2B;IAE1E,8DAA8D;IACrD,SAAS,GAAG,MAAM,CAAC;IAE5B;;;;OAIG;IACM,QAAQ,GAAG,KAAK,CAAC;IAE1B,6DAA6D;IAClC,KAAK,CAAwB;IAExD,oFAAoF;IAC3E,YAAY,GAAG,IAAI,CAAC;IAE7B,mFAAmF;IAC1E,OAAO,GAAG,KAAK,CAAC;IAEzB,wFAAwF;IAC9E,gBAAgB,GAAG,IAAI,YAAY,EAAU,CAAC;IAExD,qGAAqG;IAC3F,qBAAqB,GAAG,IAAI,YAAY,EAA4B,CAAC;IAE/E,uFAAuF;IAC7E,eAAe,GAAG,IAAI,YAAY,EAAU,CAAC;IAEvD,2FAA2F;IACnF,aAAa,GAAG,CAAC,CAAC;IAC1B,uDAAuD;IAC/C,aAAa,GAAG,KAAK,CAAC;IAEtB,UAAU,CAAgB;IAC1B,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAExC,QAAQ;QACN,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;IAC/C,CAAC;IAED,kBAAkB;QAChB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC;IACjC,CAAC;IAED,+CAA+C;IACxC,SAAS,CAAC,KAAa,EAAE,IAAwB;QACtD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,YAAY,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClD,KAAK,SAAS,CAAC,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,kFAAkF;IAC3E,aAAa,CAAC,IAAwB;QAC3C,OAAO,IAAI,CAAC,IAAI,KAAK,YAAY;eAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;eACf,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI;eAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;IACpD,CAAC;IAED,gFAAgF;IACxE,cAAc;QACpB,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YACjD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;wHA/EU,8BAA8B;6DAA9B,8BAA8B;;;;;;YC5B3C,8BAAoB;YAClB,gLAyDC;YACD,+BAAyB;YAC3B,iBAAM;;YA3DJ,cAyDC;YAzDD,8BAyDC;4BDlCS,YAAY,EAAE,+BAA+B;;iFAI5C,8BAA8B;cAP1C,SAAS;6BACI,IAAI,YACN,4BAA4B,WAC7B,CAAC,YAAY,EAAE,+BAA+B,CAAC;;kBAKvD,SAAS;mBAAC,cAAc;;kBAGxB,KAAK;;kBAOL,KAAK;;kBAGL,KAAK;mBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;;kBAGxB,KAAK;;kBAGL,KAAK;;kBAGL,MAAM;;kBAGN,MAAM;;kBAGN,MAAM;;kFA7BI,8BAA8B","sourcesContent":["import {\n Component, EventEmitter, Input, Output, ElementRef, ViewChild, AfterViewChecked, OnInit, OnDestroy,\n ChangeDetectorRef, inject\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs';\nimport { RealtimeSessionState, RealtimeThreadItem } from './realtime-session-state';\nimport { RealtimeDelegationCardComponent } from './realtime-delegation-card.component';\nimport { ParsedDelegationArtifact } from '../../services/delegation-result-parser';\n\n/**\n * The unified, chronological live thread for the call overlay: caption bubbles\n * interleaved with delegation cards exactly where they happened.\n *\n * PURELY PRESENTATIONAL over {@link RealtimeSessionState} — the overlay shell owns the\n * state object (which merges the service streams once) and passes it here AND to the\n * activity rail, so there is exactly one copy of the per-CallID merge logic.\n *\n * Also renders the EPHEMERAL narration \"live note\": indented, muted, italic text under\n * the ACTIVE working card (latest narration only — replaced, never accumulated).\n */\n@Component({\n standalone: true,\n selector: 'mj-realtime-session-thread',\n imports: [CommonModule, RealtimeDelegationCardComponent],\n templateUrl: './realtime-session-thread.component.html',\n styleUrl: './realtime-session-thread.component.css'\n})\nexport class RealtimeSessionThreadComponent implements OnInit, AfterViewChecked, OnDestroy {\n @ViewChild('scrollAnchor') private scrollAnchor?: ElementRef<HTMLElement>;\n\n /** Display name of the agent (caption avatar / meta line). */\n @Input() AgentName = 'Sage';\n\n /**\n * Display name of the signed-in user for their turns — consistent with the main\n * chat's sender names, and ready for multi-user sessions where \"You\" stops meaning\n * anything. Hosts bind the current user's name; the default keeps old hosts working.\n */\n @Input() UserName = 'You';\n\n /** Shared live-session state, owned by the overlay shell. */\n @Input({ required: true }) State!: RealtimeSessionState;\n\n /** Whether to render caption bubbles (toggled by the controls' captions button). */\n @Input() ShowCaptions = true;\n\n /** Whether developer affordances on delegation cards are revealed (gear-gated). */\n @Input() DevMode = false;\n\n /** Re-emitted from a delegation card's dev \"Open run\" link (the delegated run's ID). */\n @Output() OpenRunRequested = new EventEmitter<string>();\n\n /** Re-emitted from a delegation card's \"View\" artifact chip (focuses the artifact's surface tab). */\n @Output() OpenArtifactRequested = new EventEmitter<ParsedDelegationArtifact>();\n\n /** Re-emitted from a WORKING delegation card's ✕ cancel affordance (the call's ID). */\n @Output() CancelRequested = new EventEmitter<string>();\n\n /** Item count at the last change notification, to auto-scroll only when the list grows. */\n private lastItemCount = 0;\n /** Drives auto-scroll: set whenever the list grows. */\n private pendingScroll = false;\n\n private changedSub?: Subscription;\n private cdr = inject(ChangeDetectorRef);\n\n ngOnInit(): void {\n this.changedSub = this.State.Changed$.subscribe(() => this.onStateChanged());\n this.lastItemCount = this.State.Items.length;\n }\n\n ngAfterViewChecked(): void {\n if (this.pendingScroll) {\n this.pendingScroll = false;\n this.scrollAnchor?.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'end' });\n }\n }\n\n ngOnDestroy(): void {\n this.changedSub?.unsubscribe();\n }\n\n /** track fn for the @for over thread items. */\n public TrackItem(index: number, item: RealtimeThreadItem): string {\n switch (item.Kind) {\n case 'delegation': return `d:${item.Card.CallID}`;\n case 'divider': return `s:${index}`;\n default: return `c:${index}`;\n }\n }\n\n /** True when the live narration note should render under THIS delegation item. */\n public ShowsLiveNote(item: RealtimeThreadItem): boolean {\n return item.Kind === 'delegation'\n && !item.Card.Done\n && this.State.Narration !== null\n && item.Card.CallID === this.State.ActiveCallId;\n }\n\n /** Marks for check on every state change; auto-scrolls when the thread grew. */\n private onStateChanged(): void {\n if (this.State.Items.length > this.lastItemCount) {\n this.pendingScroll = true;\n }\n this.lastItemCount = this.State.Items.length;\n this.cdr.markForCheck();\n }\n}\n","<div class=\"thread\">\n @for (item of State.Items; track TrackItem($index, item)) {\n @switch (item.Kind) {\n @case ('caption') {\n @if (ShowCaptions) {\n <div class=\"turn\" [class.turn--user]=\"item.Role === 'User'\" [class.turn--agent]=\"item.Role === 'Assistant'\">\n <div class=\"turn-avatar\">{{ (item.Role === 'User' ? UserName : AgentName).charAt(0).toUpperCase() }}</div>\n <div class=\"turn-body\">\n <div class=\"turn-meta\">\n @if (item.Role === 'User') {\n <span class=\"typed-tag\">{{ UserName }}</span>\n } @else {\n {{ AgentName }} <span class=\"muted\">· voice</span>\n }\n </div>\n <div class=\"bubble\">{{ item.Text }}</div>\n </div>\n </div>\n }\n }\n @case ('divider') {\n <!-- Session-leg boundary: subtle rule marking a resume / chained leg -->\n <div class=\"thread-divider\" role=\"separator\">\n <span class=\"thread-divider__line\" aria-hidden=\"true\"></span>\n <span class=\"thread-divider__label\">\n <i [class]=\"item.Icon\" aria-hidden=\"true\"></i>\n {{ item.Label }}\n @if (item.At) {\n <span class=\"thread-divider__time\">· {{ item.At | date:'MMM d, h:mm a' }}</span>\n }\n </span>\n @if (item.CloseReason) {\n <span class=\"thread-divider__chip\" title=\"Why the previous session leg ended\">{{ item.CloseReason }}</span>\n }\n <span class=\"thread-divider__line\" aria-hidden=\"true\"></span>\n </div>\n }\n @case ('delegation') {\n <div class=\"delegation-block\">\n <mj-realtime-delegation-card\n [Card]=\"item.Card\"\n [DevMode]=\"DevMode\"\n (OpenRunRequested)=\"OpenRunRequested.emit($event)\"\n (OpenArtifactRequested)=\"OpenArtifactRequested.emit($event)\"\n (CancelRequested)=\"CancelRequested.emit($event)\">\n </mj-realtime-delegation-card>\n @if (ShowsLiveNote(item)) {\n <!-- Ephemeral narration: latest only, never persisted, fades with completion -->\n <div class=\"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 </div>\n }\n }\n } @empty {\n <div class=\"thread-empty\">The live transcript and any delegated work will appear here.</div>\n }\n <div #scrollAnchor></div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"realtime-session-thread.component.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-session-thread.component.ts","../../../../src/lib/components/realtime/realtime-session-thread.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component, EventEmitter, Input, Output, ElementRef, ViewChild, AfterViewChecked, OnInit, OnDestroy,\n ChangeDetectorRef, inject\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MarkdownModule } from '@memberjunction/ng-markdown';\nimport { Subscription } from 'rxjs';\nimport { RealtimeSessionState, RealtimeThreadItem } from './realtime-session-state';\nimport { RealtimeDelegationCardComponent } from './realtime-delegation-card.component';\nimport { ParsedDelegationArtifact } from '@memberjunction/realtime-runtime';\n\n/**\n * The unified, chronological live thread for the call overlay: caption bubbles\n * interleaved with delegation cards exactly where they happened.\n *\n * PURELY PRESENTATIONAL over {@link RealtimeSessionState} — the overlay shell owns the\n * state object (which merges the service streams once) and passes it here AND to the\n * activity rail, so there is exactly one copy of the per-CallID merge logic.\n *\n * Also renders the EPHEMERAL narration \"live note\": indented, muted, italic text under\n * the ACTIVE working card (latest narration only — replaced, never accumulated).\n */\n@Component({\n standalone: true,\n selector: 'mj-realtime-session-thread',\n imports: [CommonModule, RealtimeDelegationCardComponent, MarkdownModule],\n templateUrl: './realtime-session-thread.component.html',\n styleUrl: './realtime-session-thread.component.css'\n})\nexport class RealtimeSessionThreadComponent implements OnInit, AfterViewChecked, OnDestroy {\n @ViewChild('scrollAnchor') private scrollAnchor?: ElementRef<HTMLElement>;\n\n /** Display name of the agent (caption avatar / meta line). */\n @Input() AgentName = 'Sage';\n\n /**\n * Display name of the signed-in user for their turns — consistent with the main\n * chat's sender names, and ready for multi-user sessions where \"You\" stops meaning\n * anything. Hosts bind the current user's name; the default keeps old hosts working.\n */\n @Input() UserName = 'You';\n\n /** Shared live-session state, owned by the overlay shell. */\n @Input({ required: true }) State!: RealtimeSessionState;\n\n /** Whether to render caption bubbles (toggled by the controls' captions button). */\n @Input() ShowCaptions = true;\n\n /** Whether developer affordances on delegation cards are revealed (gear-gated). */\n @Input() DevMode = false;\n\n /** Re-emitted from a delegation card's dev \"Open run\" link (the delegated run's ID). */\n @Output() OpenRunRequested = new EventEmitter<string>();\n\n /** Re-emitted from a delegation card's \"View\" artifact chip (focuses the artifact's surface tab). */\n @Output() OpenArtifactRequested = new EventEmitter<ParsedDelegationArtifact>();\n\n /** Re-emitted from a WORKING delegation card's ✕ cancel affordance (the call's ID). */\n @Output() CancelRequested = new EventEmitter<string>();\n\n /** Item count at the last change notification, to auto-scroll only when the list grows. */\n private lastItemCount = 0;\n /** Drives auto-scroll: set whenever the list grows. */\n private pendingScroll = false;\n\n private changedSub?: Subscription;\n private cdr = inject(ChangeDetectorRef, { optional: true });\n\n ngOnInit(): void {\n this.changedSub = this.State.Changed$.subscribe(() => this.onStateChanged());\n this.lastItemCount = this.State.Items.length;\n }\n\n ngAfterViewChecked(): void {\n if (this.pendingScroll) {\n this.pendingScroll = false;\n this.scrollAnchor?.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'end' });\n }\n }\n\n ngOnDestroy(): void {\n this.changedSub?.unsubscribe();\n }\n\n /** track fn for the @for over thread items. */\n public TrackItem(index: number, item: RealtimeThreadItem): string {\n switch (item.Kind) {\n case 'delegation': return `d:${item.Card.CallID}`;\n case 'divider': return `s:${index}`;\n default: return `c:${index}`;\n }\n }\n\n /** True when the live narration note should render under THIS delegation item. */\n public ShowsLiveNote(item: RealtimeThreadItem): boolean {\n return item.Kind === 'delegation'\n && !item.Card.Done\n && this.State.Narration !== null\n && item.Card.CallID === this.State.ActiveCallId;\n }\n\n /** Set of item indices whose long text has been expanded by the user. */\n public ExpandedItems = new Set<number>();\n\n /**\n * Returns true when the caption text is considered a \"long blob\" (>280 chars or >4 lines)\n * that warrants height clamping and an expand/collapse toggle.\n */\n public IsLongText(text: string | null | undefined): boolean {\n if (!text) {\n return false;\n }\n return text.length > 280 || text.split('\\n').length > 4;\n }\n\n /** Returns whether the caption item at the specified index is expanded. */\n public IsExpanded(index: number): boolean {\n return this.ExpandedItems.has(index);\n }\n\n /** Toggles expanded/collapsed state for the caption item at the given index. */\n public ToggleExpanded(index: number, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.ExpandedItems.has(index)) {\n this.ExpandedItems.delete(index);\n } else {\n this.ExpandedItems.add(index);\n }\n this.cdr?.markForCheck();\n }\n\n /**\n * Prepares text for markdown rendering, restoring structure (headings, horizontal rules,\n * bullet items) if newlines were stripped by single-line input paste or speech-to-text.\n */\n public FormatMarkdownText(text: string | null | undefined): string {\n if (!text) {\n return '';\n }\n let cleaned = text;\n // Restore newlines before markdown headings on same line: \"Title ### Heading\" -> \"Title\\n\\n### Heading\"\n cleaned = cleaned.replace(/[ \\t]+(?:—\\s*)?(#{1,6}[ \\t]+)/g, '\\n\\n$1');\n // Restore newlines around horizontal rules on same line: \"Text --- ##\" -> \"Text\\n\\n---\\n\\n##\"\n cleaned = cleaned.replace(/[ \\t]+(?:—\\s*)?(---|___|\\*\\*\\*)[ \\t]*/g, '\\n\\n$1\\n\\n');\n // Restore newlines before bullet items on same line: \"around: - Item 1 - Item 2\" -> \"around:\\n- Item 1\\n- Item 2\"\n cleaned = cleaned.replace(/[ \\t]+-[ \\t]+(?=[A-Za-z0-9\\*])/g, '\\n- ');\n return cleaned;\n }\n\n /** Marks for check on every state change; auto-scrolls when the thread grew. */\n private onStateChanged(): void {\n if (this.State.Items.length > this.lastItemCount) {\n this.pendingScroll = true;\n }\n this.lastItemCount = this.State.Items.length;\n this.cdr?.markForCheck();\n }\n}\n","<div class=\"thread\">\n @for (item of State.Items; track TrackItem($index, item)) {\n @switch (item.Kind) {\n @case ('caption') {\n @if (ShowCaptions) {\n <div class=\"turn\" [class.turn--user]=\"item.Role === 'User'\" [class.turn--agent]=\"item.Role === 'Assistant'\">\n <div class=\"turn-avatar\">{{ (item.Role === 'User' ? UserName : AgentName).charAt(0).toUpperCase() }}</div>\n <div class=\"turn-body\">\n <div class=\"turn-meta\">\n @if (item.Role === 'User') {\n <span class=\"typed-tag\">{{ UserName }}</span>\n } @else {\n {{ AgentName }} <span class=\"muted\">· voice</span>\n }\n </div>\n <div class=\"bubble\" [class.bubble--clamped]=\"IsLongText(item.Text) && !IsExpanded($index)\" [class.bubble--expanded]=\"IsLongText(item.Text) && IsExpanded($index)\">\n <div class=\"bubble-content\" [class.bubble-content--clamped]=\"IsLongText(item.Text) && !IsExpanded($index)\" [class.bubble-content--expanded]=\"IsLongText(item.Text) && IsExpanded($index)\">\n <mj-markdown [data]=\"FormatMarkdownText(item.Text)\" [enableCollapsibleHeadings]=\"true\"></mj-markdown>\n </div>\n @if (IsLongText(item.Text)) {\n <div class=\"bubble-actions\">\n <button\n type=\"button\"\n class=\"bubble-expand-btn\"\n (click)=\"ToggleExpanded($index, $event)\"\n [attr.aria-expanded]=\"IsExpanded($index)\">\n <span>{{ IsExpanded($index) ? 'Show less' : 'Show more' }}</span>\n <i class=\"fa-solid\" [class.fa-chevron-up]=\"IsExpanded($index)\" [class.fa-chevron-down]=\"!IsExpanded($index)\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n </div>\n }\n }\n @case ('divider') {\n <!-- Session-leg boundary: subtle rule marking a resume / chained leg -->\n <div class=\"thread-divider\" role=\"separator\">\n <span class=\"thread-divider__line\" aria-hidden=\"true\"></span>\n <span class=\"thread-divider__label\">\n <i [class]=\"item.Icon\" aria-hidden=\"true\"></i>\n {{ item.Label }}\n @if (item.At) {\n <span class=\"thread-divider__time\">· {{ item.At | date:'MMM d, h:mm a' }}</span>\n }\n </span>\n @if (item.CloseReason) {\n <span class=\"thread-divider__chip\" title=\"Why the previous session leg ended\">{{ item.CloseReason }}</span>\n }\n <span class=\"thread-divider__line\" aria-hidden=\"true\"></span>\n </div>\n }\n @case ('delegation') {\n <div class=\"delegation-block\">\n <mj-realtime-delegation-card\n [Card]=\"item.Card\"\n [DevMode]=\"DevMode\"\n (OpenRunRequested)=\"OpenRunRequested.emit($event)\"\n (OpenArtifactRequested)=\"OpenArtifactRequested.emit($event)\"\n (CancelRequested)=\"CancelRequested.emit($event)\">\n </mj-realtime-delegation-card>\n @if (ShowsLiveNote(item)) {\n <!-- Ephemeral narration: latest only, never persisted, fades with completion -->\n <div class=\"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 </div>\n }\n }\n } @empty {\n <div class=\"thread-empty\">The live transcript and any delegated work will appear here.</div>\n }\n <div #scrollAnchor></div>\n</div>\n"]}
|
|
@@ -29,13 +29,7 @@ export declare class RealtimeSessionTimelineCardComponent {
|
|
|
29
29
|
get Title(): string;
|
|
30
30
|
/** Whether the start and end fall on the same calendar day (drives the end-time format). */
|
|
31
31
|
get SameDayRange(): boolean;
|
|
32
|
-
/**
|
|
33
|
-
* The status chip label, or null to hide the chip entirely:
|
|
34
|
-
* - Closed sessions show the close reason (`Error` / `Explicit` / `Janitor` / `Shutdown`)
|
|
35
|
-
* humanized, falling back to "Closed" for legacy rows without one;
|
|
36
|
-
* - Active sessions show "Live"; Idle shows "Idle";
|
|
37
|
-
* - no meta (lookup unavailable) → no chip.
|
|
38
|
-
*/
|
|
32
|
+
/** The status chip label, or null to hide the chip entirely. */
|
|
39
33
|
get StatusChip(): string | null;
|
|
40
34
|
/** Whether the chip represents an error close (drives the error chip styling). */
|
|
41
35
|
get IsErrorChip(): boolean;
|
|
@@ -43,8 +37,6 @@ export declare class RealtimeSessionTimelineCardComponent {
|
|
|
43
37
|
get IsLiveChip(): boolean;
|
|
44
38
|
/** Emits {@link OpenRequested} for the whole-card / Open-button click. */
|
|
45
39
|
Open(event?: MouseEvent): void;
|
|
46
|
-
/** Human label for the session's close reason ("Closed" when the column is null/unknown). */
|
|
47
|
-
private closeReasonLabel;
|
|
48
40
|
static ɵfac: i0.ɵɵFactoryDeclaration<RealtimeSessionTimelineCardComponent, never>;
|
|
49
41
|
static ɵcmp: i0.ɵɵComponentDeclaration<RealtimeSessionTimelineCardComponent, "mj-realtime-session-timeline-card", never, { "Group": { "alias": "Group"; "required": true; }; "Meta": { "alias": "Meta"; "required": false; }; "UserName": { "alias": "UserName"; "required": false; }; }, { "OpenRequested": "OpenRequested"; }, never, never, true, never>;
|
|
50
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-session-timeline-card.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-session-timeline-card.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAiB,MAAM,eAAe,CAAC;AAEvE,OAAO,
|
|
1
|
+
{"version":3,"file":"realtime-session-timeline-card.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-session-timeline-card.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAiB,MAAM,eAAe,CAAC;AAEvE,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAI5B,MAAM,uCAAuC,CAAC;;AAE/C;;;;;;;;;;;;;;GAcG;AACH,qBAOa,oCAAoC;IAC/C,wFAAwF;IAC7D,KAAK,EAAG,4BAA4B,CAAC;IAEhE,sGAAsG;IAC7F,IAAI,EAAE,2BAA2B,GAAG,IAAI,CAAQ;IAEzD,sGAAsG;IAC7F,QAAQ,SAAS;IAE1B,iGAAiG;IACvF,aAAa,uBAA8B;IAQrD,qGAAqG;IACrG,IAAW,KAAK,IAAI,MAAM,CAEzB;IAED,4FAA4F;IAC5F,IAAW,YAAY,IAAI,OAAO,CAEjC;IAED,gEAAgE;IAChE,IAAW,UAAU,IAAI,MAAM,GAAG,IAAI,CAErC;IAED,kFAAkF;IAClF,IAAW,WAAW,IAAI,OAAO,CAEhC;IAED,iFAAiF;IACjF,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,0EAA0E;IACnE,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI;yCA7C1B,oCAAoC;2CAApC,oCAAoC;CAqDhD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
2
|
import { DatePipe } from '@angular/common';
|
|
3
|
+
import { SessionCardIsSameDayRange, SessionCardStatusChip, SessionCardTitle } from '../../utils/realtime-session-timeline';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
function RealtimeSessionTimelineCardComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
5
6
|
i0.ɵɵdomElementStart(0, "span", 12);
|
|
@@ -73,46 +74,30 @@ export class RealtimeSessionTimelineCardComponent {
|
|
|
73
74
|
UserName = 'You';
|
|
74
75
|
/** Emitted with the `MJ: AI Agent Sessions.ID` when the user asks to open the session review. */
|
|
75
76
|
OpenRequested = new EventEmitter();
|
|
77
|
+
/*
|
|
78
|
+
* Title / chip / range derivations live in `@memberjunction/conversations-runtime` alongside the
|
|
79
|
+
* grouping pass, because the React Native thread renders the same card and must not re-decide
|
|
80
|
+
* what "Timed out" means. These getters are the Angular binding surface over them, nothing more.
|
|
81
|
+
*/
|
|
76
82
|
/** Card title: "Realtime session · <agent>" when the agent name is known, else the generic label. */
|
|
77
83
|
get Title() {
|
|
78
|
-
|
|
79
|
-
return agent ? `Realtime session · ${agent}` : 'Realtime session';
|
|
84
|
+
return SessionCardTitle(this.Meta);
|
|
80
85
|
}
|
|
81
86
|
/** Whether the start and end fall on the same calendar day (drives the end-time format). */
|
|
82
87
|
get SameDayRange() {
|
|
83
|
-
|
|
84
|
-
const end = this.Group?.EndedAt;
|
|
85
|
-
if (!start || !end) {
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
return start.toDateString() === end.toDateString();
|
|
88
|
+
return SessionCardIsSameDayRange(this.Group);
|
|
89
89
|
}
|
|
90
|
-
/**
|
|
91
|
-
* The status chip label, or null to hide the chip entirely:
|
|
92
|
-
* - Closed sessions show the close reason (`Error` / `Explicit` / `Janitor` / `Shutdown`)
|
|
93
|
-
* humanized, falling back to "Closed" for legacy rows without one;
|
|
94
|
-
* - Active sessions show "Live"; Idle shows "Idle";
|
|
95
|
-
* - no meta (lookup unavailable) → no chip.
|
|
96
|
-
*/
|
|
90
|
+
/** The status chip label, or null to hide the chip entirely. */
|
|
97
91
|
get StatusChip() {
|
|
98
|
-
|
|
99
|
-
case 'Closed':
|
|
100
|
-
return this.closeReasonLabel();
|
|
101
|
-
case 'Active':
|
|
102
|
-
return 'Live';
|
|
103
|
-
case 'Idle':
|
|
104
|
-
return 'Idle';
|
|
105
|
-
default:
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
92
|
+
return SessionCardStatusChip(this.Meta)?.Label ?? null;
|
|
108
93
|
}
|
|
109
94
|
/** Whether the chip represents an error close (drives the error chip styling). */
|
|
110
95
|
get IsErrorChip() {
|
|
111
|
-
return this.Meta?.
|
|
96
|
+
return SessionCardStatusChip(this.Meta)?.Tone === 'error';
|
|
112
97
|
}
|
|
113
98
|
/** Whether the chip represents a live session (drives the live chip styling). */
|
|
114
99
|
get IsLiveChip() {
|
|
115
|
-
return this.Meta?.
|
|
100
|
+
return SessionCardStatusChip(this.Meta)?.Tone === 'live';
|
|
116
101
|
}
|
|
117
102
|
/** Emits {@link OpenRequested} for the whole-card / Open-button click. */
|
|
118
103
|
Open(event) {
|
|
@@ -122,21 +107,6 @@ export class RealtimeSessionTimelineCardComponent {
|
|
|
122
107
|
this.OpenRequested.emit(sessionId);
|
|
123
108
|
}
|
|
124
109
|
}
|
|
125
|
-
/** Human label for the session's close reason ("Closed" when the column is null/unknown). */
|
|
126
|
-
closeReasonLabel() {
|
|
127
|
-
switch (this.Meta?.CloseReason) {
|
|
128
|
-
case 'Explicit':
|
|
129
|
-
return 'Ended';
|
|
130
|
-
case 'Error':
|
|
131
|
-
return 'Error';
|
|
132
|
-
case 'Janitor':
|
|
133
|
-
return 'Timed out';
|
|
134
|
-
case 'Shutdown':
|
|
135
|
-
return 'Server shutdown';
|
|
136
|
-
default:
|
|
137
|
-
return 'Closed';
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
110
|
static ɵfac = function RealtimeSessionTimelineCardComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RealtimeSessionTimelineCardComponent)(); };
|
|
141
111
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RealtimeSessionTimelineCardComponent, selectors: [["mj-realtime-session-timeline-card"]], inputs: { Group: "Group", Meta: "Meta", UserName: "UserName" }, outputs: { OpenRequested: "OpenRequested" }, decls: 17, vars: 7, consts: [["role", "group", 1, "session-card", 3, "click"], ["aria-hidden", "true", 1, "session-card__icon"], [1, "fa-solid", "fa-tower-broadcast"], [1, "session-card__body"], [1, "session-card__head"], [1, "session-card__title"], [1, "session-card__chip", 3, "session-card__chip--error", "session-card__chip--live"], [1, "session-card__meta"], [1, "session-card__turns"], [1, "session-card__preview"], ["type", "button", "title", "Open this realtime session in review mode", 1, "session-card__open", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-up-right-from-square"], [1, "session-card__chip"], [1, "session-card__range"], ["aria-hidden", "true", 1, "session-card__dot"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-right-long", "session-card__range-arrow"], [1, "session-card__preview-role"]], template: function RealtimeSessionTimelineCardComponent_Template(rf, ctx) { if (rf & 1) {
|
|
142
112
|
i0.ɵɵdomElementStart(0, "div", 0);
|
|
@@ -189,5 +159,5 @@ export class RealtimeSessionTimelineCardComponent {
|
|
|
189
159
|
}], OpenRequested: [{
|
|
190
160
|
type: Output
|
|
191
161
|
}] }); })();
|
|
192
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RealtimeSessionTimelineCardComponent, { className: "RealtimeSessionTimelineCardComponent", filePath: "src/lib/components/realtime/realtime-session-timeline-card.component.ts", lineNumber:
|
|
162
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RealtimeSessionTimelineCardComponent, { className: "RealtimeSessionTimelineCardComponent", filePath: "src/lib/components/realtime/realtime-session-timeline-card.component.ts", lineNumber: 33 }); })();
|
|
193
163
|
//# sourceMappingURL=realtime-session-timeline-card.component.js.map
|