Skip to content

Instantly share code, notes, and snippets.

@vishalnarkhede
Last active May 18, 2022 10:23
Show Gist options
  • Save vishalnarkhede/a49d9ba1c3a914d8406554497677eb22 to your computer and use it in GitHub Desktop.
Save vishalnarkhede/a49d9ba1c3a914d8406554497677eb22 to your computer and use it in GitHub Desktop.
Hook for displaying the channel name
import { useEffect, useState } from 'react';
import { Dimensions } from 'react-native';
import type { Channel, EventHandler } from 'stream-chat';
import { useChatContext, DefaultStreamChatGenerics } from 'stream-chat-react-native';
export const vw = (percentageWidth: number, rounded = false) => {
const value = Dimensions.get('window').width * (percentageWidth / 100);
return rounded ? Math.round(value) : value;
};
const maxCharacterLengthDefault = (vw(100) - 16) / 6;
export const getChannelPreviewDisplayName = <
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
>({
channelName,
currentUserId,
maxCharacterLength,
members,
}: {
maxCharacterLength: number;
channelName?: string;
currentUserId?: string;
members?: Channel<StreamChatGenerics>['state']['members'];
}) => {
if (channelName) return channelName;
const channelMembers = Object.values(members || {});
const otherMembers = channelMembers.filter((member) => member.user?.id !== currentUserId);
const name = otherMembers.slice(0).reduce((returnString, currentMember, index, originalArray) => {
const returnStringLength = returnString.length;
const currentMemberName = currentMember.user?.name || currentMember.user?.id || 'Unknown User';
// a rough approximation of when the +Number shows up
if (returnStringLength + (currentMemberName.length + 2) < maxCharacterLength) {
if (returnStringLength) {
returnString += `, ${currentMemberName}`;
} else {
returnString = currentMemberName;
}
} else {
const remainingMembers = originalArray.length - index;
returnString += `, +${remainingMembers}`;
originalArray.splice(1); // exit early
}
return returnString;
}, '');
return name;
};
export const useChannelPreviewDisplayName = <
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
>(
channel?: Channel<StreamChatGenerics>,
characterLength?: number,
) => {
const { client } = useChatContext<StreamChatGenerics>();
const currentUserId = client.userID;
const members = channel?.state.members;
const numOfMembers = Object.keys(members || {}).length;
const channelName = channel?.data?.name;
const maxCharacterLength = characterLength || maxCharacterLengthDefault;
const [displayName, setDisplayName] = useState(
getChannelPreviewDisplayName({
channelName,
currentUserId,
maxCharacterLength,
members,
}),
);
useEffect(() => {
const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
setDisplayName(
getChannelPreviewDisplayName({
channelName: event.channel?.name,
currentUserId,
maxCharacterLength,
members: channel?.state.members,
}),
);
};
const subscriptions: Array<ReturnType<Channel['on']>> = [];
if (channel) {
subscriptions.push(channel.on('member.added', handleEvent));
subscriptions.push(channel.on('member.removed', handleEvent));
subscriptions.push(channel.on('member.updated', handleEvent));
}
return () => {
subscriptions.forEach(({ unsubscribe }) => unsubscribe?.());
};
}, [channel]);
useEffect(() => {
setDisplayName(
getChannelPreviewDisplayName({
channelName,
currentUserId,
maxCharacterLength,
members,
}),
);
}, [channelName, currentUserId, maxCharacterLength, numOfMembers]);
return displayName;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment