Skip to content

feat(miner-ui): add the persistent collapsible chat rail shell - #6564

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
ultrahighsuper:feat/chat-rail-6513
Jul 16, 2026
Merged

feat(miner-ui): add the persistent collapsible chat rail shell#6564
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
ultrahighsuper:feat/chat-rail-6513

Conversation

@ultrahighsuper

Copy link
Copy Markdown
Contributor

What

Mounts a persistent, collapsible chat rail once in the root route so it survives client-side navigation across all four routes. Pure structural shell — no chat content yet.

Resolves #6513.

  • apps/loopover-miner-ui/src/components/chat-rail.tsx — the rail shell.
  • apps/loopover-miner-ui/src/routes/__root.tsx — mounts it once, beside the routed content.

Behavior (per the issue's requirements)

  • Wide viewports: docks a ~380px complementary panel beside the routed <main>, not overlapping it. __root.tsx's container is restructured into a row holding the main content and the rail side by side, without changing the four routes' own content (and preserving the existing active-route nav highlighting).
  • Below the useIsMobile breakpoint: collapses to the same Sheet-based slide-over sidebar.tsx already uses on mobile — imported from @loopover/ui-kit/components/sheet + @loopover/ui-kit/hooks/use-mobile, not a second bespoke mobile-collapse mechanism or a new breakpoint constant.
  • Toggle: a visible collapse/expand control. Collapsing only hides the docked panel (hidden) — it never unmounts the rail, so future in-rail state is preserved across an expand/collapse cycle.
  • Persistent state: the open/collapsed state lives in the exported RootShell that the root route mounts once, so it survives client-side navigation (in-memory; no localStorage, per the issue).
  • Static placeholder content only — no composer, message list, streaming, or backend call.

Scope / non-goals (explicit "do NOT" list honored)

  • No new custom modal / matchMedia / CSS-only breakpoint for the mobile mode — reuses sidebar.tsx's Sheet + use-mobile.tsx exactly.
  • No @loopover/ui-kit change; no scroll-area/avatar/state-views usage; no route-tree change; no config flag; no composer/message-list/streaming/fetch.

Tests — apps/loopover-miner-ui/src/chat-rail.test.tsx

  • Wide viewport docks a complementary panel (not the sheet); collapsed hides it from the a11y tree while the toggle stays visible; the toggle requests the open/close change.
  • Below the mobile breakpoint the rail renders via the ui-kit Sheet slide-over (asserted by role dialog), not the docked panel.
  • RootShell mounts exactly one rail and keeps its open state across a simulated client-side navigation (the Outlet content swaps while the shell stays mounted).

apps/** is outside Codecov's coverage.include, so no patch-coverage gate applies. Locally green: miner-ui npm run test (--coverage) — full suite 155/155 pass, coverage 87.04% stmts / 86.39% branch / 79.79% funcs / 89.08% lines (above the app floor); tsc --noEmit clean; eslint clean (no new warnings).

…ored#6513)

Mounts a persistent chat rail once in the root route so it survives client-side
navigation across the four routes.

- apps/loopover-miner-ui/src/components/chat-rail.tsx — a pure structural shell.
  Wide viewports dock a ~380px complementary panel beside the routed content;
  below the ui-kit useIsMobile breakpoint it collapses to the same Sheet-based
  slide-over sidebar.tsx uses on mobile (imported from @loopover/ui-kit, not a
  second bespoke mobile-collapse mechanism). A visible toggle expands/collapses
  it; collapsing only hides the docked panel (never unmounts it), so future
  in-rail state is preserved across an expand/collapse cycle. Static placeholder
  content only — no composer, message list, streaming, or backend call.
- apps/loopover-miner-ui/src/routes/__root.tsx — restructured into a row that
  holds the routed <main> and the rail side by side without changing the four
  routes' own content (and preserving the existing active-route nav
  highlighting). The rail open/collapsed state lives in the exported RootShell
  that the root route mounts once, so it persists across route navigation.

No @loopover/ui-kit change, no route-tree change, no scroll-area/avatar/
state-views usage, no config flag. This app's files are outside Codecov's
coverage.include; the local vitest gate stays green.

Tests — apps/loopover-miner-ui/src/chat-rail.test.tsx:
- Wide viewport docks a complementary panel (not the sheet); collapsed hides it
  from the a11y tree while the toggle stays visible; the toggle requests the
  open/close change.
- Below the mobile breakpoint the rail renders via the ui-kit Sheet slide-over,
  not the docked panel.
- RootShell mounts exactly one rail and keeps its open state across a simulated
  client-side navigation (the Outlet content swaps while the shell stays
  mounted).

Closes JSONbored#6513
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 16, 2026
@loopover-orb

loopover-orb Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-16 13:58:24 UTC

3 files · 1 AI reviewer · no blockers · readiness 82/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
Adds a persistent ChatRail shell mounted once in RootShell, with a docked ~380px panel on wide viewports and a Sheet slide-over on mobile (reusing the existing useIsMobile/Sheet pattern from sidebar.tsx), toggle state owned by RootShell so it survives client-side navigation. The implementation matches the issue's stated requirements closely (no new modal/breakpoint mechanism, hides rather than unmounts on collapse, static placeholder content only), and the accompanying tests exercise the real component tree (wide vs mobile viewport branching, toggle click behavior, state persistence across simulated navigation) rather than fabricated scenarios. One structural nit: the wide-viewport width is applied only via inline `style` on the `<aside>`, so verify `RAIL_WIDTH_PX` truly governs total layout width consistently with the `max-w-[calc(64rem+380px)]` container math in `__root.tsx`.

Nits — 5 non-blocking
  • `apps/loopover-miner-ui/src/routes/__root.tsx:70` hardcodes `380px` in the container's `max-w-[calc(64rem+380px)]` separately from `RAIL_WIDTH_PX` in chat-rail.tsx — if one changes without the other, the docked panel could overflow or leave a gap; consider deriving both from a single shared constant.
  • Mobile toggle button text is always "Chat" (chat-rail.tsx) while desktop toggle switches between "Show chat"/"Hide chat" — the mobile button's `aria-expanded` still reflects state so it's not a functional bug, but the asymmetric labeling is a minor UX inconsistency worth a one-line justification.
  • The PR reviewer brief flags `Chat rail: persistent collapsible shell mounted in __root.tsx #6513` in `__root.tsx:20` as an unexplained magic number in a doc comment; it's inside a comment, not logic, so this is purely cosmetic and not worth acting on.
  • No `aria-live` region announces the mobile-vs-desktop mode switch when `useIsMobile` transitions mid-session (e.g., a resized window) — minor since this is a placeholder shell and not yet handling real content.
  • Extract a single shared width constant (e.g. export `RAIL_WIDTH_PX` from chat-rail.tsx and consume it in the `__root.tsx` `max-w-[calc(64rem+380px)]` calculation) so the two files can't drift.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #6513
Related work ⚠️ 1 scoped overlap Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 112 registered-repo PR(s), 70 merged, 21 issue(s).
Contributor context ✅ Confirmed Gittensor contributor ultrahighsuper; Gittensor profile; 112 PR(s), 21 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The PR adds a new chat-rail.tsx shell mounted once in __root.tsx (via an exported RootShell holding in-memory open/collapsed state), docks a ~380px panel beside the routed content on wide viewports, reuses ui-kit's Sheet + useIsMobile hook for the mobile slide-over instead of inventing a new breakpoint/modal, and ships only static placeholder content with no composer/message-list/streaming/backend

Review context
  • Author: ultrahighsuper
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, JavaScript, Rust, TypeScript, Cuda, Ruby
  • Official Gittensor activity: 112 PR(s), 21 issue(s).
  • Related work: Titles/paths share 7 meaningful terms. (issue #6513, issue #6518)
Contributor next steps
  • Start here: Review top overlaps.
  • Then work through the remaining 2 steps in the Signals table above.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 93f3467 into JSONbored:main Jul 16, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chat rail: persistent collapsible shell mounted in __root.tsx

1 participant