!!! Пожалуйста, не используйте версию 1.5.0.
React Hook для управления государством в приложениях чата.
Полная документация еще недоступна, но будет подготовлена .
Если вы заинтересованы в этой библиотеке и нуждаетесь в большей документации, пожалуйста, дайте мне знать, добавив одну из положительных реакций (+1, сердце, ракета) в выделенном вопросе здесь: #1
Это библиотека чата без головы. Думайте об этом как о чем -то вроде формах, но для приложений для чата.
Библиотеку можно использовать как с помощью @Chatscope/CHAT-UI-KIT-React, так и с другими компонентами чата.
Цель этого состоит в том, чтобы предоставить инструмент для обработки функций, которые чаще всего реализуются в приложениях чата.
В первую очередь это управление государством приложения, а также некоторые приятные дополнения, такие как дебюрция или дроссельная передача или получение сигнализации индикатора печати.
Логика приложений в чате часто повторяется. Большинство из этих приложений содержит список пользователей, список конференций и, к лицу с сообщениями. На рынке есть как минимум несколько поставщиков API в чате. Они предоставляют услуги SaaS, которые вы можете использовать для создания приложения чата. Вы также почти всегда получаете от них готовую к употреблению библиотеку обмена сообщениями. Такая библиотека инкапсулирует сложный протокол связи.
Иногда вы также получаете компоненты пользовательского интерфейса и крючки/поставщики, которые связывают пользовательский интерфейс с библиотекой сообщений поставщика. Оба тесно связаны, что делает замену библиотеки обмена сообщениями или компонентов пользовательского интерфейса много работы.
В этом случае вы должны позаботиться о том, как сохранить в вашем приложении: список контактов и статусов их, список сообщений для каждого контакта, переключение между чатами, установление активного чата, рендеринг сообщений и так далее ...
Если вы создаете свой собственный подкрепленный и реализуете коммуникационный слой самостоятельно, вы также не будете избегать всех этих вещей.
Разве не лучше сосредоточиться на бизнес -функциональности приложения? На макете, выборе цвета и т. Д., Вместо того, чтобы задаться вопросом, как найти сообщение в массиве, чтобы настроить свое состояние для «читать»?
Такие вещи часто оказываются сложнее сделать, чем кажутся.
Например, список сообщений не всегда является плоским массивом. Это часто будет объектом с сообщениями, назначенными пользователям и разговорам, и, кроме того, он будет сгруппирован в блоки входящих и исходящих сообщений.
Добавление сообщения в список требует примерно следующих шагов:
Уфф, это немного, верно?
Такие вещи должны быть закрыты в отдельных логических библиотеках, которые можно использовать простым и интуитивно понятным способом. Реализация последовательного интерфейса также обеспечивает возможность внутренней настройки (например, изменение структуры данных) без изменения способа использования библиотеки.
Используя пряжу.
yarn add @chatscope/use-chatИспользуя NPM.
npm install @chatscope/use-chatБиблиотека состоит из трех частей:
Это класс, который реализует интерфейс Istorage. Все данные, такие как разговоры, сообщения, индикатор текущего разговора и т. Д., Составляют в хранилище. BasicStorage - это основная реализация Istorage. Он должен быть полностью функциональным и может использоваться для большинства приложений. Тем не менее, можно написать новые реализации, например, на основе Redux или другой государственной библиотеки. Вот почему хранилище предоставляется ChatProvider извне.
Это класс, который реализует интерфейс iChatservice. Цель этой службы - поддерживать соединение с сервером чата, отправлять и получать сообщения и команды протокола чата. Это точка, которая соединяет ваш сервер чата с библиотекой. Чтобы использовать эту библиотеку, вам нужно написать свой собственный чат -сервис, который реализует интерфейс iChatservice. Реализация службы зависит от того, какой сервер чата вы используете. Содержание службы может быть вашим кодом, написанным с нуля, но служба также может быть уровнем инкапсуляции для любой готовой к использованию библиотеки связи в чате
Существует SRC/примеры/exampleChatservice.ts, доступные для быстрого запуска. Это хорошая отправная точка для разработки реального сервиса для вашего приложения.
В будущем я предоставлю больше примеров, показывающих реальную связь с чат -сервером на основе Socket.io.
Реализации услуг для некоторых поставщиков SaaS также будут доступны.
Это простая функция, которую вам нужно реализовать себя. Эта функция получает объект хранения чата (iChatStorage) в качестве первого аргумента и обновлять функцию как второе. Эта функция должна вернуть экземпляр класса, реализующий iChatservice. Иногда в вашей реализации чат -сервиса вам нужно будет получить значения от хранилища, а также сохранить их в хранилище. Здесь вы можете передать хранилище в свой сервис. Доступ к состоянию хранения предоставляется методом Storage.getState (). Запись на хранилище реализуется путем вызова, таких как Storage.AddConversation (), Storage.Adduser () и т. Д. Второй аргумент - функция обновления . Каждая запись в хранилище, выполняемое в службе, должна вызвать функцию UpdateState для выполнения повторного разрешения. Например, когда служба получает сигнализацию, которую подключил какой -то пользователь, вы можете добавить пользователя к хранилищу с помощью метода Storage.Adduser () и Next Call UpdateState ().
Это описание, вероятно, выглядит сложным :). Но, поверьте, мне это действительно просто по сравнению с тем, когда вам нужно позаботиться обо всем.
Это очень простой пример, но показывает, насколько легко реализовать чат с помощью UseChat Hook.
Для более сложного примера на основе CRA, пожалуйста, посетите https://github.com/chatscope/use-chat-example. Приложение для рабочего примера доступно здесь: https://use-chat.examples.chatscope.io
Файл: index.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 >
) ;
} ;Файл чат.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 > ) ;
} https://chatscope.io
Грань