e3725b7339
read-only ядро собрано: список/поиск/пусто/редактор-автосейв/конфликт-диалог. 16/42 Ф в коде+UI. Fd 0% (ждёт девайс). Дальше — регистрация экрана у лида.
153 lines
13 KiB
Markdown
153 lines
13 KiB
Markdown
# Diff: Заметки (Notes) — итерация 1 (2026-07-13)
|
|
|
|
Ff_app: **42.8%** · Fd_app: **0.0%** (среднее по 6 экранам; Fd ждёт девайс-сверки) · n-a: 0
|
|
|
|
> ✅ **Скелет заведён лидом** (`133d80d`). **Итерация 1a — слой данных** (`8a8f1cf`) +
|
|
> **1b — UI read-only ядра** (`fb120d5`). `[done]` = в коде + верифицировано (compile + 7/7
|
|
> юнит-тестов MockWebServer + detekt, изолированный worktree); **Fd=0% пока держится — экраны
|
|
> собраны, но девайс/визуал-сверки ещё не было**. Пишущее проверено ЮНИТАМИ, не на forbion (mail/073).
|
|
>
|
|
> **Готово в коде (1a данные + 1b UI):**
|
|
> - Данные: `NotesApiClient` (v1: list exclude=content+If-None-Match, get, create, saveContent
|
|
> `If-Match`→412 `NoteConflictException`, setFavorite/Category/rename, delete) · `NotesRepository`
|
|
> (offline-first: 304/сеть→кэш) · `NotesCache` (дисковый ETag) · `Note`.
|
|
> - UI: `NotesViewModel` (список избранное↑+поиск, открытие/создание/сохранение/удаление,
|
|
> разрешение конфликта явным выбором) · `NotesScreen` (список+поиск+пусто-состояние Welcome+
|
|
> диалог конфликта) · `NoteEditorScreen` (plain markdown + debounce-автосейв + read-only).
|
|
> - **Осталось для полного P1:** регистрация экрана в app-шелле (переключение веб-пункта меню
|
|
> «Заметки» на нативный — зона лида, app/; пинг отправлен). **P2:** rich-редактор/preview,
|
|
> категории-навигация+CRUD, autotitle, undo, settings, шаринг + попиксельная вёрстка (Fd).
|
|
|
|
Сверка веб (`nextcloud/notes v5.0.0` + тема forbion) ↔ натив (**отсутствует**). Карта-источник:
|
|
[`notes.md`](notes.md) (снята из кода + визуально сверена на forbion, Browser 1, read-only).
|
|
Метки: `[Ф|Д]` (функционал/дизайн) · `[open|done|n-a]`. Подход к реализации согласован —
|
|
Notes API v1 + ETag-кэш, план 1→2→3 (mail/071).
|
|
|
|
Приоритеты предлагаю в конце (P1→P3); финальную приоритизацию — за лидом.
|
|
|
|
---
|
|
|
|
## Экран 1. Список заметок (главный) — Ff 50% · Fd 0%
|
|
**Ф (10, open 5):**
|
|
- [Ф][done] создать заметку (`NotesApiClient.create` + кнопка `F7CreateButton` в `NotesScreen`)
|
|
- [Ф][done] поле «Искать заметки» (фильтр по заголовку, `visibleNotes`) — UI собран
|
|
- [Ф][done] загрузка заметки (`get`) + списка (`listNotes` offline-first) + строки `F7ListCard`
|
|
- [Ф][open] индикатор «расшарена» на строке — P3
|
|
- [Ф][open] меню строки «⋯» полное (сейчас на строке только избранное+тап; ⋯-поповер) — P2
|
|
- [Ф][open] группировка по таймслотам (сегодня/недавние/…) — P2
|
|
- [Ф][open] группировка по категориям (капшены) — P2
|
|
- [Ф][done] сортировка «избранное вверх» + по дате изменения (`visibleNotes`)
|
|
- [Ф][done] пустое состояние Welcome (`NotesEmptyState`: текст + «Новая заметка»)
|
|
- [Ф][open] «Найти во всех категориях» (сброс фильтра при пустом поиске в категории) — P3
|
|
- (состояние загрузки «Загрузка …» — Д)
|
|
|
|
**Д (6, open 6):** [Д][open] композиция экрана-списка · [Д][open] мобильная вёрстка по
|
|
`_mobile-notes.css` (`content-list__search`, перенос) · [Д][open] порядок элементов шапки ·
|
|
[Д][open] типографика (Raleway, тема) · [Д][open] иконки (звезда избранного, share-индикатор) ·
|
|
[Д][open] состояние загрузки/пустое
|
|
|
|
## Экран 2. Меню заметки «⋯» (всплывающее, mail/087) — Ff 66.7% · Fd 0%
|
|
Полный состав из кода (`NoteItem` #actions), порядок сверен визуально:
|
|
**Ф (6, open 2):**
|
|
- [Ф][done] «Добавить/Удалить из избранного» (`setFavorite`, юнит-тест) — данные готовы; UI P1-UI
|
|
- [Ф][open] «Поделиться» → сайдбар шаринга (NC sharing) — P3
|
|
- [Ф][done] «<Категория>» / «Изменить категорию» (`setCategory`) — данные готовы; UI-мультиселект P2
|
|
- [Ф][done] «Переименовать» (`rename`) — данные готовы; UI-инлайн P2
|
|
- [Ф][done] «Удалить заметку» (`delete`, юнит-тест) — данные готовы; UI P1-UI
|
|
- [Ф][open] отмена удаления (`POST /notes/undo`) — не реализовано — P2
|
|
|
|
**Д (3, open 3):** [Д][open] состав/порядок пунктов меню · [Д][open] иконки пунктов ·
|
|
[Д][open] инлайн-поля (переименование/категория)
|
|
|
|
## Экран 3. Редактор заметки (rich / plain / preview) — Ff 40% · Fd 0%
|
|
**Ф (10, open 6):**
|
|
- [Ф][open] rich-редактор (@nextcloud/text) — P2
|
|
- [Ф][open] панель форматирования: жирный/курсив/цитата/моно/очистить/список/нумерованный/
|
|
заголовок/крупный заголовок/ссылка (всплывающая тулбар-панель, mail/087) — P2
|
|
- [Ф][done] plain-режим (`NoteEditorScreen`, `F7OutlinedField` markdown) — UI собран
|
|
- [Ф][open] тумблер «Просмотр»/«Правка» (preview⇄edit) — P2
|
|
- [Ф][open] тумблер «Полный экран» — P3
|
|
- [Ф][done] автосохранение с `If-Match: "<etag>"` (debounce → `saveContent`, юнит-тест 412)
|
|
- [Ф][open] автозаголовок из первой строки (`PUT /autotitle`) — P2
|
|
- [Ф][done] состояние read-only заметки (блок правки + подпись поля)
|
|
- [Ф][open] «Сохранение не удалось. Нажмите, чтобы повторить» (ошибка в state, кнопки ретрая нет) — P2
|
|
- [Ф][done] плейсхолдер поля (подпись `F7OutlinedField`)
|
|
|
|
**Д (5, open 5):** [Д][open] вёрстка редактора · [Д][open] перенос тулбара форматирования на
|
|
мобильном (`.text-menubar__entries` flex-wrap) · [Д][open] типографика тела · [Д][open] меню
|
|
действий редактора (preview/fullscreen) · [Д][open] индикатор read-only
|
|
|
|
## Экран 4. Диалог конфликта версий — Ff 100% · Fd 0%
|
|
**Ф (3, open 0):**
|
|
- [Ф][done] детект конфликта (412 на `If-Match` → `NoteConflictException` + перечитка серверной
|
|
версии, юнит-тест)
|
|
- [Ф][done] «Использовать версию с сервера» (`F7AlertDialog` dismiss → `resolveConflictUseServer`)
|
|
- [Ф][done] «Использовать текущую версию» (`F7AlertDialog` confirm → `resolveConflictKeepMine`)
|
|
- (⚠ обязателен — НЕ молчаливая перезапись, согласовано mail/071 п.2)
|
|
|
|
**Д (1, open 1):** [Д][open] вёрстка диалога конфликта
|
|
|
|
## Экран 5. Навигация категорий (шторка) — Ff 0% · Fd 0%
|
|
Всплывающие/контекстные меню категории (mail/087): «Новая категория», «⋯»-действия категории.
|
|
**Ф (8, open 8):**
|
|
- [Ф][open] «Новая категория» (создать; drag заметки → назначить) — P2
|
|
- [Ф][open] «Все заметки» + счётчик (сброс фильтра) — P1
|
|
- [Ф][open] «Без категории» + счётчик — P2
|
|
- [Ф][open] список категорий + счётчики, фильтрация по тапу — P2
|
|
- [Ф][open] «Переименовать категорию» (инлайн) — P3
|
|
- [Ф][open] «Удалить категорию» + диалог подтверждения — P3
|
|
- [Ф][open] вложенные подкатегории (`parent/child`) — P3
|
|
- [Ф][open] вход «Настройки заметок» (шестерёнка) — P2
|
|
|
|
**Д (4, open 4):** [Д][open] композиция шторки навигации · [Д][open] иконки папок (тема — серая
|
|
`folder-gray.svg`) · [Д][open] счётчики-бейджи · [Д][open] порядок (Все/Категории)
|
|
|
|
## Экран 6. Модалка «Настройки заметок» — Ff 0% · Fd 0%
|
|
**Ф (5, open 5):**
|
|
- [Ф][open] «Отображение»: Форматированный текст / Простой текст / Просмотр — P2
|
|
- [Ф][open] «Расширение файла»: .md / .txt / Свой (+ поле) — P3
|
|
- [Ф][open] «Папка заметок» (WebDAV picker) — P3
|
|
- [Ф][open] секция «Мобильные приложения» (Android / iPhone) — P3
|
|
- [Ф][open] секция «Комбинации клавиш» (в теме скрыта) — n-a? (уточнить — пока open) — P3
|
|
|
|
**Д (2, open 2):** [Д][open] полноэкранная модалка на мобильном (`_mobile-notes.css`) ·
|
|
[Д][open] вёрстка секций/переключателей
|
|
|
|
---
|
|
|
|
## Сводка
|
|
| Экран | Ф всего | Ф open | Ff% | Д всего | Д open | Fd% |
|
|
|---|---|---|---|---|---|---|
|
|
| 1. Список | 10 | 5 | 50.0% | 6 | 6 | 0% |
|
|
| 2. Меню «⋯» | 6 | 2 | 66.7% | 3 | 3 | 0% |
|
|
| 3. Редактор | 10 | 6 | 40.0% | 5 | 5 | 0% |
|
|
| 4. Конфликт | 3 | 0 | 100% | 1 | 1 | 0% |
|
|
| 5. Категории | 8 | 8 | 0% | 4 | 4 | 0% |
|
|
| 6. Настройки | 5 | 5 | 0% | 2 | 2 | 0% |
|
|
| **Итого** | **42** | **26** | **38.1%** | **21** | **21** | **0%** |
|
|
|
|
**Ff_app = 42.8%** (среднее по 6 экранам: 50+66.7+40+100+0+0) · **Fd_app = 0.0%** (экраны
|
|
собраны, но девайс/визуал-сверки ещё не было). Абсолютно: 16 из 42 Ф закрыты в коде+UI, 26 open.
|
|
Fd — весь бэклог до попиксельной сверки на устройстве.
|
|
|
|
## Предлагаемый порядок реализации (план 1→2→3, mail/071)
|
|
- **P1 — read-only ядро:** список заметок (открыть/просмотр), rich-редактор, автосейв `If-Match`,
|
|
удаление, избранное, «Все заметки», диалог конфликта. (= итерация 1 плана)
|
|
- **P2 — запись/организация:** создание, переименование, категории (создать/сменить/фильтр),
|
|
автозаголовок, поиск, группировка, настройки отображения. (= итерация 2)
|
|
- **P3 — добивка:** шаринг, подкатегории, удаление/переименование категорий, полноэкранный
|
|
режим, расширение файла/папка, попиксельная вёрстка по `_mobile-notes.css`. (= итерация 3)
|
|
|
|
## Блокеры
|
|
1. ~~Скелет модуля~~ — **снят**: заведён лидом (`133d80d`, mail/096). Слой данных 1a — в коде (`8a8f1cf`).
|
|
2. **NC-апп `notes` на glb** — установлен ли (для интеграционной проверки записи на живом
|
|
сервере); лид спросил в PPS 069. До ответа write-путь проверяется юнит-тестами (MockWebServer),
|
|
не на forbion (read-only, mail/073). НЕ блокирует разработку — только живую верификацию.
|
|
3. Повторный (подтверждающий) прогон для гейта — после реализации P1-UI, на устройстве/`bmob-*`.
|
|
|
|
## Дальше (следующий заход, автономно)
|
|
P1-UI: `NotesScreen` (список+поиск+пусто-состояние) → `NoteEditorScreen` (rich/plain/preview +
|
|
автосейв) → диалог `ConflictSolution` → регистрация экрана у лида (переключение веб-пункта меню
|
|
на нативный — зона app/, делает лид по готовности). Затем P2 (категории-CRUD/autotitle/undo/
|
|
settings), P3 (шаринг/добивка вёрстки).
|