This commit is contained in:
gpt-engineer-app[bot]
2026-01-10 23:30:14 +00:00
parent 8aeff776e1
commit 2cf2dcd7d8
4 changed files with 88 additions and 208 deletions
+57 -24
View File
@@ -9,6 +9,7 @@ import { useAchievements, incrementAiMessageCount } from '@/contexts/Achievement
import { useToast } from '@/hooks/use-toast';
import GlitchText from '@/components/GlitchText';
import MessageContent from '@/components/MessageContent';
import { FullscreenPortal } from '@/components/FullscreenPortal';
import { AI_PROVIDERS, AIProvider, getProvider, CUSTOM_API_STORAGE_KEY } from '@/lib/aiProviders';
import {
DropdownMenu,
@@ -372,16 +373,14 @@ const AIChat = () => {
sendMessage();
}
};
return (
const content = (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className={`flex flex-col ${
isFullscreen
? 'fixed inset-0 z-50 bg-background p-4 md:p-8'
isFullscreen
? 'fixed inset-0 z-50 bg-background p-4 md:p-8'
: 'h-full'
}`}
>
@@ -408,14 +407,31 @@ const AIChat = () => {
<>
<div className="flex items-center gap-2 px-2 py-1 border border-primary/30 rounded text-xs font-pixel">
<span className="text-muted-foreground">Memory:</span>
<span className={`${
(() => {
const totalChars = messages.filter(m => m.role !== 'system').reduce((acc, m) => acc + m.content.length, 0);
const percent = (totalChars / 5000) * 100;
return percent > 80 ? 'text-red-400' : percent > 50 ? 'text-yellow-400' : 'text-green-400';
})()
}`}>
{Math.min(100, Math.round((messages.filter(m => m.role !== 'system').reduce((acc, m) => acc + m.content.length, 0) / 5000) * 100))}%
<span
className={`${
(() => {
const totalChars = messages
.filter(m => m.role !== 'system')
.reduce((acc, m) => acc + m.content.length, 0);
const percent = (totalChars / 5000) * 100;
return percent > 80
? 'text-red-400'
: percent > 50
? 'text-yellow-400'
: 'text-green-400';
})()
}`}
>
{Math.min(
100,
Math.round(
(messages
.filter(m => m.role !== 'system')
.reduce((acc, m) => acc + m.content.length, 0) /
5000) *
100,
),
)}%
</span>
</div>
<Button
@@ -491,7 +507,10 @@ const AIChat = () => {
)}
</div>
<ScrollArea className="flex-1 border border-primary/30 rounded-lg p-4 mb-4 bg-background/50" ref={scrollRef}>
<ScrollArea
className="flex-1 border border-primary/30 rounded-lg p-4 mb-4 bg-background/50"
ref={scrollRef}
>
{messages.length === 0 ? (
<div className="h-full flex items-center justify-center text-muted-foreground">
<div className="text-center">
@@ -502,7 +521,7 @@ const AIChat = () => {
</div>
) : (
<div className="space-y-4">
{messages.map((message, index) => (
{messages.map((message, index) =>
message.role === 'system' ? (
<motion.div
key={message.id}
@@ -521,7 +540,9 @@ const AIChat = () => {
initial={{ opacity: 0, x: message.role === 'user' ? 20 : -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: index * 0.05 }}
className={`flex gap-3 ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}
className={`flex gap-3 ${
message.role === 'user' ? 'justify-end' : 'justify-start'
}`}
>
{message.role === 'assistant' && (
<div className="w-8 h-8 rounded border border-primary/50 flex items-center justify-center bg-primary/10 flex-shrink-0">
@@ -535,9 +556,13 @@ const AIChat = () => {
: 'bg-secondary/50 border border-primary/30'
}`}
>
<MessageContent
content={message.content}
isLoading={isLoading && message.role === 'assistant' && message.content === ''}
<MessageContent
content={message.content}
isLoading={
isLoading &&
message.role === 'assistant' &&
message.content === ''
}
/>
</div>
{message.role === 'user' && (
@@ -546,8 +571,8 @@ const AIChat = () => {
</div>
)}
</motion.div>
)
))}
),
)}
{isLoading && messages[messages.length - 1]?.role === 'user' && (
<motion.div
initial={{ opacity: 0 }}
@@ -602,7 +627,9 @@ const AIChat = () => {
id="endpoint"
placeholder="https://api.example.com/v1/chat/completions"
value={tempCustomConfig.endpoint}
onChange={(e) => setTempCustomConfig(prev => ({ ...prev, endpoint: e.target.value }))}
onChange={(e) =>
setTempCustomConfig(prev => ({ ...prev, endpoint: e.target.value }))
}
className="font-pixel text-sm bg-background/50 border-primary/50"
/>
</div>
@@ -613,7 +640,9 @@ const AIChat = () => {
type="password"
placeholder="sk-..."
value={tempCustomConfig.apiKey}
onChange={(e) => setTempCustomConfig(prev => ({ ...prev, apiKey: e.target.value }))}
onChange={(e) =>
setTempCustomConfig(prev => ({ ...prev, apiKey: e.target.value }))
}
className="font-pixel text-sm bg-background/50 border-primary/50"
/>
</div>
@@ -623,7 +652,9 @@ const AIChat = () => {
id="model"
placeholder="gpt-4, claude-3, etc."
value={tempCustomConfig.model}
onChange={(e) => setTempCustomConfig(prev => ({ ...prev, model: e.target.value }))}
onChange={(e) =>
setTempCustomConfig(prev => ({ ...prev, model: e.target.value }))
}
className="font-pixel text-sm bg-background/50 border-primary/50"
/>
</div>
@@ -658,6 +689,8 @@ const AIChat = () => {
</Dialog>
</motion.div>
);
return isFullscreen ? <FullscreenPortal>{content}</FullscreenPortal> : content;
};
export default AIChat;