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:
parent
bc4c362423
commit
cc1e670202
18 changed files with 744 additions and 120 deletions
|
|
@ -77,6 +77,7 @@ export default function Feed({
|
|||
ytSearch,
|
||||
onYtSearch,
|
||||
onExitYtSearch,
|
||||
onOpenChannel,
|
||||
}: {
|
||||
filters: FeedFilters;
|
||||
setFilters: (f: FeedFilters) => void;
|
||||
|
|
@ -91,6 +92,9 @@ export default function Feed({
|
|||
ytSearch: string | null;
|
||||
onYtSearch: (q: string) => void;
|
||||
onExitYtSearch: () => void;
|
||||
// Open a channel's dedicated page (from a card's channel name / avatar). Threaded down to
|
||||
// the cards via VirtualFeed.
|
||||
onOpenChannel?: (channelId: string, channelName?: string) => void;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [overrides, setOverrides] = useState<Record<string, string>>({});
|
||||
|
|
@ -257,11 +261,11 @@ export default function Feed({
|
|||
[qc]
|
||||
);
|
||||
|
||||
const onChannelFilter = useCallback(
|
||||
const handleOpenChannel = useCallback(
|
||||
(channelId: string, channelName: string) => {
|
||||
setFilters({ ...filters, channelId, channelName });
|
||||
onOpenChannel?.(channelId, channelName);
|
||||
},
|
||||
[filters, setFilters]
|
||||
[onOpenChannel]
|
||||
);
|
||||
|
||||
const onToggleSave = useCallback(
|
||||
|
|
@ -347,7 +351,7 @@ export default function Feed({
|
|||
view={view}
|
||||
onState={onState}
|
||||
onToggleSave={onToggleSave}
|
||||
onChannelFilter={onChannelFilter}
|
||||
onOpenChannel={handleOpenChannel}
|
||||
onResetState={onResetState}
|
||||
onOpen={openVideo}
|
||||
hasNextPage={false}
|
||||
|
|
@ -568,7 +572,7 @@ export default function Feed({
|
|||
view={view}
|
||||
onState={onState}
|
||||
onToggleSave={onToggleSave}
|
||||
onChannelFilter={onChannelFilter}
|
||||
onOpenChannel={handleOpenChannel}
|
||||
onResetState={onResetState}
|
||||
onOpen={openVideo}
|
||||
hasNextPage={!!hasNextPage}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue