chore(channels-ui): Phase 2 #3 frontend cleanup — dedup 403 handler, count cell, LS keys, dead i18n
- 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.
This commit is contained in:
parent
8fb41383e6
commit
ee601363c2
8 changed files with 54 additions and 71 deletions
|
|
@ -101,3 +101,8 @@ export function formatViews(n: number | null): string {
|
|||
if (n >= 1e3) return `${(n / 1e3).toFixed(1).replace(/\.0$/, "")}K`;
|
||||
return String(n);
|
||||
}
|
||||
|
||||
// A count for a right-aligned table cell: the humanized number, or an em-dash when unknown (null).
|
||||
export function formatCountOrDash(n: number | null | undefined): string {
|
||||
return n != null ? formatViews(n) : "—";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ export const LS = {
|
|||
perfMode: "siftlode.perfMode",
|
||||
channelFilter: "siftlode.channelFilter",
|
||||
channelsView: "siftlode.channelsView",
|
||||
channelsTable: "siftlode.channelsTable",
|
||||
channelDiscoveryTable: "siftlode.channelDiscoveryTable",
|
||||
settingsTab: "siftlode.settingsTab",
|
||||
statsTab: "siftlode.statsTab",
|
||||
adminUsersTab: "siftlode.adminUsersTab",
|
||||
|
|
|
|||
25
frontend/src/lib/youtubeErrors.ts
Normal file
25
frontend/src/lib/youtubeErrors.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
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 });
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue