diff --git a/public/app.js b/public/app.js index 8b96b43..d91e9f2 100644 --- a/public/app.js +++ b/public/app.js @@ -450,6 +450,53 @@ function renderNotes(notes) { // Добавляем обработчики кликов для тегов в заметках addTagClickListeners(); + + // Обрабатываем длинные заметки + handleLongNotes(); +} + +// Функция для обработки длинных заметок +function handleLongNotes() { + const MAX_HEIGHT = 300; // Максимальная высота в пикселях + + document.querySelectorAll(".textNote").forEach((noteElement) => { + // Проверяем высоту контента + const contentHeight = noteElement.scrollHeight; + + if (contentHeight > MAX_HEIGHT) { + // Добавляем класс для сворачивания + noteElement.classList.add("collapsed"); + + // Создаем кнопку "Показать все" + const showMoreBtn = document.createElement("button"); + showMoreBtn.classList.add("show-more-btn"); + showMoreBtn.textContent = "Показать полностью"; + showMoreBtn.setAttribute("data-expanded", "false"); + + // Вставляем кнопку после заметки + noteElement.parentElement.insertBefore( + showMoreBtn, + noteElement.nextSibling + ); + + // Обработчик клика на кнопку + showMoreBtn.addEventListener("click", function () { + const isExpanded = this.getAttribute("data-expanded") === "true"; + + if (isExpanded) { + // Сворачиваем + noteElement.classList.add("collapsed"); + this.textContent = "Показать полностью"; + this.setAttribute("data-expanded", "false"); + } else { + // Разворачиваем + noteElement.classList.remove("collapsed"); + this.textContent = "Свернуть"; + this.setAttribute("data-expanded", "true"); + } + }); + } + }); } // Функция для добавления обработчиков событий к заметкам @@ -519,29 +566,26 @@ function addNoteEventListeners() { textarea.addEventListener("input", function () { autoExpandTextarea(textarea); }); - autoExpandTextarea(textarea); + + // Контейнер для кнопки сохранения и подсказки + const saveButtonContainer = document.createElement("div"); + saveButtonContainer.classList.add("save-button-container"); // Кнопка сохранить const saveEditBtn = document.createElement("button"); saveEditBtn.textContent = "Сохранить"; saveEditBtn.classList.add("btnSave"); - // Очищаем текущий контент и вставляем markdown кнопки, textarea и кнопку сохранить - noteContent.innerHTML = ""; - noteContent.appendChild(markdownButtonsContainer); - noteContent.appendChild(textarea); - noteContent.appendChild(saveEditBtn); + // Подсказка о горячей клавише + const saveHint = document.createElement("span"); + saveHint.classList.add("save-hint"); + saveHint.textContent = "или нажмите Alt + Enter"; - // Добавляем обработчики для markdown кнопок редактирования - markdownButtons.forEach((button) => { - const btn = document.getElementById(button.id); - btn.addEventListener("click", function () { - insertMarkdownForEdit(textarea, button.tag); - }); - }); + saveButtonContainer.appendChild(saveEditBtn); + saveButtonContainer.appendChild(saveHint); - // Обработчик сохранения редактирования - saveEditBtn.addEventListener("click", async function () { + // Функция сохранения для редактирования + const saveEditNote = async function () { if (textarea.value.trim() !== "") { try { const { date, time } = getFormattedDateTime(); @@ -568,7 +612,38 @@ function addNoteEventListeners() { alert("Ошибка сохранения заметки"); } } + }; + + // Обработчик горячей клавиши Alt+Enter для сохранения редактирования + textarea.addEventListener("keydown", function (event) { + if (event.altKey && event.key === "Enter") { + event.preventDefault(); + saveEditNote(); + } }); + + // Очищаем текущий контент и вставляем markdown кнопки, textarea и контейнер с кнопкой сохранить + noteContent.innerHTML = ""; + noteContent.appendChild(markdownButtonsContainer); + noteContent.appendChild(textarea); + noteContent.appendChild(saveButtonContainer); + + // Применяем авторасширение после добавления в DOM + setTimeout(() => { + autoExpandTextarea(textarea); + textarea.focus(); + }, 0); + + // Добавляем обработчики для markdown кнопок редактирования + markdownButtons.forEach((button) => { + const btn = document.getElementById(button.id); + btn.addEventListener("click", function () { + insertMarkdownForEdit(textarea, button.tag); + }); + }); + + // Обработчик сохранения редактирования + saveEditBtn.addEventListener("click", saveEditNote); }); }); } diff --git a/public/style.css b/public/style.css index a61ce1f..37de9e4 100644 --- a/public/style.css +++ b/public/style.css @@ -367,6 +367,45 @@ textarea:focus { .textNote { margin-top: 10px; white-space: pre-wrap; + position: relative; + transition: max-height 0.3s ease; +} + +.textNote.collapsed { + max-height: 300px; + overflow: hidden; +} + +.textNote.collapsed::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 80px; + background: linear-gradient(to bottom, transparent, white); + pointer-events: none; +} + +.show-more-btn { + display: block; + width: 100%; + margin-top: 10px; + padding: 8px; + background-color: #f8f9fa; + border: 1px solid #ddd; + border-radius: 5px; + color: #007bff; + font-size: 14px; + cursor: pointer; + transition: all 0.3s ease; + text-align: center; +} + +.show-more-btn:hover { + background-color: #007bff; + color: white; + border-color: #007bff; } /* Убираем стандартные отступы для абзацев */