import { isAgeSafetySystemType, isDmAgentSystemType, type AgeSafetySystemType, type DmAgentSystemType, } from '@linktr.ee/messaging-taxonomy' import { ProhibitIcon, SparkleIcon } from '@phosphor-icons/react' import { MessageTimestamp, type EventComponentProps } from 'stream-chat-react' const DM_AGENT_SYSTEM_MESSAGE_FALLBACK_TEXT: Record = { SYSTEM_DM_AGENT_PAUSED: 'DM Agent has left the conversation', SYSTEM_DM_AGENT_RESUMED: 'DM Agent has rejoined the conversation', } /** * System-message timestamps are hidden by default. A semantic type must opt in * here to render one, so new/unknown system types stay timestamp-less until * explicitly added. Keep in sync with the mobile client (cerberus * `CustomMessageSystem`); there is no shared package between the two surfaces. */ const SHOW_SYSTEM_MESSAGE_TIMESTAMP_TYPES: readonly AgeSafetySystemType[] = [ 'SYSTEM_AGE_SAFETY_BLOCKED', ] const AGE_SAFETY_SYSTEM_MESSAGE_FALLBACK_TEXT: Record< AgeSafetySystemType, string > = { SYSTEM_AGE_SAFETY_BLOCKED: 'This user isn’t able to reply because they don’t meet our age safety guidelines.', } const AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS = 'age safety guidelines.' const AGE_SAFETY_SYSTEM_MESSAGE_URL = 'https://linktr.ee/s/about/contact' const isShowTimestampSystemType = ( value: string | undefined ): value is (typeof SHOW_SYSTEM_MESSAGE_TIMESTAMP_TYPES)[number] => { return SHOW_SYSTEM_MESSAGE_TIMESTAMP_TYPES.includes( value as (typeof SHOW_SYSTEM_MESSAGE_TIMESTAMP_TYPES)[number] ) } const shouldShowSystemMessageTimestamp = ( message: EventComponentProps['message'] ): boolean => { return isShowTimestampSystemType(message.metadata?.custom_type) } type CustomSystemMessageVariant = | { kind: 'dm-agent' type: DmAgentSystemType } | { kind: 'age-safety' type: AgeSafetySystemType } const getCustomSystemMessageVariant = ( message: EventComponentProps['message'] ): CustomSystemMessageVariant | undefined => { const metadataCustomType = message.metadata?.custom_type if (isDmAgentSystemType(metadataCustomType)) { return { kind: 'dm-agent', type: metadataCustomType, } } if (isAgeSafetySystemType(metadataCustomType)) { return { kind: 'age-safety', type: metadataCustomType, } } const fallbackType = message.dm_agent_system_type if (isDmAgentSystemType(fallbackType)) { return { kind: 'dm-agent', type: fallbackType, } } return undefined } const renderAgeSafetyMessageText = (messageText: string): React.ReactNode => { const emphasisIndex = messageText.indexOf(AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS) if (emphasisIndex === -1) { return messageText } const emphasisEndIndex = emphasisIndex + AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS.length return ( <> {messageText.slice(0, emphasisIndex)} {AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS} {messageText.slice(emphasisEndIndex)} ) } export const CustomSystemMessage: React.FC = (props) => { const isDateHidden = !shouldShowSystemMessageTimestamp(props.message) const customSystemMessageVariant = getCustomSystemMessageVariant( props.message ) if (customSystemMessageVariant?.kind === 'dm-agent') { const messageText = props.message.text?.trim() || DM_AGENT_SYSTEM_MESSAGE_FALLBACK_TEXT[customSystemMessageVariant.type] return (

{messageText}

{!isDateHidden && }
) } if (customSystemMessageVariant?.kind === 'age-safety') { const messageText = props.message.text?.trim() || AGE_SAFETY_SYSTEM_MESSAGE_FALLBACK_TEXT[customSystemMessageVariant.type] return (

{renderAgeSafetyMessageText(messageText)}

{!isDateHidden && }
) } return (

{props.message.text}

{!isDateHidden && }
) }