Skip to content

Commit 73cef35

Browse files
authored
Merge pull request #268 from codeunia-dev/feat/messageuserstatus
feat(messages): Enhance mobile responsiveness for messaging interface
2 parents d2f2482 + 728365f commit 73cef35

File tree

5 files changed

+63
-30
lines changed

5 files changed

+63
-30
lines changed

app/protected/messages/page.tsx

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,24 @@ export default function MessagesPage() {
5959
<div className="max-w-7xl mx-auto flex items-center justify-between">
6060
<div className="flex items-center gap-3">
6161
<MessageSquare className="h-6 w-6 text-primary" />
62-
<h1 className="text-2xl font-bold">Messages</h1>
62+
<h1 className="text-xl md:text-2xl font-bold">Messages</h1>
6363
</div>
6464
<Button onClick={() => setShowNewMessage(true)} className="gap-2">
6565
<Plus className="h-4 w-4" />
66-
New Message
66+
<span className="hidden sm:inline">New Message</span>
67+
<span className="sm:hidden">New</span>
6768
</Button>
6869
</div>
6970
</div>
7071

7172
{/* Main Content */}
7273
<div className="flex-1 overflow-hidden">
7374
<div className="max-w-7xl mx-auto h-full flex">
74-
{/* Sidebar - Conversation List */}
75-
<div className="w-80 border-r flex flex-col bg-background">
75+
{/* Sidebar - Conversation List (Hidden on mobile when conversation is selected) */}
76+
<div className={`
77+
w-full md:w-80 md:border-r flex flex-col bg-background
78+
${selectedConversationId ? 'hidden md:flex' : 'flex'}
79+
`}>
7680
{/* Search */}
7781
<div className="p-3 border-b">
7882
<div className="relative">
@@ -97,12 +101,36 @@ export default function MessagesPage() {
97101
</div>
98102
</div>
99103

100-
{/* Main Area - Conversation View */}
101-
<div className="flex-1 bg-background flex flex-col">
104+
{/* Main Area - Conversation View (Hidden on mobile when no conversation selected) */}
105+
<div className={`
106+
flex-1 bg-background flex flex-col
107+
${selectedConversationId ? 'flex' : 'hidden md:flex'}
108+
`}>
102109
{selectedConversationId && selectedConversation && (
103-
<div className="border-b p-4 bg-muted/50 flex-shrink-0">
104-
<div className="flex items-center gap-3">
105-
<h2 className="font-semibold">{conversationName}</h2>
110+
<div className="border-b p-3 md:p-4 bg-muted/50 flex-shrink-0">
111+
<div className="flex items-center gap-2 md:gap-3">
112+
{/* Back button for mobile */}
113+
<Button
114+
variant="ghost"
115+
size="icon"
116+
className="md:hidden"
117+
onClick={() => setSelectedConversationId(null)}
118+
>
119+
<svg
120+
xmlns="http://www.w3.org/2000/svg"
121+
width="20"
122+
height="20"
123+
viewBox="0 0 24 24"
124+
fill="none"
125+
stroke="currentColor"
126+
strokeWidth="2"
127+
strokeLinecap="round"
128+
strokeLinejoin="round"
129+
>
130+
<path d="m15 18-6-6 6-6"/>
131+
</svg>
132+
</Button>
133+
<h2 className="font-semibold text-sm md:text-base truncate">{conversationName}</h2>
106134
{!selectedConversation.is_group && selectedConversation.other_user && selectedConversation.other_user.id ? (
107135
<UserStatusIndicator
108136
userId={selectedConversation.other_user.id}

components/messages/ConversationList.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,24 @@ export function ConversationList({ conversations, selectedId, onSelect, loading
111111

112112
<div className="flex-1 min-w-0">
113113
<div className="flex items-center justify-between mb-1">
114-
<span className={cn('font-semibold truncate', conversation.unread_count > 0 && 'text-primary')}>
114+
<span className={cn('font-semibold truncate text-sm md:text-base', conversation.unread_count > 0 && 'text-primary')}>
115115
{name}
116116
</span>
117117
{conversation.last_message_at && (
118-
<span className="text-xs text-muted-foreground flex-shrink-0 ml-2">
118+
<span className="text-[10px] md:text-xs text-muted-foreground flex-shrink-0 ml-2">
119119
{formatDistanceToNow(new Date(conversation.last_message_at), { addSuffix: true })}
120120
</span>
121121
)}
122122
</div>
123123
<div className="flex items-center justify-between">
124124
<p className={cn(
125-
'text-sm truncate',
125+
'text-xs md:text-sm truncate',
126126
conversation.unread_count > 0 ? 'font-medium text-foreground' : 'text-muted-foreground'
127127
)}>
128128
{conversation.last_message_content || 'No messages yet'}
129129
</p>
130130
{conversation.unread_count > 0 && (
131-
<Badge variant="default" className="ml-2 flex-shrink-0">
131+
<Badge variant="default" className="ml-2 flex-shrink-0 text-xs">
132132
{conversation.unread_count}
133133
</Badge>
134134
)}

components/messages/MessageInput.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export function MessageInput({ onSend, disabled, placeholder = 'Type a message..
9090
}, [content, isTyping, onTyping])
9191

9292
return (
93-
<form onSubmit={handleSubmit} className="border-t bg-background p-3">
93+
<form onSubmit={handleSubmit} className="border-t bg-background p-2 md:p-3">
9494
<div className="flex gap-2 items-end max-w-full">
9595
<Textarea
9696
ref={textareaRef}
@@ -99,14 +99,14 @@ export function MessageInput({ onSend, disabled, placeholder = 'Type a message..
9999
onKeyDown={handleKeyDown}
100100
placeholder={placeholder}
101101
disabled={disabled || sending}
102-
className="min-h-[44px] max-h-[120px] resize-none flex-1"
102+
className="min-h-[40px] md:min-h-[44px] max-h-[120px] resize-none flex-1 text-sm md:text-base"
103103
rows={1}
104104
/>
105105
<Button
106106
type="submit"
107107
size="icon"
108108
disabled={!content.trim() || sending || disabled}
109-
className="flex-shrink-0 h-11 w-11"
109+
className="flex-shrink-0 h-10 w-10 md:h-11 md:w-11"
110110
>
111111
{sending ? (
112112
<Loader2 className="h-4 w-4 animate-spin" />
@@ -115,7 +115,7 @@ export function MessageInput({ onSend, disabled, placeholder = 'Type a message..
115115
)}
116116
</Button>
117117
</div>
118-
<p className="text-xs text-muted-foreground mt-1.5">
118+
<p className="text-[10px] md:text-xs text-muted-foreground mt-1 md:mt-1.5 hidden sm:block">
119119
Press Enter to send, Shift+Enter for new line
120120
</p>
121121
</form>

components/messages/TypingIndicator.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,14 @@ interface TypingIndicatorProps {
99
export function TypingIndicator({ usernames }: TypingIndicatorProps) {
1010
if (usernames.length === 0) return null
1111

12-
const getTypingText = () => {
13-
if (usernames.length === 1) {
14-
return `${usernames[0]} is typing...`
15-
} else if (usernames.length === 2) {
16-
return `${usernames[0]} and ${usernames[1]} are typing...`
17-
} else {
18-
return `${usernames[0]} and ${usernames.length - 1} others are typing...`
19-
}
20-
}
21-
2212
return (
2313
<div className="flex items-center gap-2 px-4 py-2 text-sm text-muted-foreground">
2414
<div className="flex gap-1">
2515
<span className="w-2 h-2 bg-muted-foreground rounded-full animate-bounce" style={{ animationDelay: '0ms' }} />
2616
<span className="w-2 h-2 bg-muted-foreground rounded-full animate-bounce" style={{ animationDelay: '150ms' }} />
2717
<span className="w-2 h-2 bg-muted-foreground rounded-full animate-bounce" style={{ animationDelay: '300ms' }} />
2818
</div>
29-
<span>{getTypingText()}</span>
19+
<span>Typing...</span>
3020
</div>
3121
)
3222
}

hooks/useMessages.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ export function useMessages(conversationId: string | null) {
4242

4343
const supabase = createClient()
4444

45+
console.log('📡 Setting up message subscription for conversation:', conversationId)
46+
4547
const subscription = supabase
4648
.channel(`messages:${conversationId}`)
4749
.on(
@@ -53,6 +55,8 @@ export function useMessages(conversationId: string | null) {
5355
filter: `conversation_id=eq.${conversationId}`
5456
},
5557
async (payload) => {
58+
console.log('🔔 New message received via realtime:', payload)
59+
5660
// Fetch the complete message with sender details
5761
const { data } = await supabase
5862
.from('messages')
@@ -70,6 +74,8 @@ export function useMessages(conversationId: string | null) {
7074
.single()
7175

7276
if (data) {
77+
console.log('📨 Fetched complete message data:', data)
78+
7379
// Decrypt the message content
7480
const decryptResponse = await fetch('/api/messages/decrypt', {
7581
method: 'POST',
@@ -79,21 +85,30 @@ export function useMessages(conversationId: string | null) {
7985

8086
const { decrypted } = await decryptResponse.json()
8187
const decryptedMessage = { ...data, content: decrypted }
88+
89+
console.log('🔓 Decrypted message:', decrypted)
8290

8391
setMessages(prev => {
8492
// Avoid duplicates
8593
const exists = prev.some(msg => msg.id === data.id)
86-
if (exists) return prev
94+
if (exists) {
95+
console.log('⚠️ Message already exists, skipping')
96+
return prev
97+
}
98+
console.log('✅ Adding new message to state')
8799
return [...prev, decryptedMessage as Message]
88100
})
89101
// Mark as read
90102
await messageService.markAsRead(conversationId)
91103
}
92104
}
93105
)
94-
.subscribe()
106+
.subscribe((status) => {
107+
console.log('Message subscription status:', status)
108+
})
95109

96110
return () => {
111+
console.log('🔌 Unsubscribing from messages')
97112
subscription.unsubscribe()
98113
}
99114
}, [conversationId])

0 commit comments

Comments
 (0)