Cap planet captions at 30 degrees with a third ring, fall back only within the current person's sessions, and load self when the people catalog fails.
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
import { sessionMatchesSubject } from "./chat-profile-picker-model";
|
|
import type { ChatSession } from "./home-types";
|
|
import { isUnsavedEmptyConsultation } from "./session-list-filter";
|
|
|
|
/** A list row is metadata, never authority to erase an opened transcript.
|
|
* A complete refresh of one person drops that person's rows the server no
|
|
* longer returns, and leaves every other person untouched. */
|
|
export function mergeSubjectSessionRows(
|
|
current: readonly ChatSession[],
|
|
incoming: readonly ChatSession[],
|
|
options?: { readonly subjectId?: string; readonly complete?: boolean },
|
|
): ChatSession[] {
|
|
const incomingIds = new Set(incoming.map((session) => session.id));
|
|
const subjectId = options?.subjectId;
|
|
const base = options?.complete && subjectId
|
|
? current.filter((session) => incomingIds.has(session.id)
|
|
|| !sessionMatchesSubject(session, subjectId)
|
|
|| isUnsavedEmptyConsultation(session))
|
|
: current;
|
|
const rows = new Map(base.map((session) => [session.id, session]));
|
|
for (const row of incoming) {
|
|
const existing = rows.get(row.id);
|
|
rows.set(row.id, existing?.messagesHydrated
|
|
? { ...existing, ...row, messages: existing.messages, messagesHydrated: true }
|
|
: row);
|
|
}
|
|
return [...rows.values()];
|
|
}
|