import * as React from "react"; import type { RawMessage } from "../values"; import Text from "@tensamin/markdown/text"; import { AlertTriangle, Check, Ellipse, RefreshCw } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import type { User } from "@tensamin/user/context"; import { Avatar, AvatarFallback, AvatarImage, cn, Tooltip, TooltipContent, TooltipTrigger, } from "@tensamin/ui"; import MessageContextMenu from "./messageContextMenu"; import Media from "./media"; import { useStorage } from "@tensamin/storage/context"; import { useTTP } from "@tensamin/ttp"; function MessageComponent({ grouped, message, user, }: { grouped: boolean; message: RawMessage & { failed?: boolean; }; user: User | null; }) { const actuallyFailed = message.failed && message.message_state === "awaiting"; // Fade-in const [hasFadedIn, setHasFadedIn] = useState(false); const opacityClass = !hasFadedIn ? "opacity-0" : actuallyFailed || message.message_state === "awaiting" ? "opacity-50" : "opacity-100"; useEffect(() => { const timeout = window.setTimeout(() => { setHasFadedIn(true); }, 100); return () => { window.clearTimeout(timeout); }; }, []); // Check if message is a url const [isValidURL, setIsValidURL] = useState(false); useEffect(() => { try { if (message.content.split(" ").length > 1) throw new Error(); new URL(message.content); setIsValidURL(true); } catch { setIsValidURL(false); } }, [message.content]); // Message states const { load } = useStorage(); const { send } = useTTP(); const messageStateReadUpdate = useCallback(async () => { const readConfirmations = await load("settings.read_confirmations"); if (readConfirmations) { if (!user?.user_id) return; await send("message_state", { chat_partner_id: user?.user_id, send_time: message.send_time, message_state: "read", }); } else { await send("message_state", { chat_partner_id: user?.user_id, send_time: message.send_time, message_state: "received", }); } }, [load, message.send_time, user?.user_id, send]); useEffect(() => { let cancelled = false; async function run() { const receiveConfirmations = await load("settings.receive_confirmations"); if (cancelled) return; switch (message.message_state) { case "sent": if (receiveConfirmations) { messageStateReadUpdate(); } break; case "received": messageStateReadUpdate(); break; default: break; } } run(); return () => { cancelled = true; }; }, [message.message_state, load, messageStateReadUpdate]); return (
{new Date(message.send_time).toLocaleString([], { hour: "2-digit", minute: "2-digit", })}
) : (Failed to send message
{user.display}
{new Date(message.send_time).toLocaleString([], { hour: "2-digit", minute: "2-digit", })}