简体   繁体   English

Slack 如何存储未读消息?

[英]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>可以检测消息何时实际进入视口。

松弛截图<\/a>

But what would I store in the state?但是我会在该州存储什么? The ids of each unread message?每条未读消息的ID? If so, when I refresh and my app receives all the messages, how does it know any of them are read?如果是这样,当我刷新并且我的应用程序收到所有消息时,它如何知道其中任何一条已被读取? I could store the ids of each read<\/em> message instead but that sounds unwieldy.我可以存储每条已读<\/em>消息的 ID,但这听起来很笨拙。

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>
    • server saves the messages to the databases服务器将消息保存到数据库<\/li>
    • server forwards the message to clientB服务器将消息转发给客户端B<\/li>
    • clientB checks that the message does not have timeSeen<\/code> , eg it's null<\/code> clientB 检查消息没有timeSeen<\/code> ,例如它是null<\/code><\/li>
    • 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>
    • clientB sends a request to the server to mark the message as seen when requested by the hook clientB 向服务器发送请求,以在钩子请求时将消息标记为已看到<\/li>
    • server marks the message with messageId<\/code> as seen by setting timeSeen = now()<\/code>服务器通过设置timeSeen = now()<\/code> messageId<\/code>标记消息<\/li>
    • server sends an update to clientB with meta into on the message with messageId<\/code> (timeSeen updated)服务器向 clientB 发送更新,并在带有messageId<\/code>的消息上使用元数据(timeSeen 已更新)<\/li>
    • 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM