diff --git a/client/src/components/chat/chatArea/AnimatedMessage.tsx b/client/src/components/chat/chatArea/AnimatedMessage.tsx
deleted file mode 100644
index 8a59f93..0000000
--- a/client/src/components/chat/chatArea/AnimatedMessage.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-import { useContext, useState } from 'react';
-import { Trash2 } from 'lucide-react';
-import AttachmentPreview from './AttachmentPreview.tsx';
-import { ChatMessagesProps } from '@/types/types.ts';
-import { useChat } from '@/context/chat/useChat.ts';
-import { AuthContext } from '@/utils/AuthProvider.tsx';
-
-type AnimatedMessageProps = {
- message: ChatMessagesProps;
- onDelete: (messageId: number) => void;
-};
-
-const AnimatedMessage = ({ onDelete, message }: AnimatedMessageProps) => {
- const { user } = useContext(AuthContext);
- const { me, groupOwner } = useChat();
- const [isRemoving, setIsRemoving] = useState(false);
-
- const handleDelete = () => {
- setIsRemoving(true);
- setTimeout(() => {
- onDelete(message.message_id);
- }, 300);
- };
-
- return (
-
-
-
-
- {message.sender}: {message.message}
-
- {message.attachment_urls && (
-
- {message.attachment_urls?.length > 0
- ? message.attachment_urls.map((url, index) => (
-
- ))
- : null}
-
- )}
-
- {me.isGroupOwner ||
- message.sender == user?.username ||
- (me.isGroupAdmin &&
- me.isGroupOwner &&
- message.sender_id !== groupOwner) ? (
-
- ) : null}
-
-
- );
-};
-
-export default AnimatedMessage;
diff --git a/client/src/components/chat/chatArea/MessageElement.tsx b/client/src/components/chat/chatArea/MessageElement.tsx
new file mode 100644
index 0000000..bbaf8de
--- /dev/null
+++ b/client/src/components/chat/chatArea/MessageElement.tsx
@@ -0,0 +1,89 @@
+import { useContext, useState } from 'react';
+import { Trash2 } from 'lucide-react';
+import AttachmentPreview from './AttachmentPreview.tsx';
+import { ChatMessagesProps } from '@/types/types.ts';
+import { useChat } from '@/context/chat/useChat.ts';
+import { AuthContext } from '@/utils/AuthProvider.tsx';
+import { format, isToday, isYesterday, formatDistanceToNow } from 'date-fns';
+import { pl } from 'date-fns/locale';
+
+type AnimatedMessageProps = {
+ message: ChatMessagesProps;
+ onDelete: (messageId: number) => void;
+};
+
+const MessageElement = ({ onDelete, message }: AnimatedMessageProps) => {
+ const { user } = useContext(AuthContext);
+ const { me, groupOwner } = useChat();
+ const [isRemoving, setIsRemoving] = useState(false);
+
+ const handleDelete = () => {
+ setIsRemoving(true);
+ setTimeout(() => {
+ onDelete(message.message_id);
+ }, 300);
+ };
+
+ const formatMessageDate = (date: Date) => {
+ if (isToday(date)) {
+ return `Dzisiaj o ${format(date, 'HH:mm')}`;
+ }
+ if (isYesterday(date)) {
+ return `Wczoraj o ${format(date, 'HH:mm')}`;
+ }
+ return format(date, "d MMMM yyyy 'o' HH:mm", { locale: pl });
+ };
+
+ const messageDate = new Date(message.sent_at);
+ const formattedDate = formatMessageDate(messageDate);
+ const fullDate = format(messageDate, "d MMMM yyyy 'o' HH:mm", { locale: pl });
+ const timeAgo = formatDistanceToNow(messageDate, {
+ addSuffix: true,
+ locale: pl,
+ });
+
+ const canDelete =
+ me.isGroupOwner ||
+ message.sender === user?.username ||
+ (me.isGroupAdmin && me.isGroupOwner && message.sender_id !== groupOwner);
+
+ return (
+
+
+
+
+ {message.sender}
+
+ {formattedDate}
+
+
+
{message.message}
+ {message.attachment_urls && message.attachment_urls.length > 0 && (
+
+ {message.attachment_urls.map((url, index) => (
+
+ ))}
+
+ )}
+
+ {canDelete && (
+
+ )}
+
+
+ );
+};
+
+export default MessageElement;
diff --git a/client/src/components/chat/chatArea/MessagesArea.tsx b/client/src/components/chat/chatArea/MessagesArea.tsx
index 8221eb3..57b0836 100644
--- a/client/src/components/chat/chatArea/MessagesArea.tsx
+++ b/client/src/components/chat/chatArea/MessagesArea.tsx
@@ -2,7 +2,7 @@ import { useContext, useEffect, useRef, useState } from 'react';
import { socket } from '@/socket/socket.ts';
import { sendContact } from '@/api/contactsApi.tsx';
import LoadingWheel from '../LoadingWheel.tsx';
-import AnimatedMessage from '@/components/chat/chatArea/AnimatedMessage.tsx';
+import AnimatedMessage from '@/components/chat/chatArea/MessageElement.tsx';
import { ChatMessagesProps } from '@/types/types.ts';
import { useChat } from '@/context/chat/useChat.ts';
import { AuthContext } from '@/utils/AuthProvider.tsx';
@@ -56,7 +56,7 @@ function MessagesArea() {
const isAtBottom =
container.scrollHeight - container.scrollTop <=
- container.clientHeight + 100;
+ container.clientHeight + 200;
setShouldScrollToBottom(isAtBottom);
};
diff --git a/client/src/pages/Chat.tsx b/client/src/pages/Chat.tsx
index c1e0cba..1a296d2 100644
--- a/client/src/pages/Chat.tsx
+++ b/client/src/pages/Chat.tsx
@@ -32,7 +32,7 @@ function Chat() {
}, []);
return (
-