import { compareText } from "./collate"; import { serverOrderLang } from "./saveLanguage"; // The channel manager's list order, and the priority steps its menu offers. /** The steps a channel's menu offers (owner, 2026-09-26): fixed levels, so bubbling a channel up * the list is one pick, not a run of +1 presses, and not straight to the top either. The row's * stepper still sets any value, negatives included. */ const PRIORITY_STEPS: readonly number[] = [10, 5, 3, 2, 1, 0]; /** The steps to offer for a channel at `current`: the fixed ones, plus `current` itself in its * place when it is off the scale (a 7, a -2) — the menu always shows, ticked, where it is now. */ export function priorityChoices(current: number): number[] { return PRIORITY_STEPS.includes(current) ? [...PRIORITY_STEPS] : [...PRIORITY_STEPS, current].sort((a, b) => b - a); } interface Ordered { id: string; priority: number; title?: string | null; } /** The server's order (`routes/channels.py`: priority desc, then the title in the reader's alphabet — * the ICU collation of `app/collation.py`, which `compareText` shares — a missing title last). */ function before(a: Ordered, b: Ordered, lang: string): boolean { if (a.priority !== b.priority) return a.priority > b.priority; if (a.title == null) return false; if (b.title == null) return true; return compareText(a.title, b.title, lang) < 0; } /** `rows` with the channel `id` taken out and put back where its priority now places it, every * other row left exactly where it was — the server's order, without a refetch that would reorder * anything the reader did not touch. It takes the account's `preferences`, not a language: the * server sorts in the STORED language (`serverOrderLang`), which a UI language is not always. */ export function placeByPriority( rows: readonly T[], id: string, preferences: Record | null | undefined, ): T[] { const moved = rows.find((r) => r.id === id); if (!moved) return [...rows]; const lang = serverOrderLang(preferences); const rest = rows.filter((r) => r !== moved); const at = rest.findIndex((r) => before(moved, r, lang)); rest.splice(at < 0 ? rest.length : at, 0, moved); return rest; }