fix: prevent message horizontal overflow with proper text wrapping

Message Layout Improvements:
- Added proper padding to message items (px-3 py-2)
- Added flex-1 min-w-0 to message content container to allow shrinking
- Added break-words and overflow-hidden to prevent horizontal overflow
- Ensures long URLs and unbreakable text wrap properly

Message Composer Improvements:
- Added border-t and consistent padding (px-3 py-2)
- Added border and rounded-md to textarea for better visual separation
- Added min-w-0 to textarea to prevent overflow in flex layout
- Added flex-shrink-0 to Send button to prevent squishing
- Added mb-2 to reply preview for spacing

These changes ensure:
- Long messages and URLs wrap correctly without horizontal scroll
- Consistent spacing throughout the chat interface
- Proper flex behavior prevents layout breaks
- Professional chat UI appearance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Alejandro Gómez
2026-01-11 22:12:53 +01:00
parent 8f262e1189
commit 6c1c1bbf04
2 changed files with 11 additions and 9 deletions

View File

@@ -39,15 +39,15 @@ const MessageItem = memo(function MessageItem({
conversation: Conversation; conversation: Conversation;
}) { }) {
return ( return (
<div className="group flex items-start hover:bg-muted/50"> <div className="group flex items-start hover:bg-muted/50 px-3 py-2">
<div className=""> <div className="flex-1 min-w-0">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<UserName pubkey={message.author} className="font-semibold text-sm" /> <UserName pubkey={message.author} className="font-semibold text-sm" />
<span className="text-xs text-muted-foreground"> <span className="text-xs text-muted-foreground">
<Timestamp timestamp={message.timestamp} /> <Timestamp timestamp={message.timestamp} />
</span> </span>
</div> </div>
<div className="text-sm leading-relaxed"> <div className="text-sm leading-relaxed break-words overflow-hidden">
{message.event ? ( {message.event ? (
<RichText event={message.event}> <RichText event={message.event}>
{message.replyTo && ( {message.replyTo && (
@@ -59,7 +59,9 @@ const MessageItem = memo(function MessageItem({
)} )}
</RichText> </RichText>
) : ( ) : (
<span className="whitespace-pre-wrap">{message.content}</span> <span className="whitespace-pre-wrap break-words">
{message.content}
</span>
)} )}
</div> </div>
</div> </div>
@@ -177,9 +179,9 @@ export function ChatViewer({
</div> </div>
{/* Message composer */} {/* Message composer */}
<div className=""> <div className="border-t px-3 py-2">
{replyTo && ( {replyTo && (
<div className="flex items-center gap-2 rounded bg-muted px-2 py-1 text-xs"> <div className="flex items-center gap-2 rounded bg-muted px-2 py-1 text-xs mb-2">
<span>Replying to {replyTo.slice(0, 8)}...</span> <span>Replying to {replyTo.slice(0, 8)}...</span>
<button <button
onClick={() => setReplyTo(undefined)} onClick={() => setReplyTo(undefined)}
@@ -207,7 +209,7 @@ export function ChatViewer({
name="message" name="message"
autoFocus autoFocus
placeholder="Type a message..." placeholder="Type a message..."
className="flex-1 resize-none bg-background px-2 py-1.5 text-sm" className="flex-1 resize-none bg-background px-3 py-2 text-sm border rounded-md min-w-0"
rows={1} rows={1}
onKeyDown={(e) => { onKeyDown={(e) => {
// Submit on Enter (without Shift) // Submit on Enter (without Shift)
@@ -217,7 +219,7 @@ export function ChatViewer({
} }
}} }}
/> />
<Button type="submit" variant="secondary"> <Button type="submit" variant="secondary" className="flex-shrink-0">
Send Send
</Button> </Button>
</form> </form>

View File

@@ -282,7 +282,7 @@ export class Nip29Adapter extends ChatProtocolAdapter {
const filter: Filter = { const filter: Filter = {
kinds: [9], kinds: [9],
"#h": [groupId], "#h": [groupId],
limit: options?.limit || 200, limit: options?.limit || 50,
}; };
if (options?.before) { if (options?.before) {