How can I excatly do a similar Date system like the one in the Whatsapp chat screen?
As you can see the messages are in a group by date, I mean they are separated by date.
Here is a ScreenShot that i found for better explanation:
I do this in a FlatList, while rendering the messages one by one.
Here is what i did
let previousDate = "";
if (index > 0) {
previousDate = moment(this.state.messages[index - 1].created_at).format(
"L"
);
} else {
previousDate = moment(this.state.messages.created_at).format("L");
}
let currentDate = moment(item.created_at).format("L");
So, i created a functional component for renderItem
prop of the FlatList, so item
and index
comes from the actual data from the FlatList.
What i'm trying to do here is, basically grabbing the current rendering item's created_at
and compare it with the previous item's created_at
, and to do that, i'm using the original data which is stored in the state. But unfortunately when the FlatList rendering the very first item which has index number 0
there is no previous element to compare in the original data in state, that's why i checking if is greater than 0 go and grab date from previous indexed item. And in the Else case, which means when rendering the first item, do not look for previous item and just get the created_at
.
And below i check if the currentDate
and previousDate
s are NOT the same, render a custom component else do not render anything.
{previousDate && !moment(currentDate).isSame(previousDate, "day") ? ( // custom component) : null}
It's should work like that, but the major problem is, i used inverted
FlatList for to able to messages go from bottom of the screen to the top. But now, becouse of it's a inverted flatlist the items being rendering from bottom to the top and it gives me result like this:
NOTE: At the beginning the messages were coming also reversed but i fixed this with sending them also reversed from the DB.
So, i don't know how do i able to achieve my goal, and do it like on the first picture.
Thank you!
New feature to allow searching by dateBy tapping the calendar icon, the date picker would appear to select any month, date, and year. Android users are also likely to receive the new feature through the Search option in the chat window.
The screenshots shared by the WhatsApp features tracker show that a Calendar icon will be available right above the keyboard. You can enter the relevant date, month, and year to find the message on WhatsApp. This feature will be very useful for people who like reading old texts.
See how many messages you and your friends have sent to each other. To find out whom you communicate with most on WhatsApp, go to Settings > Account > Network Usage. A number appears next to each contact that represents the total number of messages sent back and forth.
I use a helper function (generateItems
) to address the problem that you are describing. Here is the code that I use to group my messages by day and then render either a <Message />
or a <Day />
in the renderItem
prop. This is using an inverted
FlatList
as you described.
import moment from 'moment';
function groupedDays(messages) {
return messages.reduce((acc, el, i) => {
const messageDay = moment(el.created_at).format('YYYY-MM-DD');
if (acc[messageDay]) {
return { ...acc, [messageDay]: acc[messageDay].concat([el]) };
}
return { ...acc, [messageDay]: [el] };
}, {});
}
function generateItems(messages) {
const days = groupedDays(messages);
const sortedDays = Object.keys(days).sort(
(x, y) => moment(y, 'YYYY-MM-DD').unix() - moment(x, 'YYYY-MM-DD').unix()
);
const items = sortedDays.reduce((acc, date) => {
const sortedMessages = days[date].sort(
(x, y) => new Date(y.created_at) - new Date(x.created_at)
);
return acc.concat([...sortedMessages, { type: 'day', date, id: date }]);
}, []);
return items;
}
export default generateItems;
For reference here is my list as well as the renderItem
function:
<MessageList
data={generatedItems}
extraData={generatedItems}
inverted
keyExtractor={item => item.id.toString()}
renderItem={renderItem}
/>
function renderItem({ item }) {
if (item.type && item.type === 'day') {
return <Day {...item} />;
}
return <Message {...item} />;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With