diff --git a/dev-dist/sw.js b/dev-dist/sw.js index 6cdc433..49ebada 100644 --- a/dev-dist/sw.js +++ b/dev-dist/sw.js @@ -82,7 +82,7 @@ define(['./workbox-47da91e0'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "/index.html", - "revision": "0.9eood2uf828" + "revision": "0.9t777mpmecg" }], { "ignoreURLParametersMatching": [/^utm_/, /^fbclid$/] }); diff --git a/src/components/notes/NoteEditor.tsx b/src/components/notes/NoteEditor.tsx index 784c33c..630829a 100644 --- a/src/components/notes/NoteEditor.tsx +++ b/src/components/notes/NoteEditor.tsx @@ -14,7 +14,7 @@ import { ImproveTextModal } from "./ImproveTextModal"; import { extractTags } from "../../utils/markdown"; interface NoteEditorProps { - onSave: () => void; + onSave: (noteId?: number | string) => void; } export const NoteEditor: React.FC = ({ onSave }) => { @@ -80,7 +80,7 @@ export const NoteEditor: React.FC = ({ onSave }) => { setContent(""); setImages([]); setFiles([]); - onSave(); + onSave(note.id); } catch (error) { console.error("Ошибка сохранения заметки:", error); showNotification("Ошибка сохранения заметки", "error"); @@ -106,7 +106,9 @@ export const NoteEditor: React.FC = ({ onSave }) => { console.error("Ошибка улучшения текста:", error); setImproveError(true); setImproveErrorMessage( - error.response?.data?.error || error.message || "Ошибка улучшения текста" + error.response?.data?.error || + error.message || + "Ошибка улучшения текста" ); } finally { setIsAiLoading(false); @@ -147,7 +149,10 @@ export const NoteEditor: React.FC = ({ onSave }) => { console.error("Детали ошибки:", error.response?.data); setTagsGenerationError(true); setShowTagsModal(false); - const errorMessage = error.response?.data?.error || error.message || "Ошибка генерации тегов"; + const errorMessage = + error.response?.data?.error || + error.message || + "Ошибка генерации тегов"; showNotification(errorMessage, "error"); } finally { setIsGeneratingTags(false); @@ -159,13 +164,19 @@ export const NoteEditor: React.FC = ({ onSave }) => { const existingTags = extractTags(content); const tagsToAdd = tags - .filter((tag) => !existingTags.some((existing) => existing.toLowerCase() === tag.toLowerCase())) + .filter( + (tag) => + !existingTags.some( + (existing) => existing.toLowerCase() === tag.toLowerCase() + ) + ) .map((tag) => `#${tag}`) .join(" "); if (tagsToAdd) { // Добавляем теги в конец заметки - const newContent = content.trim() + (content.trim() ? "\n\n" : "") + tagsToAdd; + const newContent = + content.trim() + (content.trim() ? "\n\n" : "") + tagsToAdd; setContent(newContent); showNotification(`Добавлено тегов: ${tags.length}`, "success"); } else { diff --git a/src/components/notes/NoteItem.tsx b/src/components/notes/NoteItem.tsx index 0733793..14f6aea 100644 --- a/src/components/notes/NoteItem.tsx +++ b/src/components/notes/NoteItem.tsx @@ -31,6 +31,7 @@ interface NoteItemProps { onReload: () => void; isSelected?: boolean; onSelect?: (id: number | string) => void; + onFocusNote?: (id: number | string) => void; } export const NoteItem: React.FC = ({ @@ -41,6 +42,7 @@ export const NoteItem: React.FC = ({ onReload, isSelected = false, onSelect, + onFocusNote, }) => { const [isEditing, setIsEditing] = useState(false); const [editContent, setEditContent] = useState(note.content); @@ -138,6 +140,13 @@ export const NoteItem: React.FC = ({ setDeletedImageIds([]); setDeletedFileIds([]); onReload(); + // Устанавливаем фокус на заметку после сохранения + if (onFocusNote) { + // Небольшая задержка для завершения обновления DOM + setTimeout(() => { + onFocusNote(note.id); + }, 100); + } } catch (error) { console.error("Ошибка обновления заметки:", error); showNotification("Ошибка обновления заметки", "error"); diff --git a/src/components/notes/NotesList.tsx b/src/components/notes/NotesList.tsx index 2841251..1cdf225 100644 --- a/src/components/notes/NotesList.tsx +++ b/src/components/notes/NotesList.tsx @@ -8,6 +8,7 @@ import { extractTags } from "../../utils/markdown"; export interface NotesListRef { reloadNotes: () => void; + focusNote: (noteId: number | string) => void; } interface NotesListProps { @@ -81,8 +82,34 @@ export const NotesList = forwardRef( // eslint-disable-next-line react-hooks/exhaustive-deps }, [userId, searchQuery, selectedDate, selectedTag]); + const focusNote = (noteId: number | string) => { + // Используем data-атрибут для поиска элемента заметки + const noteElement = document.querySelector( + `[data-note-id="${noteId}"]` + ) as HTMLDivElement | null; + + if (noteElement) { + // Прокручиваем к верхней части заметки + noteElement.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" }); + // Добавляем визуальное выделение на короткое время + // Очищаем предыдущий таймер, если он был установлен + const existingTimeout = (noteElement as any).__focusTimeout; + if (existingTimeout) { + clearTimeout(existingTimeout); + } + noteElement.style.transition = "box-shadow 0.3s ease"; + noteElement.style.boxShadow = "0 0 0 3px rgba(33, 150, 243, 0.5)"; + const timeout = setTimeout(() => { + noteElement.style.boxShadow = ""; + (noteElement as any).__focusTimeout = null; + }, 2000); + (noteElement as any).__focusTimeout = timeout; + } + }; + useImperativeHandle(ref, () => ({ reloadNotes: loadNotes, + focusNote: focusNote, })); const handleDelete = async (id: number | string) => { @@ -167,6 +194,7 @@ export const NotesList = forwardRef( onReload={loadNotes} isSelected={selectedNoteIds.includes(note.id)} onSelect={onNoteSelect} + onFocusNote={focusNote} /> ))} diff --git a/src/pages/NotesPage.tsx b/src/pages/NotesPage.tsx index 6a1dba8..6018722 100644 --- a/src/pages/NotesPage.tsx +++ b/src/pages/NotesPage.tsx @@ -63,10 +63,32 @@ const NotesPage: React.FC = () => { const activeFilters = getActiveFilters(); - const handleNoteSave = () => { + const handleNoteSave = (noteId?: number | string) => { // Вызываем перезагрузку заметок после создания новой заметки if (notesListRef.current) { notesListRef.current.reloadNotes(); + // Устанавливаем фокус на сохраненную заметку после небольшой задержки, + // чтобы дать время для перезагрузки и рендеринга заметок + if (noteId) { + let attempts = 0; + const maxAttempts = 15; + const attemptFocus = () => { + attempts++; + if (notesListRef.current) { + // Проверяем, есть ли элемент заметки в DOM + const noteElement = document.querySelector( + `[data-note-id="${noteId}"]` + ); + if (noteElement || attempts >= maxAttempts) { + notesListRef.current.focusNote(noteId); + } else if (attempts < maxAttempts) { + // Пытаемся еще раз, если заметка еще не появилась в DOM + setTimeout(attemptFocus, 100); + } + } + }; + setTimeout(attemptFocus, 200); + } } };