Skip to content

fix(ui): restore provider wave indicator tones#9

Merged
astyfx merged 2 commits intomainfrom
fix/provider-wave-indicator-tones
Mar 25, 2026
Merged

fix(ui): restore provider wave indicator tones#9
astyfx merged 2 commits intomainfrom
fix/provider-wave-indicator-tones

Conversation

@astyfx
Copy link
Copy Markdown
Member

@astyfx astyfx commented Mar 25, 2026

Summary

  • restore provider-specific wave indicator tones through a shared helper
  • apply the provider tone directly to task tab, task list, message bubble, and workspace responding waves
  • keep mixed or Stave workspace activity on the neutral primary tone and cover the helper with a model-catalog test

Verification

  • bun test tests/model-catalog.test.ts
  • bun run typecheck

Copilot AI review requested due to automatic review settings March 25, 2026 02:47
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Restores provider-specific wave indicator tones across the UI by introducing a shared helper in the provider model catalog and applying it consistently to wave indicators in chat, task tabs/list, and workspace sidebar.

Changes:

  • Add getProviderWaveToneClass to the provider model catalog and cover it with a unit test.
  • Update ChatPanel, task tabs, and task list items to apply the provider tone directly on WaveIndicator.
  • Update workspace sidebar responding-wave rendering to use provider tone when a workspace has a single responding provider, otherwise fall back to neutral.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/model-catalog.test.ts Adds coverage for the new provider wave tone helper.
src/lib/providers/model-catalog.ts Introduces getProviderWaveToneClass to centralize tone mapping.
src/components/session/ChatPanel.tsx Uses shared helper for responding wave indicator tone (including neutral for user/stave).
src/components/layout/WorkspaceTaskTabs.tsx Applies provider tone directly to WaveIndicator in task tabs.
src/components/layout/TaskItem.tsx Applies provider tone directly to WaveIndicator in task list items.
src/components/layout/ProjectWorkspaceSidebar.tsx Computes workspace-level responding tone (single-provider vs mixed/neutral) and applies it to waves.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +253 to +257
return getWorkspaceRespondingTasks(workspaceId).length;
}

function getWorkspaceRespondingToneClass(workspaceId: string) {
const providers = Array.from(new Set(getWorkspaceRespondingTasks(workspaceId).map((task) => task.provider)));
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

getWorkspaceRespondingTaskCount and getWorkspaceRespondingToneClass both call getWorkspaceRespondingTasks(workspaceId), which filters the workspace task list each time. Consider computing the responding tasks once (e.g., return { respondingTasks, count, toneClass } from a single helper or pass the filtered list into both calculations) to avoid duplicate O(n) scans on every render.

Copilot uses AI. Check for mistakes.
const workspaceBusy = busyWorkspaceKey === `${entry.projectPath}:${entry.workspaceId}`;
const respondingTaskCount = getWorkspaceRespondingTaskCount(entry.workspaceId);
const isResponding = respondingTaskCount > 0;
const respondingToneClass = getWorkspaceRespondingToneClass(entry.workspaceId);
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

respondingToneClass is computed unconditionally for each collapsed workspace entry, even when isResponding is false. Since getWorkspaceRespondingToneClass scans tasks (filter/map/Set), consider only computing it inside the isResponding branch (or defaulting to "text-primary" when not responding) to avoid unnecessary work during sidebar renders.

Suggested change
const respondingToneClass = getWorkspaceRespondingToneClass(entry.workspaceId);
const respondingToneClass = isResponding
? getWorkspaceRespondingToneClass(entry.workspaceId)
: "text-primary";

Copilot uses AI. Check for mistakes.
const workspaceBusy = busyWorkspaceKey === `${project.projectPath}:${workspace.id}`;
const respondingTaskCount = getWorkspaceRespondingTaskCount(workspace.id);
const isResponding = respondingTaskCount > 0;
const respondingToneClass = getWorkspaceRespondingToneClass(workspace.id);
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

respondingToneClass is computed for every workspace row even when isResponding is false. Since getWorkspaceRespondingToneClass performs a task scan, consider computing it only when needed (e.g., when respondingTaskCount > 0) to reduce repeated work during renders.

Suggested change
const respondingToneClass = getWorkspaceRespondingToneClass(workspace.id);
const respondingToneClass = isResponding ? getWorkspaceRespondingToneClass(workspace.id) : "";

Copilot uses AI. Check for mistakes.
@astyfx astyfx merged commit ab4cb5b into main Mar 25, 2026
3 checks passed
@astyfx astyfx deleted the fix/provider-wave-indicator-tones branch March 25, 2026 06:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants