@memberjunction/ng-conversations 6.1.0-edge.2 → 6.1.0-edge.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +180 -4
- package/README.md +32 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +159 -9
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +497 -106
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.d.ts +14 -2
- package/dist/lib/components/conversation/pinned-messages-panel.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.js +37 -19
- package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +7 -3
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +78 -159
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +287 -7
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +850 -56
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +98 -16
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +218 -69
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.d.ts +206 -0
- package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -0
- package/dist/lib/services/conversation-detail-window.store.js +503 -0
- package/dist/lib/services/conversation-detail-window.store.js.map +1 -0
- package/dist/lib/services/search.service.d.ts +10 -4
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +16 -11
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/lib/utils/agent-artifact-summary.d.ts +54 -0
- package/dist/lib/utils/agent-artifact-summary.d.ts.map +1 -0
- package/dist/lib/utils/agent-artifact-summary.js +49 -0
- package/dist/lib/utils/agent-artifact-summary.js.map +1 -0
- package/dist/lib/utils/conversation-detail-window.d.ts +49 -0
- package/dist/lib/utils/conversation-detail-window.d.ts.map +1 -0
- package/dist/lib/utils/conversation-detail-window.js +86 -0
- package/dist/lib/utils/conversation-detail-window.js.map +1 -0
- package/dist/lib/utils/date-jump.d.ts +65 -0
- package/dist/lib/utils/date-jump.d.ts.map +1 -0
- package/dist/lib/utils/date-jump.js +106 -0
- package/dist/lib/utils/date-jump.js.map +1 -0
- package/package.json +32 -32
|
@@ -7,14 +7,11 @@ import { BeforeResponseFormSubmittedEventArgs, AfterResponseFormSubmittedEventAr
|
|
|
7
7
|
import { LazyArtifactInfo } from '../../models/lazy-artifact-info';
|
|
8
8
|
import { RealtimeSessionTimelineMeta } from '../../utils/realtime-session-timeline';
|
|
9
9
|
import { MJAIAgentRunEntityExtended } from '@memberjunction/ai-core-plus';
|
|
10
|
+
import { type DateJumpPeriod, type DateJumpOutcome } from '../../utils/date-jump';
|
|
10
11
|
import * as i0 from "@angular/core";
|
|
11
|
-
/**
|
|
12
|
-
* Container component for displaying a list of messages
|
|
13
|
-
* Uses dynamic component creation (like skip-chat) to avoid Angular binding overhead
|
|
14
|
-
* This dramatically improves performance when messages are added/removed
|
|
15
|
-
*/
|
|
16
12
|
export declare class MessageListComponent extends BaseAngularComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit, AfterViewChecked {
|
|
17
13
|
private cdRef;
|
|
14
|
+
private hostRef;
|
|
18
15
|
messages: MJConversationDetailEntity[];
|
|
19
16
|
conversation: MJConversationEntity | null;
|
|
20
17
|
currentUser: UserInfo;
|
|
@@ -29,6 +26,49 @@ export declare class MessageListComponent extends BaseAngularComponent implement
|
|
|
29
26
|
allowPinning: boolean;
|
|
30
27
|
allowMessageEdit: boolean;
|
|
31
28
|
allowMessageDelete: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* True when older pages remain above the loaded window.
|
|
31
|
+
*
|
|
32
|
+
* Setter rather than a plain input: flipping this creates or destroys the sentinel via
|
|
33
|
+
* `@if`, and the observer has to be re-pointed at the new element. Relying on an ambient
|
|
34
|
+
* `ngAfterViewChecked` tick to notice is fragile — once the list settles there may not be
|
|
35
|
+
* another one.
|
|
36
|
+
*/
|
|
37
|
+
set HasMoreAbove(value: boolean);
|
|
38
|
+
get HasMoreAbove(): boolean;
|
|
39
|
+
private _hasMoreAbove;
|
|
40
|
+
/** True while an older page is in flight. */
|
|
41
|
+
IsLoadingOlder: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The host's scrolling element, used as the sentinel observer's root.
|
|
44
|
+
*
|
|
45
|
+
* This component's own container does NOT scroll — hosts wrap it in their own scroller
|
|
46
|
+
* (in the chat area, `.chat-messages-container`, which carries the `min-height: 0` a flex
|
|
47
|
+
* child needs). Passing it in is deterministic; discovering it by walking the DOM depends
|
|
48
|
+
* on layout having settled, which is not knowable from in here.
|
|
49
|
+
*
|
|
50
|
+
* Optional: when omitted the component falls back to walking its ancestors.
|
|
51
|
+
*/
|
|
52
|
+
set ScrollRoot(value: HTMLElement | null | undefined);
|
|
53
|
+
get ScrollRoot(): HTMLElement | null;
|
|
54
|
+
private _scrollRoot;
|
|
55
|
+
/**
|
|
56
|
+
* Marks the host as "someone else owns the scrolling", which drops `overflow-y` on this
|
|
57
|
+
* component's own container.
|
|
58
|
+
*
|
|
59
|
+
* `position: sticky` pins to the nearest ancestor with `overflow-y: auto|scroll`. When a
|
|
60
|
+
* host supplies a scroller, this component's container still declared `overflow-y: auto`
|
|
61
|
+
* but never actually scrolled (its content grows to fit), so the sticky date header bound
|
|
62
|
+
* to a container whose `scrollTop` is permanently 0 — it rendered, then rode out of view
|
|
63
|
+
* with the messages and could not be clicked.
|
|
64
|
+
*
|
|
65
|
+
* Driven off `_scrollRoot` rather than `resolveScrollParent()` on purpose: the DOM walk is
|
|
66
|
+
* lazy and layout-dependent, and dropping `overflow-y` for a consumer that turned out to
|
|
67
|
+
* have NO scrolling ancestor would leave the transcript unable to scroll or page at all.
|
|
68
|
+
* The explicit input is the only signal that is safe here — a host that passes it has, by
|
|
69
|
+
* definition, a scroller of its own.
|
|
70
|
+
*/
|
|
71
|
+
get HostSuppliesScroller(): boolean;
|
|
32
72
|
/** Display name shown on AI messages. Null = the engine-resolved agent name. */
|
|
33
73
|
set assistantDisplayName(value: string | null);
|
|
34
74
|
get assistantDisplayName(): string | null;
|
|
@@ -100,8 +140,23 @@ export declare class MessageListComponent extends BaseAngularComponent implement
|
|
|
100
140
|
beforeResponseFormSubmitted: EventEmitter<BeforeResponseFormSubmittedEventArgs>;
|
|
101
141
|
/** Forwarded from MessageItemComponent — see its docs. */
|
|
102
142
|
afterResponseFormSubmitted: EventEmitter<AfterResponseFormSubmittedEventArgs>;
|
|
143
|
+
/**
|
|
144
|
+
* Asks the host to load the next older page. Fired when the "earlier messages"
|
|
145
|
+
* sentinel scrolls into view — never on a raw scroll event, so a fast scroll costs
|
|
146
|
+
* one emit rather than one per pixel.
|
|
147
|
+
*/
|
|
148
|
+
OlderRequested: EventEmitter<void>;
|
|
149
|
+
/**
|
|
150
|
+
* Asks the host to page older history far enough back to satisfy a date jump, then scroll.
|
|
151
|
+
* Emitted instead of handled locally because paging belongs to the window store.
|
|
152
|
+
*/
|
|
153
|
+
DateJumpRequested: EventEmitter<DateJumpPeriod>;
|
|
103
154
|
messageContainerRef: ViewContainerRef;
|
|
104
155
|
scrollContainer: ElementRef;
|
|
156
|
+
/** Only present while `HasMoreAbove` is true — the `@if` creates and destroys it. */
|
|
157
|
+
olderSentinel?: ElementRef<HTMLElement>;
|
|
158
|
+
/** Template rendered in place of an unmounted timeline item. */
|
|
159
|
+
private spacerTemplate?;
|
|
105
160
|
/**
|
|
106
161
|
* Per-message rendered entries — see `RenderedMessageEntry` for the 3-way
|
|
107
162
|
* union (default MessageItemComponent / consumer messageRenderer slot
|
|
@@ -110,12 +165,113 @@ export declare class MessageListComponent extends BaseAngularComponent implement
|
|
|
110
165
|
private _renderedMessages;
|
|
111
166
|
private _shouldScrollToBottom;
|
|
112
167
|
private _previousMessageCount;
|
|
168
|
+
/** Watches the "earlier messages" sentinel. Rebuilt whenever the sentinel comes or goes. */
|
|
169
|
+
private _olderObserver?;
|
|
170
|
+
/**
|
|
171
|
+
* Set when the newest render PREPENDED older content, so `ngAfterViewChecked` can hold
|
|
172
|
+
* the user's reading position instead of letting the browser's pixel-based `scrollTop`
|
|
173
|
+
* slide them to unfamiliar content.
|
|
174
|
+
*/
|
|
175
|
+
private _restoreScrollAfterPrepend;
|
|
176
|
+
/** `scrollHeight` captured immediately before a prepend render. */
|
|
177
|
+
private _heightBeforePrepend;
|
|
178
|
+
/** Memoized result of {@link resolveScrollParent} — the host's scroller, not ours. */
|
|
179
|
+
private _scrollParent;
|
|
180
|
+
/** What the live observer is currently watching, so a stale pairing can be detected. */
|
|
181
|
+
private _observedSentinel;
|
|
182
|
+
private _observedRoot;
|
|
183
|
+
/** Guards the no-scroll-parent warning so it fires once, not every checked cycle. */
|
|
184
|
+
private _warnedNoScrollParent;
|
|
185
|
+
/** Guards the missing-spacer-template warning the same way. */
|
|
186
|
+
private _warnedNoSpacerTemplate;
|
|
187
|
+
/** Rendered pixel height per timeline key, captured just before an item is unmounted. */
|
|
188
|
+
private _measuredHeights;
|
|
189
|
+
/** Watches spacers so an item remounts as the user scrolls back toward it. */
|
|
190
|
+
private _spacerObserver?;
|
|
191
|
+
/** Which spacers the live observer is watching, so it is only rebuilt when the set changes. */
|
|
192
|
+
private _observedSpacerKeys;
|
|
193
|
+
/** Scroller the window listener is attached to, and its coalescing frame handle. */
|
|
194
|
+
private _scrollListenerTarget;
|
|
195
|
+
private _onScroll;
|
|
196
|
+
private _scrollFrame;
|
|
197
|
+
/** Items kept mounted beyond the visible page, above and below. */
|
|
198
|
+
private static readonly MOUNT_BUFFER;
|
|
199
|
+
/**
|
|
200
|
+
* Height used for an item unmounted before it was ever measured. Only a first-render
|
|
201
|
+
* fallback — a real measurement replaces it and is preferred forever after.
|
|
202
|
+
*/
|
|
203
|
+
private static readonly ESTIMATED_MESSAGE_HEIGHT;
|
|
204
|
+
private static readonly ESTIMATED_SESSION_HEIGHT;
|
|
205
|
+
/** Frames spent waiting for a scroller to appear, and the pending rAF handle. */
|
|
206
|
+
private _scrollParentRetries;
|
|
207
|
+
private _scrollParentRetryHandle;
|
|
208
|
+
/** ~1s at 60fps — long enough for layout to settle, short enough to report a real fault. */
|
|
209
|
+
private static readonly MAX_SCROLL_PARENT_RETRIES;
|
|
210
|
+
/**
|
|
211
|
+
* Render key of the FIRST timeline item last time we rendered. A change here means older
|
|
212
|
+
* content arrived at the head — the only reliable way to tell a prepend from an append,
|
|
213
|
+
* since both grow `messages.length`.
|
|
214
|
+
*/
|
|
215
|
+
private _previousFirstKey;
|
|
113
216
|
currentDateDisplay: string;
|
|
114
217
|
showDateNav: boolean;
|
|
115
218
|
shouldShowDateFilter: boolean;
|
|
116
|
-
constructor(cdRef: ChangeDetectorRef);
|
|
219
|
+
constructor(cdRef: ChangeDetectorRef, hostRef: ElementRef<HTMLElement>);
|
|
117
220
|
toggleDateNav(): void;
|
|
221
|
+
/**
|
|
222
|
+
* Handles a date-navigator selection.
|
|
223
|
+
*
|
|
224
|
+
* The list cannot page history itself — it is a Generic widget with no store — so it asks
|
|
225
|
+
* the host, which owns the window and runs the older-page loop, then calls back into
|
|
226
|
+
* {@link ScrollToDateTarget}. The label updates immediately so the dropdown feels responsive
|
|
227
|
+
* while paging runs.
|
|
228
|
+
*/
|
|
118
229
|
jumpToDate(period: string): void;
|
|
230
|
+
/**
|
|
231
|
+
* Scrolls to the start of `period` within the currently loaded messages.
|
|
232
|
+
*
|
|
233
|
+
* Called by the host AFTER it has paged as far back as it intends to, so whatever is loaded
|
|
234
|
+
* now is the best answer available. Returns the outcome rather than failing silently — the
|
|
235
|
+
* plan's explicit requirement for this path.
|
|
236
|
+
*/
|
|
237
|
+
ScrollToDateTarget(period: DateJumpPeriod): DateJumpOutcome;
|
|
238
|
+
/**
|
|
239
|
+
* Scrolls a loaded detail into view, mounted or not.
|
|
240
|
+
*
|
|
241
|
+
* Resolves through the TIMELINE KEY rather than querying `[data-message-id]`, because the
|
|
242
|
+
* jump target is by definition far above the viewport — exactly the region this component
|
|
243
|
+
* unmounts and replaces with height-holding spacers. A DOM query for the message id misses
|
|
244
|
+
* every unmounted target, which made a legitimate jump report "nothing loaded to jump to".
|
|
245
|
+
*
|
|
246
|
+
* Spacers carry the same timeline key as the item they stand in for, so scrolling to the
|
|
247
|
+
* key lands on the right place either way; the spacer observer then remounts the real item
|
|
248
|
+
* as it enters the viewport.
|
|
249
|
+
*/
|
|
250
|
+
private scrollToDetail;
|
|
251
|
+
/**
|
|
252
|
+
* Scrolls a LOADED message into view by id, mounted or not, and returns whether it landed.
|
|
253
|
+
*
|
|
254
|
+
* Public because the pins panel's "Jump to message" lives on the host: a pin can be far
|
|
255
|
+
* above the viewport, which is exactly the region this component unmounts into spacers, so
|
|
256
|
+
* the host's own `[data-message-id]` query found nothing and the button silently did
|
|
257
|
+
* nothing. Resolution goes through the timeline key instead — see
|
|
258
|
+
* {@link scrollToTimelineEntry}.
|
|
259
|
+
*
|
|
260
|
+
* Returns false when the message is not in the loaded window at all; the host decides
|
|
261
|
+
* whether to page back for it or tell the user.
|
|
262
|
+
*/
|
|
263
|
+
ScrollToMessage(messageId: string): boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Shared resolution for both jump paths: timeline key -> rendered node.
|
|
266
|
+
*
|
|
267
|
+
* Two things a `[data-message-id]` query cannot do, and both matter here:
|
|
268
|
+
* - A session-stamped row folds into its session CARD, so the row itself never has a
|
|
269
|
+
* node of its own; the card is what is on screen.
|
|
270
|
+
* - An item far from the viewport is unmounted and replaced by a height-holding spacer,
|
|
271
|
+
* which carries the SAME timeline key — so scrolling to the key lands in the right
|
|
272
|
+
* place either way, and the spacer observer remounts the real item on arrival.
|
|
273
|
+
*/
|
|
274
|
+
private scrollToTimelineEntry;
|
|
119
275
|
private _initialRenderComplete;
|
|
120
276
|
ngOnInit(): void;
|
|
121
277
|
ngAfterViewInit(): void;
|
|
@@ -131,6 +287,69 @@ export declare class MessageListComponent extends BaseAngularComponent implement
|
|
|
131
287
|
*/
|
|
132
288
|
private restampAssistantIdentity;
|
|
133
289
|
ngAfterViewChecked(): void;
|
|
290
|
+
/** The rendered sentinel, read from the DOM so it does not depend on view-query timing. */
|
|
291
|
+
private findSentinelElement;
|
|
292
|
+
/**
|
|
293
|
+
* Whether this instance is actually on screen.
|
|
294
|
+
*
|
|
295
|
+
* `offsetParent` is null for any element in a `display: none` subtree — which is how the
|
|
296
|
+
* chat area parks the message lists of conversations you are not currently looking at.
|
|
297
|
+
*/
|
|
298
|
+
private isHostVisible;
|
|
299
|
+
/**
|
|
300
|
+
* Retries {@link syncOlderObserver} on animation frames until a scroller appears.
|
|
301
|
+
*
|
|
302
|
+
* Bounded: after {@link MAX_SCROLL_PARENT_RETRIES} frames it gives up and logs the DOM
|
|
303
|
+
* chain it walked, so a genuine host-layout problem names itself instead of presenting
|
|
304
|
+
* as "paging silently doesn't work".
|
|
305
|
+
*/
|
|
306
|
+
private scheduleScrollParentRetry;
|
|
307
|
+
/** One-time diagnostic dump of the ancestor chain, so the failure is self-explaining. */
|
|
308
|
+
private warnNoScrollParentOnce;
|
|
309
|
+
/**
|
|
310
|
+
* The element that ACTUALLY scrolls the transcript.
|
|
311
|
+
*
|
|
312
|
+
* This component's own `.message-list-container` does not scroll: the chat area wraps it
|
|
313
|
+
* in `.chat-messages-container`, and that outer div is the one carrying `min-height: 0`
|
|
314
|
+
* alongside `overflow-y: auto` — the pair a flex child needs before it will scroll instead
|
|
315
|
+
* of growing to fit its content. Targeting the inner div means writing `scrollTop` on an
|
|
316
|
+
* element whose `scrollHeight === clientHeight`, which silently does nothing, and giving
|
|
317
|
+
* an IntersectionObserver a root that never scrolls.
|
|
318
|
+
*
|
|
319
|
+
* Walking up keeps this component agnostic about the host's markup — any consumer that
|
|
320
|
+
* wraps it in its own scroller works the same way.
|
|
321
|
+
*/
|
|
322
|
+
private resolveScrollParent;
|
|
323
|
+
/**
|
|
324
|
+
* Holds the user's reading position after older content is spliced in above.
|
|
325
|
+
*
|
|
326
|
+
* `scrollTop` is a pixel offset from the top, so inserting content above silently shifts
|
|
327
|
+
* everything down — the user ends up looking at messages they never scrolled to. Adding
|
|
328
|
+
* the height delta puts the same message back under their eyes.
|
|
329
|
+
*/
|
|
330
|
+
private restoreScrollAfterPrepend;
|
|
331
|
+
/**
|
|
332
|
+
* True when the environment provides `IntersectionObserver`.
|
|
333
|
+
*
|
|
334
|
+
* False under SSR and in the unit-test projects. Both observer syncs are reached a
|
|
335
|
+
* microtask late (see the `HasMoreAbove` setter), so a spec that stubs the global and
|
|
336
|
+
* restores it synchronously has already restored it by the time the sync runs — the
|
|
337
|
+
* constructor call then throws inside a `.then()` with no catch, which surfaces as an
|
|
338
|
+
* unhandled rejection rather than a test failure and fails the run despite every
|
|
339
|
+
* assertion passing.
|
|
340
|
+
*/
|
|
341
|
+
private get canObserve();
|
|
342
|
+
/**
|
|
343
|
+
* Keeps the IntersectionObserver attached to the current sentinel element.
|
|
344
|
+
*
|
|
345
|
+
* The sentinel lives inside `@if (HasMoreAbove)`, so it is created and destroyed as the
|
|
346
|
+
* user reaches the top of the loaded window and as older pages arrive. Runs every checked
|
|
347
|
+
* cycle and is a no-op once attached.
|
|
348
|
+
*
|
|
349
|
+
* Observer-on-sentinel rather than a scroll listener: a fast scroll costs one callback,
|
|
350
|
+
* not one per frame.
|
|
351
|
+
*/
|
|
352
|
+
private syncOlderObserver;
|
|
134
353
|
ngOnDestroy(): void;
|
|
135
354
|
/**
|
|
136
355
|
* Called when messages array changes
|
|
@@ -148,6 +367,67 @@ export declare class MessageListComponent extends BaseAngularComponent implement
|
|
|
148
367
|
* chronological position. Everything else renders exactly as before.
|
|
149
368
|
*/
|
|
150
369
|
private updateMessages;
|
|
370
|
+
/**
|
|
371
|
+
* The span of timeline indices that stay mounted.
|
|
372
|
+
*
|
|
373
|
+
* Follows the tail on first paint and whenever nothing measurable is on screen. Once items
|
|
374
|
+
* are rendered, the span is centred on what the reader is actually looking at — measured
|
|
375
|
+
* from scroll position, plus {@link MessageListComponent.MOUNT_BUFFER} either side — so
|
|
376
|
+
* scrolling back does not collapse the window to the newest messages on the next render.
|
|
377
|
+
*
|
|
378
|
+
* (An earlier design pinned the top of the span with a remembered key instead. It was
|
|
379
|
+
* replaced by the measurement below for the reason that comment explains, and the key no
|
|
380
|
+
* longer exists.)
|
|
381
|
+
*/
|
|
382
|
+
private computeMountedRange;
|
|
383
|
+
/** The rendered DOM node for a timeline key, whatever kind of entry backs it. */
|
|
384
|
+
private nodeForKey;
|
|
385
|
+
/**
|
|
386
|
+
* Items that must never be unmounted regardless of position.
|
|
387
|
+
*
|
|
388
|
+
* The tail carries streaming output, `isLastMessage` affordances and suggested
|
|
389
|
+
* responses; an in-progress message is mid-stream and would lose its live state.
|
|
390
|
+
*/
|
|
391
|
+
private mustStayMounted;
|
|
392
|
+
/**
|
|
393
|
+
* Records what an entry occupied on screen, so its spacer holds exactly that much space.
|
|
394
|
+
*
|
|
395
|
+
* Called immediately BEFORE destroying — afterwards the node is gone. A wrong height here
|
|
396
|
+
* is the failure mode that makes scrolling jump, which is the whole thing spacers exist
|
|
397
|
+
* to prevent.
|
|
398
|
+
*/
|
|
399
|
+
private rememberHeight;
|
|
400
|
+
/** Measured height when we have one, else a kind-appropriate estimate. */
|
|
401
|
+
private heightFor;
|
|
402
|
+
/**
|
|
403
|
+
* Measures every currently-mounted item.
|
|
404
|
+
*
|
|
405
|
+
* Runs each checked cycle so an item has a real height recorded BEFORE it scrolls far
|
|
406
|
+
* enough to be unmounted — otherwise its first spacer is always a guess.
|
|
407
|
+
*/
|
|
408
|
+
private measureMountedItems;
|
|
409
|
+
/**
|
|
410
|
+
* Replaces a mounted item with a height-holding spacer, or leaves an existing spacer
|
|
411
|
+
* alone. Stored under the item's own timeline key so {@link updateMessages}'s
|
|
412
|
+
* remove-stale pass and the remount path both find it.
|
|
413
|
+
*/
|
|
414
|
+
private ensureSpacer;
|
|
415
|
+
/**
|
|
416
|
+
* Re-evaluates the mounted window as the user scrolls.
|
|
417
|
+
*
|
|
418
|
+
* Attached once to the host's scroller. Coalesced onto an animation frame so a fast scroll
|
|
419
|
+
* costs one re-render per frame rather than one per event, and skipped entirely when the
|
|
420
|
+
* window has not actually moved.
|
|
421
|
+
*/
|
|
422
|
+
private syncScrollListener;
|
|
423
|
+
private detachScrollListener;
|
|
424
|
+
/**
|
|
425
|
+
* Watches the current spacers so scrolling back toward one remounts it.
|
|
426
|
+
*
|
|
427
|
+
* Rebuilt on every render because spacers come and go. Remounting reads from `messages`,
|
|
428
|
+
* which is already in memory — this never triggers a fetch.
|
|
429
|
+
*/
|
|
430
|
+
private syncSpacerObserver;
|
|
151
431
|
/** Stable render key for a timeline item — message ID, or a prefixed session key for session blocks. */
|
|
152
432
|
private getTimelineKey;
|
|
153
433
|
/** Render key for a session block (case-insensitive on the session id; prefixed so it can't collide with message IDs). */
|
|
@@ -236,6 +516,6 @@ export declare class MessageListComponent extends BaseAngularComponent implement
|
|
|
236
516
|
*/
|
|
237
517
|
removeMessage(message: MJConversationDetailEntity): void;
|
|
238
518
|
static ɵfac: i0.ɵɵFactoryDeclaration<MessageListComponent, never>;
|
|
239
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<MessageListComponent, "mj-conversation-message-list", never, { "messages": { "alias": "messages"; "required": false; }; "conversation": { "alias": "conversation"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "isProcessing": { "alias": "isProcessing"; "required": false; }; "showEmptyFill": { "alias": "showEmptyFill"; "required": false; }; "showDateNavigation": { "alias": "showDateNavigation"; "required": false; }; "showAgentRunDetails": { "alias": "showAgentRunDetails"; "required": false; }; "showReactions": { "alias": "showReactions"; "required": false; }; "showMessageRating": { "alias": "showMessageRating"; "required": false; }; "allowPinning": { "alias": "allowPinning"; "required": false; }; "allowMessageEdit": { "alias": "allowMessageEdit"; "required": false; }; "allowMessageDelete": { "alias": "allowMessageDelete"; "required": false; }; "assistantDisplayName": { "alias": "assistantDisplayName"; "required": false; }; "assistantAvatarUrl": { "alias": "assistantAvatarUrl"; "required": false; }; "artifactMap": { "alias": "artifactMap"; "required": false; }; "agentRunMap": { "alias": "agentRunMap"; "required": false; }; "ratingsMap": { "alias": "ratingsMap"; "required": false; }; "userAvatarMap": { "alias": "userAvatarMap"; "required": false; }; "attachmentsMap": { "alias": "attachmentsMap"; "required": false; }; "sessionMetaMap": { "alias": "sessionMetaMap"; "required": false; }; "messageRendererTemplate": { "alias": "messageRendererTemplate"; "required": false; }; "messageExtraTemplate": { "alias": "messageExtraTemplate"; "required": false; }; "messagesUpdate": { "alias": "messagesUpdate"; "required": false; }; }, { "editMessage": "editMessage"; "deleteMessage": "deleteMessage"; "retryMessage": "retryMessage"; "testFeedbackMessage": "testFeedbackMessage"; "artifactClicked": "artifactClicked"; "replyInThread": "replyInThread"; "viewThread": "viewThread"; "messageEdited": "messageEdited"; "openEntityRecord": "openEntityRecord"; "suggestedResponseSelected": "suggestedResponseSelected"; "attachmentClicked": "attachmentClicked"; "diagnosticRequested": "diagnosticRequested"; "messagePinToggled": "messagePinToggled"; "realtimeSessionOpenRequested": "realtimeSessionOpenRequested"; "beforeResponseFormSubmitted": "beforeResponseFormSubmitted"; "afterResponseFormSubmitted": "afterResponseFormSubmitted"; }, never, never, false, never>;
|
|
519
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MessageListComponent, "mj-conversation-message-list", never, { "messages": { "alias": "messages"; "required": false; }; "conversation": { "alias": "conversation"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "isProcessing": { "alias": "isProcessing"; "required": false; }; "showEmptyFill": { "alias": "showEmptyFill"; "required": false; }; "showDateNavigation": { "alias": "showDateNavigation"; "required": false; }; "showAgentRunDetails": { "alias": "showAgentRunDetails"; "required": false; }; "showReactions": { "alias": "showReactions"; "required": false; }; "showMessageRating": { "alias": "showMessageRating"; "required": false; }; "allowPinning": { "alias": "allowPinning"; "required": false; }; "allowMessageEdit": { "alias": "allowMessageEdit"; "required": false; }; "allowMessageDelete": { "alias": "allowMessageDelete"; "required": false; }; "HasMoreAbove": { "alias": "HasMoreAbove"; "required": false; }; "IsLoadingOlder": { "alias": "IsLoadingOlder"; "required": false; }; "ScrollRoot": { "alias": "ScrollRoot"; "required": false; }; "assistantDisplayName": { "alias": "assistantDisplayName"; "required": false; }; "assistantAvatarUrl": { "alias": "assistantAvatarUrl"; "required": false; }; "artifactMap": { "alias": "artifactMap"; "required": false; }; "agentRunMap": { "alias": "agentRunMap"; "required": false; }; "ratingsMap": { "alias": "ratingsMap"; "required": false; }; "userAvatarMap": { "alias": "userAvatarMap"; "required": false; }; "attachmentsMap": { "alias": "attachmentsMap"; "required": false; }; "sessionMetaMap": { "alias": "sessionMetaMap"; "required": false; }; "messageRendererTemplate": { "alias": "messageRendererTemplate"; "required": false; }; "messageExtraTemplate": { "alias": "messageExtraTemplate"; "required": false; }; "messagesUpdate": { "alias": "messagesUpdate"; "required": false; }; }, { "editMessage": "editMessage"; "deleteMessage": "deleteMessage"; "retryMessage": "retryMessage"; "testFeedbackMessage": "testFeedbackMessage"; "artifactClicked": "artifactClicked"; "replyInThread": "replyInThread"; "viewThread": "viewThread"; "messageEdited": "messageEdited"; "openEntityRecord": "openEntityRecord"; "suggestedResponseSelected": "suggestedResponseSelected"; "attachmentClicked": "attachmentClicked"; "diagnosticRequested": "diagnosticRequested"; "messagePinToggled": "messagePinToggled"; "realtimeSessionOpenRequested": "realtimeSessionOpenRequested"; "beforeResponseFormSubmitted": "beforeResponseFormSubmitted"; "afterResponseFormSubmitted": "afterResponseFormSubmitted"; "OlderRequested": "OlderRequested"; "DateJumpRequested": "DateJumpRequested"; }, never, never, false, never>;
|
|
240
520
|
}
|
|
241
521
|
//# sourceMappingURL=message-list.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-list.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/message/message-list.component.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"message-list.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/message/message-list.component.ts"],"names":[],"mappings":"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"}
|