UNPKG

@sendbird/uikit-chat-hooks

Version:

A set of React hooks for integrating Sendbird chat functionality into your React app.

109 lines (95 loc) 2.91 kB
import { useRef } from 'react'; import type { SendbirdBaseChannel, SendbirdChatSDK, SendbirdOpenChannelListQuery } from '@sendbird/uikit-utils'; import { useAsyncEffect, useFreshCallback, useUniqHandlerId } from '@sendbird/uikit-utils'; import { useChannelHandler } from '../../handler/useChannelHandler'; import type { UseOpenChannelList, UseOpenChannelListOptions } from '../../types'; import { useOpenChannelListReducer } from './reducer'; const createOpenChannelListQuery = (sdk: SendbirdChatSDK, queryCreator: UseOpenChannelListOptions['queryCreator']) => { const passedQuery = queryCreator?.(); if (passedQuery) return passedQuery; return sdk.openChannel.createOpenChannelListQuery({}); }; export const useOpenChannelListWithQuery: UseOpenChannelList = (sdk, userId, options) => { const queryRef = useRef<SendbirdOpenChannelListQuery>(); const handlerId = useUniqHandlerId('useOpenChannelListWithQuery'); const { error, loading, openChannels, refreshing, updateChannels, appendChannels, deleteChannels, updateRefreshing, updateLoading, updateError, } = useOpenChannelListReducer(); const init = useFreshCallback(async (uid?: string) => { if (uid) { queryRef.current = createOpenChannelListQuery(sdk, options?.queryCreator); if (queryRef.current?.hasNext) { const channels = await queryRef.current.next(); appendChannels(channels, true); } } }); const updateChannel = (channel: SendbirdBaseChannel) => { if (channel.isOpenChannel()) updateChannels([channel]); }; useChannelHandler( sdk, handlerId, { onChannelChanged: updateChannel, onChannelFrozen: updateChannel, onChannelUnfrozen: updateChannel, onChannelDeleted: (url) => deleteChannels([url]), onUserEntered: (channel, user) => { const isMe = user.userId === userId; if (isMe && channel.isOpenChannel() && !openChannels.find((it) => it.url === channel.url)) { appendChannels([], true); refresh(); } }, }, 'open', ); useAsyncEffect(async () => { updateLoading(true); updateError(null); try { await init(userId); } catch (e) { updateError(e); appendChannels([], true); } finally { updateLoading(false); } }, [userId]); const refresh = useFreshCallback(async () => { updateRefreshing(true); updateError(null); try { await init(userId); } catch (e) { updateError(e); appendChannels([], true); } finally { updateRefreshing(false); } }); const next = useFreshCallback(async () => { if (queryRef.current?.hasNext) { const channels = await queryRef.current.next(); appendChannels(channels, false); } }); return { error, loading, openChannels, refresh, refreshing, next, }; };