feat: enhance chat room UI with user avatars and message improvements
- Added user avatar generation with external avatar service - Implemented message styling with user-specific layouts - Added message length counter and validation - Updated CSS for improved message and user profile display - Restricted message length to 2048 characters - Added disabled state for send button based on message length
This commit is contained in:
parent
3d41e2cc42
commit
d4d99fb5e7
5 changed files with 144 additions and 24 deletions
|
@ -161,14 +161,18 @@ export function ChatRoom(props: ChatRoomProps) {
|
|||
}
|
||||
});
|
||||
|
||||
const MAX_MESSAGE_LENGTH = 2048;
|
||||
|
||||
const handleSendMessage = async (e: Event) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!message().trim()) return;
|
||||
const trimmedMessage = message().trim();
|
||||
if (!trimmedMessage) return;
|
||||
if (trimmedMessage.length > MAX_MESSAGE_LENGTH) return;
|
||||
|
||||
try {
|
||||
await sendMessage({
|
||||
content: message(),
|
||||
content: trimmedMessage,
|
||||
roomId: props.roomId,
|
||||
});
|
||||
setMessage('');
|
||||
|
@ -242,6 +246,10 @@ export function ChatRoom(props: ChatRoomProps) {
|
|||
};
|
||||
});
|
||||
|
||||
// Function to generate avatar URL
|
||||
const getUserAvatarUrl = (userId: string, size: number = 40) =>
|
||||
`https://avatars.jusemon.com/${userId}?size=${size}`;
|
||||
|
||||
return (
|
||||
<div class='chat-room'>
|
||||
<Show when={roomQuery.data?.room} fallback={<div>Loading room...</div>}>
|
||||
|
@ -276,13 +284,24 @@ export function ChatRoom(props: ChatRoomProps) {
|
|||
<For each={messages()}>
|
||||
{(message) => (
|
||||
<div
|
||||
class={`message ${message.user.id === props.userId ? 'own-message' : ''}`}
|
||||
class={`message-wrapper ${message.user.id === props.userId ? 'own-message-wrapper' : 'other-message-wrapper'}`}
|
||||
>
|
||||
<div class='message-header'>
|
||||
<span class='username'>{message.user.username}</span>
|
||||
<span class='time'>{formatTime(message.createdAt)}</span>
|
||||
{message.user.id !== props.userId && (
|
||||
<img
|
||||
src={getUserAvatarUrl(message.user.id)}
|
||||
alt={`${message.user.username}'s avatar`}
|
||||
class='message-avatar'
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
class={`message ${message.user.id === props.userId ? 'own-message' : 'other-message'}`}
|
||||
>
|
||||
<div class='message-header'>
|
||||
<span class='username'>{message.user.username}</span>
|
||||
<span class='time'>{formatTime(message.createdAt)}</span>
|
||||
</div>
|
||||
<div class='message-content'>{message.content}</div>
|
||||
</div>
|
||||
<div class='message-content'>{message.content}</div>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
|
@ -295,7 +314,12 @@ export function ChatRoom(props: ChatRoomProps) {
|
|||
ref={messageInput}
|
||||
type='text'
|
||||
value={message()}
|
||||
onInput={(e) => setMessage(e.currentTarget.value)}
|
||||
onInput={(e) => {
|
||||
const inputValue = e.currentTarget.value;
|
||||
if (inputValue.length <= MAX_MESSAGE_LENGTH) {
|
||||
setMessage(inputValue);
|
||||
}
|
||||
}}
|
||||
placeholder='Type a message...'
|
||||
/>
|
||||
<button
|
||||
|
@ -306,7 +330,18 @@ export function ChatRoom(props: ChatRoomProps) {
|
|||
😊
|
||||
</button>
|
||||
</div>
|
||||
<button type='submit'>Send</button>
|
||||
<div class='message-length-counter'>
|
||||
{message().length}/{MAX_MESSAGE_LENGTH}
|
||||
</div>
|
||||
<button
|
||||
type='submit'
|
||||
disabled={
|
||||
message().trim().length === 0 ||
|
||||
message().length > MAX_MESSAGE_LENGTH
|
||||
}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
|
||||
{showEmojiPicker() && (
|
||||
<div ref={emojiPickerContainer} class='emoji-picker-container'>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue