feat: improve VS Code dev flow and stabilize sidebar/chat behavior (#754)
* fix: improve session sidebar tooltip and truncation behavior - Keep new-draft tooltip anchored to its trigger button - Fix minimal-mode worktree/group header text truncation - Tune minimal-mode right padding to reduce early label clipping * fix: render reasoning through markdown pipeline - Use Streamdown rendering for reasoning in live chat mode - Remove italic styling from reasoning text - Render expanded reasoning content with MarkdownRenderer * chore: remove legacy electron dependencies - Removed unused Electron packages from root and UI manifests - Deleted obsolete Electron context menu type declaration - Regenerated lockfile after dependency cleanup * fix: handle non-repository folders in git status API - Prevent 500 errors when status is requested outside a valid Git repo - Improve repository detection using `git rev-parse --git-dir` - Reduce noisy server logs for expected non-repo status checks * fix unloaded session chat layout flicker * fix: reduce noisy TTS status polling Cache and dedupe TTS status requests, and only check provider availability when the related voice features are enabled so disabled voice setups stay quiet. * perf: throttle background PR git status refreshes * fix: improve VS Code Explorer file drop mentions in chat - Add Explorer context action to insert selected files as @mentions. - Handle Explorer drag-and-drop to prefill @file mentions instead of attachments. - Prevent duplicate plain-path text when dropping multiple files. * fix: deduplicate recent sessions in VS Code sidebar - Hide sessions from main list when already shown in recent - Apply dedup only in VS Code runtime - Keep session search behavior unchanged * feat: add true HMR dev flow for VS Code extension - Load VS Code webview from Vite dev server with React refresh preamble - Add `vscode:dev` runner that starts watchers and opens Extension Development Host - Update VS Code dev docs and scripts to use the new HMR startup flow * feat: polish VS Code session sidebar and attachment UX - Add resizable sessions sidebar in VS Code layout - Tighten session list spacing and hover behavior in VS Code - Remove bulk file/image attach success toasts while keeping error toasts
This commit is contained in:
committed by
GitHub
parent
ea6d4c4d43
commit
1231fd773e
@@ -19,6 +19,67 @@
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
interface SayTTSStatusCache {
|
||||
available: boolean;
|
||||
voices: Array<{ name: string; locale: string }>;
|
||||
checkedAt: number;
|
||||
}
|
||||
|
||||
interface UseSayTTSOptions {
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
const SAY_TTS_STATUS_TTL_MS = 30000;
|
||||
let sayTTSStatusCache: SayTTSStatusCache | null = null;
|
||||
let sayTTSStatusRequest: Promise<SayTTSStatusCache> | null = null;
|
||||
|
||||
async function getSayTTSStatus(): Promise<SayTTSStatusCache> {
|
||||
const now = Date.now();
|
||||
if (sayTTSStatusCache && now - sayTTSStatusCache.checkedAt < SAY_TTS_STATUS_TTL_MS) {
|
||||
return sayTTSStatusCache;
|
||||
}
|
||||
|
||||
if (sayTTSStatusRequest) {
|
||||
return sayTTSStatusRequest;
|
||||
}
|
||||
|
||||
sayTTSStatusRequest = (async () => {
|
||||
try {
|
||||
const response = await fetch('/api/tts/say/status');
|
||||
if (!response.ok) {
|
||||
const unavailableStatus: SayTTSStatusCache = {
|
||||
available: false,
|
||||
voices: [],
|
||||
checkedAt: Date.now(),
|
||||
};
|
||||
sayTTSStatusCache = unavailableStatus;
|
||||
return unavailableStatus;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const nextStatus: SayTTSStatusCache = {
|
||||
available: Boolean(data.available),
|
||||
voices: Array.isArray(data.voices) ? data.voices : [],
|
||||
checkedAt: Date.now(),
|
||||
};
|
||||
sayTTSStatusCache = nextStatus;
|
||||
return nextStatus;
|
||||
} catch {
|
||||
const unavailableStatus: SayTTSStatusCache = {
|
||||
available: false,
|
||||
voices: [],
|
||||
checkedAt: Date.now(),
|
||||
};
|
||||
sayTTSStatusCache = unavailableStatus;
|
||||
return unavailableStatus;
|
||||
} finally {
|
||||
sayTTSStatusRequest = null;
|
||||
}
|
||||
})();
|
||||
|
||||
return sayTTSStatusRequest;
|
||||
}
|
||||
|
||||
export interface UseSayTTSReturn {
|
||||
/** Whether TTS is currently playing */
|
||||
isPlaying: boolean;
|
||||
@@ -61,7 +122,8 @@ function getAudioContext(): AudioContext {
|
||||
return sharedAudioContext;
|
||||
}
|
||||
|
||||
export function useSayTTS(): UseSayTTSReturn {
|
||||
export function useSayTTS(options: UseSayTTSOptions = {}): UseSayTTSReturn {
|
||||
const enabled = options.enabled ?? true;
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [isAvailable, setIsAvailable] = useState(false);
|
||||
const [voices, setVoices] = useState<Array<{ name: string; locale: string }>>([]);
|
||||
@@ -97,28 +159,27 @@ export function useSayTTS(): UseSayTTSReturn {
|
||||
|
||||
// Check if macOS say is available
|
||||
const checkAvailability = useCallback(async (): Promise<boolean> => {
|
||||
try {
|
||||
const response = await fetch('/api/tts/say/status');
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setIsAvailable(data.available);
|
||||
if (data.voices) {
|
||||
setVoices(data.voices);
|
||||
}
|
||||
return data.available;
|
||||
}
|
||||
setIsAvailable(false);
|
||||
return false;
|
||||
} catch (err) {
|
||||
console.error('[useSayTTS] Failed to check availability:', err);
|
||||
if (!enabled) {
|
||||
setIsAvailable(false);
|
||||
setVoices([]);
|
||||
return false;
|
||||
}
|
||||
}, []);
|
||||
|
||||
try {
|
||||
const status = await getSayTTSStatus();
|
||||
setIsAvailable(status.available);
|
||||
setVoices(status.voices);
|
||||
return status.available;
|
||||
} catch {
|
||||
setIsAvailable(false);
|
||||
setVoices([]);
|
||||
return false;
|
||||
}
|
||||
}, [enabled]);
|
||||
|
||||
// Check availability on mount
|
||||
useEffect(() => {
|
||||
checkAvailability();
|
||||
void checkAvailability();
|
||||
}, [checkAvailability]);
|
||||
|
||||
// Stop current playback
|
||||
|
||||
Reference in New Issue
Block a user