{"repo": "chicostate/creativeblock", "files": {"creativeblock/components/ChatBubble.tsx": {"9f62fc94bdff7485668b6770bf6b12db3e5644d3": {"t": 1785746575.774451, "n": 7172, "h": "05f3b7b25f4cbde1", "c": "import React, { useEffect, useState } from 'react';\nimport {\n View,\n Text,\n Modal,\n TouchableOpacity,\n StyleSheet,\n TextInput,\n FlatList,\n ActivityIndicator,\n Alert,\n} from 'react-native';\nimport { ThemedView } from './ThemedView';\nimport { ThemedText } from './ThemedText';\n\ntype ChatUser = {\n _id: number;\n name: string;\n avatar?: string;\n};\n\ntype IMessage = {\n _id: number;\n text: string;\n createdAt: Date;\n user: ChatUser;\n};\n\nconst BOT: ChatUser = {\n _id: 0,\n name: 'DeepSeek',\n avatar: 'https://cdn.deepseek.com/platform/favicon.png',\n};\n\nconst YOU: ChatUser = {\n _id: 1,\n name: 'You',\n};\n\nconst DEEPSEEK_API_URL =\n 'https://api.deepseek.com/v1/chat/completions'; // baseURL + route\nconst DEEPSEEK_API_KEY = 'sk-2f8bbae12ec14d6a9f1b442d9427b7ed'; // ← secure in .env for prod\n\nexport default function ChatBubble() {\n const [visible, setVisible] = useState(false);\n const [messages, setMessages] = useState([]);\n const [inputText, setInputText] = useState('');\n const [loading, setLoading] = useState(false);\n\n // initial “welcome” message\n useEffect(() => {\n setMessages([\n {\n _id: Date.now(),\n text: 'Type your question or share what’s on your mind…',\n createdAt: new Date(),\n user: BOT,\n },\n ]);\n }, []);\n\n /* ------------------------------------------------------------------ */\n /* SEND TO DEEPSEEK */\n /* ------------------------------------------------------------------ */\n const sendMessageToDeepSeek = async (userMsg: IMessage) => {\n setLoading(true);\n\n try {\n const res = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${DEEPSEEK_API_KEY}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n model: 'deepseek-chat', // or 'deepseek-reasoner'\n messages: [{ role: 'user', content: userMsg.text }],\n }),\n });\n\n if (!res.ok) {\n const errTxt = await res.text();\n throw new Error(\n `DeepSeek error (${res.status}): ${errTxt.slice(0, 200)}…`,\n );\n }\n\n const data = await res.json();\n const aiText =\n data.choices?.[0]?.message?.content?.trim() ||\n '🤖 (no response from DeepSeek)';\n\n const aiMessage: IMessage = {\n _id: Date.now() + 1,\n text: aiText,\n createdAt: new Date(),\n user: BOT,\n };\n\n setMessages(prev => [aiMessage, ...prev]);\n } catch (err: any) {\n console.error('DeepSeek API Error:', err);\n Alert.alert('DeepSeek Error', err.message);\n } finally {\n setLoading(false);\n }\n };\n\n /* ------------------------------------------------------------------ */\n /* UI LOGIC */\n /* ------------------------------------------------------------------ */\n const handleSend = () => {\n const trimmed = inputText.trim();\n if (!trimmed) return;\n\n const userMessage: IMessage = {\n _id: Date.now(),\n text: trimmed,\n createdAt: new Date(),\n user: YOU,\n };\n\n // add user msg locally\n setMessages(prev => [userMessage, ...prev]);\n setInputText('');\n\n // fire off to deepseek\n sendMessageToDeepSeek(userMessage);\n };\n\n return (\n <>\n {/* floating FAB */}\n setVisible(true)}>\n Chat\n \n\n {/* modal */}\n setVisible(false)}\n >\n \n \n \n DeepSeek Chat\n \n\n {loading && (\n \n )}\n\n item._id.toString()}\n renderItem={({ item }) => {\n const isUser = item.user._id === YOU._id;\n return (\n \n \n {item.text}\n \n \n );\n }}\n style={styles.messagesList}\n />\n\n {/* input */}\n \n \n \n Send\n \n \n\n setVisible(false)}\n style={styles.closeButton}\n >\n Close\n \n \n \n \n \n );\n}\n\n/* ------------------------------ styles ----------------------------- */\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n bottom: 40,\n right: 20,\n backgroundColor: '#4A90E2',\n borderRadius: 30,\n width: 60,\n height: 60,\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 999,\n },\n fabText: { color: '#fff', fontWeight: 'bold' },\n modalContainer: {\n flex: 1,\n backgroundColor: 'rgba(0,0,0,0.4)',\n justifyContent: 'center',\n },\n chatContainer: {\n margin: 20,\n borderRadius: 10,\n padding: 15,\n maxHeight: '80%',\n },\n chatTitle: { textAlign: 'center', marginBottom: 6 },\n messagesList: { flexGrow: 0, maxHeight: 300, marginBottom: 10 },\n messageBubble: { marginVertical: 4, padding: 10, borderRadius: 8 },\n userBubble: { alignSelf: 'flex-end', backgroundColor: '#add8e6' },\n botBubble: { alignSelf: 'flex-start', backgroundColor: '#d3d3d3' },\n messageText: { fontSize: 16 },\n inputRow: { flexDirection: 'row' },\n input: {\n flex: 1,\n borderWidth: 1,\n borderColor: '#888',\n borderRadius: 6,\n paddingHorizontal: 8,\n marginRight: 8,\n },\n sendButton: {\n backgroundColor: '#4A90E2',\n borderRadius: 6,\n paddingHorizontal: 16,\n justifyContent: 'center',\n },\n sendButtonText: { color: '#fff', fontWeight: 'bold' },\n closeButton: {\n marginTop: 10,\n backgroundColor: 'red',\n borderRadius: 6,\n alignItems: 'center',\n paddingVertical: 8,\n },\n closeButtonText: { color: '#fff', fontWeight: 'bold' },\n});\n\n"}, "d2d788efe41831bc4631fccac0e4e68a64b08632": {"t": 1785765894.3495014, "n": 7172, "h": "05f3b7b25f4cbde1", "c": "import React, { useEffect, useState } from 'react';\nimport {\n View,\n Text,\n Modal,\n TouchableOpacity,\n StyleSheet,\n TextInput,\n FlatList,\n ActivityIndicator,\n Alert,\n} from 'react-native';\nimport { ThemedView } from './ThemedView';\nimport { ThemedText } from './ThemedText';\n\ntype ChatUser = {\n _id: number;\n name: string;\n avatar?: string;\n};\n\ntype IMessage = {\n _id: number;\n text: string;\n createdAt: Date;\n user: ChatUser;\n};\n\nconst BOT: ChatUser = {\n _id: 0,\n name: 'DeepSeek',\n avatar: 'https://cdn.deepseek.com/platform/favicon.png',\n};\n\nconst YOU: ChatUser = {\n _id: 1,\n name: 'You',\n};\n\nconst DEEPSEEK_API_URL =\n 'https://api.deepseek.com/v1/chat/completions'; // baseURL + route\nconst DEEPSEEK_API_KEY = 'sk-2f8bbae12ec14d6a9f1b442d9427b7ed'; // ← secure in .env for prod\n\nexport default function ChatBubble() {\n const [visible, setVisible] = useState(false);\n const [messages, setMessages] = useState([]);\n const [inputText, setInputText] = useState('');\n const [loading, setLoading] = useState(false);\n\n // initial “welcome” message\n useEffect(() => {\n setMessages([\n {\n _id: Date.now(),\n text: 'Type your question or share what’s on your mind…',\n createdAt: new Date(),\n user: BOT,\n },\n ]);\n }, []);\n\n /* ------------------------------------------------------------------ */\n /* SEND TO DEEPSEEK */\n /* ------------------------------------------------------------------ */\n const sendMessageToDeepSeek = async (userMsg: IMessage) => {\n setLoading(true);\n\n try {\n const res = await fetch(DEEPSEEK_API_URL, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${DEEPSEEK_API_KEY}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n model: 'deepseek-chat', // or 'deepseek-reasoner'\n messages: [{ role: 'user', content: userMsg.text }],\n }),\n });\n\n if (!res.ok) {\n const errTxt = await res.text();\n throw new Error(\n `DeepSeek error (${res.status}): ${errTxt.slice(0, 200)}…`,\n );\n }\n\n const data = await res.json();\n const aiText =\n data.choices?.[0]?.message?.content?.trim() ||\n '🤖 (no response from DeepSeek)';\n\n const aiMessage: IMessage = {\n _id: Date.now() + 1,\n text: aiText,\n createdAt: new Date(),\n user: BOT,\n };\n\n setMessages(prev => [aiMessage, ...prev]);\n } catch (err: any) {\n console.error('DeepSeek API Error:', err);\n Alert.alert('DeepSeek Error', err.message);\n } finally {\n setLoading(false);\n }\n };\n\n /* ------------------------------------------------------------------ */\n /* UI LOGIC */\n /* ------------------------------------------------------------------ */\n const handleSend = () => {\n const trimmed = inputText.trim();\n if (!trimmed) return;\n\n const userMessage: IMessage = {\n _id: Date.now(),\n text: trimmed,\n createdAt: new Date(),\n user: YOU,\n };\n\n // add user msg locally\n setMessages(prev => [userMessage, ...prev]);\n setInputText('');\n\n // fire off to deepseek\n sendMessageToDeepSeek(userMessage);\n };\n\n return (\n <>\n {/* floating FAB */}\n setVisible(true)}>\n Chat\n \n\n {/* modal */}\n setVisible(false)}\n >\n \n \n \n DeepSeek Chat\n \n\n {loading && (\n \n )}\n\n item._id.toString()}\n renderItem={({ item }) => {\n const isUser = item.user._id === YOU._id;\n return (\n \n \n {item.text}\n \n \n );\n }}\n style={styles.messagesList}\n />\n\n {/* input */}\n \n \n \n Send\n \n \n\n setVisible(false)}\n style={styles.closeButton}\n >\n Close\n \n \n \n \n \n );\n}\n\n/* ------------------------------ styles ----------------------------- */\nconst styles = StyleSheet.create({\n fab: {\n position: 'absolute',\n bottom: 40,\n right: 20,\n backgroundColor: '#4A90E2',\n borderRadius: 30,\n width: 60,\n height: 60,\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 999,\n },\n fabText: { color: '#fff', fontWeight: 'bold' },\n modalContainer: {\n flex: 1,\n backgroundColor: 'rgba(0,0,0,0.4)',\n justifyContent: 'center',\n },\n chatContainer: {\n margin: 20,\n borderRadius: 10,\n padding: 15,\n maxHeight: '80%',\n },\n chatTitle: { textAlign: 'center', marginBottom: 6 },\n messagesList: { flexGrow: 0, maxHeight: 300, marginBottom: 10 },\n messageBubble: { marginVertical: 4, padding: 10, borderRadius: 8 },\n userBubble: { alignSelf: 'flex-end', backgroundColor: '#add8e6' },\n botBubble: { alignSelf: 'flex-start', backgroundColor: '#d3d3d3' },\n messageText: { fontSize: 16 },\n inputRow: { flexDirection: 'row' },\n input: {\n flex: 1,\n borderWidth: 1,\n borderColor: '#888',\n borderRadius: 6,\n paddingHorizontal: 8,\n marginRight: 8,\n },\n sendButton: {\n backgroundColor: '#4A90E2',\n borderRadius: 6,\n paddingHorizontal: 16,\n justifyContent: 'center',\n },\n sendButtonText: { color: '#fff', fontWeight: 'bold' },\n closeButton: {\n marginTop: 10,\n backgroundColor: 'red',\n borderRadius: 6,\n alignItems: 'center',\n paddingVertical: 8,\n },\n closeButtonText: { color: '#fff', fontWeight: 'bold' },\n});\n\n"}}}}