Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .changeset/young-bars-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'@rocket.chat/livechat': minor
---

Updated the MessageSeparator component in the Livechat widget to show user-friendly labels instead of always displaying the full formatted date.
Changes:

Added a getDateLabel helper function that compares the message date against today and yesterday
Messages from today now show "Today"
Messages from yesterday now show "Yesterday"
Older messages still display the full formatted date (e.g. MAY 15, 2026)

Files changed: packages/livechat/src/components/Messages/MessageSeparator/index.tsxe
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,60 @@ type MessageSeparatorProps = {
use?: any;
};

const isSameDay = (a: Date, b: Date) =>
a.getFullYear() === b.getFullYear() &&
a.getMonth() === b.getMonth() &&
a.getDate() === b.getDate();


const getDateLabel = (date: string, t: TFunction): string => {

@psshrijith psshrijith May 22, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this version looks more readable. @Varun789-mx

const isSameDay = (a: Date, b: Date) =>
	a.getFullYear() === b.getFullYear() &&
	a.getMonth() === b.getMonth() &&
	a.getDate() === b.getDate();

const getDateLabel = (date: string, t: TFunction): string => {
	const messageDate = new Date(date);

	if (isNaN(messageDate.getTime())) return '';

	const today = new Date();

	if (isSameDay(messageDate, today)) {
		return t('today');
	}

	const yesterday = new Date(today);
	yesterday.setDate(today.getDate() - 1);

	if (isSameDay(messageDate, yesterday)) {
		return t('yesterday');
	}

	return t('message_separator_date', {
		val: messageDate,
		formatParams: {
			val: {
				month: 'short',
				day: '2-digit',
				year: 'numeric',
			},
		},
	}).toUpperCase();
};

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this LGTM and i place the

const isSameDay = (a: Date, b: Date) =>
	a.getFullYear() === b.getFullYear() &&
	a.getMonth() === b.getMonth() &&
	a.getDate() === b.getDate();

outside the main which will prevent multiple function calls make it more efficient

const messageDate = new Date(date);
if (isNaN(messageDate.getTime())) {
return '';
}
const today = new Date();
const yesterday = new Date();
yesterday.setDate(today.getDate() - 1);


if (isSameDay(messageDate, today)) return t('Today');
if (isSameDay(messageDate, yesterday)) return t('Yesterday');

return t('message_separator_date', {
val: messageDate,
formatParams: {
val: { month: 'short', day: '2-digit', year: 'numeric' },
},
}).toUpperCase();
};

// TODO: find a better way to pass `use` and do not default to a string
// eslint-disable-next-line @typescript-eslint/naming-convention
const MessageSeparator = ({ date, unread, use: Element = 'div', className, style = {}, t }: MessageSeparatorProps) => (
<Element
className={createClassName(
styles,
'separator',
{
date: !!date && !unread,
unread: !date && !!unread,
},
[className],
)}
style={style}
>
<hr className={createClassName(styles, 'separator__line')} />
{(date || unread) && (
<span className={createClassName(styles, 'separator__text')}>
{(!!date &&
t('message_separator_date', {
val: new Date(date),
formatParams: {
val: { month: 'short', day: '2-digit', year: 'numeric' },
},
}).toUpperCase()) ||
(unread && t('unread_messages'))}
</span>
)}
<hr className={createClassName(styles, 'separator__line')} />
</Element>
);
const MessageSeparator = ({ date, unread, use: Element = 'div', className, style = {}, t }: MessageSeparatorProps) => {
const dateLabel = date ? getDateLabel(date, t) : '';

return (
<Element
className={createClassName(
styles,
'separator',
{
date: !!date && !unread,
unread: !date && !!unread,
},
[className],
)}
style={style}
>
<hr className={createClassName(styles, 'separator__line')} />
{(date || unread) && (
<span className={createClassName(styles, 'separator__text')}>
{dateLabel || (unread ? t('Unread_Messages') : null)}
</span>
)}
<hr className={createClassName(styles, 'separator__line')} />
</Element>
);
};

export default withTranslation()(memo(MessageSeparator));