From c31adb56923298469572fcf9b4dea5889d4f0cad Mon Sep 17 00:00:00 2001 From: b-mob-notify Date: Mon, 13 Jul 2026 08:46:57 +0000 Subject: [PATCH] =?UTF-8?q?app-map:=20notifications.diff.md=20(Ff=2045.5%,?= =?UTF-8?q?=20iter1)=20+=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0=20STATUS?= =?UTF-8?q?=20=E2=80=94=20=D1=81=D0=BD=D0=B8=D0=BC=D0=B0=D1=8E=20=D0=B3?= =?UTF-8?q?=D0=B5=D0=B9=D1=82=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/app-map/STATUS.md | 2 +- docs/app-map/notifications.diff.md | 93 ++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 docs/app-map/notifications.diff.md diff --git a/docs/app-map/STATUS.md b/docs/app-map/STATUS.md index be697b5..2308cd7 100644 --- a/docs/app-map/STATUS.md +++ b/docs/app-map/STATUS.md @@ -16,7 +16,7 @@ | talk | b-mob-conf | 1 | 41.3 | предв. | ~29 | ? | нет | P1 меню сообщения ~закрыто (Копировать/ссылка/2×переслать/Напоминание/Ответить-лично, …01198a4); остаток P1 файл-тред+перевод эскалирую (кросс-модуль/провайдеры); далее P2 меню беседы; Fd на устройстве | | tasks | b-mob-tasks | 1 | 24.6 | 52.7 | ~34 | ~8 | нет | P1 закрыт в коде (умные коллекции+3-state видимость+персист, `bd56c4b`); далее P2 управление списками; ждёт девайс-сверки | | notes | b-mob-notes | 1 | 42.8 | 0.0 | 26 | 21 | нет | P1 read-only ядро в коде+UI (`8a8f1cf` данные + `fb120d5` VM/список/редактор/конфликт); compile+7/7 тестов+detekt OK (worktree); Fd ждёт девайс. Пинг лиду на регистрацию экрана в app-шелле | -| notifications | b-mob-notify | 0 | — | — | — | — | нет | карта готова, diff | +| notifications | b-mob-notify | 1 | 45.5 | 0.0 | 12 | 9 | нет | diff выложен: лента РАБОТАЕТ в app-shell (список/пусто/скрыть-одно/переход/иконка/время); P1-дыры: «Скрыть все» + action-кнопки (парсинг `actions`) + unregister-push; прошу лида завести `feature/notifications` (перенос `NotificationsSheet` из app/); Fd ждёт девайс + наполнение ленты (mail/107) | | deck | b-mob-deck | 1 | 24.8 | предв. | 48 | ? | нет | P1 done: назначить-себя (6eeba1b) + бейдж коммент. (9d726f4) + меню колонки (4fdadef) + быстрые сроки (d0bf359); compile+detekt GREEN; далее бейдж чек-пунктов, назначение произв. юзера; Fd на устройстве | | calendar | b-mob-calendar | 1 | 64.0 | 80.4 | ~35 | ~7 | нет | P1 разворот повторений+BYDAY=1MO ЗАКРЫТ в коде (`CalendarRecurrence`, 15 тестов, compile+detekt green, коммиты e7d0a5a/492af61); Appointments=n-a (101); далее P2 EXDATE/RECURRENCE-ID | | contacts | b-mob-contacts | 1 | 37.4 | предв. | ~32 | ? | нет | P1 edit/delete РЕАЛИЗОВАН в main (ядро `bc1a497` + UI `6b98c5a`: Room v4→5, форма правки, delete-подтверждение; гейты зелёные); live-проверка на bmob-* + device Fd далее; потом P2 группы/типы | diff --git a/docs/app-map/notifications.diff.md b/docs/app-map/notifications.diff.md new file mode 100644 index 0000000..9b7f54f --- /dev/null +++ b/docs/app-map/notifications.diff.md @@ -0,0 +1,93 @@ +# Diff: Уведомления (Notifications) — итерация 1 (2026-07-13) + +Ff_app: **45.5%** (done 10 / open 12, n-a 1) · Fd_app: **0.0%** (ждёт девайс-сверки) · автор `b-mob-notify` + +> Сверка веб (`nextcloud/notifications 5.0.0-dev.0` + тема forbion, mail/078) ↔ **натив +> (реализован в app-shell)**. Лента УЖЕ работает: `NotificationsSheet` (`app/AppSheets.kt`) + +> `F7NotificationRow` (`core/designsystem`) + `NotificationsRepository` (`core/network`, API v2). +> `[done]` = есть в коде натива; `Fd=0%` — вёрстка на устройстве/визуально ещё не сверялась. +> Карта-источник: [`notifications.md`](notifications.md) (из кода + живая сверка forbion, +> Browser 1/`cloude`, read-only; лента `cloude` = 3 уведомления `firstrunwizard`). +> +> **NB зона:** лента живёт в `app/AppSheets.kt` (app-shell, зона лида). Два P1-расхождения +> (Скрыть-все, action-кнопки) требуют правок в app/ → **прошу лида завести `feature/notifications` +> и перенести `NotificationsSheet`** (предложено в mail/107), тогда закрываю автономно. +> +> **Приоритеты предлагаю (P1→P3); финальная приоритизация — за лидом.** + +Метки: `[Ф|Д]` (функционал/дизайн) · `[open|done|n-a]`. + +--- + +## Экран 1. Триггер (колокольчик) — Ff n-a (зона лида) +Колокольчик-вход живёт в шелле (нижняя шторка, слот `#mobile-header-notifications`) — **зона +`b-dev-mobile`** (shell.md), не считаю в свой Ff. +**Ф (1, n-a 1):** +- [Ф][n-a] иконка-триггер + раскрытие ленты — шелл (лид). Индикатор непрочитанных (точка + `showDot` / warning `hasThrottledPushNotifications`) — если понадобится, отдельным пингом лиду. + +## Экран 2. Лента (дропдаун/шит) — Ff 57.1% · Fd 0% +**Ф (8, done 4, open 3, n-a 1):** +- [Ф][done] загрузка списка (`NotificationsRepository.load`, OCS API v2, `limit=50`) +- [Ф][done] пустое состояние «Нет уведомлений» (иконка `nof-not-icon.svg` + текст) — `items.isEmpty()` +- [Ф][done] состояние загрузки (спиннер `CircularProgressIndicator`) +- [Ф][done] состояние ошибки (текст `error`) +- [Ф][open] **«Скрыть все уведомления»** (dismiss-all → `DELETE …/api/v2/notifications`) — НЕТ + в нативе; на forbion кнопка видна ВСЕГДА (даже при пустой ленте, см. карту) — **P1** +- [Ф][open] баннер fairUsePolicy при throttled push («Push notifications might be unreliable») — P3 +- [Ф][open] авто-обновление ленты: сейчас только push-триггер (`refreshRequest`), ETag/поллинга + (`lastETag`/notify_push) НЕТ — P2 +- [Ф][n-a] пустой вариант «Запрос разрешений браузера» (`webNotificationsGranted===null`) — n-a: + веб-концепт web-push; натив на FCM, разрешение POST_NOTIFICATIONS запрашивается системно + +**Д (5, open 5):** [Д][open] вёрстка ленты по теме/токенам · [Д][open] высота/скролл шита · +[Д][open] пустое состояние (вид иконки/текста) · [Д][open] состояние загрузки/ошибки · +[Д][open] анимация inbox-zero (галочка+конфетти при переходе >0→0) — P3 + +## Экран 3. Элемент уведомления (`F7NotificationRow` ↔ `NotificationItem`) — Ff 50.0% · Fd 0% +**Ф (12, done 6, open 6):** +- [Ф][done] относительное время (`formatNotificationRelativeTime`) — совпадает с forbion («N минут назад») +- [Ф][done] кнопка «Скрыть» (× → `dismissNotification` → `DELETE …/notifications/{id}`) +- [Ф][done] иконка app (`resolveNotificationIcon` + `AsyncImage` с auth-хедером) +- [Ф][done] subject (плоский текст) +- [Ф][done] message (плоский текст, если есть) +- [Ф][done] переход по тапу (`onNotificationClick` → `openAppLink(notification.link)`) +- [Ф][open] **action-кнопки уведомления** (`notification.actions[]` → `ActionButton`) — НЕТ в + нативе; ломает сценарии с действиями (Talk-приглашение «Присоединиться/Отклонить», и т.п.) — **P1** +- [Ф][open] `subjectRich` (`NcRichText` + User/File-параметры) — только плоский subject — P2 +- [Ф][open] `messageRich` (rich + autolink) — только плоский message — P2 +- [Ф][open] `externalLink` (вариант «↗», target=_blank + primary-кнопка «Contact…») — не отличается + от обычной ссылки — P3 +- [Ф][open] сворачивание длинного message (`.collapsed` + разворот по тапу) — нет — P3 +- [Ф][open] подсветка нового `notification--new` — нет — P3 + +**Д (4, open 4):** [Д][open] компоновка строки (время+× сверху, иконка+subject/message) · +[Д][open] вёрстка по теме (карточный стиль `_mobile-common.css` + токены) · [Д][open] иконки/аватар · +[Д][open] типографика subject(SemiBold)/message/время + +## Экран 4. Кнопка действия (`ActionButton`) — Ff 0.0% · Fd 0% — ОТСУТСТВУЕТ В НАТИВЕ +Модель `action{label,link,type,primary}`; в нативной `F7Notification` поля `actions` вообще НЕТ +(`NotificationsRepository` их не парсит). +**Ф (3, open 3):** +- [Ф][open] primary/secondary по типу (`WEB`/`primary` → primary; GET/POST/DELETE → secondary) — P1 +- [Ф][open] выполнение действия (`method:action.type url:action.link`) + удаление из ленты — P1 +- [Ф][open] WEB-действие как прямая ссылка (`href`) — P1 + +--- + +## Вне карты-экрана: core/push (моя зона, отдельный бэклог) +Не входит в Ff ленты (нет веб-экрана-аналога), но моя зона и уже зафиксировано в представлении +(mail/070). Держу как отдельный трек: +- [Ф][open] **unregister при logout** (DELETE устройства в f7push) — нигде не вызывается, + строки копятся на сервере (327× «not found» в диагнозе) — P1-push +- [Ф][open] retry/бэкофф в `F7PushRegistrar.registerBlocking` (сейчас глотает ошибку, код 0) — P2-push +- [Ф][n-a] серверные хвосты FCM (чистка 403 SenderId mismatch, старые `f7cloud-apk`) — ячейка A, + через integrator-b (mail/064) — вне натива + +## Сводка +- **Ff = 45.5%** (done 10 / open 12; n-a 3 не в счёте: web-permission-empty, триггер-шелл, серверный FCM). +- **P1 (гейт-приоритет):** «Скрыть все» + action-кнопки (+парсинг `actions` в repo) + unregister-push. +- **P2:** rich subject/message, авто-обновление ETag, retry регистрации. +- **P3:** fairUsePolicy, external-«↗», сворачивание message, `notification--new`, inbox-zero. +- **Fd=0%** до девайс-сверки (вёрстка по теме forbion; лента у `cloude` наполняется — mail/107, + как засеют `occ notification:generate`, сверю rich/action/список живьём).