perf: reduce UI render fanout and scroll jitter
- Cut broad render fanout across the app by replacing shared-store whole-object subscriptions with leaf selectors, memoizing hot chrome boundaries, and isolating disabled global providers from live session/message state. This keeps header controls, composer toolbars, side panels, and other non-hot UI surfaces from repainting on every assistant update or keystroke. - Rework sidebar session ordering so recent, project groups, and worktree groups derive from one ordering source while avoiding streaming-time thrash. The sidebar now uses a stabilized session snapshot, preserves structural identity for unchanged rows, reads live row status/details per session, and applies a one-shot sort bump on idle->busy instead of continuously resorting during activity. - Fix chat/input scroll instability by separating viewport-resize handling from message-growth handling, disabling conflicting native scroll anchoring, and stopping textarea autosize from collapsing on every growth keystroke. This removes the multiline typing jiggle during streaming and reduces unnecessary composer rerenders. - Also gate voice context wiring behind voice-mode enablement and codify the learned render/scroll/order anti-patterns in AGENTS.md so future changes avoid the same classes of regressions.
This commit is contained in:
@@ -24,18 +24,16 @@ export interface UseMessageTTSReturn {
|
||||
export function useMessageTTS(): UseMessageTTSReturn {
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
|
||||
const {
|
||||
voiceProvider,
|
||||
speechRate,
|
||||
speechPitch,
|
||||
speechVolume,
|
||||
sayVoice,
|
||||
browserVoice,
|
||||
openaiVoice,
|
||||
summarizeMessageTTS,
|
||||
summarizeCharacterThreshold,
|
||||
showMessageTTSButtons,
|
||||
} = useConfigStore();
|
||||
const voiceProvider = useConfigStore((state) => state.voiceProvider);
|
||||
const speechRate = useConfigStore((state) => state.speechRate);
|
||||
const speechPitch = useConfigStore((state) => state.speechPitch);
|
||||
const speechVolume = useConfigStore((state) => state.speechVolume);
|
||||
const sayVoice = useConfigStore((state) => state.sayVoice);
|
||||
const browserVoice = useConfigStore((state) => state.browserVoice);
|
||||
const openaiVoice = useConfigStore((state) => state.openaiVoice);
|
||||
const summarizeMessageTTS = useConfigStore((state) => state.summarizeMessageTTS);
|
||||
const summarizeCharacterThreshold = useConfigStore((state) => state.summarizeCharacterThreshold);
|
||||
const showMessageTTSButtons = useConfigStore((state) => state.showMessageTTSButtons);
|
||||
|
||||
const shouldCheckOpenAIAvailability = showMessageTTSButtons && voiceProvider === 'openai';
|
||||
const shouldCheckSayAvailability = showMessageTTSButtons && voiceProvider === 'say';
|
||||
|
||||
Reference in New Issue
Block a user