fix(web): stop rapid localStorage flip when removing a language model#1295
Conversation
The selected-language-model state was owned by a useSelectedLanguageModel hook instantiated in three chat components, each running its own reset effect against the shared "selectedLanguageModel" localStorage key. Since usehooks-ts broadcasts a storage event on every write, those instances re-triggered each other into a rapid write loop when a model was removed. Lift the state into a single LanguageModelProvider mounted once in the (app) layout. The hook is now a thin context consumer, so there is exactly one owner of the localStorage state and one reset effect. The reset is also made idempotent (only writes when the resolved selection differs by key). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
💤 Files with no reviewable changes (2)
WalkthroughThis PR centralizes language model selection from component prop-drilling to a React context provider at the root layout, with localStorage persistence that correctly resets when the stored selection is no longer available. All consumers are updated to remove languageModels props and use the context-driven hook instead. ChangesLanguage Model Context Refactoring
Sequence DiagramsequenceDiagram
participant Root as App Layout
participant Provider as LanguageModelProvider
participant Context as SelectedLanguageModelContext
participant Consumer as ChatBox/Components
Root->>Root: Fetch configured language models
Root->>Provider: Pass languageModels list
Provider->>Provider: Initialize localStorage entry
Provider->>Provider: Compute fallback model (first in list)
Provider->>Provider: useEffect validates stored selection
Note over Provider: If stored model not in list,<br/>reset to fallback
Provider->>Context: Provide selectedLanguageModel + setter
Consumer->>Context: useSelectedLanguageModel()
Consumer->>Consumer: Render with selected model
Consumer->>Context: setSelectedLanguageModel(model)
Context->>Provider: Update stored selection
Provider->>Provider: Write to localStorage
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The selected-language-model state was owned by a
useSelectedLanguageModelhook instantiated in three chat components (chatBox,chatBoxToolbar,chatThread), each running its own reset effect against the shared"selectedLanguageModel"localStorage key. Since usehooks-ts broadcasts a storage event on every write, those instances re-triggered each other into a rapid write loop when a model was removed.Lift the state into a single
LanguageModelProvidermounted once in the(app)layout.useSelectedLanguageModelis now a thin context consumer, so there is exactly one owner of the localStorage state and one reset effect. The reset is also made idempotent — it only writes when the resolved selection differs by key.🤖 Generated with Claude Code
Summary by CodeRabbit