import { ChannelChat } from "@components/PageComponents/Messages/ChannelChat.tsx"; import { PageLayout } from "@components/PageLayout.tsx"; import { Sidebar } from "@components/Sidebar.tsx"; import { Avatar } from "@components/UI/Avatar.tsx"; import { SidebarSection } from "@components/UI/Sidebar/SidebarSection.tsx"; import { SidebarButton } from "@components/UI/Sidebar/sidebarButton.tsx"; import { useToast } from "@core/hooks/useToast.ts"; import { useDevice } from "@core/stores/deviceStore.ts"; import { Protobuf, Types } from "@meshtastic/core"; import { numberToHexUnpadded } from "@noble/curves/abstract/utils"; import { getChannelName } from "@pages/Channels.tsx"; import { HashIcon, LockIcon, LockOpenIcon } from "lucide-react"; import { useState } from "react"; import { MessageInput } from "@components/PageComponents/Messages/MessageInput.tsx"; import { cn } from "@core/utils/cn.ts"; import { MessageType, useMessageStore } from "@core/stores/messageStore.ts"; type NodeInfoWithUnread = Protobuf.Mesh.NodeInfo & { unreadCount: number }; export const MessagesPage = () => { const { channels, nodes, hardware, hasNodeError, unreadCounts, resetUnread } = useDevice(); const { getNodeNum, getMessages, setActiveChat, chatType, activeChat, setChatType } = useMessageStore() const { toast } = useToast(); const [searchTerm, setSearchTerm] = useState(""); const filteredNodes: NodeInfoWithUnread[] = Array.from(nodes.values()) .filter((node) => node.num !== hardware.myNodeNum) .map((node) => ({ ...node, unreadCount: unreadCounts.get(node.num) ?? 0, })) .filter((node) => { const nodeName = node.user?.longName ?? `!${numberToHexUnpadded(node.num)}`; return nodeName.toLowerCase().includes(searchTerm.toLowerCase()); }) .sort((a, b) => b.unreadCount - a.unreadCount); const allChannels = Array.from(channels.values()); const filteredChannels = allChannels.filter( (ch) => ch.role !== Protobuf.Channel.Channel_Role.DISABLED, ); const currentChannel = channels.get(activeChat); const otherNode = nodes.get(activeChat); const nodeHex = otherNode?.num ? numberToHexUnpadded(otherNode.num) : "Unknown"; const isDirect = chatType === MessageType.Direct; const isBroadcast = chatType === MessageType.Broadcast; const currentChat = { type: chatType, id: activeChat }; return ( <> {filteredChannels.map((channel) => ( { setChatType(MessageType.Broadcast); setActiveChat(channel.index); resetUnread(channel.index); }} element={} /> ))}
setSearchTerm(e.target.value)} className="w-full p-2 border border-slate-300 rounded-sm bg-white text-slate-900 dark:bg-slate-700 dark:border-slate-600 dark:text-slate-100 focus:outline-none focus:ring-2 focus:ring-blue-500" />
{filteredNodes.map((node) => ( 0 ? node.unreadCount : undefined} active={activeChat === node.num && chatType === MessageType.Direct} onClick={() => { setChatType(MessageType.Direct); setActiveChat(node.num); resetUnread(node.num); }} element={ } /> ))}
{isBroadcast && currentChannel && (
)} {isDirect && otherNode && (
)} {!isBroadcast && !isDirect && (
Select a channel or node to start messaging.
)}
{(isBroadcast || isDirect) ? ( ) : (
Select a chat to send a message.
)}
); }; export default MessagesPage;