fix: centered input + default stream
This commit is contained in:
@@ -39,7 +39,7 @@ export default function ChatUI({
|
|||||||
stop: [''],
|
stop: [''],
|
||||||
repeatPenalty: 1.1,
|
repeatPenalty: 1.1,
|
||||||
seed: 0,
|
seed: 0,
|
||||||
stream: false,
|
stream: true,
|
||||||
keepAlive: '5m',
|
keepAlive: '5m',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -108,7 +108,8 @@ export default function ChatUI({
|
|||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
let message = 'Request failed';
|
let message = 'Request failed';
|
||||||
if (res.status === 500) message = 'Server error (likely model too large or OOM)';
|
if (res.status === 500)
|
||||||
|
message = 'Server error (likely model too large or OOM)';
|
||||||
else if (res.status === 401) message = 'Unauthorized';
|
else if (res.status === 401) message = 'Unauthorized';
|
||||||
else message = data?.message ?? data?.error ?? message;
|
else message = data?.message ?? data?.error ?? message;
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
@@ -179,13 +180,31 @@ export default function ChatUI({
|
|||||||
/>
|
/>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* Messages */}
|
{/* Messages + centered input when empty */}
|
||||||
<main className="flex-1 overflow-y-auto flex flex-col p-6">
|
<main className="flex-1 overflow-y-auto flex flex-col p-6">
|
||||||
|
{messages.length === 0 ? (
|
||||||
|
/* ── Empty state: input centered within the chat column only ── */
|
||||||
|
<div className="flex-1 flex flex-col items-center justify-center">
|
||||||
|
<p className="text-primary text-sm mb-3 opacity-60">
|
||||||
|
Start a conversation…
|
||||||
|
</p>
|
||||||
|
<input
|
||||||
|
value={input}
|
||||||
|
onChange={(e) => setInput(e.target.value)}
|
||||||
|
onKeyDown={(e) =>
|
||||||
|
e.key === 'Enter' && !loading && sendMessage()
|
||||||
|
}
|
||||||
|
disabled={loading}
|
||||||
|
className="w-full max-w-2xl p-3 rounded-xl bg-black/20 border border-muted outline-none disabled:opacity-50"
|
||||||
|
placeholder="Message..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
/* ── Active chat: messages list ── */
|
||||||
<div className="w-full max-w-2xl mx-auto space-y-3">
|
<div className="w-full max-w-2xl mx-auto space-y-3">
|
||||||
{messages.map((msg, i) => (
|
{messages.map((msg, i) => (
|
||||||
<div key={i} className="text-sm">
|
<div key={i} className="text-sm">
|
||||||
<b>{msg.role === 'user' ? 'You' : 'AI'}:</b> {msg.content}
|
<b>{msg.role === 'user' ? 'You' : 'AI'}:</b> {msg.content}
|
||||||
{/* Blinking cursor shown on the last message while streaming */}
|
|
||||||
{loading &&
|
{loading &&
|
||||||
settings.stream &&
|
settings.stream &&
|
||||||
i === messages.length - 1 &&
|
i === messages.length - 1 &&
|
||||||
@@ -198,35 +217,22 @@ export default function ChatUI({
|
|||||||
<div className="text-xs text-muted">Thinking...</div>
|
<div className="text-xs text-muted">Thinking...</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{/* Input — floats center when empty, slides to bottom on first message */}
|
{/* Input bar — only shown once conversation has started */}
|
||||||
<div
|
{messages.length > 0 && (
|
||||||
className={`
|
<div className="p-4">
|
||||||
transition-all duration-500 ease-in-out
|
|
||||||
${
|
|
||||||
messages.length === 0
|
|
||||||
? 'absolute inset-0 flex items-center justify-center pointer-events-none'
|
|
||||||
: 'p-4'
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
<div className="w-full max-w-2xl mx-auto pointer-events-auto transition-all duration-500 ease-in-out">
|
|
||||||
{messages.length === 0 && (
|
|
||||||
<p className="text-center text-primary text-sm mb-3 opacity-60">
|
|
||||||
Start a conversation…
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<input
|
<input
|
||||||
value={input}
|
value={input}
|
||||||
onChange={(e) => setInput(e.target.value)}
|
onChange={(e) => setInput(e.target.value)}
|
||||||
onKeyDown={(e) => e.key === 'Enter' && !loading && sendMessage()}
|
onKeyDown={(e) => e.key === 'Enter' && !loading && sendMessage()}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
className="w-full p-3 rounded-xl bg-black/20 border border-muted outline-none disabled:opacity-50"
|
className="w-full max-w-2xl mx-auto block p-3 rounded-xl bg-black/20 border border-muted outline-none disabled:opacity-50"
|
||||||
placeholder="Message..."
|
placeholder="Message..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user