refactor(nav): read navigation from context, drop the prop-drilling

VideoCard/PlayerModal read openChannel from useNavigationActions (the memo'd
VideoCard subscribes to the STABLE actions context, so a page/channel change
no longer re-renders it); NavSidebar/Header read page/setPage; ChannelPage
reads closeChannel; NotificationsPanel reads setPage. App sheds the matching
props, and Feed/VirtualFeed no longer thread onOpenChannel at all.
This commit is contained in:
2026-07-18 02:19:52 +02:00
parent 41bb1b2ab3
commit a1bdfece6d
9 changed files with 20 additions and 53 deletions
+3 -3
View File
@@ -1,5 +1,6 @@
import { memo, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigationActions } from "./NavigationProvider";
import {
Bookmark,
Check,
@@ -368,7 +369,6 @@ function VideoCard({
onState,
onResetState,
onToggleSave,
onOpenChannel,
onOpen,
}: {
video: Video;
@@ -378,10 +378,10 @@ function VideoCard({
onState: (id: string, status: string) => void;
onResetState?: (id: string) => void;
onToggleSave: (id: string, saved: boolean) => void;
onOpenChannel?: (channelId: string, channelName: string) => void;
onOpen?: (v: Video, startAt?: number | null) => void;
}) {
const { t, i18n } = useTranslation();
const { openChannel } = useNavigationActions();
const spec = FEED_VIEW_SPEC[view];
const watched = video.status === "watched";
// The thumbnail-less row drops Thumb, and with it the duration / live state / saved marker that
@@ -451,7 +451,7 @@ function VideoCard({
data-testid="video-card-channel"
onClick={(e) => {
e.stopPropagation();
onOpenChannel?.(video.channel_id, video.channel_title ?? t("card.thisChannel"));
openChannel(video.channel_id, video.channel_title ?? t("card.thisChannel"));
}}
title={channelClamped ? video.channel_title ?? undefined : undefined}
className="text-sm text-muted truncate block w-fit max-w-full text-left hover:text-fg"