import { Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipTrigger, } from "@components/UI/Tooltip.tsx"; import { MessageState, useDeviceStore } from "@core/stores/deviceStore.ts"; import { cn } from "@core/utils/cn.ts"; import { Avatar } from "@components/UI/Avatar.tsx"; import { AlertCircle, CheckCircle2, CircleEllipsis } from "lucide-react"; import type { LucideIcon } from "lucide-react"; import { ReactNode, useMemo } from "react"; import { Message } from "@core/stores/messageStore.ts"; interface MessageProps { lastMsgSameUser: boolean; message: Message; } interface MessageStatus { state: MessageState; displayText: string; icon: LucideIcon; } const MESSAGE_STATUS: Record = { ack: { state: "ack", displayText: "Message delivered", icon: CheckCircle2 }, waiting: { state: "waiting", displayText: "Waiting for delivery", icon: CircleEllipsis }, failed: { state: "failed", displayText: "Delivery failed", icon: AlertCircle }, }; const getMessageStatus = (state: MessageState): MessageStatus => MESSAGE_STATUS[state] || { state: "failed", displayText: "Unknown error", icon: AlertCircle }; const StatusTooltip = ({ status, children }: { status: MessageStatus; children: ReactNode }) => ( {children} {status.displayText} ); const StatusIcon = ({ status, className, ...otherProps }: { status: MessageStatus; className?: string }) => { const isFailed = status.state === "failed"; const iconClass = cn("text-slate-500 dark:text-slate-400 w-4 h-4 shrink-0", className); const Icon = status.icon; return ( ); }; const getMessageTextStyles = (status: MessageStatus) => { const isAcknowledged = status.state === "ack"; const isFailed = status.state === "failed"; return cn( "break-words overflow-hidden", isAcknowledged ? "text-slate-900 dark:text-white" : "text-slate-900 dark:text-slate-400", isFailed && "text-red-500 dark:text-red-500", ); }; const TimeDisplay = ({ date, className }: { date: Date; className?: string }) => { const _date = new Date(date); return (
{_date?.toLocaleDateString()} {_date?.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit" })}
) }; export const MessageItem = ({ lastMsgSameUser, message }: MessageProps) => { const { getDevices } = useDeviceStore(); const isDeviceUser = useMemo( () => getDevices() .map((device) => device.nodes.get(device.hardware.myNodeNum)?.num) .includes(message.from), [getDevices, message.from], ); const messageUser = message?.from ? getDevices().find((device) => device.nodes.has(message.from))?.nodes.get(message.from) : null; const messageStatus = getMessageStatus(message.state); const messageTextClass = getMessageTextStyles(messageStatus); return (
{!lastMsgSameUser && (
{messageUser?.user?.longName}
)}
{message.message}
); };