diff --git a/packages/react/src/components/channel/ChannelCard.tsx b/packages/react/src/components/channel/ChannelCard.tsx index 054acc02d..e9bdc48eb 100644 --- a/packages/react/src/components/channel/ChannelCard.tsx +++ b/packages/react/src/components/channel/ChannelCard.tsx @@ -1,12 +1,13 @@ import { formatCount } from "@/lib/time"; import { Button } from "@/shadcn/ui/button"; -import { ReactNode } from "react"; +import { ReactNode, useCallback } from "react"; import { useTranslation } from "react-i18next"; import { ChannelMenu } from "./ChannelMenu"; import { ChannelImg } from "./ChannelImg"; import { TopicBadge } from "../topic/TopicBadge"; import { ChannelSocials } from "./ChannelSocials"; import type { SetOptional } from "type-fest"; +import { Link, useNavigate } from "react-router-dom"; type WithNonOptional = Pick< T, @@ -49,45 +50,74 @@ export function ChannelCard({ inactive, }: ChannelCardProps) { const { t } = useTranslation(); + const navigate = useNavigate(); + + const channelHref = `/channel/${id}`; + + const goToChannelClickHandler = useCallback( + (evt: React.MouseEvent) => { + if ((evt.target as HTMLElement).closest("a")) { + console.info("no action b/c closest element is a link.", evt); + return; + } + console.info("JS video click handling", evt); + // clicked a non-link part of the channel card. + if (evt.ctrlKey) { + /** Control clicking a non-link part always goes to the external link no matter what the context */ + window.open(channelHref, "_blank"); + evt.preventDefault(); + evt.stopPropagation(); + } else { + navigate(channelHref); + evt.preventDefault(); + evt.stopPropagation(); + } + }, + [channelHref, navigate], + ); switch (size) { case "xs": case "sm": return ( -
- -
-
- {org} - {group && ` / ${group}`} -
-
{name}
-
- {showSubscribers && - t("component.channelInfo.subscriberCount", { - n: formatCount(subscriber_count ?? "0"), - })} - {showVideoCount && - ` / ${t("component.channelInfo.videoCount", { - 0: video_count ?? "0", - })}`} - {showClipCount && - ` / ${t("component.channelInfo.clipCount", { - n: clip_count ?? "0", - })}`} -
- {size === "sm" && ( -
- {top_topics?.map((topic) => ( - - ))} +
+ + +
+
+ {org} + {group && ` / ${group}`}
- )} -
-
+
{name}
+
+ {showSubscribers && + t("component.channelInfo.subscriberCount", { + n: formatCount(subscriber_count ?? "0"), + })} + {showVideoCount && + ` / ${t("component.channelInfo.videoCount", { + 0: video_count ?? "0", + })}`} + {showClipCount && + ` / ${t("component.channelInfo.clipCount", { + n: clip_count ?? "0", + })}`} +
+ {size === "sm" && ( +
+ {top_topics?.map((topic) => ( + + ))} +
+ )} +
+ {children ?? ( - - - - - - {/* {inactive && ( + + + + + {/* {inactive && (
)} */} -
- {name} -
-
-
- {t("component.channelInfo.subscriberCount", { - n: formatCount(subscriber_count ?? "0"), - })} +
+ {name} +
+
+
+ {t("component.channelInfo.subscriberCount", { + n: formatCount(subscriber_count ?? "0"), + })} +
+
+ + {t("component.channelInfo.videoCount", { + 0: video_count ?? 0, + })} + + / + + {t("component.channelInfo.clipCount", { + n: clip_count ?? "0", + })} + +
-
- - {t("component.channelInfo.videoCount", { 0: video_count ?? 0 })} - - / - - {t("component.channelInfo.clipCount", { n: clip_count ?? "0" })} - +
+ {top_topics?.map((topic) => ( + + ))}
-
-
- {top_topics?.map((topic) => ( - - ))} -
-
+ + {children ?? ( { + setMiniPlayer(false); + }, []); + return ( <>