@contentgrowth/llm-service 0.9.7 → 0.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -209,6 +209,7 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
|
|
|
209
209
|
onResultRef.current = onResult;
|
|
210
210
|
onEndRef.current = onEnd;
|
|
211
211
|
}, [onResult, onEnd]);
|
|
212
|
+
const isStartingRef = (0, import_react2.useRef)(false);
|
|
212
213
|
(0, import_react2.useEffect)(() => {
|
|
213
214
|
if (typeof window !== "undefined") {
|
|
214
215
|
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
@@ -218,10 +219,14 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
|
|
|
218
219
|
recognition.continuous = true;
|
|
219
220
|
recognition.interimResults = true;
|
|
220
221
|
recognition.onstart = () => {
|
|
222
|
+
console.log("[useSpeechRecognition] Native onstart event fired");
|
|
223
|
+
isStartingRef.current = false;
|
|
221
224
|
setIsListening(true);
|
|
222
225
|
setError(null);
|
|
223
226
|
};
|
|
224
227
|
recognition.onend = () => {
|
|
228
|
+
console.log("[useSpeechRecognition] Native onend event fired");
|
|
229
|
+
isStartingRef.current = false;
|
|
225
230
|
if (isSimulatingRef.current) {
|
|
226
231
|
return;
|
|
227
232
|
}
|
|
@@ -245,6 +250,7 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
|
|
|
245
250
|
};
|
|
246
251
|
recognition.onerror = (event) => {
|
|
247
252
|
console.error("[useSpeechRecognition] Native onerror event:", event.error);
|
|
253
|
+
isStartingRef.current = false;
|
|
248
254
|
if (event.error === "not-allowed" && process.env.NODE_ENV === "development") {
|
|
249
255
|
console.warn("Speech recognition blocked. Simulating input for development...");
|
|
250
256
|
isSimulatingRef.current = true;
|
|
@@ -269,6 +275,7 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
|
|
|
269
275
|
}
|
|
270
276
|
}
|
|
271
277
|
return () => {
|
|
278
|
+
console.log("[useSpeechRecognition] Effect cleanup - stopping recognition");
|
|
272
279
|
if (isSimulatingRef.current && simulationTimeoutRef.current) {
|
|
273
280
|
clearTimeout(simulationTimeoutRef.current);
|
|
274
281
|
simulationTimeoutRef.current = null;
|
|
@@ -280,21 +287,40 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
|
|
|
280
287
|
}, []);
|
|
281
288
|
(0, import_react2.useEffect)(() => {
|
|
282
289
|
if (recognitionRef.current) {
|
|
290
|
+
console.log("[useSpeechRecognition] Updating language to:", language);
|
|
283
291
|
recognitionRef.current.lang = language;
|
|
284
292
|
}
|
|
285
293
|
}, [language]);
|
|
286
294
|
const start = (0, import_react2.useCallback)(() => {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
+
console.log("[useSpeechRecognition] start() called");
|
|
296
|
+
if (isSimulatingRef.current) return;
|
|
297
|
+
if (!recognitionRef.current) {
|
|
298
|
+
console.error("[useSpeechRecognition] Recognition instance missing");
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (isStartingRef.current) {
|
|
302
|
+
console.warn("[useSpeechRecognition] Already starting - ignoring duplicate call");
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (recognitionRef.current.isListening) {
|
|
306
|
+
console.warn("[useSpeechRecognition] Already listening - ignoring");
|
|
307
|
+
}
|
|
308
|
+
if (isListening) {
|
|
309
|
+
console.warn("[useSpeechRecognition] App state says already listening - ignoring");
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
setTranscript("");
|
|
314
|
+
isStartingRef.current = true;
|
|
315
|
+
recognitionRef.current.start();
|
|
316
|
+
console.log("[useSpeechRecognition] recognition.start() executed");
|
|
317
|
+
} catch (error2) {
|
|
318
|
+
isStartingRef.current = false;
|
|
319
|
+
console.error("[useSpeechRecognition] Failed to start recognition:", error2);
|
|
295
320
|
}
|
|
296
321
|
}, [isListening]);
|
|
297
322
|
const stop = (0, import_react2.useCallback)(() => {
|
|
323
|
+
console.log("[useSpeechRecognition] stop() called");
|
|
298
324
|
if (isSimulatingRef.current) {
|
|
299
325
|
if (simulationTimeoutRef.current) {
|
|
300
326
|
clearTimeout(simulationTimeoutRef.current);
|
|
@@ -308,11 +334,11 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
|
|
|
308
334
|
if (onEndRef.current) onEndRef.current();
|
|
309
335
|
return;
|
|
310
336
|
}
|
|
311
|
-
if (recognitionRef.current
|
|
337
|
+
if (recognitionRef.current) {
|
|
312
338
|
recognitionRef.current.stop();
|
|
313
|
-
|
|
339
|
+
console.log("[useSpeechRecognition] recognition.stop() executed");
|
|
314
340
|
}
|
|
315
|
-
}, [
|
|
341
|
+
}, []);
|
|
316
342
|
const resetTranscript = (0, import_react2.useCallback)(() => {
|
|
317
343
|
setTranscript("");
|
|
318
344
|
}, []);
|
|
@@ -921,51 +947,70 @@ var TapToTalk = ({
|
|
|
921
947
|
});
|
|
922
948
|
const isListening = !!voiceTrigger || nativeSpeech.isListening || customRecorder.isRecording;
|
|
923
949
|
const isActive = isListening || isTranscribing;
|
|
950
|
+
const processingRef = (0, import_react6.useRef)(false);
|
|
924
951
|
const toggleVoice = async () => {
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
tapCountRef.current.count++;
|
|
928
|
-
} else {
|
|
929
|
-
tapCountRef.current.count = 1;
|
|
930
|
-
}
|
|
931
|
-
tapCountRef.current.lastTap = now;
|
|
932
|
-
if (tapCountRef.current.count >= 5) {
|
|
933
|
-
setShowDebug((prev) => !prev);
|
|
934
|
-
tapCountRef.current.count = 0;
|
|
935
|
-
if (isActive) {
|
|
936
|
-
if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") nativeSpeech.stop();
|
|
937
|
-
else customRecorder.stop();
|
|
938
|
-
setVoiceTrigger(null);
|
|
939
|
-
}
|
|
952
|
+
if (processingRef.current) {
|
|
953
|
+
console.log("[TapToTalk] toggleVoice ignored - processing");
|
|
940
954
|
return;
|
|
941
955
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
956
|
+
processingRef.current = true;
|
|
957
|
+
console.log("[TapToTalk] toggleVoice called. isActive:", isActive);
|
|
958
|
+
try {
|
|
959
|
+
const now = Date.now();
|
|
960
|
+
if (now - tapCountRef.current.lastTap < 500) {
|
|
961
|
+
tapCountRef.current.count++;
|
|
946
962
|
} else {
|
|
947
|
-
|
|
963
|
+
tapCountRef.current.count = 1;
|
|
948
964
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
} catch (e) {
|
|
958
|
-
setErrorMsg("Mic access denied");
|
|
965
|
+
tapCountRef.current.lastTap = now;
|
|
966
|
+
if (tapCountRef.current.count >= 5) {
|
|
967
|
+
setShowDebug((prev) => !prev);
|
|
968
|
+
tapCountRef.current.count = 0;
|
|
969
|
+
if (isActive) {
|
|
970
|
+
console.log("[TapToTalk] Debug trigger force-stop");
|
|
971
|
+
if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") nativeSpeech.stop();
|
|
972
|
+
else customRecorder.stop();
|
|
959
973
|
setVoiceTrigger(null);
|
|
960
974
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
if (isActive) {
|
|
978
|
+
if (isTranscribing && !isListening) {
|
|
979
|
+
console.log("[TapToTalk] Ignoring click during transcription");
|
|
965
980
|
return;
|
|
966
981
|
}
|
|
967
|
-
|
|
982
|
+
console.log("[TapToTalk] Stopping voice...");
|
|
983
|
+
if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") {
|
|
984
|
+
nativeSpeech.stop();
|
|
985
|
+
} else {
|
|
986
|
+
customRecorder.stop();
|
|
987
|
+
}
|
|
988
|
+
setVoiceTrigger(null);
|
|
989
|
+
} else {
|
|
990
|
+
console.log("[TapToTalk] Starting voice...");
|
|
991
|
+
setErrorMsg(null);
|
|
992
|
+
onFocusTarget == null ? void 0 : onFocusTarget();
|
|
993
|
+
setVoiceTrigger("click");
|
|
994
|
+
if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "custom") {
|
|
995
|
+
try {
|
|
996
|
+
await customRecorder.start();
|
|
997
|
+
} catch (e) {
|
|
998
|
+
setErrorMsg("Mic access denied");
|
|
999
|
+
setVoiceTrigger(null);
|
|
1000
|
+
}
|
|
1001
|
+
} else {
|
|
1002
|
+
if (!nativeSpeech.isSupported) {
|
|
1003
|
+
setErrorMsg("Speech not supported");
|
|
1004
|
+
setVoiceTrigger(null);
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
nativeSpeech.start();
|
|
1008
|
+
}
|
|
968
1009
|
}
|
|
1010
|
+
} finally {
|
|
1011
|
+
setTimeout(() => {
|
|
1012
|
+
processingRef.current = false;
|
|
1013
|
+
}, 300);
|
|
969
1014
|
}
|
|
970
1015
|
};
|
|
971
1016
|
let bgColor = accentColor;
|