feat: Implement core chat functionality with LM Studio integration and theme management.

This commit is contained in:
Evandro Fonseca Junior committed 2026-03-04 16:56:45 -03:00
1 parent 93df87d7e9
commit 0297db110a
13 files changed
+670 -451

No files matched your search

+20 -27
View File
@@ -1,3 +1,4 @@
import { useThemeColor } from '@/hooks/useThemeColor';
import * as Haptics from 'expo-haptics';
import { Send, Square, X } from 'lucide-react-native';
import React, { useEffect, useState } from 'react';
@@ -20,6 +21,7 @@ interface ChatInputProps {
export function ChatInput({ onSend, onStop, isLoading, editingText, onCancelEdit }: ChatInputProps) {
const [text, setText] = useState('');
const colors = useThemeColor();
// When editingText changes, fill the input
useEffect(() => {
@@ -58,23 +60,27 @@ export function ChatInput({ onSend, onStop, isLoading, editingText, onCancelEdit
const isEditing = editingText !== null && editingText !== undefined;
return (
<View style={styles.outerContainer}>
<View style={[styles.outerContainer, { backgroundColor: colors.backgroundColor, borderTopColor: colors.border }]}>
{/* Edit mode banner */}
{isEditing && (
<View style={styles.editBanner}>
<Text style={styles.editBannerText}>Editing message</Text>
<View style={[styles.editBanner, { backgroundColor: colors.bannerBg, borderBottomColor: colors.border }]}>
<Text style={[styles.editBannerText, { color: colors.bannerText }]}>Editing message</Text>
<TouchableOpacity onPress={handleCancelEdit} style={styles.editCancelBtn}>
<X size={16} color="#6B7280" />
<X size={16} color={colors.textMuted} />
</TouchableOpacity>
</View>
)}
<View style={styles.container}>
<View style={[styles.inputWrapper, isEditing && styles.inputWrapperEditing]}>
<View style={[
styles.inputWrapper,
{ backgroundColor: colors.inputBg, borderColor: colors.border, borderWidth: 1 },
isEditing && { borderColor: colors.tint, borderWidth: 1.5 }
]}>
<TextInput
style={styles.input}
style={[styles.input, { color: colors.text }]}
placeholder="Send a message..."
placeholderTextColor="#9CA3AF"
placeholderTextColor={colors.textMuted}
value={text}
onChangeText={setText}
multiline
@@ -85,20 +91,23 @@ export function ChatInput({ onSend, onStop, isLoading, editingText, onCancelEdit
{/* Send or Stop button */}
{isLoading ? (
<TouchableOpacity
style={styles.stopButton}
style={[styles.stopButton, { backgroundColor: colors.errorText }]}
onPress={handleStop}
activeOpacity={0.7}
>
<Square size={16} color="#FFFFFF" />
<Square size={16} color={colors.backgroundColor} />
</TouchableOpacity>
) : (
<TouchableOpacity
style={[styles.sendButton, !text.trim() && styles.sendButtonDisabled]}
style={[
styles.sendButton,
{ backgroundColor: text.trim() ? colors.tint : colors.border }
]}
onPress={handleSend}
disabled={!text.trim()}
activeOpacity={0.7}
>
<Send size={18} color={text.trim() ? '#FFFFFF' : '#9CA3AF'} />
<Send size={18} color={text.trim() ? colors.backgroundColor : colors.textMuted} />
</TouchableOpacity>
)}
</View>
@@ -109,9 +118,7 @@ export function ChatInput({ onSend, onStop, isLoading, editingText, onCancelEdit
const styles = StyleSheet.create({
outerContainer: {
backgroundColor: '#FFFFFF',
borderTopWidth: 1,
borderTopColor: '#E5E7EB',
},
editBanner: {
flexDirection: 'row',
@@ -119,13 +126,10 @@ const styles = StyleSheet.create({
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingVertical: 8,
backgroundColor: '#EFF6FF',
borderBottomWidth: 1,
borderBottomColor: '#DBEAFE',
},
editBannerText: {
fontSize: 13,
color: '#2563EB',
fontWeight: '500',
},
editCancelBtn: {
@@ -138,43 +142,32 @@ const styles = StyleSheet.create({
inputWrapper: {
flexDirection: 'row',
alignItems: 'flex-end',
backgroundColor: '#F3F4F6',
borderRadius: 24,
paddingHorizontal: 16,
paddingVertical: 6,
minHeight: 44,
maxHeight: 120,
},
inputWrapperEditing: {
borderWidth: 1.5,
borderColor: '#2563EB',
},
input: {
flex: 1,
fontSize: 15,
lineHeight: 22,
paddingTop: 8,
paddingBottom: 8,
color: '#111827',
},
sendButton: {
width: 34,
height: 34,
borderRadius: 17,
backgroundColor: '#111827',
alignItems: 'center',
justifyContent: 'center',
marginLeft: 8,
marginBottom: 2,
},
sendButtonDisabled: {
backgroundColor: '#E5E7EB',
},
stopButton: {
width: 34,
height: 34,
borderRadius: 17,
backgroundColor: '#EF4444',
alignItems: 'center',
justifyContent: 'center',
marginLeft: 8,