preface
When we chat on QQ, the chat records of the same minute will be displayed together. When we send messages, the sending time of each message will be accurate to the second. So how does he achieve the display of these data by minute?
Today add open source project to me on the chat messages show time, I met the question, at first not understand should be how to deal with these data, then after some thinking, and finally an implementation approach and its implementation, the implementation of next I will share with you this way of thinking and process, welcome interested developers to read this article.
Let me show you the final result:
Implementation approach
First, let me show you my data, as follows:
[{
"createTime": "The 2020-12-21 20:58:19"."avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg"."msgId": "121710f399b84322bdecc238199d6888"."msgText": "/ smile/"."userName": "The Amazing Programmer."."userId": "c04618bab36146e3a9d3b411e7f9eb8f"."status": false
}, {
"createTime": "The 2020-12-21 20:58:22"."avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg"."msgId": "121710f399b84322bdecc238199d6888"."msgText": "Anyone else?"."userName": "The Amazing Programmer."."userId": "c04618bab36146e3a9d3b411e7f9eb8f"."status": false
}, {
"createTime": "The 2020-12-21 20:58:46"."avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg"."msgId": "121710f399b84322bdecc238199d6888"."msgText": "Chat history, added time to send messages."."userName": "The Amazing Programmer."."userId": "c04618bab36146e3a9d3b411e7f9eb8f"."status": false
}, {
"createTime": "The 2020-12-21 20:58:52"."avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg"."msgId": "121710f399b84322bdecc238199d6888"."msgText": "Now it looks a lot easier."."userName": "The Amazing Programmer."."userId": "c04618bab36146e3a9d3b411e7f9eb8f"."status": false
}, {
"createTime": "The 2020-12-21 21:35:27"."avatarSrc": "https://www.kaisir.cn/uploads/1ece3749801d4d45933ba8b31403c685touxiang.jpeg"."msgId": "121710f399b84322bdecc238199d6888"."msgText": "/ smile/"."userName": "The Amazing Programmer."."userId": "c04618bab36146e3a9d3b411e7f9eb8f"."status": false
}]
Copy the code
Observing the above data, we found that: Each message object has a createTime property, which is the time at which the message was sent. Now we need to keep only one createTime property for the same minute, and only render the object with the createTime property. That’s how you render the same minute of data together.
That’s the general idea, but let’s look at the specific idea:
- Declare an object named
timeObj
In the message objectcreateTime
The fieldYear – month – day hour: minuteDeclare a new array of message recordsfinalTextList
Store processed data - Iterates through the message record array to get the message record object currently iterated
- Of the traversed message log object
createTime
Property, interceptionYear – month – day hour: minuteDeclare a variabletime
To save the - judge
time
Does it existtimeObj
In the - Delete the message record object traversed if it exists
createTime
Property to place the message log object after the property is deletedfinalTextList
In the - Otherwise it would be
time
Put in as a propertytimeObj
In, place the traversed message log object intactfinalTextList
In the
After processing the data, we determine at render time whether createTime exists in the current render item and render if it does.
The implementation process
Next, we take the data returned by the interface and process it in accordance with the above ideas.
Process the data returned by the interface
Res.data. messageTextList is the list of message records returned by the interface, as shown below.
// List of message contents
const messageTextList: Array<msgListType> = res.data.messageTextList;
// An array of processed message contents
const finalTextList: Array<msgListType> = [];
// Time stores objects
const timeObj: { [key: string] :boolean } = {};
// Process the list of message contents, keeping only one creation time for each minute of data
for (let i = 0; i < messageTextList.length; i++) {
// Message object
const messageObj = messageTextList[i];
// Get time year - month - day: minute
const time = (messageObj.createTime as string).substring(0.16);
// If time already exists in timeObj, remove createTime from the current message object
if (_.has(timeObj, time)) {
// Remove the createTime attribute
_.unset(messageObj, "createTime");
// Place the message object with the createTime attribute removed into the processed message array
finalTextList.push(messageObj);
} else {
// Place time as the key in timeObj
timeObj[time] = true;
// Put the message object into the processed message arrayfinalTextList.push(messageObj); }}// Render the message list
this.renderPage(finalTextList, {});
Copy the code
In the above code msgListType is the type definition of the message log object, has is the lodash method to determine whether the object contains an attribute, and unset is the Lodash method to remove an attribute from the object.
Handling push data
Received a data server push, we would like to news aggregation server push to the already rendered in the chat, if not the same minute news render new time, so we need to remove the current push message createTime fields, intercepting year – month – day: points to judge whether the list of records in the rendering of the news, If the createTime field is not present, render as it is, otherwise delete createTime and render as follows:
Render a single message object after receiving a new message pushed by the server
const thisSenderMessageObj: msgListType = {
msgText: msgObj.msgText,
avatarSrc: msgObj.avatarSrc,
userId: msgObj.userId,
userName: msgObj.userName,
createTime: msgObj? .createTime };Remove the createTime object for the new message by finding the message in the message record list at the same minute as the new message
for (let i = 0; i < this.senderMessageList.length; i++) {
const messageObj: msgListType = this.senderMessageList[i];
// Intercepts the time when the current message is sent and the time when the new message is sent: minute to determine whether they are equal
if(_.isEqual( messageObj.createTime? .substring(0.16),thisSenderMessageObj.createTime? .substring(0.16))) {
// Remove the createTime attribute for the new message
_.unset(thisSenderMessageObj, "createTime"); }}// Parse and render
this.messageParsing(thisSenderMessageObj);
Copy the code
MsgObj pushes messages to the server
To render the page
Let’s look at the rendering code for the page, as shown below, which only renders the data in the object that contains the createTime attribute
<! - message time -- > < div class = "snder - time - a panel" v - if = "item. CreateTime" > < span > {{item. CreateTime. Substring (5, 16) }}</span> </div>Copy the code
Rendering optimization
Thanks to @Leewing’s suggestion, I changed the data type directly. When rendering new data, I will compare the already rendered data each time with O(n) time complexity.
After using the idea of digging friends, the time complexity is directly reduced from O(n) to O(1)😄, the code is as follows:
<! - message time: current sending messages indicate for the first time -- > < div class = "sender - time - a panel" v - if = "index = = = 0" > < span > {{item. CreateTime. Substring (11, 16) }}</span> </div> <! On the current message and send a message time to capture moments of subtraction is greater than 1 will display time -- > < div class = "sender - time - a panel" v - else - if = "parseInt (item) createTime) the substring (11, 13) + item.createTime.substring(14, 16) ) - parseInt( senderMessageList[index - 1].createTime.substring(11, 13) + senderMessageList[index - 1].createTime.substring(14, 16) ) > 1 " > <span>{{ item.createTime.substring(11, 16) }}</span> </div>Copy the code
Implementation effect
Finally, let’s take a look at the implementation, as follows:
Let’s send another message to see what it looks like:
The project address
Code address: message-display.vue
Online experience address: chat-system
Write in the last
- If there are any errors in this article, please correct them in the comments section. If this article helped you, please like it and follow 😊
- This article was first published in nuggets. Reprint is prohibited without permission 💌