Всплывающая подсказка с текстом комментария при наведении #268

Open
opened 2026-06-30 16:55:49 +03:00 by vvzvlad · 0 comments
Owner

Что хотим

При наведении курсора на текст, помеченный комментарием (жёлтая подсветка .comment-mark), показывать рядом небольшую всплывающую подсказку с текстом комментария — чтобы прочитать комментарий, не открывая боковую панель.

Текущее поведение

  • Комментарий — inline-марка TipTap: <span class="comment-mark" data-comment-id="…"> (packages/editor-ext/src/lib/comment/comment.ts).
  • По клику диспатчится ACTIVE_COMMENT_EVENT, который открывает боковую панель (apps/client/src/features/editor/page-editor.tsx). Прочитать текст комментария можно только через панель.
  • Текст комментариев лежит в react-query кеше ["comments", pageId] (useCommentsQuery), но грузится только при открытой панели.

Зафиксированные решения

  • Содержимое всплывашки: только plain-text родительского комментария (без автора/аватара/форматирования).
  • Область: только основной редактор (page-editor.tsx); read-only / публичные шары / история — вне scope.
  • Resolved-комментарии: не показывать (как и клик, который их игнорирует; такие марки и так визуально невидимы).

Предлагаемое решение

Отдельный React-компонент CommentHoverPreview (без правок в editor-ext):

  1. Монтируется в page-editor.tsx, получает pageId и containerRef (menuContainerRef, оборачивает EditorContent).
  2. Через useCommentsQuery({ pageId }) строит Map<commentId, IComment> (react-query дедуплицирует запрос с боковой панелью по тому же ключу).
  3. Делегированные mouseover/mouseout на контейнере: по target.closest('.comment-mark[data-comment-id]') достаёт комментарий; пропускает неизвестные/resolved.
  4. Извлекает plain-text из ProseMirror-JSON (content), показывает fixed-карточку через createPortal, позиционируя по getBoundingClientRect() спана (снизу, переворот наверх у края экрана). Карточка pointer-events: none — не ломает клик и не требует логики наведения на саму карточку.
  5. Закрытие по mouseout, scroll, resize; небольшая задержка открытия против мерцания; сброс при смене страницы.

Файлы

  • Новый: apps/client/src/features/comment/components/comment-hover-preview.tsx (компонент + хелпер commentContentToText).
  • Правка: apps/client/src/features/editor/page-editor.tsx — смонтировать компонент рядом с <EditorContent>.
  • (Опц.) apps/client/src/features/editor/styles/core.css — стиль карточки (либо Mantine Paper withBorder shadow).

Краевые случаи

  • Комментарии ещё не загружены → подсказки нет (мягко), появляется после загрузки.
  • Resolved → пропуск по resolvedAt и классу resolved.
  • Вложенные/перекрывающиеся марки → берём самый внутренний спан.
  • Клик по-прежнему открывает панель (карточка pointer-events: none).
  • Длинный текст → обрезка + ограничение высоты.
  • Тач-устройства → hover не применим, клик работает.

Чеклист реализации

  • CommentHoverPreview + хелпер commentContentToText
  • Монтирование в page-editor.tsx
  • Стили карточки
  • Проверка: hover показывает текст; resolved/незагруженные — нет; клик открывает панель; нет лишнего запроса при открытии панели; скролл/смена страницы закрывают подсказку
## Что хотим При наведении курсора на текст, помеченный комментарием (жёлтая подсветка `.comment-mark`), показывать рядом небольшую всплывающую подсказку с текстом комментария — чтобы прочитать комментарий, не открывая боковую панель. ## Текущее поведение - Комментарий — inline-марка TipTap: `<span class="comment-mark" data-comment-id="…">` (`packages/editor-ext/src/lib/comment/comment.ts`). - По клику диспатчится `ACTIVE_COMMENT_EVENT`, который открывает боковую панель (`apps/client/src/features/editor/page-editor.tsx`). Прочитать текст комментария можно только через панель. - Текст комментариев лежит в react-query кеше `["comments", pageId]` (`useCommentsQuery`), но грузится только при открытой панели. ## Зафиксированные решения - **Содержимое всплывашки:** только plain-text родительского комментария (без автора/аватара/форматирования). - **Область:** только основной редактор (`page-editor.tsx`); read-only / публичные шары / история — вне scope. - **Resolved-комментарии:** не показывать (как и клик, который их игнорирует; такие марки и так визуально невидимы). ## Предлагаемое решение Отдельный React-компонент `CommentHoverPreview` (без правок в `editor-ext`): 1. Монтируется в `page-editor.tsx`, получает `pageId` и `containerRef` (`menuContainerRef`, оборачивает `EditorContent`). 2. Через `useCommentsQuery({ pageId })` строит `Map<commentId, IComment>` (react-query дедуплицирует запрос с боковой панелью по тому же ключу). 3. Делегированные `mouseover`/`mouseout` на контейнере: по `target.closest('.comment-mark[data-comment-id]')` достаёт комментарий; пропускает неизвестные/resolved. 4. Извлекает plain-text из ProseMirror-JSON (`content`), показывает `fixed`-карточку через `createPortal`, позиционируя по `getBoundingClientRect()` спана (снизу, переворот наверх у края экрана). Карточка `pointer-events: none` — не ломает клик и не требует логики наведения на саму карточку. 5. Закрытие по `mouseout`, `scroll`, `resize`; небольшая задержка открытия против мерцания; сброс при смене страницы. ## Файлы - **Новый:** `apps/client/src/features/comment/components/comment-hover-preview.tsx` (компонент + хелпер `commentContentToText`). - **Правка:** `apps/client/src/features/editor/page-editor.tsx` — смонтировать компонент рядом с `<EditorContent>`. - **(Опц.)** `apps/client/src/features/editor/styles/core.css` — стиль карточки (либо Mantine `Paper withBorder shadow`). ## Краевые случаи - Комментарии ещё не загружены → подсказки нет (мягко), появляется после загрузки. - Resolved → пропуск по `resolvedAt` и классу `resolved`. - Вложенные/перекрывающиеся марки → берём самый внутренний спан. - Клик по-прежнему открывает панель (карточка `pointer-events: none`). - Длинный текст → обрезка + ограничение высоты. - Тач-устройства → hover не применим, клик работает. ## Чеклист реализации - [ ] `CommentHoverPreview` + хелпер `commentContentToText` - [ ] Монтирование в `page-editor.tsx` - [ ] Стили карточки - [ ] Проверка: hover показывает текст; resolved/незагруженные — нет; клик открывает панель; нет лишнего запроса при открытии панели; скролл/смена страницы закрывают подсказку
vvzvlad added the feature label 2026-06-30 16:55:49 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#268