-
-
Búsqueda web
-
Busca información en Google mediante Serper.
+
);
}
diff --git a/vocero-frontend/src/components/VoiceStage.tsx b/vocero-frontend/src/components/VoiceStage.tsx
index 098e764..65c9383 100644
--- a/vocero-frontend/src/components/VoiceStage.tsx
+++ b/vocero-frontend/src/components/VoiceStage.tsx
@@ -1,5 +1,5 @@
import { CircleAlert, Mic, MicOff, Square, Volume2 } from "lucide-react";
-import { useEffect, useState, type CSSProperties, type PointerEvent } from "react";
+import { useEffect, useState, useSyncExternalStore, type CSSProperties, type PointerEvent } from "react";
import type { ConnectionStatus } from "../lib/contracts";
import { GATE_MAX, GATE_OFF } from "../lib/settings";
@@ -98,6 +98,45 @@ function Waveform({ side }: { side: "left" | "right" }) {
);
}
+function MicrophoneGate({
+ controller,
+ threshold,
+ muted,
+ live,
+}: {
+ controller: VoiceController;
+ threshold: number;
+ muted: boolean;
+ live: boolean;
+}) {
+ const level = useSyncExternalStore(controller.subscribeLevel, controller.getLevel);
+ return (
+
= threshold ? "gate-open" : ""}`}>
+ {live && (
+ {
+ controller.changeSettings({ noiseGate });
+ }}
+ />
+ )}
+
+
+ );
+}
function JoinCountdown({ deadline }: { deadline: number }) {
const [now, setNow] = useState(Date.now);
useEffect(() => {
@@ -195,32 +234,12 @@ export function VoiceStage({ state, controller }: { state: AppState; controller:
) : (
<>
-
= state.settings.noiseGate ? "gate-open" : ""}`}
- >
- {live && (
- {
- controller.changeSettings({ noiseGate });
- }}
- />
- )}
-
-
+