Embed router migration#7
Merged
Merged
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…o client All 15 command names survive; subcommand trees on filter, mode, default_ring_recipients, and ring collapse into their panels. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…on's custom_id) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both destructive buttons share the label Reset and open a confirmation modal (shared helper, also adopted by delete-data). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Handlers live at their route's path ([param] folders, get/post/modal.ts files) and index.ts is a plain routing table importing each one directly. Per-panel helpers sit in _shared.ts files. Also unifies the reset naming (recipients /clear and clearDefaultRingees become /reset and resetDefaultRingees) and moves the delete-data confirmation modal onto /delete-data itself instead of a /confirm subpath. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
node 22's bundled npm 10 computes a different ideal tree for vite's optional esbuild peer, so a lockfile written by npm 11 fails npm ci under npm 10 (and vice versa). Upgrade npm in CI and normalize the lockfile with npm 11. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Apply the embed redesign handoff across all panels: harmonized accent colors, unicode-emoji titles, `Label · value` status lines, and a consistent final nav row (Home last, on its own row) via a new navRow helper. Render the flash notice as a bolded-lead markdown blockquote. Rework role signups from the two-step add into a scoped panel like filter: pick a scope (by-channel or by-role, as path segments), view its links, and edit them inline with one diffed multi-select. The /signuprole and /unsignuprole commands drive the same edit routes via add/remove query params, mirroring the filter members pattern. Batch (multi-scope) editing is intentionally left out: panel state lives entirely in the customId and Discord caps it at 100 chars, which a multi-id scope path blows past at ~4 ids. Add branded ringvc/vc emoji on Home, guarded on client availability so an unresolvable emoji falls back to none. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reserve router.route for paths that serve multiple methods. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the per-panel back/home nav row with a shared section bar (Home, Signups, Filters, Ringees, Mode), the current section rendered as an inert Primary tab. The Signups tab carries the branded voice-chat app emoji, fetched at startup, with a unicode-bell fallback. Fold Home's old section-button row into the bar, rename Filter to Filters and ring recipients to Ringees, and restyle the catalog page onto grouped description lines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Split the eight sections across two pages of four tabs, with a pager (back on the left, forward on the right) in each row's fifth slot. The bar opens on the page holding the active section, and its nav param lets the pager peek at the other page without leaving the panel. The active tab is inert only on its own root, staying a live link back on sub-pages and other scopes. Move the Github and Support links onto a dedicated About page, leaving Home as the branded welcome plus the bar. Colour the Delete data tab its destructive red when selected, and drop its now-redundant Cancel button. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A dedicated fast path for ringing your saved defaults into your current voice channel, dispatching to the existing /ring/default route so it inherits the same in-VC / not-in-VC handling. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a reusable subNav row (the old role-signups switch, generalized) that sits just above the section bar wherever a section has sibling views. Signups shows My signups / Role signups (the latter only with Manage Roles), and role signups moves its By channel / By role switch below its selects. Split Ring into Quick ring (the immediate action) and Default ringees (the saved list plus auto-ring). The bar's Ring tab is voice-aware, opening Quick ring in a voice channel and Default ringees otherwise, so it never lands on the "not in a voice channel" notice by default. Default ringees inlines prev/next into its action row, keeping the dense panel within Discord's five-row limit. A channel auto-ring override now drops when set back to the global value, so the manual "Remove override" button, route, and handler are gone. Rename ring recipients to ringees throughout, link /ring_defaults from the Default ringees panel, and key the subNav buttons so they never collide with the bar's customIds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move the action acknowledgement below the panel body instead of between the title and the body. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switching the filter type now reinterprets the existing list (blocked users become allowed users, and vice versa) instead of clearing it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- paginate: an exactly-full list (a multiple of PAGE_SIZE) now gets a trailing empty page, so a 26th member can still be added at 25 entries - flashLine: bold only the first line's lead so the ** markers don't span blockquote lines and render literally on multi-line flashes - extract resolveSelectionEdit so the filter/recipients/signups member editors share the select-vs-query-param diff logic; recipients now honors add/remove query params like the others - signups: run the add/remove mutations with Promise.all instead of sequentially awaiting each - vitest: inject dummy env so the suite is self-contained and no longer depends on a developer's .env Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The eight sections no longer fit a five-button row, forcing a two-page split with a pager. A string select holds all of them in one row: the active section is the menu's default option (so it shows as the current value), and the paging plus the nav override query param are gone. navBar no longer needs the current path or query params, so its callers pass only the active section. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The router strips the key during decode, so the POST handlers no longer receive a ts param they never read; base36 keeps the encoding short. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- pageCountOf: only append a trailing empty add-page when a full page
fills the whole edit select (PAGE_SIZE >= SELECT_MAX_VALUES); an
exactly-full list now spans exactly its full pages, so the count line
and pager no longer advertise a phantom page
- page-jump: reject partly-numeric input ("2abc", "1e2") instead of
honoring parseInt's prefix
- ring: restore the server-only guard so /ring from a DM says so rather
than the misleading "join a voice channel" hint
- unsignuprole with no channel routes through the by-role reset
confirmation modal instead of silently clearing every channel
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- role edit handlers call the existing resolveSelectionEdit instead of hand-rolling the select/diff-or-query-param resolution - extract the guild + Manage-Roles + pick-a-scope guard the four role edit/reset handlers repeated into roleEditGuard, returning the resolved guild and scope or the flash to redirect with - move mentionChannel beside mentionUser/mentionRole in @main/ring so the mention family lives in one place Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The four member panels built the same add/remove select by hand, varying only the entity type, its default entries, and the noun. editSelectRow takes the caller's entity-specific builder plus that noun and applies the shared min/max, "Edit <noun>: select to add, deselect to remove" placeholder, reset key, and pattern wiring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Modal dispatches no longer accept reply flags; the confirm modal carries Ephemeral on its setTo instead, applied when a command-launched submission creates its reply. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pageCountOf appends a trailing empty page for adding entries when the last page fills the edit select; the count line derives its page count from the total instead so that navigation-only page never inflates it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Switching a filter's type keeps its entries and reverses what they mean: a blacklist's blocked users become the only people a whitelist lets through. The notice now spells that out and warns instead of confirming when there are entries to reinterpret. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The section bar showed the active section as a selected value, reading
like a value picker. Make the active section the placeholder ("Section:
…") instead, so the bar reads as a location label; selecting any option
routes there.
Move the Ring defaults action from the Quick ring panel onto the Default
ringees panel it rings, left of ⚙ Options via a new pagedControls
leading slot, and redirect its POST back to that panel.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The section bar's "Section:" placeholder now has a sibling: the active sub-nav button is prefixed "View:" to name the current view, so the two nav levels announce themselves the same way and the sub-view switch reads as navigation rather than a pair of actions. That labeling also distinguishes the Default ringees *view* from the Ring defaults *action*, which is what made them feel jumbled — so Ring defaults stays on the Quick ring panel where a ring-now action belongs, and pagedControls drops the leading-action slot it no longer needs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The section bar showed the active section as its placeholder ("Section:
X"), restating what the panel title already says and reading as a stored
value. Make it an action prompt ("Switch sections") so the bar reads as
navigation, and drop the now-unused active argument from every call site.
The sub-nav keeps its "Viewing:" prefix: its buttons are all visible, so
marking the current one helps, whereas the collapsed bar is better spent
inviting the open.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hiding every panel's options behind a ⚙ toggle buried controls like the filter type switch even when the row was free. Show the option buttons directly whenever there's no pager competing for the row (the common single-page case); the toggle now appears only when pagination needs the row too. Destructive actions stay safe through their own confirm modal, not the toggle. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Every panel's Reset was Danger-red, pulling the eye to a rare action and away from the content. Reset is already modal-guarded (type-to-confirm), so the red wasn't the safeguard. Make the five Resets Secondary and keep red only for the Delete-data section's "Delete everything", so red means the one point-of-no-return action. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Modals can't be colored, so signal danger through text instead: prefix every confirm title with⚠️ and add a "This can't be undone." line under the input. Raise the delete-everything confirmation word from DELETE to DELETE EVERYTHING so the nuclear action takes a deliberate phrase, and have its test reference the constant instead of the literal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The toggle switched between green (enable) and grey (disable), so its color flip read as a state change on its own. Use Primary for both and let the label carry enable vs disable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Its one caller passes only (router, path); the label always defaults to "Back". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirror signup/unsignup/signuprole: resolve the current voice channel when no channel option is given, and open the by-role panel when there is no channel context instead of jumping to the reset-all modal. Bulk reset stays available behind the panel's Reset button. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compress paragraph-length comments across the new route layer to one or two lines, keeping only the load-bearing rationale (per-render customId reset, the add-page rule, off-page alreadyPresent semantics, the blacklist/whitelist guard) and cutting restatement. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
use embeds to replace complicated commands