[英]How does slack store unread message counts?
I'm building a chat application and I'm trying to identify the state architecture for indicating unread messages.我正在构建一个聊天应用程序,并试图识别状态架构以指示未读消息。
My state currently contains a list of messages.我的状态当前包含消息列表。 On render, I group them by conversation so I can render a list of recipients and, for the selected recipient, the messages.
在渲染时,我按对话对它们进行分组,这样我就可以渲染收件人列表,并为选定的收件人渲染消息。
The simplest approach would be to also store a
lastRead<\/code> hash of
{recipient: lastReadTimestamp}<\/code> in the state as well.
最简单的方法是将
{recipient: lastReadTimestamp}<\/code>的
lastRead<\/code>哈希也存储在状态中。
On render, count the number of messages in each conversation whose timestamp is greater than the stored
lastRead<\/code> timestamp to get the number of unread messages.
在渲染时,计算每个会话中时间戳大于存储的
lastRead<\/code>时间戳的消息数,以获取未读消息的数量。
And when the recipient is selected, set the
lastRead<\/code> timestamp for that recipient to that of the most recent message.
选择收件人后,将该收件人的
lastRead<\/code>时间戳设置为最新消息的时间戳。
The problem with this is if, while you're away, 15+ messages come in - to the point that some are beyond the viewport and you'd have to scroll to see them.这样做的问题是,当您离开时,有 15 条以上的消息进入 - 以至于有些消息超出了视口,您必须滚动才能看到它们。 Once you select that recipient, it will mark the
lastRead<\/code> timestamp as the most recent message, essentially marking the entire conversation as "read" even though there are messages above that haven't been seen.
一旦您选择了该收件人,它会将
lastRead<\/code>时间戳标记为最新消息,基本上将整个对话标记为“已读”,即使上面有尚未看到的消息。
Instead I was hoping to have functionality more like Slack's.相反,我希望拥有更像 Slack 的功能。 in-view<\/a> or an InteractionObserver<\/a> could detect when a message has actually come into the viewport.
in-view<\/a>或InteractionObserver<\/a>可以检测消息何时实际进入视口。
Has anyone seen a good design pattern for this?有没有人看到一个好的设计模式?
"
We did use IntersectionObserver for exactly the same use case in a chat application.我们确实在聊天应用程序中将 IntersectionObserver 用于完全相同的用例。
Pre-requests<\/strong> : The messages have 2 meta-fields:预请求<\/strong>:消息有 2 个元字段:
time<\/code> (when it was sent)
time<\/code> (发送时间)
<\/li>
timeSeen<\/code> (when it was viewed)
timeSeen<\/code> (查看时间)
<\/li><\/ul> The flow is as follows:<\/strong>
流程如下:<\/strong>
- clientA sends a message via the server clientA 通过服务器发送消息<\/li>
server appends time = now()<\/code> and timeSeen = null<\/code> to that message
服务器将time = now()<\/code>和timeSeen = null<\/code>附加到该消息
<\/li>
![](/img/trans.png)
server saves the messages to the databases服务器将消息保存到数据库<\/li>
![](/img/trans.png)
server forwards the message to clientB服务器将消息转发给客户端B<\/li>
![](/img/trans.png)
clientB checks that the message does not have timeSeen<\/code> , eg it's null<\/code>
clientB 检查消息没有timeSeen<\/code> ,例如它是null<\/code>
<\/li>
![](/img/trans.png)
clientB renders the message inside an IntersectionObserver<\/code> wrapped component, which triggers a hook when message is in viewport and passes the messageId<\/code> as a param
clientB 在IntersectionObserver<\/code>包装的组件中呈现消息,当消息在视口中时触发挂钩并将messageId<\/code>作为参数传递
<\/li>
![](/img/trans.png)
clientB sends a request to the server to mark the message as seen when requested by the hook clientB 向服务器发送请求,以在钩子请求时将消息标记为已看到<\/li>
![](/img/trans.png)
server marks the message with messageId<\/code> as seen by setting timeSeen = now()<\/code>
服务器通过设置timeSeen = now()<\/code> messageId<\/code>标记消息
<\/li>
![](/img/trans.png)
server sends an update to clientB with meta into on the message with messageId<\/code> (timeSeen updated)
服务器向 clientB 发送更新,并在带有messageId<\/code>的消息上使用元数据(timeSeen 已更新)
<\/li>
![](/img/trans.png)
clientB sees that timeSeen is not null anymore and does not call the hook on re-renders clientB 看到 timeSeen 不再为空,并且不会在重新渲染时调用钩子<\/li><\/ul>I know this sounds a bit of an overkill, but this way you can reliably get the following:
我知道这听起来有点矫枉过正,但这样你就可以可靠地获得以下信息:
- All messages will have meta on when those where seen所有消息都会在看到的时候显示元数据<\/li>
You can aggregate the unseen counters and lists on the server side based on the meta您可以根据元数据在服务器端聚合看不见的计数器和列表<\/li><\/ul>"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.