refactor(voice): Push-to-Talk-Pfad raus, nur Tap-to-Talk
handlePressIn/Out + onResponderGrant/Release/Terminate weg. Push-to- Talk lief parallel zu Tap-to-Talk und triggerte je nach Touch-Timing unkontrollierbar. Stefan kennt das Verhalten ohnehin nicht (sagt "druecken startet, druecken stoppt") — Push-to-Talk macht UX nur unklarer ohne Mehrwert. isLongPress-Ref entfernt (war nur fuer Push-to-Talk-Discrimination). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,7 +44,6 @@ const VoiceButton: React.FC<VoiceButtonProps> = ({
|
|||||||
const [meterDb, setMeterDb] = useState(-160);
|
const [meterDb, setMeterDb] = useState(-160);
|
||||||
const pulseAnim = useRef(new Animated.Value(1)).current;
|
const pulseAnim = useRef(new Animated.Value(1)).current;
|
||||||
const durationTimer = useRef<ReturnType<typeof setInterval> | null>(null);
|
const durationTimer = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||||
const isLongPress = useRef(false);
|
|
||||||
|
|
||||||
// Puls-Animation starten/stoppen
|
// Puls-Animation starten/stoppen
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -117,31 +116,10 @@ const VoiceButton: React.FC<VoiceButtonProps> = ({
|
|||||||
if (disabled || isRecording) return;
|
if (disabled || isRecording) return;
|
||||||
const started = await audioService.startRecording(true); // autoStop = true
|
const started = await audioService.startRecording(true); // autoStop = true
|
||||||
if (started) {
|
if (started) {
|
||||||
isLongPress.current = false;
|
|
||||||
setIsRecording(true);
|
setIsRecording(true);
|
||||||
}
|
}
|
||||||
}, [disabled, isRecording]);
|
}, [disabled, isRecording]);
|
||||||
|
|
||||||
// Push-to-Talk: Lang druecken
|
|
||||||
const handlePressIn = async () => {
|
|
||||||
if (disabled || isRecording) return;
|
|
||||||
isLongPress.current = true;
|
|
||||||
const started = await audioService.startRecording(false); // kein autoStop
|
|
||||||
if (started) {
|
|
||||||
setIsRecording(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePressOut = async () => {
|
|
||||||
if (!isRecording || !isLongPress.current) return;
|
|
||||||
isLongPress.current = false;
|
|
||||||
setIsRecording(false);
|
|
||||||
const result = await audioService.stopRecording();
|
|
||||||
if (result && result.durationMs > 300) {
|
|
||||||
onRecordingComplete(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Tap-to-Talk: Einmal tippen startet mit Auto-Stop.
|
// Tap-to-Talk: Einmal tippen startet mit Auto-Stop.
|
||||||
// Guard gegen Doppel-Tap während asyncer Start/Stop.
|
// Guard gegen Doppel-Tap während asyncer Start/Stop.
|
||||||
const tapBusy = useRef(false);
|
const tapBusy = useRef(false);
|
||||||
@@ -162,7 +140,6 @@ const VoiceButton: React.FC<VoiceButtonProps> = ({
|
|||||||
// Aufnahme mit Auto-Stop starten
|
// Aufnahme mit Auto-Stop starten
|
||||||
const started = await audioService.startRecording(true);
|
const started = await audioService.startRecording(true);
|
||||||
if (started) {
|
if (started) {
|
||||||
isLongPress.current = false;
|
|
||||||
setIsRecording(true);
|
setIsRecording(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,10 +178,6 @@ const VoiceButton: React.FC<VoiceButtonProps> = ({
|
|||||||
isRecording && styles.buttonOuterRecording,
|
isRecording && styles.buttonOuterRecording,
|
||||||
{ transform: [{ scale: pulseAnim }] },
|
{ transform: [{ scale: pulseAnim }] },
|
||||||
]}
|
]}
|
||||||
onStartShouldSetResponder={() => true}
|
|
||||||
onResponderGrant={handlePressIn}
|
|
||||||
onResponderRelease={handlePressOut}
|
|
||||||
onResponderTerminate={handlePressOut}
|
|
||||||
>
|
>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
activeOpacity={0.8}
|
activeOpacity={0.8}
|
||||||
|
|||||||
Reference in New Issue
Block a user