Files
life-echo/app-ios/components/chat/ChatBubble.tsx

163 lines
3.6 KiB
TypeScript
Raw Normal View History

2026-01-31 21:20:50 +01:00
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { AppColors } from '@/constants/theme';
import { Message } from '@/data/mockData';
interface ChatBubbleProps {
message: Message;
}
export function ChatBubble({ message }: ChatBubbleProps) {
const isAI = message.senderType === 'ai';
return (
<View style={[styles.container, isAI ? styles.aiContainer : styles.userContainer]}>
{/* Avatar */}
<View style={[styles.avatar, isAI ? styles.aiAvatar : styles.userAvatar]}>
<Text style={styles.avatarEmoji}>{isAI ? '📖' : '👤'}</Text>
</View>
{/* Bubble */}
<View style={[styles.bubble, isAI ? styles.aiBubble : styles.userBubble]}>
<Text style={[styles.text, isAI ? styles.aiText : styles.userText]}>
{message.content}
</Text>
</View>
</View>
);
}
// Typing indicator component
export function TypingIndicator() {
return (
<View style={[styles.container, styles.aiContainer]}>
<View style={[styles.avatar, styles.aiAvatar]}>
<Text style={styles.avatarEmoji}>📖</Text>
</View>
<View style={[styles.bubble, styles.aiBubble]}>
<View style={styles.typingDots}>
<View style={[styles.dot, styles.dot1]} />
<View style={[styles.dot, styles.dot2]} />
<View style={[styles.dot, styles.dot3]} />
</View>
</View>
</View>
);
}
// Time separator component
export function TimeSeparator({ time }: { time: string }) {
return (
<View style={styles.timeContainer}>
<View style={styles.timeBadge}>
<Text style={styles.timeText}>{time}</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
marginBottom: 16,
paddingHorizontal: 14,
},
aiContainer: {
flexDirection: 'row',
},
userContainer: {
flexDirection: 'row-reverse',
},
avatar: {
width: 40,
height: 40,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
},
aiAvatar: {
backgroundColor: AppColors.lavender,
marginRight: 10,
},
userAvatar: {
backgroundColor: AppColors.blushPink,
marginLeft: 10,
},
avatarEmoji: {
fontSize: 18,
},
bubble: {
maxWidth: '70%',
paddingVertical: 12,
paddingHorizontal: 16,
borderRadius: 18,
},
aiBubble: {
backgroundColor: AppColors.white,
borderTopLeftRadius: 4,
shadowColor: AppColors.deepPurple,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.06,
shadowRadius: 8,
elevation: 2,
},
userBubble: {
backgroundColor: AppColors.mediumPurple,
borderTopRightRadius: 4,
shadowColor: AppColors.mediumPurple,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 3,
},
text: {
fontSize: 15,
lineHeight: 22,
},
aiText: {
color: AppColors.deepPurple,
},
userText: {
color: AppColors.white,
},
// Typing indicator styles
typingDots: {
flexDirection: 'row',
alignItems: 'center',
height: 20,
paddingHorizontal: 4,
},
dot: {
width: 8,
height: 8,
borderRadius: 4,
backgroundColor: AppColors.slatePurple,
marginHorizontal: 2,
opacity: 0.5,
},
dot1: {
opacity: 1,
},
dot2: {
opacity: 0.7,
},
dot3: {
opacity: 0.4,
},
// Time separator styles
timeContainer: {
alignItems: 'center',
marginVertical: 16,
},
timeBadge: {
paddingVertical: 4,
paddingHorizontal: 12,
backgroundColor: 'rgba(140, 142, 163, 0.1)',
borderRadius: 12,
},
timeText: {
fontSize: 12,
color: AppColors.slatePurple,
},
});