Итерация 0: план, журналы, gitignore
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
# Сборка
|
||||
build/
|
||||
build-*/
|
||||
cmake-build-*/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.user
|
||||
*.autosave
|
||||
|
||||
# Qt
|
||||
.qmlcache/
|
||||
*.qmlc
|
||||
*.jsc
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Служебные артефакты
|
||||
*.log
|
||||
@@ -0,0 +1,13 @@
|
||||
# CHANGELOG
|
||||
|
||||
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.0.0/).
|
||||
Версия проекта: `0.0.0` (разработка не начата).
|
||||
|
||||
## [0.0.0] - 2026-08-16
|
||||
|
||||
### Добавлено
|
||||
- Составлен полный план разработки (PLAN.md): архитектура, технологический стек
|
||||
(Qt 6.8 QML, libgit2 + libssh2, cmark-gfm, KSyntaxHighlighting, SQLite), 16 фаз.
|
||||
- Заведён журнал итераций (done.md).
|
||||
- Инициализирован локальный git-репозиторий проекта (удалённый Gitea-репозиторий
|
||||
будет добавлен позже).
|
||||
@@ -0,0 +1,239 @@
|
||||
# PLAN — Текстовый редактор/заметочник «Flora»
|
||||
|
||||
Минималистичный markdown-заметочник с git-историей, синхронизацией и графом связей.
|
||||
Аналог Obsidian, но лёгкий: быстрый запуск на любом железе, мгновенное открытие заметок.
|
||||
|
||||
## Технологии
|
||||
|
||||
| Компонент | Решение |
|
||||
|---|---|
|
||||
| Язык | C++17 |
|
||||
| UI | Qt 6.8 LTS, Qt Quick / QML |
|
||||
| Сборка | CMake |
|
||||
| Markdown-парсер | cmark-gfm (CommonMark + GFM) |
|
||||
| Git | libgit2 (с поддержкой SSH через libssh2 + OpenSSL) |
|
||||
| SSH | libssh2 + OpenSSL (генерация ключей, known_hosts) |
|
||||
| Подсветка кода | KSyntaxHighlighting (KDE, LGPL — совместимо с GPL-3.0) |
|
||||
| БД | SQLite (Qt SQL) — метаданные, теги, связи, свойства |
|
||||
| Diff | libgit2 diff между blob версии и текущим файлом |
|
||||
| PDF | QtPdf (предпросмотр) + QPdfWriter (экспорт) |
|
||||
| Лицензия | GPL-3.0 |
|
||||
|
||||
Целевые платформы: macOS, Windows, Linux, Android.
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
Flora/
|
||||
├── CMakeLists.txt, LICENSE (GPL-3.0), README, .gitignore
|
||||
├── src/
|
||||
│ ├── main.cpp
|
||||
│ ├── app/ (VaultManager, WindowController)
|
||||
│ ├── core/ (FileStore, TreeModel, DocumentManager, SettingsStore)
|
||||
│ ├── git/GitManager.{h,cpp} # libgit2
|
||||
│ ├── markdown/ (MdParser@cmark-gfm, HtmlRenderer, SyntaxHighlight)
|
||||
│ ├── db/Database.{h,cpp} # SQLite: теги, связи, свойства
|
||||
│ ├── editor/ (DiffRenderer)
|
||||
│ ├── sync/ (SyncManager, WebDavSync, SyncthingClient, GitHubSync,
|
||||
│ │ SshManager, ErrorCatalog)
|
||||
│ └── export/ (HtmlExporter, PdfExporter)
|
||||
├── qml/
|
||||
│ ├── MainWindow.qml, VaultWindow.qml
|
||||
│ ├── wizard/WelcomeWizard.qml, ProviderSetupGuide.qml, SshSetupGuide.qml
|
||||
│ ├── panels/ FileTreePanel, TabsBar, EditorPanel, FormatToolbar,
|
||||
│ │ CalendarPanel, LinksTagsPanel, GraphPanel, TableEditor
|
||||
│ └── dialogs/ NameDialog, ConfirmDialog, HistoryDiffDialog, SyncDialog,
|
||||
│ VaultSwitcherPopup
|
||||
├── third_party/ cmark/ libgit2/ libssh2/ openssl/ ksyntaxhighlighting/
|
||||
├── tests/ (QtTest + Catch2)
|
||||
└── packaging/ (macOS / Windows / Linux / Android)
|
||||
```
|
||||
|
||||
## Функциональные требования (общие)
|
||||
|
||||
- Левая панель (файловое дерево) — 15% экрана, ширина меняется мышью; центральная — 70%;
|
||||
правая — 15%. Размеры панелей запоминаются между сессиями.
|
||||
- Автосохранение файла каждые 5 секунд.
|
||||
- Хранилище = локальная папка, внутри которой git-репозиторий (создаётся автоматически).
|
||||
- Все сохранения — автоматически, авто-коммиты в git.
|
||||
- Редактор: режимы «редактирование» и «просмотр» (рендер как HTML в браузере).
|
||||
- Файлы любого формата открываются корректно: md — редактор, html/pdf — предпросмотр.
|
||||
|
||||
## Фазы
|
||||
|
||||
### Фаза 0 — Каркас
|
||||
1. Репозиторий, LICENSE (GPL-3.0), README, .gitignore.
|
||||
2. Подключение cmark, libgit2 (с SSH), libssh2, OpenSSL, KSyntaxHighlighting как подпроектов
|
||||
(статическая сборка).
|
||||
3. Скелет: главное меню вверху (Файл / Правка / Вид / Справка), SplitView 15/70/15,
|
||||
кнопка «+ хранилище» внизу слева.
|
||||
|
||||
### Фаза 1 — Первый запуск (мастер)
|
||||
4. WelcomeWizard: выбор локальной папки (новая или с файлами) → предложение подключить
|
||||
GitHub/GitLab/Gitea, Nextcloud/WebDAV, Syncthing → git-репозиторий создаётся
|
||||
автоматически → открытие хранилища. Выбор запоминается.
|
||||
5. Подключение git-провайдера — два режима на выбор:
|
||||
- HTTPS + токен (через ProviderSetupGuide);
|
||||
- SSH-ключ (через SshSetupGuide) — если токен создать невозможно.
|
||||
Подключение можно пропустить; позже доступно через кнопку хранилища (внизу слева) →
|
||||
«Настройки хранилища» → «Подключить синхронизацию».
|
||||
|
||||
#### 5.1. HTTPS + токен (ProviderSetupGuide)
|
||||
Пошаговая инструкция для каждого провайдера:
|
||||
- Шаг 1 — создать токен: точная ссылка на страницу токенов и необходимые права:
|
||||
- GitHub: github.com/settings/tokens (Fine-grained: `Contents: Read and write` / классический scope `repo`);
|
||||
- GitLab: Настройки → Access Tokens (scope `api` или `read_repository`+`write_repository`);
|
||||
- Gitea: Настройки → Приложения → Personal Access Token (scope `repo`).
|
||||
- Шаг 2 — создать репозиторий (пустой, без README/.gitignore — иначе конфликт истории).
|
||||
- Шаг 3 — для self-hosted GitLab/Gitea: URL инстанса (включая http://localhost:3000), пометка про HTTPS.
|
||||
- Шаг 4 — вставить токен, кнопка «Проверить соединение» (реальный API-запрос: проверка
|
||||
токена и доступности репо), после успеха — авто-push и настройка автосинка.
|
||||
- Кнопки: «Скопировать команды для терминала» (git remote add/push вручную),
|
||||
«Назад/Пропустить».
|
||||
|
||||
#### 5.2. SSH-ключ (SshSetupGuide)
|
||||
- Использовать существующий ключ (путь + опц. passphrase, хранится в системном keychain /
|
||||
настройках с предупреждением) ИЛИ сгенерировать новый в приложении
|
||||
(ed25519/RSA через OpenSSL, работает и на Android, без ssh-keygen).
|
||||
- Добавить публичный ключ в аккаунт: инструкция + кнопка «Скопировать публичный ключ»:
|
||||
- GitHub: Settings → SSH and GPG keys;
|
||||
- GitLab: Preferences → SSH Keys;
|
||||
- Gitea: Настройки → SSH-ключи.
|
||||
- Параметры: хост (github.com, gitlab.com, custom), порт (22/другой), имя пользователя
|
||||
(`git` по умолчанию), строка подключения вида `git@github.com:user/repo.git`.
|
||||
- «Проверить соединение»: реальное подключение через libssh2; проверка host key:
|
||||
при первом подключении показать отпечаток и предложить «Доверять и сохранить»
|
||||
(known_hosts в `.flora/ssh/`); при несовпадении — блокировка с предупреждением «Возможен MITM».
|
||||
- Успех → авто-push и настройка автосинка.
|
||||
|
||||
### Фаза 2 — Мульти-хранилища (несколько окон)
|
||||
6. VaultManager: список известных хранилищ в настройках; последнее открытое = основное
|
||||
(открывается при старте).
|
||||
7. Кнопка внизу слева → поповер со списком хранилищ + «Добавить новое»: новое хранилище
|
||||
открывается в новом окне, старое продолжает работать; закрытие окна не удаляет
|
||||
хранилище; после перезапуска открывается только новое (основное), к старым — возврат
|
||||
через ту же кнопку.
|
||||
|
||||
### Фаза 3 — Хранилище и файловое дерево
|
||||
8. FileStore + QFileSystemWatcher, TreeModel для QML TreeView: подпапки с отступами,
|
||||
стрелка «>» раскрытия, иконки пустой/заполненной папки и файлов по типу.
|
||||
9. Кнопка «+» над деревом и ПКМ по пустому месту → меню «Файл»/«Папка» → диалог имени.
|
||||
Переименование (F2/ПКМ), удаление (файл/пустая папка — одно подтверждение, непустая
|
||||
папка — двойное), перемещение drag&drop между папками.
|
||||
10. Двойной клик по файлу — открыть в новой вкладке (md — в редакторе, прочие — предпросмотром).
|
||||
|
||||
### Фаза 4 — Редактор, вкладки, автосохранение
|
||||
11. DocumentManager: список открытых файлов, QTimer автосохранения каждые 5 сек
|
||||
(только если есть изменения), восстановление открытых вкладок после перезапуска.
|
||||
12. TabsBar с вкладками, закрытием, режимом «открыть рядом»: центральная область — две
|
||||
колонки SplitView, в каждую открывается вкладка (одна активна в каждой колонке).
|
||||
13. Режим редактирования: TextArea + моноширинный шрифт, путь/название файла в заголовке
|
||||
вкладки. Переключение режимов — Ctrl+E / Ctrl+V.
|
||||
|
||||
### Фаза 5 — Панель форматирования (подменю вверху)
|
||||
14. FormatToolbar над редактором, видна в режиме редактирования:
|
||||
- Жирный, курсив, подчёркнутый, зачёркнутый, выделение (==mark==), цвет текста,
|
||||
цвет выделения (палитры), верхний/нижний индекс (возведение в квадрат, подстрочное);
|
||||
- Заголовки # 1–6 (выпадающий выбор);
|
||||
- Списки: маркированный / нумерованный / задачи `- [ ]`;
|
||||
- Цитата (`>`), Выноска (GFM `> [!NOTE/INFO/WARN/ERROR]`);
|
||||
- Таблица: по умолчанию 2×1; в режиме редактирования таблицы по краям «+»-кнопки
|
||||
справа и снизу (20px шириной), добавляют столбец/строку, раскладка растёт
|
||||
по вертикали/горизонтали;
|
||||
- Обтекание текста вокруг картинок и таблиц: вставка директивы
|
||||
`![[img.png|float:left|width:40%]]`, рендер в обтекаемый блок.
|
||||
Кнопки работают с выделенным текстом (вставка/оборачивание markdown-разметки).
|
||||
|
||||
### Фаза 6 — Просмотр Markdown
|
||||
15. MdParser на cmark-gfm: CommonMark + GFM-таблицы, зачёркивание, автоссылки, выноски,
|
||||
raw-HTML, [[wiki-ссылки]], директивы обтекания.
|
||||
16. Подсветка кода: KSyntaxHighlighting — язык из ограждения (таблица алиасов: «С», «C»,
|
||||
«С++», «C++», python, go, rust, js, …; при отсутствии — авто по расширению/дефолт).
|
||||
Подсветка в режиме просмотра; в редакторе — по расширению файла через слоёный Text
|
||||
(фоновый слой rich-текст + прозрачный TextArea сверху), обновление по таймеру-дебонсу.
|
||||
17. Задачи: `- [ ]`/`- [x]` рендерятся чекбоксами; клик в просмотре переключает галочку
|
||||
в исходнике и перерисовывает.
|
||||
18. Ссылки в просмотре: клик по [[wiki]]/обычной ссылке открывает файл в новой вкладке.
|
||||
|
||||
### Фаза 7 — Правая панель: календарь, ссылки и теги, граф
|
||||
19. Календарь: клик по дню создаёт/открывает Журнал/ГГГГ-ММ-ДД.md (папка журнала настраивается).
|
||||
20. «Ссылки и теги» (секция над графом, для текущего файла): все ссылки и теги файла;
|
||||
клик по ссылке → переход в файл; клик по тегу → список всех файлов с этим тегом,
|
||||
клик по файлу → открыть.
|
||||
21. Граф связей (Canvas): узлы-файлы и теги-кластеры, рёбра по ссылкам/тегам/связям из БД,
|
||||
простая симуляция отталкивания/притяжения на JS, drag узлов, клик — открыть файл,
|
||||
кнопка «Обновить».
|
||||
|
||||
### Фаза 8 — База данных (notion-подобные связи)
|
||||
22. Database (SQLite, файл `.flora/flora.db` в хранилище): таблицы files, tags, file_tags,
|
||||
links, properties (свойства страниц: приоритет, статус, даты, связи), relations
|
||||
(родитель/ребёнок).
|
||||
23. Синхронизация БД с файловой системой при каждом изменении. UI: диалог
|
||||
«Свойства и связи» файла (ПКМ → Свойства), поиск по свойствам, backlinks.
|
||||
Граф дополнительно рисует связи из БД.
|
||||
|
||||
### Фаза 9 — Git: история и откат
|
||||
24. GitManager: репозиторий создаётся автоматически при создании хранилища, авто-коммиты,
|
||||
.gitignore (.flora/, .stfolder, конфликт-копии).
|
||||
25. Меню Правка → «Вернуться к предыдущей версии»: для открытого файла список версий →
|
||||
diff-просмотр (строки «+»/«−» цветные, контекст), внизу кнопки «Применить» и «Отклонить».
|
||||
Применение — замена файла на выбранную версию (через git) + автокоммит отката.
|
||||
|
||||
### Фаза 10 — Экспорт и предпросмотр
|
||||
26. Меню Файл → Экспорт: HTML (картинки инлайн base64 или копией, с обтеканием)
|
||||
и PDF (HTML → QTextDocument → QPdfWriter).
|
||||
27. Предпросмотр .html (тот же QTextDocument-рендер, без JS) и .pdf (QtPdf) из дерева.
|
||||
|
||||
### Фаза 11 — Синхронизация
|
||||
28. SyncManager (период в настройках):
|
||||
- Nextcloud/WebDAV: загрузка/скачивание дерева, сравнение mtime+hash, конфликты →
|
||||
имя.conflict.время.md, авторизация по логину/паролю (сохранение токена);
|
||||
- GitHub/GitLab/Gitea: git push/pull по HTTPS (токен) или SSH, merge конфликтов;
|
||||
- Syncthing: REST API (localhost:8384): сканирование папки, статус устройств, кнопка
|
||||
«Синхронизировать». Файлы .stfolder игнорируются git-ом.
|
||||
Подключение новых провайдеров — через кнопку хранилища (внизу слева) →
|
||||
«Настройки хранилища».
|
||||
|
||||
#### Каталог ошибок (ErrorCatalog)
|
||||
Каждой ошибке API/libgit2/SSH соответствует человеческое сообщение и рекомендация:
|
||||
|
||||
| Ошибка | Причина | Что показать пользователю |
|
||||
|---|---|---|
|
||||
| 401 Unauthorized | Неверный/просроченный/отозванный токен | «Токен не принят. Создайте новый» + ссылка на страницу токенов |
|
||||
| 403 Forbidden | Недостаточно прав токена / rate limit | «Проверьте права токена (scope repo/api)»; при rate limit — «Подождите N минут» |
|
||||
| 404 Not Found | Неверный URL инстанса или репо не существует / нет доступа (private) | «Проверьте адрес и что репозиторий создан», кнопка «Создать пустой репозиторий» (шаг 2) |
|
||||
| 409 / non-fast-forward | В репозитории уже есть чужие коммиты | «Отключите «Синхронизировать» и выполните ручное слияние» + команды терминала |
|
||||
| TLS/SSL (self-signed) | Self-hosted инстанс без сертификата | «Добавьте сертификат в доверенные» / опция «Разрешить небезопасное соединение» с предупреждением |
|
||||
| Таймаут / нет сети | Недоступен хост, прокси, DNS | «Проверьте интернет и прокси», повтор с ретраями |
|
||||
| Двухфакторка | GitHub требует OTP при пароле | «Используйте токен вместо пароля» |
|
||||
| Пустой локальный репо | Хранилище ещё без коммитов | Авто-коммит инициализационный перед push |
|
||||
| `Permission denied (publickey)` (SSH) | Ключ не добавлен в аккаунт / не тот ключ | «Добавьте публичный ключ в аккаунт» + ссылка на страницу ключей |
|
||||
| Passphrase неверна (SSH) | Неверная парольная фраза | «Введите passphrase заново» |
|
||||
| Host key mismatch (SSH) | Сервер подменился / ключ поменялся | «Подключение заблокировано: отпечаток изменился» + оба отпечатка, кнопка «Удалить старый и продолжить» (с предупреждением) |
|
||||
| Таймаут/отказ порта (SSH) | Неверный порт/хост, файрвол, репо не существует | «Проверьте хост, порт и имя репозитория» |
|
||||
| Неверный формат ключа (SSH) | Ключ повреждён/не тот формат | «Поддерживаются ed25519, RSA (PKCS#1/PKCS#8)» |
|
||||
|
||||
Ошибка не блокирует работу: всё хранится локально, подключение можно повторить позже.
|
||||
|
||||
### Фаза 12 — Настройки
|
||||
29. QSettings: размеры панелей (запоминание), шрифты, интервалы автосохранения/автокоммита,
|
||||
тема (светлая/тёмная), токены, основное хранилище. Горячие клавиши.
|
||||
|
||||
### Фаза 13 — Тесты
|
||||
30. QtTest/Catch2: md→HTML (таблицы, выноски, обтекание, задачи), подсветка языков
|
||||
(алиасы), GitManager (коммиты, откат, diff), Database, конфликты синка. Прогон через CTest.
|
||||
|
||||
### Фаза 14 — Android
|
||||
31. Сборка cmark/libgit2/libssh2/OpenSSL/KSyntaxHighlighting под NDK (статически; libgit2
|
||||
с SSH-транспортом). Манифест, разрешения, выбор хранилища системным диалогом,
|
||||
ПКМ → долгое нажатие, адаптация панелей под экран телефона. SSH-ключи — в приватном
|
||||
хранилище приложения.
|
||||
|
||||
### Фаза 15 — Упаковка и лицензия
|
||||
32. Пакеты: macOS .app/.dmg, Windows NSIS, Linux AppImage, Android APK.
|
||||
33. Лицензионные заголовки GPL-3.0 во всех файлах, README, чек-лист соответствия лицензии.
|
||||
|
||||
## Служебные файлы проекта
|
||||
- PLAN.md — этот план (актуальная версия).
|
||||
- CHANGELOG.md — история изменений проекта.
|
||||
- done.md — журнал итераций: что планировалось за итерацию и что сделано.
|
||||
@@ -0,0 +1,30 @@
|
||||
# done.md — журнал итераций
|
||||
|
||||
Каждая итерация: что запланировано → что сделано. Сделанное помечается `[x]`,
|
||||
к незавершённому возвращаемся в следующей итерации.
|
||||
|
||||
## Итерация 0 — подготовка проекта
|
||||
|
||||
**Планировалось:**
|
||||
- [x] Составить подробный план разработки (PLAN.md) со всеми требованиями
|
||||
и дополнениями (SSH, мастер первого запуска, notion-БД, тулбар и т.д.).
|
||||
- [x] Создать CHANGELOG.md для истории изменений.
|
||||
- [x] Создать done.md (этот файл) для журнала итераций.
|
||||
- [x] Создать .gitignore.
|
||||
- [x] Инициализировать локальный git-репозиторий и сделать первый коммит
|
||||
(удалённый Gitea-репозиторий пользователь добавит позже).
|
||||
|
||||
**Сделано:**
|
||||
- PLAN.md создан (16 фаз, полная архитектура).
|
||||
- CHANGELOG.md создан с записью 0.0.0.
|
||||
- done.md создан.
|
||||
- .gitignore создан.
|
||||
- git init выполнен, первый коммит сделан.
|
||||
|
||||
**Незавершённое / следующая итерация:**
|
||||
- Итерация 1: Фаза 0 плана — каркас проекта:
|
||||
- LICENSE (GPL-3.0), README;
|
||||
- подключение cmark, libgit2 (SSH), libssh2, OpenSSL, KSyntaxHighlighting
|
||||
как подпроектов (статическая сборка);
|
||||
- скелет приложения: главное меню (Файл/Правка/Вид/Справка), SplitView 15/70/15,
|
||||
кнопка «+ хранилище» внизу слева.
|
||||
Reference in New Issue
Block a user