feat(channels): dedicated channel page + ephemeral explore UI

Frontend for the channel-explore feature:
- ChannelPage: banner/avatar/stats header, Subscribe/unsubscribe, an "exploring" badge
  while browsing an un-subscribed channel, Videos/About tabs. Reuses Feed scoped to the
  channel (scope=all + source=all so the per-user ephemeral videos show). Auto-ingests
  recent uploads on first visit (background, with a loading note) + "Load more from
  YouTube" to page deeper; skipped for demo / already-subscribed channels.
- App: openChannel/closeChannel as a Back-aware sub-view (history.state._chan, mirrors the
  YT-search _yt pattern); ChannelPage takes over the content column, nav rail stays.
- ChannelLink/cards/player: the channel name now opens our channel page (onChannelFilter →
  onOpenChannel); the in-card "only this channel" filter button is dropped (the page
  subsumes it). PlayerModal channel-name wiring follows in the next commit.
- api: channelDetail + exploreChannel; ChannelDetail/ExploreResult types.
- i18n EN/HU/DE: channel namespace, explore_cleanup scheduler labels, explore config group,
  channels_explore quota label.
This commit is contained in:
npeter83 2026-06-30 03:08:52 +02:00
parent bc4c362423
commit cc1e670202
18 changed files with 744 additions and 120 deletions

View file

@ -40,7 +40,7 @@ export interface VirtualFeedProps {
view: "grid" | "list";
onState: (id: string, status: string) => void;
onToggleSave: (id: string, saved: boolean) => void;
onChannelFilter: (channelId: string, channelName: string) => void;
onOpenChannel: (channelId: string, channelName: string) => void;
onResetState: (id: string) => void;
onOpen: (v: Video, startAt?: number | null) => void;
hasNextPage: boolean;
@ -53,7 +53,7 @@ export default function VirtualFeed({
view,
onState,
onToggleSave,
onChannelFilter,
onOpenChannel,
onResetState,
onOpen,
hasNextPage,
@ -149,7 +149,7 @@ export default function VirtualFeed({
view="grid"
onState={onState}
onToggleSave={onToggleSave}
onChannelFilter={onChannelFilter}
onOpenChannel={onOpenChannel}
onResetState={onResetState}
onOpen={onOpen}
/>
@ -162,7 +162,7 @@ export default function VirtualFeed({
view="list"
onState={onState}
onToggleSave={onToggleSave}
onChannelFilter={onChannelFilter}
onOpenChannel={onOpenChannel}
onResetState={onResetState}
onOpen={onOpen}
/>