import type { AssistantMessage, CollabNoteCard, CollabNotesCard as NotesCard } from '@trek/shared'; import { Link2, Paperclip, Pin, PinOff, StickyNote, Tag, Type } from 'lucide-react'; import type { ReactNode } from 'react'; import Markdown, { type Components } from 'react-markdown'; import remarkBreaks from 'remark-breaks'; import remarkGfm from 'remark-gfm'; import { useTranslation } from '../../../../i18n'; import { safeHexColor } from '../../../../utils/safeColor'; import { NoteHeadBand } from '../../../Collab/CollabNoteHead'; import { SoftPill, tintOf } from '../../../Planner/planParts'; import { sanitizedMarkdownComponents, sanitizedMarkdownPlugins } from '../../../shared/markdownSanitize'; import type { ChangeItem, ChangeState } from '../../assistantParts'; import { useAssistantView } from '../../assistantViewContext'; import type { CardEntry } from '../cardTypes'; import { Fact, FactChange } from '../parts/CardFacts'; import CardFrame from '../parts/CardFrame'; import CardHeader from '../parts/CardHeader'; import { CardOpenButton } from '../parts/CardOpen'; import { PersonFace } from '../parts/CardPeople'; import { CardMore } from '../parts/CardRows'; import { isChanged, isOpen } from './collabCardModel'; import { NOTES_TARGET } from './collabLook'; /** * Shared notes of the trip in the assistant chat, drawn like the Collab * tab's note cards: a head band tinted by the category's colour with its * title and pin, the start of the text in three lines, and the facts (the * link's host, the files, the category) as badges. A link in a note reads as * a word here, since the text may be cut. A held new note has a dashed * frame, a held change marks what it changes, a note about to go is struck. */ const ICON = { size: 10, strokeWidth: 2.2, 'aria-hidden': true } as const; /** The note's markdown as the note card renders it, its links as words. */ const NOTE_MARKDOWN: Components = { ...sanitizedMarkdownComponents, a: ({ children }) => {children}, }; /** A small accent dot before what a held change sets anew. */ function ChangedDot({ on }: { on: boolean }) { if (!on) return null; return