Last active
May 18, 2022 10:23
-
-
Save vishalnarkhede/a49d9ba1c3a914d8406554497677eb22 to your computer and use it in GitHub Desktop.
Hook for displaying the channel name
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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