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 { getChannelName } from "@pages/Channels.tsx"; import { HashIcon, LockIcon, LockOpenIcon, SearchIcon } from "lucide-react"; import { useMemo, 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"; import { useSidebar } from "@core/stores/sidebarStore.tsx"; import { Input } from "@components/UI/Input.tsx"; type NodeInfoWithUnread = Protobuf.Mesh.NodeInfo & { unreadCount: number }; export const MessagesPage = () => { const { channels, getNodes, getNode, hasNodeError, unreadCounts, resetUnread } = useDevice(); const { getNodeNum, getMessages, setActiveChat, chatType, activeChat, setChatType } = useMessageStore() const { toast } = useToast(); const { isCollapsed } = useSidebar() const [searchTerm, setSearchTerm] = useState(""); const filteredNodes: NodeInfoWithUnread[] = useMemo(() => { const lowerCaseSearchTerm = searchTerm.toLowerCase(); return getNodes(node => { const longName = node.user?.longName?.toLowerCase() ?? ''; const shortName = node.user?.shortName?.toLowerCase() ?? ''; return longName.includes(lowerCaseSearchTerm) || shortName.includes(lowerCaseSearchTerm) }) .map((node) => ({ ...node, unreadCount: unreadCounts.get(node.num) ?? 0, })) .sort((a, b) => b.unreadCount - a.unreadCount); }, [getNodes, searchTerm, unreadCounts]); 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 = getNode(activeChat); const isDirect = chatType === MessageType.Direct; const isBroadcast = chatType === MessageType.Broadcast; const currentChat = { type: chatType, id: activeChat }; const renderChatContent = () => { switch (chatType) { case MessageType.Broadcast: return ( ); case MessageType.Direct: return ( ); default: return (
Select a channel or node to start messaging.
); } } const leftSidebar = useMemo(() => ( {filteredChannels?.map((channel) => ( { setChatType(MessageType.Broadcast); setActiveChat(channel.index); resetUnread(channel.index); }} > ))} ), [filteredChannels, unreadCounts, activeChat, chatType, isCollapsed, setActiveChat, setChatType, resetUnread]); const rightSidebar = useMemo(() => (
{filteredNodes?.map((node) => ( 0 ? node.unreadCount : undefined} active={activeChat === node.num && chatType === MessageType.Direct} onClick={() => { setChatType(MessageType.Direct); setActiveChat(node.num); resetUnread(node.num); }}> ))}
), [filteredNodes, searchTerm, activeChat, chatType, setActiveChat, setChatType, resetUnread, hasNodeError]); return (
{renderChatContent()}
{(isBroadcast || isDirect) ? ( ) : (
Select a chat to send a message.
)}
); }; export default MessagesPage;