myYouTube/analytics/2026-09-18-feed-card-cleanup.md
vrubelroman fb6e639309 Remove watch/download buttons from feed video cards
Cards stay fully clickable via thumbnail and title; downloads are
managed from the video page. On the Saved page the download button
remains (status/delete), and the dead .button-link styles are removed.
2026-09-22 07:53:19 +00:00

11 KiB
Raw Blame History

Чистка карточек видео: убрать «Смотреть» и «Скачать» из ленты, оставить действия на /local

Задача

Убрать из карточек видео (VideoCard) кнопки «Смотреть» и «Скачать» на всех ленточных маршрутах: /, /category/:id, /uncategorized, /search, а также на странице видео канала /channels/:id/videos. Карточка остаётся кликабельной целиком через превью и заголовок (это ссылки), скачивание остаётся доступным со страницы видео. Исключение — /local («На сервере»): там кнопка скачивания остаётся, т.к. показывает статус загрузки и участвует в управлении копиями. Кнопка «Смотреть» не нужна нигде в карточках (включая /local) — превью/заголовок и так ведут на страницу видео.

Контекст

  • VideoCard (frontend/src/components/VideoCard.tsx) сейчас рендерит: thumbnail-Link (с aria-label="Смотреть: …"), title-Link, .video-meta, и блок .video-actions с двумя элементами: «Смотреть» (Link className="button-link" + Icon name="play") и <DownloadButton video={video} />.
  • VideoCard используется ровно в двух местах: Feed.tsx (строка 113 — все режимы ленты, включая /local и /search) и ChannelVideos.tsx (строка 21). Компактные карточки в режиме «Каналы» (CompactVideoCard) уже без кнопок и не затрагиваются.
  • DownloadButton остаётся нужным в трёх местах: карточки /local, страница видео VideoPage (showDelete — там живёт «Удалить копию»), и он не меняется. На карточке /local сегодня он рендерится без showDelete (кнопки «Удалить копию» в карточке нет и не было — она только на VideoPage); на /local показываются статусы («Скачать» / «Скачивается N%» / «В очереди…» / «На сервере» / «Повторить» / «Загрузить снова»). Поведение на /local менять не требуется — сохранить как есть.
  • Кнопка «Смотреть» — единственное использование класса .button-link и иконки Icon в VideoCard. После удаления кнопки класс .button-link становится мёртвым во всём CSS (проверено rg: только App.css и VideoCard.tsx), а импорт Icon в VideoCard — неиспользуемым (noUnusedLocals в tsconfig → ошибка сборки, если не убрать).
  • В DownloadButton кэш-инвалидация на завершении/удалении (['feed'], ['video', id]) не зависит от места рендера — на /local и VideoPage она продолжит работать как раньше.

Затронутые подсистемы и файлы

Только frontend. Backend, тесты, миграции — не трогаем.

  • frontend/src/components/VideoCard.tsx — добавить опциональный проп showActions (default false); блок .video-actions рендерить только при showActions и только с <DownloadButton>; удалить «Смотреть» и импорт Icon; DownloadButton импорт оставить; aria-label на thumbnail-Link сохранить.
  • frontend/src/pages/Feed.tsx — передать showActions={isLocal} в VideoCard (строка 113). isLocal уже вычислен (строка 19).
  • frontend/src/pages/ChannelVideos.tsx — без изменений (проп по умолчанию false).
  • frontend/src/App.css — чистка мёртвых правил .button-link:
    • строка 58 (transition-список) — убрать .button-link;
    • строка 59 (общий стиль кнопок) — убрать .button-link;
    • строки 62–63 (.button-secondary, .button-link + hover) — оставить только .button-secondary;
    • строка 91 — .video-actions .button-link, .video-actions .button-secondary → оставить только .video-actions .button-secondary (secondary внутри actions остаётся: его рендерит DownloadButton на /local);
    • строка 280 (media ≤620px) — убрать .video-actions .button-link, из списка;
    • строка 307 (pointer: coarse) — убрать .video-actions .button-link, из списка;
    • .video-actions (строка 90) и .download-* правила остаются — используются DownloadButton на /local и VideoPage.
  • README.md — не трогаем (кнопки карточек в README не документируются; это полировка UI, не фича).

Критерии приёмки

  1. На /, /category/:id, /uncategorized, /search и /channels/:id/videos в карточках нет ни «Смотреть», ни «Скачать»; карточка кликабельна через превью и заголовок, aria-label="Смотреть: …" на thumbnail-Link сохранён.
  2. На /local кнопка скачивания осталась и ведёт себя как раньше: статусы (Скачать/Скачивается N%/В очереди…/Обработка…/На сервере/Повторить/Загрузить снова) и инвалидация кэшей ['feed']/['video', id] по завершении работают. «Смотреть» в карточках нет и на /local.
  3. DownloadButton не сломан нигде: на VideoPage (showDelete) — скачивание, статусы и «Удалить копию» (с инвалидацией) работают как раньше.
  4. CSS почищен: rg "button-link" frontend/src не находит ни одного вхождения (ни в CSS, ни в TSX); правила .video-actions и .download-* остаются живыми (используются DownloadButton).
  5. npm run lint и npm run build в frontend/ чистые (нет unused-импортов/локалов).
  6. Backend не тронут: git status показывает изменения только в frontend/ и analytics/; pytest не требуется (изменений backend/тестов нет), при желании прогоняется без изменений.
  7. Деплой по правилу команды: docker compose up -d --build, curl http://localhost:8080/api/health → OK.

План

  1. VideoCard.tsx: interface Props { video: FeedVideoDto; showActions?: boolean }; деструктуризация ({ video, showActions = false }); .video-actions рендерить условно {showActions && <div className="video-actions"><DownloadButton video={video} /></div>}; удалить «Смотреть»-Link и импорт Icon.
  2. Feed.tsx: <VideoCard key={…} video={video} showActions={isLocal} />.
  3. App.css: вычистить .button-link из строк 58, 59, 62, 63, 91, 280, 307 (по списку выше), не трогая .video-actions и .download-*.
  4. Проверки: rg -n "button-link" frontend/src → пусто; npm run lint, npm run build в frontend/; ручная проверка: лента/категории/поиск/страница канала без кнопок, /local с кнопкой и статусами, VideoPage с «Удалить копию»; деплой и health-проверка.

Риски и ограничения

  • Не потерять действия на /local: условие рендера должно опираться на isLocal из Feed.tsx, а не на проп, вычисляемый внутри карточки (VideoCard не знает маршрут надёжно — точнее держать флаг в родителе). ChannelVideos по умолчанию без действий.
  • Icon/DownloadButton импорты: после удаления «Смотреть» импорт Icon в VideoCard неиспользуемый — при noUnusedLocals сборка упадёт, если его оставить; импорт DownloadButton нужен (условный рендер).
  • «Удалить копию» на карточке /local: в карточке её нет и не было (DownloadButton там рендерится без showDelete); критерий — «не сломать», а не «добавить». Удаление копии остаётся на VideoPage (проп showDelete не трогаем).
  • CSS-чистка: класс .button-link после правки нигде не используется — удалять его правила целиком; .video-actions .button-secondary оставить (secondary-кнопки DownloadButton в блоке действий). Медиа-правила ≤620px и pointer:coarse править точечно, не трогая соседние селекторы.
  • Empty-state /local: подсказка «Нажми „Скачать“ у понравившегося ролика…» остаётся корректной, т.к. на /local кнопка сохраняется. Но на обычной ленте кнопки больше нет — путь скачивания теперь только через страницу видео (это осознанное UX-решение задачи).
  • Feed.tsx уже загружен: изменения ограничиваются одной строкой рендера — не усложнять компонент дополнительной логикой.

Журнал изменений

  • 2026-09-18: документ создан перед реализацией. Зафиксированы решения: проп showActions в VideoCard (default false); «Смотреть» убирается везде, DownloadButton остаётся только на /local (как сегодня, без showDelete); ChannelVideos не меняется; CSS: полное удаление мёртвого класса .button-link, сохранение .video-actions/.download-*; README не трогаем; backend не трогаем.