✨ Добавлены функции для работы с многострочными списками и улучшено отображение дат заметок
- Реализована возможность создания нумерованных списков и улучшены функции для работы с многострочными списками. - Обновлены фильтры для отображения заметок по дате, используя поле created_at вместо date. - Оптимизировано отображение дат создания и изменения заметок в единой строке. - Добавлены новые кнопки и обработчики событий для поддержки новых функций в интерфейсе редактирования заметок.
This commit is contained in:
parent
a77bdd3e7b
commit
083ac11ab1
199
public/app.js
199
public/app.js
@ -9,6 +9,7 @@ const italicBtn = document.getElementById("italicBtn");
|
|||||||
const colorBtn = document.getElementById("colorBtn");
|
const colorBtn = document.getElementById("colorBtn");
|
||||||
const headerBtn = document.getElementById("headerBtn");
|
const headerBtn = document.getElementById("headerBtn");
|
||||||
const listBtn = document.getElementById("listBtn");
|
const listBtn = document.getElementById("listBtn");
|
||||||
|
const numberedListBtn = document.getElementById("numberedListBtn");
|
||||||
const quoteBtn = document.getElementById("quoteBtn");
|
const quoteBtn = document.getElementById("quoteBtn");
|
||||||
const codeBtn = document.getElementById("codeBtn");
|
const codeBtn = document.getElementById("codeBtn");
|
||||||
const linkBtn = document.getElementById("linkBtn");
|
const linkBtn = document.getElementById("linkBtn");
|
||||||
@ -288,6 +289,20 @@ function insertMarkdown(tag) {
|
|||||||
const selected = text.substring(start, end);
|
const selected = text.substring(start, end);
|
||||||
const after = text.substring(end);
|
const after = text.substring(end);
|
||||||
|
|
||||||
|
// Мультистрочные преобразования списков (toggle)
|
||||||
|
if (
|
||||||
|
(tag === "1. " || tag === "- " || tag === "- [ ] ") &&
|
||||||
|
selected.includes("\n")
|
||||||
|
) {
|
||||||
|
const mode =
|
||||||
|
tag === "1. " ? "ordered" : tag === "- " ? "unordered" : "todo";
|
||||||
|
const transformed = transformSelection(noteInput, mode);
|
||||||
|
noteInput.value = transformed.newValue;
|
||||||
|
noteInput.setSelectionRange(transformed.newSelStart, transformed.newSelEnd);
|
||||||
|
noteInput.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (selected.startsWith(tag) && selected.endsWith(tag)) {
|
if (selected.startsWith(tag) && selected.endsWith(tag)) {
|
||||||
// Если теги уже есть, удаляем их
|
// Если теги уже есть, удаляем их
|
||||||
noteInput.value = `${before}${selected.slice(
|
noteInput.value = `${before}${selected.slice(
|
||||||
@ -304,6 +319,7 @@ function insertMarkdown(tag) {
|
|||||||
noteInput.setSelectionRange(cursorPosition, cursorPosition + 12);
|
noteInput.setSelectionRange(cursorPosition, cursorPosition + 12);
|
||||||
} else if (
|
} else if (
|
||||||
tag === "- " ||
|
tag === "- " ||
|
||||||
|
tag === "1. " ||
|
||||||
tag === "> " ||
|
tag === "> " ||
|
||||||
tag === "# " ||
|
tag === "# " ||
|
||||||
tag === "- [ ] "
|
tag === "- [ ] "
|
||||||
@ -327,6 +343,7 @@ function insertMarkdown(tag) {
|
|||||||
noteInput.setSelectionRange(cursorPosition, cursorPosition + 3);
|
noteInput.setSelectionRange(cursorPosition, cursorPosition + 3);
|
||||||
} else if (
|
} else if (
|
||||||
tag === "- " ||
|
tag === "- " ||
|
||||||
|
tag === "1. " ||
|
||||||
tag === "> " ||
|
tag === "> " ||
|
||||||
tag === "# " ||
|
tag === "# " ||
|
||||||
tag === "- [ ] "
|
tag === "- [ ] "
|
||||||
@ -408,6 +425,20 @@ function insertMarkdownForEdit(textarea, tag) {
|
|||||||
const selected = text.substring(start, end);
|
const selected = text.substring(start, end);
|
||||||
const after = text.substring(end);
|
const after = text.substring(end);
|
||||||
|
|
||||||
|
// Мультистрочные преобразования списков (toggle)
|
||||||
|
if (
|
||||||
|
(tag === "1. " || tag === "- " || tag === "- [ ] ") &&
|
||||||
|
selected.includes("\n")
|
||||||
|
) {
|
||||||
|
const mode =
|
||||||
|
tag === "1. " ? "ordered" : tag === "- " ? "unordered" : "todo";
|
||||||
|
const transformed = transformSelection(textarea, mode);
|
||||||
|
textarea.value = transformed.newValue;
|
||||||
|
textarea.setSelectionRange(transformed.newSelStart, transformed.newSelEnd);
|
||||||
|
textarea.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (selected.startsWith(tag) && selected.endsWith(tag)) {
|
if (selected.startsWith(tag) && selected.endsWith(tag)) {
|
||||||
// Если теги уже есть, удаляем их
|
// Если теги уже есть, удаляем их
|
||||||
textarea.value = `${before}${selected.slice(
|
textarea.value = `${before}${selected.slice(
|
||||||
@ -424,6 +455,7 @@ function insertMarkdownForEdit(textarea, tag) {
|
|||||||
textarea.setSelectionRange(cursorPosition, cursorPosition + 12);
|
textarea.setSelectionRange(cursorPosition, cursorPosition + 12);
|
||||||
} else if (
|
} else if (
|
||||||
tag === "- " ||
|
tag === "- " ||
|
||||||
|
tag === "1. " ||
|
||||||
tag === "> " ||
|
tag === "> " ||
|
||||||
tag === "# " ||
|
tag === "# " ||
|
||||||
tag === "- [ ] "
|
tag === "- [ ] "
|
||||||
@ -447,6 +479,7 @@ function insertMarkdownForEdit(textarea, tag) {
|
|||||||
textarea.setSelectionRange(cursorPosition, cursorPosition + 3);
|
textarea.setSelectionRange(cursorPosition, cursorPosition + 3);
|
||||||
} else if (
|
} else if (
|
||||||
tag === "- " ||
|
tag === "- " ||
|
||||||
|
tag === "1. " ||
|
||||||
tag === "> " ||
|
tag === "> " ||
|
||||||
tag === "# " ||
|
tag === "# " ||
|
||||||
tag === "- [ ] "
|
tag === "- [ ] "
|
||||||
@ -466,6 +499,109 @@ function insertMarkdownForEdit(textarea, tag) {
|
|||||||
textarea.focus();
|
textarea.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== МУЛЬТИСТРОЧНЫЕ СПИСКИ (TOGGLE) ====================
|
||||||
|
function transformSelection(textarea, mode) {
|
||||||
|
const fullText = textarea.value;
|
||||||
|
const selStart = textarea.selectionStart;
|
||||||
|
const selEnd = textarea.selectionEnd;
|
||||||
|
|
||||||
|
// Расширяем до границ строк
|
||||||
|
let blockStart = fullText.lastIndexOf("\n", selStart - 1);
|
||||||
|
blockStart = blockStart === -1 ? 0 : blockStart + 1;
|
||||||
|
let blockEnd = fullText.indexOf("\n", selEnd);
|
||||||
|
blockEnd = blockEnd === -1 ? fullText.length : blockEnd;
|
||||||
|
|
||||||
|
const block = fullText.substring(blockStart, blockEnd);
|
||||||
|
const lines = block.split("\n");
|
||||||
|
|
||||||
|
const orderedRe = /^(\s*)(\d+)\.\s/;
|
||||||
|
const unorderedRe = /^(\s*)([-*+])\s/;
|
||||||
|
const todoRe = /^(\s*)- \[( |x)\] \s?/i;
|
||||||
|
const anyListPrefixRe = /^(\s*)(- \[(?: |x)\]\s?|[-*+]\s|\d+\.\s)/i;
|
||||||
|
|
||||||
|
function stripAnyPrefix(line) {
|
||||||
|
const m = line.match(anyListPrefixRe);
|
||||||
|
if (!m) return line;
|
||||||
|
return line.slice((m[1] + (m[2] || "")).length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleOrdered(inputLines) {
|
||||||
|
const nonEmpty = inputLines.filter((l) => l.trim() !== "");
|
||||||
|
const allHave =
|
||||||
|
nonEmpty.length > 0 && nonEmpty.every((l) => orderedRe.test(l));
|
||||||
|
if (allHave) {
|
||||||
|
return inputLines.map((l) => {
|
||||||
|
if (!l.trim()) return l;
|
||||||
|
const m = l.match(orderedRe);
|
||||||
|
if (!m) return l;
|
||||||
|
return m[1] + l.slice(m[0].length);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let index = 1;
|
||||||
|
return inputLines.map((l) => {
|
||||||
|
if (!l.trim()) return l;
|
||||||
|
// Снимаем любые префиксы и нумеруем заново
|
||||||
|
const indent = l.match(/^\s*/)?.[0] || "";
|
||||||
|
const content = stripAnyPrefix(l.trimStart());
|
||||||
|
const numbered = `${indent}${index}. ${content}`;
|
||||||
|
index += 1;
|
||||||
|
return numbered;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleUnordered(inputLines) {
|
||||||
|
const nonEmpty = inputLines.filter((l) => l.trim() !== "");
|
||||||
|
const allHave =
|
||||||
|
nonEmpty.length > 0 && nonEmpty.every((l) => unorderedRe.test(l));
|
||||||
|
if (allHave) {
|
||||||
|
return inputLines.map((l) => {
|
||||||
|
if (!l.trim()) return l;
|
||||||
|
const m = l.match(unorderedRe);
|
||||||
|
if (!m) return l;
|
||||||
|
return m[1] + l.slice(m[0].length);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return inputLines.map((l) => {
|
||||||
|
if (!l.trim()) return l;
|
||||||
|
const indent = l.match(/^\s*/)?.[0] || "";
|
||||||
|
const content = stripAnyPrefix(l.trimStart());
|
||||||
|
return `${indent}- ${content}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTodo(inputLines) {
|
||||||
|
const nonEmpty = inputLines.filter((l) => l.trim() !== "");
|
||||||
|
const allHave =
|
||||||
|
nonEmpty.length > 0 && nonEmpty.every((l) => todoRe.test(l));
|
||||||
|
if (allHave) {
|
||||||
|
return inputLines.map((l) => {
|
||||||
|
if (!l.trim()) return l;
|
||||||
|
const m = l.match(todoRe);
|
||||||
|
if (!m) return l;
|
||||||
|
return m[1] + l.slice(m[0].length);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return inputLines.map((l) => {
|
||||||
|
if (!l.trim()) return l;
|
||||||
|
const indent = l.match(/^\s*/)?.[0] || "";
|
||||||
|
const content = stripAnyPrefix(l.trimStart());
|
||||||
|
return `${indent}- [ ] ${content}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let newLines;
|
||||||
|
if (mode === "ordered") newLines = toggleOrdered(lines);
|
||||||
|
else if (mode === "unordered") newLines = toggleUnordered(lines);
|
||||||
|
else newLines = toggleTodo(lines);
|
||||||
|
|
||||||
|
const newBlock = newLines.join("\n");
|
||||||
|
const newValue =
|
||||||
|
fullText.slice(0, blockStart) + newBlock + fullText.slice(blockEnd);
|
||||||
|
const newSelStart = blockStart;
|
||||||
|
const newSelEnd = blockStart + newBlock.length;
|
||||||
|
return { newValue, newSelStart, newSelEnd };
|
||||||
|
}
|
||||||
|
|
||||||
// Обработчики для кнопок markdown
|
// Обработчики для кнопок markdown
|
||||||
boldBtn.addEventListener("click", function () {
|
boldBtn.addEventListener("click", function () {
|
||||||
insertMarkdown("**");
|
insertMarkdown("**");
|
||||||
@ -487,6 +623,10 @@ listBtn.addEventListener("click", function () {
|
|||||||
insertMarkdown("- ");
|
insertMarkdown("- ");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
numberedListBtn.addEventListener("click", function () {
|
||||||
|
insertMarkdown("1. ");
|
||||||
|
});
|
||||||
|
|
||||||
quoteBtn.addEventListener("click", function () {
|
quoteBtn.addEventListener("click", function () {
|
||||||
insertMarkdown("> ");
|
insertMarkdown("> ");
|
||||||
});
|
});
|
||||||
@ -934,9 +1074,12 @@ async function renderNotes(notes) {
|
|||||||
let notesToDisplay = notes;
|
let notesToDisplay = notes;
|
||||||
|
|
||||||
if (selectedDateFilter) {
|
if (selectedDateFilter) {
|
||||||
notesToDisplay = notesToDisplay.filter(
|
notesToDisplay = notesToDisplay.filter((note) => {
|
||||||
(note) => note.date === selectedDateFilter
|
if (note.created_at) {
|
||||||
);
|
return formatDateFromTimestamp(note.created_at) === selectedDateFilter;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedTagFilter) {
|
if (selectedTagFilter) {
|
||||||
@ -993,10 +1136,9 @@ async function renderNotes(notes) {
|
|||||||
imagesHtml += "</div>";
|
imagesHtml += "</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Форматируем дату создания и дату изменения
|
// Форматируем дату создания и дату изменения (в одну строку)
|
||||||
let dateDisplay = `${note.date} ${note.time}`;
|
let dateDisplay = `${note.date} ${note.time}`;
|
||||||
if (note.updated_at && note.created_at !== note.updated_at) {
|
if (note.updated_at && note.created_at !== note.updated_at) {
|
||||||
// Если дата изменения отличается от даты создания, показываем обе даты
|
|
||||||
const createdDate = new Date(note.created_at);
|
const createdDate = new Date(note.created_at);
|
||||||
const updatedDate = new Date(note.updated_at);
|
const updatedDate = new Date(note.updated_at);
|
||||||
|
|
||||||
@ -1011,19 +1153,19 @@ async function renderNotes(notes) {
|
|||||||
|
|
||||||
dateDisplay = `Создано: ${formatDate(
|
dateDisplay = `Создано: ${formatDate(
|
||||||
createdDate
|
createdDate
|
||||||
)}<br>Изменено: ${formatDate(updatedDate)}`;
|
)} • Изменено: ${formatDate(updatedDate)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const noteHtml = `
|
const noteHtml = `
|
||||||
<div id="note" class="container" data-note-id="${note.id}">
|
<div id="note" class="container" data-note-id="${note.id}">
|
||||||
<div class="date">
|
<div class="date">
|
||||||
${dateDisplay}
|
<span class="date-text">${dateDisplay}</span>
|
||||||
<div id="editBtn" class="notesHeaderBtn" data-id="${
|
<div id="editBtn" class="notesHeaderBtn" data-id="${
|
||||||
note.id
|
note.id
|
||||||
}">Редактировать</div>
|
}">Ред.</div>
|
||||||
<div id="deleteBtn" class="notesHeaderBtn" data-id="${
|
<div id="deleteBtn" class="notesHeaderBtn" data-id="${
|
||||||
note.id
|
note.id
|
||||||
}">Удалить</div>
|
}">Удал.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="textNote" data-original-content="${note.content.replace(
|
<div class="textNote" data-original-content="${note.content.replace(
|
||||||
/"/g,
|
/"/g,
|
||||||
@ -1151,6 +1293,11 @@ function addNoteEventListeners() {
|
|||||||
{ id: "editColorBtn", icon: "mdi:palette", tag: "color" },
|
{ id: "editColorBtn", icon: "mdi:palette", tag: "color" },
|
||||||
{ id: "editHeaderBtn", icon: "mdi:format-header-1", tag: "# " },
|
{ id: "editHeaderBtn", icon: "mdi:format-header-1", tag: "# " },
|
||||||
{ id: "editListBtn", icon: "mdi:format-list-bulleted", tag: "- " },
|
{ id: "editListBtn", icon: "mdi:format-list-bulleted", tag: "- " },
|
||||||
|
{
|
||||||
|
id: "editNumberedListBtn",
|
||||||
|
icon: "mdi:format-list-numbered",
|
||||||
|
tag: "1. ",
|
||||||
|
},
|
||||||
{ id: "editQuoteBtn", icon: "mdi:format-quote-close", tag: "> " },
|
{ id: "editQuoteBtn", icon: "mdi:format-quote-close", tag: "> " },
|
||||||
{ id: "editCodeBtn", icon: "mdi:code-tags", tag: "`" },
|
{ id: "editCodeBtn", icon: "mdi:code-tags", tag: "`" },
|
||||||
{ id: "editLinkBtn", icon: "mdi:link", tag: "[Текст ссылки](URL)" },
|
{ id: "editLinkBtn", icon: "mdi:link", tag: "[Текст ссылки](URL)" },
|
||||||
@ -1231,6 +1378,9 @@ function addNoteEventListeners() {
|
|||||||
pattern === listPatterns[4]
|
pattern === listPatterns[4]
|
||||||
) {
|
) {
|
||||||
listType = "unordered";
|
listType = "unordered";
|
||||||
|
} else if (pattern === listPatterns[7]) {
|
||||||
|
// Нумерованный список всегда начинается с 1.
|
||||||
|
listType = "numbered";
|
||||||
} else {
|
} else {
|
||||||
listType = "ordered";
|
listType = "ordered";
|
||||||
}
|
}
|
||||||
@ -1282,6 +1432,9 @@ function addNoteEventListeners() {
|
|||||||
nextNumber.toString()
|
nextNumber.toString()
|
||||||
);
|
);
|
||||||
newMarker = indent + numberStr + ". ";
|
newMarker = indent + numberStr + ". ";
|
||||||
|
} else if (listType === "numbered") {
|
||||||
|
// Для нумерованного списка всегда начинаем с 1.
|
||||||
|
newMarker = indent + "1. ";
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea.value = beforeCursor + "\n" + newMarker + afterCursor;
|
textarea.value = beforeCursor + "\n" + newMarker + afterCursor;
|
||||||
@ -1879,6 +2032,7 @@ noteInput.addEventListener("keydown", function (event) {
|
|||||||
/^(\s*)\+ /, // Неупорядоченный список: +
|
/^(\s*)\+ /, // Неупорядоченный список: +
|
||||||
/^(\s*)(\d+)\. /, // Упорядоченный список: 1. 2. 3.
|
/^(\s*)(\d+)\. /, // Упорядоченный список: 1. 2. 3.
|
||||||
/^(\s*)(\w+)\. /, // Буквенный список: a. b. c.
|
/^(\s*)(\w+)\. /, // Буквенный список: a. b. c.
|
||||||
|
/^(\s*)1\. /, // Нумерованный список (начинается с 1.)
|
||||||
];
|
];
|
||||||
|
|
||||||
let listMatch = null;
|
let listMatch = null;
|
||||||
@ -1896,6 +2050,9 @@ noteInput.addEventListener("keydown", function (event) {
|
|||||||
pattern === listPatterns[4]
|
pattern === listPatterns[4]
|
||||||
) {
|
) {
|
||||||
listType = "unordered";
|
listType = "unordered";
|
||||||
|
} else if (pattern === listPatterns[7]) {
|
||||||
|
// Нумерованный список всегда начинается с 1.
|
||||||
|
listType = "numbered";
|
||||||
} else {
|
} else {
|
||||||
listType = "ordered";
|
listType = "ordered";
|
||||||
}
|
}
|
||||||
@ -1944,6 +2101,9 @@ noteInput.addEventListener("keydown", function (event) {
|
|||||||
const nextNumber = number + 1;
|
const nextNumber = number + 1;
|
||||||
const numberStr = listMatch[2].replace(/\d+/, nextNumber.toString());
|
const numberStr = listMatch[2].replace(/\d+/, nextNumber.toString());
|
||||||
newMarker = indent + numberStr + ". ";
|
newMarker = indent + numberStr + ". ";
|
||||||
|
} else if (listType === "numbered") {
|
||||||
|
// Для нумерованного списка всегда начинаем с 1.
|
||||||
|
newMarker = indent + "1. ";
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea.value = beforeCursor + "\n" + newMarker + afterCursor;
|
textarea.value = beforeCursor + "\n" + newMarker + afterCursor;
|
||||||
@ -2068,6 +2228,15 @@ async function loadUserInfo() {
|
|||||||
// Календарь
|
// Календарь
|
||||||
let currentDate = new Date();
|
let currentDate = new Date();
|
||||||
|
|
||||||
|
// Функция для преобразования timestamp в формат dd.mm.yyyy
|
||||||
|
function formatDateFromTimestamp(timestamp) {
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
const day = String(date.getDate()).padStart(2, "0");
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||||
|
const year = date.getFullYear();
|
||||||
|
return `${day}.${month}.${year}`;
|
||||||
|
}
|
||||||
|
|
||||||
// Функция для отображения календаря
|
// Функция для отображения календаря
|
||||||
function renderCalendar() {
|
function renderCalendar() {
|
||||||
const calendarDays = document.getElementById("calendarDays");
|
const calendarDays = document.getElementById("calendarDays");
|
||||||
@ -2110,10 +2279,12 @@ function renderCalendar() {
|
|||||||
// Очищаем календарь
|
// Очищаем календарь
|
||||||
calendarDays.innerHTML = "";
|
calendarDays.innerHTML = "";
|
||||||
|
|
||||||
// Создаём Set дат, когда были созданы заметки
|
// Создаём Set дат, когда были созданы заметки (используем created_at)
|
||||||
const noteDates = new Set();
|
const noteDates = new Set();
|
||||||
allNotes.forEach((note) => {
|
allNotes.forEach((note) => {
|
||||||
noteDates.add(note.date);
|
if (note.created_at) {
|
||||||
|
noteDates.add(formatDateFromTimestamp(note.created_at));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Получаем последний день предыдущего месяца
|
// Получаем последний день предыдущего месяца
|
||||||
@ -2429,10 +2600,12 @@ function renderCalendarMobile() {
|
|||||||
// Очищаем календарь
|
// Очищаем календарь
|
||||||
calendarDays.innerHTML = "";
|
calendarDays.innerHTML = "";
|
||||||
|
|
||||||
// Создаём Set дат, когда были созданы заметки
|
// Создаём Set дат, когда были созданы заметки (используем created_at)
|
||||||
const noteDates = new Set();
|
const noteDates = new Set();
|
||||||
allNotes.forEach((note) => {
|
allNotes.forEach((note) => {
|
||||||
noteDates.add(note.date);
|
if (note.created_at) {
|
||||||
|
noteDates.add(formatDateFromTimestamp(note.created_at));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Получаем последний день предыдущего месяца
|
// Получаем последний день предыдущего месяца
|
||||||
|
|||||||
@ -8,6 +8,15 @@
|
|||||||
/>
|
/>
|
||||||
<title>Вход в систему заметок</title>
|
<title>Вход в систему заметок</title>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
try {
|
||||||
|
if (localStorage.getItem("isAuthenticated") === "true") {
|
||||||
|
// Используем replace, чтобы не оставлять страницу логина в истории
|
||||||
|
window.location.replace("/notes");
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- PWA Meta Tags -->
|
<!-- PWA Meta Tags -->
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
|
|||||||
@ -267,6 +267,13 @@
|
|||||||
<button class="btnMarkdown" id="listBtn" title="Список">
|
<button class="btnMarkdown" id="listBtn" title="Список">
|
||||||
<span class="iconify" data-icon="mdi:format-list-bulleted"></span>
|
<span class="iconify" data-icon="mdi:format-list-bulleted"></span>
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
class="btnMarkdown"
|
||||||
|
id="numberedListBtn"
|
||||||
|
title="Нумерованный список"
|
||||||
|
>
|
||||||
|
<span class="iconify" data-icon="mdi:format-list-numbered"></span>
|
||||||
|
</button>
|
||||||
<button class="btnMarkdown" id="quoteBtn" title="Цитата">
|
<button class="btnMarkdown" id="quoteBtn" title="Цитата">
|
||||||
<span class="iconify" data-icon="mdi:format-quote-close"></span>
|
<span class="iconify" data-icon="mdi:format-quote-close"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -8,6 +8,14 @@
|
|||||||
/>
|
/>
|
||||||
<title>Регистрация - NoteJS</title>
|
<title>Регистрация - NoteJS</title>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
try {
|
||||||
|
if (localStorage.getItem("isAuthenticated") === "true") {
|
||||||
|
window.location.replace("/notes");
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- PWA Meta Tags -->
|
<!-- PWA Meta Tags -->
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
|
|||||||
@ -376,11 +376,17 @@ textarea:focus {
|
|||||||
.date {
|
.date {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: grey;
|
color: grey;
|
||||||
white-space: pre-line;
|
white-space: nowrap;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date .date-text {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notesHeaderBtn {
|
.notesHeaderBtn {
|
||||||
@ -474,7 +480,7 @@ textarea:focus {
|
|||||||
.textNote li {
|
.textNote li {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 0.5;
|
line-height: 1;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
@ -548,7 +554,7 @@ textarea:focus {
|
|||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin-left: -20px;
|
margin-left: -20px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 0.5;
|
line-height: 1.5;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,7 +591,7 @@ textarea:focus {
|
|||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin-left: -20px;
|
margin-left: -20px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 0.5;
|
line-height: 1.5;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1257,7 +1263,6 @@ textarea:focus {
|
|||||||
.mobile-sidebar .tag {
|
.mobile-sidebar .tag {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
background-color: #e7f3ff;
|
|
||||||
color: var(--accent-color, #007bff);
|
color: var(--accent-color, #007bff);
|
||||||
border: 1px solid var(--accent-color, #007bff);
|
border: 1px solid var(--accent-color, #007bff);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
|||||||
@ -563,9 +563,9 @@ app.get("/api/notes/search", requireAuth, (req, res) => {
|
|||||||
params.push(`%#${tag.trim()}%`);
|
params.push(`%#${tag.trim()}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Поиск по дате
|
// Поиск по дате (используем created_at вместо date)
|
||||||
if (date && date.trim()) {
|
if (date && date.trim()) {
|
||||||
whereClause += " AND n.date = ?";
|
whereClause += " AND strftime('%d.%m.%Y', n.created_at) = ?";
|
||||||
params.push(date.trim());
|
params.push(date.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user