stream-chat-react
Version:
React components to create chat conversations or livestream style chat
63 lines (62 loc) • 3.67 kB
JavaScript
import React, { useCallback, useMemo } from 'react';
import uniqBy from 'lodash.uniqby';
import { useSearchContext } from '../SearchContext';
import { Avatar } from '../../../components/Avatar';
import { ChannelPreview } from '../../../components/ChannelPreview';
import { useChannelListContext, useChatContext } from '../../../context';
import { DEFAULT_JUMP_TO_PAGE_SIZE } from '../../../constants/limits';
export const ChannelSearchResultItem = ({ item }) => {
const { setActiveChannel } = useChatContext();
const { setChannels } = useChannelListContext();
const onSelect = useCallback(() => {
setActiveChannel(item);
setChannels?.((channels) => uniqBy([item, ...channels], 'cid'));
}, [item, setActiveChannel, setChannels]);
return (React.createElement(ChannelPreview, { channel: item, className: 'str-chat__search-result', onSelect: onSelect }));
};
export const MessageSearchResultItem = ({ item, }) => {
const { channel: activeChannel, client, searchController, setActiveChannel, } = useChatContext();
const { setChannels } = useChannelListContext();
const channel = useMemo(() => {
const { channel: channelData } = item;
const type = channelData?.type ?? 'unknown';
const id = channelData?.id ?? 'unknown';
return client.channel(type, id);
}, [client, item]);
const onSelect = useCallback(async () => {
if (!channel)
return;
await channel.state.loadMessageIntoState(item.id, undefined, DEFAULT_JUMP_TO_PAGE_SIZE);
// FIXME: message focus should be handled by yet non-existent msg list controller in client packaged
searchController._internalState.partialNext({ focusedMessage: item });
setActiveChannel(channel);
setChannels?.((channels) => uniqBy([channel, ...channels], 'cid'));
}, [channel, item, searchController, setActiveChannel, setChannels]);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const getLatestMessagePreview = useCallback(() => item.text, [item]);
if (!channel)
return;
return (React.createElement(ChannelPreview, { active: channel.cid === activeChannel?.cid &&
item.id === searchController._internalState.getLatestValue().focusedMessage?.id, channel: channel, className: 'str-chat__search-result', getLatestMessagePreview: getLatestMessagePreview, onSelect: onSelect }));
};
export const UserSearchResultItem = ({ item }) => {
const { client, setActiveChannel } = useChatContext();
const { setChannels } = useChannelListContext();
const { directMessagingChannelType } = useSearchContext();
const onClick = useCallback(() => {
const newChannel = client.channel(directMessagingChannelType, {
members: [client.userID, item.id],
});
newChannel.watch();
setActiveChannel(newChannel);
setChannels?.((channels) => uniqBy([newChannel, ...channels], 'cid'));
}, [client, item, setActiveChannel, setChannels, directMessagingChannelType]);
return (React.createElement("button", { "aria-label": `Select User Channel: ${item.name || ''}`, className: 'str-chat__search-result', "data-testid": 'search-result-user', onClick: onClick, role: 'option' },
React.createElement(Avatar, { className: 'str-chat__avatar--channel-preview', image: item.image, name: item.name || item.id, user: item }),
React.createElement("div", { className: 'str-chat__search-result--display-name' }, item.name || item.id)));
};
export const DefaultSearchResultItems = {
channels: ChannelSearchResultItem,
messages: MessageSearchResultItem,
users: UserSearchResultItem,
};