Обновлены компоненты NoteEditor, NoteItem и NotesList для улучшения обработки сохранения заметок и добавления фокуса на сохраненные заметки. Изменены типы параметров функций и добавлена логика для плавного прокручивания к заметкам. Обновлен сервисный работник с новым ревизионным номером для кэширования.

This commit is contained in:
Fovway 2025-11-07 22:56:07 +07:00
parent 06400d6e97
commit 05a9275253
5 changed files with 78 additions and 8 deletions

View File

@ -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$/]
});

View File

@ -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<NoteEditorProps> = ({ onSave }) => {
@ -80,7 +80,7 @@ export const NoteEditor: React.FC<NoteEditorProps> = ({ onSave }) => {
setContent("");
setImages([]);
setFiles([]);
onSave();
onSave(note.id);
} catch (error) {
console.error("Ошибка сохранения заметки:", error);
showNotification("Ошибка сохранения заметки", "error");
@ -106,7 +106,9 @@ export const NoteEditor: React.FC<NoteEditorProps> = ({ 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<NoteEditorProps> = ({ 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<NoteEditorProps> = ({ 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 {

View File

@ -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<NoteItemProps> = ({
@ -41,6 +42,7 @@ export const NoteItem: React.FC<NoteItemProps> = ({
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<NoteItemProps> = ({
setDeletedImageIds([]);
setDeletedFileIds([]);
onReload();
// Устанавливаем фокус на заметку после сохранения
if (onFocusNote) {
// Небольшая задержка для завершения обновления DOM
setTimeout(() => {
onFocusNote(note.id);
}, 100);
}
} catch (error) {
console.error("Ошибка обновления заметки:", error);
showNotification("Ошибка обновления заметки", "error");

View File

@ -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<NotesListRef, NotesListProps>(
// 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<NotesListRef, NotesListProps>(
onReload={loadNotes}
isSelected={selectedNoteIds.includes(note.id)}
onSelect={onNoteSelect}
onFocusNote={focusNote}
/>
))}
</div>

View File

@ -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);
}
}
};