Push all design and src app changes
This commit is contained in:
@@ -1,25 +1,32 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
Animated,
|
||||
Easing,
|
||||
View,
|
||||
Text,
|
||||
Image,
|
||||
} from 'react-native';
|
||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { colors } from '../theme/colors';
|
||||
import { colors, spacing, borderRadius, typography, shadows, iconSizes } from '../theme';
|
||||
import { ChatbotModal } from './ChatbotModal';
|
||||
|
||||
const logo = require('../assets/ic_launcher_foreground.png');
|
||||
|
||||
export const FloatingAssistantButton: React.FC = () => {
|
||||
const [scaleValue] = useState(new Animated.Value(1));
|
||||
const [pulseValue] = useState(new Animated.Value(1));
|
||||
const [glowValue] = useState(new Animated.Value(0));
|
||||
const [isChatbotVisible, setIsChatbotVisible] = useState(false);
|
||||
const [showLabel, setShowLabel] = useState(true);
|
||||
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
// Continuous pulse animation
|
||||
Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(pulseValue, {
|
||||
toValue: 1.1,
|
||||
toValue: 1.15,
|
||||
duration: 1500,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
@@ -32,7 +39,32 @@ export const FloatingAssistantButton: React.FC = () => {
|
||||
}),
|
||||
])
|
||||
).start();
|
||||
}, [pulseValue]);
|
||||
|
||||
// Glow animation
|
||||
Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(glowValue, {
|
||||
toValue: 1,
|
||||
duration: 2000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
Animated.timing(glowValue, {
|
||||
toValue: 0,
|
||||
duration: 2000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
])
|
||||
).start();
|
||||
|
||||
// Hide label after 5 seconds
|
||||
const timer = setTimeout(() => {
|
||||
setShowLabel(false);
|
||||
}, 5000);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [pulseValue, glowValue]);
|
||||
|
||||
const handlePressIn = () => {
|
||||
Animated.spring(scaleValue, {
|
||||
@@ -63,12 +95,35 @@ export const FloatingAssistantButton: React.FC = () => {
|
||||
{
|
||||
transform: [{ scale: pulseValue }],
|
||||
opacity: pulseValue.interpolate({
|
||||
inputRange: [1, 1.1],
|
||||
outputRange: [0.3, 0],
|
||||
inputRange: [1, 1.15],
|
||||
outputRange: [0.4, 0],
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* Glow effect */}
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.glowRing,
|
||||
{
|
||||
opacity: glowValue.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [0.2, 0.6],
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* Label */}
|
||||
{showLabel && (
|
||||
<Animated.View style={styles.labelContainer}>
|
||||
<View style={styles.label}>
|
||||
<Text style={styles.labelText}>Ask AI Assistant</Text>
|
||||
<View style={styles.labelArrow} />
|
||||
</View>
|
||||
</Animated.View>
|
||||
)}
|
||||
|
||||
{/* Main button */}
|
||||
<Animated.View
|
||||
@@ -86,11 +141,15 @@ export const FloatingAssistantButton: React.FC = () => {
|
||||
onPressOut={handlePressOut}
|
||||
activeOpacity={0.9}
|
||||
>
|
||||
<MaterialCommunityIcons
|
||||
name="robot-excited"
|
||||
size={32}
|
||||
color={colors.background}
|
||||
/>
|
||||
<Image source={logo} style={styles.buttonLogo} resizeMode="contain" />
|
||||
{/* Microphone indicator */}
|
||||
<View style={styles.micIndicator}>
|
||||
<MaterialCommunityIcons
|
||||
name="microphone"
|
||||
size={12}
|
||||
color={colors.background}
|
||||
/>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</Animated.View>
|
||||
|
||||
@@ -108,32 +167,87 @@ const styles = StyleSheet.create({
|
||||
position: 'absolute',
|
||||
bottom: 90,
|
||||
right: 20,
|
||||
width: 70,
|
||||
height: 70,
|
||||
borderRadius: 35,
|
||||
width: 76,
|
||||
height: 76,
|
||||
borderRadius: 38,
|
||||
backgroundColor: colors.highlight,
|
||||
},
|
||||
glowRing: {
|
||||
position: 'absolute',
|
||||
bottom: 85,
|
||||
right: 15,
|
||||
width: 86,
|
||||
height: 86,
|
||||
borderRadius: 43,
|
||||
backgroundColor: colors.highlight,
|
||||
},
|
||||
labelContainer: {
|
||||
position: 'absolute',
|
||||
bottom: 100,
|
||||
right: 100,
|
||||
},
|
||||
label: {
|
||||
backgroundColor: colors.surfaceAlt,
|
||||
paddingHorizontal: spacing.lg,
|
||||
paddingVertical: spacing.md,
|
||||
borderRadius: borderRadius.lg,
|
||||
borderWidth: 2,
|
||||
borderColor: colors.border,
|
||||
...shadows.md,
|
||||
},
|
||||
labelText: {
|
||||
...typography.caption,
|
||||
fontSize: 13,
|
||||
fontWeight: '700',
|
||||
color: colors.highlightAlt,
|
||||
},
|
||||
labelArrow: {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
right: -6,
|
||||
width: 12,
|
||||
height: 12,
|
||||
marginTop: -6,
|
||||
backgroundColor: colors.surfaceAlt,
|
||||
borderRightWidth: 2,
|
||||
borderBottomWidth: 2,
|
||||
borderColor: colors.border,
|
||||
transform: [{ rotate: '-45deg' }],
|
||||
},
|
||||
buttonContainer: {
|
||||
position: 'absolute',
|
||||
bottom: 90,
|
||||
right: 20,
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
shadowColor: colors.highlight,
|
||||
shadowOffset: { width: 0, height: 8 },
|
||||
shadowOpacity: 0.6,
|
||||
shadowRadius: 16,
|
||||
elevation: 12,
|
||||
width: 72,
|
||||
height: 72,
|
||||
borderRadius: 36,
|
||||
},
|
||||
button: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
width: 72,
|
||||
height: 72,
|
||||
borderRadius: 36,
|
||||
backgroundColor: colors.highlight,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderWidth: 3,
|
||||
borderColor: colors.highlightAlt,
|
||||
...shadows.glowStrong,
|
||||
},
|
||||
buttonLogo: {
|
||||
width: 48,
|
||||
height: 48,
|
||||
},
|
||||
micIndicator: {
|
||||
position: 'absolute',
|
||||
bottom: 4,
|
||||
right: 4,
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: 10,
|
||||
backgroundColor: '#4ADE80',
|
||||
borderWidth: 2,
|
||||
borderColor: colors.background,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user