feat(discovery): total-videos column + subscribe confirmation

Add a "Videos" column (channel total uploads, already in the discovery
response) to the Discover-from-playlists table, and guard the Subscribe button
with a confirm dialog warning it changes the real YouTube account and spends
quota (mirrors the unsubscribe guard). Strings added in EN/HU/DE.
This commit is contained in:
npeter83 2026-06-19 11:18:28 +02:00
parent 8de1d801c4
commit 0d48e11d31
4 changed files with 33 additions and 1 deletions

View file

@ -7,6 +7,7 @@ import { notify } from "../lib/notifications";
import Tooltip from "./Tooltip";
import ChannelLink from "./ChannelLink";
import DataTable, { type Column } from "./DataTable";
import { useConfirm } from "./ConfirmProvider";
// The Channel manager's "Discovery" tab: channels that turn up in the user's playlists but
// that they don't subscribe to. Subscribing here only creates the subscription + enriches
@ -20,6 +21,7 @@ export default function ChannelDiscovery({
}) {
const { t } = useTranslation();
const qc = useQueryClient();
const confirm = useConfirm();
const query = useQuery({
queryKey: ["discovered-channels"],
@ -60,6 +62,17 @@ export default function ChannelDiscovery({
},
});
// Subscribing changes the user's real YouTube account and spends a little quota — confirm
// first (mirrors the unsubscribe guard in the Subscriptions tab).
const onSubscribe = async (c: DiscoveredChannel) => {
const ok = await confirm({
title: t("channels.discovery.subscribe"),
message: t("channels.discovery.confirmSubscribe", { name: c.title ?? c.id }),
confirmLabel: t("channels.discovery.subscribe"),
});
if (ok) subscribe.mutate(c);
};
const rows = query.data ?? [];
const columns: Column<DiscoveredChannel>[] = [
@ -87,6 +100,19 @@ export default function ChannelDiscovery({
</span>
),
},
{
key: "videos",
header: t("channels.discovery.cols.totalVideos"),
align: "right",
nowrap: true,
sortable: true,
sortValue: (c) => c.video_count ?? -1,
render: (c) => (
<span className="text-muted tabular-nums">
{c.video_count != null ? formatViews(c.video_count) : "—"}
</span>
),
},
{
key: "inPlaylists",
header: t("channels.discovery.cols.inPlaylists"),
@ -123,7 +149,7 @@ export default function ChannelDiscovery({
}
>
<button
onClick={() => subscribe.mutate(c)}
onClick={() => onSubscribe(c)}
disabled={!canWrite || subscribe.isPending}
className="glass-card glass-hover inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs disabled:opacity-50 transition"
>