使用聊天
快点! 请不要使用 1. 5.0 版本 它有错误的属性名称!
聊天应用程序中状态管理的反应钩.
完整的文件尚未提供,但 将准备。 。 。 .
如果你对图书馆感兴趣 需要更多的文件, 请让我知道,在此增加一个积极反应(+1,心,火箭): https://github.com/chatscope/use-chat/issues/1 (中文(简体) )
这是什么?
这是一个无头聊天室。 把它当成一个像Formik的东西 但聊天应用.
库可同时使用 @chatscope/chat-ui-kit-反应 以及其他聊天组件.
其目的是提供一个工具,处理聊天应用程序中最常执行的功能.
主要是应用状态管理,以及一些优美的加词,如发出或接收打字指示器信号的去弹出或节奏.
为什么?
聊天应用程序的逻辑经常是重复的. 这些应用程序大多包含用户列表,会议列表和课程信息.
市场上至少有几家聊天API供应商. 它们提供saas服务,您可以用来构建聊天应用程序.
你也几乎总是从他们那里得到一个随时可以使用,简单的信息库. 这样一个库封装了一个复杂的通信协议.
有时也会得到UI组件和钩子/提供者,将UI绑定在提供者的信息库上.
两者密切相关,这使得替换消息库或UI组件的工作很多.
在此情况下,您必须注意如何在您的应用程序中保存:联系人列表及其状态,每个联系人的信息列表,聊天间切换,设置活动聊天,传送消息等. .
如果你自己创建了备份并执行通信层,你也不会避免做所有这些事情.
关注应用程序的业务功能不更好吗? 在布局,颜色选择等方面,而不是在数组中想着如何找到一个消息来将其状态设置为"已读"?
这种事情往往比看起来复杂.
例如,消息列表并不总是一个平坦的数组. 它常常是被指定给用户和对话的信息的对象,此外,它将被归类为收发信息块.
在列表中添加信息需要大致采取以下步骤:
- 为给定的对话找到信件列表,
- 找到最后一组,
- 检查信件是否来自用户组,
- 如果不是,那么就创建一个小组,并添加信息
- 将组添加到列表中
额,有一点,对不对?
这种东西应该在单独的逻辑库中被关闭,可以简单而直观地使用. 实施一致的接口也提供了内部调试(如改变数据结构)而不改变库使用方式的可能性.
特征
- 处理用户状态( 具有用户的商业属性, 如名称、 外观、 存在等)
- 处理对话状态(包括当前对话)
- 许多对话处理分组信件状态
- 发送已解禁的打字指标
- 自动节奏收到打字指示器
- 处理当前信件输入值
- 处理信件草稿
- 更新已有信件
- 支持任何通信服务
安装
使用纱线.
yarn add @chatscope/use-chat
使用 npm. (中文(简体) ).
npm install @chatscope/use-chat
建筑
该图书馆由三部分组成:
- 存储 - 保存状态的地点
- ChatProvider - 聊天上下文提供者
- 使用Chat - 绑定存储服务和用户界面的钩子
基本组合
这是一个执行IStorage接口的类. 所有数据,如对话,消息,当前对话指标等都坐落在存储中. BasicStorage是IStorage的基本执行. 它应充分发挥作用,并可用于大多数应用. 然而,有可能根据redux或另一个州立图书馆编写新的执行. 因此,储存从外部提供给查特普罗维德.
实例聊天服务
此类执行 IChatService 接口 .
该服务的目的是维持与聊天服务器的连接,发送并接收消息和聊天协议命令.
这是连接您的聊天服务器和库的点 .
要使用此库, 您需要自己编写执行 IChatService 接口的 ChatService .
服务的执行取决于您正在使用的聊天服务器 .
服务的内容可以是您从零开始写的代码, 但服务也可以是任何随时可以使用聊天通信库的封装层
有一个 实例/实例/实例 可供快速启动。 这是为您的应用程序开发真实服务的好起点.
今后,我将提供更多实例,说明与套接字的真正沟通。 基于io聊天服务器.
还将为一些SAAS供应商提供服务.
服务厂
这是一个简单的功能,你需要执行自己. 此函数收到一个聊天存储对象(IChatStorage)作为第一个参数,并更新函数作为第二个参数. 此函数必须返回执行 IChatService 的类实例 . 有时在您的 ChatService 执行中, 您需要从存储中获取值并保存到存储中 . 你可以把存储器交给你服务。 访问存储状态是通过存储.getstate()方法提供的. 写入存储通过调用存储.addConversation (), survey.addUser ()等功能实现. 第二个论点是 更新状态 函数. 每次写入从服务中执行的存储需要调用更新状态函数来进行再交付. 例如,当服务收到一些用户已连接的信号化时,您可以使用存储.addUser () 方法添加用户到存储中 和下一个调用更新状态 ().
这种描述可能看起来很复杂:). 但相信我,这真的很简单 比起你必须照顾一切.
基本用途
这是一个非常简单的例子,但它表明,使用 使用聊天 钩.
关于基于CRA的更复杂的例子,请访问 https://github.com/查特镜/use-查特-例。 。 。 . 这里有工作示例应用程序: https://use-chat.examples.chatscope.io (英语)
文件:索引.js
import {nanoid} from "nanoid";
import {
BasicStorage,
ChatProvider,
ExampleChatService,
AutoDraft
} from "@chatscope/use-chat";
// Storage needs to generate id for messages and groups
const messageIdGenerator = () => nanoid();
const groupIdGenerator = () => nanoid();
// Create serviceFactory
const serviceFactory = (storage, updateState) => {
return new ExampleChatService(storage, updateState);
};
const chatStorage = new BasicStorage({groupIdGenerator, messageIdGenerator});
export const App = () => {
return (
<ChatProvider serviceFactory={serviceFactory} storage={chatStorage} config={{
typingThrottleTime: 250,
typingDebounceTime: 900,
debounceTyping: true,
autoDraft: AutoDraft.Save | AutoDraft.Restore
}}>
<Chat />
</ChatProvider>
);
};
文件 Chat.js :
import {useState, useMemo } from "react";
import { MainContainer, Sidebar, ConversationList, Conversation, Avatar, MessageGroup, Message,
ChatContainer, ConversationHeader, MessageList, MessageInput} from "@chatscope/chat-ui-kit-react";
import { useChat, ChatMessage, MessageContentType, MessageDirection, MessageStatus } from "@chatscope/use-chat";
export const Chat = () => {
// Message input value
const [value, setValue] = useState("");
// Get all chat related values and methods from useChat hook
const {
currentMessages, conversations, activeConversation, setActiveConversation, sendMessage, getUser
} = useChat();
// Get current user data
const [currentUserAvatar, currentUserName] = useMemo(() => {
if (activeConversation) {
const participant = activeConversation.participants.length > 0 ? activeConversation.participants[0] : undefined;
if (participant) {
const user = getUser(participant.id);
if (user) {
return [<Avatar src={user.avatar} />, user.username]
}
}
}
return [undefined, undefined];
}, [activeConversation]);
const handleSend = text => {
// Logger user (sender)
const currentUserId = "123";
const message = new ChatMessage({
id: "",
content: text,
contentType: MessageContentType.TextHtml,
senderId: currentUserId,
direction: MessageDirection.Outgoing,
status: MessageStatus.Sent
});
sendMessage({
message,
conversationId: activeConversation.id,
senderId: currentUserId,
});
};
return (<MainContainer>
<Sidebar position="left">
<ConversationList>
{conversations.map(c => {
// Helper for getting the data of the first participant
const [avatar, name] = (() => {
const participant = c.participants.length > 0 ? c.participants[0] : undefined;
if (participant) {
const user = getUser(participant.id);
if (user) {
return [<Avatar src={user.avatar} />, user.username]
}
}
return [undefined, undefined]
})();
return (<Conversation key={c.id}
name={name}
active={activeConversation?.id === c.id}
unreadCnt={c.unreadCounter}
onClick={e => setActiveConversation(c.id)}>
{avatar}
</Conversation>);
})}
</ConversationList>
</Sidebar>
<ChatContainer>
<ConversationHeader>
{currentUserAvatar}
<ConversationHeader.Content userName={currentUserName} />
</ConversationHeader>
<MessageList>
{currentMessages.map(g => <MessageGroup key={g.id} direction={g.direction}>
<MessageGroup.Messages>
{g.messages.map(m => <Message key={m.id} model={{
type: "text",
payload: m.content
}} />)}
</MessageGroup.Messages>
</MessageGroup>)}
</MessageList>
<MessageInput value={value} onSend={handleSend} />
</ChatContainer>
</MainContainer>);
}