import React, { useEffect, useState, useRef } from "react"; import { aiApi } from "../../api/aiApi"; import { offlineNotesApi } from "../../api/offlineNotesApi"; import { Note } from "../../types/note"; import { NotePreview } from "./NotePreview"; import { useNotification } from "../../hooks/useNotification"; interface MergeNotesModalProps { isOpen: boolean; onClose: () => void; selectedNotes: Note[]; onSuccess: () => void; } export const MergeNotesModal: React.FC = ({ isOpen, onClose, selectedNotes, onSuccess, }) => { const [mergedContent, setMergedContent] = useState(""); const [isLoading, setIsLoading] = useState(false); const [isSaving, setIsSaving] = useState(false); const [deleteOriginalNotes, setDeleteOriginalNotes] = useState(false); const isClosedRef = useRef(false); const { showNotification } = useNotification(); // Выполняем объединение при открытии модального окна useEffect(() => { if (isOpen && selectedNotes.length >= 2) { isClosedRef.current = false; handleMerge(); } else { // Сбрасываем состояние при закрытии setMergedContent(""); setIsLoading(false); setIsSaving(false); setDeleteOriginalNotes(false); isClosedRef.current = false; } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isOpen]); const handleClose = () => { isClosedRef.current = true; setIsLoading(false); setIsSaving(false); setMergedContent(""); setDeleteOriginalNotes(false); onClose(); }; const handleMerge = async () => { setIsLoading(true); setMergedContent(""); try { const notesContent = selectedNotes.map((note) => note.content); const merged = await aiApi.mergeNotes(notesContent); // Проверяем, не была ли модалка закрыта во время запроса if (!isClosedRef.current) { setMergedContent(merged); } } catch (error) { // Игнорируем ошибку, если модалка была закрыта if (isClosedRef.current) { return; } console.error("Ошибка объединения заметок:", error); showNotification("Ошибка объединения заметок", "error"); handleClose(); } finally { if (!isClosedRef.current) { setIsLoading(false); } } }; const handleSave = async () => { if (!mergedContent.trim()) { showNotification("Нет контента для сохранения", "warning"); return; } setIsSaving(true); try { const now = new Date(); const date = now.toLocaleDateString("ru-RU"); const time = now.toLocaleTimeString("ru-RU", { hour: "2-digit", minute: "2-digit", }); await offlineNotesApi.create({ content: mergedContent, date, time, }); // Удаляем исходные заметки, если тумблер включен if (deleteOriginalNotes) { try { await Promise.all( selectedNotes.map((note) => offlineNotesApi.delete(note.id)) ); showNotification( `Объединенная заметка сохранена! Удалено ${selectedNotes.length} исходных заметок.`, "success" ); } catch (deleteError) { console.error("Ошибка удаления исходных заметок:", deleteError); showNotification( "Объединенная заметка сохранена, но произошла ошибка при удалении исходных заметок", "warning" ); } } else { showNotification("Объединенная заметка сохранена!", "success"); } onSuccess(); handleClose(); } catch (error) { console.error("Ошибка сохранения заметки:", error); showNotification("Ошибка сохранения заметки", "error"); } finally { setIsSaving(false); } }; useEffect(() => { const handleEscape = (e: KeyboardEvent) => { if (e.key === "Escape") { handleClose(); } }; if (isOpen) { document.addEventListener("keydown", handleEscape); } return () => document.removeEventListener("keydown", handleEscape); }, [isOpen]); if (!isOpen) return null; return (
e.stopPropagation()} >

Объединение заметок

×
{isLoading ? (

Объединяю заметки через ИИ...

Выбрано заметок: {selectedNotes.length}

) : ( <>

Результат объединения {selectedNotes.length}{" "} {selectedNotes.length === 2 ? "заметок" : selectedNotes.length > 4 ? "заметок" : "заметок"} :

)}
); };