Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 0186d2f4ab15cab7f3228b1dbc2292d0bb7e332d
parent 92741a1277212425cbb3b72de61fc753498588dc
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Fri, 11 Sep 2026 11:24:38 -0400

editor: the two channel-priority components S3 and S4 will fill in

Empty-but-exported, with the props as the contract. They exist now so the two UI
slices each edit a file the other does not and can run fully in parallel on
separate branches: S3 fills in ChannelTierSelect, S4 fills in FocusBanner.

FocusBanner already honours the one rule S4 is written around — render nothing
when nothing is focused — so it is green on /channels before S3 exists and on the
lane consoles before anything writes a focus.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Aeditor/app/channels/components/ChannelTierSelect.tsx | 41+++++++++++++++++++++++++++++++++++++++++
Aeditor/app/channels/components/FocusBanner.tsx | 43+++++++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/editor/app/channels/components/ChannelTierSelect.tsx b/editor/app/channels/components/ChannelTierSelect.tsx @@ -0,0 +1,41 @@ +// THE /channels TIER CONTROL — a STUB, filled in by slice S3. +// +// It exists at S0 only so S3 and S4 each edit a file the other does not: S3 +// fills this in and S4 fills in FocusBanner.tsx, and the two branches run in +// parallel with no shared file. The props are the contract both slices code +// against; the body is `null` until S3. +// +// What S3 makes of it: the cell that `ChannelSyncToggle` occupies today +// (ChannelsTable.tsx) becomes a `<select>` over STORED_CHANNEL_TIERS with +// `aria-label={`tier for ${slug}`}`, posting `setChannelTierAction(slug, tier)` +// — one writer, `saveChannelPriorityAction`, recompiles the four roots in the +// same saveSettings call. `focused` and `heldReason` are DISPLAY facts derived +// from the same `focusSummary` the banner uses, not a second read. The +// per-operation overrides sit behind a disclosure beside the select, with a +// "Sync only" preset; `overrides` carries what is currently pinned. + +import type { + PriorityOperation, + StoredChannelTier, +} from "yt-dlp-transcript-common/lib/channelPriority"; + +export type ChannelTierSelectProps = { + slug: string; + // The channel's BASE tier (tierOf), not its effective tier for any one + // operation — the overrides are shown beside it, not folded into it. + tier: StoredChannelTier; + // Per-operation pins, normalised (only operations that differ from `tier`). + overrides?: Partial<Record<PriorityOperation, StoredChannelTier>>; + // This channel is in the active focus set. Focus is a corpus-wide selector, + // never a stored tier, so it is passed in rather than read off `tier`. + focused?: boolean; + // "Held — focus: <name>" for a non-focus row while a focus holds the lanes. + heldReason?: string | null; + disabled?: boolean; +}; + +export default function ChannelTierSelect( + _props: ChannelTierSelectProps, +): React.ReactNode { + return null; +} diff --git a/editor/app/channels/components/FocusBanner.tsx b/editor/app/channels/components/FocusBanner.tsx @@ -0,0 +1,43 @@ +// THE FOCUS BANNER — a STUB, filled in by slice S4. +// +// It exists at S0 for the same reason ChannelTierSelect.tsx does: S3 and S4 +// then each edit one file the other does not. It already honours the one rule +// S4 is written around — RENDER NOTHING WHEN NOTHING IS FOCUSED — so it is +// green on /channels before S3 exists and green on the lane consoles before +// anything writes a focus. +// +// What S4 makes of it: `Focus: <name> (N channels) · <units> pending in this +// lane · M channels held`, plus an "End focus" button posting `endFocusAction()`. +// The numbers come from `computeLeafPending`, which the status panel already +// computes, so the banner is one sum over `counts` and no new read. +// +// WHERE IT GOES on the lane consoles: OperationDetail.tsx, between +// HowPriorityWorks and RunnerOperationView — i.e. OUTSIDE the `<section +// data-lane>` that RunnerOperationView opens, whose contract comment reserves +// `role="status"` and forbids a nested `<section>`. +// +// It is NOT a new AutoRunnerIdleReason. A lane whose focus group holds the rest +// is not idle, it is dispatching focus work; "M channels held" is a display +// fact. + +import type { AutoQueueKind } from "yt-dlp-transcript-common/lib/autoQueueTypes"; +import type { FocusSummary } from "yt-dlp-transcript-common/lib/channelPriority"; + +export type FocusBannerProps = { + summary: FocusSummary; + // Display name for the focus: a site's title for a site focus, or a short + // channel list. Resolved by the caller — this file does no I/O and the model + // stores a siteId, not a title. + name?: string; + // The lane this banner is drawn beside, when it is on a lane console. Null on + // /channels, where the per-lane line is repeated for each ENABLED lane. + lane?: AutoQueueKind | null; +}; + +export default function FocusBanner({ + summary, +}: FocusBannerProps): React.ReactNode { + // Nothing focused, nothing to say. S4 replaces the rest of this body. + if (!summary.active) return null; + return null; +}