NoteJS/public/notes.html
Fovway 49834d4ef4 Добавлена поддержка загрузки и управления файлами в заметках
- Реализована возможность загрузки файлов (PDF, DOC, XLS и др.) к заметкам с помощью нового API.
- Добавлены функции для получения, удаления и отображения прикрепленных файлов в интерфейсе заметок.
- Обновлены стили и обработчики событий для работы с файлами в режиме редактирования и создания заметок.
- Улучшена логика обработки файлов, включая проверку на дубликаты и ограничения по размеру.
2025-10-29 00:07:15 +07:00

482 lines
17 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>Заметки - NoteJS</title>
<!-- Предотвращение мерцания темы -->
<script>
(function () {
try {
const savedTheme = localStorage.getItem("theme");
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
const theme = savedTheme || (systemPrefersDark ? "dark" : "light");
if (theme === "dark") {
document.documentElement.setAttribute("data-theme", "dark");
}
} catch (e) {}
})();
</script>
<!-- PWA Meta Tags -->
<meta
name="description"
content="NoteJS - современная система заметок с поддержкой Markdown, изображений, тегов и календаря"
/>
<meta name="theme-color" content="#007bff" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
<meta name="apple-mobile-web-app-title" content="NoteJS" />
<meta name="apple-touch-fullscreen" content="yes" />
<meta name="msapplication-TileColor" content="#007bff" />
<meta name="msapplication-config" content="/browserconfig.xml" />
<meta name="msapplication-TileImage" content="/icons/icon-144x144.png" />
<meta name="application-name" content="NoteJS" />
<meta name="format-detection" content="telephone=no" />
<!-- Icons -->
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/icons/icon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/icons/icon-16x16.png"
/>
<link rel="apple-touch-icon" sizes="57x57" href="/icons/icon-48x48.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/icons/icon-48x48.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/icons/icon-72x72.png" />
<link rel="apple-touch-icon" sizes="76x76" href="/icons/icon-72x72.png" />
<link
rel="apple-touch-icon"
sizes="114x114"
href="/icons/icon-128x128.png"
/>
<link
rel="apple-touch-icon"
sizes="120x120"
href="/icons/icon-128x128.png"
/>
<link
rel="apple-touch-icon"
sizes="144x144"
href="/icons/icon-144x144.png"
/>
<link
rel="apple-touch-icon"
sizes="152x152"
href="/icons/icon-152x152.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/icon-192x192.png"
/>
<link rel="mask-icon" href="/icon.svg" color="#007bff" />
<!-- Manifest -->
<link rel="manifest" href="/manifest.json" />
<!-- Styles -->
<link rel="stylesheet" href="/style.css?v=4" />
<!-- Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/iconify/2.0.0/iconify.min.js"></script>
</head>
<body>
<!-- Кнопка открытия слайдера для мобильной версии -->
<div class="mobile-menu-btn" id="mobileMenuBtn">
<span class="iconify" data-icon="mdi:menu"></span>
</div>
<!-- Слайдер для мобильной версии -->
<div class="mobile-sidebar" id="mobileSidebar">
<div class="sidebar-close-btn" id="sidebarCloseBtn">
<span class="iconify" data-icon="mdi:close"></span>
</div>
<div class="sidebar-content">
<div class="mini-calendar">
<div class="calendar-header">
<button class="calendar-nav" id="prevMonthMobile"></button>
<span class="calendar-month-year" id="monthYearMobile"></span>
<button class="calendar-nav" id="nextMonthMobile"></button>
</div>
<div class="calendar-weekdays">
<div class="calendar-weekday">Пн</div>
<div class="calendar-weekday">Вт</div>
<div class="calendar-weekday">Ср</div>
<div class="calendar-weekday">Чт</div>
<div class="calendar-weekday">Пт</div>
<div class="calendar-weekday">Сб</div>
<div class="calendar-weekday">Вс</div>
</div>
<div class="calendar-days" id="calendarDaysMobile"></div>
</div>
<!-- Секция поиска -->
<div class="search-section">
<div class="search-header">
<span class="search-title"
><span class="iconify" data-icon="mdi:magnify"></span> Поиск</span
>
</div>
<div class="search-container">
<input
type="text"
id="searchInputMobile"
placeholder="Поиск по заметкам..."
class="search-input"
/>
<button
id="clearSearchBtnMobile"
class="clear-search-btn"
style="display: none"
>
</button>
</div>
</div>
<!-- Секция тегов -->
<div class="tags-section">
<div class="tags-header">
<span class="tags-title"
><span class="iconify" data-icon="mdi:tag"></span> Теги</span
>
</div>
<div class="tags-container" id="tagsContainerMobile">
<!-- Теги будут добавлены динамически -->
</div>
</div>
</div>
</div>
<!-- Оверлей для закрытия слайдера -->
<div class="mobile-sidebar-overlay" id="sidebarOverlay"></div>
<div class="container-leftside">
<div class="mini-calendar">
<div class="calendar-header">
<button class="calendar-nav" id="prevMonth"></button>
<span class="calendar-month-year" id="monthYear"></span>
<button class="calendar-nav" id="nextMonth"></button>
</div>
<div class="calendar-weekdays">
<div class="calendar-weekday">Пн</div>
<div class="calendar-weekday">Вт</div>
<div class="calendar-weekday">Ср</div>
<div class="calendar-weekday">Чт</div>
<div class="calendar-weekday">Пт</div>
<div class="calendar-weekday">Сб</div>
<div class="calendar-weekday">Вс</div>
</div>
<div class="calendar-days" id="calendarDays"></div>
</div>
<!-- Секция поиска -->
<div class="search-section">
<div class="search-header">
<span class="search-title"
><span class="iconify" data-icon="mdi:magnify"></span> Поиск</span
>
</div>
<div class="search-container">
<input
type="text"
id="searchInput"
placeholder="Поиск по заметкам..."
class="search-input"
/>
<button
id="clearSearchBtn"
class="clear-search-btn"
style="display: none"
>
</button>
</div>
</div>
<!-- Секция тегов -->
<div class="tags-section">
<div class="tags-header">
<span class="tags-title"
><span class="iconify" data-icon="mdi:tag"></span> Теги</span
>
</div>
<div class="tags-container" id="tagsContainer">
<!-- Теги будут добавлены динамически -->
</div>
</div>
</div>
<div class="center">
<div class="container">
<header class="notes-header">
<div class="notes-header-left">
<span
><span class="iconify" data-icon="mdi:note-text"></span> Мои
заметки</span
>
<div
id="filter-indicator"
class="filter-indicator"
style="display: none"
></div>
</div>
<div class="user-info">
<div
id="user-avatar-container"
class="user-avatar-mini"
style="display: none"
title="Перейти в профиль"
>
<img id="user-avatar" src="" alt="Аватар" loading="lazy" />
</div>
<div
id="user-avatar-placeholder"
class="user-avatar-mini user-avatar-placeholder-mini"
style="display: none"
title="Перейти в профиль"
>
<span class="iconify" data-icon="mdi:account"></span>
</div>
<button
id="theme-toggle-btn"
class="theme-toggle-btn"
title="Переключить тему"
>
<span class="iconify" data-icon="mdi:theme-light-dark"></span>
</button>
<button
id="settings-btn"
class="settings-icon-btn"
title="Настройки"
>
<span class="iconify" data-icon="mdi:cog"></span>
</button>
<form action="/logout" method="POST" style="display: inline">
<button type="submit" class="logout-btn" title="Выйти">
<span class="iconify" data-icon="mdi:logout"></span>
</button>
</form>
</div>
</header>
<div class="main">
<div class="markdown-buttons">
<button class="btnMarkdown" id="boldBtn" title="Жирный текст">
<span class="iconify" data-icon="mdi:format-bold"></span>
</button>
<button class="btnMarkdown" id="italicBtn" title="Курсив">
<span class="iconify" data-icon="mdi:format-italic"></span>
</button>
<button
class="btnMarkdown"
id="strikethroughBtn"
title="Перечеркнутый"
>
<span class="iconify" data-icon="mdi:format-strikethrough"></span>
</button>
<button class="btnMarkdown" id="colorBtn" title="Цвет текста">
<span class="iconify" data-icon="mdi:palette"></span>
</button>
<button class="btnMarkdown" id="spoilerBtn" title="Скрытый текст">
<span class="iconify" data-icon="mdi:eye-off"></span>
</button>
<div class="header-dropdown">
<button class="btnMarkdown" id="headerBtn" title="Заголовок">
<span
class="iconify"
data-icon="mdi:format-header-pound"
></span>
<span
class="iconify"
data-icon="mdi:menu-down"
style="font-size: 10px; margin-left: -2px"
></span>
</button>
<div class="header-dropdown-menu" id="headerDropdown">
<button data-level="1">H1</button>
<button data-level="2">H2</button>
<button data-level="3">H3</button>
<button data-level="4">H4</button>
<button data-level="5">H5</button>
<button data-level="6">H6</button>
</div>
</div>
<button class="btnMarkdown" id="listBtn" title="Список">
<span class="iconify" data-icon="mdi:format-list-bulleted"></span>
</button>
<button
class="btnMarkdown"
id="numberedListBtn"
title="Нумерованный список"
>
<span class="iconify" data-icon="mdi:format-list-numbered"></span>
</button>
<button class="btnMarkdown" id="quoteBtn" title="Цитата">
<span class="iconify" data-icon="mdi:format-quote-close"></span>
</button>
<button class="btnMarkdown" id="codeBtn" title="Код">
<span class="iconify" data-icon="mdi:code-tags"></span>
</button>
<button class="btnMarkdown" id="linkBtn" title="Ссылка">
<span class="iconify" data-icon="mdi:link"></span>
</button>
<button class="btnMarkdown" id="checkboxBtn" title="To-Do список">
<span
class="iconify"
data-icon="mdi:checkbox-marked-outline"
></span>
</button>
<button
class="btnMarkdown"
id="imageBtn"
title="Загрузить изображения"
>
<span class="iconify" data-icon="mdi:image-plus"></span>
</button>
<button class="btnMarkdown" id="fileBtn" title="Прикрепить файлы">
<span class="iconify" data-icon="mdi:file-plus"></span>
</button>
<button class="btnMarkdown" id="previewBtn" title="Предпросмотр">
<span class="iconify" data-icon="mdi:eye"></span>
</button>
</div>
<textarea
class="textInput"
id="noteInput"
placeholder="Ваша заметка..."
></textarea>
<!-- Контейнер для предпросмотра заметки -->
<div
id="notePreviewContainer"
class="note-preview-container"
style="display: none"
>
<div class="note-preview-header">
<span>Предпросмотр:</span>
</div>
<div id="notePreviewContent" class="note-preview-content"></div>
</div>
<!-- Скрытый input для загрузки изображений -->
<input
type="file"
id="imageInput"
accept="image/*"
multiple
style="display: none"
/>
<!-- Скрытый input для загрузки файлов -->
<input
type="file"
id="fileInput"
accept=".pdf,.doc,.docx,.xls,.xlsx,.txt,.zip,.rar,.7z"
multiple
style="display: none"
/>
<!-- Контейнер для отображения загруженных изображений -->
<div
id="imagePreviewContainer"
class="image-preview-container"
style="display: none"
>
<div class="image-preview-header">
<span>Загруженные изображения:</span>
<button
type="button"
id="clearImagesBtn"
class="clear-images-btn"
>
Очистить все
</button>
</div>
<div id="imagePreviewList" class="image-preview-list"></div>
</div>
<!-- Контейнер для отображения прикрепленных файлов -->
<div
id="filePreviewContainer"
class="file-preview-container"
style="display: none"
>
<div class="file-preview-header">
<span>Прикрепленные файлы:</span>
<button type="button" id="clearFilesBtn" class="clear-files-btn">
Очистить все
</button>
</div>
<div id="filePreviewList" class="file-preview-list"></div>
</div>
<div class="save-button-container">
<div class="action-buttons">
<button
class="btnSave btnAI"
id="aiImproveBtn"
title="Улучшить или создать текст через ИИ"
>
<span class="iconify" data-icon="mdi:robot"></span>
Помощь ИИ
</button>
<button class="btnSave" id="saveBtn">Сохранить</button>
</div>
<span class="save-hint">или нажмите Alt + Enter</span>
</div>
</div>
</div>
<div id="notes-container" class="notes-container"></div>
</div>
<div class="footer">
<p>Создатель: <span>Fovway</span></p>
</div>
<!-- Модальное окно для просмотра изображений -->
<div id="imageModal" class="image-modal">
<span class="image-modal-close">&times;</span>
<img class="image-modal-content" id="modalImage" loading="lazy" />
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/11.1.0/marked.min.js"></script>
<script src="/app.js"></script>
<!-- PWA Script -->
<script src="/pwa.js"></script>
<script>
// Проверяем загрузку Iconify
document.addEventListener("DOMContentLoaded", function () {
if (typeof Iconify === "undefined") {
console.warn(
"Iconify не загружен, загружаем альтернативную версию..."
);
const script = document.createElement("script");
script.src =
"https://cdnjs.cloudflare.com/ajax/libs/iconify/2.0.0/iconify.min.js";
document.head.appendChild(script);
}
});
</script>
</body>
</html>