Files
nahodka-front/src/pages/ChatListPage.jsx
2026-08-13 00:37:41 +03:00

100 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useState, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { useTranslation } from 'react-i18next';
import { useChats } from "../hooks/useChats";
import { useAuthContext } from "../context/AuthContext";
import { useUnread } from "../context/UnreadContext";
import { getPostForChat } from "../stores/chatPostStore";
import { useDeleteChat } from "../hooks/useDeleteChat";
import ChatHeader from "../components/chat/ChatHeader";
import ChatListItem from "../components/chat/ChatListItem";
import Toast from "../components/Toast";
export default function ChatListPage() {
const { t } = useTranslation();
const navigate = useNavigate();
const { chats, loading, fetchChats } = useChats();
const { isAuthenticated } = useAuthContext();
const { unreadMap, totalUnread } = useUnread();
const { deleteChat } = useDeleteChat();
const [deleteError, setDeleteError] = useState("");
useEffect(() => {
if (isAuthenticated) {
fetchChats();
}
}, [isAuthenticated, fetchChats]);
// При поступлении непрочитанного сообщения (WS) обновляем список, чтобы
// превью показывало новое сообщение и подсветку, не дожидаясь ручного обновления.
useEffect(() => {
if (!isAuthenticated) return;
const timer = setTimeout(() => fetchChats(), 500);
return () => clearTimeout(timer);
// totalUnread — числовое значение, поэтому изменение состава чатов с той же
// суммой не создаст цикл обновлений.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [totalUnread, isAuthenticated, fetchChats]);
const handleDeleteChat = useCallback(async (chatId) => {
if (!window.confirm(t('chat.confirmDeleteChat'))) return;
const result = await deleteChat(chatId);
if (result.success) {
fetchChats();
} else {
setDeleteError(result.error);
}
}, [t, deleteChat, fetchChats]);
const goBack = () => navigate("/feed");
const openChat = (chatId) => navigate(`/chats/${chatId}`);
if (!isAuthenticated) {
return (
<div className="f-app">
<div className="chat-page">
<ChatHeader title={t('chat.chats')} onBack={goBack} />
<div className="chat-empty-full">{t('chat.loginToSee')}</div>
</div>
</div>
);
}
return (
<div className="f-app">
<div className="chat-page">
<ChatHeader title={t('chat.chats')} onBack={goBack} />
<div className="chat-list">
{loading && (
<div className="chat-empty-full">{t('chat.loading')}</div>
)}
{!loading && chats.length === 0 && (
<div className="chat-empty-full">{t('chat.noChats')}</div>
)}
{!loading && chats.map((chat) => (
<ChatListItem
key={chat.id}
chat={chat}
post={getPostForChat(chat.id)}
unreadMap={unreadMap}
t={t}
onOpen={openChat}
onDelete={handleDeleteChat}
/>
))}
</div>
</div>
{deleteError && (
<Toast
message={deleteError}
type="error"
onDismiss={() => setDeleteError("")}
/>
)}
</div>
);
}