diff --git a/src/components/PageComponents/Messages/MessageItem.tsx b/src/components/PageComponents/Messages/MessageItem.tsx index 167059d7..2bbe48bb 100644 --- a/src/components/PageComponents/Messages/MessageItem.tsx +++ b/src/components/PageComponents/Messages/MessageItem.tsx @@ -9,7 +9,7 @@ import { useDevice } 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 type { IconNode, LucideIcon } from "lucide-react"; import { ReactNode, useMemo } from "react"; import { MessageState, @@ -27,37 +27,6 @@ interface MessageStatusInfo { iconClassName?: string; } -const MESSAGE_STATUS_MAP: Record = { - [MessageState.Ack]: { - displayText: "Message delivered", - icon: CheckCircle2, - ariaLabel: "Message delivered", - iconClassName: "text-green-500", - }, - [MessageState.Waiting]: { - displayText: "Waiting for delivery", - icon: CircleEllipsis, - ariaLabel: "Sending message", - iconClassName: "text-slate-400", - }, - [MessageState.Failed]: { - displayText: "Delivery failed", - icon: AlertCircle, - ariaLabel: "Message delivery failed", - iconClassName: "text-red-500 dark:text-red-400", - }, -}; - -const UNKNOWN_STATUS: MessageStatusInfo = { - displayText: "Unknown state", - icon: AlertCircle, - ariaLabel: "Message status unknown", - iconClassName: "text-red-500 dark:text-red-400", -}; - -const getMessageStatusInfo = (state: MessageState): MessageStatusInfo => - MESSAGE_STATUS_MAP[state] ?? UNKNOWN_STATUS; - const StatusTooltip = ( { statusInfo, children }: { statusInfo: MessageStatusInfo; @@ -82,17 +51,55 @@ interface MessageItemProps { export const MessageItem = ({ message }: MessageItemProps) => { const { getNode } = useDevice(); const { getMyNodeNum } = useMessageStore(); - const { i18n } = useTranslation(); + const { t, i18n } = useTranslation(); + + const MESSAGE_STATUS_MAP = useMemo( + (): Record => ({ + [MessageState.Ack]: { + displayText: t("message_item_status_delivered_displayText"), + icon: CheckCircle2, + ariaLabel: t("message_item_status_delivered_ariaLabel"), + iconClassName: "text-green-500", + }, + [MessageState.Waiting]: { + displayText: t("message_item_status_waiting_displayText"), + icon: CircleEllipsis, + ariaLabel: t("message_item_status_waiting_ariaLabel"), + iconClassName: "text-slate-400", + }, + [MessageState.Failed]: { + displayText: t("message_item_status_failed_displayText"), + icon: AlertCircle, + ariaLabel: t("message_item_status_failed_ariaLabel"), + iconClassName: "text-red-500 dark:text-red-400", + }, + }), + [t], + ); + + const UNKNOWN_STATUS = useMemo((): MessageStatusInfo => ({ + displayText: t("message_item_status_unknown_displayText"), + icon: AlertCircle, + ariaLabel: t("message_item_status_unknown_ariaLabel"), + iconClassName: "text-red-500 dark:text-red-400", + }), [t]); + + const getMessageStatusInfo = useMemo( + () => (state: MessageState): MessageStatusInfo => + MESSAGE_STATUS_MAP[state] ?? UNKNOWN_STATUS, + [MESSAGE_STATUS_MAP, UNKNOWN_STATUS], + ); const messageUser: Protobuf.Mesh.NodeInfo | null | undefined = useMemo(() => { return message.from != null ? getNode(message.from) : null; }, [getNode, message.from]); const myNodeNum = useMemo(() => getMyNodeNum(), [getMyNodeNum]); + const { displayName, shortName, isFavorite } = useMemo(() => { const userIdHex = message.from.toString(16).toUpperCase().padStart(2, "0"); const last4 = userIdHex.slice(-4); - const fallbackName = `Meshtastic ${last4}`; + const fallbackName = t("message_item_fallbackName_withLastFour", { last4 }); const longName = messageUser?.user?.longName; const derivedShortName = messageUser?.user?.shortName || fallbackName; const derivedDisplayName = longName || derivedShortName; @@ -103,7 +110,7 @@ export const MessageItem = ({ message }: MessageItemProps) => { shortName: derivedShortName, isFavorite: isFavorite, }; - }, [messageUser, message.from]); + }, [messageUser, message.from, t, myNodeNum]); const messageStatusInfo = getMessageStatusInfo(message.state); const StatusIconComponent = messageStatusInfo.icon; diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 784bf181..c43d5fd3 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -162,6 +162,15 @@ "messages_sendMessagePrompt": "Select a chat to send a message.", "messages_actionsMenu_addReactionLabel": "Add Reaction", "messages_actionsMenu_replyLabel": "Reply", + "message_item_fallbackName_withLastFour": "Meshtastic {{last4}}", + "message_item_status_delivered_ariaLabel": "Message delivered", + "message_item_status_delivered_displayText": "Message delivered", + "message_item_status_failed_ariaLabel": "Message delivery failed", + "message_item_status_failed_displayText": "Delivery failed", + "message_item_status_unknown_ariaLabel": "Message status unknown", + "message_item_status_unknown_displayText": "Unknown state", + "message_item_status_waiting_ariaLabel": "Sending message", + "message_item_status_waiting_displayText": "Waiting for delivery", "channel_page_title": "Channel: {{channelName}}", "channel_name_primary": "Primary",