managarten/chat/apps/mobile/components/MessageItem.tsx
Till-JS c638a7ffee feat(chat): integrate chat project into monorepo with full app structure
- Restructure chat as apps/mobile, apps/web, apps/landing, backend
- Add NestJS backend for secure Azure OpenAI API calls
- Remove exposed API key from mobile app (security fix)
- Add shared chat-types package
- Create SvelteKit web app scaffold
- Create Astro landing page scaffold
- Update pnpm workspace configuration
- Add project-level CLAUDE.md documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 13:48:24 +01:00

97 lines
2.2 KiB
TypeScript

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useTheme } from '@react-navigation/native';
import SkeletonLoader from './SkeletonLoader';
import TypingIndicator from './TypingIndicator';
type MessageProps = {
text: string;
sender: 'user' | 'ai';
timestamp: Date;
isLoading?: boolean;
};
export default function MessageItem({
text,
sender,
timestamp,
isLoading = false
}: MessageProps) {
const { colors } = useTheme();
const isUser = sender === 'user';
return (
<View style={[
styles.container,
isUser ? styles.userContainer : styles.aiContainer,
{ backgroundColor: isUser ? colors.primary : colors.card }
]}>
{isLoading && sender === 'ai' ? (
// Zeige Skeleton oder TypingIndicator wenn geladen wird
<>
<SkeletonLoader
lines={4}
style={styles.skeletonContainer}
/>
<TypingIndicator
dotColor={colors.text + '80'}
style={styles.typingIndicator}
/>
</>
) : (
// Zeige die eigentliche Nachricht
<Text style={[
styles.messageText,
{ color: isUser ? '#fff' : colors.text }
]}>
{text}
</Text>
)}
<Text style={[
styles.timestamp,
{ color: isUser ? 'rgba(255,255,255,0.7)' : colors.text + '80' }
]}>
{timestamp.getHours().toString().padStart(2, '0')}:{timestamp.getMinutes().toString().padStart(2, '0')}
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 12,
borderRadius: 16,
marginVertical: 4,
marginHorizontal: 12,
},
userContainer: {
maxWidth: '80%',
alignSelf: 'flex-start',
borderBottomLeftRadius: 4,
},
aiContainer: {
width: '95%',
alignSelf: 'flex-end',
borderBottomRightRadius: 4,
},
messageText: {
fontSize: 16,
lineHeight: 22,
},
timestamp: {
fontSize: 12,
marginTop: 4,
alignSelf: 'flex-end',
},
skeletonContainer: {
padding: 0,
margin: 0,
opacity: 0.8,
},
typingIndicator: {
marginLeft: -5,
marginTop: 5,
}
});