feat: add day separator labels between chat messages
This commit is contained in:
@@ -6,6 +6,8 @@ import Typography from '@mui/material/Typography';
|
|||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
import LinearProgress from '@mui/material/LinearProgress';
|
import LinearProgress from '@mui/material/LinearProgress';
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
import Chip from '@mui/material/Chip';
|
||||||
|
import Divider from '@mui/material/Divider';
|
||||||
import SendIcon from '@mui/icons-material/Send';
|
import SendIcon from '@mui/icons-material/Send';
|
||||||
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||||
import AttachFileIcon from '@mui/icons-material/AttachFile';
|
import AttachFileIcon from '@mui/icons-material/AttachFile';
|
||||||
@@ -18,6 +20,27 @@ import type { NextcloudMessage } from '../../types/nextcloud.types';
|
|||||||
|
|
||||||
const LONG_POLL_TIMEOUT = 25;
|
const LONG_POLL_TIMEOUT = 25;
|
||||||
|
|
||||||
|
function dayKey(timestamp: number): string {
|
||||||
|
const d = new Date(timestamp * 1000);
|
||||||
|
return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dayLabel(timestamp: number): string {
|
||||||
|
const msgDate = new Date(timestamp * 1000);
|
||||||
|
const today = new Date();
|
||||||
|
const yesterday = new Date();
|
||||||
|
yesterday.setDate(today.getDate() - 1);
|
||||||
|
|
||||||
|
const sameDay = (a: Date, b: Date) =>
|
||||||
|
a.getFullYear() === b.getFullYear() &&
|
||||||
|
a.getMonth() === b.getMonth() &&
|
||||||
|
a.getDate() === b.getDate();
|
||||||
|
|
||||||
|
if (sameDay(msgDate, today)) return 'Heute';
|
||||||
|
if (sameDay(msgDate, yesterday)) return 'Gestern';
|
||||||
|
return msgDate.toLocaleDateString('de-DE', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });
|
||||||
|
}
|
||||||
|
|
||||||
const ChatMessageView: React.FC = () => {
|
const ChatMessageView: React.FC = () => {
|
||||||
const { selectedRoomToken, selectRoom, rooms, loginName, isActive } = useChat();
|
const { selectedRoomToken, selectRoom, rooms, loginName, isActive } = useChat();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
@@ -265,9 +288,18 @@ const ChatMessageView: React.FC = () => {
|
|||||||
<CircularProgress size={24} />
|
<CircularProgress size={24} />
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
messages.map((msg) => (
|
messages.map((msg, idx) => {
|
||||||
|
const showDaySep = idx === 0 || dayKey(msg.timestamp) !== dayKey(messages[idx - 1].timestamp);
|
||||||
|
return (
|
||||||
|
<React.Fragment key={msg.id}>
|
||||||
|
{showDaySep && (
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, px: 2, py: 1 }}>
|
||||||
|
<Divider sx={{ flex: 1 }} />
|
||||||
|
<Chip label={dayLabel(msg.timestamp)} size="small" variant="outlined" sx={{ fontSize: '0.7rem', height: 20 }} />
|
||||||
|
<Divider sx={{ flex: 1 }} />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
<ChatMessage
|
<ChatMessage
|
||||||
key={msg.id}
|
|
||||||
message={msg}
|
message={msg}
|
||||||
isOwnMessage={msg.actorType === 'users' && msg.actorId === loginName}
|
isOwnMessage={msg.actorType === 'users' && msg.actorId === loginName}
|
||||||
isOneToOne={isOneToOne}
|
isOneToOne={isOneToOne}
|
||||||
@@ -275,7 +307,9 @@ const ChatMessageView: React.FC = () => {
|
|||||||
onReactionToggled={handleReactionToggled}
|
onReactionToggled={handleReactionToggled}
|
||||||
reactionsOverride={reactionsMap.get(msg.id)}
|
reactionsOverride={reactionsMap.get(msg.id)}
|
||||||
/>
|
/>
|
||||||
))
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
})
|
||||||
)}
|
)}
|
||||||
<div ref={messagesEndRef} />
|
<div ref={messagesEndRef} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user