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.
11 KiB
11 KiB
Чистка карточек видео: убрать «Смотреть» и «Скачать» из ленты, оставить действия на /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(defaultfalse); блок.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.
- строка 58 (transition-список) — убрать
README.md— не трогаем (кнопки карточек в README не документируются; это полировка UI, не фича).
Критерии приёмки
- На
/,/category/:id,/uncategorized,/searchи/channels/:id/videosв карточках нет ни «Смотреть», ни «Скачать»; карточка кликабельна через превью и заголовок,aria-label="Смотреть: …"на thumbnail-Link сохранён. - На
/localкнопка скачивания осталась и ведёт себя как раньше: статусы (Скачать/Скачивается N%/В очереди…/Обработка…/На сервере/Повторить/Загрузить снова) и инвалидация кэшей['feed']/['video', id]по завершении работают. «Смотреть» в карточках нет и на/local. DownloadButtonне сломан нигде: наVideoPage(showDelete) — скачивание, статусы и «Удалить копию» (с инвалидацией) работают как раньше.- CSS почищен:
rg "button-link" frontend/srcне находит ни одного вхождения (ни в CSS, ни в TSX); правила.video-actionsи.download-*остаются живыми (используются DownloadButton). npm run lintиnpm run buildвfrontend/чистые (нет unused-импортов/локалов).- Backend не тронут:
git statusпоказывает изменения только вfrontend/иanalytics/;pytestне требуется (изменений backend/тестов нет), при желании прогоняется без изменений. - Деплой по правилу команды:
docker compose up -d --build,curl http://localhost:8080/api/health→ OK.
План
VideoCard.tsx:interface Props { video: FeedVideoDto; showActions?: boolean }; деструктуризация({ video, showActions = false });.video-actionsрендерить условно{showActions && <div className="video-actions"><DownloadButton video={video} /></div>}; удалить «Смотреть»-Link и импортIcon.Feed.tsx:<VideoCard key={…} video={video} showActions={isLocal} />.App.css: вычистить.button-linkиз строк 58, 59, 62, 63, 91, 280, 307 (по списку выше), не трогая.video-actionsи.download-*.- Проверки:
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 не трогаем.