Skip to content

fix(web): device hub remembers the flat view - #19504

Closed
meghrp wants to merge 2 commits into
pingdotgg:mainfrom
meghrp:fix/device-flat-view-preference
Closed

meghrp wants to merge 2 commits into
pingdotgg:mainfrom
meghrp:fix/device-flat-view-preference

Conversation

@meghrp

@meghrp meghrp commented Oct 14, 2026

Copy link
Copy Markdown

Problem

When you open a device in the device hub and switch to Flat view, the choice does not stick. Switch to another thread and come back, and the device is in the 3D view again. Users who prefer the flat view have to pick it again on every visit.

To reproduce, open a device from + → Device, choose Flat view, open another thread, then go back to the first thread. The device shows the 3D view.

Change

DeviceStreamView kept the choice in component state, so it reset to 3D each time the view mounted again. The choice now goes through the existing useLocalStorage hook under t3code:device-presentation. The default stays 3D, so nothing changes for anyone who never picks Flat.

The user guide for devices now says that the app remembers the choice.

Scope and approval

This is a small fix for an obvious bug, so it has no prior issue. A view choice the user made explicitly is lost on remount. The fix keeps every default and adds no setting. It only stops the app from discarding the choice.

It covers the full device panel on web and desktop, which share this component. Mobile has no 3D view, so it needs no change. The preference is stored per browser or desktop app. It is not synced across devices.

Verification

  • A new test in DeviceStreamView.test.tsx streams a device, presses Flat, unmounts, and mounts the view again. Before the fix, the 3D viewer mounted again (expected 2 to be 1). After the fix, it stays flat. The four existing tests in that file still pass.
  • vp lint on the changed files and tsc-rs --noEmit for apps/web both pass.
  • I did not do a manual pass with a live simulator.

Made with Claude Opus 5.5 in Claude Code.

🤖 Generated with Claude Code

Megh Pathak and others added 2 commits October 14, 2026 12:08
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 14, 2026
@coderabbitai

coderabbitai Bot commented Oct 14, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 693c0529-cd07-4d9a-8f05-9cbc797e45a0
📥 Commits

Reviewing files that changed from the base of the PR and between 7ac952c and c6b33dc.

📒 Files selected for processing: 3
  • apps/web/src/components/device/DeviceStreamView.test.tsx
  • apps/web/src/components/device/DeviceStreamView.tsx
  • docs/user/devices.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

DeviceStreamView now stores the selected Flat or phone presentation in local storage and restores it when a device view mounts. The device tests cover retaining Flat after remounting, and the documentation describes this behavior.

Changes: Device view persistence

Layer / File(s) Summary
Persist and verify the presentation choice
apps/web/src/components/device/DeviceStreamView.tsx, apps/web/src/components/device/DeviceStreamView.test.tsx, docs/user/devices.md
DeviceStreamView validates the stored presentation as phone or flat and persists it under t3code:device-presentation. A test checks that Flat remains selected after remounting. The device documentation describes the stored choice.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to c6b33

The view choice persists per browser or desktop app, and storage failures leave the device view usable with the phone default.

Security architecture risk: ⚪ Minimal · up to c6b33

The change remembers only a validated display preference. It does not change device permissions, stream access or deployment behavior. No material security risk was identified in the reviewed change.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The new shared-state scope is the presentation preference across device views using the same browser/app storage. Manipulating this key can select an existing supported presentation, but it does not select a device, tenant, environment or privileged operation.

Security Findings and Attack Paths

  • inferred — No introduced security attack path was identified in the inspected integration: externally modified stored data is schema-decoded before affecting presentation, while device stream access and authority remain unchanged from the base.

Trust Boundaries and Controls

  • observed — Local-storage content crosses into UI state through JSON/schema decoding restricted to phone and flat; writes use the same schema. Phone rendering additionally retains its existing availability and capability checks, so the persisted preference is not an authorization control.

Resilience and Maintainability Implications

  • inferred — Repeated or concurrent selections replace one non-sensitive enum value rather than performing a multi-resource transaction. Storage corruption, denied writes or interruption can affect preference retention, but the inspected transition does not couple those failures to stream ownership or security controls.
Pre-merge checks: Passed 4
Passed Passed checks: 4 passed
Check name Status Explanation
Description check Passed The description explains the problem, implementation, scope, verification results, and limitations. It also identifies the absence of live simulator testing.
Title check Passed The title is concise, uses the repository's conventional format, and clearly describes the main change: remembering the Flat device view.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Thanks for explaining the repeated view selection. The prior-approval rule applies because replacing per-view state with one browser-wide storage key makes a choice persist across all devices and threads. Please discuss that behavior in an Ideas discussion and obtain approval of the direction and scope before requesting reconsideration.

@maria-rcks maria-rcks closed this Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants