Skip to content

Conversation

@ussaama
Copy link
Contributor

@ussaama ussaama commented Dec 8, 2025

Summary by CodeRabbit

  • Improvements

    • Simplified refine button navigation flow and improved state management to enhance responsiveness when refining conversations.
  • Localization

    • Added new translation entries and reorganized existing translation keys to ensure consistent labeling across the application interface.

✏️ Tip: You can customize this high-level summary in your review settings.

…e" selected from dashboard and show "Refine" button

- ECHO-614 disable "Refine" button while "Go deeper" response is generating
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Walkthrough

This PR implements a localStorage-based mechanism to disable the refine button while "Go Deeper" response generates, simplifies refine navigation logic by removing cooldown dependency, and updates translation identifiers from "experimental" to "beta" across participant and portal editor components.

Changes

Cohort / File(s) Change Summary
Refine button state management
echo/frontend/src/components/participant/ParticipantConversationAudio.tsx, echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx, echo/frontend/src/components/participant/refine/RefineSelection.tsx
Added localStorage-backed state using key refine_disabled_${conversationId} to track disabled state per conversation. Removed useRefineSelectionCooldown hook and simplified refine navigation to always route to the refine endpoint. Button disabled state now depends on isStopping or isRefineDisabled. RefineSelection sets the flag to true when Echo action starts.
Translation updates
echo/frontend/src/components/project/ProjectPortalEditor.tsx
Updated translation IDs for Beta labels from "dashboard.dembrane.concrete.experimental" to "dashboard.dembrane.concrete.beta" in two occurrences.
Locale file
echo/frontend/src/locales/en-US.po
Added new translation entry for dashboard.dembrane.concrete.beta and relocated source location references for multiple existing translation keys (Advanced Settings, Page Content, Page Title, Portal Content, Live Preview, Concrete Topics, etc.) to reflect refactored component references.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • ParticipantConversationAudio.tsx: Verify that removal of cooldown logic and simplified navigation align with product requirements; check that localStorage key format is consistent
  • RefineSelection.tsx: Confirm that localStorage flag is properly set when Echo generation starts and that cleanup paths exist
  • en-US.po: Validate that all relocated translation key references point to correct source files and that no translations were unintentionally duplicated or lost

Suggested labels

bug, improvement

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Changes address ECHO-614 (disable refine button), ECHO-571 (label changes), and update translations, but ECHO-613 and ECHO-591 requirements are not evident in the code changes provided. Verify implementation of ECHO-613 (Go deeper functionality) and ECHO-591 (2FA error message) in the changeset, or confirm they are out of scope for this PR.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: translation fixes, label replacements, and disabling the refine button during generation.
Out of Scope Changes check ✅ Passed All changes appear scoped to the linked issues: refine button disabling logic, label/translation updates, and UI text improvements align with stated objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch testing

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.

❤️ Share

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

@coderabbitai coderabbitai bot added bug Something isn't working improvement labels Dec 8, 2025
@ussaama ussaama added this pull request to the merge queue Dec 8, 2025
Merged via the queue into main with commit 441a45d Dec 8, 2025
20 of 21 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 176aaf3 and 81d7985.

📒 Files selected for processing (5)
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx (4 hunks)
  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx (3 hunks)
  • echo/frontend/src/components/participant/refine/RefineSelection.tsx (3 hunks)
  • echo/frontend/src/components/project/ProjectPortalEditor.tsx (2 hunks)
  • echo/frontend/src/locales/en-US.po (40 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
echo/frontend/**/src/{routes,components}/**/*.tsx

📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)

echo/frontend/**/src/{routes,components}/**/*.tsx: Compose Mantine primitives (Stack, Group, ActionIcon, etc.) while layering Tailwind utility classes via className, alongside toast feedback via @/components/common/Toaster
For Tailwind classes that need dynamic values, replace with inline style props using CSS variables instead of hardcoded hex values

Files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
  • echo/frontend/src/components/project/ProjectPortalEditor.tsx
echo/frontend/**/src/**/*.{css,tsx,ts}

📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)

Use CSS variables var(--app-background) and var(--app-text) instead of hardcoded colors like #F6F4F1 or #2D2D2C to ensure theme changes propagate

Files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
  • echo/frontend/src/components/project/ProjectPortalEditor.tsx
echo/frontend/**/src/{theme.tsx,components,routes}/**/*.tsx

📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)

When adding new Mantine components, reference the global Mantine theme in src/theme.tsx with custom primary color palette and component defaults, preferring CSS variables in styles over hardcoded hex values

Files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
  • echo/frontend/src/components/project/ProjectPortalEditor.tsx
echo/frontend/**/src/{components,routes}/**/*.tsx

📄 CodeRabbit inference engine (echo/frontend/AGENTS.md)

UI mutations should surface inline feedback: pair toasts with contextual Mantine Alert components inside modals/forms for errors or warnings

Files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
  • echo/frontend/src/components/project/ProjectPortalEditor.tsx
🧠 Learnings (17)
📓 Common learnings
Learnt from: ussaama
Repo: Dembrane/echo PR: 259
File: echo/frontend/src/components/layout/ParticipantLayout.tsx:33-33
Timestamp: 2025-08-08T10:39:31.114Z
Learning: In echo/frontend/src/components/layout/ParticipantLayout.tsx, prefer using simple pathname.includes("start") and pathname.includes("finish") to control the settings button visibility. No need to switch to segment-based matching or add a useEffect to auto-close the modal for these routes, per ussaama’s preference in PR #259.
Learnt from: ussaama
Repo: Dembrane/echo PR: 205
File: echo/frontend/src/lib/query.ts:1444-1506
Timestamp: 2025-07-10T12:48:20.683Z
Learning: ussaama prefers string concatenation over template literals for simple cases where readability is clearer, even when linting tools suggest template literals. Human readability takes precedence over strict linting rules in straightforward concatenation scenarios.
📚 Learning: 2025-11-21T12:44:30.306Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 366
File: echo/frontend/src/components/participant/refine/RefineSelection.tsx:38-38
Timestamp: 2025-11-21T12:44:30.306Z
Learning: In echo/frontend/src/components/participant/refine/RefineSelection.tsx, the refine selection panels (Make it concrete / Go deeper) should use h-[50%] when only one panel is visible to maintain half-height spacing for consistent visual weight. The flexClass logic should remain: showVerify && showEcho ? "flex-1" : "h-[50%]".

Applied to files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/locales/en-US.po
📚 Learning: 2025-08-06T13:38:30.769Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 256
File: echo/frontend/src/components/participant/MicrophoneTest.tsx:54-54
Timestamp: 2025-08-06T13:38:30.769Z
Learning: In echo/frontend/src/components/participant/MicrophoneTest.tsx, the useDisclosure hook is used where only the `close` function is needed locally (called in handleConfirmMicChange and handleCancelMicChange), while `opened` and `open` are unused because the modal state is managed by a parent component. The `showSecondModal` state variable is used separately to control content switching within the modal between the main UI and confirmation step.

Applied to files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
  • echo/frontend/src/locales/en-US.po
📚 Learning: 2025-08-08T10:39:31.114Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 259
File: echo/frontend/src/components/layout/ParticipantLayout.tsx:33-33
Timestamp: 2025-08-08T10:39:31.114Z
Learning: In echo/frontend/src/components/layout/ParticipantLayout.tsx, prefer using simple pathname.includes("start") and pathname.includes("finish") to control the settings button visibility. No need to switch to segment-based matching or add a useEffect to auto-close the modal for these routes, per ussaama’s preference in PR #259.

Applied to files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/routes/**/*.tsx : Use Lingui macros `t` from `lingui/core/macro` and `Trans` from `lingui/react/macro` for localizing UI strings in routed screens

Applied to files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/project/ProjectPortalEditor.tsx
  • echo/frontend/src/locales/en-US.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{routes,components}/**/*.tsx : Compose Mantine primitives (`Stack`, `Group`, `ActionIcon`, etc.) while layering Tailwind utility classes via `className`, alongside toast feedback via `@/components/common/Toaster`

Applied to files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/hooks/useAppPreferences.tsx : User preferences (font family, color scheme) persist in localStorage under key `dembrane-app-preferences`; font preference is linked to color scheme: DM Sans→Parchment+Graphite, Space Grotesk→White+Black

Applied to files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/routes/auth/**/*.tsx : Gentle login/logout flows use `useTransitionCurtain().runTransition()` before navigation—animations expect Directus session mutations to await that promise

Applied to files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
📚 Learning: 2025-10-28T13:47:02.926Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 350
File: echo/frontend/src/components/participant/ParticipantConversationText.tsx:82-85
Timestamp: 2025-10-28T13:47:02.926Z
Learning: The participant “finish” flow should call finishConversation(conversationId) (echo/frontend/src/lib/api.ts) before navigating to /:projectId/conversation/:conversationId/finish so the backend sets is_finished and triggers task_finish_conversation_hook.

Applied to files:

  • echo/frontend/src/components/participant/refine/RefineSelection.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/locales/en-US.po
📚 Learning: 2025-10-28T13:47:02.926Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 350
File: echo/frontend/src/components/participant/ParticipantConversationText.tsx:82-85
Timestamp: 2025-10-28T13:47:02.926Z
Learning: In text mode (echo/frontend/src/components/participant/ParticipantConversationText.tsx), participants only submit PORTAL_TEXT chunks (no audio). The “Finish” button is shown only after at least one text message is saved to Directus.

Applied to files:

  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
  • echo/frontend/src/locales/en-US.po
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{components,routes}/**/*.tsx : UI mutations should surface inline feedback: pair toasts with contextual Mantine `Alert` components inside modals/forms for errors or warnings

Applied to files:

  • echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
📚 Learning: 2025-12-05T00:33:33.442Z
Learnt from: CR
Repo: Dembrane/echo PR: 0
File: echo/frontend/AGENTS.md:0-0
Timestamp: 2025-12-05T00:33:33.442Z
Learning: Applies to echo/frontend/**/src/{routes/auth,components/settings}/**/hooks/index.ts : Auth session state depends on the shared `['auth','session']` React Query key; invalidate it on login/logout before fetching `['users','me']`

Applied to files:

  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
📚 Learning: 2025-08-19T10:22:55.323Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 266
File: echo/frontend/src/components/conversation/ConversationAccordion.tsx:675-678
Timestamp: 2025-08-19T10:22:55.323Z
Learning: In echo/frontend/src/components/conversation/hooks/index.ts, the useConversationsCountByProjectId hook uses useSuspenseQuery with Directus aggregate, which always returns string numbers like "0", "1", "2" and suspends during loading instead of returning undefined. Therefore, Number(conversationsCountQuery.data) ?? 0 is safe and the Number() conversion is necessary for type conversion from string to number.

Applied to files:

  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
📚 Learning: 2025-08-19T10:22:55.323Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 266
File: echo/frontend/src/components/conversation/ConversationAccordion.tsx:675-678
Timestamp: 2025-08-19T10:22:55.323Z
Learning: In echo/frontend/src/components/conversation/hooks/index.ts, the useConversationsCountByProjectId hook uses regular useQuery (not useSuspenseQuery), which means conversationsCountQuery.data can be undefined during loading states. When using Number(conversationsCountQuery.data) ?? 0, this creates NaN because Number(undefined) = NaN and NaN is not nullish, so the fallback doesn't apply. The correct pattern is Number(conversationsCountQuery.data ?? 0) to ensure the fallback happens before type conversion.

Applied to files:

  • echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx
📚 Learning: 2025-05-30T15:38:44.413Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 169
File: echo/frontend/src/components/project/ProjectPortalEditor.tsx:409-464
Timestamp: 2025-05-30T15:38:44.413Z
Learning: Badge-based selectors in ProjectPortalEditor.tsx: Keyboard navigation enhancements for accessibility are considered optional improvements rather than critical issues. The user acknowledges these suggestions but doesn't prioritize them as blockers.

Applied to files:

  • echo/frontend/src/components/project/ProjectPortalEditor.tsx
  • echo/frontend/src/locales/en-US.po
📚 Learning: 2025-08-19T10:14:31.647Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 266
File: echo/frontend/src/components/chat/ChatAccordion.tsx:214-221
Timestamp: 2025-08-19T10:14:31.647Z
Learning: In the Echo frontend codebase using Lingui, i18n IDs in Trans components (e.g., `<Trans id="any.string.here">`) can be arbitrary strings and don't need to follow specific naming conventions. They are just references used in .po files, and the actual translations need to be manually defined in the locale files.

Applied to files:

  • echo/frontend/src/components/project/ProjectPortalEditor.tsx
  • echo/frontend/src/locales/en-US.po
📚 Learning: 2025-09-16T08:34:38.109Z
Learnt from: ussaama
Repo: Dembrane/echo PR: 293
File: echo/frontend/src/components/chat/ChatTemplatesMenu.tsx:15-16
Timestamp: 2025-09-16T08:34:38.109Z
Learning: In ChatTemplatesMenu.tsx, titles are preferred over IDs for template selection logic since titles are unique one-liners and work effectively as identifiers. IDs were added primarily for better list rendering rather than selection purposes.

Applied to files:

  • echo/frontend/src/locales/en-US.po
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: ci-check-server
🔇 Additional comments (4)
echo/frontend/src/locales/en-US.po (1)

291-305: i18n wiring for Beta / Refine / “Go deeper” / “Make it concrete” is coherent

All the new/updated Lingui IDs (beta label, refine modal titles/reason, “Go deeper”/“Make it concrete” buttons & descriptions, concrete topics, portal/thank-you content, live preview/refresh) line up with the TSX usages in the other files. Wording is consistent with the product language and the Echo→Go deeper / Verify→Make it concrete rename, and the obsolete experimental keys are correctly tombstoned with #~. No action needed here.

Also applies to: 324-337, 687-690, 790-808, 936-959, 1388-1423, 1736-1739, 1799-1807, 1898-1901, 2097-2130, 2178-2186, 2337-2340, 2545-2556, 2712-2715, 3623-3626, 3758-3761, 3807-3810, 3824-3827, 3426-3438, 4260-4263

echo/frontend/src/components/project/ProjectPortalEditor.tsx (1)

552-562: Beta labelling now correctly driven by shared translation IDs

Both “Go deeper” and “Make it concrete” badges use dashboard.dembrane.concrete.beta, and the title/description/topic-select IDs (dashboard.dembrane.concrete.title/description/topic.select) match the locale file. This centralizes the Beta copy and removes the old experimental key cleanly. LGTM.

Also applies to: 737-751

echo/frontend/src/components/participant/ParticipantConversationAudioContent.tsx (1)

2-3: LocalStorage cleanup for refine-disable flag is correctly hooked into chat lifecycle

Tying removeValue() into both useChat onError and onFinish against the shared refine_disabled_${conversationId} key is the right shape to ensure the refine-disable flag doesn’t get stuck after a Go deeper run. The hook is only used for side effects here, which is fine given the small overhead. LGTM.

Also applies to: 30-35, 60-66

echo/frontend/src/components/participant/refine/RefineSelection.tsx (1)

3-4: Refine selection now correctly marks the refine flow as disabled on “Go deeper”

Using useLocalStorage with the per-conversation key and flipping it to true in handleEchoClick right after starting the echo cooldown is the right trigger point from this component’s POV; the rest of the refine UI (flex layout, cooldown messaging) is preserved exactly as before. The only caveat is ensuring the reader of this flag actually reacts to it—which I’m calling out in the parent ParticipantConversationAudio review.

Also applies to: 15-18, 25-30

Comment on lines +13 to 14
import { useDisclosure, useLocalStorage, useWindowEvent } from "@mantine/hooks";
import {
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 8, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Mantine useLocalStorage same tab synchronization multiple components

💡 Result:

Short answer: Mantine's useLocalStorage syncs across browser tabs/windows via the storage event, but it does NOT automatically propagate updates to other hook instances in the same tab. Use one of these patterns to keep multiple components in the same tab in sync:

  • Lift the state into a shared parent (or React context) and have components consume that single source of truth (recommended). [1]
  • Use a small global pub/sub (mitt or an EventTarget) so setValue writes localStorage and emits a same-tab event other hook instances listen to. [3]
  • Replace/use a custom "synced" hook that uses an emitter + storage events to sync both same-tab and cross-tab (examples exist, e.g. useSyncedLocalStorage). [3]

Background / why: Mantine's hook subscribes to the window "storage" event which only fires in other documents (other tabs/windows), not in the same tab where localStorage was changed — so same-tab updates won't trigger other hook instances. [1][2]

Sources:

  • Mantine useLocalStorage docs (browser tabs sync via storage event). [1]
  • Explanation that storage events don't fire in the same tab. [2]
  • Example approach / custom hook that adds same-tab sync via an emitter (useSyncedLocalStorage). [3]

Refine disable flag is not synchronized within the same tab—Refine button likely stays enabled during "Go deeper" response generation

The refine disable mechanism is split across three components using separate useLocalStorage instances:

  • RefineSelection writes true to localStorage via useLocalStorage when starting "Go deeper"
  • ParticipantConversationAudioContent clears it via removeValue() on onError/onFinish
  • ParticipantConversationAudio reads via its own useLocalStorage instance and disables the button via disabled={isStopping || isRefineDisabled}

The problem: Mantine's useLocalStorage only synchronizes state across browser tabs/windows via the storage event. Within the same tab, updating localStorage in one component does not automatically update the state in other components using the same key—each hook instance maintains isolated React state. When RefineSelection calls its setter, ParticipantConversationAudio's isRefineDisabled state does not update in the same tab. Additionally, navigating between nested routes keeps ParticipantConversationAudio mounted, so its initializer only runs once and won't pick up later writes.

Result: The Refine button is probably never actually disabled while a Go deeper response is generating, and may remain disabled longer than intended on cleanup. This defeats ECHO-614.

Recommendation: Replace the cross-component localStorage coordination with a single source of truth owned by the parent component and passed to children:

-const [isRefineDisabled, _setIsRefineDisabled] = useLocalStorage({
-  defaultValue: false,
-  key: `refine_disabled_${conversationId}`,
-});
+const [isRefineDisabled, setIsRefineDisabled] = useState(false);
...
<Outlet
  context={{
    isRecording,
+   isRefineDisabled,
+   setIsRefineDisabled,
  }}
/>

Then have RefineSelection and ParticipantConversationAudioContent call setIsRefineDisabled via useOutletContext() instead of their own useLocalStorage instances. You can optionally mirror to localStorage afterward if persistence across full page reloads is needed.

Applies to lines: 13–14, 50–56, 218–225, 458–474

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In echo/frontend/src/components/participant/ParticipantConversationAudio.tsx
around lines 13–14, 50–56, 218–225 and 458–474 the disable flag is implemented
with multiple useLocalStorage hooks which do not synchronize React state within
the same tab; replace this cross-component localStorage coordination with a
single boolean state (isRefineDisabled) declared in the parent component, pass
that state and its setter down to children via outlet context (useOutletContext)
or props, remove the child components' useLocalStorage usages so RefineSelection
calls setIsRefineDisabled(true) when starting "Go deeper" and
ParticipantConversationAudioContent calls setIsRefineDisabled(false) on
finish/error, and optionally mirror the parent state to localStorage only for
full-page reload persistence.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants