diff --git a/public/app.js b/public/app.js
index ec8b8e1..9eeb3ed 100644
--- a/public/app.js
+++ b/public/app.js
@@ -815,6 +815,7 @@ function addNoteEventListeners() {
{ id: "editQuoteBtn", icon: "mdi:format-quote-close", tag: "> " },
{ id: "editCodeBtn", icon: "mdi:code-tags", tag: "`" },
{ id: "editLinkBtn", icon: "mdi:link", tag: "[Текст ссылки](URL)" },
+ { id: "editImageBtn", icon: "mdi:image-plus", tag: "image" },
];
markdownButtons.forEach((button) => {
@@ -837,6 +838,36 @@ function addNoteEventListeners() {
autoExpandTextarea(textarea);
});
+ // Создаем элементы для загрузки изображений в режиме редактирования
+ const editImageInput = document.createElement("input");
+ editImageInput.type = "file";
+ editImageInput.accept = "image/*";
+ editImageInput.multiple = true;
+ editImageInput.style.display = "none";
+ editImageInput.id = `editImageInput-${noteId}`;
+
+ const editImagePreviewContainer = document.createElement("div");
+ editImagePreviewContainer.id = `editImagePreviewContainer-${noteId}`;
+ editImagePreviewContainer.classList.add("image-preview-container");
+ editImagePreviewContainer.style.display = "none";
+
+ const editImagePreviewHeader = document.createElement("div");
+ editImagePreviewHeader.classList.add("image-preview-header");
+ editImagePreviewHeader.innerHTML = `
+ Новые изображения:
+
+ `;
+
+ const editImagePreviewList = document.createElement("div");
+ editImagePreviewList.id = `editImagePreviewList-${noteId}`;
+ editImagePreviewList.classList.add("image-preview-list");
+
+ editImagePreviewContainer.appendChild(editImagePreviewHeader);
+ editImagePreviewContainer.appendChild(editImagePreviewList);
+
+ // Массив для хранения новых изображений в режиме редактирования
+ const editSelectedImages = [];
+
// Контейнер для кнопки сохранения и подсказки
const saveButtonContainer = document.createElement("div");
saveButtonContainer.classList.add("save-button-container");
@@ -854,9 +885,73 @@ function addNoteEventListeners() {
saveButtonContainer.appendChild(saveEditBtn);
saveButtonContainer.appendChild(saveHint);
+ // Функция обновления превью изображений для режима редактирования
+ const updateEditImagePreview = function() {
+ if (editSelectedImages.length === 0) {
+ editImagePreviewContainer.style.display = "none";
+ return;
+ }
+
+ editImagePreviewContainer.style.display = "block";
+ editImagePreviewList.innerHTML = "";
+
+ editSelectedImages.forEach((file, index) => {
+ const reader = new FileReader();
+ reader.onload = function (e) {
+ const previewItem = document.createElement("div");
+ previewItem.className = "image-preview-item";
+
+ previewItem.innerHTML = `
+
+
+
${file.name}
+ `;
+
+ editImagePreviewList.appendChild(previewItem);
+
+ // Обработчик удаления изображения
+ const removeBtn = previewItem.querySelector(".remove-image-btn");
+ removeBtn.addEventListener("click", function () {
+ editSelectedImages.splice(index, 1);
+ updateEditImagePreview();
+ });
+ };
+ reader.readAsDataURL(file);
+ });
+ };
+
+ // Функция загрузки изображений для режима редактирования
+ const uploadEditImages = async function(noteId) {
+ if (editSelectedImages.length === 0) {
+ return [];
+ }
+
+ const formData = new FormData();
+ editSelectedImages.forEach(file => {
+ formData.append("images", file);
+ });
+
+ try {
+ const response = await fetch(`/api/notes/${noteId}/images`, {
+ method: "POST",
+ body: formData,
+ });
+
+ if (!response.ok) {
+ throw new Error("Ошибка загрузки изображений");
+ }
+
+ const result = await response.json();
+ return result.images || [];
+ } catch (error) {
+ console.error("Ошибка загрузки изображений:", error);
+ return [];
+ }
+ };
+
// Функция сохранения для редактирования
const saveEditNote = async function () {
- if (textarea.value.trim() !== "") {
+ if (textarea.value.trim() !== "" || editSelectedImages.length > 0) {
try {
const { date, time } = getFormattedDateTime();
const response = await fetch(`/api/notes/${noteId}`, {
@@ -865,7 +960,7 @@ function addNoteEventListeners() {
"Content-Type": "application/json",
},
body: JSON.stringify({
- content: textarea.value,
+ content: textarea.value || " ", // Минимальный контент, если только изображения
date: date,
time: time,
}),
@@ -875,6 +970,11 @@ function addNoteEventListeners() {
throw new Error("Ошибка сохранения заметки");
}
+ // Загружаем новые изображения, если они есть
+ if (editSelectedImages.length > 0) {
+ await uploadEditImages(noteId);
+ }
+
// Перезагружаем заметки
await loadNotes(true);
} catch (error) {
@@ -892,10 +992,31 @@ function addNoteEventListeners() {
}
});
- // Очищаем текущий контент и вставляем markdown кнопки, textarea и контейнер с кнопкой сохранить
+ // Обработчики для загрузки изображений в режиме редактирования
+ editImageInput.addEventListener("change", function (event) {
+ const files = Array.from(event.target.files);
+ files.forEach(file => {
+ if (file.type.startsWith('image/')) {
+ editSelectedImages.push(file);
+ }
+ });
+ updateEditImagePreview();
+ });
+
+ // Обработчик очистки всех изображений в режиме редактирования
+ const editClearImagesBtn = editImagePreviewHeader.querySelector(`#editClearImagesBtn-${noteId}`);
+ editClearImagesBtn.addEventListener("click", function () {
+ editSelectedImages.length = 0;
+ updateEditImagePreview();
+ editImageInput.value = "";
+ });
+
+ // Очищаем текущий контент и вставляем markdown кнопки, textarea, элементы для изображений и контейнер с кнопкой сохранить
noteContent.innerHTML = "";
noteContent.appendChild(markdownButtonsContainer);
noteContent.appendChild(textarea);
+ noteContent.appendChild(editImageInput);
+ noteContent.appendChild(editImagePreviewContainer);
noteContent.appendChild(saveButtonContainer);
// Применяем авторасширение после добавления в DOM
@@ -908,7 +1029,12 @@ function addNoteEventListeners() {
markdownButtons.forEach((button) => {
const btn = document.getElementById(button.id);
btn.addEventListener("click", function () {
- insertMarkdownForEdit(textarea, button.tag);
+ if (button.tag === "image") {
+ // Для кнопки изображения открываем диалог выбора файлов
+ editImageInput.click();
+ } else {
+ insertMarkdownForEdit(textarea, button.tag);
+ }
});
});