/* * Copyright 2026 Element Creations Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial * Please see LICENSE files in the repository root for full details. */ import React, { type JSX, type MouseEventHandler, type KeyboardEvent, type MouseEvent } from "react"; import classNames from "classnames"; import { Tooltip } from "@vector-im/compound-web"; import styles from "./MessageTimestampView.module.css"; import { type ViewModel } from "../../viewmodel/ViewModel"; import { useViewModel } from "../../viewmodel/useViewModel"; import { useI18n } from "../../utils/i18nContext"; export interface MessageTimestampViewSnapshot { /** * The localized timestamp to render in the component */ ts: string; /** * The localized sent timestamp formatted as full date */ tsSentAt: string; /** * The localized received timestamp formatted as full date * If specified will render both the sent-at and received-at timestamps in the tooltip */ tsReceivedAt?: string; /** * If set to true then no tooltip will be shown */ inhibitTooltip?: boolean; /** * If specified, will be rendered as an anchor bearing the href, a `span` element will be used otherwise */ href?: string; } export interface MessageTimestampViewActions { /** * Optional onClick handler to attach to the DOM element */ onClick?: MouseEventHandler; /** * Optional onContextMenu handler to attach to the DOM element */ onContextMenu?: MouseEventHandler; } /** * The view model for the message timestamp. * * Snapshot data describes timestamp content and rendering behavior, while * container styling is supplied via component props. */ export type MessageTimestampViewModel = ViewModel & MessageTimestampViewActions; interface MessageTimestampViewProps { /** * The view model for the message timestamp. */ vm: MessageTimestampViewModel; /** * Optional CSS class name to apply to the component. */ className?: string; } /** * Displays a message timestamp with optional tooltip details. * * The view model provides the timestamp values and display options. The component * can render as a link when `href` is set, and can show both sent-at and received-at * times in the tooltip when `tsReceivedAt` is provided. Use `className` for * host-level styling. * * @example * ```tsx * * ``` */ export function MessageTimestampView({ vm, className }: Readonly): JSX.Element { const { translate: _t } = useI18n(); const { ts, tsSentAt, tsReceivedAt, inhibitTooltip, href } = useViewModel(vm); const onKeyDown = (event: KeyboardEvent): void => { if (vm.onClick) { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); vm.onClick?.(event as unknown as MouseEvent); } } }; let label = tsSentAt; let caption: string | undefined; if (tsReceivedAt && tsReceivedAt?.length > 0) { label = _t("timeline|message_timestamp_sent_at", { dateTime: label }); caption = _t("timeline|message_timestamp_received_at", { dateTime: tsReceivedAt, }); } let content; if (href) { content = ( {ts} ); } else { content = ( {ts} ); } if (inhibitTooltip) return content; return ( {content} ); }