- Extract notifyYouTubeActionError (new lib/youtubeErrors.ts): the "403 → Connect your YouTube account, else fallback toast" logic was duplicated in Channels.tsx and ChannelDiscovery.tsx. (Separate file, not lib/notifications, to avoid the api ↔ notifications import cycle.) - Extract format.formatCountOrDash(): the `n != null ? formatViews(n) : "—"` count cell was repeated across the subs/videos columns in Channels + ChannelDiscovery. - Register channelsTable / channelDiscoveryTable in storage.ts LS instead of bare "siftlode.*" string literals. - Delete 7 dead channels.json keys (filterPlaceholder, tags.newTag/createTag, row.stored/subs/getFullHistory/getFullHistoryHint) from en/hu/de — verified 0 refs (createTag matches were the unrelated api.createTag method, not the key). Behavior-neutral. tsc green, knip no new unused, localdev boots.
26 lines
964 B
TypeScript
26 lines
964 B
TypeScript
import { HttpError } from "./api";
|
|
import { notify } from "./notifications";
|
|
import i18n from "../i18n";
|
|
|
|
// A YouTube-gated action (subscribe, sync, backfill, unsubscribe) that 403s means the user hasn't
|
|
// granted the write scope — surface a "Connect" affordance instead of a vague failure. Pass
|
|
// `onConnect` to offer the connect-wizard button (callers that have no wizard handle, e.g. the
|
|
// channel page, just get the message). `fallbackMessage` is the already-translated non-403 error.
|
|
export function notifyYouTubeActionError(
|
|
err: unknown,
|
|
fallbackMessage: string,
|
|
onConnect?: () => void,
|
|
): void {
|
|
if (err instanceof HttpError && err.status === 403) {
|
|
notify({
|
|
level: "error",
|
|
message: i18n.t("channels.notify.needYouTube"),
|
|
action: onConnect
|
|
? { label: i18n.t("channels.notify.connect"), onClick: onConnect }
|
|
: undefined,
|
|
});
|
|
} else {
|
|
notify({ level: "error", message: fallbackMessage });
|
|
}
|
|
}
|