Add toggle listening mode on VoiceFAB tap
- FAB now toggles between idle and listening states - Green background (idle) → Red background (listening) - Icon switches between mic-outline and mic - Connects to VoiceContext for state management 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1c23ca41b8
commit
764c149e2e
@ -1,6 +1,6 @@
|
||||
import { Tabs } from 'expo-router';
|
||||
import React, { useCallback } from 'react';
|
||||
import { Platform, View, Alert } from 'react-native';
|
||||
import { Platform, View } from 'react-native';
|
||||
import { Feather } from '@expo/vector-icons';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
|
||||
@ -9,6 +9,7 @@ import { VoiceFAB } from '@/components/VoiceFAB';
|
||||
import { AppColors } from '@/constants/theme';
|
||||
import { useColorScheme } from '@/hooks/use-color-scheme';
|
||||
import { useVoiceCall } from '@/contexts/VoiceCallContext';
|
||||
import { useVoice } from '@/contexts/VoiceContext';
|
||||
|
||||
export default function TabLayout() {
|
||||
const colorScheme = useColorScheme();
|
||||
@ -17,15 +18,17 @@ export default function TabLayout() {
|
||||
// VoiceFAB uses VoiceCallContext internally to hide when call is active
|
||||
useVoiceCall(); // Ensure context is available
|
||||
|
||||
// Handle voice FAB press - initiate voice call
|
||||
// Voice context for listening mode toggle
|
||||
const { isListening, startSession, stopSession } = useVoice();
|
||||
|
||||
// Handle voice FAB press - toggle listening mode
|
||||
const handleVoiceFABPress = useCallback(() => {
|
||||
// TODO: Integrate with voice call service when ready
|
||||
Alert.alert(
|
||||
'Voice Call',
|
||||
'Voice call with Julia AI will be available soon.',
|
||||
[{ text: 'OK' }]
|
||||
);
|
||||
}, []);
|
||||
if (isListening) {
|
||||
stopSession();
|
||||
} else {
|
||||
startSession();
|
||||
}
|
||||
}, [isListening, startSession, stopSession]);
|
||||
|
||||
// Calculate tab bar height based on safe area
|
||||
// On iOS with home indicator, insets.bottom is ~34px
|
||||
@ -116,8 +119,8 @@ export default function TabLayout() {
|
||||
/>
|
||||
</Tabs>
|
||||
|
||||
{/* Voice FAB - shown when no call is active */}
|
||||
<VoiceFAB onPress={handleVoiceFABPress} />
|
||||
{/* Voice FAB - toggle listening mode */}
|
||||
<VoiceFAB onPress={handleVoiceFABPress} isListening={isListening} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* Voice Floating Action Button Component
|
||||
*
|
||||
* A floating action button for initiating voice calls with Julia AI.
|
||||
* Shows on screens where voice chat is available.
|
||||
* A floating action button for toggling voice listening mode.
|
||||
* Tap to start/stop listening.
|
||||
* Hidden when a call is already active.
|
||||
*/
|
||||
|
||||
@ -23,11 +23,12 @@ interface VoiceFABProps {
|
||||
onPress: () => void;
|
||||
style?: ViewStyle;
|
||||
disabled?: boolean;
|
||||
isListening?: boolean;
|
||||
}
|
||||
|
||||
const FAB_SIZE = 56;
|
||||
|
||||
export function VoiceFAB({ onPress, style, disabled = false }: VoiceFABProps) {
|
||||
export function VoiceFAB({ onPress, style, disabled = false, isListening = false }: VoiceFABProps) {
|
||||
const { isCallActive } = useVoiceCall();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
@ -103,7 +104,11 @@ export function VoiceFAB({ onPress, style, disabled = false }: VoiceFABProps) {
|
||||
]}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={[styles.fab, disabled && styles.fabDisabled]}
|
||||
style={[
|
||||
styles.fab,
|
||||
isListening && styles.fabListening,
|
||||
disabled && styles.fabDisabled,
|
||||
]}
|
||||
onPress={onPress}
|
||||
onPressIn={handlePressIn}
|
||||
onPressOut={handlePressOut}
|
||||
@ -111,7 +116,7 @@ export function VoiceFAB({ onPress, style, disabled = false }: VoiceFABProps) {
|
||||
activeOpacity={0.9}
|
||||
>
|
||||
<Ionicons
|
||||
name="mic"
|
||||
name={isListening ? 'mic' : 'mic-outline'}
|
||||
size={28}
|
||||
color={disabled ? AppColors.textMuted : AppColors.white}
|
||||
/>
|
||||
@ -141,6 +146,9 @@ const styles = StyleSheet.create({
|
||||
shadowRadius: 8,
|
||||
elevation: 8,
|
||||
},
|
||||
fabListening: {
|
||||
backgroundColor: AppColors.error,
|
||||
},
|
||||
fabDisabled: {
|
||||
backgroundColor: AppColors.surface,
|
||||
shadowOpacity: 0.1,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user